Reutilización de CLABE para Cargos Recurrentes

Permite a tus clientes usar la misma CLABE para múltiples pagos SPEI

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.2.0+json'

2. Crea un Customer

Primero debes crear un cliente que tendrá asociada la referencia SPEI recurrente.

curl --request POST \
  --url https://api.conekta.io/customers \
  --header 'accept: application/vnd.conekta-v2.2.0+json' \
  --header 'content-type: application/json' \
  --header 'Authorization: Bearer key_xxxxxxxxxxxxxxxxxxxxxxxx \
  --data '{
    "name": "Juan Perez",
    "email": "[email protected]",
    "phone": "+5215555555555"
  }'

Respuesta:

{
  "livemode": true,
  "name": "Juan Perez",
  "email": "[email protected]",
  "phone": "+5215555555555",
  "id": "cus_xxxxxxxxxx",
  "object": "customer",
  "created_at": 1768564855,
  "corporate": false,
  "custom_reference": ""
}

Importante: Guarda el id del customer, lo necesitarás en los siguientes pasos.

3. Crea una referencia SPEI recurrente

Ahora debes crear un payment source de tipo spei_recurrent para el cliente. Esta será la CLABE que se reutilizará en múltiples órdenes.

curl --request POST \
  --url https://api.conekta.io/customers/cus_xxxxxxxxxx/payment_sources \
  --header 'accept: application/vnd.conekta-v2.2.0+json' \
  --header 'content-type: application/json' \
  --header 'Authorization: Bearer key_xxxxxxxxxxxxxxxxxxxxxxxx' \
  --data '{
    "type": "spei_recurrent"
  }'

Respuesta:

{
  "id": "off_ref_xxxxxxxxxx",
  "object": "payment_source",
  "type": "spei_recurrent",
  "reference": "646180111802000138",
  "created_at": 1768564900,
  "parent_id": "cus_xxxxxxxxxx",
  "bank": "STP"
}

El valor de reference (CLABE) será la referencia que se utilizará posteriormente para realizar los pagos.

4. Crea una orden con reutilización de CLABE

Al crear un order con el parámetro reuse_customer_clabe: true, el sistema usará la CLABE de la referencia recurrente del cliente en lugar de generar una nueva.

Los campos mostrados en el ejemplo son los mínimos requeridos, si deseas saber más sobre el objeto order revisa nuestra REST API.

curl --request POST \
  --url https://api.conekta.io/orders \
  --header 'accept: application/vnd.conekta-v2.2.0+json' \
  --header 'content-type: application/json' \
  --header 'Authorization: Bearer key_xxxxxxxxxxxxxxxxxxxxxxxx' \
  --data '{
    "currency": "MXN",
    "reuse_customer_clabe": true,
    "customer_info": {
      "customer_id": "cus_xxxxxxxxxx"
    },
    "line_items": [{
      "name": "Producto 1",
      "unit_price": 50000,
      "quantity": 1
    }],
    "charges": [{
      "payment_method": {
        "type": "spei"
      }
    }]
  }'

Respuesta:

{
  "livemode": true,
  "amount": 50000,
  "currency": "MXN",
  "payment_status": "pending_payment",
  "amount_refunded": 0,
  "customer_info": {
    "email": "[email protected]",
    "phone": "+5215555555555",
    "name": "Juan Perez",
    "corporate": false,
    "customer_id": "cus_xxxxxxxxxx",
    "object": "customer_info"
  },
  "object": "order",
  "id": "ord_xxxxxxxxxx",
  "metadata": {},
  "is_refundable": false,
  "created_at": 1768564962,
  "updated_at": 1768564964,
  "line_items": {
    "object": "list",
    "has_more": false,
    "total": 1,
    "data": [
      {
        "name": "Producto 1",
        "unit_price": 50000,
        "quantity": 1,
        "object": "line_item",
        "id": "line_item_xxxxxxxxxx",
        "parent_id": "ord_xxxxxxxxxx",
        "metadata": {},
        "antifraud_info": {}
      }
    ]
  },
  "charges": {
    "object": "list",
    "has_more": false,
    "total": 1,
    "data": [
      {
        "id": "xxxxxxxxxxxxxxxxxxxx",
        "livemode": true,
        "created_at": 1768564963,
        "currency": "MXN",
        "payment_method": {
          "clabe": "646180111802000138",
          "bank": "STP",
          "receiving_account_number": "646180111802000138",
          "receiving_account_bank": "STP",
          "payment_attempts": [],
          "object": "bank_transfer_payment",
          "type": "spei",
          "expires_at": 1776337233
        },
        "object": "charge",
        "description": "Payment from order",
        "status": "pending_payment",
        "amount": 50000,
        "fee": 1450,
        "customer_id": "",
        "order_id": "ord_xxxxxxxxxx"
      }
    ]
  }
}

