Reutilización de referencia recurrente de efectivo
Cobra varias órdenes con la misma referencia de efectivo de tu cliente
Si cobras a un mismo cliente de forma periódica (mensualidades, renovaciones, abonos) y quieres que siempre pague con la misma referencia de efectivo, crea tus órdenes con el parámetro reuse_customer_cash_reference: true. La orden usará la referencia recurrente de efectivo de tu cliente en lugar de generar una nueva. Cuando el cliente pague ese monto en tienda, Conekta liquidará esa orden.
Es el equivalente en efectivo de la reutilización de CLABE para SPEI.
Cómo funciona
sequenceDiagram
participant Dev as Tu servidor
participant Conekta
participant Tienda as Tienda / BBVA
Dev->>Conekta: POST /customers/:id/payment_sources (cash_recurrent)
Conekta-->>Dev: Referencia recurrente del cliente
Dev->>Conekta: POST /orders (reuse_customer_cash_reference: true)
Conekta-->>Dev: Orden pending_payment con la referencia del cliente
Tienda->>Conekta: Pago con la referencia y el monto de la orden
Conekta-->>Dev: Webhooks order.paid / charge.paid
- Creas la referencia recurrente una sola vez. Se guarda como un payment source de tipo
cash_recurrenten el cliente. - Creas una orden por cada cobro. Con
reuse_customer_cash_reference: true, el cargo de efectivo usa la referencia del cliente, con el monto de esa orden. - El cliente paga en tienda con su referencia de siempre y el monto de la orden.
- Conekta liquida la orden. Busca la orden pendiente de ese cliente con la misma referencia y el mismo monto, la marca como pagada y te lo notifica por webhook.
La referencia recurrente no se modifica: pagar o cancelar una orden no la desactiva, y puedes seguir usándola en órdenes nuevas.
Requisitos
- Tus llaves privadas → API Keys de pruebas y API Keys de producción.
- Un cliente con una referencia recurrente de efectivo (
cash_recurrent) → Cargo recurrente en efectivo. - Un webhook configurado para recibir las confirmaciones de pago → Configurar un webhook.
- Si usas BBVA como red de efectivo, tu cuenta debe tener configurado un convenio recurrente de BBVA. Si no lo tienes, contacta a tu ejecutivo de Conekta.
1. Añade tu llave privada y versión del API
- Tu API key en el header de autenticación:
--header 'Authorization: Bearer key_xxxxxxxxxxxxxxxxxxxxxxxx' - La versión del API en el header accept:
'accept: application/vnd.conekta-v2.3.0+json'
2. Crea la referencia recurrente del cliente
Si tu cliente todavía no tiene una referencia recurrente de efectivo, créala como un payment source de tipo cash_recurrent:
curl --request POST \
--url https://api.conekta.io/customers/cus_2xHJayvPVd3BpmdC7/payment_sources \
--header 'accept: application/vnd.conekta-v2.3.0+json' \
--header 'content-type: application/json' \
--header 'Authorization: Bearer key_xxxxxxxxxxxxxxxxxxxxxxxx' \
--data '{
"type": "cash_recurrent"
}'Respuesta:
{
"id": "off_ref_2xHJayvPVd3BpmdC8",
"object": "payment_source",
"provider": "Cash",
"type": "cash_recurrent",
"reference": "10001XXXXXXXXXXX0104",
"barcode": "10001XXXXXXXXXXX0104",
"barcode_url": "https://barcode/url.png",
"expires_at": 0,
"created_at": 1790633754,
"parent_id": "cus_2xHJayvPVd3BpmdC7",
"agreements": [
{
"provider": "bbva_cash_in",
"agreement": "2409526"
}
]
}El valor de
referencees la referencia que tu cliente usará en todas sus órdenes. Si tu cuenta tiene BBVA, muestra a tu cliente el número de convenio (agreement) junto con la referencia: lo necesita para pagar en practicajas o banca móvil de BBVA.
3. Crea una orden que reutilice la referencia
Envía reuse_customer_cash_reference: true junto con customer_info.customer_id y un cargo de tipo cash. Los campos del ejemplo son los mínimos; para conocer el resto revisa la REST API.
La orden solo se puede pagar mientras su cargo no haya vencido. El vencimiento del cargo (payment_method.expires_at) se fija así:
- Si envías
charges[].payment_method.expires_at(fecha en formato UNIX), se usa ese valor. - Si no lo envías y tu cuenta tiene configurados días de vencimiento por defecto para referencias, vence en esos días.
- Si no aplica ninguno de los dos, el cargo vence un mes después de crearse.
El vencimiento es de la orden, no de la referencia: la referencia recurrente del cliente sigue vigente para órdenes nuevas.
curl --request POST \
--url https://api.conekta.io/orders \
--header 'accept: application/vnd.conekta-v2.3.0+json' \
--header 'content-type: application/json' \
--header 'Authorization: Bearer key_xxxxxxxxxxxxxxxxxxxxxxxx' \
--data '{
"currency": "MXN",
"reuse_customer_cash_reference": true,
"customer_info": {
"customer_id": "cus_2xHJayvPVd3BpmdC7"
},
"line_items": [{
"name": "Mensualidad octubre",
"unit_price": 50000,
"quantity": 1
}],
"charges": [{
"payment_method": {
"type": "cash"
}
}]
}'Respuesta:
{
"livemode": true,
"amount": 50000,
"currency": "MXN",
"payment_status": "pending_payment",
"customer_info": {
"customer_id": "cus_2xHJayvPVd3BpmdC7",
"object": "customer_info"
},
"object": "order",
"id": "ord_2tXx9jDpCqIrjVKZ",
"metadata": {
"reuse_customer_cash_reference": true
},
"charges": {
"object": "list",
"has_more": false,
"total": 2,
"data": [
{
"id": "6abaedb171b62300012a240d",
"status": "pending_payment",
"amount": 50000,
"payment_method": {
"object": "cash_payment",
"type": "cash",
"product_type": "cash_in",
"reference": "10001XXXXXXXXXXX0104",
"barcode_url": "https://barcode/url.png",
"agreement": null,
"expires_at": 1790834399
},
"order_id": "ord_2tXx9jDpCqIrjVKZ"
},
{
"id": "6abaedb171b62300012a2415",
"status": "pending_payment",
"amount": 50000,
"payment_method": {
"object": "cash_payment",
"type": "cash",
"product_type": "bbva_cash_in",
"reference": "10001XXXXXXXXXXX0104",
"barcode_url": "https://barcode/url.png",
"agreement": "2409526",
"expires_at": 1790834399
},
"order_id": "ord_2tXx9jDpCqIrjVKZ"
}
]
}
}La referencia
10001XXXXXXXXXXX0104es la misma del paso 2. Si tu cuenta tiene varias redes de efectivo, la orden trae un cargo por red, todos con la misma referencia; el de BBVA usa el convenio recurrente. Cuando el cliente paga en una red, los demás cargos de la orden se cancelan.
4. Recibe la confirmación del pago
Cuando el cliente paga en tienda con su referencia, Conekta busca la orden pendiente creada con reuse_customer_cash_reference: true que tenga esa referencia y ese monto, y que no haya vencido. Esa orden se marca como pagada y recibirás los eventos charge.paid y order.paid en tu webhook.
Si usas la aprobación de pagos por webhook de la referencia recurrente: mientras el cliente tenga una orden pendiente creada con
reuse_customer_cash_reference: true, Conekta no te envía la consulta de aprobación. En Conekta Efectivo, la tienda recibe directamente el monto de la orden pendiente y el pago se aplica a esa orden.
Verifica siempre la firma de los webhooks antes de procesarlos. Consulta Autenticación de webhooks.
Ten en cuenta lo siguiente:
- El monto debe coincidir exactamente. Si el cliente paga un monto que no corresponde a ninguna orden pendiente con el flag, el pago sigue el flujo normal de la referencia recurrente: Conekta consulta tu webhook para aprobarlo y genera una orden nueva.
- Si hay varias órdenes pendientes con el mismo monto, el pago liquida la más reciente. Para evitar confusiones, cancela las órdenes que ya no quieras cobrar.
- Un pago se aplica una sola vez. Si la red reenvía la misma notificación, Conekta la reconoce como duplicada y no liquida otra orden pendiente.
- Dos pagos del mismo monto seguidos. Si el cliente paga dos órdenes del mismo monto en pocos minutos (por ejemplo, dos mensualidades el mismo día), el segundo pago puede rechazarse con el mensaje "El pago está en proceso" mientras se confirma el primero. Una vez confirmado el primer pago, lo que ocurre en unos 10 minutos, el cliente puede hacer el segundo.
5. Crea las siguientes órdenes
Para el siguiente cobro, repite el paso 3 con reuse_customer_cash_reference: true. No necesitas crear otra referencia.
curl --request POST \
--url https://api.conekta.io/orders \
--header 'accept: application/vnd.conekta-v2.3.0+json' \
--header 'content-type: application/json' \
--header 'Authorization: Bearer key_xxxxxxxxxxxxxxxxxxxxxxxx' \
--data '{
"currency": "MXN",
"reuse_customer_cash_reference": true,
"customer_info": {
"customer_id": "cus_2xHJayvPVd3BpmdC7"
},
"line_items": [{
"name": "Mensualidad noviembre",
"unit_price": 50000,
"quantity": 1
}],
"charges": [{
"payment_method": {
"type": "cash"
}
}]
}'La referencia es la misma en todas las órdenes del cliente, así que puede pagar siempre con el mismo número o código de barras.
Pruebas
En modo de pruebas (con tus llaves de pruebas), los cargos en efectivo se marcan como pagados automáticamente unos 30 segundos después de crear la orden, y recibes los eventos charge.paid y order.paid en tu webhook. Úsalo para probar que tu integración crea la orden con la referencia del cliente y procesa las notificaciones de pago.
En modo de pruebas no se simula el pago en tienda con la referencia, así que la búsqueda de la orden por referencia y monto solo ocurre con pagos reales.
Manejo de errores
| Error | Causa | Solución |
|---|---|---|
422 customer_info.customer_id.missing | Enviaste reuse_customer_cash_reference: true sin customer_info.customer_id. | Envía el customer_id del cliente que tiene la referencia recurrente. |
404 offline_recurrent_reference.not_found | El cliente no tiene una referencia cash_recurrent, o tu red BBVA no tiene convenio recurrente configurado. | Crea la referencia (paso 2). Si usas BBVA, contacta a tu ejecutivo para configurar el convenio recurrente. |
422 reuse_customer_cash_reference.invalid_datatype | Enviaste el parámetro con un valor que no es booleano, por ejemplo "yes". | Envía true o false. |
Consulta el catálogo completo en Códigos de error HTTP.
Error: customer_id faltante
{
"details": [
{
"debug_message": "The \"customer_info attribute customer_id\" is missing.",
"message": "El parametro customer_id\" es requerido.",
"param": "customer_info.customer_id",
"code": "conekta.errors.parameter_validation.customer_info.customer_id.missing"
}
],
"object": "error",
"type": "parameter_validation_error",
"log_id": "xxxxxxxxxxxxxxxxxxxx"
}HTTP Status: 422 Unprocessable Entity
Error: referencia recurrente no encontrada
{
"details": [
{
"debug_message": "Recurrent reference not found",
"message": "Referencia recurrente no encontrada",
"code": "conekta.errors.resource_not_found.processing.offline_recurrent_reference.not_found"
}
],
"object": "error",
"type": "resource_not_found_error",
"log_id": "xxxxxxxxxxxxxxxxxxxx"
}HTTP Status: 404 Not Found
Para saber cuál de las dos causas aplica, consulta el cliente (GET /customers/cus_2xHJayvPVd3BpmdC7):
- Si en
payment_sourcesno hay una referenciacash_recurrent, créala (paso 2). - Si la referencia existe y tu cuenta tiene BBVA, el error viene del convenio recurrente. Cuando el convenio está configurado,
agreementsde la referencia incluyebbva_cash_in; si no aparece, contacta a tu ejecutivo de Conekta.
Error: tipo de dato inválido
{
"details": [
{
"debug_message": "Invalid datatype for \"reuse_customer_cash_reference\" expecting at least Boolean.",
"message": "\"reuse_customer_cash_reference\" tiene un tipo inválido.",
"param": "reuse_customer_cash_reference",
"code": "conekta.errors.parameter_validation.reuse_customer_cash_reference.invalid_datatype"
}
],
"object": "error",
"type": "parameter_validation_error"
}HTTP Status: 422 Unprocessable Entity
Comportamiento por defecto
Si no envías reuse_customer_cash_reference o lo envías en false, cada orden de efectivo genera una referencia única nueva, distinta de la referencia recurrente del cliente. Consulta Cargo único en efectivo.
Relacionado
- Cargo recurrente en efectivo — cómo se crea la referencia
cash_recurrenty cómo funciona el flujo de pagos con aprobación por webhook. - Reutilización de CLABE — el mismo patrón para pagos SPEI.
- Cargo único en efectivo — órdenes de efectivo con referencia única.
- Configurar un webhook — para recibir
charge.paidyorder.paid. - Autenticación de webhooks — verifica la firma de cada notificación.
Updated 5 days ago

