Admin pause or freeze powers
Can any privileged role stop, freeze, or block payments through the settlement contracts, and how is that role constrained? C1
No checkable evidence settles this yet, so it counts as 0.
incumbent No public chain settlementdeveloper.safaricom.co.ke
Incumbent rails have no public chain settlement and no public code. They are scored with the same rubric as every other row. Their low ratings show the verifiability gap between rails whose behaviour can be inspected and rails whose behaviour must be trusted; that gap is the point of the comparison, not a claim that the incumbent is unsafe.
Nothing rated Partial or Strong.
Offered only in the countries listed.
Scoped to what this file assesses: Safaricom's M-Pesa and its Daraja API. Safaricom's own Daraja docs describe M-Pesa as a mobile money service in Kenya, and every Daraja example uses Kenyan (254) MSISDNs. M-Pesa services in other countries (for example those run by Vodacom and other operators) are separate operators with their own ledgers, terms and APIs, and are not covered here. Safaricom's customer terms (safaricom.co.ke) returned HTTP 403 to automated requests, so any further limits stated there (for example on roaming or international transfers) were not read.
Listed countries (1): Kenya
Daraja "Getting Started" terminology section defines M-PESA. Page is client-rendered; text read from the portal's own GraphQL populateApi response and archived.
Who can block valid use, and can users route around them?
Pillar rating: weakest of 5
0 of 5 Partial or better · 3 no evidence
Can any privileged role stop, freeze, or block payments through the settlement contracts, and how is that role constrained? C1
No checkable evidence settles this yet, so it counts as 0.
Can a payer or payee complete settlement by calling the public contracts directly, without the provider's API, signer, or relayer? C2
Settlement happens only inside Safaricom's M-Pesa platform, reached through Safaricom's authenticated API or its own channels (SIM toolkit, USSD, app). No direct settlement path exists.
Daraja Postman collection (v2.1): every M-Pesa operation (stkpush, c2b registerurl/simulate, b2c, b2b, reversal, transactionstatus, accountbalance) is a POST to sandbox/api.safaricom.co.ke carrying 'Authorization: Bearer <Access-Token>' from Safaricom's /oauth/v1/generate.
developer.safaricom.co.ke/collections/Safaricom%20APIs.postman_collection.json
Does the payment flow require a relayer, paymaster, bundler, or API that only the provider runs? C3
Every integration depends on Safaricom's hosted API and on Safaricom provisioning shortcodes and credentials. No intermediary code is public and no fallback exists, so the dependency is closed and single-vendor.
C2B docs (loaded via the portal's populateApi query): production endpoints are api.safaricom.co.ke; access needs a Safaricom-issued OAuth token; enabling external validation requires emailing apisupport@safaricom.co.ke.
Is the settlement layer free of address or geographic filtering, and is any filtering at the edge disclosed and avoidable? C4
No checkable evidence settles this yet, so it counts as 0.
Re-assessed under the updated anchors on 2026-10-07; still unknown. The NPS Regulations require transaction screening (reg 31, see context), but no Safaricom document read discloses what M-Pesa filters: a search of all 31 Daraja API docs (populateApi) for sanction, AML, blacklist, watchlist and KYC found only KYC fields for organisation operators and a C2B error code "Invalid KYC Details", and the customer terms and privacy statement returned 403. Settlement runs in Safaricom's closed ledger, so neither disclosure nor its absence could be shown.
Are the tokens and chains the rail depends on enumerated, with their issuers' freeze powers and sequencer assumptions stated to payees? C5
No checkable evidence settles this yet, so it counts as 0.
Is the whole stack visible?
Pillar rating: weakest of 4
0 of 4 Partial or better · 2 no evidence
Does the deployed bytecode match public source, and can a third party rebuild it? O1
No checkable evidence settles this yet, so it counts as 0.
Are the SDK, frontend, backend or API, indexer, and deploy scripts all public? O2
Only client SDKs and samples are public. The platform itself (ledger, API gateway, USSD/STK services) is closed.
github.com/safaricom has 15 public repos; the non-fork M-Pesa ones are client libraries (Node, PHP, Java, C#), an Android STK sample, and callback-listener samples. None contains the M-Pesa backend, an indexer, or deploy scripts.
Can a stranger reach a working deployment from the README? O3
No checkable evidence settles this yet, so it counts as 0.
Are ABIs, event schemas, an API schema, and a payee data export in a non-proprietary format all in the repo? O4
API and callback schemas are documented on a hosted portal, with a Postman collection in place of OpenAPI. None of this is versioned in a repo, and no payee export format is specified, so the score is 1 (documented only).
Public Postman v2.1 collection 'Safaricom APIs' (_postman_id 21f972ff-40aa-439e-a906-e52cff4bcf63) with request schemas for M-Pesa Express, C2B, B2C, B2B, reversal, transaction status, account balance and Pull Transactions.
developer.safaricom.co.ke/collections/Safaricom%20APIs.postman_collection.json
C2B docs define the callback payload fields (TransactionType, TransID, TransTime, TransAmount, BusinessShortCode, BillRefNumber, MSISDN, FirstName, MiddleName, LastName, ...); merchants recover missed notifications through the Pull Transaction API or the M-PESA Org portal.
Does the license actually let a third party fork, modify, and run it?
Pillar rating: weakest of 3
0 of 3 Partial or better · 2 no evidence
Does every repository needed to run the product carry an OSI-approved license? F1
Two of the seven listed SDK repos (Java, C#) carry no license at all, so they cannot legally be forked. Two more (listener, PHP) declare ISC/MIT only in a package manifest, with no license text; they are recorded as "none" in repos. The platform needed to run the rail has no public code at all. Judgment call: scored on the listed SDK repos because no repo can run the product.
mpesa-java-sdk at this commit: pom.xml has no <licenses> element and the repo root (.idea, MpesaMaven.iml, README.md, out, pom.xml, src, target) has no LICENSE file. mpesa-api-C-Sharp (7f3d6e9e9c979c79e4c5bedd43de646623a4d6cd) likewise has no LICENSE file and no license statement in its README.
mpesa_listener has no LICENSE file; package.json L10 carries the npm-init default license: ISC. mpesa-php-sdk (5effb808e79ba6b3d8631ef83c2b9b31fa450152) has no LICENSE file; composer.json L10 declares license: mit with no license text.
mpesa-node-library LICENSE is Apache License 2.0; LNMOnlineAndroidSample (74eced63f0cd5fd2f9869f9fcaf9b14823dcadb8) is Apache-2.0; mpesa_c2b_php_confirmation_validation (96a55227d6191c0717edb0293bbd4c3bde1709c1) is GPL-3.0.
Can the provider unilaterally relicense future versions, and has it committed not to? F2
No checkable evidence settles this yet, so it counts as 0.
Does a production deployment need a proprietary plugin or hosted-only service? F3
No checkable evidence settles this yet, so it counts as 0.
What can an observer learn, and did the user knowingly choose it?
Pillar rating: weakest of 5
0 of 5 Partial or better · 4 no evidence
Do the SDK, widget, or frontend ship analytics, telemetry, error reporting, or fingerprinting? P1
No checkable evidence settles this yet, so it counts as 0.
Does the flow collect anything beyond addresses, amounts, token, and chain? P2
Each C2B payment sends the payee the payer's name as held in the M-Pesa register and a partial phone number (v2) or an enumerable SHA-256 of it (v1); settlement does not need either. Re-assessed under the updated anchors: 1 needs collection beyond settlement needs "disclosed in a policy", and 0 covers undisclosed collection or collection beyond the stated legal requirement. The only disclosure read is the integrator documentation; Safaricom's data privacy statement returned 403, so no payer-facing disclosure and no stated legal basis for passing the name to payees was read. The National Payment System Regulations, 2014 (see context) require Safaricom to keep a register of customer ID details (reg 12), not to pass customer names to payees. Score lowered from 1 to 0. Judgment call: between 1 and 0 the lower anchor is taken because the evidence for 1 (policy disclosure within a stated legal requirement) was not seen; a reviewer who can read the privacy statement and finds a disclosed legal basis for this sharing could restore 1.
C2B v2 callback payload sent to the merchant includes the payer's FirstName, MiddleName and LastName 'as per the M-Pesa register' and a masked MSISDN (C2B v1 sends a SHA-256 hash of the MSISDN, which is not anonymising for phone-number inputs).
What do calldata and events reveal about who paid whom for what? P3
No checkable evidence settles this yet, so it counts as 0.
Which third parties see a request during a payment, and can they be swapped out? P4
No checkable evidence settles this yet, so it counts as 0.
Can RPC and indexer URLs be changed, and is the indexer code public? P5
No checkable evidence settles this yet, so it counts as 0.
Who can cause loss, lock users in, or change the rules?
Pillar rating: weakest of 6
0 of 6 Partial or better · 3 no evidence
Who holds funds between payer and payee, and can the provider redirect them? S1
Payer and payee funds sit in M-Pesa accounts on Safaricom's platform, so the provider holds custody, and the API docs disclose this. Neither the trust arrangement behind the e-money nor any limit on redirecting funds could be read (the terms returned 403).
C2B docs: 'Funds originate from the customer wallet and are transferred to the merchant's short code'; the confirmation payload's OrgAccountBalance is the shortcode's balance held on M-PESA.
Account Balance API docs: organizations query 'their M-PESA account balances' through Safaricom's endpoint.
Who can change the contract code, and with how much notice? S2
No checkable evidence settles this yet, so it counts as 0.
How large an allowance does the SDK ask users to grant, and for how long? S3
No checkable evidence settles this yet, so it counts as 0.
If the provider disappears tomorrow, do payees keep their funds and the ability to keep settling? S4
Derived. S1 = 1 (provider custody), C2 = 0 (no direct settlement), C3 = 0 (closed single-vendor API), O3 unknown (nothing to self-host). Both funds and the ability to settle depend on Safaricom's liveness.
All settlement, balance and reversal operations are Safaricom-hosted endpoints (see C2, C3); no exit path outside Safaricom's platform is documented.
developer.safaricom.co.ke/collections/Safaricom%20APIs.postman_collection.json
Are secrets kept out of client bundles and are webhooks signed and verified? S5
Payment callbacks are unsigned per the Daraja docs, and the reference handlers accept them without verification, so a party who learns a merchant's callback URL can forge payment confirmations unless the merchant re-queries Transaction Status. Handling of API credentials (consumer key/secret, SecurityCredential) in client bundles was not assessed.
Reference C2B ConfirmationURL handler logs req.body and returns ResultCode 0 with no authenticity check; the B2C/B2B result handlers in the same file (L18-L29, L88-L99) do the same.
Reference PHP confirmation handler reads php://input, logs it and acknowledges, with no signature or source verification.
safaricom/mpesa_c2b_php_confirmation_validation · confirm.php
C2B docs: M-PESA POSTs confirmation/validation results as application/json to the registered URLs; the documented payload and URL requirements (public IP/domain, HTTPS in production) include no signature, HMAC, or shared-secret field or header.
Has the code been audited at a pinned commit, were findings fixed traceably, and is there a live bounty? S6
No checkable evidence settles this yet, so it counts as 0.
Published audits and similar reviews of this provider's code, newest first. Context for the Audits and bug bounty rating, which scores them; this list does not change any rating, and an audit of older code says little about what is deployed now.
No published audit report was found.
Facts an institution's procurement, finance and security functions ask for. Separate from the CROPS ratings and never scored.
Group A: operational facts. Group B: 45 due-diligence controls derived from a UN agency's vendor requirements: 10 evidenced, 0 attested, 7 absent, 0 not applicable, 28 unknown. "Not applicable" means there is no operator to hold the control: it falls to whoever deploys the rail. How to read this.
| Component | Paid by | Amount | Basis |
|---|---|---|---|
| provider | both | per Safaricom tariff (amounts not published in Daraja) | Daraja says that, depending on the tariff, the charge is levied on the organisation or split between organisation and customer; debited to the Charges Paid account. |
| limit | none | customer daily transfer limit KES 500,000 | Daraja B2C result-code table ("currently Ksh 500,000"). |
| limit | none | maximum customer account balance KES 500,000 | Daraja B2C result-code table. |
Safaricom's consumer tariff pages (send, withdraw, pay) return 403 to automated access, and the Wayback Machine availability API returned 429, so no archived first-party tariff was used. Per-transaction amounts are unknown, not zero. The Daraja sample "Fee For B2C Payment|KES|22.40" is sandbox example data and is not recorded.
Daraja M-Pesa Express documentation (client-rendered; GraphQL markdown archived).
Daraja B2C documentation, result codes 4 and 8.
Provider-custodial
| Entity | Country | Regulator | Licence | Register |
|---|---|---|---|---|
| Safaricom PLC | Kenya | Central Bank of Kenya | Authorised payment service provider (mobile money) Issue, process, store, send and facilitate mobile money payments; platform processing payments on behalf of merchants. First licensed January 1, 2016. | register |
Evidence is the regulator's own directory, extracted from the current PDF (it replaces the earlier transcription in data/archive/m-pesa-cbk-directory.txt). The register URL is the CBK payments page that links the directory.
CBK Directory of Authorized Payment Service Providers as at August 10, 2026, entry 1 (PDF linked from the CBK national payments system page; text extracted and archived 2026-10-09).
| Where | Method | Partner | Fee | Limits |
|---|---|---|---|---|
| Kenya | mobile money | Daraja B2C (business to customer M-Pesa wallet) | customer daily transfer and balance limits KES 500,000 |
Agent cash-out is the product's core, but no readable first-party source for agent withdrawal terms or fees was found (safaricom.co.ke 403; Daraja does not cover agents). CBK states that M-Pesa launched with 307 agents in 2007 (Governor's 2013 speech), which is not a current terms source. Agent and ATM rows are therefore not recorded.
Daraja B2C use cases (salary, loan and financial-institution withdrawal payouts to customer wallets or bank accounts).
2007-03-01: M-PESA launch in Kenya. CBK gives the month (March 2007) only; the day is a placeholder.
The CBK licence date (January 1, 2016) is the date of the current authorisation under the 2011 Act, not the launch.
Central Bank of Kenya publication "Kenya's Payments Journey" (PDF, excerpt archived).
www.centralbank.go.ke/wp-content/uploads/2023/02/Kenyas-Payments-Journey.pdf
Safaricom PLC, KE
The Kenyan Business Registration Service register was not checked, so no registration number is recorded.
CBK PSP directory entry 1.
Absence of a found incident is not evidence that none occurred.
No primary-source incident notice could be read. Safaricom's newsroom and status pages return 403, and no CBK enforcement notice naming M-Pesa was found in this pass.
Other changes (tariff changes, limit changes, product changes) need Safaricom announcements, which return 403.
CBK PSP directory entry 1.
Closed ledger; no public chain to read. Safaricom and CBK publish aggregate figures, which are reported, not verifiable, and are not recorded here.
| Control | State | What was found |
|---|---|---|
| Assurance and certifications | ||
| B1.1 ISO 27001, developer organisation Is the organisation that develops the product ISO 27001 certified, and does the certificate name that entity? | Unknown | |
| B1.2 ISO 27001, hosting and support organisation Is the organisation that hosts and supports the service ISO 27001 certified in its own name, with a scope covering the service? | Unknown | |
| B1.3 SOC 2 Type II or ISAE 3000/3402 reports Does the provider undergo periodic SOC 2 Type II or ISAE 3402 Type II assessments and make reports available? | Unknown | |
| B1.4 Independent source-code security review before go-live Was the application reviewed by an independent party before launch, and is the report linked? | Unknown | |
| B1.5 Penetration testing Is the service penetration-tested before go-live and at least every three years, with results available? | Unknown | |
| B1.6 Vulnerability scanning cadence Are the platform and the application scanned for vulnerabilities at least every six months? | Unknown | |
| Vulnerability and patch management | ||
| B2.1 Security contact and disclosure policy Is there a published way to report a vulnerability (SECURITY.md, security.txt, or a disclosure page)? | Absent | none of 7 repo(s): safaricom/mpesa-node-library ✗ no security policy file; safaricom/LNMOnlineAndroidSample ✗ no security policy file; safaricom/mpesa_c2b_php_confirmation_validation ✗ no security policy file; safaricom/mpesa_listener ✗ no security policy file; safaricom/mpesa-php-sdk ✗ no security policy file; safaricom/mpesa-java-sdk ✗ no security policy file; safaricom/mpesa-api-C-Sharp ✗ no security policy file source 1 · source 2 · source 3 · source 4 · source 5 · source 6 · source 7 |
| B2.2 Patch service levels Does the provider commit to patch timelines for known vulnerabilities (the partner expects 30 days critical, 40 high, 90 medium)? | Unknown | |
| B2.3 Dependency and vulnerability scanning in CI Do the public repositories run dependency or code scanning automatically? | Absent | none of 7 repo(s): safaricom/mpesa-node-library ✗ no scanning config or workflow step found; safaricom/LNMOnlineAndroidSample ✗ no scanning config or workflow step found; safaricom/mpesa_c2b_php_confirmation_validation ✗ no scanning config or workflow step found; safaricom/mpesa_listener ✗ no scanning config or workflow step found; safaricom/mpesa-php-sdk ✗ no scanning config or workflow step found; safaricom/mpesa-java-sdk ✗ no scanning config or workflow step found; safaricom/mpesa-api-C-Sharp ✗ no scanning config or workflow step found source 1 · source 2 · source 3 · source 4 · source 5 · source 6 · source 7 |
| Incident reporting and continuity | ||
| B3.1 Incident reporting commitment Does the provider commit to notify customers of security or data incidents within a stated time (the partner expects 24 hours)? | Unknown | |
| B3.2 Backups and restore testing Are customer records backed up daily and restores tested on a schedule? | Unknown | |
| B3.3 Recovery plan Is there an approved and tested recovery plan for the service? | Unknown | |
| B3.4 Status page and post-mortems Does the provider publish service status and post-mortems for incidents? | Unknown | |
| Identity and access (operator side) | ||
| B4.1 MFA for end users Can or must end users protect accounts with multi-factor authentication? | Unknown | |
| B4.2 MFA and separate accounts for privileged access Is privileged access protected by MFA and kept on separate accounts? | Unknown | |
| B4.3 Periodic access reviews Are user access rights reviewed at least annually and privileged accounts at least six-monthly? | Unknown | |
| B4.4 Segregation of duties and joiner-mover-leaver controls Is there a documented segregation-of-duties model and a joiner-mover-leaver process? | Unknown | |
| B4.5 Session timeout Are idle interactive sessions terminated after a defined period (the partner expects 60 minutes)? | Unknown | |
| API and integration | ||
| B5.1 API authentication, browser to server Which standard (OAuth 2.0, OpenID Connect, SAML, JWT) protects browser-to-server API calls? | Evidenced | OAuth 2.0 client-credentials bearer tokens on every Daraja call. CROPS C2 |
| B5.2 API authentication, server to server Are server-to-server calls authenticated with keys or PKI certificates, and are keys scoped and rotatable? | Evidenced | Consumer key and secret issued per app; B2C and similar calls also carry an encrypted initiator security credential; callbacks are unsigned (see CROPS S5). CROPS C2 · CROPS S5 |
| B5.3 Token expiry Do API tokens expire, and within what period (the partner caps it at 120 minutes for public data, 30 otherwise)? | Unknown | The Daraja docs say access tokens expire ("Regenerate a new token and use it before expiry") but the C2B, B2C, M-Pesa Express and Transaction Status docs read do not state the lifetime. The Authorization doc alias returned "Invalid ApiName Option" from populateApi. |
| B5.4 Export controls If an API exports data, does it limit volumes and log exports? | Unknown | |
| Data protection and privacy governance | ||
| B6.1 Data classification and encryption Does the provider state a data classification and enforce encryption at rest and TLS 1.2 or better in transit? | Evidenced | Observed: developer.safaricom.co.ke refuses TLS 1.1 and accepts TLS 1.2. No data classification or encryption-at-rest statement could be read (safaricom.co.ke returns 403). source 1 |
| B6.2 Production data kept out of test environments Does the provider state that production or real personal data is not used in development and testing? | Unknown | |
| B6.3 Data retention and deletion on termination What is retained, for how long, and is customer data removed on termination? | Unknown | |
| B6.4 Data protection impact assessment and roles For systems holding personal data, has a DPIA been completed and are controller and processor defined? | Unknown | The privacy statement returns 403 to automated access. |
| B6.5 Data processing or sharing agreement available Can a customer obtain a data processing agreement or equivalent? | Unknown | |
| Logging and monitoring | ||
| B7.1 Audit logging Are account changes, logins and activity on important records logged and retained? | Unknown | |
| B7.2 Central monitoring and endpoint detection Are logs sent to a managed SIEM and is endpoint detection running on all platforms? | Unknown | |
| Hosting and network | ||
| B8.1 Hardened hosting Are hosts hardened to a recognised benchmark, with only essential ports open, IDS/IPS, a WAF for internet-facing applications and tenant isolation? | Unknown | |
| B8.2 Deployment configuration and infrastructure as code Does the repository ship reproducible deployment configuration (containers, IaC, Helm) that a self-hoster can harden? | Absent | none of 7 repo(s): safaricom/mpesa-node-library ✗ no deployment configuration; safaricom/LNMOnlineAndroidSample ✗ no deployment configuration; safaricom/mpesa_c2b_php_confirmation_validation ✗ no deployment configuration; safaricom/mpesa_listener ✗ no deployment configuration; safaricom/mpesa-php-sdk ✗ no deployment configuration; safaricom/mpesa-java-sdk ✗ no deployment configuration; safaricom/mpesa-api-C-Sharp ✗ no deployment configuration source 1 · source 2 · source 3 · source 4 · source 5 · source 6 · source 7 |
| Engineering practice in public repositories | ||
| B9.1 Default branch protected Does the default branch require reviews and passing checks, with no direct pushes? | Absent | none of 7 repo(s): safaricom/mpesa-node-library ✗ no branch rules visible (classic branch protection is not readable without push access); safaricom/LNMOnlineAndroidSample ✗ no branch rules visible (classic branch protection is not readable without push access); safaricom/mpesa_c2b_php_confirmation_validation ✗ no branch rules visible (classic branch protection is not readable without push access); safaricom/mpesa_listener ✗ no branch rules visible (classic branch protection is not readable without push access); safaricom/mpesa-php-sdk ✗ no branch rules visible (classic branch protection is not readable without push access); safaricom/mpesa-java-sdk ✗ no branch rules visible (classic branch protection is not readable without push access); safaricom/mpesa-api-C-Sharp ✗ no branch rules visible (classic branch protection is not readable without push access) source 1 · source 2 · source 3 · source 4 · source 5 · source 6 · source 7 |
| B9.2 CI runs on pull requests Does every pull request trigger automated checks? | Absent | none of 7 repo(s): safaricom/mpesa-node-library ✗ no .github/workflows; safaricom/LNMOnlineAndroidSample ✗ no .github/workflows; safaricom/mpesa_c2b_php_confirmation_validation ✗ no .github/workflows; safaricom/mpesa_listener ✗ no .github/workflows; safaricom/mpesa-php-sdk ✗ no .github/workflows; safaricom/mpesa-java-sdk ✗ no .github/workflows; safaricom/mpesa-api-C-Sharp ✗ no .github/workflows source 1 · source 2 · source 3 · source 4 · source 5 · source 6 · source 7 |
| B9.3 Tests run in CI Do the CI workflows run the test suite? | Absent | none of 7 repo(s): safaricom/mpesa-node-library ✗ test command in a workflow; safaricom/LNMOnlineAndroidSample ✗ test command in a workflow; safaricom/mpesa_c2b_php_confirmation_validation ✗ test command in a workflow; safaricom/mpesa_listener ✗ test command in a workflow; safaricom/mpesa-php-sdk ✗ test command in a workflow; safaricom/mpesa-java-sdk ✗ test command in a workflow; safaricom/mpesa-api-C-Sharp ✗ test command in a workflow source 1 · source 2 · source 3 · source 4 · source 5 · source 6 · source 7 |
| B9.4 Coverage reported Is test coverage measured and reported (the partner expects 85%)? | Absent | none of 7 repo(s): safaricom/mpesa-node-library ✗ coverage tooling referenced; safaricom/LNMOnlineAndroidSample ✗ coverage tooling referenced; safaricom/mpesa_c2b_php_confirmation_validation ✗ coverage tooling referenced; safaricom/mpesa_listener ✗ coverage tooling referenced; safaricom/mpesa-php-sdk ✗ coverage tooling referenced; safaricom/mpesa-java-sdk ✗ coverage tooling referenced; safaricom/mpesa-api-C-Sharp ✗ coverage tooling referenced source 1 · source 2 · source 3 · source 4 · source 5 · source 6 · source 7 |
| B9.5 Versioned releases Are releases tagged with immutable semantic versions? | Evidenced | some of 7 repo(s): safaricom/mpesa-node-library ✓ latest tags: v0.1.3; safaricom/LNMOnlineAndroidSample ✗ no tags; safaricom/mpesa_c2b_php_confirmation_validation ✗ no tags; safaricom/mpesa_listener ✗ no tags; safaricom/mpesa-php-sdk ✓ latest tags: 1.0.8, 1.0.7, 1.0.6; safaricom/mpesa-java-sdk ✗ no tags; safaricom/mpesa-api-C-Sharp ✗ no tags source 1 · source 2 · source 3 · source 4 · source 5 · source 6 · source 7 |
| B9.6 Signed tags or commits Are release tags or recent commits cryptographically signed? | Evidenced | some of 7 repo(s): safaricom/mpesa-node-library ✓ 9 of 10 recent commits signed; safaricom/LNMOnlineAndroidSample ✗ 2 of 10 recent commits signed; safaricom/mpesa_c2b_php_confirmation_validation ✗ 0 of 3 recent commits signed; safaricom/mpesa_listener ✗ 4 of 10 recent commits signed; safaricom/mpesa-php-sdk ✓ 8 of 10 recent commits signed; safaricom/mpesa-java-sdk ✓ 4 of 8 recent commits signed; safaricom/mpesa-api-C-Sharp ✗ 1 of 4 recent commits signed source 1 · source 2 · source 3 · source 4 · source 5 · source 6 · source 7 |
| B9.7 Changelog Is a changelog maintained with the code? | Evidenced | some of 7 repo(s): safaricom/mpesa-node-library ✓ 1 release(s) with notes; safaricom/LNMOnlineAndroidSample ✗ no changelog or release notes; safaricom/mpesa_c2b_php_confirmation_validation ✗ no changelog or release notes; safaricom/mpesa_listener ✗ no changelog or release notes; safaricom/mpesa-php-sdk ✓ 3 release(s) with notes; safaricom/mpesa-java-sdk ✗ no changelog or release notes; safaricom/mpesa-api-C-Sharp ✗ no changelog or release notes source 1 · source 2 · source 3 · source 4 · source 5 · source 6 · source 7 |
| B9.8 Contribution and branching model documented Does the README or contribution guide state how changes are proposed, reviewed and released? | Evidenced | some of 7 repo(s): safaricom/mpesa-node-library ✓ contribution section in README; safaricom/LNMOnlineAndroidSample ✗ none found; safaricom/mpesa_c2b_php_confirmation_validation ✗ none found; safaricom/mpesa_listener ✗ none found; safaricom/mpesa-php-sdk ✗ none found; safaricom/mpesa-java-sdk ✗ none found; safaricom/mpesa-api-C-Sharp ✗ none found source 1 · source 2 · source 3 · source 4 · source 5 · source 6 · source 7 |
| Architecture documentation | ||
| B10.1 Architecture documentation Is there a public architecture document covering logical, infrastructure and integration architecture and the components used? | Evidenced | Integration architecture only (Daraja API docs with sequence diagrams, account types and environments); logical and infrastructure architecture of the M-Pesa platform are not published. source 1 |
| Commercial and financial | ||
| B11.1 Contracting entity Which legal entity would an institution contract with, and in which jurisdiction? | Evidenced | Safaricom PLC, Kenya (Safaricom House, Waiyaki Way, Westlands, Nairobi). The M-Pesa customer terms (which name the contracting entity) return 403 and were not read. source 1 |
| B11.2 Funding of ongoing operation How is ongoing operation and maintenance funded (revenue, foundation, grants, fee switch), per a primary source? | Evidenced | Transaction charges under Safaricom's tariff, levied on the organisation or split with the customer (Daraja account-type notes); Safaricom PLC is a listed company. source 1 |
| B11.3 Termination terms What happens to customer funds and data on termination by either side? | Unknown | The M-Pesa customer terms return 403 to automated access. |
| AI components | ||
| B12.1 AI in the payment path Does an AI system take part in payment processing or compliance decisions (for example automated transaction screening)? | Unknown | |
| B12.2 AI controls documented If AI is used, are monitoring, validation, override, decommissioning and bias evaluation documented? | Unknown | |
| Component | Role | Public | Licence | Operator | Required |
|---|---|---|---|---|---|
| M-Pesa core platform (e-money ledger and transaction processing) | ledger | No | proprietary | Safaricom PLC | Yes |
| M-Pesa customer register (identity behind each wallet) | kyc | No | proprietary | Safaricom PLC | Yes |
| Daraja API gateway and OAuth token service (api.safaricom.co.ke) | api | No | proprietary | Safaricom PLC | No |
| Customer channels (SIM Toolkit, USSD, M-Pesa app, Safaricom app) | wallet | No | proprietary | Safaricom PLC | No |
| M-PESA Org portal (org.ke.m-pesa.com) | frontend | No | proprietary | Safaricom PLC | No |
| Trust fund holding e-money balances (trustees, banks not named) | other | No | proprietary | Trustees and Kenyan commercial banks (unnamed) | No |
| mpesa-node-library | sdk | Yes | Apache-2.0 | github.com/safaricom (attribution is a judgment call, see notes) | No |
| LNMOnlineAndroidSample | sdk | Yes | Apache-2.0 | github.com/safaricom (attribution is a judgment call, see notes) | No |
| mpesa_c2b_php_confirmation_validation | sdk | Yes | GPL-3.0 | github.com/safaricom (attribution is a judgment call, see notes) | No |
| mpesa_listener | sdk | Yes | none | github.com/safaricom (attribution is a judgment call, see notes) | No |
| mpesa-php-sdk | sdk | Yes | none | github.com/safaricom (attribution is a judgment call, see notes) | No |
| mpesa-java-sdk | sdk | Yes | none | github.com/safaricom (attribution is a judgment call, see notes) | No |
| mpesa-api-C-Sharp | sdk | Yes | none | github.com/safaricom (attribution is a judgment call, see notes) | No |
| Repository | Role | License |
|---|---|---|
| safaricom/mpesa-node-library | sdk | Apache-2.0 |
| safaricom/LNMOnlineAndroidSample | sdk | Apache-2.0 |
| safaricom/mpesa_c2b_php_confirmation_validation | sdk | GPL-3.0 |
| safaricom/mpesa_listener | sdk | none |
| safaricom/mpesa-php-sdk | sdk | none |
| safaricom/mpesa-java-sdk | sdk | none |
| safaricom/mpesa-api-C-Sharp | sdk | none |
None listed.
Incumbent. M-Pesa is a closed, custodial mobile-money ledger run by Safaricom; the repos listed are sample clients and callback listeners for the Daraja REST API, not code that runs the rail. Attribution of github.com/safaricom is a judgment call: the org is not GitHub-verified and developer.safaricom.co.ke does not link to it, but the org profile links to developer.safaricom.co.ke and commits in mpesa-php-sdk and mpesa-java-sdk come from safaricom.net addresses, and the mpesa-php-sdk composer.json author uses a safaricom.co.ke address. Forks in that org (android-daraja-sdk, mpesa-py, mpesa-api-go, Mpesa.Net), unrelated repos (kubernetes, kubespray, cisco-anyconnect) and the empty mpesa-perl-sample are excluded. www.safaricom.co.ke, including the data privacy statement and M-Pesa terms, returned HTTP 403 (bot protection) to every non-browser request on 2026-10-07, so neither document could be read or cited; the website field therefore points at the Daraja developer portal, which does resolve. Daraja pages are a client-rendered app: page URLs return 200 and their content loads from the portal's /api/graphql populateApi query, which is how the docs were read. The static Postman collection is the one fully fetchable interface artifact.