API Referencia
undefined

POS Integrado

Cómo empezar

Primero, debes instalar en tu máquina la librería/SDK en C, puedes encontrar el código fuente en GitHub y seguir las instrucciones para compilarlo. También puede usar las DLLs ya compiladas que se adjuntan en el último release

Esta librería y sus dependencias (libserialport) son requisitos para utilizar el SDK.

Por el momento, hay un SDK para .NET, Java y Javascript (tecnologías web).

SDK .NET

Para .NET lo puedes encontrar en NuGet.org para instalarlo puedes utilizar por ejemplo el package manager de VisualStudio.

PM> Install-Package TransbankPosSDK

SDK Java

Para Java se puede incluir el paquete por Maven.

        <dependency>
            <groupId>com.github.transbankdevelopers</groupId>
            <artifactId>transbank-sdk-pos-java</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

SDK Web

El SDK Web consta de dos partes: SDK Javacript y Cliente Desktop.

Cliente Desktop: Este cliente se debe instalar e inicializar en el computador que tendrá el equipo POS conectado físicamente. Al instalar e inicializar este servicio, se creará un servidor de websockets local en el puerto 8090, que permitirá, a través del SDK de javascript, poder enviar y recibir mensajes al equipo POS, de manera simple y transparente.

SDK Javacript: Este SDK se debe instalar en el software de caja (o cualquier software web que presente HTML, CSS y JS en un navegador web). Este SDK entrega una interfaz simple para conectarse con el cliente desktop, de manera que se puedan mandar instrucciones al POS con un API fácil de usar directamente desde el browser.

Dentro de cada repositorio se encuentra la documentación más detallada.

Instalar el SDK en el software web donde se realizará la integración

npm install transbank-pos-sdk-web

También se puede incluir directamente el tag script

<script src="https://unpkg.com/[email protected]/dist/pos.js"></script>
<script>
// En este caso, el objeto en vez de ser POS, es Transbank.POS
// Ej: Transbank.POS.connect(...); en vez de POS.connect(...) como se especifica en los ejemplos de mas abajo. 
</script>

Variable de entorno

Para utilizar el SDK del POS es necesario el archivo Transbank.dll, o Transbank.dylib del SDK de C. Para que el cliente pueda encontrar la librería nativa, utiliza una variable de ambiente llamada NATIVE_TRANSBANK_WRAP que debe apuntar al archivo de esta variable.

Por ejemplo en MacOS se debe correr el comando export en el mismo Shell en que se ejecutará el programa que utiliza la librería.

export NATIVE_TRANSBANK_WRAP=/usr/local/lib/libTransbankWrap.dylib

En Windows, se debe correr este comando en la ventana de CMD antes de ejecutar el programa que utiliza la librería. setx NATIVE_TRANSBANK_WRAP=c:\TransbankLib\TransbankWrapJava.dll

Instalar el cliente desktop: Se debe descargar el las DLL mencionadas anteriormente (libserialport-0.dll) e instalarla idealmente en la carpeta system32 (en windows). En OSX se puede instalar como brew install libserialport o con estas instrucciones.

Se debe descargar el archivo .jar del último release del repositorio y ejecutar:

java -jar transbank-pos-sdk-web-client.jar

Este cliente desktop debe estar ejecutándose siempre para que el SDK Javascript funcione correctamente. Puedes ejecutarlo automáticamente cuando se inicie el computador. Este paso depende de tu sistema operativo

Drivers

Actualmente contamos con 2 equipos POS Integrado en circulación.

Verifone VX520 y VX520C

Este equipo esta certificado para operar mediante conexión serial, utilizando el puerto RS232. En este caso solo debes tener instalados los drivers de tu adaptador USB-Serial o tu tarjeta RS232.

Ingenico Desk 3500

Estos equipos funcionan tanto con puerto serial RS232 y USB (Generalmente plug and play), para el cual puedes necesitar instalar un driver de Ingenico.

Este driver es compatible con los siguiente sistemas operativos.

  • Windows XP
  • Windows Vista
  • Windows 7
  • Windows 2008 Server
  • Windows 2008 Server R2
  • Windows 8 and 8.1
  • Windows XP Embedded
  • Windows 2012 Server
  • Windows 2016 Server
  • Windows 10

Recuerda que necesitas tener instalados los drivers correspondientes a tu tarjeta de puerto serial o adaptador USB Serial.

LibSerialPort

Los SDK dependen de libSerialPort para la comunicación serial.

Incluimos una DLL compilada en el release de la librería en C, pero puedes obtener el código desde el repositorio oficial usando git:

git clone git://sigrok.org/libserialport