La CLABE 646180111802000138 es la misma que se obtuvo en el paso 3. Podrás usarla para tus próximos pagos utilizando reuse_customer_clabe en true.

5. Crear órdenes subsecuentes

Para crear más órdenes con la misma CLABE, simplemente repite el paso 4 con el parámetro reuse_customer_clabe: true.

curl --request POST \
  --url https://api.conekta.io/orders \
  --header 'accept: application/vnd.conekta-v2.2.0+json' \
  --header 'content-type: application/json' \
  --header 'Authorization: Bearer key_xxxxxxxxxxxxxxxxxxxxxxxx' \
  --data '{
    "currency": "MXN",
    "reuse_customer_clabe": true,
    "customer_info": {
      "customer_id": "cus_xxxxxxxxxx"
    },
    "line_items": [{
      "name": "Renovación Anual",
      "unit_price": 500000,
      "quantity": 1
    }],
    "charges": [{
      "payment_method": {
        "type": "spei"
      }
    }]
  }'

Respuesta:

{
  "id": "ord_yyyyyyyyyy",
  "charges": {
    "data": [{
      "payment_method": {
        "type": "spei",
        "clabe": "646180111802000138"
      }
    }]
  }
}
📌

La CLABE 646180111802000138 es la misma en todas las órdenes, facilitando el proceso de pago.


Manejo de errores

Error: customer_id faltante

Si envías reuse_customer_clabe: true sin proporcionar customer_info.customer_id, recibirás:

curl --request POST \
  --url https://api.conekta.io/orders \
  --header 'accept: application/vnd.conekta-v2.2.0+json' \
  --header 'content-type: application/json' \
  --header 'Authorization: Bearer key_xxxxxxxxxxxxxxxxxxxxxxxx' \
  --data '{
    "currency": "MXN",
    "reuse_customer_clabe": true,
    "customer_info": {
      "name": "Juan Perez",
      "email": "[email protected]",
      "phone": "+5215555555555"
    },
    "line_items": [{
      "name": "Producto 1",
      "unit_price": 50000,
      "quantity": 1
    }],
    "charges": [{
      "payment_method": {
        "type": "spei"
      }
    }]
  }'

Respuesta:

{
  "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 SPEI no encontrada

Si el cliente no tiene una referencia SPEI recurrente creada, recibirás:

curl --request POST \
  --url https://api.conekta.io/orders \
  --header 'accept: application/vnd.conekta-v2.2.0+json' \
  --header 'content-type: application/json' \
  --header 'Authorization: Bearer key_xxxxxxxxxxxxxxxxxxxxxxxx' \
  --data '{
    "currency": "MXN",
    "reuse_customer_clabe": true,
    "customer_info": {
      "customer_id": "cus_yyyyyyyyyy"
    },
    "line_items": [{
      "name": "Producto 1",
      "unit_price": 50000,
      "quantity": 1
    }],
    "charges": [{
      "payment_method": {
        "type": "spei"
      }
    }]
  }'

Respuesta:

{
  "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

Solución: Crea primero un payment source de tipo spei_recurrent para el cliente (ver paso 3).


Error: Tipo de dato inválido

Si envías reuse_customer_clabe con un valor que no es booleano (por ejemplo, un string), recibirás un error de validación:

{
  "details": [
    {
      "debug_message": "The \"reuse_customer_clabe\" parameter is invalid.",
      "message": "El parámetro reuse_customer_clabe es inválido.",
      "param": "reuse_customer_clabe",
      "code": "conekta.errors.parameter_validation.reuse_customer_clabe.invalid_datatype"
    }
  ],
  "object": "error",
  "type": "parameter_validation_error"
}

HTTP Status: 422 Unprocessable Entity


Comportamiento por defecto

Si no incluyes el parámetro reuse_customer_clabe o lo estableces en false, se generará una nueva CLABE única para cada orden:

curl --request POST \
  --url https://api.conekta.io/orders \
  --header 'accept: application/vnd.conekta-v2.2.0+json' \
  --header 'content-type: application/json' \
  --header 'Authorization: Bearer key_xxxxxxxxxxxxxxxxxxxxxxxx' \
  --data '{
    "currency": "MXN",
    "customer_info": {
      "customer_id": "cus_xxxxxxxxxx"
    },
    "line_items": [{
      "name": "Compra única",
      "unit_price": 10000,
      "quantity": 1
    }],
    "charges": [{
      "payment_method": {
        "type": "spei"
      }
    }]
  }'

Respuesta:

{
  "charges": {
    "data": [{
      "payment_method": {
        "type": "spei",
        "clabe": "646180111812345678"
      }
    }]
  }
}
📌

La CLABE 646180111812345678 es diferente a la referencia recurrente del cliente 646180111802000138.