Skip to content

Integración Aplicación POS Android

Introducción

En el presente documento se incluye la especificación técnica que deben cumplir las aplicaciones de terceros, para hacer uso del software que representa al módulo de pagos, incluido en los terminales.

Se entiende por aplicaciones de terceros cualquier servicio instalado en el terminal que no forma parte ni del sistema operativo ni de la arquitectura de pagos implementada por CardNET.

Un intent es un caso de uso concreto implementado en el módulo de pagos. Para todos los intents se sigue la misma lógica: envío de petición y recepción de respuesta. Los intents implementados son:

  • Transacción de venta
  • Transacción de anulación
  • Impresión de recibos

Del mismo modo, se dispone de un servicio REST implementado en el módulo de pagos, el cual permitirá a las aplicaciones de terceros realizar las diferentes acciones. Al consumir cada método del servicio REST se sigue la misma lógica: Envío de parámetros requeridos por el servicio y recepción de respuesta. Los métodos implementados son:

  • Transacción de venta
  • Transacción de anulación
  • Impresión de recibos

El objetivo de esta especificación es definir la manera en que una aplicación puede realizar un cobro, invocando el servicio de pago del terminal, obteniendo como respuesta el resultado de la transacción.

Servicios de intents para el uso de la aplicación de pago

El objetivo de esta especificación es definir la manera en que una aplicación puede realizar un cobro, invocando el servicio de pago del terminal, obteniendo como respuesta el resultado de la transacción.

Transaction Actions

  • ACTION_REQUEST = "com.necomplus.tpv.transaction.REQUEST";
  • ACTION_RESPONSE = "com.necomplus.tpv.transaction.RESPONSE";

Request Parameters

DatoTipoDescripciónM/O
TYPEstringTipo de transacción para una venta enviar SALE, Anulación REFUDM
AMMOUNTdoubleMonto de la transacción en formato Double ejemplos 1200 ; 2503 ; 10023 entendiéndose que los dos últimos son los centavosO
ITBISdoubleITBIS de la transacción em formato Double ejemplos 1200 ; 2503 ; 10023 entendiéndose que los dos últimos son los centavos.O
TAXdoubleITBIS de la transacción em formato Double ejemplos 1200 ; 2503 ; 10023 entendiéndose que los dos últimos son los centavos.O
REFERENCEstringCódigo de referencia de una transacción especifica, ejemplo: 123456O
DatajsonSe entrega toda la data de la transacción que se vaya a enviar al Ágora para guardar por parte del terceroO

Response Parameters

DatoTipoDescripciónM/O
CodestringCódigo de respuesta de la transacción: "0" Aprobada, "1" Fallida, "2" CandeladaM
MessagestringMensaje que quiere que se muestre en la ventana de aprobación ejemplo “error transaction”O
DatajsonSe entrega toda la data de la transacción para imprimir el recibo, ver el ejemplo del JSON.O

Ejemplo

json
{
  "voucherNumber": "000001",
  "authCode": 0,
  "resultMessage": "ACEPTADA",
  "ticket": {
    "AID": "A0000000041010",
    "ARC": "00",
    "ATC": "00297",
    "PSN": "00",
    "Amount": "100",
    "Authorization": "006360",
    "CardBank": "Banco XXX",
    "CardHolder": "",
    "CardIssuer": "Credito",
    "CardNumber": "************3059",
    "CardTechnology": 1, // 1 chip , 2 cless, 3 Banda
    "CardType": "",
    "Currency": "DOP",
    "Date": "20200522",
    "Id": "432864",
    "Language": "es",
    "Location": "SANTO DOMINGO",
    "MerchantId": "329811087",
    "MerchantName": "Comercio",
    "OriginalTransactionDate": "",
    "OriginalTransactionId": "",
    "PinIndicator": 0, // 1 pin
    "SignatureImage": "89504e470d0a1a0a0000000d49484452000001f400000139080600000066a0d2e0000000047...",
    "SignatureIndicator": 1,
    "Status": "0",
    "TerminalId": "00000001",
    "Time": "0106",
    "Type": "Payment"
  }
}

Ejemplo de mensajería

java
/**
 * MENSAJERÍA INTENTS CARDNET
 */

// PETICIÓN DE TRANSACCIÓN ---------------------------------------------------------------------------
public static final String ACTION_REQUEST = "com.necomplus.tpv.transaction.REQUEST"; // NOMBRE PETICIÓN DE TRANSACCIÓN EN INTENT

// PARÁMETROS DE ENVÍO
public enum ParamsRequest {
    TYPE,
    AMOUNT,
    REFERENCE;

    public String getValue() {
        return ACTION_REQUEST + ".params" + this.name();
    }
}

// ParamsRequest.TYPE: Tipo de la transacción que se quiere procesar en el aplicativo Cardnet en formato String
// ejemplo: Para realizar una venta enviar "SALE"

