商米设备的集成(打印小票,刷卡功能)

简言:

 公司一直在做使用pos设备有关的项目,选用的是商米的商户,设备主要实现功能就是刷卡功能与打印小票功能,商家提供了一个简单的demo,刚开始就让人蒙圈, 查阅百度,各种博客,发现关于商米设备的很少,所以只能硬着头皮,看开发文档,一步一步实现了。

1.设备

我现在主要针对的设备是P1 4G的设备,既能刷卡功能,又有小票打印功能,v1设备只支持打印小票,

 2 .对于商米功能的简介

SunmiPaySDK 是 Sunmi 基于固件封装的贴近 java 开发者的一套调用硬件的接口,开发中通过该 SDK 可以快速调用
Sunmi 金融机具相应的固件接口,实现自己相关业务逻辑的开发。SDK 主要包含:设备信息基础模块,卡操作模块,密码键
盘模块,EMV 模块,安全模块。

3.如何集成商米(重点来喽)

1. 查看自己的设备机型, 我的是P1-4G,

2.  点开设置—>应用—>右上角—>点击选择显示系统应用
  P1N 或 P1-4G 机具上已安装 SunmiPayHardwareService 版本 3.1.2 或者更高版本
  确保 P1N 或 P1-4G 机具已安装 SunmiPaySDKService 版本 1.0.6 或者更高版本

3. android studio 如何集成

1) 在app目录下添加这个aar 包(商米给的demo中有)

在app的build.gradle中

2)在商米提供的demo中,

3) 创建一个application 来实现商米的初始化

 application的实现

public static int pikIndex = 14;
/**
 * 获取读卡模块
 */
public static ReadCardOpt mReadCardOpt;

/**
 * RSA公私钥操作模块
 */
public static SecurityOpt mSecurityOpt;
public static final String TAG = "MyApplication";

private SunmiPayKernel mSunmiPayKernel;

@Override
public void onCreate() {
    super.onCreate();
    mApplicationContext = getApplicationContext();
    LogManager.isDebug = true;
    NetworkHelper.initOkHttp();
    conn();
    AidlUtil.getInstance().connectPrinterService(this);
}

/**
 * 连接支付SDK
 */
private void conn() {
    mSunmiPayKernel = SunmiPayKernel.getInstance();
    mSunmiPayKernel.connectPayService(mConnCallback,getApplicationContext());
}

/**
 * 连接状态回调
 */
