POST /api/v1/payments
Direct-charge flow — devolvemos el paymentFormUrl del provider upstream para que vos embebas / redirijas.
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://sandbox.key2pays.com/api/v1/payments \
-H "Authorization: Bearer sk_test_51N8mP...exampleK3Y" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"amount": 50,
"paymentMethodId": "1001",
"country": "MEX",
"userEmail": "test@test.com",
"merchantOrderId": "ORD-12345",
"hostedCheckout": true,
"returnUrl": "https://your-site.com/return"
}'{
"transactionId": "TXN-MVZQXW7B-A4F2",
"status": "pending",
"amount": 50.00,
"amountLocal": 882.17,
"currencyLocal": "MXN",
"fxRate": 17.64,
"paymentMethodId": "1001",
"fees": {
"platform": 1.45,
"provider": 1.50,
"network": 1.50,
"total": 4.45
},
"settlement": {
"type": "delayed",
"delay": "48h",
"reserve": 5,
"status": "pending"
},
"paymentFormUrl": "https://secure-int.key2pay.io/checkout?token=…",
"checkoutUrl": "https://sandbox.key2pays.com/c/TXN-MVZQXW7B-A4F2?returnUrl=https%3A%2F%2Fyour-site.com%2Freturn",
"paymentData": {},
"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://sandbox.key2pays.com/api/v1/api/v1/payments" \
-H "Authorization: Bearer sk_test_…YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"amount": 50,
"paymentMethodId": "1001",
"country": "MEX",
"userEmail": "test@test.com",
"userName": "Cliente de Prueba",
"hostedCheckout": "false"
}'