> ## Documentation Index
> Fetch the complete documentation index at: https://devs.tapipay.la/llms.txt
> Use this file to discover all available pages before exploring further.

# Creación de una orden

> El aviso de que una orden de pago se creó o de que su creación falló.

> [!NOTE]
>
> **Próximamente.** Este webhook todavía no está disponible.

TapiPay te avisa con este webhook cuando se crea una [orden de pago](https://devs.tapipay.la/es/recursos/ordenes-de-pago.md) o cuando falla la creación del cargo. Solo acompaña a tres respuestas de `POST /v2/debts/orders`: `201`, `422 ORDER_NOT_CREATED` y `500`. Con cualquier otra (por ejemplo, un campo inválido, un contacto que no existe o una llave ya usada), no hay webhook: el motivo te llega solo en la respuesta.

Ante un `500`, este webhook puede llegar o no. Si llega `ORDER_CREATION_FAILED` con `PROVIDER_UNAVAILABLE`, no significa que no se cobró: reintenta con el mismo `externalRequestId`, como se indica en [Reintentos e idempotencia](https://devs.tapipay.la/es/recursos/ordenes-de-pago.md#reintentos-e-idempotencia).

| `type` | `orderStatus` | Cuándo llega |
| - | - | - |
| `ORDER_CREATION_SUCCESS` | `PROCESSING` | Se creó la orden. |
| `ORDER_CREATION_FAILED` | `FAILED` | La creación de la orden falló. El motivo viene en `creationError`. |

> [!NOTE]
>
> Forma parte de los [webhooks de órdenes y medios de pago](https://devs.tapipay.la/es/webhooks.md#órdenes-y-medios-de-pago): comparte con ellos el endpoint, la seguridad y el contrato. Su llave de idempotencia es `id`.

## Creación y cobro son avisos distintos

`ORDER_CREATION_SUCCESS` informa que la orden **se creó**, no que se cobró. El resultado del cargo te llega después, con el [pago de una orden](https://devs.tapipay.la/es/webhooks/pago-de-orden.md).

Puede llegarte `ORDER_CREATION_FAILED` y después `ORDER_PAYMENT_CONFIRMED` de la misma orden, si el banco terminó procesando el cargo. En ese caso, toma como definitivo el cobro: el dinero ingresó.

## El payload

| Campo | Tipo | Presente | Descripción |
| - | - | - | - |
| `type` | String | Siempre | `ORDER_CREATION_SUCCESS` u `ORDER_CREATION_FAILED`. Úsalo para enrutar. |
| `hash` | String \| null | Siempre | Hash de verificación. `null` si no tienes llave pública configurada. Ver [Seguridad de los webhooks](https://devs.tapipay.la/es/webhooks/seguridad.md#hash-cifrado). |
| `id` | String (uuid) | Siempre | Identificador único de la notificación. Si te llega repetida, trae el mismo `id`. **Úsalo como llave de idempotencia.** |
| `orderId` | String (uuid) | Variable | El `orderId` de la orden. Siempre en `ORDER_CREATION_SUCCESS`. En `ORDER_CREATION_FAILED` solo si la orden llegó a crearse. |
| `externalOrderId` | String | Siempre | Tu identificador de la orden, el `externalRequestId`. |
| `orderStatus` | String | Siempre | `PROCESSING` en `ORDER_CREATION_SUCCESS`, `FAILED` en `ORDER_CREATION_FAILED`. |
| `companyCode` | String | Siempre | Código de la empresa de la orden. |
| `externalClientId` | String | Siempre | Tu identificador del usuario. |
| `amount` | Number | Siempre | Monto de la orden, en pesos con hasta 2 decimales. |
| `currency` | String | Siempre | Moneda, en ISO 4217. Por ahora `MXN`. |
| `paymentProcessor` | String | Siempre | Por ahora `BANK_ACCOUNT`. |
| `paymentMethod` | Object | Variable | El medio de pago de la orden: `{ type, externalPaymentMethodId }`. Siempre en `ORDER_CREATION_SUCCESS`. En `ORDER_CREATION_FAILED` puede no venir, por ejemplo con `PAYMENT_METHOD_NOT_SUPPORTED`. Nunca trae la cuenta ni la CLABE. |
| `creationError` | Object | Solo `ORDER_CREATION_FAILED` | Motivo: `{ code, message }`. Ver [Motivos](#motivos). |
| `additionalData` | Object | Siempre | Por ahora siempre llega vacío (`{}`). |
| `createdAt` | String | Solo `ORDER_CREATION_SUCCESS` | Cuándo se creó la orden, en ISO 8601 UTC. |
| `failedAt` | String | Solo `ORDER_CREATION_FAILED` | Cuándo falló la creación, en ISO 8601 UTC. |

> [!WARNING]
>
> **Si `orderId` o `paymentMethod` no vienen, la clave no está: no llegan en `null` ni vacíos.** Verifica que existan antes de leerlos.

## Motivos

`creationError.code` es un código de TapiPay, no el del banco. `message` viene en inglés y sirve para tus logs, no para mostrárselo al usuario.

| `code` | `message` | Qué significa |
| - | - | - |
| `PAYMENT_METHOD_REQUIRED` | The order requires a payment method | La orden necesita un medio de pago. |
| `PAYMENT_METHOD_NOT_SUPPORTED` | The payment method is not supported for this order | El medio de pago no sirve para este tipo de orden. |
| `PAYMENT_METHOD_INACTIVE` | The payment method is not active | El banco informó que la cuenta no está activa. Pídele al usuario que registre otra. |
| `ORDER_REJECTED` | The order was rejected by the payment provider | El banco rechazó el cargo. |
| `PROVIDER_UNAVAILABLE` | The payment provider could not confirm the order | El banco no confirmó a tiempo. La orden puede cobrarse igual. |
| `INTERNAL_ERROR` | The order could not be created | Falla de TapiPay, no imputable a tu pedido. |
| `INVALID_ORDER_REQUEST` | The order request was rejected | La orden no cumple una regla. No se creó. |

> [!NOTE]
>
> Trata la lista de códigos como **abierta**: se pueden agregar códigos nuevos. Si te llega uno que no conoces, trátalo como un fallo de creación sin acción específica.

## Ejemplos

Una orden que se crea, una que se crea pero falla, y una cuya creación falló antes de que la orden existiera (sin `orderId`). Los ejemplos corresponden a una integración sin llave pública, por eso `hash` viene en `null`.

```json Creada theme={null}
{
  "type": "ORDER_CREATION_SUCCESS",
  "hash": null,
  "id": "3c9e7a14-6b2d-5f80-a1c3-9d4e8b2f6a07",
  "orderId": "6f1c2b9e-4d3a-4b8e-9a71-2c5d8e0f1a23",
  "externalOrderId": "CARGO-2026-00042",
  "orderStatus": "PROCESSING",
  "companyCode": "MX-S-12345",
  "externalClientId": "CLI-00042",
  "amount": 350.00,
  "currency": "MXN",
  "paymentProcessor": "BANK_ACCOUNT",
  "paymentMethod": { "type": "BANK_ACCOUNT", "externalPaymentMethodId": "b7e4a0c2-9f13-4e6d-8a25-71c3d9e0b4f8" },
  "additionalData": {},
  "createdAt": "2026-10-23T15:00:04.000Z"
}
```

```json Cuenta inactiva theme={null}
{
  "type": "ORDER_CREATION_FAILED",
  "hash": null,
  "id": "d17b4e92-0a6c-5e31-8f2b-6c3a9e1d7b40",
  "orderId": "4e7b1a90-2c6d-4f3e-8a15-6b9d0c2e7f48",
  "externalOrderId": "CARGO-2026-00043",
  "orderStatus": "FAILED",
  "companyCode": "MX-S-12345",
  "externalClientId": "CLI-00043",
  "amount": 980.00,
  "currency": "MXN",
  "paymentProcessor": "BANK_ACCOUNT",
  "paymentMethod": { "type": "BANK_ACCOUNT", "externalPaymentMethodId": "7d2c9e14-5a3b-4f86-b1e0-9c4a8f6d2b53" },
  "creationError": { "code": "PAYMENT_METHOD_INACTIVE", "message": "The payment method is not active" },
  "additionalData": {},
  "failedAt": "2026-10-23T15:05:12.000Z"
}
```

```json Sin orden theme={null}
{
  "type": "ORDER_CREATION_FAILED",
  "hash": null,
  "id": "8a5f2c63-e91d-5b47-9c06-1f8d3a7e4b29",
  "externalOrderId": "CARGO-2026-00044",
  "orderStatus": "FAILED",
  "companyCode": "MX-S-12345",
  "externalClientId": "CLI-00044",
  "amount": 120.00,
  "currency": "MXN",
  "paymentProcessor": "BANK_ACCOUNT",
  "paymentMethod": { "type": "BANK_ACCOUNT", "externalPaymentMethodId": "3f8a6d21-7c4e-4b95-a0d2-5e9b1c7f4a36" },
  "creationError": { "code": "INVALID_ORDER_REQUEST", "message": "The order request was rejected" },
  "additionalData": {},
  "failedAt": "2026-10-23T15:07:30.000Z"
}
```

## Recomendaciones

* **Procesa cada notificación una sola vez.** La misma notificación puede llegar más de una vez, siempre con el mismo `id`. Guarda los `id` procesados en almacenamiento persistente.
* **Correlaciona por `externalOrderId`.** Es el único identificador que viene siempre: `orderId` falta si la orden no llegó a crearse.
* **No asumas un orden de llegada** entre este aviso y los del [pago de una orden](https://devs.tapipay.la/es/webhooks/pago-de-orden.md).
* **Ignora los campos que no conozcas**: se pueden agregar campos nuevos.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.