owned this note
owned this note
Published
Linked with GitHub
# 如何用JS建構POS系統 - 發票機跟刷卡機 - 高逸宸(Logan)
{%hackmd @HWDC/BJOE4qInR %}
>#### 》[議程介紹](https://hwdc.ithome.com.tw/2024/session-page/3125)
>#### 》[填寫議程滿意度問卷|回饋建言給辛苦的講者](https://forms.gle/Zji1xkyDjvQWzbSZ6)
---
## Javascript POS
系統商支援線上電商
需求:原本有實體Pos 有多個通路 有線上跟線下
## 如何解決線下通路問題
POS(Point of Sale)
- 出單機
- 終端機
- 展示螢幕
- 收銀機
出單機?
大家都沒碰過XD
你機械系畢業你應該碰過吧
!?
原本是想用Browser 內建的 ctrl + p
遇到二聯三聯發票的瓶頸
# EPSON 出單機
USB
電源
RS232(早期的通訊埠):Pos 機設備經常使用的規格
--可能廠商不支援下列通訊方式--
LAN(新型):網路通訊 使用TCP IP ,適合長距離控制
藍芽(新型):移動 POS 設備可能會使用藍牙進行無線通信,適合需要靈活佈置的應用
# 通訊文本格式
- ECS/POS
EPSON制定給POS的碼(ASCII)
連結:https://download4.epson.biz/sec_pubs/pos/reference_en/escpos/commands.html
## Web Serial / USB API
瀏覽器會跳視窗提醒,導致每次列印都會跳提醒。
> 解決策略 Node.js USB
> https://developer.mozilla.org/en-US/docs/Web/API/Web_Serial_API

## Node.js USB
- escpos
- escpos-web
https://www.npmjs.com/package/escpos
https://github.com/node-escpos/driver
範例程式碼
``` js
const escpos = require("escpos");
escpos.USB = require("escpos-usb");
const device = new escpos.USB(0x04b8, 0x0e17);
const options = { encoding: "BIG5" };
const printer = new escpos.Printer(device, options);
device.open(function (error) {
printer
.font("a")
.align("ct")
.style("bu")
.size(1, 1)
.text("The quick brown fox jumps over the lazy dog")
.text("敏捷的棕色狐狸跳過懶狗")
.barcode("1234567", "EAN8")
.table(["One", "Two", "Three"])
.tableCustom([
{ text: "Left", align: "LEFT", width: 0.33, style: "B" },
{ text: "Center", align: "CENTER", width: 0.33 },
{ text: "Right", align: "RIGHT", width: 0.33 },
],
{ encoding: "cp857", size: [1, 1] } // Optional
)
.qrimage("https://github.com/song940/node-escpos", function (err) {
this.cut();
this.close();
});
});
```
- 客戶端防火牆的 port 打開
## 部署流程
由於需求要以線下為主,因此必須將開發的內容包裝成能夠 Local 執行
方案
1.
- JS POS Client click button
- Local Serrver
- pkg --output pos.exe
- Printer
2. Electron.js
## 刷卡機
- 確認通訊方式
- 確認通訊文本格式(文件跟信用卡機要)
- 機台還要跟信用卡中心要求開啟 POS 連線功能
乙太網路(需要跟銀行要求開啟)
電話孔(跟銀行通訊確認信用卡資訊的)
電源
Serial Port
USB to RS232 當時只是看到伽利略的名字很厲害就買了
> https://www.npmjs.com/package/serialport
連接 -> 寫入 -> 監聽
``` js
// 寫入
const sendMessage = (message, callback) => {
cardReader.write(message, (err) => {
if (err) {
console.log("Error on write: ", err.message);
res.status(500).send("Failed to write message");
cardReader.close();
return;
}
console.log("Message sent: ", message);
});
};
let completeData = "";
// 監聽
cardReader.on("data", (data) => {
completeData += Buffer.from(data).toString("utf8");
console.log("Data received: ", completeData);
if (completeData.length >= 400) {
cardReader.close((err) => {
if (err) {
console.log("Error on close: ", err.message);
}
console.log("Card reader closed");
callback(completeData);
});
}
});
cardReader.on("error", (err) => {
console.log("Error: ", err.message);
res.status(500).send("Card reader error");
// cardReader.close();
});
cardReader.on("close", () => {
console.log("Serial port closed");
});
```
要跟刷卡機的公司要資料格式
需要自己處理fileds製作欄位
信用卡中心要開啟POS連線功能,因為預設POS連線備鎖起來了
## 如果你要JS串連硬體設備
- 問客服 他們一定有技術客服
- 確認通訊方式和文本格式
- 選擇適合的一條路 新型的有wi-fi 和藍牙
## 優勢
- 跨平台支援
- 靈活性與擴充性
- 很多人做過惹,網路上很多文件教學函式庫等等可以用
- 低成本