Skip to main content

Listeners

Here is the angular stone of Webserial, the listeners. With them, you can listen to the events that the device emits.

How to listen to an event

When you create a new instance of the PinPax class, you can listen to the events that the device emits.

pinPax.on("serial:message", (data) => {
console.log(data);
});

Each event has a different data structure, so you need to check the data structure for each event.

Note

All events will return SerialEvent as shown in the image below.

Locale Dropdown

Get all available listeners

For boardroid class there events that you can listen to, of course only listen to the events that you need.

Object

To get all the available listeners, you can use the availableListeners property.

console.log(pinPax.availableListeners);

The result will be an object with the available listeners, and if you are listen each event

[
{
"type": "serial:connected",
"listening": false
},
{
"type": "serial:connecting",
"listening": false
},
{
"type": "serial:disconnected",
"listening": false
},
{
"type": "serial:error",
"listening": false
},
{
"type": "serial:lost",
"listening": false
},
{
"type": "serial:message",
"listening": false
},
{
"type": "serial:need-permission",
"listening": false
},
{
"type": "serial:reconnect",
"listening": false
},
{
"type": "serial:sent",
"listening": false
},
{
"type": "serial:soft-reload",
"listening": false
},
{
"type": "serial:timeout",
"listening": false
},
{
"type": "serial:unsupported",
"listening": false
},
{
"type": "debug",
"listening": false
},
{
"type": "unknown",
"listening": false
},
{
"type": "buttons-status",
"listening": false
},
{
"type": "connectMessage",
"listening": false
},
{
"type": "get-config",
"listening": false
},
{
"type": "info",
"listening": false
},
{
"type": "init-app",
"listening": false
},
{
"type": "keep-alive",
"listening": false
},
{
"type": "login",
"listening": false
},
{
"type": "reset-app",
"listening": false
},
{
"type": "voucher",
"listening": false
},
{
"type": "payment",
"listening": false
},
{
"type": "error",
"listening": false
}
]

Array

But sometimes you don't want the object you want only an array with the available listeners, you can do this:

pinPax.availableListeners.map((el) => el.type);

And one more time here is the result

[
"serial:connected",
"serial:connecting",
"serial:disconnected",
"serial:error",
"serial:lost",
"serial:message",
"serial:need-permission",
"serial:reconnect",
"serial:sent",
"serial:soft-reload",
"serial:timeout",
"serial:unsupported",
"unknown",
"debug",
"buttons-status",
"connectMessage",
"get-config",
"info",
"init-app",
"keep-alive",
"login",
"reset-app",
"voucher",
"payment",
"error"
]

Debug

Warning

Don't use this event in production, only for debug. The amount of data can be huge and slow down the application.

If you want to know all events dispatched, you need to enable the debug mode.

pinPax.__debug__ = true; // enable debug mode
Note

This event is only dispatched when you enable the debug mode only.

So then you can listen to the debug event.

pinPax.on("debug", (event) => {
// event.detail = {
// type: 'event',
// data: 'data of event'
// }
console.log(event.detail);
});

Serial connected

When the serial is connected, this event is dispatched.

pinPax.on("serial:connected", (event) => {
console.log(event.detail);
});

Serial connecting

When the serial is trying to connect, this event is dispatched.

pinPax.on("serial:connecting", (event) => {
// without data
});

Serial disconnected

When the serial is disconnected, this event is dispatched.

pinPax.on("serial:disconnected", (event) => {
console.log(event.detail);
});

Serial error

When the serial has an error, this event is dispatched.

pinPax.on("serial:error", (event) => {
console.log(event.detail);
});

Serial lost

When the serial is lost, this event is dispatched.

pinPax.on("serial:lost", (event) => {
console.log(event.detail);
});

Serial message

When the serial receives a message, this event is dispatched.

Note

This event is dispatched along others events that send event of machine, so this event is only for debug.

pinPax.on("serial:message", (event) => {
console.log(event.detail);
});

Serial need permission

When the serial needs permission, this event is dispatched. This occurs because user interaction is needed to request the serial.

Recommendation: Use a button or a screen to show what is happening.

pinPax.on("serial:need-permission", (event) => {
console.log(event.detail);
});

Serial reconnect

When the serial is trying to reconnect, this event is dispatched.

pinPax.on("serial:reconnect", (event) => {
// without data
});

Serial sent

When the serial sends a message to machine, this event is dispatched.

Note

This event is more oriented for debug.

pinPax.on("serial:sent", (event) => {
console.log(event.detail);
});
structure event.detail
{
"event": "string",
"bytes": []
}

Serial soft reload

When the serial is trying to soft reload, this event is dispatched.

pinPax.on("serial:soft-reload", (event) => {
// without data
});

Serial timeout

When the serial has a timeout, this event is dispatched.

pinPax.on("serial:timeout", (event) => {
console.log(event.detail);
});

Serial unsupported

