Android Payme支付接入

公司新项目需要接入HK的payme支付,一开始说没资料自己网上找,搜了一圈,发现啥都可以参考的案例,就参照后台的来撸了一把,再次记录下.坑多得很...

首先申请密钥啥的都不说了,申请下来即可.

第一步首先获得token;一开始用okHttp的请求怎么死活请求都不行,头部参数好像带不进去,后面换了两个不同的封装都是不行,最后找同学的一个retrofit2实现了...

请求很简单就带两个id在头部里面就行了.

 /**
     * 獲取Token
     */
    public void getJsonToken(Context context) {
        SortedMap<String, Object> paramMap = new TreeMap<>();
        paramMap.put("client_id", ApiConstant.CLIENT_ID);
        paramMap.put("client_secret", ApiConstant.CLIEND_SECRET);
        RetrofitHelper.getHttpService().getToken(paramMap)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(
                        mTokenBean -> {
                            if (mTokenBean != null) {
                                tokenBeanMutableLiveData.setValue(mTokenBean);
                            }
                        },
                        throwable -> {
                           
                        },
                        () -> Log.e("m_tag_token", "Token完成"));
    }

获取Token成功后就开始提交订单;用获取的到的Token去请求,这步坑很多.,商品需要以body形式传过去,格式参照需要的结构组装即可,

 /**
     * 提交订单
     */
    public void BodyOrder(Context context, String token, String createdTime, String uuId,
                          String currencyCode, String name, Double price, int quantity, String sku) {
        //商品信息层
        ShopInfoBean shopInfoBean = new ShopInfoBean();
        shopInfoBean.setCurrencyCode(currencyCode);
        shopInfoBean.setName(name);
        shopInfoBean.setPrice(price);
        shopInfoBean.setQuantity(quantity);
        shopInfoBean.setSku(sku);

        //订单信息层
        ShopListBean shopListBean = new ShopListBean();
        List<ShopInfoBean> shoppingCart = new ArrayList<>();
        shoppingCart.add(shopInfoBean);

        shopListBean.setOrderDescription("");
        shopListBean.setOrderId("xxx");
        shopListBean.setShoppingCart(shoppingCart);

        //返回状态层
        PaymeBean paymeBean = new PaymeBean();
        paymeBean.setAppFailCallback("xxx");
        paymeBean.setAppSuccessCallback("xxx");
        paymeBean.setCurrencyCode("HKD");
        paymeBean.setEffectiveDuration(30);
        paymeBean.setMerchantData(shopListBean);
        paymeBean.setNotificationUri("xxx");
        paymeBean.setTotalAmount("578.0");


        Gson gson = new GsonBuilder().disableHtmlEscaping().create();
        String digestString = null;
        digestString = "SHA-256=" + TestSha256.getSHA256(gson.toJson(paymeBean));

        String signStr = "(request-target): post /payments/paymentrequests\n" +
                "api-version: 0.12\n" +
                "request-date-time: " + createdTime + "\n" +
                "trace-id: " + uuId + "\n" +
                "authorization: " + token + "\n" +
                "digest: " + digestString;
        //密钥
        String signKey = ApiConstant.SIGNKEY;
        //base64 解碼商家簽名密鑰
        String base64SignKey = new String(Base64.decode(signKey, Base64.DEFAULT));
        String str = sha256_HMAC(signStr, base64SignKey);
        String newSingature = "keyId=\"" + ApiConstant.KEYID + "\",algorithm=\"hmac-sha256\"," +
                "headers=\"(request-target) Api-Version Request-Date-Time Trace-Id Authorization Digest\",signature=\"" + str + "\"";

        Map<String, String> headmap = new LinkedHashMap<>();
        headmap.put("Accept", "application/json");
        headmap.put("Accept-Language", "en-US");
        headmap.put("Content-Type", "application/json");
        headmap.put("Api-Version", "0.12");
        headmap.put("Request-Date-Time", createdTime);
        headmap.put("Trace-Id", uuId);
        headmap.put("Authorization", token);
        headmap.put("Digest", digestString);
        headmap.put("Signature", newSingature);

        RetrofitHelper.getHttpService().postBodyOrder(headmap, paymeBean)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(
                        mTokenBean -> {
                            if (mTokenBean != null) {
                                orderInfoBeanMutableLiveData.setValue(mTokenBean);
                            }
                        },
                        throwable -> {
                        },
                        () -> Log.e("m_tag_order", "订单完成"));

    }