// ParamsRequest.AMOUNT: Monto de la transacción en formato double
// ejemplo: 12.0 ; 25.03 ; 100.23

// ParamsRequest.REFERENCE: Indica el código de referencia a una transacción específica en formato String
// ejemplo: 123456

// RESPUESTA DE TRANSACCIÓN --------------------------------------------------------------------------
public static final String ACTION_RESPONSE = "com.necomplus.tpv.transaction.RESPONSE"; // NOMBRE RESPUESTA DE TRANSACCIÓN EN INTENT

// PARÁMETROS DE RESPUESTA
public enum ParamsResponse {
    CODE,
    MESSAGE,
    DATA;

    public String getValue() {
        return ACTION_RESPONSE + ".params" + this.name();
    }
}

// ParamsResponse.CODE: Código de respuesta transacción en formato String
// códigos de respuesta en transacciones
public static final int TX_APPROVED = 0;  // APROBADA
public static final int TX_FAILED = 1;    // TRANSACCIÓN FALLIDA
public static final int TX_CANCEL = 2;    // CANCELADA

// ParamsResponse.MESSAGE: Mensaje de la transacción en formato String
// ejemplo: "success", "cancel", "error transaction"

// ParamsResponse.DATA: Data extra en formato json como respuesta de la transacción
// ejemplo:
/**
{
    "authCode": "123456",
    "voucherNumber": "000001"
}
**/
private static final String JSON_NAME_AUTH_CODE = "authCode";
private static final String JSON_NAME_VOUCHER_CODE = "voucherNumber";

// EJEMPLO DE USO

// REGISTRAR BROADCAST PARA RECIBIR LA RESPUESTA DE LA TRANSACCIÓN
private BroadcastReceiver receiverTransaction = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent != null && intent.getExtras() != null) {
            int code = intent.getExtras().getInt(NameIntents.ParamsResponse.CODE.getValue());
            String message = intent.getExtras().getString(NameIntents.ParamsResponse.MESSAGE.getValue());

            if (transactionData.getCodeResult() == TX_APPROVED) {
                try {
                    String json = intent.getExtras().getString(NameIntents.ParamsResponse.DATA.getValue());
                    if (json == null) {
                        return;
                    }
                    JSONObject jsonObject = new JSONObject(json);
                    String authCode = jsonObject.getString(JSON_NAME_AUTH_CODE);
                    String referenceNumber = jsonObject.getString(JSON_NAME_VOUCHER_CODE);
                    onSuccess();
                } catch (JSONException e) {
                    Throwable ex = new Throwable(e.getMessage());
                    onError(ex);
                }
            } else {
                Throwable ex = new Throwable(message);
                onError(ex);
            }
        }
    }
};

// FILTRO DE INTENT Y REGISTRO DE RECEIVER
IntentFilter intentFilter = new IntentFilter(ACTION_RESPONSE);
context.registerReceiver(receiverTransaction, intentFilter);

// ENVIAR REQUEST A LA APLICACIÓN PARA LA VENTA
Intent intent = new Intent(ACTION_REQUEST);
intent.putExtra(NameIntents.ParamsRequest.AMOUNT.getValue(), 10.0);
intent.putExtra(NameIntents.ParamsRequest.TYPE.getValue(), "SALE");
intent.putExtra(NameIntents.ParamsRequest.REFERENCE.getValue(), "123456");
context.sendBroadcast(intent);

Servicios REST para el uso de la aplicación de pago

El objetivo es que desde una aplicación de terceros pueda invocar la aplicación de una manera sencilla para realizar la transacción y recibir los datos con el resultado.

Server

  • HOST: ip del terminal
  • PORT: 2001

Sale

  • Método: POST
  • Endpoint: /tx_sale

Parameters Request

DatoTypeDescripciónM/O
amountdoubleMonto de la transacción en formato Double. Ejemplos: 1200 ; 2503 ; 10023 entendíendose que los dos últimos son los centavos.[M]

Parameters Response

DatoTypeDescripciónM/O
DatajsonSe entrega toda la data de la transacción para imprimir el recibo. Ver el ejemplo del JSON.[O]

Ejemplo

Request

HOST:PORT/tx_refund?amount=500&authNumber=0000117

Response

