Saltar al contenido principal

Ó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​

NombreTipoObligatorioDescripción
req.quotation_idstringSíUUID de la cotización de createQuotation. De uso único.
req.metadataRecord<string, string>NoPares clave/valor libres, se devuelven sin modificar en las lecturas.
req.purposestringSí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.namesstringSíNombre(s) del remitente.
req.sender.last_namesstringSíApellido(s) del remitente.
req.sender.document.typestringSíTipo de documento, ej. "CC".
req.sender.document.idstringSíNúmero de documento.
req.sender.document.countrystringSíCódigo de país ISO alpha-2 de 2 caracteres donde se emitió el documento.
req.sender.countrystringSíCódigo de país ISO alpha-2 de 2 caracteres del remitente.
req.sender.phonestringNoTelé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.emailstringNoEmail 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.namesstringSíNombre(s) del beneficiario.
req.destination.receiver.last_namesstringSíApellido(s) del beneficiario.
req.destination.receiver.document.typestringSíTipo de documento del beneficiario, ej. "V".
req.destination.receiver.document.idstringSíNúmero de documento del beneficiario.
req.destination.receiver.document.countrystringSíCódigo de país ISO alpha-2 de 2 caracteres donde se emitió el documento.
req.destination.receiver.emailstringNoEmail del beneficiario. Se valida como dirección de email cuando está presente.
req.destination.receiver.countrystringSíCódigo de país ISO alpha-2 de 2 caracteres del beneficiario.
req.destination.payment_instructions.bank_accountobjectUno de los dos{ bank_name, number, type }. Mutuamente excluyente con bank_phone_account.
req.destination.payment_instructions.bank_account.bank_namestring—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.numberstring—Número de cuenta.
req.destination.payment_instructions.bank_account.type"CHECKING" | "SAVINGS" | "CORRIENTE" | "AHORRO"—Tipo de cuenta.
req.destination.payment_instructions.bank_phone_accountobjectUno de los dos{ bank_name, phone_number, document_id? }. Mutuamente excluyente con bank_account.
req.destination.payment_instructions.bank_phone_account.bank_namestring—El mismo catálogo cerrado que bank_account.bank_name.
req.destination.payment_instructions.bank_phone_account.phone_numberstring—Formato E.164, ej. "+584121234567".
req.destination.payment_instructions.bank_phone_account.document_idstringNoSi se omite, del lado del servidor recae en destination.receiver.document.id.
idempotencyKeystringNoTu 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:

CampoTipoSignificado
idstringIdentificador de la orden.
idempotency_keystring (opcional)La clave de idempotencia devuelta.
typestringTipo de orden, ej. "REMITTANCE".
statusstringConsulta estado de la orden.
quotation_idstringLa cotización que esta orden consumió.
amountstringMonto en moneda origen, como string decimal.
currencystringMoneda origen.
metadataRecord<string, string>Se devuelve sin modificar.
purposestring | null (opcional)Propósito de la remesa, cuando se informa.
senderobject (opcional)Misma forma que el sender del request. Se omite en algunos estados.
destination.receiverobject (opcional)Misma forma que el receiver del request.
destination.payment_instructionsobject (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_currencystring (opcional)Monto/moneda del pago, una vez que se despachó.
execution.source.status / execution.destination.statusstringEstado de ejecución por tramo, ej. "COMPLETED", "PENDING".
execution.source.reference_id / execution.destination.reference_idstring | nullId de referencia por tramo.
eventsarray (opcional)Línea de tiempo de cambios de estado: { id, from_status, to_status, trigger, reason, message, created_at }.
failure_code / failure_reasonstring | null (opcional)Solo se completa cuando status === "FAILED".
created_at / updated_atstringTimestamps 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_id no es un UUID válido.
  • req.purpose falta 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 email del receiver no es una dirección válida, sender.phone no es E.164, o sender.email no es una dirección válida.
  • payment_instructions tiene cero o los dos de bank_account / bank_phone_account definidos.
  • bank_name está fuera del catálogo de bancos, el type de la cuenta bancaria está fuera de CHECKING/SAVINGS/CORRIENTE/AHORRO, o phone_number no es E.164.
  • idempotencyKey se 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 mismo X-Idempotency-Key con 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 como order.idempotency_key — consulta idempotencia.
  • Un reintento de createOrder solo es seguro con la misma clave de idempotencia del intento original.
  • bank_name siempre es un código de catálogo, nunca un nombre comercial — "BANCO_BANESCO_VE", no "Banesco".

Referencia de API​

POST /orders

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​

NombreTipoObligatorioDescripción
params.cursorstringNoCursor opaco del pagination.next_cursor de una página anterior. Omítelo para la primera página.
params.limitnumberNoTamaño de página, 1–100, default 20. Queda fijo durante todo el recorrido una vez que pasas un cursor.
params.statusstringNoFiltra por estado de la orden.
params.typestringNoFiltra 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_keystringNoFiltra por la clave de idempotencia que enviaste al crear.
params.created_fromstringNoFecha o fecha-hora ISO 8601, límite inferior inclusivo.
params.created_tostringNoFecha o fecha-hora ISO 8601, límite superior inclusivo.

Retorno​

OrdersListResponse:

CampoTipoSignificado
dataOrder[]Consulta la tabla de campos de Order bajo createOrder más arriba.
pagination.next_cursorstring | nullToken opaco de la próxima página; null cuando termina el recorrido.
pagination.has_morebooleanMisma condición de fin de lista que un next_cursor nulo.
pagination.limitnumberTamaño de página efectivo del recorrido.
pagination.totalnumber | nullTotal 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.limit definido 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_key es lo bastante preciso como para volver innecesaria la paginación cuando ya sabes qué clave de idempotencia buscas.

Referencia de API​

GET /orders

getOrder(id)​

Lee una orden puntual por id.

Firma​

getOrder(id: string): Promise<Order>

Parámetros​

NombreTipoObligatorioDescripción
idstringSí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):

  • id vací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.

Referencia de API​

GET /orders/{id}