旺立方接入指南

1.概述

旺立方定位于支撑中小商户外卖接单业务场景,关于旺立方的的介绍请看这里。业务场景的定位决定了旺立方接入旺POS体系的独特性,此文档主要介绍旺立方使用者如何接入旺POS平台。

2.接入流程

整体时序图如下:

2.1 开通订单服务

登录BP平台,进入菜单路径:旺立方订单服务,如图:

填写好相应配置信息以后,点击开通。以上,即已开通订单服务.

这里有两个配置需要特别说明下:

注意,此处对接机制遵守旺POS平台业务接入AccessToken机制

此处主要填写授权地址授权地址用于设备在添加来自此BP的订单服务时,提供给设备端做下账户验证。

2.2 设备端添加订单服务

  1. 开启旺立方设备,设备会自动打印一个WiFi设置二维码纸片。如图:
  2. 使用微信扫描二维码,进入2.1服务配置中所填写的授权页面。
  3. 在授权页完成授权。

ps: 授权页面完全由BP自定义,只需要完成对设备使用者的身份认证即可,确认授权后,需要通过授权设备使用服务回调通知接口通知给旺POS平台,平台需要记录订单服务与设备的授权关系。

2.3 推送订单

推送订单完全上遵循旺pos订单服务机制,同时加入了一些加密数据等特性,详情如下:

http://pos.weipass.cn/WeiposAcc/service/PushDataV2
POST
// 基本参数
access_token=ACCESS_TOKEN,          //访问旺POS接口的唯一身份id               
device_en=xxxxx,                    //目标设备en号
msg_type=service_invoke,            //常量,标识此次接口调用类型为服务调用
encrypt_type=raw                    //加密类型:raw-不加密,ac-非对称加密
data={a:1,b:2 ...}                  //业务数据,为JSON结构的字符串

// 平台对业务参数data节点有着严格的格式定义,以下是各种格式的说明及示例

### 1. 普通模式(不加密)

    device_en=b7a0bc2b,
    msg_type=service_invoke,
    access_token=55641270d54809390bcad724,
    data={
        "template_code": "MSG100006",   //常量,标识此消息类型
        "out_order_no": "052600004",    //外部订单号
        "print_mode": 1,               //打印模式:1-标准打印, 2-旺POS标签打印 
        "print_content": "y82yzbXY1rc6IM37vqlTT0hPCsGqz7W157uwOiAxODY4NHh4eHh4eAogIMGqz7XIyzog1cXI/QoK\nz8K1pcqxvOQ6IDIwMTUtMDUtMjEgMTA6Mjg6MzYKy82yzcqxvOQ6ILDr0KHKsdLUxNoKoaqhqqGq\noaqhqqGqoaqhqqGqoaqhqqGqoaqhqqGqoaoKINChvMYgICAgyv3BvyAgICAgw/uzxgogNy4wMCAg\nICAgMbfdICAgICDO97rsysG4x8Lrt7kKIDguMDAgICAgIDG33SAgICAgz+O4ycjiy7+4x8Lrt7kK\nMTAuMDAgICAgIDG33SAgICAgwunAscWjyOK4x8Lrt7kKoaqhqqGqoaqhqqGqoaqhqqGqoaqhqqGq\noaqhqqGqoaoKtqm1pb3wtu46IDI1LjAw1KoK08W73civICA6IC0yLjAw1KoKyrW8ytanuLY6IDIz\nLjAw1Ko=",
                                      //标准打印内容,这是对原始内容进行Base64编码(GBK)后的内容  
        "command": [1,2],             //指令集合, 1-接单打印, 2-拒绝接单
        "setting":{                   //订单设置参数,用于设置本条订单的一些交互   
            "timeout":900,            //订单受理失效时间,单位秒,默认为不过期
            "need_accept":1           //订单是否需要受理, 1-需要受理,0-无需受理,默认为1
        }
    }

