cashSales

Registrar una venta cobrada en efectivo

Changed on

Registra una venta cobrada en efectivo. No mueve dinero por Recurrente: no se descuenta comisión, no impacta el balance del merchant, y no se genera transacción en el ledger. Si pasas tax_id, se intenta emitir la factura electrónica (DTE) automáticamente.

Puedes enviar customer_id para reutilizar un cliente creado con POST /customers, conservando su nombre y correo en el registro de la venta. Debe pertenecer a la cuenta seleccionada y al entorno de la llave. Si omites tax_id, se usa el nit guardado en ese cliente; un tax_id explícito tiene prioridad solo para esta venta, sin modificar al cliente. Con NIT y facturación configurada, se intenta emitir el DTE. El nombre fiscal sigue la validación habitual del NIT, igual que en un checkout; no se sustituye el nombre devuelto por SAT con texto libre. El correo se conserva en el cliente, pero no se envía en el XML de la FEL. Si omites customer_id, se mantiene la venta anónima existente. Con una llave TEST heredada solo son visibles los clientes que ya aparecen en un checkout de prueba; para probar el flujo completo usa una llave de Sandbox.

Un 201 confirma el registro de la venta, no la certificación del DTE: si la emisión falla o el certificador no responde, la venta queda registrada igual y el intento del DTE se reintenta por su cuenta. Consulta GET /intents/{id} para el estado actual. Si tu cuenta factura fuera de Recurrente no emitimos el DTE, aunque envíes NIT: el NIT queda guardado en la venta y la factura la emites tú.

Envía Idempotency-Key para reintentos seguros: si pierdes la respuesta después de registrar la venta, repetir el mismo request con la misma clave devuelve la respuesta original en vez de registrar una segunda venta y emitir un segundo DTE.

La respuesta devuelve el ID del recurso unificado (in_…). Persiste ese ID para reconciliar el evento intent.succeeded y para consultar el estado actual mediante GET /intents/{id}. También aparece como checkout.latest_intent.id; solo el id superior del evento legacy cash_intent.succeeded usa el ID concreto del CashIntent (ca_…).

tax_invoice_url en los webhooks refleja el estado del DTE al momento de la entrega. Puede ser null si la emisión todavía no concluyó o falló y luego se recupera. Ese cambio no genera un segundo webhook de éxito; recupera la URL actual con GET /intents/{id}.

Si operas una plataforma, envía X-ACCOUNT-ID tanto al crear como al consultar para que la venta y su DTE pertenezcan a la cuenta conectada y se emitan bajo su NIT. X-CUSTOM-ACCOUNT-ID no selecciona el contexto de lectura.

post/cash_sales

Request

Headers

Idempotency-Keystring

Clave de idempotencia para reintentos seguros de operaciones críticas, especialmente las que mueven dinero o cambian estado operativo. Reintentar con la misma clave y el mismo cuerpo devuelve la respuesta original (header Idempotency-Replayed: true); reusarla con parámetros distintos devuelve 409.

Request body

amount_in_centsinteger required

Monto en centavos

currency'GTQ' | 'USD'

Moneda. Default — la moneda principal de la cuenta.

descriptionstring

(Opcional) Descripción visible en el recibo y la actividad

customer_idstring

(Opcional) ID público del cliente de esta cuenta y entorno. Reutiliza su nombre, correo y NIT; no crea otro cliente ni realiza un cobro electrónico.

tax_idstring

(Opcional) NIT para esta venta; tiene prioridad sobre el nit del customer_id. Si existe un NIT y la cuenta tiene facturación electrónica configurada, se intenta emitir el DTE automáticamente.

Response

Venta en efectivo registrada (no confirma la certificación del DTE)

idstring

ID del intent unificado. Úsalo con GET /intents/{id} y con el id superior de los eventos intent.*.

statusstring
amount_in_centsinteger
currencystring
descriptionstring
tax_idstring nullable
created_atstring date-time

Changes

    • info

      added the new optional header request parameter Idempotency-Key

    • info

      added the new optional request property

    • info

      added the non-success response with the status

    • info

      added the non-success response with the status

    • breaking

      added to the response property oneOf list for the response status

    • breaking

      added to the response property oneOf list for the response status

    • breaking

      the / response's property type changed from object to array for status

    • breaking

      the / response's property type changed from object to array for status