# Cargo recurrente — Transferencias SPEI (Direct API)

Úsalo cuando necesites cobrar montos recurrentes a un mismo cliente o proveedor por transferencia bancaria — por ejemplo rentas, mensualidades B2B, o pagos periódicos de proveedores — sin pedirle datos de tarjeta ni depender de que él inicie una transferencia distinta cada vez. A diferencia de un cargo SPEI único, aquí Conekta asigna una CLABE fija y reutilizable a un cliente: cualquier transferencia que llegue a esa CLABE se reconcilia automáticamente contra ese cliente, sin importar cuántas veces pague.

Ventajas de la solución:

  • Transacciones interbancarias recurrentes por montos grandes
  • Referencia única y persistente por cliente/proveedor
  • Recepción de pagos 24/7, sin intervención manual
  • Conciliación automática por CLABE — identificas cada pago sin pedirle referencia al cliente
  • Notificación y visibilidad de pagos en tiempo real vía webhook

Cómo funciona el flujo

  1. Registras al cliente — creas un customer con un payment_source de tipo spei_recurrent. Conekta genera y devuelve una CLABE (campo reference) asociada permanentemente a ese cliente.
  2. Compartes la CLABE — se la das a tu cliente o proveedor una sola vez; él la usa para transferir cada vez que le corresponda pagar.
  3. Conekta reconcilia automáticamente — cada transferencia recibida en esa CLABE se asocia al cliente y dispara el webhook correspondiente, sin que tengas que crear una orden nueva por cada pago.
📘

Nota

A diferencia del cargo SPEI único, aquí no creas una orden antes del pago — la orden se genera cuando el banco confirma la transferencia contra la CLABE ya asignada.


Prerequisitos

  • Llaves de modo de pruebas configuradas — para probar el flujo antes de ir a producción
  • Conocimientos básicos de una API REST (autenticación por header, verbos HTTP, formato JSON) — no se requiere ningún recurso externo, solo lo que ya se usa a lo largo de esta documentación
  • Backend propio capaz de exponer un endpoint HTTPS para recibir webhooks
  • Alguna librería o SDK de Conekta en el lenguaje de tu preferencia (opcional — también puedes integrar directo contra la API REST)

1. Añade tu llave privada y versión del API

Necesitarás tu llave privada de pruebas. Si aún no cuentas con ella, puedes obtenerla en tu Panel Conekta.

--header 'Authorization: Bearer key_xxxxxxx'
using Conekta.net.Api;
using Conekta.net.Client;
using Conekta.net.Model;

Configuration config = new Configuration();
config.AccessToken = "key_xxxxx";
require_once("/path/to/lib/Conekta.php");
\Conekta\Conekta::setApiKey("key_eYvWV7gSDkNYXsmr");
\Conekta\Conekta::setApiVersion("2.0.0");
require "conekta"
Conekta.api_key = "key_eYvWV7gSDkNYXsmr"
Conekta.api_version = "2.0.0"
import conekta
conekta.api_key = "key_eYvWV7gSDkNYXsmr"
conekta.api_version = "2.0.0"
var conekta = require('conekta');
conekta.api_key = 'key_eYvWV7gSDkNYXsmr';
conekta.api_version = '2.0.0';
import com.conekta;
Conekta.setApiKey("key_eYvWV7gSDkNYXsmr");
com.conekta.Conekta.apiVersion = "2.0.0"
import (
    conekta "github.com/conekta/conekta-go"
)
conekta.APIKey = "key_pMcnDF4zFyWKyLG15LuqwA"

2. Crea tu SPEI Recurrente

Con esto tus clientes estarán listos para pagar con una referencia personalizada. Para este proceso necesitas primero crear un customer e indicar que va a utilizar el payment_source de spei_recurrente. Con esto se genera la CLABE (referencia en la respuesta) que podrá usar tu cliente y realizar pagos con SPEI de manera recurrente en su banca.

Nota: En modo de pruebas se genera la misma referencia, en modo productivo esta cambia.

curl --request POST \
  --url https://api.conekta.io/customers \
  --header 'accept: application/vnd.conekta-v2.2.0+json' \
  -u key_eYvWV7gSDkNYXsmr: \
  --header 'content-type: application/json' \
  --data '{
      "name": "Fulanito",
      "email": "[email protected]",
      "phone": "+5218181818181",
      "payment_sources": {
        "type": "spei_recurrent"
      }
  }'

