Skip to main content
FinConnect initiates USSD push payments — the customer receives a prompt on their mobile device to authorize the payment. Your server submits the payment request to the provider; the provider then contacts the customer’s phone to complete the transaction.

Payment flow

1

Your server calls sdk.pay()

You call sdk.pay(paymentData, ipnId) with the payment details and (for PesaPal) the IPN ID returned from a prior sdk.registerIpn() call.
2

FinConnect authenticates with the provider

The SDK fetches a fresh auth token from the provider using your configured credentials. See Authentication for details.
3

Provider sends a USSD push notification

The provider delivers a USSD prompt to the customer’s mobile number included in the payment payload.
4

Customer enters their PIN to authorize

The customer confirms the payment on their device by entering their mobile money PIN.
5

Provider sends an IPN notification

The provider sends a payment status notification to your registered webhook URL (PesaPal only).
6

Your server processes the notification

Your webhook handler receives the notification and confirms or rejects the order.

The sdk.pay() method

await sdk.pay(paymentData: any, ipnId?: string): Promise<any>
The ipnId parameter behaves differently per provider:
  • PesaPalipnId is required. The SDK merges it into the payload as notification_id before submitting to POST /api/Transactions/SubmitOrderRequest.
  • ClickPesaipnId is ignored. The raw paymentData object is sent directly to POST /third-parties/payments/initiate-ussd-push-request.
  • AzamPayipnId is ignored. The raw paymentData object is sent directly to POST /azampay/mno/checkout.
For PesaPal payments, you must register an IPN URL first and include the returned ipnId. Omitting it means PesaPal has nowhere to send payment status callbacks.

Registering an IPN URL (PesaPal)

Before you initiate a PesaPal payment, register your webhook URL to receive payment notifications:
const ipnId = await sdk.registerIpn(
  'https://yourdomain.com/webhooks/pesapal',
  'POST'
);
registerIpn() calls POST /api/URLSetup/RegisterIPN and returns an ipn_id string. Pass this value as the second argument to sdk.pay().

Payment payload examples

The SDK merges notification_id into your payload and posts it to POST /api/Transactions/SubmitOrderRequest with a Bearer token:
const ipnId = await sdk.registerIpn('https://yourdomain.com/webhooks/pesapal', 'POST');

const result = await sdk.pay(
  {
    id: 'ORDER-001',
    currency: 'KES',
    amount: 1500,
    description: 'Payment for order ORDER-001',
    callback_url: 'https://yourdomain.com/payments/callback',
    billing_address: {
      email_address: 'customer@example.com',
      phone_number: '0712345678',
      country_code: 'KE',
      first_name: 'Jane',
      last_name: 'Doe',
    }
  },
  ipnId
);
The final request body sent to PesaPal includes all fields above, plus notification_id: ipnId.