json
{
  "amount": "1500 DOP",
  "amountOriginalFormat": "1500",
  "approbationNumber": "419886",
  "bankCode": "0081",
  "bankName": "Popular",
  "cancellationsAmount": 0.0,
  "cancellationsNumber": 0,
  "cardInformation": {
    "aid": "A0000000041010",
    "apLabel": "DEBIT MASTERCARD",
    "cardNetworkId": "INTERNACIONAL NO UE",
    "cardSubType": "MASTERCARD",
    "cardType": "MASTERCARD",
    "isCTL": true,
    "isChip": false,
    "isMagneticSwipe": false,
    "maskedPAN": "***********9547",
    "needPin": false,
    "needSignature": false,
    "posEntryMode": 4,
    "posEntryModeText": "CONTACTLESS",
    "sequenceNumber": 0,
    "txType": 0
  },
  "commerceData": {
    "commerceAddress": "Avenida Doctor Jimenez Diaz, 19",
    "commerceName": "Necomplus",
    "uniqueCode": "202124004"
  },
  "copyTx": false,
  "creditsAmount": 0.0,
  "creditsNumber": 0,
  "cvm": 5,
  "isTip": false,
  "op": 1,
  "referenceNumber": "0000118",
  "refundCancellationsNumber": 0,
  "refundsAmount": 0.0,
  "refundsCancellationsAmount": 0.0,
  "refundsNumber": 0,
  "responseCode": "",
  "sessionDate": "210921",
  "sessionNumber": "001",
  "signatureCaptured": false,
  "terminal": "00000001",
  "totalTransAmount": 0.0,
  "totalTransNumber": 0,
  "transNumber": "0000118",
  "tvp": "T0000113",
  "txDateDay": "21/09/21",
  "txDateHour": "22:43:17",
  "txDateTime": "21/09/21 22:43:17",
  "txnDateType": 0,
  "txnMessage": "OPERACION ACEPTADA",
  "txnResult": 4,
  "txnType": 3,
  "typeTransaction": "000011"
}

Intents para Impresión

java
// PRINTER INTENTS IMPLEMENTATION
// para generar el recibo como imagen

JSONOBJECT jsonData = {
    "typeFace": "Droid Sans Mono",
    "advancePaper": true,
    "letterSpacing": 0,
    "grayLevel": 2,
    rows: [
        {
            "type": "IMAGE",
            "image": "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",
            "align": "CENTER"
        },
        {
            "type": "BR",
        },
        {
            "type": "TEXT",
            "text": "PRUEBA ",
            "rightText": "CONCEPTO",
            "align": "LEFT",
            "fontSize": 23,
            "isBold": false,
            "isUnderline": true,
            "isInverse": true
        },
    ]
}
// implementation
-----------------------------------------------------------------------------------------------------------
public class PrinterReceiver extends BroadcastReceiver {
    public static final String ACTION_REQUEST_PRINTER = "com.necomplus.tpv.device.print.request";
    public static final String ACTION_RESPONSE_PRINTER = "com.necomplus.tpv.device.print.response";
    public static final String ACTION_PARAM_PRINTER_JSON_DATA = "com.necomplus.tpv.device.print.params.DATA_VOUCHER";
    public static final String ACTION_PARAM_PRINTER_RESULT = "com.necomplus.tpv.device.print.params.RESULT";

    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent != null && intent.getExtras() != null) {
            String result = intent.getExtras().getInt(ACTION_PARAM_PRINTER_RESULT);
        }
    }
}
// Registrar broadcast
---------------------------------------------------------------------------------------------------------
PrinterReceiver printerReceiver = new PrinterReceiver();
registerReceiver(printerReceiver, new IntentFilter(printerReceiver.ACTION_RESPONSE_PRINTER));
// envio de la petición
Intent intent = new Intent(ACTION_REQUEST_PRINTER);
intent.putExtra(ACTION_PARAM_PRINTER_JSON_DATA, jsonData));
mContext.sendBroadcast(intent);
// tipos de elementos para enviar en la petición
// ---------------------------------------------------------------------------------------------
IMAGE
{
    "type": "IMAGE", // tipo de elemento Imagen
    "image": "BASE64", // datos de la imagen enviado en base64
    "align": "CENTER" // alineación de la imagen
},
TEXT
{
    "type": "TEXT", // tipo de elemento Texto
    "text": "ISO Payment API", // Texto principal a escribir
    "rightText": "text", // Texto que se alinea a la derecha del voucher
    "align": "LEFT", // Alineación del texto general
    "fontSize": 23, // tamaño fuente del texto
    "isBold": false, // bandera para indicar si el texto es resaltado
    "isUnderline": true, // bandera para indicar si el texto lleva subrayado
},
BARCODE
{
    "type": "BARCODE", // tipo de elemento código de barras
    "content": "12345670", // datos para el código de barras
    "height": 32, // altura del código de barras
    "margin": 5, // margen vertical
    "scale": 2, // escala de la imagen
    "format": "EAN_8", // formato del código de barras
    "align": "CENTER" // alineación del código de barras
},
QR
{
    "type": "QR",
    "content": "Copyright © 2020 by ITOS TECHNOLOGY S.L",
    "size": 64,
    "align": "CENTER"
},
SALTO DE LÍNEA
{
    "type": "BR", // tipo de elemento salto de linea
}

