API Referencia
undefined

Onepay

Conceptos y SDKs

Onepay puede ser usado en diversos canales y en múltiples modalidades de pago. Por ende es importante entender esos canales y modalidades a la hora de realizar una integración.

En cuanto a modalidades, Onepay puede usarse para ventas por internet y también para ventas presenciales. Veamos primero los conceptos necesarios para entender el pago por internet, lo que te permitirá también entender la forma de ocuparlo para modalidades presenciales (como el caso de un cortafila).

En las ventas por internet el flujo de Onepay varía ligeramente según el canal mediante el cual se enlaza la transacción con la app Onepay en el teléfono del usuario. Los canales son:

  • WEB: Web desktop. En este caso aparece un QR en la pantalla del comercio que le permite al usuario escanearlo con la app Onepay y confirmar la transacción. El comercio es notificado cuando el usuario ha completado la transacción.

  • MOBILE: Web móvil. Aquí el navegador móvil abre la app Onepay, donde el usuario confirma directamente la transacción. Luego la app Onepay abre una nueva pestaña del navegador del sistema para notificar al comercio que se ha completado la transacción.

  • APP: Integración app-to-app. Aquí el comercio cuenta con una app móvil que abre la app Onepay cuando el usuario desea pagar usando este medio de pago. Una vez se completa la transacción, la app Onepay invoca nuevamente la app del comercio.

Para los dos primeros canales (WEB y MOBILE) se ofrece un SDK Javascript con dos modalidades de integración:

  • Checkout: Integración recomendada que maneja toda la comunicación con Onepay e informa al usuario de los pasos a seguir a través de un diálogo "modal". En esta modalidad el comercio indica dos urls que conectan el frontend del comercio con el backend. La primera url es la encargada de crear la transacción. La segunda url es la que toma el control después de que el usuario completa el flujo en la app. Checkout se encarga de hacer invisibles las diferencias entre el canal WEB y MOBILE.

  • QR Directo: La versión "hágalo usted mismo" para usuarios avanzados. Provee más flexibilidad pero es más compleja y requiere más trabajo la integración. Se le entregan al comercio las herramientas para dibujar el código QR y para "escuchar" los eventos que van ocurriendo en la app del usuario. También se incluye una forma de abrir la app de Onepay en caso de canal MOBILE, pero toda la lógica debe ser manejada por el comercio.

Para el canal APP se ofrecen SDKs iOS y Android

Finalmente, para las labores del backend, se ofrecen SDKs para Java, .NET, PHP, Ruby y Python. Estos SDKs se utilizan en todos los casos, independiente del canal y de la modalidad de integración web.

En la venta presencial se utilizan las mismas herramientas pero de diferente forma, pues ahora el dispositivo que genera la transacción (ej: totem de auto atención o un tablet operado como cortafila) no es propiedad del tarjetahabiente. En este caso se usa el canal MOBILE, pues será una pestaña del navegador móvil en el teléfono del cliente donde se notificará al comercio el resultado de la transacción.

A continuación veremos el paso a paso para algunas integraciones tanto para venta por internet como presencial.

Integración Web (Checkout)

1. Front-end: Configuración

Para realizar la integración checkout debes utilizar nuestro SDK Javascript siguiendo las instrucciones de instalación.

Luego en tu frontend debes invocar a Onepay.checkout de la siguiente forma:

Onepay.checkout({
  endpoint: './transaction-create',
  commerceLogo: 'https://tu-url.com/images/icons/logo-01.png',
  callbackUrl: './onepay-result',
  transactionDescription: 'Set de pelotas',
  onclose: function (status) {
      console.log('el estado recibido es: ', status);
  }
});

Esto abrirá un modal que se encargará de toda la interacción con el usuario.

A continuación una descripción de los parámetros recibidos por esta función:

  • endpoint : corresponde a la URL de tu backend que tiene la lógica de crear la transacción usando alguno de nuestros SDK disponibles o invocando directamente al API de Onepay.

El SDK enviara el parámetro channel a tu endpoint, cuyo valor podría ser "WEB" o "MOBILE". Debes asegurarte de capturar este parámetro para poder enviar el channel adecuado al API de Onepay.

Se espera que el endpoint retorne un JSON como el del siguiente ejemplo:

{
 "externalUniqueNumber":"38bab443-c55b-4d4e-86fa-8b9f4a2d2d13",
 "amount":88000,
 "qrCodeAsBase64":"QRBASE64STRING",
 "issuedAt":1534216134,
 "occ":"1808534370011282",
 "ott":89435749
}

