Collecting the payment
How a created payment is actually collected: the paymentData block, the paymentFormUrl redirect for direct charge, and the hosted-checkout alternative.
POST /api/v1/payments creates a pending transaction and returns a paymentFormUrl— the provider's hosted page where the buyer completes the payment (the CLABE for SPEI, the QR for PIX, the voucher for cash, the card form, etc. are rendered there). The API does not return those per-method instruction fields inline.
The response envelope
{
"transactionId": "TXN-...",
"status": "pending",
"paymentMethodId": "sbx_spei",
"amount": 50.00,
"amountLocal": 882.17,
"currencyLocal": "MXN",
"paymentFormUrl": "https://secure-int.key2pay.io/checkout?token=...",
"paymentData": { "method": "spei" },
"expiresAt": "..."
}paymentData actually contains: only { "method": "<slug>" } — the resolved method slug. It does NOT carry a CLABE, QR code, voucher code, bank account, or per-method expiresAt. Those live on the provider's hosted page behind paymentFormUrl. (The top-level expiresAt in the envelope is a short placeholder, not a per-method deadline.)Direct charge → redirect the buyer
For the direct-charge flow, send the buyer to paymentFormUrl (redirect, open in a new tab, or embed in an iframe). They complete the payment on the provider's page; you learn the outcome from the webhook (payment.completed / payment.failed) or by polling GET /payments/{id}.
const res = await api.post("/payments", {
amount: 50, paymentMethodId: "sbx_spei", country: "MEX", userEmail: "test@test.com",
});
// Direct charge: redirect the buyer to the provider's hosted page.
window.location.href = res.paymentFormUrl;
// Then react to the payment.completed webhook (or poll GET /payments/{id}).Method slugs
paymentData.methodis one of the canonical method slugs. Switch on it if you want method-aware copy, but you don't need to render per-method UI — the provider's page does that.
carddebitbank_transferwirespeipixoxxoboletovoucheronline_paymentapplepaygooglepaycryptoPrefer not to redirect to the provider? Use hosted checkout
POST /api/v1/checkout/sessions returns a single checkoutUrl on OUR domain — we render the method picker + the per-method UI (CLABE/QR/voucher) for you, and the buyer never sees the upstream provider. See the hosted-checkout doc for the full flow.