#Respuesta de API
{
   "livemode":false,
   "name":"Fulanito",
   "email":"[email protected]",
   "phone":"+5215555555555",
   "id":"cus_2nNW3ZFwnaeicFygP",
   "object":"customer",
   "created_at":1587510139,
   "corporate":false,
   "custom_reference":"",
   "payment_sources":{
      "object":"list",
      "has_more":false,
      "data":[{
         "id":"off_ref_2nZpKdaweaacDUz6W",
         "object":"payment_source",
         "type":"spei_recurrent",
         "reference":"646180111812345678",
         "created_at":1587510139,
         "parent_id":"cus_2nNW3ZFwnaeicFygP"
      }]
   }
}
using System.Collections.Generic;
using System.Diagnostics;
using Conekta.net.Api;
using Conekta.net.Client;
using Conekta.net.Model;

namespace Example
{
    public class CreateCustomerExample
    {
        public static void Main()
        {
            Configuration config = new Configuration();
            config.AccessToken = "key_xxxxxxx";

            var apiInstance = new CustomersApi(config);
            var paymentSources = new List<CustomerPaymentMethodsRequest>()
            {
                new CustomerPaymentMethodsRequest(
                    new PaymentMethodSpeiRequest("spei_recurrent")
                )
            };
            var customer = new(
                name: "test dot",
                phone: "+573143159063",
                email: "[email protected]",
                paymentSources: paymentSources,
            );
            try
            {
                // Create customer
                CustomerResponse result = apiInstance.CreateCustomer(customer);
                Debug.WriteLine(result);
            }
            catch (ApiException  e)
            {
                Debug.Print("Exception when calling CustomersApi.CreateCustomer: " + e.Message);
                Debug.Print("Status Code: " + e.ErrorCode);
                Debug.Print(e.StackTrace);
            }
        }
    }
}
try{
    $customer = \Conekta\Customer::create(
      array(
          'name'  => "fulanito",
          'email' => "[email protected]",
          'phone' => "+5218181818181",
          'payment_sources' => array(
                array(
                'type' => "spei_recurrent"
                )
            )
      )
    );
    var_dump(json_encode($customer));
  } catch (\Conekta\ProcessingError $error){
    echo $error->getMessage();
  } catch (\Conekta\ParameterValidationError $error){
    echo $error->getMessage();
  } catch (\Conekta\Handler $error){
    echo $error->getMessage();
  }

#Respuesta de API
{
   "livemode":false,
   "name":"Fulanito",
   "email":"[email protected]",
   "phone":"+5215555555555",
   "id":"cus_2nNW3ZFwnaeicFygP",
   "object":"customer",
   "created_at":1587510139,
   "corporate":false,
   "custom_reference":"",
   "payment_sources":{
      "object":"list",
      "has_more":false,
      "total":1,
      "data":[{
         "id":"off_ref_2nZpKdaweaacDUz6W",
         "object":"payment_source",
         "type":"spei_recurrent",
         "reference":"646180111812345678",
         "created_at":1587510139,
         "parent_id":"cus_2nNW3ZFwnaeicFygP"
      }]
   }
}
# N/A
# N/A
# N/A
# N/A
# N/A

3. Crear un Webhook

Consultar la referencia sobre Webhooks.

Con todo esto configurado ahora podrás utilizar SPEI Recurrente para tus clientes.


4. Agregar límites mínimo y/o máximo (opcional)

Agregar límites permitirá no aceptar pagos por debajo del mínimo y/o por encima del máximo en caso de ser configurados. Con la creación de su cuenta, puede notificarnos a través de servicio a cliente o su contacto en Conekta para que hagamos el set up de sus límites.

Ejemplo de caso de error

A tener en cuenta:

  • Si cuentas con validación a través de webhook, esa validación tiene prioridad sobre tus límites min-max a nivel compañía, por lo que si un webhook acepta o rechaza la transacción, esta será la decisión final y los límites no serán tomados en cuenta.

Errores comunes

Error HTTPCausa probableSolución
401 UnauthorizedLlave incorrecta o de otro modo (pruebas vs. producción)Usa la llave correspondiente al ambiente, ver API Keys — Testing
422 Unprocessable Entitypayment_sources.type inválido o customer mal formadoVerifica que el tipo sea exactamente spei_recurrent y que el customer tenga los campos requeridos
Transferencia no reconciliadaEl pago llegó fuera de los límites min/max configuradosRevisa los límites del paso 4 y la validación en tu endpoint de webhook

Para el catálogo completo de errores, consulta Códigos de error HTTP.


Relacionado