Pagos bajo demanda Webpay Oneclick

Guarda los datos de tarjeta de tus clientes con Webpay Oneclick para cobrar bajo la lógica que tu definas

Kushki permite guardar los datos de tarjeta de un cliente de manera segura utilizando Webpay Oneclick de Transbank. Tus clientes podrán comprar utilizando tarjetas de crédito, débito RedCompra, sin necesariamente un cobro inicial, para luego cobrar bajo la lógica que tu comercio define. Esto te permite, por ejemplo, sumar a un cliente ahora, configurar su forma de pago y cobrar en el futuro a medida que entregas tu servicio; o agilizar su proceso de compra futura en tu sitio, cobrando en el momento y permitiendo luego compras con 1 sólo click.

Podrás cobrar el monto que quieras, cuantas veces quieras, en base a la lógica que defina tu comercio.

Actualmente es la única forma de inscribir y suscribir tarjetas de débito en Chile.

¿Cómo funciona?

Un flujo de pago en Webpay Oneclick generalmente cuenta con los siguientes pasos:

Diagrama Flujo Usuario Webpay Oneclick

  1. El usuario inicia el proceso de inscripción de tarjeta en tu sitio o app.
  2. Se redirige al usuario al portal de Webpay para seleccionar el tipo de tarjeta, donde ingresa sus datos.
  3. Luego, pasa al portal del emisor de la tarjeta (el banco u otra entidad fincanciera) donde se autentica utilizando sus credenciales.
  4. Una vez resuelta la autenticación, se autoriza la inscripción y el usuario vuelve a tu sitio.
  5. Se despliega un mensaje de éxito o fracaso dependiendo del resultado del pago al usuario.

Básicamente, integrar pagos on demand consiste en 2 etapas: Inscripción y cobro

El flujo que integrarás es el siguiente:

Flujo Webpay oneclick (on-demand)

1. Inscripción

Lo primero que debes hacer para generar cobros on demand es inscribr la tarjeta de tu cliente. Para realizarlo, sigue los siguientes pasos:

Configura tu front-end

La responsabilidad del front-end es recoger la información de tarjeta del usuario de una manera segura, tokenizar esa información a través de los servidores de Kushki y luego enviar esa infromación al back-end para iniciar el proceso de inscripción de tarjeta para que luego puedas realizar cobros.

Tiens dos opciones para integrar: Cajita y Kushki.js.

Cajita

Usa Cajita para simplicar tu integración y proporcionar una solución lista para usar y recopilar información de tarjeta de forma segura.

Configura Cajita

Incluye el script de kushki-checkout.js en tu página de pago añadiéndolo al <head> de tu archivo HTML. Siempre carga kushki-checkout directamente desde cdn.kushkipagos.com para seguir cumpliendo con el estándar PCI. No incluyas el script en un bundle o paquete o hostees una copia de él.

<head>
<title>Checkout</title>
<script src="https://cdn.kushkipagos.com/kushki-checkout.js"> </script>
</head>
Añade Cajita a tu sitio web

Cajita necesita un lugar donde vivir en tu página. Ingresa el siguiente código en el <body> de tu sitio donde quieras que se despliegue el formulario de pago.

<form id="payment-form" action="/confirm" method="post">
<input type="hidden" name="cart_id" value="123">
</form>

Recuerda configurar la acción del formulario action de acuerdo al endpoind correspondiente en tu back-end.

Luego, añade el siguente tag script. Asegúrate que el formulario se haya cargado.

<script type="text/javascript">
var kushki = new KushkiCheckout({
is_subscription: true, // Variable que indica que se inscribirá la tarjeta
form: "payment-form",
merchant_id: "8291028192001", // Reemplaza esto por tu public merchant id
amount: "14.99",
currency: "USD",
payment_methods:["credit-card"], // Podrás habilitar más medios de pago.
inTestEnvironment: true, // Configurado en modo prueba
});
</script>

Esto creará un formlario pre-definido en tu página para inscribir una tarjeta de crédito.

Kushki.js

Usa Kushki.js si necesitas un mayor control sobre el “look & feel” o apariencia de tu formulario de tarjeta.

Configura Kushki.js
Opción 1 - CDN

Usa el siguiente tag script al final del <body> en tu página de pagos.

<script src="https://cdn.kushkipagos.com/kushki.min.js"></script>
Option 2 - NPM

Instala el paquete desde npm.

npm install --save @kushki/js

Luego impórtalo en tu código utilizando el siguiente código.

import { Kushki } from “@kushki/js”;
Configura el objeto Kushki

Añade el siguiente código a tu aplicación

const kushki = new Kushki({
merchantId: 'public-merchant-id', // Your public merchant id
inTestEnvironment: true,
});
Recoge la información del usuario y envíala a tu back-end

Primero, añade el formulario a tu página de pagos con los campos requeridos. Puedes diseñarlo de la forma que mejor te parezca.

Por ejemplo:

<form id="payment-form">
<input placeholder="Card Number" type="text" name="number">
<input placeholder="Full Name" type="text" name="name">
<input placeholder="MM" type="text" name="expiry_month">
<input placeholder="YY" type="text" name="expiry_uear">
<input placeholder="CVC" type="text" name="cvc">
<button id="submit">Pay $49.99</button>
</form>

Luego, cuando el usuario envia el formlario, solicita el token y envíalo a tu back-end.

kushki.requestSubscriptionToken({
amount: '49.99',
currency: "USD",
card: {
name: form.name,
number: form.number,
cvc: form.cvv,
expiryMonth: form.expiry_month,
expiryYear: form.expiry_year,
},
}, (response) => {
if(response.code){
console.log(response);
// Submit your code to your back-end
} else {
console.error('Error: ',response.error, 'Code: ', response.code, 'Message: ',response.message);
}
});

Configura tu back-end

La responsabilidad del back-end es recibir el token obtenido desde tu front-end e iniciar el proceso de inscripción de tarjeta con Kushki.

Cuando el usuario envía el formulario, tu front-end envía un token a un endpoint que hayas especificado. Con este token, deberás realizar una llamada a nuestro endpoint de suscripción para inscribir la tarjeta.

Es importante que definas la variable de periodicidad periodicity en "custom" ya que de otra manera cobrarás de manera recurrente a tu cliente. Para más información, vé nuestra guías de pagos recurrentes.

  • Javascript
  • Python
  • PHP
