@danidoble/webserial
Version:
WebSerial API wrapper
422 lines (421 loc) • 14.9 kB
JavaScript
import { K as p, D as c } from "./kernel-BRG-vva2.js";
import { s as i } from "./relay-C71zVBZv.js";
class l extends p {
__pinpax__ = {
server: "DEV",
businessId: null,
encryptionKey: null,
apiKey: null,
asyncResponses: {
voucher: null,
sale: null
},
waiting: {
voucher: !1,
sale: !1,
sale_init: "idle",
sale_login: "idle"
}
};
constructor({
filters: t = null,
config_port: e = {
baudRate: 115200,
dataBits: 8,
stopBits: 1,
parity: "none",
bufferSize: 32768,
flowControl: "none"
},
no_device: s = 1,
device_listen_on_channel: a = 1,
socket: n = !1
} = {
filters: null,
config_port: {
baudRate: 115200,
dataBits: 8,
stopBits: 1,
parity: "none",
bufferSize: 32768,
flowControl: "none"
},
no_device: 1,
device_listen_on_channel: 1,
socket: !1
}) {
if (super({ filters: t, config_port: e, no_device: s, device_listen_on_channel: a, socket: n }), this.__internal__.device.type = "pinpax", c.getCustom(this.typeDevice, s))
throw new Error(`Device ${this.typeDevice} ${s} already exists`);
this.__internal__.time.response_connection = 4e3, this.__internal__.time.response_general = 3e3, this.__internal__.serial.delay_first_connection = 1e3, this.__internal__.serial.response.replacer = "", this.__internal__.serial.response.limiter = `\r
`, this.#i(), c.add(this), this.getResponseAsString();
}
#i() {
const t = [
"buttons-status",
"init-app",
"connectMessage",
"voucher",
"info",
"keep-alive",
"reset-app",
"get-config",
"payment",
"error",
"refund",
"login"
];
for (const e of t)
this.serialRegisterAvailableListener(e);
}
set businessId(t) {
this.__pinpax__.businessId = t;
}
get businessId() {
return this.__pinpax__.businessId;
}
set encryptionKey(t) {
this.__pinpax__.encryptionKey = t;
}
get encryptionKey() {
return this.__pinpax__.encryptionKey;
}
set apiKey(t) {
this.__pinpax__.apiKey = t;
}
get apiKey() {
return this.__pinpax__.apiKey;
}
set server(t) {
this.__pinpax__.server = t;
}
get server() {
return this.__pinpax__.server;
}
serialMessage(t) {
let e = null;
try {
e = JSON.parse(t), e.request || (e.request = this.lastAction), e.name || (e.name = this.lastAction);
} catch (s) {
console.error("Error parsing response", s, t), this.dispatch("serial:message", t);
return;
}
switch (e.response) {
case "INIT":
this.dispatch("init", { name: "INIT", request: this.lastAction, status: "ok" }), this.__pinpax__.waiting.sale_init === "waiting" && (this.__pinpax__.waiting.sale_init = "received");
break;
case "INITAPP":
this.dispatch("init-app", { name: "INITAPP", request: this.lastAction, status: "started" }), this.__pinpax__.waiting.sale_init === "waiting" ? this.__pinpax__.waiting.sale_init = "received" : this.#n().then(() => {
});
break;
case "CONNECT":
this.dispatch("connectMessage", { name: "CONNECT", request: this.lastAction, status: "connected" }), this.#r().then(() => {
});
break;
case "LOGIN":
e.name || (e.name = "LOGIN"), this.__pinpax__.waiting.sale_login === "waiting" && (this.__pinpax__.waiting.sale_login = "received"), this.dispatch("login", e);
break;
case "LASTVOUCHER":
e.name || (e.name = "LASTVOUCHER"), this.dispatch("voucher", e), this.__pinpax__.waiting.voucher && (this.__pinpax__.asyncResponses.voucher = e, this.__pinpax__.waiting.voucher = !1);
break;
case "DEVICEINFO":
e.name || (e.name = "DEVICEINFO"), this.dispatch("info", e);
break;
case "KEEPALIVE":
this.dispatch("keep-alive", { name: "KEEPALIVE", request: this.lastAction, status: "alive" });
break;
case "RESETAPP":
this.dispatch("reset-app", { name: "RESETAPP", request: this.lastAction, status: "accepted" });
break;
case "GETCONFIG":
e.name || (e.name = "GETCONFIG"), this.dispatch("get-config", e);
break;
case "HIDEBUTTONS":
this.dispatch("buttons-status", { name: "HIDEBUTTONS", request: this.lastAction, hidden: !0 });
break;
case "SHOWBUTTONS":
this.dispatch("buttons-status", { name: "SHOWBUTTONS", request: this.lastAction, hidden: !1 });
break;
case "PAYMENT_PROCESS":
e.name || (e.name = "PAYMENT_PROCESS"), this.dispatch("payment", {
name: "PAYMENT_PROCESS",
request: this.lastAction,
status: "starting",
amount: e.amount,
reference: e.referecence
});
break;
case "INSERT_CARD":
this.dispatch("payment", { name: "INSERT_CARD", request: this.lastAction, status: "insert card" });
break;
case "CARD_DATA":
e.name || (e.name = "CARD_DATA"), this.dispatch("payment", {
name: "CARD_DATA",
request: this.lastAction,
status: "card data",
amount: e.amount,
cardHolderName: e.cardHolderName,
ccMark: e.ccMark,
ccType: e.ccType,
currency: e.currency,
maskedPan: e.maskedPan,
readingType: e.readingType
});
break;
case "MERCHANT":
e.name || (e.name = "MERCHANT"), this.dispatch("payment", {
request: this.lastAction,
status: "merchant",
afiliation: e.afiliation,
alias: e.alias,
amountCashBackCommission: e.amountCashBackCommission,
currency: e.currency,
description: e.description,
hasCashBack: e.hasCashBack,
limitCashBackAmount: e.limitCashBackAmount,
merchant: e.merchant,
months: e.months,
name: e.name
});
break;
case "TRANSACTION_RESULT":
e.name || (e.name = "TRANSACTION_RESULT"), this.#o({
status: "result",
approved: e.approved,
acquirer: e.acquirer,
address: e.address,
amount: e.amount,
amountCashback: e.amountCashback,
appIDLabel: e.appIDLabel,
appId: e.appId,
arqc: e.arqc,
auth: e.auth,
ccBin: e.ccBin,
ccExpirationDate: e.ccExpirationDate,
ccName: e.ccName,
ccNumber: e.ccNumber,
ccType: e.ccType,
comissionCashback: e.comissionCashback,
currency: e.currency,
date: e.date,
errorCode: e.errorCode,
errorDescription: e.errorDescription,
folio: e.folio,
id: e.id,
merchantName: e.merchantName,
msiLabel: e.msiLabel,
operation: e.operation,
pin: e.pin,
qps: e.qps,
reference: e.reference,
response: e.response,
source: e.source,
sourceLabel: e.sourceLabel,
time: e.time
});
break;
case "ERROR":
e.name || (e.name = "ERROR"), this.__pinpax__.waiting.sale && (this.__pinpax__.asyncResponses.sale = {
status: "error",
approved: !1,
response: e
}), this.dispatch("error", { name: "ERROR", request: this.lastAction, status: "error", response: e }), this.dispatch("payment", { name: "ERROR", request: this.lastAction, status: "error", response: e });
break;
case "CHECKINTERNET":
this.dispatch("network", {
name: "CHECKINTERNET",
request: this.lastAction,
hasInternet: e.internet,
quality: e.quality
});
break;
case "REFUND":
this.dispatch("refund", { name: "ERROR", request: this.lastAction, status: "refund", response: e });
break;
}
this.dispatch("serial:message", e);
}
serialSetConnectionConstant() {
return i.connection();
}
softReload() {
super.softReload(), this.__pinpax__.waiting.sale = !1, this.__pinpax__.waiting.voucher = !1, this.__pinpax__.asyncResponses.sale = null, this.__pinpax__.asyncResponses.voucher = null;
}
async sendCustomCode(t = {}) {
if (typeof t != "object") throw new Error("Invalid object");
if (t.constructor !== Object) throw new Error("Invalid object");
if (Object.keys(t).length === 0) throw new Error("Empty object");
if (t.action === void 0 || t.action === null) throw new Error("Invalid object add action");
const e = JSON.stringify(t), s = this.parseStringToBytes(e, `\r
`);
await this.appendToQueue(this.stringArrayToUint8Array(s), "custom");
}
async connectMessage() {
await this.appendToQueue(i.connect(), "connect:message");
}
async #e() {
if (this.isDisconnected) throw new Error("Device is disconnected");
return this.queue.length === 0 ? !0 : new Promise((t) => {
const e = setInterval(() => {
this.queue.length === 0 && (clearInterval(e), t(!0));
}, 500);
});
}
async #t({ type: t = "production" } = {}) {
const e = i.readQR({ type: t });
return await this.appendToQueue(e, "read-qr");
}
async #s() {
await this.appendToQueue(i.forceHide(), "force-hide");
}
async #a() {
await this.appendToQueue(i.forceShow(), "force-show");
}
async #n() {
await this.connectMessage();
}
async #r() {
await this.hideButtons();
}
#o(t) {
this.dispatch("payment", t), this.__pinpax__.waiting.sale && (this.__pinpax__.asyncResponses.sale = t);
}
cancelSaleRequestInProcess() {
this.__pinpax__.waiting.sale && (this.__pinpax__.asyncResponses.sale = {
status: "error",
approved: !1,
response: {}
});
}
async #c() {
return new Promise((t, e) => {
const s = setTimeout(() => {
this.__pinpax__.waiting.sale_login === "waiting" && (this.__pinpax__.waiting.sale_login = "timeout", e(new Error("Login timeout")));
}, 1e4), a = setInterval(() => {
this.__pinpax__.waiting.sale_login === "received" && (clearTimeout(s), clearInterval(a), t(!0));
}, 100);
});
}
async #p() {
return new Promise((t, e) => {
const s = setTimeout(() => {
this.__pinpax__.waiting.sale_init === "waiting" && (this.__pinpax__.waiting.sale_init = "timeout", e(new Error("Init timeout")));
}, 1e4), a = setInterval(() => {
this.__pinpax__.waiting.sale_init === "received" && (clearTimeout(s), clearInterval(a), t(!0));
}, 100);
});
}
async makeSale({
amount: t = 0,
reference: e = null
} = {
amount: 0,
reference: null
}) {
if (this.isDisconnected) throw new Error("Device is disconnected");
if (this.__pinpax__.waiting.sale) throw new Error("Already waiting for sale response");
const s = i.makeSale({ amount: t, reference: e });
this.__pinpax__.waiting.sale = !0, this.__pinpax__.asyncResponses.sale = null, this.queue.length > 0 && await this.#e();
let a = !1;
try {
this.__pinpax__.waiting.sale_login = "waiting", await this.login(), await this.#c(), this.__pinpax__.waiting.sale_login = "idle", this.__pinpax__.waiting.sale_init = "waiting", await this.init(), await this.#p(), this.__pinpax__.waiting.sale_init = "idle";
} catch (n) {
a = !0, this.__pinpax__.waiting.sale_login = "idle", this.__pinpax__.waiting.sale_init = "idle", this.__pinpax__.waiting.sale = !1, this.dispatch("error", {
name: "ERROR",
request: this.lastAction,
status: "error",
response: "Error during login/init before sale",
error: n
});
}
return a ? !1 : (await this.appendToQueue(s, "make-sale"), new Promise((n) => {
const r = setInterval(() => {
if (this.__pinpax__.asyncResponses.sale) {
const o = this.__pinpax__.asyncResponses.sale;
this.__pinpax__.asyncResponses.sale = null, this.__pinpax__.waiting.sale = !1, clearInterval(r), n(o.approved);
}
}, 100);
}));
}
async getVoucher({ folio: t = null } = {}) {
if (this.isDisconnected) throw new Error("Device is disconnected");
if (this.__pinpax__.waiting.voucher) throw new Error("Already waiting for voucher");
if (!t) throw new Error("Folio is required");
this.__pinpax__.waiting.voucher = !0, this.__pinpax__.asyncResponses.voucher = null;
const e = i.getVoucher({ folio: t });
return this.queue.length > 0 && await this.#e(), await this.appendToQueue(e, "get-voucher"), new Promise((s, a) => {
const n = setTimeout(() => {
this.__pinpax__.waiting.voucher = !1, a("Timeout");
}, 1e4), r = setInterval(() => {
if (this.__pinpax__.asyncResponses.voucher) {
const o = this.__pinpax__.asyncResponses.voucher;
this.__pinpax__.asyncResponses.voucher = null, this.__pinpax__.waiting.voucher = !1, clearInterval(r), clearTimeout(n), s(o.voucher);
}
}, 100);
});
}
async info() {
await this.appendToQueue(i.info(), "info");
}
async keepAlive() {
await this.appendToQueue(i.keepAlive(), "keep-alive");
}
async restartApp() {
await this.appendToQueue(i.restartApp(), "reset-app");
}
async getConfig() {
return await this.appendToQueue(i.getConfig(), "get-config");
}
async hideButtons() {
return await this.appendToQueue(i.hideButtons(), "hide-buttons"), await this.#s();
}
async showButtons() {
return await this.appendToQueue(i.showButtons(), "show-buttons"), await this.#a();
}
async demo() {
return console.warn("RUNNING DEMO APP, BE CAREFUL"), await this.appendToQueue(i.demo(), "demo");
}
async refund({ amount: t = 0, folio: e = null, auth: s = null } = {}) {
return await this.appendToQueue(
i.refund({
amount: t,
folio: e,
auth: s
}),
"refund"
);
}
async readProductionQR() {
return await this.#t({ type: "production" });
}
async readQualityAssuranceQR() {
return this.#t({ type: "QA" });
}
async exit() {
return await this.appendToQueue(i.exit(), "exit-app");
}
async init() {
await this.appendToQueue(i.init(), "init-app");
}
async login() {
if (!this.apiKey || !this.businessId || !this.encryptionKey || !this.server)
throw new Error("Invalid data to login check apiKey, businessId, encryptionKey, server");
const t = JSON.stringify({
action: "LOGIN_MIT",
server: this.__pinpax__.server,
business_id: this.__pinpax__.businessId,
encryption_key: this.__pinpax__.encryptionKey,
api_key: this.__pinpax__.apiKey
}), e = this.parseStringToBytes(t, `\r
`);
await this.appendToQueue(e, "login");
}
async stop() {
await this.appendToQueue(i.stop(), "stop");
}
async verifyNetwork() {
await this.appendToQueue(i.verifyNetwork(), "verify-network");
}
}
export {
l as PinPax
};