> ## 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.

# Guardar intent de pago

> Crea o reemplaza el intent de pago en borrador, con todos sus tenders, antes de colocar el pedido.

Crea o reemplaza el intent de pago `DRAFT` de un pedido `OPEN`. `tenders` es la lista de pagos de este checkout. El orden del arreglo es `sequence`. El primer tender real (todo lo que no sea `REDEMPTION`) es el tender primario.

El servidor calcula el `amount` de cada tender y `allocation.amounts`. Envía `allocation` sin `amounts`. Un solo tender real puede enviar `allocation: null`, que significa que cubre lo que ningún otro tender cubre. Un tender `REDEMPTION` siempre envía `allocation: null`: cubre un monto, no líneas.

> [!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.setTenders(tenders)`. Los tenders `REDEMPTION` salen de `order.applyRedeem` con `payment_id`, no de esta lista. `order.placeOrder()` guarda el borrador y luego coloca el pedido con su `intent_id`.

## Parámetros de ruta

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

## Cuerpo de la solicitud

| Campo | Requerido | Tipo | Descripción |
| - | - | - | - |
| `tenders` | Sí | array | Al menos un tender. Ver abajo. |
| `metadata` | No | object | Se guarda en el intent. Por defecto `{}`. |

Cada tender:

| Campo | Requerido | Descripción |
| - | - | - |
| `method` | Sí | `CASH`, `CARD`, `BANK_TRANSFER`, `WALLET`, `PIN_PAD`, `FINANCING` o `REDEMPTION` |
| `provider` | Sí | Id de proveedor del catálogo, por ejemplo `firespark` o `kushki` |
| `collect_at` | Sí | `DEVICE`, `KIOSK`, `COUNTER`, `DOOR` u `OTHER` |
| `payment_id` | En `REDEMPTION` | Id del pago del merchant. Obligatorio en `REDEMPTION`. |
| `allocation` | No | `{ lines: [{ line_uid, units? }], fees: [line_uid] }` o `null` |
| `details` | En `REDEMPTION` | Datos del método. `details.method` debe coincidir con `method`. |
| `id` | No | Id estable del tender. Si lo omites, se genera. |
| `attempt_reference` | No | Clave de idempotencia del intento actual, 10–64 caracteres. |

`collect_at: DEVICE` se cobra en el dispositivo. `COUNTER`, `KIOSK`, `DOOR` y `OTHER` se cobran en persona. La propina y el envío quedan en el tender real primario.

Un tender `REDEMPTION` por cada `payment_id`. `details.rewards[]` lista cada recompensa. Cada recompensa tiene su `amount`, y `details.amount` es la suma de `rewards`. `amount` en un canje es el total en dinero de toda la entrada, no por unidad, limitado por su tope `before_taxes`. Los tenders reales pagan el resto del total del pedido: con `before_taxes` (por defecto), al menos los impuestos.

```bash theme={null}
curl -X PUT "https://firespark.cloud/api/storefront/v1/orders/ord-48291/payment-intent" \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "tenders": [
      {
        "method": "CARD",
        "provider": "kushki",
        "collect_at": "DEVICE",
        "allocation": {
          "lines": [{ "line_uid": "f6a7b8c9-d0e1-2345-f678-901234567890" }],
          "fees": []
        }
      },
      {
        "method": "CASH",
        "provider": "firespark",
        "collect_at": "DOOR",
        "allocation": null
      }
    ]
  }'
```

## Respuesta

Devuelve `200` con el pedido. El intent activo tiene `status: DRAFT`, `is_mixed: true` cuando hay dos o más tenders reales, y `primary_tender_id` en el primer tender real.

## Respuestas de error

Los errores de pago devuelven `{ "error": "...", "details": { "code": "..." } }`. `422` salvo que se indique otra cosa.

| `details.code` | Cuándo |
| - | - |
| `PAYMENT_INTENT_LOCKED` | El pedido no está `OPEN`, o el intent ya está `LOCKED` (`409`) |
| `PAYMENT_INTENT_STALE` | El total del pedido cambió después de guardar el intent (`409`) |
| `MIXED_PAYMENTS_DISABLED` | Dos o más métodos reales con los pagos mixtos apagados. `details.reason` es `RULE_DISABLED`, `KILL_SWITCH` o `WORKFLOW_NO_MIXED_LANE` |
| `PAYMENT_TOO_MANY_METHODS` | Más métodos reales de los que permite la regla |
| `PAYMENT_TOO_MANY_ITEMS` | Un método cubre más ítems que su tope |
| `PAYMENT_AMOUNT_EXCEEDED` | El total de un método supera su tope |
| `PAYMENT_UNALLOCATED_LINES` | Más de un tender real omite `allocation`, o un intent solo de canje no cubre el pedido |
| `PAYMENT_INVALID_ALLOCATION` | Una línea, unidad o fee no corresponde a ese tender |
| `PAYMENT_INVALID_PRIMARY` | Los descuentos dejan el tender primario bajo cero |
| `PAYMENT_LINE_NOT_SPLITTABLE` | Los montos de una línea no se pueden partir por unidades |
| `PAYMENT_REDEMPTION_EXCEEDED` | Los canjes superan el total del pedido menos propina y envío |
| `PAYMENT_REDEMPTION_MISMATCH` | Un tender `REDEMPTION` no coincide con los canjes de su `payment_id` |
| `REDEEM_PAYMENT_METHOD_NOT_CONFIGURED` | `redeem.payment_id` no existe o no es un pago `REDEMPTION`. `details.reason` es `NOT_FOUND` (también si el pago no está activo) o `NOT_REDEMPTION` |
| `PAYMENT_METHOD_UNAVAILABLE` | El pago no aplica a este pedido |
| `PAYMENT_INVALID_COMBINATION` | El método y el pago no coinciden, o el pedido tiene más de un tender en efectivo |
| `404` | Pedido no encontrado |


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