Débito Domiciliado
¿Qué es el Débito Domiciliado?
El Débito Domiciliado es un método que permite a las empresas cobrar a sus clientes de forma automática a través de su cuenta bancaria.
¿Cómo funciona el Débito Domiciliado?
La primera vez que se envía una solicitud de domiciliación a un cliente, el banco del cliente puede rechazarla con el mensaje "No posee afiliación". Esto significa que el cliente aún no ha autorizado el Débito Domiciliado para la empresa.
¿Qué debe hacer el cliente?
Para activar el Débito Domiciliado, el cliente debe acceder a la aplicación banca online de su institución bancaria y buscar la sección de domiciliaciones. Allí, podrá ver la solicitud de la empresa y aprobarla.
¿Qué pasa después de que el cliente aprueba la domiciliación?
El dinero se debitará al instante de su cuenta, si dispone de saldo suficiente.
¿Qué pasa si el cliente no aprueba la domiciliación?
Si el cliente no aprueba la domiciliación, la empresa no podrá realizar cobros automáticos a la cuenta del cliente. Retornará un rechazo MD22
Flujo de una transacción de Débito Domiciliado
1.Iniciar la solicitud de Débito por domiciliación: se envía un request al endpoint /api/v1/transaction/dom. En el cuerpo de la solicitud, se incluyen todos los datos necesarios para la transacción, como el account (la empresa), el amount (monto a cobrar) y la información de la domiciliación (domiciliation_data).
2.Validar la afiliación del cliente: el banco del cliente verifica si existe una afiliación o autorización previa para que la empresa pueda realizar el débito. Esta afiliación está vinculada a un contrato (domiciliation_data.contract) específico que el cliente ha aprobado.
3.Procesar la transacción:si el cliente ha aprobado la domiciliación, el banco procesa el débito automáticamente, en caso contrario, el banco del cliente rechazará la transacción con un mensaje específico, como "No posee afiliación" o "MD22".
El webhook (notification_urls) recibirá el estatus de rechazo.4.Recibir el estatus de la transacción: el webhook de notificación recibirá la respuesta definitiva de la transacción, ya sea el débito exitoso o el rechazo, junto con un mensaje firmado para validar su autenticidad.
POST api/v1/transaction/dom
{
"internal_id": "4D9F32F8627D",
"group_id": "C986C4E94624",
"account": {
"bank_code": "0001",
"type": "CNTA",
"number": "00011234567890123456"
},
"amount": {
"amt": 5,
"currency": "VES"
},
"concept": "Cobro de servicios",
"notification_urls": {
"web_hook_endpoint": "https://pruebas.sypago.net/notification"
},
"receiving_user": {
"name": "John Doe",
"document_info": {
"type": "V",
"number": "123456789"
},
"account": {
"bank_code": "0102",
"type": "CELE",
"number": "04121234567"
}
},
"domiciliation_data": {
"contract": {
"id": "1234567890",
"related_date": "2021-12-31"
}
}
}
{
"transaction_id": "AFD1AD8DA41E",
"operation_secret": "66471d35-6252-47aa-a99f-2b4873dc5adc"
}
- C#
- Java
class Domiciliacion
{
static String BASE_URL = "https://pruebas.api.sypago.net/";
static String TOKEN_PATH = "/api/v1/auth/token";
static String DEBITO_PATH = "/api/v1/transaction/dom";
static String CTA = "00014567890123456789";
static SocketsHttpHandler shHandler;
static async Task Main(string[] args)
{
shHandler = new SocketsHttpHandler
{
MaxConnectionsPerServer = 100,
PooledConnectionLifetime = TimeSpan.FromMinutes(10),
ConnectTimeout = TimeSpan.FromSeconds(200),
PooledConnectionIdleTimeout = TimeSpan.FromSeconds(5),
ResponseDrainTimeout = TimeSpan.FromSeconds(5),
};
HttpClient? cliente;
cliente = new HttpClient(shHandler);
cliente.BaseAddress = new Uri(BASE_URL);
string body = "{"client_id":"user_name","secret":"api_key"}";
var contenido = new StringContent(body, Encoding.UTF8, "application/json");
var respuesta = await cliente.PostAsync(TOKEN_PATH, contenido);
var resultado = await respuesta.Content.ReadAsStringAsync();
JsonDocument jsonDoc = JsonDocument.Parse(resultado);
string accessToken = jsonDoc.RootElement.GetProperty("access_token").GetString();
//Console.WriteLine(accessToken);
var internal_id = new Random().Next(1, 999999).ToString("000000") + new Random().Next(1, 999999).ToString("000000");
var group_id = new Random().Next(1, 999999).ToString("000000") + new Random().Next(1, 999999).ToString("000000");
body = "{"internal_id": "" + internal_id + "","group_id": "" + group_id + "","account": {"bank_code": "0001","type": "CNTA","number": "" + CTA + ""},"amount": {"amt": 2.00,"currency": "VES"},"concept": "CONCEPTO-Domiciliacion","notification_urls": {"web_hook_endpoint": "http://Urlretorno:8080/transaction/sts"},"receiving_user": {"name": "Carly Mata","document_info": {"type": "V","number": "12345678"},"account": {"bank_code": "0102","type": "CELE","number": "4121234567"}},"domiciliation_data": {"contract": {"id": "%s","related_date": "2023-10-05"},"invoices": [{"id": "%s","related_date": "2023-10-05","rejection_date": "2024-10-05","amount": {"amt": 2,"currency": "VES"}}]}}";
cliente.DefaultRequestHeaders.Add("Authorization", "Bearer " + accessToken);
contenido = new StringContent(body, Encoding.UTF8, "application/json");
respuesta = await cliente.PostAsync(DEBITO_PATH, contenido);
resultado = await respuesta.Content.ReadAsStringAsync();
Console.WriteLine($"resultado: {resultado}");
Console.WriteLine("
");
jsonDoc = JsonDocument.Parse(resultado);
string transaction_id = jsonDoc.RootElement.GetProperty("transaction_id").GetString();
Console.WriteLine($"transaction_id: {transaction_id}");
}
}
public class Domiciliacion {
static String BASE_URL = "https://pruebas.api.sypago.net/";
static String DEBITO_OTP_PATH = "/api/v1/transaction/dom";
static String cuenta = "00014567890123456789";
static String TOKEN_PATH = "/api/v1/auth/token";
static String CREDEN = """
{
"client_id":"user_name",
"secret":"api_key"
}
""";
// Cliente Http
public static final MediaType JSON = MediaType.get("application/json");
OkHttpClient client = new OkHttpClient();
public static void main(String[] args) throws IOException {
Domiciliacion sypago = new Domiciliacion();
String internal_id = RandomStringUtils.random(12, true, true);
String group_id = RandomStringUtils.random(12, true, true);
String IP = java.net.InetAddress.getLocalHost().getHostAddress();
String contractID = RandomStringUtils.random(8, false, true);
String invoicesID = RandomStringUtils.random(8, false, true);
String body = """
{
"internal_id": "%s",
"group_id": "%s",
"account": {
"bank_code": "0001",
"type": "CNTA",
"number": "%s"
},
"amount": {
"amt": 2.00,
"currency": "VES"
},
"concept": "CONCEPTO-Domiciliacion",
"notification_urls": {
"web_hook_endpoint": "http://%s:8080/transaction/sts"
},
"receiving_user": {
"name": "Carly Mata",
"document_info": {
"type": "V",
"number": "12345678"
},
"account": {
"bank_code": "0102",
"type": "CELE",
"number": "4121234567"
}
},
"domiciliation_data": {
"contract": {
"id": "%s",
"related_date": "2023-10-05"
},
"invoices": [
{
"id": "%s",
"related_date": "2023-10-05",
"rejection_date": "2024-10-05",
"amount": {
"amt": 2,
"currency": "VES"
}
}
]
}
}
""".formatted(internal_id, group_id, cuenta,IP, contractID, invoicesID);
var resp = sypago.domiciliacion(BASE_URL+DEBITO_OTP_PATH, body, sypago.getToken(BASE_URL+TOKEN_PATH, CREDEN));
System.out.println("Identificador de la transacción: " + resp);
}
public String domiciliacion(String url, String json, String token) throws IOException {
RequestBody body = RequestBody.create(json, JSON);
Request request = new Request.Builder()
.url(url)
.addHeader("Authorization", "Bearer " + token)
.post(body)
.build();
try (Response response = client.newCall(request).execute()) {
int httpcode = response.code();
if(httpcode == 401) return "No se ha autenticado con el token";
JSONObject respuesta = new JSONObject(response.body().string());
if(httpcode == 409) {
return respuesta.getString("message");
}
return respuesta.getString("transaction_id");
}
}
public String getToken(String url, String json) throws IOException {
RequestBody body = RequestBody.create(json, JSON);
Request request = new Request.Builder()
.url(url)
.post(body)
.build();
try (Response response = client.newCall(request).execute()) {
int httpcode = response.code();
if(httpcode == 401) return "No se ha autenticado con el token";
JSONObject respuesta = new JSONObject(response.body().string());
if(httpcode == 409) {
return respuesta.getString("message");
}
return respuesta.getString("access_token");
}
}
}