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

# Reabrir pedido

> Anula todos los pagos de un pedido colocado y sin cobrar, y continúa con un nuevo pedido OPEN con el mismo contenido.

Reabre un pedido colocado del cliente autenticado mientras todavía no se ha cobrado nada. En un kiosco, el botón Cancelar durante la espera de liberación del checkout llama a este endpoint.

Fire spark anula todos los tenders de pago pendientes (las recompensas de REDEMPTION se liberan), cancela el pedido como `VOIDED` con las notificaciones habituales y crea un nuevo pedido `OPEN` con la misma tienda, canal, fulfillment, marca, cliente, productos, modificadores y canjes. Los pagos no se copian.

El vínculo se guarda en `metadata.reopen`. `as_order_id` es el reemplazo de este pedido. `from_order_id` es el pedido que este reemplazó. Pueden estar los dos. Un pedido nuevo se puede colocar y reabrir de nuevo mientras esté `CLOSED` y se pueda cancelar, sin límite en la cadena. Un reintento sin `order_id` devuelve el mismo reemplazo.

Un pedido que ya está `VOIDED`, `REVERSED` o `CANCELLED` (legacy) y nunca se cumplió también se puede reabrir, por ejemplo después de una inyección fallida cuyo cobro con tarjeta se reversó en el dispositivo. No se anula ni se cancela nada otra vez y no se envía webhook; solo se crea y vincula el nuevo pedido `OPEN`. Todos los tenders reales deben haber terminado sin dinero retenido (`CANCELLED`, `FAILED` o `REFUNDED` completo). Mientras una reversa sigue en curso (un tender está `PAID`) la respuesta es `400` `ORDER_PAYMENT_CAPTURED`; reintenta cuando llegue el reembolso. Un tender todavía `IDLE` o `PENDING` es `422` `ORDER_NOT_REOPENABLE`. Un pedido `REFUNDED` o `COMPLETED` nunca se reabre: un reembolso solo ocurre después de la entrega.

`order_id` en el cuerpo es opcional. Si lo omites, o no envías cuerpo, el id del pedido nuevo se genera igual que antes (`genOrderId(storeId)`: `ord-<tienda>-<12 alfanuméricos en minúscula>`). Si envías `order_id`, ese valor es el id del pedido nuevo. Puede ser cualquier id que arme `genId()` (`isGenId` es la misma validación que usa la API). `genOrderId` es una opción y sigue devolviendo `ord-<tienda>-<hash>`. `genOrderId(storeId, { length, format })` cambia el hash: `length` es al menos 8 (por defecto 12) y `format` es `alphanumeric` (por defecto, `0-9a-z`), `numeric` (`0-9`) o `alphabetic` (`a-z`). Un hash solo es `genId().hash(16, "numeric").build()`. El separador es opcional, así que un literal puede ir pegado al hash: `genId().literal("BB21921").hash(8, "numeric").build()` produce un id como `BB2192100000001`. Un hash de menos de 12 caracteres avisa, y un hash numérico de menos de 16 dígitos avisa; los dos igual devuelven el id. Un hash más corto es más fácil de adivinar y choca más seguido. `isGenId` acepta `[A-Za-z0-9-]`, máximo 64 caracteres, sin `-` al inicio, al final o duplicado, y una racha de al menos 8 caracteres `[0-9a-z]`. Si el formato no coincide, la respuesta es `400` con `details.code` y `code` `ORDER_ID_INVALID` y `error` `order_id does not match the genId format`. Si ya existe un pedido vigente con ese id en este comercio y entorno, la respuesta es `409` con `details.code` y `code` `ORDER_ID_EXISTS` y `error` `An order with this id already exists`. El mismo `409` se devuelve si el insert pierde una carrera contra `orders_id_merchant_env_deleted_unique` (Postgres `23505`). La unicidad es esa restricción, sobre `(id, merchant_id, env, deleted_at)`. `orders.id` no tiene una restricción única de una sola columna, y esta API no agrega una.

> [!NOTE]
>
> Requiere un access token de Storefront API de [Intercambio de
> token](https://firespark.cloud/docs/es/storefront-api/oauth/exchange/post.md).

En `@fire-spark/storefront`, llama `order.reopen()`. Devuelve el nuevo `Order`; reemplaza el pedido actual con él. Pasa un id de `genId` o `genOrderId` cuando el pedido nuevo debe usar ese código: `order.reopen(genOrderId(storeId))`. Un id propio es `order.reopen(genId().literal("BB21921").hash(8, "numeric").build())`. La misma llamada con opciones de `genOrderId` es `order.reopen(genOrderId(storeId, { length: 16, format: "numeric" }))`. El SDK envía ese valor como `order_id`. Omite el argumento para conservar el id generado.

> [!WARNING]
>
> La reapertura se rechaza con `400` si algún pago ya fue capturado y, en un
> pedido cancelado, no fue reembolsado por completo. En ese caso no cambia nada.

## Parámetros de ruta

| Parámetro | Requerido | Descripción |
| - | - | - |
| `id` | Sí | Identificador externo del pedido |

## Cuerpo de la solicitud

| Campo | Requerido | Descripción |
| - | - | - |
| `order_id` | No | Id del pedido nuevo, armado con `genId` (`genOrderId` es una opción). Ejemplo: `BB2192100000001` con `genId().literal("BB21921").hash(8, "numeric")`. Omítelo para conservar el id generado. |

```bash theme={null}
curl -X POST "https://firespark.cloud/api/storefront/v1/orders/ord-48291/reopen" \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"order_id":"ord-store1-abcdefghij12"}'
```

Sin `order_id`, envía la misma solicitud sin cuerpo.

## Respuesta

Devuelve `201` con el nuevo pedido abierto. Reintentar la misma reapertura devuelve `200` con el mismo pedido nuevo.

> [!NOTE]
>
> Las integraciones reciben el mismo webhook `order.voided` que en una
> [cancelación](https://firespark.cloud/docs/es/storefront-api/orders/\[id]/cancel/post) del pedido original.

```json Éxito theme={null}
{
  "data": {
    "id": "ord-48292",
    "status": "OPEN",
    "payment_status": "IDLE",
    "metadata": { "reopen": { "from_order_id": "ord-48291" } }
  }
}
```

## Respuestas de error

| Estado | Descripción |
| - | - |
| `400` | Un pago ya fue capturado, o un pedido cancelado aún tiene un tender `PAID` (`details.code` y `code`: `ORDER_PAYMENT_CAPTURED`), o `order_id` no es un `genId` (`ORDER_ID_INVALID`, `error`: `order_id does not match the genId format`) |
| `401` | Token de acceso ausente o inválido |
| `404` | Pedido no encontrado |
| `409` | Ya existe un pedido con ese `order_id`, incluida una carrera de la restricción única (`details.code` y `code`: `ORDER_ID_EXISTS`, `error`: `An order with this id already exists`) |
| `422` | El pedido no se puede reabrir en su estado actual, incluido un pedido cancelado con un tender `IDLE` o `PENDING` (`details.code: ORDER_NOT_REOPENABLE`) |


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