En el paso 2 más abajo podrás ver más información sobre este endpoint.

  • commerceLogo: (Opcional) Corresponde a la URL full del logo de comercio que se mostrará en el modal. Como el modal reside en un dominio externo, no puede ser una URL relativa (a diferencia de los otros parámetros). El logo se redimensionará a 125 pixeles de ancho y la altura se calcula automáticamente para mantener las proporciones de la imagen.

  • callbackUrl : URL que se invocará desde el SDK una vez que la transacción ha sido autorizada por el comercio. En este callback el comercio debe hacer la confirmación de la transacción, para lo cual dispone de 30 segundos desde que la transacción se autorizó, de lo contrario esta sera automáticamente reversada.

En el paso 3 más abajo podrás ver más sobre cómo se invoca este callback.

  • transactionDescription : (Opcional) Texto que representa la descripción general de la compra, se dibujará en el modal sobre el valor del precio.

  • onclose : (Opcional) Función de callback que será invocada cuando el usuario cierre el modal ya sea porque se arrepintió de realizar el pago o porque hubo un error en este último y el usuario presionó el botón "Entendido". Esto puede ser útil para el flujo de tu comercio en caso que necesites de alguna forma poder saber y tomar control de la acción del usuario al cerrar el modal. Los valores que puede tener el parámetro status son CANCELED en caso que usuario cierre al presionar el link No pagar, volver a la pagina del comercio, o ERROR en caso que el usuario presione el botón Entendido si un error ocurre en el proceso de pago.

2. Back-end: Crear una Transacción

Como puedes imaginar, para completar la integración necesitarás programar el código que maneja las llamadas en las URLs indicadas por endpoint y callbackUrl.

Primero que nada, deberás configurar también el callbackUrl en el backend. La razón detrás de esto es que si el canal es MOBILE no es el componente javascript quien invocará el callback, sino que la propia app Onepay que reside en el teléfono del usuario. La configuración del callback en el backend le permite a la app Onepay saber donde redireccionar en ese caso:

import cl.transbank.onepay.Onepay;


// URL de retorno para canal MOBILE (web móvil). También será usada en canal WEB
// si integras la modalidad checkout del SDK javascript.
Onepay.setCallbackUrl("https://www.misitioweb.com/onepay-result");
use Transbank\Onepay\OnepayBase;

OnepayBase::setCallbackUrl('https://www.misitioweb.com/onepay-result');
using Transbank.Onepay;

Onepay.CallbackUrl = "https://www.misitioweb.com/onepay-result";
require 'transbank/sdk'

Transbank::Onepay::Base.callback_url = "https://miapp.cl/endPayment"
from transbank import onepay
onepay.callback_url = "https://www.misitioweb.com/onepay-result"

Con eso estás preparado para crear una transacción en el código backend que será invocado por la url del endpoint.

Para esto se debe crear en primera instancia un objeto ShoppingCart que se debe llenar un Item (o varios):

import cl.transbank.onepay.model.*;

//...

ShoppingCart cart = new ShoppingCart();
cart.add(
    new Item()
        .setDescription("Zapatos")
        .setQuantity(1)
        .setAmount(15000)
        .setAdditionalData(null)
        .setExpire(-1));
use Transbank\Onepay\ShoppingCart;
use Transbank\Onepay\Item;
use Transbank\Onepay\Transaction;

$cart = new ShoppingCart();
$cart->add(new Item('Zapatos', 1, 15000));
using Transbank.Onepay:
using Transbank.Onepay.Model:

//...

ShoppingCart cart = new ShoppingCart();
cart.Add(new Item(
    description: "Zapatos",
    quantity: 1,
    amount: 15000,
    additionalData: null,
    expire: -1));
require 'transbank/sdk'

cart = Transbank::Onepay::ShoppingCart.new
cart.add(Transbank::Onepay::Item.new(amount: 15000,
                  quantity: 1,
                  description: "Zapatos",
                  additional_data: nil,
                  expire: -1))
from transbank.onepay.cart import ShoppingCart, Item

cart = ShoppingCart()
cart.add(Item(description="Zapatos",
              quantity=1, amount=15000,
              additional_data=None, expire=None))

Luego que el carro de compras contiene todos los ítems, se crea la transacción:

import cl.transbank.onepay.model.*;

// ...

