Dotpay integration
Live payments use Flutterwave hosted checkout. Uganda uses UGX mobile money, Kenya uses KES M-Pesa, Rwanda uses RWF mobile money, and other countries use USD cards.
Before you start
Register your application’s HTTPS return origins. Use a LIVE vendor key, a stable Idempotency-Key, a positive whole-unit amount, currency, customer.email, merchantReference, successUrl and cancelUrl when starting checkout. Open checkoutUrl from the response. Provider credentials stay on Dotpay’s server.
Payment returns and verification
Flutterwave returns to a signed Dotpay address, which verifies the payment and redirects to your stored application URL. An existing webhook on another domain can remain there. Poll your payment status endpoint using your vendor key and retryAfterSeconds; Dotpay verifies by transaction reference directly with Flutterwave. Browser callback parameters never prove payment.
Deliver access only when paid is true and LIVE mode, reference, amount, currency and merchantReference match your stored order. Status access is scoped to your application. Duplicate checks settle once and retain refunds.
Use your Dotpay sandbox key while your business awaits review. A super admin must approve live payments. Sandbox access remains available after approval. Test and live credentials are separate. MTN sandbox uses EUR; Airtel Uganda sandbox and live payments use UGX. Provider credentials stay on the server.
Payment links and requests
Create a link in your account and share it with one customer. Links expire after seven days. Requests are restricted to the recipient’s phone number. Sharing is manual; Dotpay does not send messages.
API checkout
Call POST /api/v_01/vendor/payments/checkout with x-api-key and a unique Idempotency-Key. Keep the same key when retrying an interrupted request.
{
"amount": 25000,
"currency": "UGX",
"network": "MTN",
"phoneNumber": "256772123456",
"description": "Order payment",
"merchantReference": "order-123"
}Poll GET /api/v_01/vendor/payments/status/:reference with the same x-api-key. Only paid: true confirms a matching successful settlement. A pending response means approval or provider reconciliation is still required.
Verify mode, amount, currency and merchantReference against your stored order before granting access. TEST payments never fulfil live orders. The response includes these fields for both initiation and status.
Full merchant API reference · API security
Respect retryAfterSeconds before checking again. Airtel waits at least three minutes before its first status enquiry. Never submit another payment to resolve an ambiguous response.
Merchant sandbox
Use /dashboard/sandbox with your own sandbox key. POST /api/sandbox/payments and GET /api/sandbox/payments?reference= use the same payment service as checkout. These routes reject live keys. MTN provides test numbers for paid, failed, declined, timeout and pending outcomes. Airtel requires test wallets supplied through its onboarding; the Uganda documentation masks example numbers.
Provider setup
Use .env.example for the complete configuration. MTN Collections needs a subscription key, API user and API key for each environment. Airtel needs client ID and client secret for each environment, an approved Collection subscription and an allowed server IP. The adapter defaults to signed Collection v2 on openapiuat.airtel.ug (test) or openapi.airtel.ug (live). It retrieves the RSA public key from Airtel and signs each request with a fresh AES key and IV. Status enquiry remains on the v1 endpoint.
Setup, deployment, migration and operations instructions are in README.md and docs/ARCHITECTURE.md.