Create payment
/api/v1/paymentsDirect-charge flow — devolvemos el paymentFormUrl del provider upstream para que vos embebas / redirijas.
cascade_exhausted con reason no_provider_for_method_region — retry una vez antes de hacer nada más. El cascade engine ya hace un force-reload de su estado interno en este escenario, así que un segundo intento ve la misma verdad que tu listing. Si el retry también falla:details.paymentMethodEnabledForShop === false→ hardcodeaste un código que no es de TU shop. Llamá GET /api/v1/payment-methods de nuevo.details.paymentMethodEnabledForShop === true→ hay un mismatch real en nuestra config; abrí ticket con elrequestIdy lo destrabamos en minutos.
paymentFormUrl del provider upstream (ej. secure-int.key2pay.io/checkout?token=…). Vos redirigís o embebés ese URL. Te da más control sobre la UI.checkoutUrl y manejamos toda la UI por método (QR, CLABE, redirect, voucher). Vos solo redirigís. 1 línea de integración./api/v1/paymentssecret keyInicia un cobro server-to-server. El shop se identifica vía el Bearer token (POST /api/v1/auth/token). Pasá `paymentMethodId` con el id 4-dígitos que devuelve GET /api/v1/payment-methods. Cada retailer / banco / método nativo tiene su propio id único (ej. 1001 → SPEI, 1002 → OXXO, 1003 → Walmart, 1004 → 7-Eleven, 1005 → BBVA, 1006 → Scotiabank) y el cascade rutea exactamente a ese upstream. El mismo `paymentMethodId` vuelve en la respuesta y queda queryable en GET /api/v1/payments. La respuesta incluye `paymentFormUrl` (URL del provider upstream — vos redirigís ahí o embebés). Si preferís nuestra UI hosted, usá POST /api/v1/checkout/sessions que devuelve `checkoutUrl` propio. La cripto de settlement, la wallet de destino y el nivel de KYC se derivan internamente del config del merchant — no se envían en el body. Nota: el path legacy `POST /api/v1/transactions` funciona exactamente igual; usa el que prefieras.
amountnumberrequiredMonto en USD. > 0, máx 100,000.paymentMethodIdstringrequiredEl código 4-dígitos de GET /api/v1/payment-methods. Cada retailer / banco / método nativo tiene su propio código único (ej. "1001" SPEI, "1002" OXXO, "1003" Walmart, "1005" BBVA). Los códigos son NUESTROS — asignados por la plataforma y estables aun cuando rotamos providers upstream. Este es el campo recomendado y el único que garantiza ruteo determinístico al rail específico.paymentMethodstringLegacy. Slug ambiguo (card · debit · spei · pix · oxxo · voucher · bank_transfer · …). Se acepta solo como fallback cuando no se manda `paymentMethodId`. El cascade elige cualquier provider del bucket de slug + país, sin garantizar un retailer específico — por ejemplo `voucher` + MEX podría rutear Walmart o 7-Eleven. Usa `paymentMethodId` en código nuevo.countrystringPaís del pagador. Acepta ISO-3 (BRA, MEX, COL, ARG, CHL, PER, …) o ISO-2 (BR, MX, CO, AR, CL, PE, …) indistintamente — normalizamos a ISO-3 internamente. Default: USA.userEmailstringEmail del pagador, máx 254 chars.userNamestringNombre del pagador, máx 120 chars.userIpstringIP del pagador (también la inferimos del request).merchantOrderIdstringYour own reference id (any string ≤120 chars). Stored on the transaction and queryable via GET /transactions?merchantOrderId=… for disaster-recovery lookup.hostedCheckoutbooleanWhen true, the response includes `checkoutUrl` — a Key2Pay-hosted page that renders QR / CLABE / redirect UI per the selected method. Redirect the customer there and listen for the webhook.returnUrlstringWhere the hosted checkout sends the customer once they finish (or click Return). Only used when `hostedCheckout: true`.merchantIdstringSolo si tu token cubre múltiples merchants; default: el del shop.shopIdstringIdem para múltiples shops.
curl https://api.ionea.io/api/v1/payments \
-H "Authorization: Bearer sk_test_51N8mP...exampleK3Y" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"amount": 50,
"paymentMethodId": "sbx_spei",
"country": "MEX",
"userEmail": "test@test.com",
"merchantOrderId": "ORD-12345"
}'
# sandbox: use a sbx_ test method (sbx_pix/sbx_spei/sbx_card/sbx_pse/sbx_cash).
# production: use the 4-digit code from GET /payment-methods (e.g. 1001 SPEI).
# For OUR hosted checkout page add "hostedCheckout": true → response carries checkoutUrl
# instead of paymentFormUrl. See /docs/endpoints/hosted-checkout.{
"transactionId": "TXN-MVZQXW7B-A4F2",
"status": "pending",
"amount": 50.00,
"amountLocal": 882.17,
"currencyLocal": "MXN",
"paymentMethodId": "sbx_spei",
"fees": {
"platform": 1.45,
"provider": 0,
"network": 0,
"total": 1.45
},
"settlement": {
"type": "delayed",
"delay": "T+2",
"reserve": 5,
"status": "pending"
},
"paymentFormUrl": "https://secure-int.key2pay.io/checkout?token=…",
"paymentData": { "method": "spei" },
"expiresAt": "2026-05-12T16:00:00.000Z"
}country: aceptamos ISO-2 ("MX", "BR","CO", …) e ISO-3 ("MEX", "BRA","COL", …) indistintamente. Internamente normalizamos a ISO-3 antes de rutear, así que cualquiera de los dos formatos funciona igual. Si pasás paymentMethodId sin country, el país se infiere del id 4-dígitos (cada uno está atado a un país específico)./api/v1/paymentssandboxamountintegerRequiredpaymentMethodIdstringRequiredcountryenumuserEmailstringuserNamestringhostedCheckoutstringcurl -X POST "https://api.ionea.io/api/v1/api/v1/payments" \
-H "Authorization: Bearer sk_test_…YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"amount": 50,
"paymentMethodId": "sbx_spei",
"country": "MEX",
"userEmail": "test@test.com",
"userName": "Cliente de Prueba",
"hostedCheckout": "false"
}'