Cómo crear una dispersión de negocio a persona (B2P)
Acredita a un usuario en ACH en línea (antes Transfiya) creando una intent SEND en Kamin Ledger. Una vez configurado tu entorno, el proceso consta de dos pasos simples.
Requisitos previos
Antes de comenzar:
- Has leído la guía de Primeros pasos y tienes configurados tu Wallet, Dominio y Autenticación.
- Has recuperado la dirección de destino desde ACH en línea, ya sea un objeto
telosigner. - Tienes un par de claves válidas para firmar las transacciones.
Flujo
Objetivo
Envía fondos a un destinatario usando el riel de pagos ACH en línea creando un intent.
Paso 1: Obtener la dirección de destino
ACH en línea soporta dos esquemas de dirección:
| Esquema | Ejemplo de formato | Caso de uso |
|---|---|---|
signer | signer:wbX9V3UnXie7zz6wSpKkZHUrdjA31rowcp@transfiya | Firmante de ACH en línea, acreditacion de fondos directo sin aceptación |
tel | tel:573066000001@transfiya | Número telefónico colombiano, requiere aceptación por parte del usuario |
Elige el que mejor se adapte a tu integración o experiencia de usuario.
¿Necesitas ayuda para obtener la dirección de destino? Consulta la guía Cómo obtener un destinatario en ACH en línea
Paso 2: Enviar la intent de transferencia
Puedes usar el SDK del ledger, la CLI o código para enviar una intent de transferencia de dinero. El ejemplo proporcionado primero resuelve el destino usando Anchor Lookup, luego procede a crear la intent SEND.
El origen es de donde se debitarán los fondos, en este caso, tu billetera, y el destino es la cuenta del usuario en ACH en línea.
Definición de campos
| Nombre | Tipo | Descripción |
|---|---|---|
| handle* | String (64) | Identificador unico del intent, usado para garantizar idempotencia |
| source* | String (64) | Billetera origen de la transferencia. En una intent SEND, el origen es tu billetera |
| target* | String (64) | Billetera destino. En una intent SEND, el destino es el fiarmante o el número de celular del usuario, según el esquema usado |
| amount* | integer | Monto de la transferencia |
| symbol* | String (16) | Moneda. Por defecto tcop |
| custom.description | String (255) | Descripción de la transferencia |
Ejemplo de solicitud
Hashea, firma y envía al endpoint Create Intent. Consulta Hashing y firmado de solicitudes para detalles.
POST https://<ledger-url>/api/v2/intentsAccept: application/json, text/plain, */*
Content-Type: application/json
x-ledger: <ledger-handle>{
"data": {
"handle": "<unique-intent-id>",
"claims": [
{
"action": "transfer",
"source": { "handle": "<source-wallet-handle>" },
"target": { "handle": "<target-signer-handle>" },
"symbol": { "handle": "tcop" },
"amount": <amount-in-cents>
}
],
"schema": "transfer",
"access": [
{ "action": "any", "signer": { "public": "<public-key>" } }
],
"custom": {
"description": "Un intent SEND a ACH en línea"
}
},
"hash": "<sha256-hash-of-data>",
"meta": {
"proofs": [
{
"method": "ed25519-v2",
"public": "<public-key>",
"digest": "<digest-del-proof>",
"result": "<signature-of-digest>",
"custom": { "moment": "<iso-8601-timestamp>" }
}
]
}
}Todas las solicitudes de mutación (como POST) deben ser firmadas con tu llave privada.
El monto enviado fue COP 1000 debido al factor de 100 que tiene el símbolo tcop
Cuerpo de la respuesta:
{
"hash": "559a7324f3f5f01a9ce23e1f1e8a6f06c68ccd4c510ecc3a025deafee781d85c",
"data": {
"handle": "cvS7ioG5k9U65GosbwDsy",
"claims": [
{
"action": "transfer",
"amount": 100000,
"source": {
"handle": "kamin.one"
},
"symbol": {
"handle": "tcop"
},
"target": {
"handle": "signer:wbX9V3UnXie7zz6wSpKkZHUrdjA31rowcp@transfiya"
}
}
],
"schema": "transfer",
"custom": {
"description": "Un intent SEND a ACH en línea"
},
"access": [
{
"action": "any",
"signer": {
"public": "Oh3xliLHnYelAZbQyTEZv5jo3JNrsBiea+/6X6AxUK0="
}
}
]
},
"luid": "$int.-0XJXjBbpzYN67lwM",
"meta": {
"proofs": [
{
"custom": {
"moment": "2025-06-17T19:09:33.299Z",
"status": "created"
},
"digest": "804c90a2b9c053976040791c7efdd7ee0b59fe1463091db68c99aa67e4912227",
"method": "ed25519-v2",
"public": "Oh3xliLHnYelAZbQyTEZv5jo3JNrsBiea+/6X6AxUK0=",
"result": "d5KZ647Gqkv85H6pqe132Hy2jprDKIWEhCjgrJTXr393Ku9OxI8yrmzfzO8YstiF5JrJOUNCXiZGQ1DDy8YMDA=="
},
{
"custom": {
"moment": "2025-06-17T19:09:33.878Z",
"status": "pending"
},
"digest": "3bf7894bf40967ef7c677b04118a9b7d34557c7152c84ac9fe752e4ff0038456",
"method": "ed25519-v2",
"public": "aSRs/3ni0v/zcLSQetGDAy1DunN9VcBPoeUK+UyzOJA=",
"result": "Fb15jWB2PQ6Z+QgDDXZoWwsG3H4WodMRxvNW6lldEfi56Vd11QRCHcNwt8D1QSOE7zuEkcVC4XISFX9/vw5ADQ=="
},
{
"custom": {
"luid": "$int.-0XJXjBbpzYN67lwM",
"moment": "2025-06-17T19:09:33.898Z",
"status": "pending"
},
"digest": "31c0ba4d36ce86f89c095830b4282d000f63a0a0b9641f0e1b290c89b733a831",
"method": "ed25519-v2",
"public": "aSRs/3ni0v/zcLSQetGDAy1DunN9VcBPoeUK+UyzOJA=",
"result": "4tfeYwp/d26g2MwBhPDoPOjZ6HD4dMrZyAighIfZvn3j/FfRWuTk/jDYgft4yPZnW1FqgcMsalhSLGt+VgdKBw=="
}
],
"status": "pending",
"thread": "-0XJXjh6_AjFUGHNz",
"moment": "2025-06-17T19:09:33.877Z",
"owners": ["Oh3xliLHnYelAZbQyTEZv5jo3JNrsBiea+/6X6AxUK0="]
}
}Verificación de la Transacción
- Revisa el campo
meta.statusen la respuesta o posteriormente con una solicitudGETa/intents/{handle}.
Consulta la guía Cómo obtener el estado de un intent. - El estado cambiará a
completedcuando la transferencia sea exitosa, o arejectedsi ocurre algún error. Puedes escuchar los cambios a través de un webhook.
Revisa la guía Cómo registrar y escuchar efectos de estado de un intent para más información. - Consulta el Ciclo de vida de un intent para detalles sobre cada estado.
¿Qué sigue?
Una vez que tu transferencia ha sido enviada, puedes:
- Monitorear el estado de la intent para confirmar su entrega
- Notificar al usuario cuando el pago se haya completado o fallado
- Registrar o conciliar la transacción en tu sistema interno
Historial de cambios
- Cambiado• Guía renombrada a dispersión B2P y movida a ACH en línea
- Cambiado• Renombrada a dispersión B2P en ACH en línea
- Agregado• Se agregó el ejemplo de la solicitud HTTP cruda (endpoint, headers y cuerpo JSON) junto a los ejemplos en TypeScript, SDK y CLI.
- Cambiado• Se actualizó el símbolo del rail Transfiya de `cop` a `tcop`.
- Agregado• Versión inicial