Para compilar en windows necesitarás lo siguiente:

  • msys2 - mingw-w64 Puedes descargarlo siguiendo el link y las instrucciones provistas en su sitio web.
    • Adicionalmente, necesitarás el toolchain para tu arquitectura:
      • x86: pacman -S mingw-w64-i686-toolchain
      • x64: pacman -S mingw-w64-x86_64-toolchain

Proyectos de ejemplo

Para cada SDK se creó un proyecto de ejemplo:

Primeros pasos

Para usar el SDK es necesario incluir las siguientes referencias.

using Transbank.POS;
using Transbank.POS.Utils;
using Transbank.POS.Responses:
#include "transbank.h"
#include "transbank_serial_utils.h"
import cl.transbank.pos.POS;
import cl.transbank.pos.exceptions.*;
import cl.transbank.pos.responses.*;
import POS from "transbank-pos-sdk-web"; // Si se instala por NPM
// <script src="https://unpkg.com/[email protected]/dist/pos.js"></script> si se inserta directamente el script en el HTML
// En el caso de incrustar el script, recordar que el objeto se llama Transbank.POS en vez de POS como se menciona en los siguientes ejemplos. 

Listar puertos disponibles

Si los respectivos drivers están instalados, entonces puedes usar la función ListPorts() del paquete Transbank.POS.Utilspara identificar los puertos que se encuentren disponibles y seleccionar el que corresponda con el puerto donde conectaste el POS Integrado.

using Transbank.POS.Utils;
//...
List<string> ports = Serial.ListPorts();
#include "transbank_serial_utils.h"
//...
char *ports = list_ports();
import cl.transbank.pos.POS;

POS pos = POS.getInstance();
List<String> ports = pos.listPorts();
import POS from "transbank-pos-sdk-web";

POS.getPorts().then((ports) => {
    console.log('ports');
}).catch(() => {
    alert("No se pudo obtener puertos. ¿Está corriendo el servicio Transbank POS?");
})

Abrir un puerto Serial

Para abrir un puerto serial y comunicarte con el POS Integrado, necesitarás el nombre del puerto (el cual puedes identificar usando la función mencionada en el apartado anterior). También necesitarás el baudrate al cual esta configurado el puerto serial del POS Integrado (por defecto es 115200), y puedes obtener los distintos valores desde la clase Transbank.POS.Utils.TbkBaudrates en .NET y la clase cl.transbank.pos.utils.TbkBaudRate en Java.

Si el puerto no puede ser abierto, se lanzará una excepción TransbankException en .NET y Java.

using Transbank.POS;
using Transbank.POS.Utils;
//...
string portName = "COM3";
POS.Instance.OpenPort(portName);
#include "transbank.h"
#include "transbank_serial_utils.h"
//...
char *portName = "COM4";
int retval = open_port(portName, 115200);
if ( retval == TBK_OK ){
    //...
}
import cl.transbank.pos.POS;

POS pos = POS.getInstance();
String port = "COM4";
pos.openPort(port);
import POS from "transbank-pos-sdk-web";
POS.openPort("COM4").then((result) => {
    if (result === true) {
    alert("Conectado satisfactoriamente")
    } else {
    alert("No se pudo conectar conectado")
    }
}).catch(error => console.log(error))

Cerrar un puerto Serial

Al finalizar el uso del POS, o si se desea desconectar de la Caja se debe liberar el puerto serial abierto anteriormente.

using Transbank.POS;
//...
bool closed = POS.Instance.ClosePort();
#include "transbank.h"
#include "transbank_serial_utils.h"
//...
retval = close_port();
if(retval == SP_OK){
    //...
}
import cl.transbank.pos.POS;
//...
pos.closePort();
import POS from "transbank-pos-sdk-web";
POS.closePort();

Transacciones

Transacción de Venta

Este comando es enviado por la caja para solicitar la ejecución de una venta. Los siguientes parámetros deben ser enviados desde la caja:

  • Monto: Monto en pesos informados al POS. Este parámetro es remitido a Transbank para realizar la autorización.
  • Número Ticket/Boleta: Este número es impreso por el POS en el voucher que se genera luego de la venta.
using Transbank.POS;
using Transbank.POS.Responses;
//...
SaleResponse response = POS.Instance.Sale(ammount, ticket);
#include "transbank.h"
#include "transbank_serial_utils.h"
//...
char* response = sale(ammount, ticket, false);
import cl.transbank.pos.POS;
//...
SaleResponse saleResponse = POS.getInstance().sale(amount, ticket);
import POS from "transbank-pos-sdk-web";

