Skip to content

Pull Transactions

Pull Transactions is a reconciliation flow for merchants running C2B collections on a paybill or till.

Use it when:

  • you need a second source of truth for recent customer payments
  • confirmation callbacks were delayed, dropped, or never reached your systems
  • operations or finance teams need to compare received callbacks against Safaricom transaction history

This API is not a replacement for your normal confirmation callbacks. It is a recovery and reconciliation tool.

PesaKit exposes the two Daraja calls as:

  • mpesa.pull.register() to register your shortcode, nominated Safaricom number, and callback URL
  • mpesa.pull.query() to fetch recent transactions for a registered shortcode

Safaricom requires a registration step before you can query transactions.

await mpesa.pull.register({
nominatedNumber: "254722000000",
callbackUrl: "https://example.com/mpesa/pull/register",
});
  • The nominated number should be a Safaricom MSISDN associated with the business account.
  • Use a public HTTPS callback URL in production.
  • Safaricom can send registration confirmations and related notifications to the callback you register here.
const response = await mpesa.pull.query({
startDate: "2026-03-10 08:00:00",
endDate: "2026-03-11 08:00:00",
offSetValue: 0,
});
for (const tx of response.Transactions) {
console.log(tx.transactionId, tx.amount, tx.billreference);
}
  • Daraja positions this API as a recent-history reconciliation flow, not a long-term statement export.
  • The query window is limited to recent transactions, commonly the last 48 hours.
  • Pagination uses offSetValue, not page numbers.
  • The API is especially useful for C2B/paybill reconciliation after callback delivery problems.

If your Daraja profile supports narrower pull filters, provide filterType and filterValue together:

await mpesa.pull.query({
startDate: "2026-03-10 08:00:00",
endDate: "2026-03-11 08:00:00",
filterType: "MSISDN",
filterValue: "254722000000",
});

The SDK requires both fields together so you do not accidentally submit a partial filter.

  • shortCode is read from the client config unless you override it per call.
  • offSetValue defaults to 0.
  • startDate and endDate must use YYYY-MM-DD HH:MM:SS.
  • The SDK normalizes the transaction list onto response.Transactions even if Daraja returns a lowercase transactions field.

Use Pull Transactions as part of a recovery loop:

  1. Receive and persist normal confirmation callbacks first.
  2. Mark records as timed_out or needs_review when callbacks are missing.
  3. Run mpesa.pull.query() for the affected time window.
  4. Match transactions using bill reference, MSISDN, amount, and your own internal correlation data.
  5. Escalate any ambiguous mismatches instead of auto-crediting blindly.