Payment verification
A payment notification is a claim that money moved. MyChurch credits nothing until Safaricom itself confirms the payment, and never credits the same payment twice.
Why
The confirmation URL a paybill registers is a public address. Anyone who learns it can post something that looks like a payment. Crediting from the notification alone would let a forged or replayed request inflate a church's collections and send receipts for money that never arrived. So every notification, whether a C2B confirmation, a payment prompt result or a line pulled from the M-Pesa statement, goes through the same check.
The check
- The notification is stored exactly as it arrived and answered at once, so Safaricom never retries for lack of a reply.
- MyChurch sends a Transaction Status query for that receipt number, using the church's own paybill initiator credentials.
- Safaricom's answer must report the same receipt number, a completed transaction and the same amount. Only then is the payment verified.
- The credit and everything it touches (ledger, account totals, pledges, fundraisers, events) happen together in one database transaction, then the receipt SMS is queued.
Verification usually takes seconds. If Safaricom does not answer, the query is repeated every few minutes, then hourly; a payment is never given up on.
Payment states
| pending | Received and stored; waiting for its turn to be checked with Safaricom. |
| querying | A Transaction Status query has been sent; waiting for Safaricom's answer. |
| verified | Safaricom confirmed the receipt, amount and completion. About to be credited. |
| credited | On the ledger, the account totals and whatever it settles. Receipt sent. |
| unmatched | Verified, but the account number matched nothing. In Incoming payments for review. |
| failed | Safaricom did not confirm it (not found, not completed, or a different amount). Never credited. |
Fail closed
If a paybill has no initiator credentials stored, or Safaricom cannot be reached, payments stay pending with the reason noted, and are credited as soon as verification succeeds. Store the initiator in Paybill setup to avoid this.
No double credits
- An M-Pesa receipt number is credited at most once, however many times it is notified, pulled or replayed.
- A payment prompt result is matched by Safaricom's checkout request id and moves from accepted to completed once.
- Bank payments are credited at most once per bank reference.
Banks
Equity and KCB offer no status API to confirm a payment the way Safaricom does. Their callbacks are accepted only on the private callback URL issued to the bank and only for a reference MyChurch issued or an account it holds; the credit is then marked unverified in the ledger and reports, with the bank's message kept, so a treasurer can reconcile it against the bank statement. See Bank integrations.
Reconciling