One request shape for every rail you accept.
Create a payment with an amount, a currency and a payment method. NATIO evaluates risk, picks a provider, sends the request and returns the outcome together with the route it took. What changes between cards, bank transfers, QR and local methods is configuration, not your integration.
Amounts in minor units. Idempotency on every mutating call.
For synchronous methods the create response already carries the final status. For asynchronous methods it carries processing and a next_action for the customer.
Minor units only
10000 is 100.00 USD. The same rule applies to captures, refunds, fees and payouts.Method as a type or a token
"card", or an object with a provider token or a stored payment method id. Raw card numbers are never accepted.Idempotency
Route on every payment
curl -X POST https://api.natio.me/v1/payments \
-H "Authorization: Bearer natio_sk_test_..." \
-H "Idempotency-Key: order-1001" \
-H "Content-Type: application/json" \
-d '{
"amount": 10000,
"currency": "USD",
"payment_method": "card",
"country": "US",
"reference": "ORD-1001",
"customer": { "external_id": "cus_42", "email": "jane@example.com" },
"capture_method": "automatic"
}'{
"id": "pay_7Kq2mN9xR4vL8wP1tY3z",
"object": "payment",
"mode": "test",
"status": "successful",
"amount": 10000,
"currency": "USD",
"captured_amount": 10000,
"refunded_amount": 0,
"capture_method": "automatic",
"payment_method": { "type": "card", "id": null },
"country": "US",
"reference": "ORD-1001",
"route": {
"provider": { "code": "demo_acquirer_b", "name": "NATIO Demo Acquirer B" },
"provider_payment_id": "dmb_9f21c4",
"attempts": 2,
"rule": "Cards → Acquirer A, fallback Acquirer B"
},
"risk": { "decision_id": "rsk_3Jv...", "score": 0 },
"failure": null,
"next_action": null,
"fee": { "amount": 320, "currency": "USD" },
"processing_time_ms": 83,
"attempts": [
{
"attempt_number": 1,
"status": "failed",
"outcome": "technical_error",
"provider_name": "NATIO Demo Acquirer A",
"provider_code": "GW-500",
"latency_ms": 41
},
{
"attempt_number": 2,
"status": "succeeded",
"outcome": "success",
"provider_name": "NATIO Demo Acquirer B",
"provider_payment_id": "dmb_9f21c4",
"latency_ms": 42
}
]
}Seven method types behind one contract.
Which providers can serve a given type, currency and country is provider configuration. Your request does not change when a market is added.
Cards
Domestic and international card payments through the acquirers and PSPs connected to your account. Card entry happens on a provider hosted page or is tokenised by a PCI-compliant provider.
Bank transfer
Push and pull bank transfers where the provider confirms the credit asynchronously. The payment stays processing until the provider notifies NATIO.
QR
QR-based rails: the provider returns a payload and an expiry, which NATIO passes back as a structured next_action for you to render.
Open banking
Account-to-account initiation where the customer authorises the payment at their bank. Returned as a redirect next_action.
Wallets
Wallet balances and wallet-backed rails, typically synchronous: the create response already carries the final status.
Instant rails
Domestic instant payment schemes with near-real-time confirmation from the provider.
Local methods
Country-specific methods exposed under one contract. Adding a new one is configuration on the provider side, not a new integration on yours.
Ten statuses, guarded transitions.
Every payment moves through an explicit state machine. Transitions are validated in code and guarded in the database, so retries and concurrent webhooks cannot produce an invalid path.
| Status | Meaning |
|---|---|
| created | Accepted and persisted. Risk and routing have not produced a provider attempt yet. |
| pending | Waiting on something outside the request: a manual risk review, or a customer action at the provider. |
| processing | A provider attempt is in flight, or an asynchronous confirmation is outstanding. |
| authorized | Funds reserved by the provider. Reached only with capture_method: manual; capture or cancel next. |
| captured | Transitional state while a capture is being confirmed by the provider. |
| successful | The provider confirmed the payment. Refundable in full or in part. |
| failed | Declined, blocked by risk, or every eligible provider failed. Carries a failure object with code, category and message. |
| cancelled | Cancelled before completion. Terminal. |
| refunded | Refunds cover the full captured amount. Terminal. |
| partially_refunded | One or more refunds cover part of the captured amount. Further refunds are allowed up to the remainder. |
An invalid transition returns 409 invalid_state_transition. Refunds have their own lifecycle: created → processing → successful or failed.
Capture, cancel, refund.
The same three operations exist for every provider, normalised by the adapter layer.
Capture
capture_method: manual the payment stops at authorized. Capture the full amount or less; the remainder is released by the provider.Cancel
Refund
Redirects and QR codes come back as data.
Asynchronous rails need the customer to do something. NATIO returns that as a structured next_action rather than an HTML page, so you decide how to present it.
- redirect
- A url to send the customer to, typically a provider hosted page or a bank authorisation screen. You provide return_url on create.
- qr_code
- A payload to render as a QR code, with an expiry timestamp.
- display_details
- Instructions to show the customer, such as transfer details for a manual bank payment.
- Completion
- The payment stays processing until the provider confirms. NATIO then updates the state machine and delivers a signed webhook (payment.successful or payment.failed).
{
"status": "processing",
"next_action": {
"type": "qr_code",
"qrPayload": "00020101021238...",
"expiresAt": "2026-09-22T10:45:00.000Z"
}
}Hosted pages and tokenisation keep you out of scope.
Card data never touches NATIO. Entry happens on a hosted page operated by a PCI-compliant provider, or is tokenised by that provider in the browser.
What NATIO stores
- Token references
- Provider-issued tokens and stored payment method ids, usable only by the provider that issued them.
- Display metadata
- Brand, last four digits and expiry where the provider returns them, for support and reconciliation.
- Nothing else
- No PAN, no CVV, no magnetic stripe data. The API rejects requests that look like raw card numbers.
What that means for you
- SAQ-A scope
- Redirecting to a hosted page or using provider tokenisation keeps a merchant integration in the smallest PCI scope. Your own obligations depend on your implementation and your assessor.
- Provider-side compliance
- Card acceptance, PCI DSS attestation and acquiring are the responsibility of the licensed providers connected to the platform.
- No custody
- NATIO does not hold or take customer funds. Money moves between you and the licensed providers, which settle directly.
Every attempt is on the record.
A payment is not a single provider call. NATIO stores each attempt and the reasoning around it, and exposes both through the API and the dashboard.
Attempts array
Timeline
Transactions
Webhooks
Send your first test payment.
Create a sandbox account, take a test key and run the full orchestration flow against demo providers — including failover, timeouts and refunds.