第三步查询订单,还是用第二步的参数,body传个"{}"即可.

 /**
     * 提查询订单信息
     */
    public void GetOrder(Context context, String orderInfo, String token, String createdTime, String uuId) {
        LoadingUtil.getInstance(context).show("查询订单中...");
        String digestString = null;
        digestString = "SHA-256=" + Sha256.getSHA256("{}");

        String signStr = "(request-target): get /payments/paymentrequests/" + orderInfo + "\n" +
                "api-version: 0.12\n" +
                "request-date-time: " + createdTime + "\n" +
                "trace-id: " + uuId + "\n" +
                "authorization: " + token + "\n" +
                "digest: " + digestString;
        //密钥
        String signKey = ApiConstant.SIGNKEY;
        //base64 解碼商家簽名密鑰
        String base64SignKey = new String(Base64.decode(signKey, Base64.DEFAULT));
        String str = sha256_HMAC(signStr, base64SignKey);

        String newSingature = "keyId=\"" + ApiConstant.KEYID + "\",algorithm=\"hmac-sha256\"," +
                "headers=\"(request-target) Api-Version Request-Date-Time Trace-Id Authorization Digest\",signature=\"" + str + "\"";

        Map<String, String> headmap = new LinkedHashMap<>();
        headmap.put("Accept", "application/json");
        headmap.put("Accept-Language", "en-US");
        headmap.put("Content-Type", "application/json");
        headmap.put("Api-Version", "0.12");
        headmap.put("Request-Date-Time", createdTime);
        headmap.put("Trace-Id", uuId);
        headmap.put("Authorization", token);
        headmap.put("Digest", digestString);
        headmap.put("Signature", newSingature);


        String url = "payments/paymentrequests/" + orderInfo;
        RetrofitHelper.getHttpService().getQueryOrder(url, headmap)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(
                        queryOrderBean -> {
                            if (queryOrderBean != null) {
                                LoadingUtil.getInstance(context).dismiss();
//                                    queryOrderBeanMutableLiveData.setValue(queryOrderBean);
                            }
                        },
                        throwable -> {
                            LoadingUtil.getInstance(context).dismiss();
                        },
                        () -> Log.e("m_tag_order", "查询订单-订单完成"));

    }

跳到Payme支付APP后支付成功了,没有返回APP的标志,只能自己轮询去查结果,根据支付状态来处理后续业务逻辑,由于跳到别的APP后请求的结果不能正常接收这边采用了eventbus的方式来接收查询的结果在做相应的处理.

 /**
     * 得到查询订单结果
     */
    @Subscribe
    public void onEvent(QueryOrderEvent queryOrderBean) {
        if (queryOrderBean != null) {
            if (TextUtils.isEmpty(queryOrderBean.queryOrderBean.getStatusCode())) {
//                ToastUtils.showToast(SubmitOrderActivity.this, "状态码不能为空!");
                runOnUiThread(() -> LoadingUtil.getInstance(SubmitOrderActivity.this).dismiss());
                return;
            }

            //支付成功则停止循环
            if (queryOrderBean.queryOrderBean.getStatusCode().contentEquals("PR005")) {
                runOnUiThread(() -> LoadingUtil.getInstance(SubmitOrderActivity.this).dismiss());
                PaymePayResultActivity.startToPaymePayResultActivity(SubmitOrderActivity.this);
                finish();
                return;
            }

            //待支付,继续循环查询(状态PR001)
            if (queryOrderBean.queryOrderBean.getStatusCode().contentEquals("PR001")) {
                long secondTime = System.currentTimeMillis() - millis;
                //小于10秒,则需等待时间为10000 - secondTime
                if (secondTime < outTime) {
                    mSubscription = Observable.timer(outTime - secondTime, TimeUnit.MILLISECONDS)
                            .subscribeOn(Schedulers.io())
                            .observeOn(AndroidSchedulers.mainThread())
                            .subscribe(aLong -> {
                                //切换到主线程显示等待彈窗
                                surePopup();
                                if (mSubscription != null) {
                                    mSubscription.unsubscribe();
                                    mSubscription = null;
                                }
                            });
                    return;
                }
                //大于等于10秒,立即弹框
                runOnUiThread(() -> {
                    //切换到主线程显示等待彈窗
                    surePopup();
                });
                return;
            }
            //PR001,Active,Request for payment initiated;PR004,Aborted,Request for Payment Rejected;PR007,Expired,Payment Request Expired
            //(状态PR007)
            runOnUiThread(() -> LoadingUtil.getInstance(SubmitOrderActivity.this).dismiss());
            //返回首页
            goHomePopup(queryOrderBean.queryOrderBean.getStatusDescription());
        }
    }

猜你喜欢

转载自blog.csdn.net/qq_19714505/article/details/110656201
今日推荐