# 青蛙小指令接入文档
# 一、青蛙小指令
青蛙小指令是实现“青蛙设备”和“收银设备”之间的互联互通的基础能力,实现“收银设备”与“青蛙设备”互相下发指令、传输数据。
青蛙小指令支持“青蛙基础版”、“青蛙Pro版”两款设备:

# 二、青蛙小指令功能详情
青蛙小指令由三部分构成:青蛙小指令SDK、数据线(及驱动)、青蛙小指令通信协议
# 1 青蛙小指令SDK
青蛙小指令SDK提供“青蛙设备”和 “收银设备”的底层通信能力,“收银设备软件”使用SDK提供的接口,可以方便快捷的实现与“青蛙设备”的双向收、发数据。(当前SDK本版本仅支持windows系统)
# 1.1 Windows端主要结构体说明:
WxposPort:串口端口列表类,这里列出Windows端所有可用的串口。(收银App需要选择对应的端口进行连接)
typedef struct _WxposPort {
char *comPortBuf; //端口号字符串,如COM1, COM2
char *portDescription; //端口描述信息
} WxposPort;
Pos机接收青蛙设备发过来的数据的回调函数
/**
* @brief 回调函数接口的定义
* @param int functionId: 青蛙设备端发给收银机的数据功能ID。具体ID的定义请参考协议文档
* @param const char* pData: 青蛙设备端发给收银机的数据,函数返回后,sdk中会释放pData内存,如需使用此数据,请拷贝保存。
* @param const void* pContext: 收银机自定义的在回调函数需用到的数据,在设置回调接口时由收银机端传入,sdk回调时直接传回
**/
typedef void(__stdcall *RecvCallback) (int functionId, const char* pData, void* pContext);
# 1.2 初始化
# 时序图:
业务逻辑
A ->> B: wxposGlobalDestroy() B -->> A: 释放成功
注:
wxposGlobalInit在程序执行初始化时只需要调用一次即可。
wxposGlobalDestroy应该在程序退出前调用,以释放端口和线程资源。
# Windows端主要方法说明:
/**
* @brief 获取串口端口列表
* @param WxposPort** pPortList: 获取到的串口端口列表
* @param uint32_t* pPortCount: 获取到的串口端口个数
* @return 0: 获取成功, < 0: 获取失败
**/
WXPAYFACE_POS_DECL int32_t __stdcall wxposGetPortList(WxposPort** pPortList, uint32_t* pPortCount);
/**
* @brief 释放串口端口列表的资源
* @param WxposPort** pPortList: 获取到的串口端口列表
**/
WXPAYFACE_POS_DECL void __stdcall wxposReleasePortList(WxposPort** pPortList);
/**
* @brief 全局初始化,启动内部服务
* @notice 非阻塞
* @param const char* comPort: 串口端口号
* @return 0: 启动成功, < 0: 启动失败
**/
WXPAYFACE_POS_DECL int32_t __stdcall wxposGlobalInit(const char* comPort);
/**
* @brief 全局停止,停止内部服务
* @notice 非阻塞
* @return 0: 停止成功, < 0: 停止失败
**/
WXPAYFACE_POS_DECL int32_t __stdcall wxposGlobalDestroy();
/**
* @brief 设置青蛙发送给收银机的数据接收回调函数
* @param RecvCallBack pCallback: 回调函数
* @param void* pContext: 收银机希望在回调函数中使用的自定义数据,sdk回调时直接传回。如不需要可传入空
**/
WXPAYFACE_POS_DECL void __stdcall wxposSetRecvCallback(RecvCallback pCallback, void* pContext);
# 1.3 POS机与青蛙间发送、接收数据
# 时序图
%% 人脸会员时序图
sequenceDiagram
participant A as App(青蛙)
participant B as SDK(青蛙)
participant C as SDK(收银机)
participant D as App(收银机)
activate A
Note right of D: POS发送数据给青蛙
D ->> C: wxposSend(functionId, pData)
activate D
C ->> B: 物理链路数据传输
B ->> A: 数据传输给业务层处理
A ->> A: 业务逻辑处理
Note left of A:青蛙发送数据给POS
A ->> B: wxposSend(functionId, pData)
B ->> C: 物理链路数据传输
C ->> D: 回调RecvCallback
D ->> D: 业务逻辑处理
# Windows端主要方法说明:
/**
* @brief 收银机发送命令和数据给青蛙设备,并通过回调接口接收到青蛙设备的回应
* @notice 非阻塞
* @param uint32_t functionId: 发送给青蛙设备的功能ID,具体ID定义参考协议文档
* @param const char* pData: 自定义数据,如果没有可填空
* @return 0: 成功, < 0: 失败。此接口是异步发送,这里是将数据放入发送缓冲区,
* 真正发送时如失败将通过回调接口通知POS APP
**/
WXPAYFACE_POS_DECL int32_t __stdcall wxposSend(uint32_t functionId, const char* pData);
/**
* @brief 回调函数接口的定义
* @param int functionId: 青蛙设备端发给收银机的数据功能ID。具体ID的定义请参考开发文档中的协议描述
* @param const char* pData: 青蛙设备端发给收银机的数据,函数返回后,sdk中会释放pData内存,如需使用此数据,请拷贝保存。
* @param const void* pContext: 收银机自定义的在回调函数需用到的数据,在设置回调接口时由收银机端传入,sdk回调时直接传回
**/
typedef void(__stdcall *RecvCallback) (int functionId, const char* pData, void* pContext);
# 1.4 POS机与青蛙的连接状态回调
# 使用场景
如果POS机与青蛙连接状态不正常,SDK APP发送数据失败后,会通过RecvCallback回调通知POS APP,POS APP可以提醒POS机的操作员对线缆连接进行检查等。
功能 | functionId | data | 说明 |
---|---|---|---|
数据发送错误 | 9999 | 无 | POS数据发送失败,可以提醒检测线缆 |
# 1.5 错误码描述
错误码 | 值 | 描述 |
---|---|---|
WXPOS_ERR_OPERATION_FAIL | -1 | 操作失败 (初始化/请求/响应/设置失败等) |
WXPOS_ERR_TIMEOUT | -2 | 运行超时 |
WXPOS_ERR_RUNTIME_ERROR | -3 | 运行时错误 |
WXPOS_ERR_PARAMETER_ERROR | -4 | 参数错误 |
WXPOS_ERR_LINK_NOT_ALIVE | -5 | 连接处于断开/失败状态 |
WXPOS_ERR_NOT_INITED | -10 | 未初始化错误 |
WXPOS_ERR_REPEATED_INIT | -11 | 重复初始化错误 |
WXPOS_ERR_PAYLOAD_OVERFLOW | -12 | 数据包超出限制(请求大小限制暂定为10K) |
WXPOS_ERR_UNKNOWN | -20 | 未知错误 |
# 1.6 其他说明
# 线程安全性
# 普通版本(仅支持Win 7以上)
除非有特殊说明,SDK提供的接口均为线程安全的(thread-safe),即可以在多个线程里同时调用某一个接口。
# Win XP兼容版本
由于在Win XP上的实现机制,wxposGlobalInit
不是线程安全的,请勿在多个线程中同时调用该函数,其余接口仍是线程安全的(thread-safe)
# DLL说明
LibWxpayFacePos.dll采用stdcall调用约定,导出函数命名规范为undecorated,比如wxposGlobalInit在dll中的导出函数名即为wxposGlobalInit。
# 2 数据线(及驱动)
####2.1 青蛙基础版
青蛙基础版接入青蛙小指令需要更换原配数据线 购买链接 更换原配数据线后,需要安装驱动 下载链接
####2.2 青蛙Pro版 青蛙Pro版无需换线即可接入青蛙小指令
# 3 青蛙小指令通信协议
青蛙小指令通信协议分为“POS->青蛙”和“青蛙->POS”两方通信协议。
# 3.1 “POS->青蛙”通信协议
“POS->青蛙”通信协议的指令分为“基础指令”和“开放指令”,基础指令为青蛙app可识别并执行的指令,为基础功能服务,如支付、会员等;开放指令为商户小程序的通信指令,可按需扩展。
功能 | 类别 | functionId | data | 说明 |
---|---|---|---|---|
微信支付指令 | 基础指令 | 1001 | json字符串,{cost:8,totalfee:10,member_discount:2}:消费8分钱,原价10分钱,会员优惠2分钱,单位为分 | 请求青蛙发回微信人脸付款码; |
其他支付结果指令 | 基础指令 | 1002 | json字符串,{pay_result:SUCCESS/FAIL},填充支付结果SUCCESS/FAIL | 在使用会员余额支付、现金支付等其它非微信支付支付方式后,使用该指令通知青蛙设备当前订单已经支付,支付结果为成功或者失败,青蛙设备将根据结果播放tts提醒用户 |
会员指令 | 基础指令 | 1003 | 空 | 请求青蛙发回卡包会员码 |
关闭指令 | 基础指令 | 1004 | 空 | 结束青蛙设备当前流程回到首页 |
小程序指令 | 开放指令 | 2001 | json字符串,请查看3.1.1小程序细则 | 可通过该指令将自定义数据传输给小程序 |
# 3.2 青蛙->POS协议
功能 | functionId | data | 说明 |
---|---|---|---|
付款码指令 | 1001 | json字符串,{code:123456789,type:WX_PAY_CODE} | 青蛙APP主动给POS机发送付款码操作,如用户扫码支付时青蛙主动发送二维码给POS机,type为WX_PAY_CODE时表示微信付款码,type为OTHER_PAY_CODE时表示非微信付款码 |
会员码指令 | 1003 | json字符串,{code:987654321}:卡包会员码为987654321 | 青蛙执行完会员指令,将会员码返回给POS机 |
小程序指令 | 2001 | 字符串 | 小程序可通过该指令将数据传输给商户POS机,data由商户自定义格式与内容 |
错误 | 4004 | json字符串,{functionId:1001,errorCode:20001,errorMessage:小程序无法处理该指令} | 返回错误信息给商户POS机 |
# 3.3 青蛙小指令详述
# 3.3.1 青蛙支付流程
(1) 青蛙app可在首页和支付结果页响应微信支付指令(1001),微信支付指令必填字段为:订单金额(如:cost:8),选填字段为:订单原价(如:totalfee:10),会员优惠(如:member_discount:2),订单原价和会员优惠必须一起传,缺一不可。
(2) 青蛙app在接收微信支付指令(1001)后,且在用户刷脸成功确认支付后,青蛙app将返回付款码指令(1001)。

