-
-
Notifications
You must be signed in to change notification settings - Fork 3
4 Operaciones Onepay
Tabla de Contenido
Onepay es un monstruo algo más difícil de domar, pero de simple funcionamiento. En pocas palabras, el cliente ingresará a tu sitio web o aplicación móvil para comprar, pero en vez de pagar a través de Webpay, usará la aplicación Onepay de su teléfono móvil para ello.
Como verás la implementación de Onepay varía dependiendo de dónde comienza el proceso de pago:
- Si es a través de un Sitio Web, tendrás que usar el SDK par Javascript de Onepay en tu sitio
- Si es a través de una App de iOS o Android, deberás usar el SDK para iOS o Android.
Para el primer punto, deberás usar el canal mobile
si es un sitio web móvil (que abre la App de Onepay), o desktop
(que muestra un código QR para ser usado en la App de Onepay)
Para el segundo, deberás indicar que el canal es app
, que permitirá a la App de Onepay pasar el control a tu aplicación de iOS o Android correctamente.
<?php
namespace App;
use DarkGhostHunter\TransbankApi\Transbank;
$transbank = Transbank::make('integration');
$transbank->setDefaults('onepay', [
'channel' => 'mobile',
'generateOttQrCode' => false,
'callbackUrl' => 'http://app.com/onepay/result',
'appScheme' => 'my-app://onepay/result',
]);
$onepay = Transbank::make('integration')->onepay();
Por supuesto, esto lo puedes sobrescribir cuando realices la transacción.
Por si te sientes perdido, así funciona el flujo de compra
Creando la transacción
El usuario realiza una compra en tu Sitio Web o App. El sitio se comunicará con tu Servidor y creará la transacción Onepay en los servidores de Transbank.
Transbank retornará el identificador de transacción (y otras cosas más) a tu Servidor, que a su vez la enviará a tu Sitio Web o App, el cual hará que el usuario abra la App de Onepay (código QR, modal con instrucciones, abrirla directamente, etc...).
[Web|App] --> Servidor --> Transbank --> Servidor --> [Web|App] --> Onepay App
Confirmando la transacción
Cuando el usuario termine de pagar, le pasará el identificador al Sitio Web o App, que lo remitirá al Servidor, que verificará el estado de pago en los servidores de Transbank.
Transbank devolverá el estado de pago a tu Servidor, que se lo enviará a tu Sitio Web o App.
Onepay App --> [Web|App] --> Servidor --> Transbank --> Servidor --> [Web|App]
Como puedes ver, cuando estás usando una App para iOS o Android, será tu propia App la encargada de comunicarse con tu Servidor para luego comunicarse con Transbank. Si usas tu App para comunicarte directamente con Transbank, abrirás paso a transacciones fraudulentas.
Como lo notaste, Onepay opera como una cesta (Carro de Compras) digital, que contendrá Items. Puedes usar cualquier método para persistir el Carro de Compras y los items entre peticiones; lo importante es que el Carro de Compras tenga Items para poder ser enviado a la plataforma Onepay.
Manejar Items te permitirá separar productos y servicios mucho mejor que usando Webpay.
Cada vez que modificas el Carro, se generarán automáticamente los datos necesarios para que sea procesado por Onepay, como el valor total de la compra.
Cuando vas a enviar el carro de compras a Onepay, se genera automáticamente un identificador único de 32 caracteres usando random_bytes()
, atributo que funciona como el buyOrder
de Webpay.
Esto debería ser suficiente para identificar la transacción de tu Carro, pero para algunas aplicaciones web quizás no sea lo más adecuado.
Si quieres reemplazar el identificador único por otro, como UUIDv4 o algún ID generado por tu propia aplicación, puedes añadirlo como parte de los atributos del carro, o suministrar tu propia lógica en forma de función anónima (Closure
) con acceso al propio Carro de Compras, usando generateEun()
.
<?php
use App\Database\Database;
// En este ejemplo, vamos a contar cuántas ventas hemos hecho en nuestro sistema,
// añadir el día, y añadir el número de Items. Es sólo un ejemplo.
$cart->generateEun(function($cart) {
/** @var \DarkGhostHunter\TransbankApi\Transactions\OnepayTransaction $cart */
return (Database::table('sales')->count() + 1) . '|' . date('Y-m-d') . '|' . $cart->countItemsQuantity();
});
// Esto nos dará como resultado `1000|2018-01-01|5`.
La lógica para generar el identificador único será ejecutado sólo cuando el Carro se envíe a Onepay, por lo que no verás este atributo al crear un carro si decides usar una función.
Onepay señala esto como
externalUniqueNumber
. Aunque no debe ser necesariamente un número, decidimos mantener el nombre de la variable así.
El Carro de compras es mágico. Cada vez que agregas, quitas o editas un Item, el total del carro cambiará automáticamente.
<?php
echo $cart->getTotal(); // 5000
$cart->deleteItem(5);
echo $cart->getTotal(); // 4000
$cart->updateItem(1, [
'amount' => -5500
]);
echo $cart->getTotal(); // -1500
El carro no dará error si llegas a un monto total negativo, pero sí lo hará cuando intentes enviarlo a Onepay. Esto te permitirá editar los Items del carro sin necesidad de esperar algún error.
¿Notate que usamos makeCart()
? Como con las transacciones en Webpay, también puedes usar createCart()
para crear el Carro de Compras con Items y despacharlo inmediatamente a Onepay.
<?php
$result = $onepay->createCart([
[
'description' => 'Producto de Prueba',
'quantity' => 1,
'amount' => 9990,
]
]);
Si estás haciendo un Carro con sólo un Item, no es necesario que ingreses un array dentro de otro array, con uno basta.
<?php
$cart = $onepay->makeCart([
'description' => 'Producto de Prueba',
'quantity' => 1,
'amount' => 9990,
]);
Igual podrás añadir, editar o eliminar items en el carro como cualquiera hecho con normalidad.
Puedes añadir items usando un array usando addItem()
. También, como puedes ver en el punto anterior, puedes crear el Carro con Items usando un array a la hora de crear el carro de compras.
<?php
use DarkGhostHunter\TransbankApi\Onepay\Item;
// Añadiremos otro Item
$cart->addItem([
'description' => 'Producto de Prueba 2',
'quantity' => 3,
'amount' => 4990,
'expire' => 0,
'additionalData' => 'sku-09120001'
]);
// Podemos crear un descuento
$cart->addItem([
'description' => 'Descuento de $1.000',
'quantity' => 1,
'amount' => -1000,
]);
// Y añadir varios items
$cart->addItems([
[
'description' => 'Producto de Prueba 3',
'quantity' => 1,
'amount' => 9000,
],
[
'description' => 'Producto de Prueba 4',
'quantity' => 3,
'amount' => 81000,
],
]);
Los Items son siempre agregados al final del array, incluso si existe un hueco anterior por un Item eliminado.
Puedes ver los Items que tiene el Carro usando el método items()
del Carro, que devolverá el array con cada Item.
<?php
$items = $cart->getItems();
Si necesitas un Item en concreto, podrás adquirirlo a través de su key
(índice) en el array. Ya que el Carro puede soportar más de un mismo Item con la misma descripción, el key
es la única forma de identificar individualmente cada Item.
<?php
$item = $cart->getItem(1);
Puedes buscar un Item por su descripción o valor. La búsqueda es exacta, y siempre se te devolverá un array con los Items encontrados. Si no se encontraron Item, recibirás null
.
<?php
$item = $cart->getItemByDescription('Producto de Prueba');
Te recomendamos que prepares tu propia lógica antes de ingresar los Items al Carrito para que no debas buscarlos por descripción.
Para eliminar un Item, ingresa el key
(índice) del array de Items. El método retornará el Item borrado, y false
si el Item no existe.
<?php
$deletedItem = $cart->deleteItem(1);
El Carro de Compras no dará error si llega a estar vacío, sin embargo sí lo hará cuando intentes enviarlo sin ningún Item.
Para editar un Item en particular, puedes simplemente indicar su key
(índice) en el array de Items, e indicar los nuevos atributos en un array. Estos atributos se mezclarán con los antiguos, y retornará el Item editado, pero si no existe, retornará false
.
<?php
$updatedItem = $cart->updateItem(1, [
'description' => 'Nuevo Producto Editado',
]);
Si especificas que la cantidad sea cero, el Item será eliminado.
Si quieres borrar un atributo para dejarlo con el valor por defecto, simplemente dale valor
null
.
Simplemente llama el método usando el key
del Item a reemplazar por completo.
<?php
$replacedItem = $cart->replaceItem(1, [
'description' => 'Producto Reemplazado',
'quantity' => 1,
'amount' => -1000,
]);
En vez de obtener todos los items y contarlos manualmente, o usar el key
del último Item, puedes simplemente llamar este método, que devolverá siempre el verdadero número de Items en el Carro de Compras.
<?php
$items = $cart->countItems();
Si quieres saber cuál es la cantidad total de Items, puedes usar countItemsQuantity()
. Por ejemplo, si tenemos 4 Items, pero cada uno con 2 de cantidad, obtendrás el resultado de 4 × 2, que es 8.
<?php
$quantity = $cart->countItemsQuantity(); // 8
⬅ 3 - Operaciones Webpay | 5 - Operaciones Patpass ➡
Para crear una transacción, instanciaremos el Carro de Compras con los datos de la transacción, y luego ingresaremos cada Item dentro de éste.
<?php
namespace App;
use DarkGhostHunter\TransbankApi\Transbank;
$onepay = Transbank::make('integration')->onepay();
// Crea el Carro
$cart = $onepay->makeCart([
'items' => [
'description' => 'Producto de Prueba',
'quantity' => 1,
'amount' => 9990,
]
]);
Como ves, los items
son un atributo del Carro de Compras. Esto permitirá que también puedas cambiar el canal del predefinido, u otros atributos de la Transacción como el appScheme
, callbackUrl
, generateOttQrCode
.
<?php
// Crea el Carro
$cart = $onepay->makeCart([
'items' => [
'description' => 'Producto de Prueba',
'quantity' => 1,
'amount' => 9990,
],
'channel' => 'web',
'appScheme' => 'my-app-v2://myappv2/onepay/result',
]);
$cart->callbackUrl = 'https://app.com/onepay/result';
$cart->generateOttQrCode = false;
El método makeCart()
acepta un sub-array de Items, aunque también puedes añadir cada Item manualmente usando addItem()
. Tienes plena libertad sobre cómo recuperar los items desde la información que envía tu sitio o app, pero lo importante es que cada Item tenga su descripción, cantidad y precio.
<?php
$cart = $onepay->makeCart([
'channel' => 'web',
'appScheme' => 'my-app-v2://myappv2/onepay/result',
'items' => [
[
'description' => 'Producto de Prueba',
'quantity' => 1,
'amount' => 9990,
],
[
'description' => 'Producto de Prueba 2',
'quantity' => 3,
'amount' => 4990,
],
]
]);
$cart->addItem([
'description' => 'Producto de Prueba 3',
'quantity' => 1,
'amount' => 14990,
]);
$cart->addItems([
[
'description' => 'Producto de Prueba 4',
'quantity' => 2,
'amount' => 11990,
],
[
'description' => 'Producto de Prueba 5',
'quantity' => 5,
'amount' => 19990,
]
]);
La expiración en días por defecto es de null
o 0
, que significa sin expiración, y los datos adicionales, que puedes usar por ejemplo para identificarlo en tu inventario, o comentar cómo debe ser entregado al cliente, vacío.
Una vez tengas listo tu Carrito de compras, puedes enviarlo a Onepay para que sea procesado. Onepay retornará una respuesta.
<?php
$result = $cart->getResult();
// Si el resultado es exitoso, enviaremos el resultado al sitio o la aplicación móvil
if ($result->isSuccess()) {
return $result->toJson();
}
// El resultado fue un fracaso, así que entregaremos el código y la descripción de error al sitio o aplicación móvil
return json_encode([
'error' => true,
'code' => $result->getErrorCode(),
'message' => $result->getErrorForHumans()
]);
Cuando serializes el resultado (en JSON o un array) para enviarlo como una respuesta, el SDK automáticamente ocultará el signature
de los atributos del carro.
<?php
$json = (string)$result;
echo strpos($json, 'signature'); // Nos dará falso, porque el "signature" no está en el json.
De todas maneras, siempre asegúrate que el signature no se vea en la respuesta de tu App.
El Transbank SDK se encarga automáticamente de verificar la firma
signature
. Si no se puede verificar, también recibirás un error.
Una vez el cliente realize el pago en Onepay, la App le devolverá el control a tu sitio web o tu aplicación móvil (el cual, a su vez, pasará los datos a tu sitio web).
<?php
namespace App;
use DarkGhostHunter\TransbankApi\Transbank;
$onepay = Transbank::make('integration')->onepay();
// Confirma la transacción
$result = $onepay->getResult([
'occ' => 1807983490979289,
'externalUniqueNumber' => 'f506a955-800c-4185-8818-4ef9fca97aae',
]);
// Si el resultado es exitoso, devolveremos el resultado a la app o sitio web como JSON
if ($result->isSuccess()) {
return $result->toJson();
}
// Pero si no fue exitoso, devolveremos el error
return json_encode([
'error' => true,
'code' => $result->getErrorCode(),
'message' => $result->getErrorForHumans(),
]);
Para anular una transacción que fue autorizada y confirmada, necesitas cuatro parámetros de la transacción a anular:
- El identificador único de Onepay
occ
, - el identificador único de tus sistemas
externalUniqueNumber
, - el código de autorización
authorizationCode
, - y el monto a anular que debe ser igual
total
.
<?php
namespace App;
use DarkGhostHunter\TransbankApi\Transbank;
$onepay = Transbank::environment()->onepay();
// Confirma la transacción
$result = $onepay->createNullify([
'occ' => 1807983490979289,
'amount' => 61950,
'authorizationCode' => 785873,
'externalUniqueNumber' => '81091abaf0b6bfcc5e2b341e2f3f1e9a',
]);
// Si el resultado es exitoso, devolveremos el resultado a la app o sitio web como JSON
if ($result->isSuccess()) {
return $result->toJson();
}
// Pero si no fue exitoso, devolveremos el error
return json_encode([
'error' => true,
'code' => $result->getErrorCode(),
'message' => $result->getErrorForHumans(),
]);