Onepay.Channel channel = Onepay.Channel.valueOf(request.getParameter("channel"));
TransactionCreateResponse response = Transaction.create(cart, channel);
/*
 * IMPORTANTE: El ejemplo está pensado en la forma más simple de integrar que
 * es apuntando a integración. El SDK asume que usarás integración si no has
 * seteado el ambiente, razón por la cual no es necesario que lo configures.
 * Sin embargo, debes tener presente que al momento de apuntar a producción
 * deberás configurar el ambiente así como tu API_KEY y SHARED_SECRET antes
 * de realizar la llamada a Transaction::create, ya que de lo contrario estarás
 * apuntando a INTEGRACION
 *
 * ejemplo:
 * use Transbank\Onepay\OnepayBase;
 * OnepayBase::setCurrentIntegrationType('LIVE');
 * OnepayBase::setApiKey('api-key-entregado-por-transbank');
 * OnepayBase::setSharedSecret('secreto-entregado-por-transbank');
 */

$channel = $request->input("channel");
$response = Transaction::create($cart, $channel);
using Transbank.Onepay;
using Transbank.Onepay.Model:

// ...
ChannelType channelType = ChannelType.Parse(channel);
var response = Transaction.Create(cart, channelType);
require 'transbank/sdk'

channel = params["channel"]
response = Transbank::Onepay::Transaction.create(shopping_cart: cart,
                                                 channel: channel)
from transbank.onepay.transaction import Transaction, Channel

channel = Channel(request.form.get("channel"))
response = Transaction.create(cart, channel)

El segundo parámetro en el ejemplo corresponde al channel y debes capturar el valor que el frontend envió cuando invoco al endpoint que está creando la transacción para fijar el valor correcto ("WEB" si se trata de web desktop, "MOBILE" si se trata de web móvil).

El resultado entregado contiene la confirmación de la creación de la transacción, en la forma de un objeto TransactionCreateResponse.

"occ": "1807983490979289",
"ott": 64181789,
"signature": "USrtuoyAU3l5qeG3Gm2fnxKRs++jQaf1wc8lwA6EZ2o=",
"externalUniqueNumber": "f506a955-800c-4185-8818-4ef9fca97aae",
"issuedAt": 1532103896,
"qrCodeAsBase64": "QRBASE64STRING"

El externalUniqueNumber corresponde a un UUID generado por SDK que identifica la transacción en el lado del comercio. Opcionalmente, puedes especificar tus propios external unique numbers.

En el caso que no se pueda completar la transacción o responseCode en la respuesta del API sea distinto de ok se lanzará una excepción.

Con eso ya tienes la información suficiente para responder el JSON que espera la modalidad checkout de parte de la url configurada como endpoint. Sólo debes eliminar signature y agregar amount desde el ShoppingCart que construiste anteriormente. Con eso retornas algo como esto:

{
"occ": "1807983490979289",
"ott": 64181789,
"externalUniqueNumber": "f506a955-800c-4185-8818-4ef9fca97aae",
"issuedAt": 1532103896,
"qrCodeAsBase64": "QRBASE64STRING",
"amount":88000
}

Y en este punto el SDK frontend toma el control de la coordinación. Si el canal es WEB se le mostrará un "modal" al usuario donde podrá escanear el código QR y también recibirá las instrucciones de cada paso a realizar para autorizar el pago. Si el canal es MOBILE el SDK javascript automáticamente abrirá la app Onepay en el mismo teléfono del usuario.

Existe un Simulador de transacciones que puedes utilizar para generar transacciones exitosas o fallidas.

3. Back-end: Confirmar la Transacción

Eventualmente la transacción llegará a término y el control retornará al backend mediante el método GET en la url indicada en el callbackUrl en el paso 1 (frontend) y 2 (backend). Es muy importante que pongas la misma URL en ambos pasos. De esta forma sólo tienes que escribir un único código que maneje la confirmación de la transacción independiente si el canal es WEB o MOBILE.

Para el canal WEB (desktop) en la integración checkout el resultado de éxito o fracaso le aparecerá comunicado al usuario dentro del diálogo modal, para luego redirigir al usuario al callback especificado en el paso 1. Para el canal MOBILE la app de Onepay abrirá una nueva pestaña en el navegador móvil del usuario y en esa pestaña se invocará la url de callback especificado en el paso 2.

En este callback el comercio debe hacer la confirmación de la transacción, para lo cual dispone de 30 segundos desde que la transacción se autorizó. De lo contrario esta sera automáticamente reversada.

El callback será invocado vía GET e irán los parámetros occ y externalUniqueNumber con los cuales podrás invocar la confirmación de la transacción desde tu backend. Adicionalmente se envía el parámetro status, que puede tomar los siguientes valores:

  • PRE_AUTHORIZED: El estado de éxito. Debes confirmar la transacción para completar el flujo.
  • CANCELLED_BY_USER: El tarjetahabiente decidió abortar la autorización.
  • REJECTED: La transacción fue rechazada.
  • REVERSED: No se pudo confirmar el pago.
  • REVERSE_NOT_COMPLETED: Se intentó reversar (ver estado anterior) pero falló por alguna razón interna.