###   加密模式

        encrypt_type=ac, 
        device_en=23bb00ec, 
        msg_type=service_invoke, 
        access_token=558b983cd54809018c91a8cf,
        data={
            "encrypt":
            "864F44308917966D4CE6AA4BF70B24FDD4C9755FE6AF7040F8F9C667C471D4305C2129F98B397ECB1759E5A7BC3AFA3BAFA8126FEDA17E2C53FF5975ADAFA871D912286E92F4293F974819E8ED2F6D3CBF926E0F432FE9E52966C3AE1C02544861A3A283B6753491695CBE5BFD06173FA0C9513E92D7921405559798DB14EC14FB374CD37B1987B84D71FBFAF833533467169438A670057A79F7FB24D9ECF143C32569175DED7CFCFD3AB36D2E20BB52BC62D1F4F9D41534BA3EF66E5B07BE0F63784A2253E46AB08CEF71CA1543D8ABC771E47CFDCCA5C5C2E9A4C1A1FB89AF5F803DD7999784BEDFDE008666436A602849C494D4D6C81B70C0DDC44F082B1A4033929E0DBC139E631106F8543E57E0619BD5FF78848D0B73C0C947250D2D288037385A4E550B9DB06B4A143121948205B767108C62FBCD8CDD6CEFBA573D17BDB442B57422AB4EE440AEE791577158076F24378DF6240170BDAE09B3C3F85E0A1275EE4249A1040AD666CA6ACD2FB6D9789F075FCADC477D9F434F192C96AC65B5E1959E3B4EB779480B2566B655277D9F434F192C96AC65B5E1959E3B4EB790E81F08DB1D5AA4BE096276AEDD75FEB5DB191FE894CC84DB1D1F767DA2F9963B58ED36A8EB986DD82400874B36380378B57188C8119F3D6D42455829BFCD5D8AC45B3F92636A80CF98C629380F76BA9DAE8C600B1E9525989693E1C52A566E496A51926E9FFE9A2DD0D7EDF6CDE178B7F0B09546CAA660B3EFBC749221E31C79C152D9DF465F14E1FCEC7AFB74D0EC240289B67FDC46B009B9830A043F8744B49FEC1068CD0E2279480B2566B655277D9F434F192C96AC65B5E1959E3B4EB779480B2566B655277D9F434F192C96ACBF0529A1788A11721DB9AE762E6FD1B02356AFE409F081C309A5334D54CE5FDBCC9B43679E9D5897FD5187E6DA06627F8C94137A53261B1A0B486C37CD33F119F5025294111104EB22934D57C5955DB800FF486A4D40830B73AA8F063884D8D16CB103E91DA4DFAD9C320DFE33DE51BEF59711600B6AEBEF05B9FFC796D356BFAD2D9A3BC0CDEECF0EA4580310CB50C2",
        }

        data 节点是按照普通模式组装好数据以后,将通过加密算法加密以后获得的数据,全部放在`encrypt`节点中。

为了进一步加强旺POS体系安全保障,旺立方支持加密业务数据,提供了业务数据在网络上传输的安全性。

平台采用非对称加密算法来进行加密,加密流程如下:

在此流程中,BP需要通过获取设备公钥接口先获取到设备的公钥,利用公钥对订单数据加密后再推送。

具体加密过程示例代码如下:

            //1. 获取accesstoken
            String accessToken = serviceInvoker.getServiceAccessToken(appId, secret);

            String url = BizConfig.weipos_url_PushData;
            Map params = new HashMap();
            if ("1".equals(print_mode)) {
                print_content = Base64Util.getBase64(print_content, "gbk"); // 注意这里的编码是GBK
            }
            //2. 组装基础数据
            params.put("access_token", accessToken);
            params.put("device_en", en);
            params.put("msg_type", "service_invoke");
            params.put("encrypt_type", encrypt_type);
            JSONObject data = new JSONObject();
            //3. 组装订单数据
            data.put("template_code", "MSG100006");  //
            data.put("out_order_no", getOrderNo());
            data.put("msg_content", msg_content);    //
            data.put("show_content", show_content);   //
            data.put("print_mode", Integer.parseInt(print_mode));   // 1-标准打印, 2-Wang标签
            data.put("print_content", print_content);
            data.put("command", clist.toArray(new Integer[0]));   //
            //4. 加密订单
            if (!encrypt_type_raw.equals(encrypt_type)) {
                //获取设备公钥
                String public_key = serviceInvoker.getDevicePublicKey(en, accessToken);
                // 加密数据
                byte[] keyBytes = RsaLongData.hex2byte(public_key);
                byte[] dataBytes = data.toString().getBytes();
                dataBytes = RsaLongData.encrypt(keyBytes, dataBytes);
                // 按照加数据格式组装数据
                data = new JSONObject();
                data.put("encrypt", RsaLongData.byte2hex(dataBytes));
                params.put("data", data.toString());
            } else {
                params.put("data", data.toString());
            }

            System.out.println(">>>>>>>>>param:" + params.toString());
            String retData = UrlPostUtil.doPost(url, params);
            ret = (JSONObject) JSONSerializer.toJSON(retData);

