Payments
A payment moves through one normalized status machine regardless of PSP: created → processing → requires_action? → authorized → captured, ending in voided, failed, partially_refunded or refunded. Amounts are always integers in the currency's minor unit.
Payment methods
| type | payload | routes to |
|---|---|---|
sim_card | none — outcome scripted by amount | simulator (sandbox test PSP) |
card | stripe.token and/or adyen.encrypted* fields from the PSP's client-side components | any PSP whose section is present |
token | token: "tok_…" | PSPs holding a reference for the token |
For card payments you can include multiple provider sections — that's what lets a single request survive fallback across PSPs.
Manual capture
Refunds
Multiple partial refunds are supported; the platform enforces the refundable balance and rejects over-refunds with 400 invalid_request before the PSP is ever called. Payment status moves to partially_refunded and finally refunded.
Searching
3DS / SCA
When a challenge is required the payment returns status: requires_action with next_action.url when the PSP provides a redirect. Completion arrives via the PSP's webhook and is reflected in the payment status — subscribe to payment.captured / payment.failed rather than polling.