POS.doSale(this.total, "ticket1").then((saleDetails) => {
    console.log(saleDetails);
    //Acá llega la respuesta de la venta. Si saleDetails.responseCode es 0, entonces la comproa fue aprobada
    if (saleDetails.responseCode===0) {
    alert("Transacción aprobada", "", "success");
    } else {
    alert("Transacción rechazada o fallida")
    }
});

El resultado de la venta se entrega en la forma de un objeto SaleResponse o un char* en el caso de la librería C. Si ocurre algún error al ejecutar la acción en el POS se lanzará una excepción del tipo TransbankSaleException en .NET. En Java puede lanzar TransbankPortNotConfiguredException.

El objeto SaleResponse retornará un objeto con los siguientes datos.

"Function": 210
"Response": "Aprobado"
"Commerce Code": 550062700310
"Terminal Id": "ABC1234C"
"Ticket": "ABC123"
"Autorization Code": "XZ123456"
"Ammount": 15000
"Shares Number": 3
"Shares Amount": 5000
"Last 4 Digits": 6677
"Operation Number": 60
"Card Type": CR
"Accounting Date":
"Account Number":
"Card Brand": AX
"Real Date": 28/10/2019 22:35:12
"Employee Id":
"Tip": 1500

Transacción de Última Venta

Este comando es enviado por la caja, solicitando al POS la re-impresión de la última venta realizada.

Si el POS recibe el comando de Última Venta y no existen transacciones en memoria del POS, se envía la respuesta a la caja indicando el código de respuesta 11. (Ver tabla de respuestas)

using Transbank.POS;
using Transbank.POS.Responses;
//...
LastSaleResponse response = POS.Instance.LastSale();
#include "transbank.h"
#include "transbank_serial_utils.h"
//...
char *lastSaleResponse = last_sale();
}
import cl.transbank.pos.POS;
//...
SaleResponse saleResponse = POS.getInstance().getLastSale();
import POS from "transbank-pos-sdk-web";

POS.getLastSale().then((response) => {
    console.log(response)
}).catch(() => {
    alert('Error al obtener última venta');
})

El resultado de la transacción última venta devuelve los mismos datos que una venta normal y se entrega en forma de un objeto LastSaleResponse o un char* en el caso de la librería C, o un objeto SaleResponse en el caso de Java. Si ocurre algún error al ejecutar la acción en el POS se lanzará una excepción del tipo TransbankLastSaleException en .NET o TransbankException en Java.

"Function": 260
"Response": "Aprobado"
"Commerce Code": 550062700310
"Terminal Id": "ABC1234C"
"Ticket": "ABC086"
"Autorization Code": "XZ123456"
"Ammount": 15000
"Shares Number": 3
"Shares Amount": 5000
"Last 4 Digits": 6677
"Operation Number": 60
"Card Type": CR
"Accounting Date":
"Account Number":
"Card Brand": AX
"Real Date": 28/10/2019 22:35:12
"Employee Id":
"Tip": 1500

Transacción de Anulación

Esta transacción siempre será responsabilidad de la caja y es quien decide cuando realizar una anulación.

El comando de anulación soporta los siguientes parámetros que pueden ser enviados desde la caja.

using Transbank.POS;
using Transbank.POS.Responses;
//...
RefundResp response = POS.Instance.Refund(21);
#include "transbank.h"
#include "transbank_serial_utils.h"
//...
RefundResponse response = refund(21);
import cl.transbank.pos.POS;
//...
RefundResponse response = POS.getInstance().refund(21);
import POS from "transbank-pos-sdk-web";

POS.refund(21).then(response => console.log(response));

Como respuesta el POS enviará un código de aprobación, acompañado de un código de autorización. En caso de rechazo el código de error está definido en la tabla de respuestas. Ver tabla de respuestas

"FunctionCode": 1210
"ResponseCode": 0
"CommerceCode": 597029414300
"TerminalId": "ABCD1234"
"AuthorizationCode": "ABCD1234"
"OperationID": 123456
"ResponseMessage": "Aprobado"
"Success": true

Transacción de Cierre

Este comando es gatillado por la caja y no recibe parámetros. El POS ejecuta la transacción de cierre contra el Autorizador (no se contempla Batch Upload). Como respuesta el POS Integrado enviará un aprobado o rechazado. (Puedes ver la tabla de respuestas en este link)

using Transbank.POS;
using Transbank.POS.Responses;
//...
CloseResponse response = POS.Instance.Close();
#include "transbank.h"
#include "transbank_serial_utils.h"
//...
BaseResponse response = register_close();
}
import cl.transbank.pos.POS;
//...
CloseResponse cr = POS.getInstance().close();
import POS from "transbank-pos-sdk-web";

