Payments and charges
A payment intent is the instruction to collect an amount. A charge is one attempt against one provider. A declined card followed by a successful mobile-money payment is two charges under one payment.
Creating
Amount, currency, country and method type are required. Everything else — a customer, a wallet, a reference, provider parameters — is optional and is frozen onto the payment at creation.
curl https://api.idealbox.org/v1/payment_intents \
-H "Authorization: Bearer ib_sk_test_4f2a9c1e8b7d6053" \
-H "Idempotency-Key: 9f2c1e44-7b21-4c0e-93a1-2f7c8d5e1a0b" \
-H "Content-Type: application/json" \
-d '{
"amount": "500000",
"currency": "XAF",
"country": "CM",
"methodType": "MOBILE_MONEY",
"reference": "order-4471",
"providerParams": { "phoneNumber": "+237699000000" }
}'Confirming
Confirming routes the payment. Routing is deterministic — priority, then merchant scope, then specificity, then id — and an open circuit makes the router skip a provider rather than fail the payment, so a second viable route keeps you trading through an outage.
curl -X POST \
https://api.idealbox.org/v1/payment_intents/pi_01JAY2K5RQ9M3W7ZB8XF4TC6VD/confirm \
-H "Authorization: Bearer ib_sk_test_4f2a9c1e8b7d6053"The next action
Switch on flowKind, never on the provider name. There are six values and there will only ever be six: a new provider maps onto an existing one rather than adding a seventh. That is what lets us enable a provider without you shipping anything.
| flowKind | What you render |
|---|---|
| DEVICE_PUSH | The customer gets a USSD or in-app prompt and enters their PIN. Nothing happens in the browser — most mobile money runs this way. |
| REDIRECT | The browser goes to the provider — a 3-D Secure challenge, a Wave page, a PayPal login — and comes back to your return URL. |
| OTP_CHALLENGE | The provider issues a code the customer reads out. You collect it and submit it to confirm the payment. |
| DIRECT | The instrument is already authorised — a tokenised card, an Apple Pay or Google Pay token. It resolves on the first call. |
| QR_DISPLAY | Render the code we return and the customer scans it with their wallet app. Useful in person and on desktop. |
| VOUCHER_INSTRUCTION | Show the customer where to send funds and the reference to quote. We match the inbound transfer and resolve the payment. |
curl "https://api.idealbox.org/v1/providers?country=CM¤cy=XAF&amount=500000" \
-H "Authorization: Bearer ib_sk_test_4f2a9c1e8b7d6053"Payment status
Status only ever moves forward. A reversal is a new object — a refund — never a status rolled back, so the first terminal value you see is safe to act on.
| status | Meaning | Final |
|---|---|---|
| REQUIRES_PAYMENT_METHOD | Created without a method. Rare — most integrations name one at creation. | No |
| REQUIRES_CONFIRMATION | Ready to start. Nothing has been charged yet. | No |
| REQUIRES_ACTION | Waiting on the customer to approve, redirect or enter a code. | No |
| PROCESSING | Routed to a provider and under way. | No |
| REQUIRES_CAPTURE | Authorised, awaiting an explicit capture. | No |
| SUCCEEDED | The funds are confirmed. Fulfil the order here. | Yes |
| FAILED | Terminal failure, carrying a canonical failure code. | Yes |
| CANCELED | Cancelled by you or by the customer before it completed. | Yes |
| EXPIRED | The customer never completed it in time. Not a decline. | Yes |
Charge status
You rarely need these, but they are what the timeline on a payment is made of, and the failure code lives on the charge rather than the payment.
| status | Meaning |
|---|---|
| PENDING | Sent to the provider; no outcome yet. |
| AUTHORIZED | Funds held but not captured. |
| SUCCEEDED | Captured. |
| FAILED | Declined, with a failure code. |
| CANCELED | The authorisation was released without capture. |
| EXPIRED | The window elapsed with no answer. |
| REFUNDED | Fully reversed by refunds. |
| PARTIALLY_REFUNDED | Partly reversed. |
| DISPUTED | The payer’s bank has opened a chargeback. |