Skip to main content
The direct API gives you full control over the payment experience. You call the discovery endpoints to learn what is available for this intent, present the choice to your customer, create an attempt, and handle the result.
Never hard-code country codes or method codes in your integration. The discovery endpoints are the contract — only methods returned at runtime are guaranteed to be routable for this intent.

Flow

1

Create a payment intent

Required fields: amount, currency, description, customer. See full field reference below.
The response returns the intent with status: pending. Save the intent id — you will use it in every subsequent call.
2

Discover available countries

Returns the list of countries where at least one method is available for this intent.
meta.supports_any_country: true means the intent can be attempted without selecting a specific country — present the method list without a country selector in that case.Both discovery endpoints return 422 when the intent is already in a final status.
3

Discover available methods for a country

countryCode is a two-letter code (e.g. DE). An optional currency query parameter filters to methods that support a specific currency.
Present the returned methods to your customer. Do not filter or hardcode them.
4

Create an attempt

Required: method_code (the value from the methods response), country (2-letter code), phone (a valid phone number object). Optional: currency.
The response returns the updated payment intent (not the attempt), including the active attempt with its next_action and status.
5

Handle the next action

Check active_attempt.next_action.type on the returned intent. See Next actions for the complete reference.If the type is collect_otp or complete_with_sdk, you must call confirm or authorize once the customer supplies the required input. All other types resolve asynchronously — wait for the webhook or poll.
6

Confirm if required

Use authorize when you do not have the specific attempt id:
Use confirm when you have the attempt id:
Both accept: otp (string, max 10 characters), confirmation_data (object). Both return the updated payment intent.
7

Check the final status

Poll GET /payment/intents/{intentId} or listen for the payment.completed / payment.failed webhook. See Webhooks.A failed attempt does not fail the intent — while the intent remains pending, you may start another attempt.

Intent fields

POST /payment/intents

Required: Optional:

Inline attempt

If you already know the method and country, you can start an attempt in the same call as intent creation by including an attempt object:
This creates the intent and immediately runs the first attempt. The response is the same as POST /payment/intents, with the active attempt already populated.

Inspect an attempt

For support and debugging, you can retrieve the raw record held by the underlying provider:
string
The gateway that processed this attempt.
string
The provider’s transaction identifier.
string
ISO 8601 timestamp of when the raw record was fetched.
object
The raw record returned by the underlying provider, unmodified.
This endpoint is for diagnostics. Do not build business logic on payload — its structure varies by provider and may change without notice.

Gateway options

gateway_options is a free-form object keyed by gateway code. Pass it when you need to send gateway-specific parameters that do not have a first-class field in the intent. Unknown gateway codes and gateways that accept no options are rejected with a 422 validation error on gateway_options.{code}. The following gateways currently accept options: