Reserva fondos en una tarjeta

Separa la autorización y captura para crear un cobro ahora, pero capturar sus fondos luego.

Web
Android
iOS

Reservar fondos en una tarjeta de un solo uso permite autorizar la disponibilidad de fondos para una tarjeta, pero retrasar la captura de fondos para cuando se complete el servicio. Por ejemplo, un hotel puede autorizar un pago previo a la llegada del pasajero y luego capturar los fondos cuando se vaya y se complete el servicio. También permite cambiar el monto de la autorización original en caso de que el pedido cambie debido al envío, impuestos o propina.

Cuando un pago es autorizado, el banco garantiza la disponiblidad del monto y lo retendrá en la tarjeta del cliente por 7 días. Si el pago no es capturado ni cancelado en ese tiempo, será capturado automáticamente.

Un ejemplo de lo que integrarás es el siguiente:

¿Cómo funciona?

Puedes reservar fondos de una tarjeta de un solo uso. Para lograrlo, deberás:

  1. Obtener token de pago único.
  2. Iniciar una autorización con Kushki.
  3. Kushki intentará realizar la autorización con la entidad emisora de la tarjeta.
  4. Si la respuesta es positiva, el comercio podrá elegir entre 2 opciones a ejecutar antes de que el plazo de autorización expire:
  • Capturar un monto: En el caso de que se desee hacer efectivo un cobro en la tarjeta del cliente.
  • Cancelar la autorización: En el caso de que se desee cancelar la autorización y liberar los fondos de la tarjeta.

El flujo que integrarás será el siguiente:

Flujo auth y captura

1. Obtener token de pago único

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 información al back-end para iniciar el proceso de preautorización.

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

Cajita

Kushki cuenta con formularios de pago listos para recopilar información de tarjeta de forma segura. Podrás usar cualquiera de nuestras versiones:

  • Cajita: la primera versión del formulario de pagos. No es personalizable.
  • Kajita: la segunda versión. Te permite personalizar tus formularios de pago desde tu Consola de administración e incluso tener varias versiones de Kajita, por ejemplo, una por cada método de pago.

Crea y personaliza tus Kajitas

Con Kushki puedes crear tus Kajitas desde la Consola de administración. Haz clic aquí para aprender cómo hacerlo.

Configura Kajita

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. No incluyas el script en un bundle o paquete ni hostees una copia de él.

<head>
<title>Checkout</title>
<script src="https://cdn.kushkipagos.com/kushki-checkout.js"> </script>
</head>

Añade Kajita a tu sitio

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

Para Kajita (v.2):

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

Para Cajita (v.1)

<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 endpoint correspondiente en tu back-end, para obtener el token.

Luego, agrega el tag script.

Para la Kajita (v.2) Podrás obtener dicho script desde tu Consola de administración según lo explicado aquí.

<script type="text/javascript">
var kushki = new KushkiCheckout({
kformId: "HmJXukKb5",
form: "my-form",
publicMerchantId: "${publicCfredentialId}",// Reemplaza esto por tucredencial pública
amount: {
subtotalIva: 0,
iva: 0,
subtotalIva0: 1000,
}
});
</script>

Para la v.1 (Cajita), añade el siguiente script, asegurándote que el formulario se haya cargado:

<script type="text/javascript">
var kushki = new KushkiCheckout({
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 formulario predefinido en tu página para aceptar pagos.

Kushki.js

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

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 formulario, solicita el token y envíalo a tu back-end.

kushki.requestToken({
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);
}
});

2. Autorización

La responsabilidad del back-end es a usar el token recolectado para realizar una petición de autorización para luego, en caso de que esta sea aprobada, poder hacer una de captura o anulación dependiendo del caso.

Cuando el usuario envia el formulario, tu front-end envia un token a un endpoint que hayas especificado. Con este token, deberás realizar una llamada a nuestro endpoint de autorización para iniciar el cobro.

  • Python
  • Javascript
  • PHP
import http.client
conn = http.client.HTTPSConnection("api-uat.kushkipagos.com")
payload = "{\"token\":\"QZPnSP1000000b3MG3062555GhIrcYt5\",\"amount\":{\"subtotalIva\":0,\"subtotalIva0\":600,\"ice\":0,\"iva\":0,\"currency\":\"USD\"},\"fullResponse\":true}"
headers = { 'content-type': "application/json" }
conn.request("POST", "/card/v1/preAuthorization", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
import request from 'request';
const options = {
method: 'POST',
url: 'https://api-uat.kushkipagos.com/card/v1/preAuthorization',
headers: {'content-type': 'application/json'},
body: {
token: 'QZPnSP1000000b3MG3062555GhIrcYt5', // Reemplázalo por el token obtenido
amount: {subtotalIva: 0, subtotalIva0: 600, ice: 0, iva: 0, currency: 'USD'},
fullResponse: true
},
json: true
};
request(options, (error, response, body) => {
if (error) throw new Error(error);
console.log(body);
});
<?php
$client = new http\Client;
$request = new http\Client\Request;
$body = new http\Message\Body;
$body->append('{"token":"QZPnSP1000000b3MG3062555GhIrcYt5","amount":{"subtotalIva":0,"subtotalIva0":600,"ice":0,"iva":0,"currency":"USD"},"fullResponse":true}');
$request->setRequestUrl('https://api-uat.kushkipagos.com/card/v1/preAuthorization');
$request->setRequestMethod('POST');
$request->setBody($body);
$request->setHeaders(array(
'content-type' => 'application/json'
));
$client->enqueue($request)->send();
$response = $client->getResponse();
echo $response->getBody();

3. Kushki verifica autorización

Kushki validará la disponibilidad de fondos con la entidad emisora de la tarjeta. Una vez obtenida la respuesta de Kushki, guarda el ticketNumber ya que será este el identificador para realizar luego la captura, así como también la anulación.

4.1. Captura (opcional)

Captura el monto que definas de acuerdo al autorizado llamando a nuestro endpoint de capturas, utilizando el ticketNumber obtenido en la autorización.

  • Python
  • Javascript
  • PHP
import http.client
conn = http.client.HTTPSConnection("api-uat.kushkipagos.com")
payload = "{\"ticketNumber\":\"319228478889680318\",\"amount\":{\"currency\":\"PEN\",\"subtotalIva\":0,\"iva\":0,\"subtotalIva0\":600,\"ice\":0},\"fullResponse\":true}"
headers = { 'content-type': "application/json" }
conn.request("POST", "/card/v1/capture", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
var request = require("request");
var options = {
method: 'POST',
url: 'https://api-uat.kushkipagos.com/card/v1/capture',
headers: {'content-type': 'application/json'},
body: {
ticketNumber: '319228478889680318',
amount: {currency: 'PEN', subtotalIva: 0, iva: 0, subtotalIva0: 600, ice: 0},
fullResponse: true
},
json: true
};
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(body);
});
<?php
$client = new http\Client;
$request = new http\Client\Request;
$body = new http\Message\Body;
$body->append('{"ticketNumber":"319228478889680318","amount":{"currency":"PEN","subtotalIva":0,"iva":0,"subtotalIva0":600,"ice":0},"fullResponse":true}');
$request->setRequestUrl('https://api-uat.kushkipagos.com/card/v1/capture');
$request->setRequestMethod('POST');
$request->setBody($body);
$request->setHeaders(array(
'content-type' => 'application/json'
));
$client->enqueue($request)->send();
$response = $client->getResponse();
echo $response->getBody();

4.2 Anular autorización (Opcional)

Si necesitas anular una autorización puedes hacerlo llamando a nuestro enpoint de anulación de cobros, utilizando el ticketNumber obtenido en la autorización.

  • Python
  • Javascript
  • PHP
import http.client
conn = http.client.HTTPSConnection("api-uat.kushkipagos.com")
payload = "{\"fullResponse\":true,\"amount\":{\"subtotalIva\":10000,\"subtotalIva0\":0,\"ice\":0,\"iva\":0,\"currency\":\"COP\"}}"
headers = { 'content-type': "application/json" }
conn.request("DELETE", "/v1/charges/1528188291221", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
var request = require("request");
var options = {
method: 'DELETE',
url: 'https://api-uat.kushkipagos.com/v1/charges/1528188291221',
headers: {'content-type': 'application/json'},
body: {
fullResponse: true,
amount: {subtotalIva: 10000, subtotalIva0: 0, ice: 0, iva: 0, currency: 'COP'}
},
json: true
};
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(body);
});
<?php
$client = new http\Client;
$request = new http\Client\Request;
$body = new http\Message\Body;
$body->append('{"fullResponse":true,"amount":{"subtotalIva":10000,"subtotalIva0":0,"ice":0,"iva":0,"currency":"COP"}}');
$request->setRequestUrl('https://api-uat.kushkipagos.com/v1/charges/1528188291221');
$request->setRequestMethod('DELETE');
$request->setBody($body);
$request->setHeaders(array(
'content-type' => 'application/json'
));
$client->enqueue($request)->send();
$response = $client->getResponse();
echo $response->getBody();

Prueba tu integración

Existen tarjetas de prueba que puedes utilizar en modo prueba para asegurarte que tu integracó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 autorización: 4349003000047015
  • Transacción declinada en captura: 4547004841271012