Push Transaction
Las transacciones push (payout) transfieren fondos a un destinatario — a una cuenta bancaria, billetera, clave PIX, dirección UPI o tarjeta.
Endpoint
POST https://{FQDN}/v2/payment
Headers:
| Header | Valor |
|---|---|
Authorization | Bearer {accessToken} |
Content-Type | application/json |
El esquema del país es el contrato
Cada país de payout tiene su propio JSON Schema draft-07. Decide qué campos de paymentMethod existen, cuáles son requeridos, el pattern que cada uno debe cumplir, los valores permitidos de walletOperator, si recipient.documents es obligatorio y qué moneda puede llevar el recipientAmount. Estas reglas difieren por corredor y cambian conforme se agregan corredores — un recipient fijado para un país será rechazado por el siguiente.
Consulta el esquema del país de destino y construye la solicitud a partir de él:
GET https://{FQDN}/schema/{countryCode}
El countryCode es ISO 3166-1 alpha-3 (BRA, IND, PHL). La respuesta cubre recipient, recipientAmount y additionalData — y, en los corredores que lo restringen, sender. Consulta Schemas para la referencia completa del endpoint.
El
senderestá presente en algunos esquemas de país y ausente en otros. Donde aparece, ajusta las reglas del lado del remitente más allá del esquema genérico de push; donde está ausente, solo aplican las reglas genéricas. Esto se está completando — trata un bloquesenderausente como "aún no restringido aquí", no como "nunca se restringirá". Leer el bloque al momento de la solicitud, en vez de guardar una copia, es lo que te mantiene al día.
Este es el esquema contra el que el gateway valida el
POST /v2/payment, así que es el único que responde "¿se aceptará este payload?" para un push.
flowchart TD
A[Elige el país de destino] --> B["GET /schema/{countryCode}"]
B --> C{"paymentMethod.type<br/>ofrecido por el corredor"}
C -->|BANK_DEPOSIT| D["accountNumber + los<br/>campos que el esquema exige"]
C -->|WALLET| E["walletId + walletType<br/>+ walletOperator"]
C -->|PIX| F["key + keyType"]
C -->|CARD| G["cardTokenId"]
D --> H["Incluye recipient.documents y<br/>additionalData.paymentPurpose<br/>si el esquema lo exige"]
E --> H
F --> H
G --> H
H --> I["POST /v2/foreign-exchange<br/>para un fxId cotizado"]
I --> J["POST /v2/payment"]
Estructura de la Solicitud
Objeto Raíz
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
externalPaymentId | string | Sí | Tu identificador único del pago (clave de idempotencia) |
ipAddress | string | Sí | Dirección IPv4 o IPv6 del originador |
paymentType | string | Sí | "PUSH" |
amount | object | Sí | Monto de origen (lo que estás enviando) |
recipientAmount | object | Sí | Monto de destino (lo que recibe el destinatario) |
sender | object | Sí | Datos y dirección del remitente |
recipient | object | Sí | Datos, dirección y método de payout del destinatario |
fxId | string | Sí | Identificador de la cotización FX del endpoint Cambio de divisas |
dynamicDescriptor | string | No | Texto a mostrar en el estado de cuenta del destinatario |
additionalData | object | No | Extras del corredor — consulta additionalData |
Cotiza una tasa FX y envía su
fxIden cada push. Es lo que vincula el pago a la tasa que cotizaste; sin él el gateway calcula la conversión por su cuenta y el destinatario puede recibir un monto distinto al que mostraste a tu usuario. Lo mismo aplica aPULLPUSH.
No existe un campo
captureen un push. La captura y la preautorización son conceptos del lado pull; un push no tiene autorización que retener.
amount / recipientAmount
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
total | number | Sí | Monto, mínimo 0 |
currency | string | Sí | Código ISO 4217 |
El amount es el lado de origen, el recipientAmount el de destino. La moneda de destino es fija por país — cada esquema de país fija el recipientAmount.currency a un enum, así que BRA solo acepta BRL y DEU solo EUR. La única excepción es Guinea (GIN), que acepta GNF o XOF.
Objeto sender
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
firstName | string | Sí | Nombre del remitente |
lastName | string | Sí | Apellido del remitente |
address | object | Sí | Dirección del remitente |
birthDate | string | Varía | YYYY-MM-DD. Requerido en KOR |
birthCountryCode | string | Varía | ISO alpha-3. Requerido en KOR |
Objeto sender.address
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
countryCode | string | Varía | Código ISO alpha-3 (ej.: "USA") |
city | string | Varía | Ciudad |
line1 | string | Varía | Dirección, línea 1 |
stateCode | string | No | Código de estado (ej.: "MA") |
line2 | string | No | Dirección, línea 2 |
zipCode | string | No | Código postal |
El esquema genérico de push exige el objeto address pero no marca ningún campo dentro de él como requerido. Varios países de destino lo sobrescriben y exigen countryCode, city y line1:
BGD, CHL, CHN, CIV, GIN, IDN, KEN, LKA, MDG, MLI, MYS, NGA, PAK, PHL, SGP, TUR
Corea del Sur (KOR) es la excepción en forma: agrega sender.birthDate y sender.birthCountryCode — ambos validados por pattern — en vez de ajustar la dirección. China (CHN) acepta un sender.birthDate opcional además de la regla de dirección.
Llenar
countryCode,cityyline1en todo push es el valor por defecto más seguro. No cuestan nada en los corredores que no los exigen, y son justamente lo que la lista de arriba seguirá creciendo para abarcar.
Objeto recipient
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
firstName | string | Sí | Nombre del destinatario |
lastName | string | Sí | Apellido del destinatario |
paymentMethod | object | Sí | Método de payout y sus datos |
address | object | Varía | Requerido por muchos corredores — consulta Cobertura por país |
documents | array | Varía | Documentos de identidad — requeridos por BRA, CHL, COL, TUR, y por KEN en BANK_DEPOSIT |
email | string | Varía | Requerido por COL |
phoneNumber | string | Varía | Requerido por KOR, MNG |
birthDate | string | Varía | Requerido por KOR |
birthCountryCode | string | Varía | Requerido por KOR |
El esquema del país es la autoridad en cada fila "Varía" de arriba.
Array recipient.documents
Cada entrada:
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
document | string | Sí | El número del documento |
type | string | Sí | Tipo de documento — el enum del esquema es específico por país |
countryCode | string | No | País emisor del documento |
El campo se llama document, no value. Tipos aceptados por país:
| País | Valores de type | ¿Requerido? |
|---|---|---|
Brasil (BRA) | CPF — 11 dígitos, o formateado 123.456.789-09 | Sí |
Colombia (COL) | CC | Sí |
Turquía (TUR) | ID, PASSPORT, DRIVER_LICENSE | Sí |
Chile (CHL) | RUT | Sí |
Kenia (KEN) | ID, PASSPORT | En BANK_DEPOSIT |
additionalData
| Campo | Tipo | Descripción |
|---|---|---|
paymentPurpose | string | Código regulatorio de finalidad del pago. Requerido por varios corredores, y los códigos aceptados son un enum específico por país — algunos tienen media docena, otros bastante más de cien |
statementNarrative | string | Texto libre que describe la transacción |
El paymentPurpose es siempre requerido en CAN, CHN, COL, EGY, GMB, IDN, IND, KOR, MYS, NPL, PAK, SGP, THA, VNM, y requerido en BANK_DEPOSIT en BGD y PHL. Lee los códigos aceptados directo del esquema del país — no son una lista compartida, y un código válido en Tailandia no vale en Malasia.
Varios corredores exigen el objeto
additionalDatapresente aunque no lleve nada dentro. El esquema pide la clave pero no obliga ninguna propiedad, así que un payload sin"additionalData": {}es rechazado conVE_001 — additionalData can't be emptymientras un objeto vacío pasa. La Cobertura por país marca esos casos.
Cambio de divisas (FX)
Para pushes entre monedas, consulta una tasa antes de enviar y pasa el fxId devuelto — el gateway entonces aplica la tasa vinculada a esa cotización.
Las tasas difieren por método de pago, así que cotiza para el método con el que vas a pagar. Consulta Foreign Exchange para los esquemas completos de solicitud/respuesta.
Ejemplo rápido:
curl -X POST https://{FQDN}/v2/foreign-exchange \
-H 'Authorization: Bearer eyJhbGciOiJSUzI1NiIs...' \
-H 'Content-Type: application/json' \
-d '{
"sourceCurrencyCode": "USD",
"destinationCurrencyCode": "BRL",
"paymentMethod": "BANK_ACCOUNT"
}'
{
"fxId": "b2c3d4e5-...",
"conversionRate": 4.975,
"sourceCurrencyCode": "USD",
"destinationCurrencyCode": "BRL",
"paymentMethod": "BANK_ACCOUNT",
"quoteIdExpiryDateTime": "2025-03-31T15:30:00Z"
}
Nota: las cotizaciones FX tienen validez limitada. Verifica el
quoteIdExpiryDateTimey renueva si expiró.
Respuesta
Un push se acepta de forma asíncrona. Un 200 con status: "PENDING" significa que el gateway recibió el pago, no que el destinatario fue pagado:
{
"paymentId": "bda24392-cac5-4fcf-af80-4a29df3ba0ff",
"parentPaymentId": "bda24392-cac5-4fcf-af80-4a29df3ba0ff",
"externalPaymentId": "push-bgd-001",
"amount": 20.0,
"created": "2026-07-15 21:29:50",
"status": "PENDING",
"approved": false,
"captured": false,
"voided": false,
"responseCode": "01",
"automaticReversed": false
}
Consulta GET /v2/payment/{externalId} o espera el webhook para el desenlace liquidado. No trates approved: false en un push PENDING como un rechazo — solo refleja que ninguna autorización ha sido aprobada aún, que es el estado normal de un push en tránsito.
Qué sigue
- Métodos de payout — Referencia de campos para
BANK_DEPOSIT,WALLET,PIXyCARD - Cobertura por país — Todos los corredores y lo que exige cada uno
- Ejemplos — Cuerpos de solicitud completos, por región
- Errores —
PAY_001yPAY_271