其中加密算法 RsaLongData.java 在此下载。

2.4 异步接收订单响应结果

设备上对订单进行操作以后,会将结果上报给平台,平台会进一步讲设备响应异步通知到业务方的服务端。 参见数据上行(DataReceived)接口

2.5 取消订单

可以在一定的时间范畴内进行取消订单的操作。取消订单的结果有这么几种:

  1. 订单还在消息队列中,没有推送到设备上,则直接取消,设备不会接收到被取消的订单
  2. 订单已经取消过了,则不能取消
  3. 订单已经下发到设备,但是还未处理,则也会取消成功,会在订单尾部打印“订单已取消”字样

参见取消订单(cancelPush)接口

3 旺立方打印指令简介

3.1 基本情况介绍

1)旺立方纸宽384点 2)基本字体大小: 中文2424,字母数字1224 一行显示384/24=16个中文字符 一行显示384/12=32个字母数字 3)采用 ESC/POS打印命令集;字符编码GBK;\n换行

3.2 重要指令

3.2.1 设置字体指令

0x1D,0x21,n

参数 功能
n的高4位+1 宽度放大倍数
n的低4位+1 高度放大倍数

比如 0x1D,0x21,0x00 , 就是设置正常的24*24字体大小;

比如 0x1D,0x21,0x11 , 就是设置为48*48的大字体;

比如 0x1D,0x21,0x01 , 就是设置为24*48的高字体;

示例

    /**
     * 构造打印指令序列
     * 
     * @return
     */
    static byte[] encode() {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();

        try {
            Charset gbk = Charset.forName("GBK");

            // 设置2*2字体
            setFont(baos, 2, 2);
            baos.write("      标题\n".getBytes(gbk));

            // 设置正常字体
            setFont(baos, 1, 1);
            baos.write("旺立方正常大小中文字体显示16字符\n".getBytes(gbk));
            baos.write("1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\n".getBytes(gbk));

            // 设置高字体
            setFont(baos, 1, 2);
            baos.write("高字体(1*2)".getBytes(gbk));

            // 设置宽字体
            setFont(baos, 2, 1);
            baos.write("宽字体(2*1)\n".getBytes(gbk));
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return baos.toByteArray();
    }

    /**
     * 设置字体
     * 
     * @param baos
     * @param w
     *            宽度放大倍数
     * @param h
     *            高度放大倍数
     */
    static void setFont(ByteArrayOutputStream baos, int w, int h) {
        if (w < 0 || w > 8 || h < 0 || h > 8) {
            throw new RuntimeException("font size error:" + w + "*" + h);
        }
        w--;
        h--;
        baos.write(0x1D);//指令第1字节
        baos.write(0x21);//指令第2字节
        baos.write((w << 4) | h);////指令第3字节
    }

效果如下:

3.2.2 二维码打印指令

0x1B,0x5A,m,n,k,sL,sH, d1 ⋯ dn

参数 功能 说明
m 无定义 默认为0
n 无定义 默认为0
k 无定义 默认为0
sL;sH 数据长度低位字节;数据长度高位字节 数据长度=sL+sH*256

示例:

    /**
     * 构造QR码打印指令序列
     * @param s QR码内容
     * @return 指令序列.
     */
    public void printQR(String sQR) {
        byte[] ds = null;
        try {
            ds = sQR.getBytes("UTF8");
        } catch (UnsupportedEncodingException e) {
        }
        baos.write(0x1D);
        baos.write(0x6B);
        baos.write(0x20);
        baos.write(0x20);
        baos.write(0x20);
        try {
            baos.write(ds);
        } catch (IOException e) {
        }
        baos.write(0);
        curX = 0;
    }
如果要打印内容为"http://www.wangpos.com/"QR,  用下面这个指令序列(16进纸格式)
1B 5A 00 00 00 17 00 68 74 74 70 3A 2F 2F 77 77 77 2E 77 61 6E 67 70 6F 73 2E 63 6F 6D 2F 

3.3 旺立方打印SDK

点击下载旺立方打印java SDK

点击旺立方打印PHP SDK