Si se recibe cualquier otro valor, el comercio debe asumir que ocurrió un error.

Finalmente, se debe confirmar la transacción:

import cl.transbank.onepay.model.*;

String status = request.getParameter("status");
String externalUniqueNumber = request.getParameter("externalUniqueNumber");
String occ = request.getParameter("occ");

if (null != status && status.equalsIgnoreCase("PRE_AUTHORIZED")) {
    try {
        TransactionCommitResponse response =
            Transaction.commit(occ, externalUniqueNumber);
        // Procesar response
    } catch (TransbankException e) {
        // Error al confirmar la transaccion
    }
} else {
    // Mostrar página de error
}
/*
 * IMPORTANTE: El ejemplo está pensado en la forma más simple de integrar que
 * es apuntando a integración. El SDK asume que usarás integración si no has
 * seteado el ambiente, razón por la cual no es necesario que lo configures.
 * Sin embargo, debes tener presente que al momento de apuntar a producción
 * deberás configurar el ambiente así como tu API_KEY y SHARED_SECRET antes
 * de realizar la llamada a Transaction::commit, ya que de lo contrario estarás
 * apuntando a INTEGRACION
 *
 * ejemplo:
 * use Transbank\Onepay\OnepayBase;
 * OnepayBase::setCurrentIntegrationType('LIVE');
 * OnepayBase::setApiKey("api-key-entregado-por-transbank");
 * OnepayBase::setSharedSecret("secreto-entregado-por-transbank");
 */

use Transbank\Onepay\Transaction;

$status = $request->input("status");
$externalUniqueNumber = $request->input("externalUniqueNumber");
$occ = $request->input("occ");

if (!empty($status) && strcasecmp($status,"PRE_AUTHORIZED") == 0) {
    try {
        $response = Transaction::commit($occ, $externalUniqueNumber);
        // Procesar $response
    } catch (Exception $e) {
        // Error al confirmar la transaccion
    }
} else {
    // Mostrar página de error
}
using Transbank.Onepay;

 if (null != status && status.Equals("PRE_AUTHORIZED", StringComparison.InvariantCultureIgnoreCase))
 {
    try
    {
        var response = Transaction.Commit(occ, externalUniqueNumber);
        // Procesar response
    }
    catch (TransbankException e)
    {
        // Error al confirmar la transaccion
    }
}
else
{
    // Mostrar página de error
}
require 'transbank/sdk'

if params["status"] == "PRE_AUTHORIZED"
  response = Transbank::Onepay::Transaction.commit(
    occ: params["occ"],
    external_unique_number: params["external_unique_number"]
  )
  # Procesar response

else
  # Mostrar página de error
end

rescue Transbank::Onepay::Errors::TransactionCommitError => e
  # Manejar el error de confirmación de transacción
if (status and status.upper() == "PRE_AUTHORIZED"):
  try:
    response = Transaction.commit(occ, external_unique_number)
    # Procesar response
  except TransactionCommitError:
    # Error al confirmar la transacción
else:
  # Mostrar página de error

El resultado obtenido en response tiene una forma como la de este ejemplo:

"occ": "1807983490979289",
"authorizationCode": "623245",
"issuedAt": 1532104549,
"signature": "FfY4Ab89rC8rEf0qnpGcd0L/0mcm8SpzcWhJJMbUBK0=",
"amount": 27500,
"transactionDesc": "Venta Normal: Sin cuotas",
"installmentsAmount": 27500,
"installmentsNumber": 1,
"buyOrder": "20180720122456123"

Para completar el flujo, solo queda que le des la noticia al usuario de que el pago ha sido exitoso y le muestres un comprobante de ser necesario.

Integración Mobile (app-to-app)

Si tu comercio posee una app móvil, entonces debes integrar también los SDKs móviles. Comienza revisando la manera de instalar el SDK Android y el SDK iOS.

A diferencia de la modalidad Checkout, en la integración con tu app tú debes encargarte directamente de la comunicación entre tu app y tu backend.

Pero como ya tienes creado el código que maneja la transacción, lo que te falta por hacer eso sólo conectar las partes.

Primero tienes en el backend que configurar el equivalente al callbackUrl pero para apps. Se trata del appScheme, que le dice a la app de Onepay cómo entregarle de vuelta el control a tu propia aplicación:

import cl.transbank.onepay.Onepay;