POS.close()

El resultado del cierre de caja se entrega en la forma de un objeto CloseResponse o una estructura BaseResponse en el caso de la librería C. Si ocurre algún error al ejecutar la acción en el POS se lanzará una excepción del tipo TransbankCloseException.

"FunctionCode": 510
"ResponseMessage": "Aprobado"
"Success": true
"CommerceCode": 550062700310
"TerminalId": "ABC1234C"

Transacción Totales

Esta operación le permitirá a la caja obtener desde el POS un resumen con el monto total y la cantidad de transacciones que se han realizado hasta el minuto y que aún permanecen en la memoria del POS.

Además la caja podrá determinar si existen transacciones que no fueron informadas desde el POS, haciendo una comparación de los totales entre la caja y el POS. La impresión del Voucher con el resumen será realizada por el POS.

using Transbank.POS;
using Transbank.POS.Responses;
//...
TotalsResponse response = POS.Instance.Totals();
#include "transbank.h"
#include "transbank_serial_utils.h"
//...
TotalsCResponse response = get_totals();
}
import cl.transbank.pos.POS;
//...
TotalsResponse response = POS.getInstance().getTotals();
import POS from "transbank-pos-sdk-web";

POS.getTotals().then(response => console.log(response));

El resultado de la transacción entrega en la forma de un objeto TotalsResponse o una estructura TotalsCResponse en el caso de la librería C. Si ocurre algún error al ejecutar la acción en el POS se lanzará una excepción del tipo TransbankTotalsException.

"Function": 710
"Response": "Aprobado"
"TX Count": 3     // Cantidad de transacciones
"TX Total": 15000 // Suma total de los montos de cada transaccion

Transacción de Detalle de Ventas

Esta transacción solicita al POS todas las transacciones que se han realizado y permanecen en la memoria del POS. El parámetro que recibe esta función es de tipo booleano e indica si se realiza la impresión del detalle en el POS. En el caso de que no se solicite la impresión, el POS envía todas las transacciones a la caja, una por una. Si se realiza la impresión, la caja recibira una lista vacia de transacciónes.

using Transbank.POS;
using Transbank.POS.Responses;
//...
bool printOnPOS = false;
List<DetailResponse> Details(printOnPOS)
#include "transbank.h"
#include "transbank_serial_utils.h"
//...
bool print_on_pos = false;
char *response = sales_detail(print_on_pos);
}
import cl.transbank.pos.POS;
//...
List<DetailResponse> ldr = POS.getInstance().details(false);
import POS from "transbank-pos-sdk-web";

let printOnPOS = false;
POS.details(printOnPOS).then(response => console.log(response));

El resultado de la transacción entrega una lista de objetos DetailResponse o un char * en el caso de la librería C. Si ocurre algún error al ejecutar la acción en el POS se lanzará una excepción del tipo TransbankSalesDetailException.

[
  {
    "Function": 261,
    "Response": "Aprobado",
    "Commerce Code": 550062700310,
    "Terminal Id": "ABC1234C",
    "Ticket": "AB123",
    "Autorization Code": "XZ123456",
    "Ammount": 15000,
    "Shares Number": 3,
    "Shares Amount": 5000,
    "Last 4 Digits": 6677,
    "Operation Number": 60,
    "Card Type": CR,
    "Accounting Date": ,
    "Account Number": ,
    "Card Brand": AX,
    "Real Date": "28/10/2019 22:35:12",
    "Employee Id": ,
    "Tip": 1500,
  },
  {
    "Function": 261,
    "Response": "Aprobado",
    "Commerce Code": 550062700310,
    "Terminal Id": "ABC1234C",
    "Ticket": "AB123",
    "Autorization Code": "XZ123456",
    "Ammount": 15000,
    "Shares Number": 3,
    "Shares Amount": 5000,
    "Last 4 Digits": 6677,
    "Operation Number": 60,
    "Card Type": CR,
    "Accounting Date": ,
    "Account Number": ,
    "Card Brand": AX,
    "Real Date": "28/10/2019 22:35:12",
    "Employee Id": ,
    "Tip": 1500
  }
]

Transacción de Carga de Llaves

Esta transacción permite al POS Integrado del comercio requerir cargar nuevas Working Keys desde Transbank. Como respuesta el POS Integrado enviará un aprobado o rechazado. (Puedes ver la tabla de respuestas en este link)

