Fuentes de pago & Tokenización
En Wompi, no sólo puedes ofrecer a tus usuarios realizar pagos de una sola vez -como el de un carrito de compras-, sino que también puedes ofrecer que paguen por tus productos y servicios sin su intervención directa, como es el caso de un cobro periódico -una suscripción a una revista por ejemplo-, o el cobro de un servicio on-demand, como entregas a domicilio o servicios de transporte, por ejemplo, donde idealmente tus usuarios sólo provean su información de pago una única vez y los cargos se hagan a futuro, según lo requiera tu modelo de negocio.
A este tipo de pagos se les conoce también como pagos automáticos.
Esto lo puedes ofrecer usando nuestra funcionalidad de fuentes de pago del API. Tus usuarios los pueden realizar usando tarjetas o cuentas Nequi, y requieren que el usuario lleve a cabo un único proceso inicial, donde provea bien sea la información de su tarjeta o de su cuenta Nequi, que será usada posteriormente para hacer los cobros respectivos.
Tan sólo debes seguir el paso a paso descrito a continuación:
Paso a paso
- Paso 1 — Solicita la información del método de pago.
- Paso 2 — Crea una fuente de pago.
- Paso 3 — Crea una transacción usando la fuente de pago.
Paso 1: Solicita la información del método de pago
El primero de estos 3 pasos para realizar un cobro usando fuentes de pago, requiere el almacenamiento de forma segura de una tarjeta, cuenta Nequi o cuenta DaviPlata. Para eso, usarás nuestro API de manera que Wompi almacene de manera segura información de tarjetas, cuentas Nequi y cuentas DaviPlata.
Al proceso de guardar y representar la información de una tarjeta de manera segura le llamamos: Tokenización. Esto quiere decir que debes enviar al endpoint respectivo del API de Wompi la información del método de pago, una única vez, y obtendrás un token el cual podrás usar para crear la fuente de pago en el Paso 2 de esta guía.
Tarjetas
Para tarjetas de crédito o débito el endpoint que debes usar es /v1/tokens/cards realizando un POST con el siguiente cuerpo JSON:
{
"number": "4242424242424242", // Número de tarjeta (como un string, sin espacios)
"exp_month": "06", // Mes de expiración (como string de 2 dígitos)
"exp_year": "29", // Año de expiración (como string de 2 dígitos)
"cvc": "123", // Código de seguridad (como string de 3 o 4 dígitos)
"card_holder": "Pedro Pérez" // Nombre del tarjeta habiente (string de mínimo 5 caracteres)
}
Como resultado a esta petición recibirás la siguiente respuesta:
{
"status": "CREATED",
"data": {
"id": "tok_prod_15_44c5638281if67l04eA63f705bfA5bde",
"created_at": "2020-09-07T19:09:31.585+00:00",
"brand": "VISA",
"name": "VISA-4242",
"last_four": "4242",
"bin": "538696",
"exp_year": "29",
"exp_month": "06",
"card_holder": "Pedro Pérez",
"expires_at": "2021-09-05T19:09:30.000Z"
}
}
Si en el campo status recibes el valor "CREATED", esto quiere decir que la tarjeta ha sido tokenizada correctamente y puedes usar la propiedad id para registrar la fuente de pago.
Cuentas Nequi
Para pagos con Nequi, el endpoint que debes usar es /v1/tokens/nequi realizando un POST con la Llave Pública como autorizador con el siguiente cuerpo JSON:
{
"phone_number": "3017654321"
}
Recibirás como respuesta en la propiedad id el token con el que podrás registrar la fuente de pago. Sin embargo, el cliente tendrá que haber aceptado primero la suscripción en su celular de modo que el estado pase de "PENDING" a "APPROVED".
{
"data": {
"id": "nequi_prod_RQkUiuv3lEnDLiSao2Cz0iQLdFlyQOI5",
"status": "PENDING",
"phone_number": "3107654321",
"name": "Company Name"
}
}
Para chequear el estado de la suscripción, puedes hacer GET en el endpoint de /v1/tokens/nequi/ con el token obtenido:
GET /v1/tokens/nequi/nequi_prod_RQkUiuv3lEnDLiSao2Cz0iQLdFlyQOI5
Una vez se obtenga un "APPROVED" en la propiedad "status" será posible registrar la fuente de pago.
{
"data": {
"id": "nequi_prod_RQkUiuv3lEnDLiSao2Cz0iQLdFlyQOI5",
"status": "APPROVED",
"phone_number": "3107654321",
"name": "Company Name"
}
}
Cuentas DaviPlata
Antes de utilizar este medio de pago en el ambiente productivo, debes solicitar al equipo comercial su respectiva activación.
Requisitos
- Llave pública del comercio
- Datos de prueba.
Explicación del uso de las APIs
- Para inicializar el proceso de tokenización de una cuenta Daviplata, el endpoint que debes utilizar es:
POST /v1/tokens/daviplata
Con la Llave publica como Bearer token para poder autenticarla, con el siguiente cuerpo JSON:
{
"type_document": "CC",
"number_document": "1122233",
"product_number": "3991111111"
}
Nota: Debes tener en cuenta que el comportamiento dependera del valor que pongas en el campo product_number, como se especifica en los datos de prueba ya que es un ambiente Sandbox.
Como resultado a esta petición recibirás la siguiente respuesta:
{
"data": {
"id": "daviplata_devtest_KYbozzUqNlHVQ3Rxgi1skM3991111111",
"status": "PENDING",
"url_services": {
"token": "token_de_autenticacion",
"code_otp_send": "https://test.com",
"code_otp_validate": "https://test.com"
}
},
"meta": {}
}
- id: Corresponde al token que se le es asociado a la cuenta Daviplata.
- status: Estado actual del token.
- token: Es la llave que nos permitirá consumir el siguiente servicio (code_otp_send), este token es de un solo uso.
- code_otp_send: URL del API que enviara el código OTP al cliente pagador.
- code_otp_validate: URL del API que validará el código OTP que el cliente pagador digite.
- Enviar el código OTP al cliente pagador:
Requisitos
- Token: Lo encuentras en el resultado de la petición anterior:
data -> url_services -> token. - URL: La encuentras en el resultado de la petición anterior:
data -> url_services -> code_otp_send.
Debes realizar una petición POST a la URL y enviar como Bearer Token el Token, ejemplo:
POST https://test.com
Como resultado a esta petición recibirás la siguiente respuesta:
{
"status": 200,
"code": "OK",
"message": "Solicitud ejecutada correctamente.",
"data": {
"subscription": {
"PK": "daviplata_devtest_KYbozzUqNlHVQ3Rxgi1skM3991111111",
"status": "PENDING",
"statusMessage": "",
"steps": {
"PurchaseIntention": [
{
"resultStatus": {
"message": "Transacción aprobada",
"transactionDate": "2024-07-31T21:52:04.146+00:00",
"transactionId": "KlfxX9Ir-rDlY-KVzI-oOzwQyGaYRmC",
"status": 0
},
"infoOtp": {
"idSesionOTP": "20270866",
"expirationDateOTP": "2024-07-31T21:52:04.146+00:00",
"expirationTimeOTP": 3
}
}
]
}
},
"authorization": {
"access_token": "pub_devtest_lfGsG2o7X6OL8fOSVcaP2r20sMGpMgT9"
},
"attempts": {
"currentSendCode": 1,
"limitSendCode": 2,
"currentValidateCode": 0,
"limitValidateCode": 2
}
}
}
Nos vamos a centrar en la información que viene en data -> subscription:
- PK: Corresponde al token asociado a la cuenta Daviplata.
- status: Estado actual del token.
- statusMessage: En caso de ser distinto de vacío, informa el motivo del fallo.
- steps -> PurchaseIntention: Es un arreglo que, en cada una de sus iteraciones en orden descendente, indica el número de veces que se ha enviado el código OTP al cliente.
- steps -> PurchaseIntention -> resultStatus: Información de la respuesta a la solicitud de envío del código OTP.
- steps -> PurchaseIntention -> infoOtp -> idSesionOTP: Este ID es de uso único y expira cuando el cliente pagador digita erróneamente el código OTP (se sugiere solicitar otro código OTP).
- steps -> PurchaseIntention -> infoOtp -> expirationDateOTP: Hora hasta la que tiene vigencia el código OTP.
- steps -> PurchaseIntention -> infoOtp -> expirationTimeOTP: Minutos de vigencia del código OTP
Adicional a esto:
- authorization -> access_token: Token que puede ser usado para consumir code_otp_send o code_otp_validate; es un token de uso único.
- attemps -> currentSendCode: Número de veces que se ha enviado el código OTP al cliente pagador.
- attemps -> limitSendCode: Número máximo de veces permitido para el envío del código OTP al cliente pagador.
- attemps -> currentValidateCode: Número de veces que el cliente pagador ha digitado y validado el código OTP.
- attemps -> limitValidateCode: Número máximo de veces permitido para la validación del código OTP.
- Validar el código OTP que digita el cliente pagador:
Requisitos
- Token: Lo encuentras en el resultado de la petición anterior:
data -> authorization -> access_token. - URL: La encuentras en el resultado de la petición del primer paso:
data -> url_services -> code_otp_validate. - Código OTP: Lo recibe el cliente pagador como mensaje de texto. En Sandbox utilizar los datos de prueba.
Debes realizar una petición POST a la URL, utilizar como Bearer Token el token, ejemplo:
POST https://test.com
y enviar en el cuerpo de la petición:
{
"code": "574829"
}
Como resultado a esta petición recibirás la siguiente respuesta:
{
"status": 200,
"code": "OK",
"message": "Solicitud ejecutada correctamente.",
"data": {
"subscription": {
"PK": "daviplata_devtest_KYbozzUqNlHVQ3Rxgi1skM3991111111",
"status": "APPROVED",
"statusMessage": "",
"steps": {
"PurchaseIntention": [
{
"resultStatus": {
"message": "Transacción aprobada",
"transactionDate": "2024-07-31T22:28:50.974+00:00",
"transactionId": "6Ggyd3w7-efqj-PZd8-40RMbLM32veV",
"status": 0
},
"infoOtp": {
"idSesionOTP": "20270866",
"expirationDateOTP": "2024-07-31T22:28:50.974+00:00",
"expirationTimeOTP": 3
}
}
],
"ConfirmIntention": [
{
"resultStatus": {
"message": "Transacción aprobada",
"transactionDate": "2024-07-31T22:28:50.974+00:00",
"transactionId": "wkwoA4TR-R1ti-yw46-0sBSeQ7vi0gB",
"status": 0
},
"Subscription": {
"Commerce": {
"commerceId": 1004,
"commerceName": "Juan Manuel Tamayo Monje"
},
"Product": {
"productCode": "DVP_CO",
"productNumber": "3991111111"
},
"Identification": {
"identificationNumber": "1234567890",
"identificationType": "CC"
},
"subscriptionId": 5734,
"maxValue": {
"currencyType": "COP",
"value": 0
},
"TppPartner": {
"tppPartnerName": "Test Daviplata Sandbox",
"tppPartnerId": "00000001"
}
}
}
]
}
},
"authorization": {
"access_token": "pub_devtest_lfGsG2o7X6OL8fOSVcaP2r20sMGpMgT9"
},
"attempts": {
"currentSendCode": 1,
"limitSendCode": 2,
"currentValidateCode": 0,
"limitValidateCode": 2
}
}
}
Nos vamos a centrar nuevamente en la información que viene en data -> subscription; en esta ocasión, recibiremos un campo adicional.
- status: Como podemos observar el token ha sido APPROVED, aquí terminaríamos el proceso de tokenización.
- steps -> ConfirmIntention: Es un arreglo que, en cada una de sus iteraciones en orden descendente, indica el número de veces que el cliente a tratado de confirmar el código OTP.
- steps -> ConfirmIntention -> resultStatus: Información de la respuesta a la solicitud de envío del código OTP.
- steps -> ConfirmIntention -> subscription: Información relacionada con la suscripción.
Si el cliente ha digitado un código OTP incorrecto, obtendremos la siguiente respuesta:
{
"status": 200,
"code": "OK",
"message": "Solicitud ejecutada correctamente.",
"data": {
"subscription": {
"PK": "daviplata_devtest_KYbozzUqNlHVQ3Rxgi1skM3220164001",
"status": "PENDING",
"statusMessage": "",
"steps": {
"PurchaseIntention": [
{
"resultStatus": {
"message": "Transacción aprobada",
"transactionDate": "2024-08-01T15:49:02.558+00:00",
"transactionId": "FAZpFUnO-3JUa-aUiy-yurjWxOeJo7z",
"status": 0
},
"infoOtp": {
"idSesionOTP": "20270866",
"expirationDateOTP": "2024-08-01T15:49:02.558+00:00",
"expirationTimeOTP": 3
}
}
],
"ConfirmIntention": [
{
"resultStatus": {
"message": "No se puede ejecutar la transacción",
"transactionDate": "2024-05-08T16:23:33.104-00:00",
"transactionId": "8eb61a58-5df1-4838-945c-0f634fdd8686",
"status": "2"
},
"faultstring": "OTP_INVALIDO"
}
]
}
},
"authorization": {
"access_token": "pub_devtest_lfGsG2o7X6OL8fOSVcaP2r20sMGpMgT9"
},
"attempts": {
"currentSendCode": 1,
"limitSendCode": 2,
"currentValidateCode": 0,
"limitValidateCode": 2
}
}
}
Nos vamos a centrar nuevamente en la información que viene en data -> subscription; en esta ocasión, recibiremos un campo adicional.
- status: Como podemos observar el proceso de tokenización continua en estado PENDING.
- steps -> ConfirmIntention -> resultStatus: Información de la respuesta a la solicitud de envío del código OTP.
- steps -> ConfirmIntention -> faultstring: Motivo del fallo de la autenticación.
Recomendaciones
- He de recordar que el token que obtenemos de
data -> authorization -> access_tokenes de uso único; por ende, en cada petición exitosa que se haga, este sera generado y devuelto para ser usado. - steps -> PurchaseIntention y steps -> ConfirmIntention son dos arrays que crecen descendientemente de acuerdo con los envíos de código OTP que solicite el cliente y las validaciones de código OTP que realice el cliente. (En ambiente Sandbox, solo encontrarás una iteración en cada uno de los escenarios mencionados anteriormente). En cualquiera de los dos casos, la última posición del array muestra el resultado de la petición solicitada.
- attemps:
- Estos escenarios no se pueden replicar en el ambiente Sandbox; por ende, la información que obtenemos en attempts es netamente informativa.
- El número máximo de reenvío de códigos OTPs en ambiente productivo es 2.
- El número máximo de intentos permitido para validar el código OTP es 2.
- Al exceder el número de intentos en cualquiera de los dos escenarios anteriores obtendremos:
{
"status": 500,
"meta": {
"trace_id": "92a53630-503e-11ef-b637-b76fbbdbd451"
},
"code": "500",
"message": "Ha agotado el número de intentos de envío de código OTP",
"data": {
"PK": "daviplata_devint_h2UEgbEE30H29iVoS1aBXUlA961zfXJL",
"status": "DECLINED",
"statusMessage": "Ha agotado el número de intentos de envío de código OTP",
"steps": {
"PurchaseIntention": [
{
"resultStatus": {
"message": "Transacción aprobada",
"transactionDate": "2024-08-01T14:45:12.270-05:00",
"transactionId": "068e2764-dece-4b85-8921-56016c554be3",
"status": 0
},
"infoOtp": {
"idSesionOTP": "84446823",
"value": "135301",
"expirationDateOTP": "2024-08-01 14:48:12.104",
"expirationTimeOTP": 3
}
},
{
"resultStatus": {
"message": "Transacción aprobada",
"transactionDate": "2024-08-01T14:45:13.803-05:00",
"transactionId": "4118cad1-fe17-43c1-b2fe-30e3e0f3b0a7",
"status": 0
},
"infoOtp": {
"idSesionOTP": "33041739",
"value": "609102",
"expirationDateOTP": "2024-08-01 14:48:13.741",
"expirationTimeOTP": 3
}
}
]
},
"createdAt": "2024-08-01T19:45:09.281Z",
"updatedAt": "2024-08-01T19:45:13.903Z"
},
"type": "Technical"
}
Cuando obtengamos un token con status APPROVED, hemos finalizado la tokenización y podemos continuar con el siguiente paso, Crear una fuente de pago, si requieres consultar un token debes realizar una petición:
GET /v1/tokens/daviplata/daviplata_prod_qOVWahMgs2oOYHvggC1Mxc3991111111
Y enviar la Llave pública como Bearer token, como resultado a esta petición recibirás la siguiente respuesta:
{
"data": {
"id": "daviplata_devtest_KYbozzUqNlHVQ3Rxgi1skM3991111111",
"status": "APPROVED",
"status_message": "",
"client_info": {
"type_document": "CC",
"number_document": "14395323",
"phone_number": "3991111111"
}
},
"meta": {}
}
Cuentas Bancolombia (Botón Bancolombia)
Con este proceso podras habilitar el proceso de suscripción de cuentras Bancolombia, permitiendo realizar cobros directamente a las cuentas inscritas exitosamente.
El primer paso del flujo se necesita generar un token de bancolombia, para continuar con el proceso a travez del endpoint
POST /v1/tokens/bancolombia_transfer
En esta petición se debe enviar la llave publica de tu comercio como Bearer Token para poder autenticarla y en el cuerpo de la petición la información asociada al Cliente.
Para el proceso de selección de cuenta, por parte del cliente, se debera primero realizar la creación de los tokens.
Acontinuación se muestran dos ejemplos distintos:
"redirect_url"URL a la cual se dirigirá la experiencia Una vez la ventana de selección de cuenta en el portal Bancolombia termine"type_auth"Tipo de solicitud de suscripción, Si es TOKEN la autorización se debera de realizar al momento de la respuesta de la petición, si es TRANSACTION esta autorización se ejecutaria en la primera autorización
-
Selección de Cuenta durante Transacción Petición
{
"redirect_url": "https://www.redirect_url_example.com",
"type_auth": "TRANSACTION"
}- Respuesta
{
"data": {
"id": "<<ID_DEL_TOKEN_CREADO>>",
"status": "AVAILABLE",
"status_message": "",
"bank_account_type": "",
"bank_account_last_four": "",
"redirect_url": "https://www.redirect_url_example.com",
"authorization_url": "",
"created_at": "2024-06-07T16:26:21.289Z",
"updated_at": "2024-06-07T16:26:21.289Z"
},
"meta": {}
}Importante que el estado este en AVAILABLE esto permite que se pueda usar el token en el paso de creación de la fuente de pago
-
Selección de Cuenta Previo a la transacción Petición
{
"redirect_url": "https://www.redirect_url_example.com",
"type_auth": "TOKEN"
}- Respuesta
{
"data": {
"id": "<<ID_DEL_TOKEN_CREADO>>",
"status": "PENDING",
"status_message": "",
"bank_account_type": "",
"bank_account_last_four": "",
"redirect_url": "https://www.redirect_url_example.com",
"authorization_url": "https://<<URL para realizar la selección y autorización de la cuenta desde Bancolombia>>",
"created_at": "2024-06-07T14:50:25.389Z",
"updated_at": "2024-06-07T14:50:26.104Z"
},
"meta": {}
}authorization_url
Por medio de este campo nos podemos dirigir a Bancolombia a realizar la suscripción sin realizar la transacción, teniendo en cuenta que una vez que esta finalize se redireccionara a la URL enviada previamente en el parametro redirect_url