Código de Respuesta

  • Succes
  • -1001 Printer Print Failure
  • -1002 Failed to set the string in buffer
  • -1003 Failed to set the image in buffer
  • -1004 Printer Busy
  • -1005 Out of paper
  • -1006 Wrong Package
  • -1007 Printer Hardware Failure
  • -1008 OverTemperature
  • -1009 Printing has not finished
  • -1999 Exception error

Formatos de Código de barras

  • CODABAR
  • CODE_39
  • CODE_93
  • CODE_128
  • EAN_8
  • EAN_13
  • ITF
  • UPC_A
  • UPC_E

Servicios REST para impresión

POST

Printer

https://192.168.1.70:2001/v1/device/printer

Request JSON Object

Para imprimir textos, imágenes o QR codes se deben desarrollar los siguientes objetos JSON:

  • typeFace: Tipografía, los que soportamos son:
    • Monospace
    • Sans-Serif
    • Droid Sans
    • Droid Sans Mono
  • advancePaper: avance de papel
  • letterSpacing: Espacio en píxeles, el valor por defecto es 4.
  • grayLevel: Establece escala de grises, si no se setea el valor por defecto es 0. Los valores disponibles son:
    • 0: Lighter grayscale
    • 1: Medium grayscale
    • 2: Darker grayscale
  • rows: Lista de columnas a imprimir: Text, Image, Barcode o QR rows.

Response

  • resultCode: Result code value

Códigos de respuesta:

  • 0 Succes
  • -1001 Printer Print Failure
  • -1002 Failed to set the string in buffer
  • -1003 Failed to set the image in buffer
  • -1004 Printer Busy
  • -1005 Out of paper
  • -1006 Wrong Package
  • -1007 Printer Hardware Failure
  • -1008 OverTemperature
  • -1009 Printing has not finished
  • -1999 Exception error

Text Row

  • type: Row Type
  • text: text to print
  • align: Align type
  • fontSize: text font size
  • isBold: Flag to print the text with bold style
  • isUnderline: Flag to print the text with underline style

Text Row with right text

  • type: Row Type
  • text: text to print on the left
  • rightText: text to print on the right
  • align: Align type
  • fontSize: text font size
  • isBold: Flag to print the text with bold style
  • isUnderline: Flag to print the text with underline style

Image row

  • type: Row Type
  • align: Align type
  • image: Base64 encoded image

BarcodeRow

  • type: Row Type
  • align: Align type
  • content: content to include in the barcode
  • height: Height of the barcode
  • margin: print margin
  • scale: Scale
  • format: Barcode Format type

QRCodeRow

  • type: Row Type
  • align: Align type
  • content: content to include in the QR Code
  • size: Size of the QR generated

Row Types

Row types available:

  • TEXT: Text row
  • IMAGE: Image row
  • BARCODE: Barcode row
  • QR: QR code row

Align types

  • LEFT: Align item to the left
  • RIGHT: Align item to the right
  • CENTER: Align item to the center

BarcodeFormat types

  • CODABAR
  • CODE_39
  • CODE_93
  • CODE_128
  • EAN_8
  • EAN_13
  • ITF
  • UPC_A
  • UPC_E

Ejemplo

bash
curl --location --request POST 'https://192.168.1.70:3001/v1/device/printer' \
--header 'X-SOURCE;' \
--data-raw '{
    "typeFace": "Droid Sans Mono",
    "advancePaper": true,
    "letterSpacing": 0,
    "grayLevel": 2,
    "rows": [
        {
            "type": "IMAGE",
            "image": "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",
            "align": "CENTER"
        },
        {
            "type": "TEXT",
            "text": "ITOS TECHNOLOGY",
            "align": "CENTER",
            "fontSize": 32,
            "isBold": true,
            "isUnderline": false
        },
        {
            "type": "TEXT",
            "text": "ISO Payment API",
            "align": "LEFT",
            "fontSize": 23,
            "isBold": false,
            "isUnderline": true
        },
        {
            "type": "TEXT",
            "text": "Date & Time: ",
            "rightText":"{{current_timestamp}}",
            "fontSize": 23,
            "isBold": false,
            "isUnderline": false
        },
        {
            "type": "TEXT",
            "text": "Version: ",
            "rightText":"1.0-alpha",
            "fontSize": 23,
            "isBold": false,
            "isUnderline": false
        },
        {
            "type": "BARCODE",
            "content": "1234566666666",
            "height": 32,
            "margin": 5,
            "scale": 2,
            "format": "ITF",
            "align": "CENTER"
        },
        {
            "type": "QR",
            "content": "Copyright © 2020 by ITOS TECHNOLOGY S.L",
            "size": 64,
            "align": "CENTER"
        }
    ]
}'