When the serial is unsupported, this event is dispatched.

pinPax.on("serial:unsupported", (event) => {
console.log(event.detail);
});

Unknown

This event is dispatched?.

pinPax.on("unknown", (event) => {
console.log(event.detail);
});

Buttons status

When you request hide or show buttons this event will be dispatched when device return answer

pinPax.on("buttons-status", (event) => {
const areHidden = event.detail.hidden; // boolean
console.log(areHidden);
});

Connect Message (PAX)

When You connect with device or request with connectMessage()

pinPax.on("connectMessage", (event) => {
console.log(event.detail.status); // connected
});

Get Configuration

Get the current configuration of device

pinPax.on("get-config", (event) => {
const { buttons, connect, last_error, login, response, server } =
event.detail;
const connected = connect === "true";
const logged = login === "true";

console.log({
connected,
logged,
buttons, // hidden or visible
last_error,
// response,
server,
});
});

Information

Get information of device

pinPax.on("info", (event) => {
/*const example = {
response: "DEVICEINFO",
firmware_version: "01.15",
serial_number: "XXXXXXXXXX",
battery_level: "0.0",
model_device: "0.0",
mark_device: "0.0",
is_on_charging: "0.0",
has_printer: "0.0",
};*/
console.log(event.detail);
});

Init App

When the app init dispatch an event that start a secuence

  1. init
  2. connect
  3. login
  4. hide buttons
Warning

This only happens if device is already connected to machine.

i.e. when resetApp

pinPax.on("init-app", (event) => {
console.log(event.detail.status); // started
});

Keep Alive

This message is fired when you execute the method keepAlive

pinPax.on("keep-alive", (event) => {
console.log(event.detail.status); // alive
});

login

pinPax.on("login", (event) => {
/*const example = {
response: "LOGIN",
server: null,
bussinesId: "XXXXXX",
api_key: "XXXXXXXXXXXXXXXXXXXXXXXXXX",
encription_key: "XXXXXXXXXXXXXXXXXXXXXXXXXX",
partnerId: null,
preferences: "null",
functions: "null",
currencies: "null",
surTax: null,
telemetryParams: "null",
companyName: null,
companyCode: null,
branchName: null,
branchCode: null,
adminUserCode: null,
activationCode: null,
products: "null",
amount: null,
reference: null,
currency: null,
userTransaction: null,
cardHolderName: null,
maskedPan: null,
ccType: null,
ccMark: null,
readingType: null,
};*/
console.log(event.detail);
});

Reset App

if you need reset the application run resetApp() then if device accepted the command will fire the event below

pinPax.on("reset-app", (event) => {
console.log(event.detail.status); // accepted
});

Get voucher

when you need to get the last purchase voucher execute getVoucher() That function is async and you can wait for the response as described on API section. But also you can listen the event as below

pinPax.on("voucher", (event) => {
console.log(event.detail.voucher);
});

Payment

When you make a sale (purchase) you need listen payment to handle responses and if was approved or not

pinPax.on("payment", (event) => {
// event.detail.status can be:
// * starting
// * insert card
// * card data
// * merchant
// * result
// * error

switch (event.detail.status) {
case "starting":
console.log(
event.detail.response.amount,
event.detail.response.reference
);
break;
case "insert card":
console.log("notify user to insert card");
break;
case "card data":
console.log(
({
amount,
currency,
cardHolderName,
maskedPan,
ccType,
ccMark,
readingType,
} = event.detail.response)
);
break;
case "merchant":
console.log(
({
name,
merchant,
currency,
afiliation,
hasCashBack,
limitCashBackAmount,
amountCashBackCommission,
description,
alias,
months,
} = event.detail.response)
);
break;
case "result":
console.log(
({
id,
operation,
reference,
amount,
approved,
currency,
folio,
auth,
time,
date,
merchantName,
address,
qps,
appId,
appIDLabel,
ccType,
ccName,
ccNumber,
ccExpirationDate,
ccBin,
pin,
msiLabel,
acquirer,
arqc,
errorCode,
errorDescription,
comissionCashback,
amountCashback,
source,
sourceLabel,
} = event.detail.response)
);
if (event.detail.response.approved === true) {
// ... oh yeah
} else {
// ... oh noooh~
}
break;
case "error":
if (
typeof event.detail.response.error !== "undefined" &&
event.detail.response.error === "06"
) {
// timeout
console.log(event.detail.response.description);
} else if (
typeof event.detail.response.description !== "undefined" &&
event.detail.response.description.includes("Ya has realizado el") &&
event.detail.response.description.includes(
"permitido para esta tarjeta."
)
){
console.log('The card max attempts was reached today');
}
break;
}

// and event.detail.response can be a lot of thing so just listen for it
console.log(event.detail.status, event.detail.response);
});

Error

You need to listen this event to handle all errors not related to payment

pinPax.on("error", (event) => {
console.log(event.detail.response);
});