const request = require("request");
const options = {
method: 'POST',
url: 'https://api-uat.kushkipagos.com/subscriptions/v1/card',
headers: {'content-type': 'application/json'},
body: {
token: 'gV3ox6100000sAxClU033646vnnJsT83',
planName: 'Gold',
periodicity: 'custom',
contactDetails: {
firstName: 'Testy',
lastName: 'McTesterson',
},
amount: {
subtotalIva: 0,
subtotalIva0: 14.99,
ice: 0,
iva: 0.14,
currency: 'USD'
},
startDate: '2021-01-01',
},
json: true
};
request(options, (error, response, body) => {
if (error) throw new Error(error);
console.log(body);
});
import http.client
conn = http.client.HTTPSConnection("api-uat.kushkipagos.com")
payload = "{\"token\":\"gV3ox6100000sAxClU033646vnnJsT83\",\"planName\":\"Premium\",\"periodicity\":\"custom\",\"contactDetails\":{\"firstName\":\"Juan\",\"lastName\":\"García\",\"email\":\"[email protected]\"},\"amount\":{\"subtotalIva\":1,\"subtotalIva0\":0,\"ice\":0,\"iva\":0.14,\"currency\":\"USD\"},\"startDate\":\"2018-09-25\",\"metadata\":{\"plan\":{\"fitness\":{\"cardio\":\"include\",\"rumba\":\"include\",\"pool\":\"include\"}}}}"
headers = { 'content-type': "application/json" }
conn.request("POST", "/subscriptions/v1/card", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
# Tu lógica acá ...
$client = new http\Client;
$request = new http\Client\Request;
$body = new http\Message\Body;
$body->append('{"token":"gV3ox6100000sAxClU033646vnnJsT83","planName":"Premium","periodicity":"custom","contactDetails":{"firstName":"Juan","lastName":"García","email":"[email protected]"},"amount":{"subtotalIva":1,"subtotalIva0":0,"ice":0,"iva":0.14,"currency":"USD"},"startDate":"2018-09-25","metadata":{"plan":{"fitness":{"cardio":"include","rumba":"include","pool":"include"}}}}');
$request->setRequestUrl('https://api-uat.kushkipagos.com/subscriptions/v1/card');
$request->setRequestMethod('POST');
$request->setBody($body);
$request->setHeaders(array(
'content-type' => 'application/json'
));
$client->enqueue($request)->send();
$response = $client->getResponse();
echo $response->getBody();
// Tu lógica acá ...

De acuerdo a tu respuesta, redirecciona al usuario a una página de éxito o fracaso para informar al cliente si la inscripción fue aprobada o declinada.

2. Cobro

Una vez que ya tengas inscrita la tarjeta de tu cliente, para realizar un cobro basta llamar a nuestro endpoint de cobros junto con el subscriptionId a medida que entregues tu servicio a tu cliente bajo la lógica que definas.

  • Javascript
  • Python
  • PHP
const request = require("request");
const options = {
method: 'POST',
url: 'https://api-uat.kushkipagos.com/subscriptions/v1/card/291929129192912', // Reemplázalo con tu id de suscripción
headers: {'content-type': 'application/json'},
body: {
amount: {
subtotalIva: 14.99,
subtotalIva0: 0,
ice: 0,
iva: 0,
currency: 'USD'
},
metadata: {customerId: '123'},
contactDetails: {
documentType: 'CC',
documentNumber: '1009283738',
firstName: 'Don',
lastName: 'Draper',
phoneNumber: '0988734644'
},
orderDetails: {
billingDetails: {
name: 'Don Draper',
phone: '0988734644',
address: 'Madison Avenue',
city: 'New York',
region: 'New York',
country: 'USA',
zipCode: '99999'
}
},
fullResponse: true
},
json: true
};
request(options, (error, response, body) => {
if (error) throw new Error(error);
console.log(body);
});
import http.client
conn = http.client.HTTPSConnection("api-uat.kushkipagos.com")
payload = "{\"language\":\"es\",\"amount\":{\"subtotalIva\":15.16,\"subtotalIva0\":0,\"ice\":0,\"iva\":1.82,\"currency\":\"USD\"},\"metadata\":{\"customerId\":\"123\"},\"contactDetails\":{\"documentType\":\"CC\",\"documentNumber\":\"1009283738\",\"email\":\"[email protected]\",\"firstName\":\"Diego\",\"lastName\":\"Cadena\",\"phoneNumber\":\"0988734644\"},\"orderDetails\":{\"siteDomain\":\"tuebook.com\",\"shippingDetails\":{\"name\":\"Diego Cadena\",\"phone\":\"0988734644\",\"address\":\"Eloy Alfaro 139 y Catalina Aldaz\",\"city\":\"Quito\",\"region\":\"Pichincha\",\"country\":\"Ecuador\",\"zipCode\":\"170402\"},\"billingDetails\":{\"name\":\"Diego Cadena\",\"phone\":\"0988734644\",\"address\":\"Eloy Alfaro 139 y Catalina Aldaz\",\"city\":\"Quito\",\"region\":\"Pichincha\",\"country\":\"Ecuador\",\"zipCode\":\"170402\"}},\"productDetails\":{\"product\":[{\"id\":\"198952AB\",\"title\":\"eBook Digital Services\",\"price\":6990000,\"sku\":\"10101042\",\"quantity\":1},{\"id\":\"198953AB\",\"title\":\"eBook Virtual Selling\",\"price\":9990000,\"sku\":\"004834GQ\",\"quantity\":1}]},\"fullResponse\":true}"
headers = { 'content-type': "application/json" }
conn.request("POST", "/subscriptions/v1/card/291929129192912", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
# Tu lógica acá ...
$client = new http\Client;
$request = new http\Client\Request;
$body = new http\Message\Body;
$body->append('{"language":"es","amount":{"subtotalIva":15.16,"subtotalIva0":0,"ice":0,"iva":1.82,"currency":"USD"},"metadata":{"customerId":"123"},"contactDetails":{"documentType":"CC","documentNumber":"1009283738","email":"[email protected]","firstName":"Diego","lastName":"Cadena","phoneNumber":"0988734644"},"orderDetails":{"siteDomain":"tuebook.com","shippingDetails":{"name":"Diego Cadena","phone":"0988734644","address":"Eloy Alfaro 139 y Catalina Aldaz","city":"Quito","region":"Pichincha","country":"Ecuador","zipCode":"170402"},"billingDetails":{"name":"Diego Cadena","phone":"0988734644","address":"Eloy Alfaro 139 y Catalina Aldaz","city":"Quito","region":"Pichincha","country":"Ecuador","zipCode":"170402"}},"productDetails":{"product":[{"id":"198952AB","title":"eBook Digital Services","price":6990000,"sku":"10101042","quantity":1},{"id":"198953AB","title":"eBook Virtual Selling","price":9990000,"sku":"004834GQ","quantity":1}]},"fullResponse":true}');
$request->setRequestUrl('https://api-uat.kushkipagos.com/subscriptions/v1/card/291929129192912');
$request->setRequestMethod('POST');
$request->setBody($body);
$request->setHeaders(array(
'content-type' => 'application/json'
));
$client->enqueue($request)->send();
$response = $client->getResponse();
echo $response->getBody();
// Tu lógica acá ...

Cancela una inscripción (Opcional)

Si tu cliente decde cancelar el servicio o una vez que dejes de darlo, para cancelar la suscripción de la tarjeta, simplemente debes llamar a nuestro endpoint de cancelación de suscripción desde tu backend.

  • Javascript
  • Python
  • PHP
const request = require("request");
request({
method: 'DELETE',
url: 'https://api-uat.kushkipagos.com/subscriptions/v1/card/213123123123',
headers: {'content-type': 'application/json'}
}, (error, response, body) => {
if (error) throw new Error(error);
console.log(body);
// Tu lógica acá ...
});
import http.client
conn = http.client.HTTPSConnection("api-uat.kushkipagos.com")
headers = { 'content-type': "application/json" }
conn.request("DELETE", "/subscriptions/v1/card/213123123123", headers=headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
# Tu lógica acá ...
$client = new http\Client;
$request = new http\Client\Request;
$request->setRequestUrl('https://api-uat.kushkipagos.com/subscriptions/v1/card/213123123123');
$request->setRequestMethod('DELETE');
$request->setHeaders(array(
'content-type' => 'application/json'
));
$client->enqueue($request)->send();
$response = $client->getResponse();
echo $response->getBody();
// Tu lógica acá ...

3. Prueba tu integración

Existen tarjetas de prueba que puedes utilizar en modo prueba para asegurarte que tu integraci ón esta lista. Úsalas con cualquier CVC, código postal y una fecha de expiración en el futuro.

  • Transacción aprobada: 5451951574925480
  • Transacción declinada en solicitud de token (front-end): 4574441215190335
  • Transacción declinada en solicitud de cobro (back-end): 4349003000047015

4. Prepara tu certificación

Toma en consideración las siguientes pautas para aprobar la certificación técnica (requerida para obtener credenciales productivas):

  • Mensajes en pantalla de acuerdo a las respuestas de Kushki.
  • Guardar y registrar todas las respuestas de Kushki (requeridas en caso de necesitar soporte).

Si estas utilizando Kushki.js, considera también lo siguiente:

  • El botón de pago se deshabilita luego de hacer el primer click.

Acepta webhooks

Maneja eventos post-pago de la manera correcta.