Onepay.setAppScheme("mi-app://mi-app/onepay-result");
use Transbank\Onepay\OnepayBase;

OnepayBase::setAppScheme("mi-app://mi-app/onepay-result");
using Transbank.Onepay:

Onepay.AppScheme = "mi-app://mi-app/onepay-result";
require 'transbank/sdk'

Transbank::Onepay::Base.app_scheme = "mi-app://mi-app/onepay-result"
from transbank import onepay

onepay.app_scheme = "mi-app://mi-app/onepay-result"

Luego puedes invocar al mismo endpoint que construiste para Checkout, pero ahora lo llamas desde tu app pasando APP en el parámetro channel (via POST).

Con eso obtendrás en tu app los datos de la nueva transacción. Usando el occ puedes usar nuestro SDK para invocar la app de Onepay:

import OnePaySDK
import os.log
//...

let onepay = OnePay();
onepay.initPayment("aqui-va-la-occ",
    callback: {(statusCode, description) in
        switch statusCode {
        case OnePayState.occInvalid:
            // Algo anda mal con el occ que obtuviste desde el backend
            // Debes reintentar obtener el occ o abortar
            os_log("OCC inválida")
        case OnePayState.notInstalled:
            // Onepay no está instalado.
            // Debes abortar o pedir al usuario instalar Onepay (y luego reintentar initPayment)
            os_log("Onepay no instalado")
        }
    }
)

En Android:

import cl.ionix.tbk_ewallet_sdk_android.Error;
import cl.ionix.tbk_ewallet_sdk_android.OnePay;
import cl.ionix.tbk_ewallet_sdk_android.callback.OnePayCallback;
//...

OnePay onepay = new OnePay(this);
onepay.initPayment("occ", new OnePayCallback() {
    @Override
    public void failure(Error error, String s) {
        switch (error) {
            case INVALID_OCC:
                // Algo anda mal con el occ que obtuviste desde el backend
                // Debes reintentar obtener el occ o abortar
                break;
            case ONE_PAY_NOT_INSTALLED:
                // Onepay no está instalado.
                // Debes abortar o pedir al usuario instalar Onepay (y luego reintentar initPayment)
                break;
            default:
                Log.e(TAG, "Error inesperado al iniciar pago Onepay " + error.toString() + ":" + s);
                // Aborta o reintenta
        }
    }
});

Si todo funciona OK, el control pasará a la app Onepay donde el usuario podrá autorizar la transacción.

Una vez el usuario realice el pago, el control volverá a tu app usando el appScheme que configuraste anteriormente.

Para eso, en iOS debes agregar una entrada a Info.plist para majar el scheme indicado. Por ejemplo, si tu appScheme fuera mi-app://mi-app/onepay-result, agregarías lo siguiente:

  <key>CFBundleURLTypes</key>
  <array>
    <dict>
      <key>CFBundleURLSchemes</key>
      <array>
        <string>mi-app</string>
      </array>
      <key>CFBundleURLName</key>
      <string>cl.micomercio.mi-app</string>
    </dict>
  </array>

Y en tu AppDelegate deberás manejar esas urls que comiencen con mi-app:

func application(_ app: UIApplication, open url: URL,
                 options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {

    let sendingAppID = options[.sourceApplication]
    print("source application = \(sendingAppID ?? "Unknown")")
    guard
        let components = NSURLComponents(url: url, resolvingAgainstBaseURL: true),
        let host = components.host,
        let path = components.path,
        let params = components.queryItems
        else {
            os_log("URL, host, path o params inválidos: %s", url.absoluteString)
            return false
    }
    if (host == "mi-app" && path == "onepay-result") {
        guard
            let occ = params.first(where: { $0.name == "occ" })?.value,
            let externalUniqueNumber = params.first(where: { $0.name == "externalUniqueNumber" })?.value
            else {
                os_log("Falta un parámetro occ o externalUniqueNumber: %s", url.absoluteString)
                return false
        }
        // Envia el occ y el externalUniqueNumber a tu backend para que
        // confirme la transacción
        print(occ, externalUniqueNumber)

    } else {
        // Otras URLs que quizás maneja tu app
    }
    return false

}

En Android debes registrar un Activity que responda a la URL registrada en dicho appScheme. Para eso debes configurar un intent filter a tu activity.

<activity ...>
  <intent-filter>
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <data android:scheme="mi-app" android:host="mi-app" android:path="onepay-result" />
  </intent-filter>
</activity>

Luego en ese Activity podrás obtener el resultado de la transacción a través del Intent:

Intent intent = getIntent();
String occ = intent.getStringExtra("occ");
String externalUniqueNumber = intent.getStringExtra("externalUniqueNumber");

Finalmente deberás enviar el occ y el externalUniqueNumber a tu backend (quizás quieras reusar el mismo callbackUrl que confirma transacciones en modo checkout, pasando el status "PRE_AUTHORIZED" y algún parámetro adicional que le haga saber a tu backend que devuelva JSON en lugar de dibujar una página web con el comprobante).

Con eso has concluido la integración de Onepay, incluyendo sus cuatro componentes: backend, frontend-web (soportando canales WEB y MOBILE) y las dos apps móviles (para el canal APP). ¡Felicitaciones!

Integración Cortafila

Las modalidades vistas hasta ahora contemplan que tu aplicación es usada directamente por el comprador (tarjetahabiente), quien compra directamente desde tu app móvil o desde tu web (y es dirigido a la app Onepay de la manera más apropiada).

Onepay ofrece la flexibilidad para ser usado también en la modalidad cortafila en tus tiendas físicas. Allí un vendedor usando por ejemplo un tablet puede acercarse a los compradores y procesar rápidamente su compra usando Onepay.

Para hacer funcionar este proceso la integración es un poco diferente a las vistas anteriormente. Suponiendo que la app para el vendedor es una app móvil, ahora verás los pasos necesarios para realizar la integración.

1. Tu app móvil inicia el flujo

Para comenzar, la app móvil del vendedor será la que inicie la transacción. Esta app debe invocar a tu backend (por ejemplo a través de un API REST).

2. Tu backend crea la transacción Onepay

import cl.transbank.onepay.Onepay;
import cl.transbank.onepay.model.*;

// ...

Onepay.setCallbackUrl("https://miapp.cl/endPayment");
TransactionCreateResponse response = Transaction.create(cart, Channel.MOBILE);
/*
 * IMPORTANTE: El ejemplo está pensado en la forma más simple de integrar que
 * es apuntando a integración. El SDK asume que usarás integración si no has
 * seteado el ambiente, razón por la cual no es necesario que lo configures.
 * Sin embargo, debes tener presente que al momento de apuntar a producción
 * deberás configurar el ambiente así como tu API_KEY y SHARED_SECRET antes
 * de realizar la llamada a Transaction::create, ya que de lo contrario estarás
 * apuntando a INTEGRACION
 *
 * ejemplo:
 * use Transbank\Onepay\OnepayBase;
 * OnepayBase::setCurrentIntegrationType('LIVE');
 * OnepayBase::setApiKey("api-key-entregado-por-transbank");
 * OnepayBase::setSharedSecret("secreto-entregado-por-transbank");
 */

use Transbank\Onepay;

OnepayBase::setCallbackUrl("https://miapp.cl/endPayment");
$channel = ChannelEnum::MOBILE();
$response = Transaction::create($cart, $channel);
using Transbank.Onepay;
using Transbank.Onepay.Model;

// ...
Onepay.CallbackUrl = "https://miapp.cl/endPayment";
var response = Transaction.Create(cart, ChannelType.MOBILE);
require 'transbank/sdk'

Transbank::Onepay::Base.callback_url = "https://miapp.cl/endPayment"
channel = Transbank::Onepay::Channels::MOBILE
response = Transbank::Onepay::Transaction.create(
    shopping_cart: cart, channel: channel)
from transbank import onepay
from transbank.onepay.transaction import Transaction, Channel

onepay.callback_url = "https://miapp.cl/endPayment"
response = Transaction.create(cart, Channel.MOBILE)

A partir de la información entregada por la app móvil del vendedor (información que debe estar autenticada y autorizada), deberás crear una transacción usando MOBILE como channel. Ten en cuenta que el callback que indiques será invocado en el dispositivo móvil del comprador y no del vendedor (como verás en el paso 4).

Luego en la respuesta que le enviarás a la app móvil del vendedor debes incluir la respuesta de la transacción Onepay.

3. Dibujar el código QR en la app móvil

En base a lo retornado por tu backend (que a su vez retornó la transacción Onepay creada), debes dibujar el código QR para que el vendedor le permita al comprador usar su app Onepay. Para eso puedes usar el campo qrCodeAsBase64 de la respuesta a la creación de la transacción onepay.

Te recomendamos también implementar un timeout y/o una interfaz para que el vendedor aborte la operación. Porque desde este momento el control lo tendrá el comprador en su propio dispositivo móvil.

4. Retomar el control en el navegador móvil del comprador

Cuando el comprador escanee el QR con su app Onepay, no tendrás manera de saber el progreso de la operación. Pero cuando el comprador termine (exitosamente o con error), tu callback será invocado en el navegador móvil del comprador.

import cl.transbank.onepay.model.*;

String status = request.getParameter("status");
String externalUniqueNumber = request.getParameter("externalUniqueNumber");
String occ = request.getParameter("occ");

if (null != status && status.equalsIgnoreCase("PRE_AUTHORIZED")) {
    try {
        TransactionCommitResponse response =
            Transaction.commit(occ, externalUniqueNumber);
        // Procesar response
        // Si response es exitoso, renderear página de exito
        // en el navegador web del tarjetahabiente y despachar
        // una push notification al dispositivo móvil que inició
        // esta transacción.
    } catch (TransbankException e) {
        // Error al confirmar la transaccion
    }
} else {
    // Mostrar página de error
}
/*
 * IMPORTANTE: El ejemplo está pensado en la forma más simple de integrar que
 * es apuntando a integración. El SDK asume que usarás integración si no has
 * seteado el ambiente, razón por la cual no es necesario que lo configures.
 * Sin embargo, debes tener presente que al momento de apuntar a producción
 * deberás configurar el ambiente así como tu API_KEY y SHARED_SECRET antes
 * de realizar la llamada a Transaction::commit, ya que de lo contrario estarás
 * apuntando a INTEGRACION
 *
 * ejemplo:
 * use Transbank\Onepay\OnepayBase;
 * OnepayBase::setCurrentIntegrationType('LIVE');
 * OnepayBase::setApiKey("api-key-entregado-por-transbank");
 * OnepayBase::setSharedSecret("secreto-entregado-por-transbank");
 */

use Transbank\Onepay\Transaction;

$status = $request->input("status");
$externalUniqueNumber = $request->input("externalUniqueNumber");
$occ = $request->input("occ");

if (!empty($status) && strcasecmp($status,"PRE_AUTHORIZED") == 0) {
    try {
        $response = Transaction::commit($occ, $externalUniqueNumber);
        // Procesar $response.
        // Si $response es exitoso, renderear página de exito
        // en el navegador web del tarjetahabiente y despachar
        // una push notification al dispositivo móvil que inició
        // esta transacción.
    } catch (Exception $e) {
        // Error al confirmar la transaccion
    }
} else {
    // Mostrar página de error
}
using Transbank.Onepay;

 if (null != status && status.Equals("PRE_AUTHORIZED", StringComparison.InvariantCultureIgnoreCase))
 {
    try
    {
        var response = Transaction.Commit(occ, externalUniqueNumber);
        // Procesar response
        // Si response es exitoso, renderear página de exito
        // en el navegador web del tarjetahabiente y despachar
        // una push notification al dispositivo móvil que inició
        // esta transacción.
    }
    catch (TransbankException e)
    {
        // Error al confirmar la transaccion
    }
}
else
{
    // Mostrar página de error
}
require 'transbank/sdk'

if params["status"] == "PRE_AUTHORIZED"
  response = Transbank::Onepay::Transaction.commit(
    occ: params["occ"],
    external_unique_number: params["external_unique_number"]
  )
  # Procesar response
  # Si response es exitoso, renderear página de exito
  # en el navegador web del tarjetahabiente y despachar
  # una push notification al dispositivo móvil que inició
  # esta transacción.
else
  # Mostrar página de error
end

rescue Transbank::Onepay::Errors::TransactionCommitError => e
  # Manejar el error de confirmación de transacción
if (status and status.upper() == "PRE_AUTHORIZED"):
  try:
    response = Transaction.commit(occ, external_unique_number)
    # Procesar response
    # Si response es exitoso, renderear página de exito
    # en el navegador web del tarjetahabiente y despachar
    # una push notification al dispositivo móvil que inició
    # esta transacción.
  except TransactionCommitError:
    # Error al confirmar la transacción
else:
  # Mostrar página de error

En ese callback debes confirmar la transacción. Y si tiene éxito la transacción debes mostrar al comprador que todo salió ok al mismo tiempo que notificas a tu app del vendedor (por ejemplo con una push notification) para que esa app también muestre a su usuario que la venta realmente se ha cobrado.

5. Aplicación demostrativa

Si quieres ver el ejemplo funcional de una aplicación integrando Cortafilas, puedes revisar las demostraciones disponibles. Descarga la aplicación Android mirando su código fuente, o dirígete a la aplicación web con su respectivo código fuente.

Credenciales del comercio

Para establecer las credenciales de tu comercio (y no seguir usando las credenciales pre-configuradas que solo funcionan en TEST), puedes realizarlo así:

import cl.transbank.onepay.Onepay;
//...

Onepay.setApiKey("api-key-entregado-por-transbank");
Onepay.setSharedSecret("secreto-entregado-por-transbank");
use Transbank\Onepay\OnepayBase;

OnepayBase::setApiKey("api-key-entregado-por-transbank");
OnepayBase::setSharedSecret("secreto-entregado-por-transbank");
using Transbank.Onepay;

Onepay.ApiKey = "api-key-entregado-por-transbank";
Onepay.SharedSecret = "secreto-entregado-por-transbank";
require 'transbank/sdk'

Transbank::Onepay::Base.api_key = "entregado por transbank"
Transbank::Onepay::Base.shared_secret = "entregado por transbank"
from transbank import onepay

onepay.api_key = "api-key-entregado-por-transbank"
onepay.shared_secret = "secreto-entregado-por-transbank"

También puedes configurar el api key y secret de una petición específica:

import cl.transbank.onepay.model.Options;
//...

Options options = new Options()
                  .setApiKey("api-key-entregado-por-transbank")
                  .setSharedSecret("secreto-entregado-por-transbank");
use Transbank\Onepay\Options;

$options = new Options(
    'api-key-entregado-por-transbank',
    'secreto-entregado-por-transbank');
var options = new Options()
        {
            ApiKey = "api-key-entregado-por-transbank",
            SharedSecret = "secreto-entregado-por-transbank"
        }
require 'transbank/sdk'

options = { api_key: 'api-key-entregado-por-transbank',
            shared_secret: 'shared-secret-entregado-por-transbank' }
from transbank.onepay import Options

options = Options("api-key-entregado-por-transbank",
                  "secreto-entregado-por-transbank")

Esas opciones puedes pasarlas como parámetro a cualquier método transaccional de Onepay (Transaction.create, Transaction.commit y Refund.create).

Apuntar a producción

Puedes configurar el SDK para utilizar los servicios del ambiente de LIVE (Producción) de la siguiente forma:

import cl.transbank.onepay.Onepay;
//...
Onepay.setIntegrationType(Onepay.IntegrationType.LIVE);
use Transbank\Onepay\OnepayBase;

OnepayBase::setCurrentIntegrationType('LIVE');
using Transbank.Onepay;

Onepay.IntegrationType = Transbank.Onepay.Enums.OnepayIntegrationType.LIVE;
require 'transbank/sdk'

Transbank::Onepay::Base.integration_type = :LIVE
from transbank import onepay

onepay.integration_type = onepay.IntegrationType.LIVE

Conciliación de Transacciones

Una vez hayas realizado transacciones en producción quedará un historial de transacciones que puedes revisar entrando a www.transbank.cl. Si lo deseas puedes realizar una conciliación entre tu sistema y el reporte que entrega el portal.

Para realizar la conciliación debes seguir los siguientes pasos:

  1. Iniciar sesión con tu usuario y contraseña en www.transbank.cl

  2. Una vez entras al portal, en el menú principal presiona "Webpay", y luego "Reporte Transaccional" Paso 2

  3. En la parte superior de la ventana puedes encontrar un buscador que te ayudará a filtrar, según los parámetros que gustes, las transacciones que quieras cuadrar. Para encontrar las transacciones de Onepay, en producto, debes seleccionar Webpay3G. Debes tener en cuenta que lamentablemente el reporte no distingue entre Webpay y Onepay. Bajo el producto Webpay3G encontraras transacciones de ambos productos. Paso 3

  4. Dentro de la tabla en la imagen anterior puedes presionar el número de orden de compra para abrir los detalles de la transacción. Es en esta sección donde podrás encontrar y conciliar la mayoría de los parámetros devueltos al confirmar una transacción utilizando commit(). Paso 4

  5. Sólo queda realizar la conciliación. A continuación puedes ver una lista de parámetros que recibirás al momento de confirmar una transacción y a que fila de la tabla "Detalles de la transacción" corresponden (la lista completa de parámetros la puedes encontrar acá).

Nombre parámetro
tipo
Fila en tabla
responseCode
String
Código de respuesta
result.authorizationCode
String
Código de autorización
result.issuedAt
Number
Fecha de creación (viene con formato unix timestamp)
result.amount
Number
Monto de la transacción.
result.transactionDesc
String
Tipo de producto
result.installmentsNumber
Number
Número de cuotas.
result.buyOrder
Number
Orden de compra.

Más funcionalidades

Consulta la referencia del API para más funcionalidades ofrecidas por Onepay:

Ejemplos de integración

Ponemos a tu disposición una serie de repositorios en nuestro Github para ayudarte a entender la integración mejor.