using Transbank.POS;
using Transbank.POS.Responses;
//...
LoadKeysResponse response = POS.Instance.LoadKeys();
#include "transbank.h"
#include "transbank_serial_utils.h"
//...
BaseResponse response = load_keys();
}
import cl.transbank.pos.POS;
//...
KeysResponse kr = POS.getInstance().loadKeys();
import POS from "transbank-pos-sdk-web";

let printOnPOS = false;
POS.loadKeys();

El resultado de la carga de llaves entrega en la forma de un objeto LoadKeysResponse o una estructura BaseResponse en el caso de la librería C, un objeto KeysResponse para Java. Si ocurre algún error al ejecutar la acción en el POS se lanzará una excepción del tipo TransbankLoadKeysException en .NET o TransbankException en Java.

"FunctionCode": 810
"ResponseMessage": "Aprobado"
"Success": true
"CommerceCode": 550062700310
"TerminalId": "ABC1234C"

Transacción de Poll

Esta mensaje es enviado por la caja para saber si el POS está conectado. En el SDK el resultado de esta operación es un Booleano o un 0 representado en la constante TBK_OK en el caso de la librería en C. Si ocurre algún error al momento de ejecutar la acción en el POS, se lanzará una excepción del tipo TransbankException.

using Transbank.POS;
//...
bool connected = POS.Instance.Poll();
#include "transbank.h"
#include "transbank_serial_utils.h"
//...
int retval = poll();
if (retval == TBK_OK){
    //...
}
import cl.transbank.pos.POS;
//...
boolean pollResult = POS.getInstance().poll();
import POS from "transbank-pos-sdk-web";

let printOnPOS = false;
POS.poll().then(result => console.log(result));

Transacción de Cambio a POS Normal

Este comando le permitirá a la caja realizar el cambio de modalidad a través de un comando. El POS debe estar en modo integrado y al recibir el comando quedara en modo normal. El resultado de esta operación es un Booleano en el caso del SDK o un 0 representado en la constante TBK_OK en el caso de la librería en C. Si ocurre algún error al momento de ejecutar la acción en el POS, se lanzará una excepción del tipo TransbankException.

using Transbank.POS;
//...
bool connected = POS.Instance.SetNormalMode();
#include "transbank.h"
#include "transbank_serial_utils.h"
//...
int retval = set_normal_mode();
if (retval == TBK_OK){
    //...
}
import cl.transbank.pos.POS;
//...
boolean normal = POS.getInstance().setNormalMode();
import POS from "transbank-pos-sdk-web";

let printOnPOS = false;
POS.setNormalMode().then(result => console.log(result));

Integración de Onepay para pagos con QR

Ahora es posible realizar pagos con Onepay dentro de tu sistema de caja. Para esto, ponemos a tu disposición, dentro del SDK, las herramientas necesarias para generar un QR de Onepay y procesar el pago en tu sistema de caja.

Lo primero que debes hacer es importar Transbank.POS y Transbank.POS.Model en tu proyecto, crear un nuevo objeto OnepayPayment y suscribirte a los eventos que te notificaran del progreso del pago en el flujo de Onepay.

Suscribirse a eventos y crear una transacción

using Transbank.POS;
using Transbank.POS.Model;
//...

int ticket = new Random().Next(1, 999999);
Pay = new OnepayPayment(ticket, total);

//Subscribe to events
Pay.OnConnect += (sender, e) => UpdateWSStatus("Web Socket Conectado");
Pay.OnDisconnect += WsDisconnected;
Pay.OnNewMessage += UpdateStatus;
Pay.OnSuccessfulPayment += ProcessPaymentResult;

Obtener el QR para iniciar el pago

Luego de crear el objeto OnepayPayment, debes iniciar el pago, lo que te entregará la imagen del QR en base64 y el número de ott. Estos le permiten al usuario pagar escaneando la imagen o ingresando el ott en la aplicación de Onepay.

using Transbank.POS;
using Transbank.POS.Model;
//...

OnepayCreateResponse response = Pay.StarPayment();

//draw the base64 image
byte[] imageBytes = Convert.FromBase64String(response.QrCodeAsBase64);
using (MemoryStream ms = new MemoryStream(imageBytes, 0, imageBytes.Length))
{
  img_qr.Image = Image.FromStream(ms);
}
txt_ott.Text = response.Ott;

Esperar que el usuario termine el pago en la App de Onepay

El último paso es esperar a que el usuario termine el flujo en la app de Onepay. Cuando la transacción termine exitosamente en Onepay, se lanzará el evento SuccessfulPaymentEventArgs

using Transbank.POS;
using Transbank.POS.Model;
//...
Pay.WatchPayment();

Ejemplos de integración

Ponemos a tu disposición un ejemplo en nuestro Github para ayudarte a entender mejor la integración.