Skip to content

Create a channel merchant's checkout session

Call POST /api/checkout-sessions from the channel’s server. Authenticate with the channel key as Authorization: Bearer sk_... and name the merchant explicitly with X-Merchant-Id: <merchant_id>.

create-checkout-session.sh
curl --request POST \
--url https://staging.api.maxanapay.com/api/checkout-sessions \
--header 'Authorization: Bearer sk_test_replace_me' \
--header 'X-Merchant-Id: b3f1c8de-7a20-4c55-9e64-1d8f2a6b40c7' \
--header 'Content-Type: application/json' \
--header 'Idempotency-Key: order_1001_checkout' \
--data @request.json

This is where the credential models diverge. The same operation accepts a direct merchant’s own key without the extra header, but a channel key represents many merchants and cannot resolve one without X-Merchant-Id. Maxana verifies that the selected merchant belongs to the calling channel.

Keep two identifiers from that response. checkout_session_id is what the browser step mounts and what every webhook about this order carries. external_order_id is the value you sent, echoed back and carried on the same events, so a delivery resolves to your order without a lookup.

amount is not returned that way. The session holds the value rather than your string, so "10.00" comes back as "10"; the "49.95" in the example above survives unchanged only because it has no trailing zero to lose. Compare it as a decimal, never as text. Amounts and currencies carries that rule and the currency codes this field accepts — every ISO 4217 code still in use, not a shorter list — and which of them a merchant can be paid in. A PayPal session whose currency is not the account’s primary settlement currency is refused here at creation with 400; read the merchant’s paypal_primary_currency from the onboarding status and open the session in it.

The session also has a clock. It starts at creation rather than when the buyer arrives, and expires_in_minutes sets it; how long a session lasts covers the default, the range, and how to choose against the page the buyer will be looking at.

Create the body from that merchant’s authoritative order record and use an Idempotency-Key when retrying the same session-creation intent. Store the returned session identifier with both your order and merchant record. Refer to the shared checkout-session contract for fields and limits.

The response says test, and the SDK wants sandbox

Section titled “The response says test, and the SDK wants sandbox”

environment on the response is the credential’s environment, and it takes one of test or live. The browser SDK’s environment option is a different vocabulary and takes one of live or sandbox.

They are not interchangeable, and they share exactly one spelling — live — which is what makes the other one easy to miss. Piping the session’s test into the SDK option throws config_error before anything mounts. Select the SDK environment from your own deployment configuration, not from a field in the session.

There is no merchant_id or channel_id field in the request body. Neither a browser-supplied tenant identifier nor a body property can override credential scope. The session is immutable; create another one when order facts change.

Continue to Add checkout to the merchant experience.