private SunmiPayKernel.ConnectCallback mConnCallback = new SunmiPayKernel.ConnectCallback() {
    @Override
    public void onServiceConnected() {
        Log.e("wl","连接成功");
        try {
           mReadCardOpt = mSunmiPayKernel.mReadCardOpt;
            mSecurityOpt = mSunmiPayKernel.mSecurityOpt;
            //存储KEK,TMK,PIK,MAK,TDK,各种默认的密钥
           initSecretKey();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    @Override
    public void onServiceDisconnected() {
        Log.e("wl","链接失败");
    }

    @Override
    public void illegal() {
        Log.e("wl","非法调用");
    }
};

/**
 * 存储KEK,TMK,PIK,MAK,TDK,各种默认的密钥
 *
 * @throws RemoteException
 */
public static void initSecretKey() throws RemoteException {
    byte[] kekByte = Utils.hexStr2Bytes("11111111111111111111111111111111");
    byte[] tmkByte = Utils.hexStr2Bytes("F40379AB9E0EC533F40379AB9E0EC533");
    byte[] checkValueByte = Utils.hexStr2Bytes("82E13665B4624DF5");

    /**
     * CheckValue的计算过程:
     KEK(明文) TMK(密文) workKey(密文)
     KEK解密TMK(密文)得到TMK(明文)
     用TMK(明文)解密workKey(密文)得到workKey(明文)
     用workKey(明文)加密16个0 取前8位是CheckValue
     */
    //测试时请将主密钥和工作密钥存入以下索引
    try {
        int rec = mSecurityOpt.saveKey(AidlConstants.Security.KEY_TYPE_KEK, kekByte, checkValueByte, 1, AidlConstants.Security.KEY_ALG_TYPE_3DES, 10, false);
        int rec1 = mSecurityOpt.saveKey(AidlConstants.Security.KEY_TYPE_TMK, tmkByte, checkValueByte, 10, AidlConstants.Security.KEY_ALG_TYPE_3DES, 11, true);
        int rec2 = mSecurityOpt.saveKey(AidlConstants.Security.KEY_TYPE_TDK, tmkByte, checkValueByte, 11, AidlConstants.Security.KEY_ALG_TYPE_3DES, 12, true);
        int rec3 = mSecurityOpt.saveKey(AidlConstants.Security.KEY_TYPE_MAK, tmkByte, checkValueByte, 11, AidlConstants.Security.KEY_ALG_TYPE_3DES, 13, true);
        int rec4 = mSecurityOpt.saveKey(AidlConstants.Security.KEY_TYPE_PIK, tmkByte, checkValueByte, 11, AidlConstants.Security.KEY_ALG_TYPE_3DES, pikIndex, true);
        LogManager.e("secutirysaveKey", rec + ":" + rec1 + ":" + rec2 + ":" + rec3 + ":" + rec4);
    } catch (RemoteException e) {
        e.printStackTrace();
    }

}

//获取全局的上下文
public static Context getGlobalAppLication(){
    return  mApplicationContext;
}

4) 调取刷卡 打印等功能;

/**
 * 实现刷卡用能
 */
private void shuaCard() {
    cardType = AidlConstants.CardType.MIFARE.getValue();
    try {
        readCardOpt.checkCard(cardType, readCardCallback, 60);
    } catch (RemoteException e) {
        e.printStackTrace();
        Toast.show(ScanActivity.this, "检卡失败,重新刷卡!");
        finish();
    }

}

/**
 * 检卡回调
 */
private ReadCardCallback readCardCallback = new ReadCardCallback.Stub() {

    @Override
    public void onCardDetected(CardInfo cardInfo) throws RemoteException {
        Message message = new Message();
        message.what = 0x01;
        message.obj = cardInfo;
        mHandler.sendMessage(message);
    }

    @Override
    public void onError(int i, String s) throws RemoteException {
        Message message = new Message();
        message.what = 0x02;
        message.obj = "code:" + i + " message:" + s;
        mHandler.sendMessage(message);
    }

    @Override
    public void onStartCheckCard() throws RemoteException {
        LogManager.e(TAG, "onStartCheckCard:正在检卡");
    }

};

private Handler mHandler = new Handler() {

    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        switch (msg.what) {
            case 0x01:
                CardInfo cardInfo = (CardInfo) msg.obj;
                String uuid = cardInfo.uuid;
              (获取参数成功)
                break;
            case 0x02:
                Toast.show(ScanActivity.this, "检卡失败请重新检卡!");
                finish();
                break;
        }
    }

};

5) 商米的打印功能

String content = "消费凭证(" + title + ")\n" + "***********欢迎光临***********\n\n"
        + "订单金额:" + orderAmountDou + "\n"
        + "优惠金额:" + s + "\n"
        + "实付金额:" + shiAmount + "\n"
        + "支付方式:" + payTypeStr + "\n"
        + "油品:" + oilNum + "#\n"
        + "------------------------------\n"
        + "门店名称:" + storeName + "\n"
        + "订单号:" + orderNumber + "\n"
        + "" + time + "\n\n";

AidlUtil.getInstance().printText(content, 24, true, false);

到这里一套完整的商米集成刷卡功能就实现了;

发布了96 篇原创文章 · 获赞 370 · 访问量 42万+

猜你喜欢

转载自blog.csdn.net/wk_beicai/article/details/93158545