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

簡言:

 公司一直在做使用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);

到這裏一套完整的商米集成刷卡功能就實現了;

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章