Órdenes
Una Orden es lo que efectivamente mueve el
dinero: consume una cotización creada antes y ejecuta el
pago a un beneficiario nombrado. createOrder crea una, listOrders recorre
el historial de órdenes de la compañía, y getOrder lee una orden puntual
por id. Consulta estado de la orden para lo
que informa el campo status a lo largo del ciclo de vida de la orden.
createOrder(...)
Consume una cotización y crea una orden para el beneficiario y las instrucciones de pago indicadas.
Firma
createOrder(req: CreateOrderRequest, idempotencyKey?: string): Promise<Order>
Parámetros
| Nombre | Tipo | Obligatorio | Descripción |
|---|---|---|---|
req.quotation_id | string | Sí | UUID de la cotización de createQuotation. De uso único. |
req.metadata | Record<string, string> | No | Pares clave/valor libres, se devuelven sin modificar en las lecturas. |
req.purpose | string | Sí | Propósito de la remesa. Uno de FAMILY_SUPPORT, PAYMENT_OF_BILLS, PURCHASE_OF_GOODS, PROFESSIONAL_SERVICES, RENTAL_OF_SPACES, INVESTMENTS, COMMISSIONS_LOANS_CAPITAL_INCREASE, TRANSPORTATION_COSTS, FEES. |
req.sender.names | string | Sí | Nombre(s) del remitente. |
req.sender.last_names | string | Sí | Apellido(s) del remitente. |
req.sender.document.type | string | Sí | Tipo de documento, ej. "CC". |
req.sender.document.id | string | Sí | Número de documento. |
req.sender.document.country | string | Sí | Código de país ISO alpha-2 de 2 caracteres donde se emitió el documento. |
req.sender.country | string | Sí | Código de país ISO alpha-2 de 2 caracteres del remitente. |
req.sender.phone | string | No | Teléfono del remitente, formato E.164 (ej. "+584121234567"). Se valida del lado del cliente cuando está presente. Solo vuelve en sender en las lecturas si lo enviaste al crear. |
req.sender.email | string | No | Email del remitente. Se valida como dirección de email cuando está presente. Solo vuelve en sender en las lecturas si lo enviaste al crear. |
req.destination.receiver.names | string | Sí | Nombre(s) del beneficiario. |
req.destination.receiver.last_names | string | Sí | Apellido(s) del beneficiario. |
req.destination.receiver.document.type | string | Sí | Tipo de documento del beneficiario, ej. "V". |
req.destination.receiver.document.id | string | Sí | Número de documento del beneficiario. |
req.destination.receiver.document.country | string | Sí | Código de país ISO alpha-2 de 2 caracteres donde se emitió el documento. |
req.destination.receiver.email | string | No | Email del beneficiario. Se valida como dirección de email cuando está presente. |
req.destination.receiver.country | string | Sí | Código de país ISO alpha-2 de 2 caracteres del beneficiario. |
req.destination.payment_instructions.bank_account | object | Uno de los dos | { bank_name, number, type }. Mutuamente excluyente con bank_phone_account. |
req.destination.payment_instructions.bank_account.bank_name | string | — | Un código de catálogo cerrado del catálogo de bancos de Venezuela, ej. "BANCO_BANESCO_VE" — nunca un nombre comercial. |
req.destination.payment_instructions.bank_account.number | string | — | Número de cuenta. |
req.destination.payment_instructions.bank_account.type | "CHECKING" | "SAVINGS" | "CORRIENTE" | "AHORRO" | — | Tipo de cuenta. |
req.destination.payment_instructions.bank_phone_account | object | Uno de los dos | { bank_name, phone_number, document_id? }. Mutuamente excluyente con bank_account. |
req.destination.payment_instructions.bank_phone_account.bank_name | string | — | El mismo catálogo cerrado que bank_account.bank_name. |
req.destination.payment_instructions.bank_phone_account.phone_number | string | — | Formato E.164, ej. "+584121234567". |
req.destination.payment_instructions.bank_phone_account.document_id | string | No | Si se omite, del lado del servidor recae en destination.receiver.document.id. |
idempotencyKey | string | No | Tu referencia de idempotencia. Se autogenera como UUID v4 si se omite. Se devuelve como idempotency_key en la orden. |
payment_instructions lleva exactamente uno de bank_account o
bank_phone_account — nunca los dos, nunca ninguno.
Retorno
Order:
| Campo | Tipo | Significado |
|---|---|---|
id | string | Identificador de la orden. |
idempotency_key | string (opcional) | La clave de idempotencia devuelta. |
type | string | Tipo de orden, ej. "REMITTANCE". |
status | string | Consulta estado de la orden. |
quotation_id | string | La cotización que esta orden consumió. |
amount | string | Monto en moneda origen, como string decimal. |
currency | string | Moneda origen. |
metadata | Record<string, string> | Se devuelve sin modificar. |
purpose | string | null (opcional) | Propósito de la remesa, cuando se informa. |
sender | object (opcional) | Misma forma que el sender del request. Se omite en algunos estados. |
destination.receiver | object (opcional) | Misma forma que el receiver del request. |
destination.payment_instructions | object (opcional) | Agrega un bank_display_name de solo lectura (el nombre comercial resuelto del catálogo) junto a los códigos que enviaste. |
destination.target_amount / destination.target_currency | string (opcional) | Monto/moneda del pago, una vez que se despachó. |
execution.source.status / execution.destination.status | string | Estado de ejecución por tramo, ej. "COMPLETED", "PENDING". |
execution.source.reference_id / execution.destination.reference_id | string | null | Id de referencia por tramo. |
events | array (opcional) | Línea de tiempo de cambios de estado: { id, from_status, to_status, trigger, reason, message, created_at }. |
failure_code / failure_reason | string | null (opcional) | Solo se completa cuando status === "FAILED". |
created_at / updated_at | string | Timestamps ISO 8601. |
Ejemplo
import {
RetornaClientBuilder,
RetornaEnvironment,
} from "@retorna-tech/retorna-gateway-sdk";
const client = new RetornaClientBuilder()
.environment(RetornaEnvironment.SANDBOX)
.clientId(process.env.RETORNA_CLIENT_ID!)
.clientSecret(process.env.RETORNA_CLIENT_SECRET!)
.privateKey(process.env.RETORNA_PRIVATE_KEY!)
.buildClient();
const quotation = await client.createQuotation({
source: { currency: "USDR" },
destination: {
country: "VE",
currency: "VES",
payout_method: { type: "P2P_PHONE_TRANSFER" },
},
quote: { mode: "SEND_EXACT", amount: "10.00" },
});
const order = await client.createOrder(
{
quotation_id: quotation.id,
purpose: "FAMILY_SUPPORT",
metadata: { invoice_id: "INV-2026-00456" },
sender: {
names: "Ana María",
last_names: "Pérez Gómez",
document: { type: "CC", id: "1020304050", country: "CO" },
country: "CO",
},
destination: {
receiver: {
names: "Carlos Andrés",
last_names: "Rodríguez López",
document: { type: "V", id: "12345678", country: "VE" },
country: "VE",
},
payment_instructions: {
bank_phone_account: {
bank_name: "BNC_VE",
phone_number: "+584121234567",
document_id: "12345678",
},
},
},
},
"invoice-2026-00456", // idempotency key — comes back as order.idempotency_key
);
console.log(order.id, order.status, order.idempotency_key);
Errores
Del lado del cliente, antes de cualquier llamada de red (RetornaSdkError):
req.quotation_idno es un UUID válido.req.purposefalta o está fuera del catálogo cerrado.- Algún campo obligatorio de sender/receiver está vacío, un código de país no
tiene 2 caracteres, el
emaildel receiver no es una dirección válida,sender.phoneno es E.164, osender.emailno es una dirección válida. payment_instructionstiene cero o los dos debank_account/bank_phone_accountdefinidos.bank_nameestá fuera del catálogo de bancos, eltypede la cuenta bancaria está fuera deCHECKING/SAVINGS/CORRIENTE/AHORRO, ophone_numberno es E.164.idempotencyKeyse pasó explícitamente como string vacío.
Desde la API (RetornaB2BError, consulta el
catálogo de errores):
B2B_UNAUTHORIZED— credenciales, token o firma rechazados.B2B_QUOTATION_NOT_FOUND— la cotización no existe o no es tuya.B2B_QUOTATION_EXPIRED— la cotización expiró antes de crear la orden.B2B_QUOTATION_MISMATCH— la orden no coincide con los términos de la cotización.B2B_QUOTATION_ALREADY_USED— la cotización ya respalda otra orden.B2B_INSUFFICIENT_BALANCE— el balance de la wallet es menor al que requiere la orden.B2B_BENEFICIARY_INVALID— los datos del beneficiario son inválidos para el método de pago.B2B_IDEMPOTENCY_CONFLICT— se reutilizó el mismoX-Idempotency-Keycon un body distinto.B2B_RATE_LIMITED/B2B_PROVIDER_REJECTED/B2B_PROVIDER_UNAVAILABLE/B2B_UNKNOWN— consulta la política de reintentos por categoría.
Notas
- Si omites
idempotencyKey, el SDK genera un UUID v4 por ti; si pasas tu propia referencia (un id de factura, un id de corrida de pagos) vuelve comoorder.idempotency_key— consulta idempotencia. - Un reintento de
createOrdersolo es seguro con la misma clave de idempotencia del intento original. bank_namesiempre es un código de catálogo, nunca un nombre comercial —"BANCO_BANESCO_VE", no"Banesco".
Referencia de API
listOrders(params)
Lista las órdenes de la compañía, con la actividad más reciente primero, con paginación por cursor y filtros opcionales.
Firma
listOrders(params?: ListOrdersParams): Promise<OrdersListResponse>
Parámetros
| Nombre | Tipo | Obligatorio | Descripción |
|---|---|---|---|
params.cursor | string | No | Cursor opaco del pagination.next_cursor de una página anterior. Omítelo para la primera página. |
params.limit | number | No | Tamaño de página, 1–100, default 20. Queda fijo durante todo el recorrido una vez que pasas un cursor. |
params.status | string | No | Filtra por estado de la orden. |
params.type | string | No | Filtra por tipo de transacción, ej. "WALLET_TO_POG". String libre, un solo valor — a diferencia de status, no acepta una lista separada por comas. |
params.idempotency_key | string | No | Filtra por la clave de idempotencia que enviaste al crear. |
params.created_from | string | No | Fecha o fecha-hora ISO 8601, límite inferior inclusivo. |
params.created_to | string | No | Fecha o fecha-hora ISO 8601, límite superior inclusivo. |
Retorno
OrdersListResponse:
| Campo | Tipo | Significado |
|---|---|---|
data | Order[] | Consulta la tabla de campos de Order bajo createOrder más arriba. |
pagination.next_cursor | string | null | Token opaco de la próxima página; null cuando termina el recorrido. |
pagination.has_more | boolean | Misma condición de fin de lista que un next_cursor nulo. |
pagination.limit | number | Tamaño de página efectivo del recorrido. |
pagination.total | number | null | Total del dataset filtrado, o null cuando no se conoce. |
Ejemplo
let cursor: string | undefined;
do {
const page = await client.listOrders({ cursor, limit: 50, status: "COMPLETED" });
for (const order of page.data) {
console.log(order.id, order.status, order.amount, order.currency);
}
cursor = page.pagination.next_cursor ?? undefined;
} while (cursor);
Errores
Del lado del cliente (RetornaSdkError):
params.limitdefinido pero no es un entero entre 1 y 100.
Desde la API (RetornaB2BError):
B2B_UNAUTHORIZED— credenciales, token o firma rechazados.B2B_INVALID_PAGINATION_CURSOR— el cursor no se pudo decodificar, o no lo emitió este listado.B2B_RATE_LIMITED— demasiadas requests; reintenta con backoff.
Notas
- Consulta paginación para las reglas completas del cursor — aplican igual al listado de órdenes y a las transacciones de la wallet.
- Mantén los filtros idénticos en cada llamada de un recorrido paginado; cambiarlos a mitad de camino invalida los supuestos del cursor.
idempotency_keyes lo bastante preciso como para volver innecesaria la paginación cuando ya sabes qué clave de idempotencia buscas.
Referencia de API
getOrder(id)
Lee una orden puntual por id.
Firma
getOrder(id: string): Promise<Order>
Parámetros
| Nombre | Tipo | Obligatorio | Descripción |
|---|---|---|---|
id | string | Sí | El id de la orden. Entre 1 y 100 caracteres. |
Retorno
Order — misma forma que createOrder más arriba.
Ejemplo
const order = await client.getOrder("0190f9b2-3c4d-4e5f-8a6b-7c8d9e0f1a2b");
console.log(order.status, order.execution.destination.status);
Errores
Del lado del cliente (RetornaSdkError):
idvacío o más largo que 100 caracteres.
Desde la API (RetornaB2BError):
B2B_UNAUTHORIZED— credenciales, token o firma rechazados.B2B_ORDER_NOT_FOUND— la orden no existe, o no le pertenece a tu compañía.
Notas
- Es de solo lectura. Consúltala periódicamente (o mejor, usa
events) para seguir una orden a través de sus transiciones de estado en vez de asumir una única llamada terminal.