# 3.3.2 青蛙卡包会员流程
青蛙app在配置卡包会员后,进入卡包会员模式
(1) 青蛙卡包会员可在首页、刷脸中和支付结果页响应会员指令(1003),用户刷脸后将自动返回会员码指令(1003)
(2) 青蛙卡包会员可在会员权益页响应会员指令(1003),重复返回会员码指令(1003)
(3) 青蛙卡包会员可在会员权益页响应微信支付指令(1001),用户确认支付后返回付款码指令(1001)

(4) 青蛙卡包会员可在首页和支付结果页响应微信支付指令(1001),用户刷脸且确认支付后返回付款码指令(1001)

# 3.3.3 小程序指令细则
小程序指令协议具体格式为JSON格式,协议功能分为两大类:
- 启动小程序
- 向正在运行的小程序透传信息
# 3.3.3.1 启动小程序
顾名思义,将会向微信人脸支付SDK发送小程序启动指令,为了保证指令的灵活度,和小程序的可调整性,协议中不包括具体的小程序相关信息,取而代之的是小程序相关的场景名称,或是启动键位,本质上,这里的指令只是对青蛙小程序现有启动场景的一种模拟。
所以这要求接入者在接入前做到两件事情:
(1) 商户开发者应在青蛙商户平台上,配置好对应的小程序相关信息(i.e.,AppId,启动路径等),同时关联到对应的机器 (2) 确保这些小程序能够正常的在对应的机器上面运行
在发送指令前,商户开发者需要明确要启动的小程序,是根据场景启动的,还是根据按键启动的。
基本content内容如下:
{
"cmdType": 0,
"launchDetail": {
"simulatedLaunchType": 0,
"sceneType": "场景名称",
"keyCmd": "按键名称"
}
}
内容详情:
参数 | 必填 | 类型 | 说明 |
---|---|---|---|
cmdType | 是 | Integer | 协议类型,{0:代表启动小程序指令;1:代表小程序透传信息} |
launchDetail | 是 | JsonObject | 启动详情结构体 |
simulatedLaunchType | 是 | Integer | 想要模拟的启动类型,{0:代表根据场景启动;1:代表根据按键启动} |
sceneType | 在simulatedLaunchType=0时必填 | String | 场景名称,目前有{R:结果页小程序;M:会员小程序;F:首页小程序} |
keyCmd | 在simulatedLaunchType=1时必填 | String | 按键名称,和商户平台上面定义的小程序启动物理按键一致即可 |
# 3.3.3.2 小程序透传信息
在某些场景下,商户可能希望通过双向通信指令,直接向在机具上运行的小程序发送指令/消息,那么可以使用如下的content结果进行消息的发送:
{
"cmdType": 1,
"msgDetail": "需要传递的信息"
}
内容详情:
参数 | 必填 | 类型 | 说明 |
---|---|---|---|
cmdType | 是 | Integer | 协议类型,{0:代表启动小程序指令;1:代表小程序透传信息} |
msgDetail | 是 | String | 消息/指令详情 |
# 3.3.3.3. 小程序侧接收透传信息
在商户侧利用收银机向小程序发送了指令/消息后,小程序侧可以通过如下的JsEvent,进行消息的接收:
//监听青蛙小指令消息
wxfaceapp.onSerialMsgEvent(function (res) {
console.log("onSerialMsgEvent msgContent = " + res.msgContent)
})
内容详情:
参数 | 必填 | 类型 | 说明 |
---|---|---|---|
msgContent | 是 | String | 收银机通过小指令传入的消息 |
# 3.3.3.4. 小程序侧发送信息
在小程序侧,也可以通过小指令,直接向收银机发送指令/消息,小程序侧可以通过如下的JsApi,进行消息的发送
//发送青蛙小指令消息
wxfaceapp.sendSerialMsg({
msgContent: "hello! this is the msg from mini program",
success(res) {
console.log("[sendSerialMsg] suc : " + res.reply)
},
fail(res) {
console.log("[sendSerialMsg] failed : "+res.reply)
}
})
内容详情:
参数 | 必填 | 类型 | 说明 |
---|---|---|---|
msgContent | 是 | String | 小程序想要通过小指令传入收银机的指令/消息 |