- Ya posterior a que el cliente pagador autorize la cuenta el comercio debera de consultar el estado de la misma por medio del API
v1/tokens/bancolombia_transfer/<<ID_DEL_TOKEN_CREADO>>El resultado de ser completa la subcripción sería parecida a la siguiente
{
"data": {
"id": "<<ID_DEL_TOKEN_CREADO>>",
"status": "APPROVED",
"status_message": "",
"bank_account_type": "CUENTA AHORROS",
"bank_account_last_four": "***1234",
"redirect_url": "https://www.redirect_url_example.com",
"authorization_url": "<<URL para realizar la selección y autorización de la cuenta desde Bancolombia en esta respuesta ya nose usaria>>",
"created_at": "2024-06-07T16:21:19.904Z",
"updated_at": "2024-06-07T16:22:22.072Z"
},
"meta": {}
}Ya con el estado APPROVED Se puede seguir al paso de la creación de la fuente de pago
Paso 2: Crea una fuente de pago
Para crear una fuente de pago, se debe hacer un POST a
/v1/payment_sources
Con los campos:
"customer_email"que es el email del pagador"type"para indicar el medio de pago correspondiente al token, que puede ser"NEQUI"o"CARD""token"el token de Nequi o Tarjeta que hayas obtenido"acceptance_token"un token de aceptación para la política de privacidad"accept_personal_auth"un token de aceptación para la autorización de tratamiento de datos personales
Tarjetas
El cuerpo de la petición debe ser similar al siguiente:
{
"type": "CARD",
"token": "tok_prod_1_BBb749EAB32e97a2D058Dd538a608301",
"customer_email": "pepito_perez@example.com",
"acceptance_token": "eyJhbGciOiJIUzI1NiJ9.eyJjb250cmFjdF9pZCI6MSwicGVybWFsaW5rIjoiaHR0cHM6Ly93b21waS5jby93cC1jb250ZW50L3VwbG9hZHMvMjAxOS8wOS9URVJNSU5PUy1ZLUNPTkRJQ0lPTkVTLURFLVVTTy1VU1VBUklPUy1XT01QSS5wZGYiLCJmaWxlX2hhc2giOiIzZGNkMGM5OGU3NGFhYjk3OTdjZmY3ODExNzMxZjc3YiIsImppdCI6IjE1ODEwOTIzNjItMzk1NDkiLCJleHAiOjE1ODEwOTU5NjJ9.JwGfnfXsP9fbyOiQXFtQ_7T4r-tjvQrkFx0NyfIED5s",
"accept_personal_auth": "eyJhbGciOiJIUzI1NiJ9.eyJjb250cmFjdF9pZCI6NDQxLCJwZXJtYWxpbmsiOiJodHRwczovL3dvbXBpLmNvbS9hc3NldHMvZG93bmxvYWRibGUvYXV0b3JpemFjaW9uLWFkbWluaXN0cmFjaW9uLWRhdG9zLXBlcnNvbmFsZXMucGRmIiwiZmlsZV9oYXNoIjoiOTVkYzcwN2M0M2UxYmViMDAwMDUyZDNkNWJhZThhMDAiLCJqaXQiOiIxNzI5NTY0MTM2LTU2NjMwIiwiZW1haWwiOiIifQ.0f-hFte-mpCcnxlrPgEG-fLdGBWUoQaUhU71pPuij40"
}
Obtendremos una respuesta con una estructura como la siguiente indicándonos que fue creada exitosamente:
{
"data": {
"id": 3891,
"public_data": {
"type": "CARD"
},
"type": "CARD",
"status": "AVAILABLE"
}
}
Cuentas Nequi
El cuerpo de la petición debe ser similar al siguiente:
{
"type": "NEQUI",
"token": "nequi_prod_RQkUiuv3lEnDLiSao2Cz0iQLdFlyQOI5",
"customer_email": "pepito_perez@example.com",
"acceptance_token": "eyJhbGciOiJIUzI1NiJ9.eyJjb250cmFjdF9pZCI6MSwicGVybWFsaW5rIjoiaHR0cHM6Ly93b21waS5jby93cC1jb250ZW50L3VwbG9hZHMvMjAxOS8wOS9URVJNSU5PUy1ZLUNPTkRJQ0lPTkVTLURFLVVTTy1VU1VBUklPUy1XT01QSS5wZGYiLCJmaWxlX2hhc2giOiIzZGNkMGM5OGU3NGFhYjk3OTdjZmY3ODExNzMxZjc3YiIsImppdCI6IjE1ODEwOTIzNjItMzk1NDkiLCJleHAiOjE1ODEwOTU5NjJ9.JwGfnfXsP9fbyOiQXFtQ_7T4r-tjvQrkFx0NyfIED5s",
"accept_personal_auth": "eyJhbGciOiJIUzI1NiJ9.eyJjb250cmFjdF9pZCI6NDQxLCJwZXJtYWxpbmsiOiJodHRwczovL3dvbXBpLmNvbS9hc3NldHMvZG93bmxvYWRibGUvYXV0b3JpemFjaW9uLWFkbWluaXN0cmFjaW9uLWRhdG9zLXBlcnNvbmFsZXMucGRmIiwiZmlsZV9oYXNoIjoiOTVkYzcwN2M0M2UxYmViMDAwMDUyZDNkNWJhZThhMDAiLCJqaXQiOiIxNzI5NTY0MTM2LTU2NjMwIiwiZW1haWwiOiIifQ.0f-hFte-mpCcnxlrPgEG-fLdGBWUoQaUhU71pPuij40"
}
Obtendremos una respuesta con una estructura como la siguiente indicándonos que fue creada exitosamente:
{
"data": {
"id": 3891,
"public_data": {
"type": "NEQUI",
"phone_number": "3105671703"
},
"type": "NEQUI",
"status": "AVAILABLE"
}
}
Cuentas DaviPlata
Requisitos
- Llave privada.
- Token Daviplata con status APPROVED.
- Email del pagador.
-
Antes de crear una fuente de pago debes obtener un Token de aceptación.
-
Para crear una fuente de pago debes realizar una petición:
POST /v1/payment_sources
Usa tu Llave privada como Bearer token y envia como cuerpo de la petición la siguiente información:
{
"type": "DAVIPLATA",
"token": "daviplata_devtest_KYbozzUqNlHVQ3Rxgi1skM3991111111",
"customer_email": "test@test.com",
"acceptance_token": "token_de_aceptacion",
"accept_personal_auth": "token_de_aceptacion_tratamiento_de_datos_personales"
}
Como resultado a esta petición recibirás la siguiente respuesta:
{
"data": {
"id": 8276,
"public_data": {
"type": "DAVIPLATA",
"type_document": "CC",
"number_document": "14395323",
"phone_number": "3991111111"
},
"token": "daviplata_devtest_KYbozzUqNlHVQ3Rxgi1skM3991111111",
"type": "DAVIPLATA",
"status": "AVAILABLE",
"customer_email": "test@test.com"
},
"meta": {}
}
- id: Es el identificador de la fuente de pago, se utiliza para:
- Crear transacciones.
- Cancelar la fuente de pago y desuscribir el Daviplata del comercio.
- public_data:
- type_document: Tipo de documento del cliente pagador.
- number_document: Número de documento del cliente pagador.
- phone_number: Número del Daviplata del cliente pagador.
- token: Token con el que se creó la fuente de pago.
- type: Medio de pago de la fuente de pago.
- status: Estado de la fuente de pago, para ser usado, el status debe ser AVAILABLE.
- customer_email: Correo del cliente pagador.
Si tratamos de crear una fuente de pago con un token cuyo estado final es diferente de APPROVED, obtendremos la siguiente respuesta:
{
"error": {
"type": "UNPROCESSABLE",
"reason": "La fuente de pago ha sido declinada"
}
}
Recomendaciones
- Una vez creada una fuente de pago con el status AVAILABLE, puedes crear transacciones utilizando el ID de la fuente de pago.
- Cuando la tokenización es exitosa (status APPROVED), se ha realizado una suscripción del Daviplata del cliente pagador con el comercio. Sin embargo, no se puede utilizar para realizar pagos ni para hacer la desuscripción. En cualquiera de los dos escenarios mencionados anteriormente, debes crear una fuente de pago.
- Un cliente pagador puede tokenizar su Daviplata con el comercio una sola vez, este escenario no se puede replicar en el ambiente Sandbox. Si trata de realizar una tokenización con una cuenta ya tokenizada obtendrá el siguiente error:
{
"status": 500,
"meta": {
"trace_id": "417adc60-503e-11ef-b637-b76fbbdbd451"
},
"code": "2",
"message": "SUSCRIPCION_YA_EXISTE",
"data": {
"PK": "daviplata_devint_yam2QkUw0jRx3PzeSYFtvhGGfXQlC96J",
"status": "DECLINED",
"statusMessage": "SUSCRIPCION_YA_EXISTE",
"steps": {
"PurchaseIntention": [
{
"resultStatus": {
"message": "Transacción aprobada",
"transactionDate": "2024-08-01T14:42:56.414-05:00",
"transactionId": "a1a30968-0494-42ae-a3fa-a33b08f73c76",
"status": 0
},
"infoOtp": {
"idSesionOTP": "29268759",
"value": "155345",
"expirationDateOTP": "2024-08-01 14:45:56.341",
"expirationTimeOTP": 3
}
}
]
},
"createdAt": "2024-08-01T19:42:53.407Z",
"updatedAt": "2024-08-01T19:42:56.539Z"
},
"type": "Technical"
}
Nota: Para la desuscripción de una cuenta Daviplata con el comercio, se recomienda crear la fuente de pago y realizar la siguiente petición:
PUT /v1/payment_sources/{{ID_FUENTE_DE_PAGO}}/void
Utilizando tu Llave privada como Bearer token, recibiras la siguiente respuesta:
{
"data": {
"id": 8276,
"public_data": {
"type": "DAVIPLATA",
"type_document": "CC",
"number_document": "300051",
"phone_number": "3991111111"
},
"token": "daviplata_devint_O2RJ3a6e7ayYjzadMmtZ1q81jQr03mZ9",
"type": "DAVIPLATA",
"status": "VOIDED",
"customer_email": "test@test.com"
},
"meta": {}
}
Como podemos observar, el status cambió a VOIDED. En este estado, si intentas crear una transacción con esta fuente de pago, no va a ser posible.
Cuentas Bancolombia (Botón Bancolombia)
El cuerpo de la petición debe ser similar al siguiente:
{
"type": "BANCOLOMBIA_TRANSFER",
"token": "<<ID_DEL_TOKEN_CREADO>>",
"payment_description": "<<Descripción de la suscripción creada, 'Este campo es el valor por defecto con el cual se describe cada cobro, aunque también cada cobro se podra personalizar durante la creación de la transacción'>>",
"customer_email": "pepito_perez@example.com",
"acceptance_token": "eyJhbGciOiJIUzI1NiJ9.eyJjb250cmFjdF9pZCI6MSwicGVybWFsaW5rIjoiaHR0cHM6Ly93b21waS5jby93cC1jb250ZW50L3VwbG9hZHMvMjAxOS8wOS9URVJNSU5PUy1ZLUNPTkRJQ0lPTkVTLURFLVVTTy1VU1VBUklPUy1XT01QSS5wZGYiLCJmaWxlX2hhc2giOiIzZGNkMGM5OGU3NGFhYjk3OTdjZmY3ODExNzMxZjc3YiIsImppdCI6IjE1ODEwOTIzNjItMzk1NDkiLCJleHAiOjE1ODEwOTU5NjJ9.JwGfnfXsP9fbyOiQXFtQ_7T4r-tjvQrkFx0NyfIED5s",
"accept_personal_auth": "eyJhbGciOiJIUzI1NiJ9.eyJjb250cmFjdF9pZCI6NDQxLCJwZXJtYWxpbmsiOiJodHRwczovL3dvbXBpLmNvbS9hc3NldHMvZG93bmxvYWRibGUvYXV0b3JpemFjaW9uLWFkbWluaXN0cmFjaW9uLWRhdG9zLXBlcnNvbmFsZXMucGRmIiwiZmlsZV9oYXNoIjoiOTVkYzcwN2M0M2UxYmViMDAwMDUyZDNkNWJhZThhMDAiLCJqaXQiOiIxNzI5NTY0MTM2LTU2NjMwIiwiZW1haWwiOiIifQ.0f-hFte-mpCcnxlrPgEG-fLdGBWUoQaUhU71pPuij40"
}
Obtendremos una respuesta con una estructura como la siguiente indicándonos que fue creada exitosamente:
{
"data": {
"id": <<{ID_FUENTE_DE_PAGO} Id de la fuente de pago, 'Este es el campo que se usaría para realizar las transacciones'>>,
"public_data": {
"type": "BANCOLOMBIA_TRANSFER",
"payment_description": "Prueba",
"bank_account_type": "CUENTA AHORROS",
"bank_account_last_four": "***1234"
},
"token": "<<ID_DEL_TOKEN_CREADO>>",
"type": "BANCOLOMBIA_TRANSFER",
"status": "AVAILABLE",
"customer_email": "john@email.com"
},
"meta": {}
}
Nota: Si quieres ofrecer a tus clientes la posibilidad de cancelar una suscripción de su cuenta Bancolombia, debes realizar el consumo de la siguiente petición
PUT /v1/payment_sources/{{ID_FUENTE_DE_PAGO}}/void
Al consumir esta petición debemos asegurarnos que el estado que se nos retorne quede en VOID para la fuente de pago.
{
"data": {
"id": <<ID_FUENTE_DE_PAGO>>,
"public_data": {
"type": "BANCOLOMBIA_TRANSFER",
"payment_description": "Prueba",
"bank_account_type": "CUENTA AHORROS",
"bank_account_last_four": "***1234"
},
"token": "<<ID_DEL_TOKEN_CREADO>>",
"type": "BANCOLOMBIA_TRANSFER",
"status": "VOIDED",
"customer_email": "john@email.com"
},
"meta": {}
}
Paso 3: Crea una transacción
Al tener disponible un id de una fuente de pago, podrás usarlo para hacer cargos a tus usuarios sin necesidad de que ellos intervengan directamente en cada ocasión. Así podrás por ejemplo cobrar mensualmente una suscripción a un servicio, realizar cobros por servicios on-demand (como ventas a domicilio o servicios de transporte), cobrar por el uso de tu plataforma, etc.
Para esto, debes usar el mismo endpoint de transacciones que usan los pagos simples (POST a /v1/transactions), con la diferencia de que en esta ocasión enviarás información del método de pago (objeto payment_method) con el número de cuotas si la fuente de pago representa una tarjeta, de lo contrario este objeto no se tiene que enviar. En cualquier caso debes enviar un payment_source_id, por ejemplo:
{
"amount_in_cents": 4990000, // Monto current centavos
"currency": "COP", // Moneda
"signature": "37c8407747e595535433ef8f6a811d853cd943046624a0ec04662b17bbf33bf5", //Firma de integridad
"customer_email": "example@gmail.com", // Email del usuario
"payment_method": {
"installments": 2 // Número de cuotas si la fuente de pago representa una tarjeta de lo contrario el campo payment_method puede ser ignorado.
},
"reference": "sJK4489dDjkd390ds02", // Referencia única de pago
"payment_source_id": 3891 // ID de la fuente de pago
}
NOTA: Si tienes dudas de como generar el valor de la firma de integridad puedes revisar la siguiente documentación: ** Genera una firma de integridad**
Transacciones con COF
Cuando el medio de pago corresponde a una tarjeta de la franquicia MasterCard o VISA y el procesador de pagos es RBM, se puede hacer uso de Credential On File (COF) y así aumentar la taza de aprobación en las transacciones del comercio. Para esto, es necesario enviar recurrent, teniendo en cuenta que payment_source_id se convierte en un campo obligatorio.
recurrent debe ser un valor Booleano:
- true: Hace referencia a todas las transacciones en las que el titular autoriza que se almacenen los datos de su tarjeta y posteriormente se realicen cobros con el mismo monto de manera periódica. (Transacción de venta COF con recurrencia)
- false: Hace referencia a todas las transacciones en las que el titular autoriza que se almacenen los datos de su tarjeta y posteriormente se realicen cobros con diferentes montos sin ningún tipo de periodicidad. (Transacci ón de venta COF almacenada)
{
"amount_in_cents": 4990000, // Monto en centavos
"currency": "COP", // Moneda
"customer_email": "example@gmail.com", // Email del usuario
"payment_method": {
"installments": 2 // Número de cuotas si la fuente de pago representa una tarjeta de lo contrario el campo payment_method puede ser ignorado.
},
"reference": "sJK4489dDjkd390ds02", // Referencia única de pago
"payment_source_id": 3891, // ID de la fuente de pago (obligatorio)
"recurrent": true // Recurrente
}
- Sí no se envía
recurrent, la transacción se realizará sin COF. - Sí se envía
recurrenten transacciones con tarjetas de franquicia diferente a MasterCard o VISA, la transacción se realizará sin COF. - Sí se envía
recurrenty el procesador habilitado para el comercio es diferente a RBM, la transacción se realizará sin COF.
Widget en modo de tokenización
Puedes integrar nuestro Widget en modo tokenización para que puedas guardar la información de tus usuarios de forma más rápida y segura.
Con tan solo unas l íneas de HTML:
<form method="POST" action="/process_token">
<script
src="https://checkout.wompi.co/widget.js"
data-render="button"
data-widget-operation="tokenize"
data-public-key="pub_test_X0zDA9xoKdePzhd8a0x9HAez7HgGO2fH"
></script>
</form>
Con el token dentro de la respuesta debes hacer un POST a /v1/payment_sources desde tu servidor y usando tu llave privada de comercio. Recuerda nunca usar la llave privada en contextos inseguros como tu código HTML.