beecloud支付后端java

因公司业务需求,支付选用第三方beecloud作为支付平台,一下是移动端APP支付流程和后台java代码,其他方式类同;


下图为整个支付的流程: pic

其中需要开发者开发的只有:

步骤①(在App端)发送订单信息

做完这一步之后就会跳到相应的支付页面(如微信app中),让用户继续后续的支付步骤

步骤②:(在App端)处理同步回调结果

付款完成或取消之后,会回到客户app中,在页面中展示支付结果(比如弹出框告诉用户“支付成功"或"支付失败”)。同步回调结果只作为界面展示的依据,不能作为订单的最终支付结果,最终支付结果应以异步回调为准。

步骤③:(在客户服务端)处理异步回调结果(Webhook

付款完成之后,根据客户在BeeCloud后台的设置,BeeCloud会向客户服务端发送一个Webhook请求,里面包括了数字签名,订单号,订单金额等一系列信息。客户需要在服务端依据规则要验证数字签名是否正确,购买的产品与订单金额是否匹配,这两个验证缺一不可。验证结束后即可开始走支付完成后的逻辑。





Webhook是BeeCloud获得渠道的确认信息后,立刻向商户服务器发送的异步回调。支付,代付,退款成功时,BeeCloud将向商户指定的URL发送HTTP/HTTPS的POST数据请求。

如果商户需要接收此类消息来实现业务逻辑,需要:

  1. 开通公网可以访问的IP地址(或域名)和端口(如果需要对传输加密,请使用支持HTTPS的URL地址,BeeCloud不要求HTTPS根证书认证)
  2. 控制台->选择应用->应用设置->Webhook参数设置 中设置接收端URL,不同应用可设置不同URL,同一应用能且仅能设置一个测试URL,一个生产URL,另外在控制台->应用设置->基本信息设置中获取"Master Secret"
  3. 处理POST请求报文,实现业务逻辑



一下是后端java代码实现




@RequestMapping(value = "/webhookReceiver")
String webhookReceiver(HttpServletRequest request) {
    ResultMessage rm = new ResultMessage(ResultConstant.FAIL);
    String appID = " ..................";
    String testSecret = "......................";
    String appSecret = "................................";
    String masterSecret = "..........................";
    BeeCloud.registerApp(appID, testSecret, appSecret, masterSecret);
    StringBuffer json = new StringBuffer();
    String line = null;
    try {
        request.setCharacterEncoding("utf-8");
        BufferedReader reader = request.getReader();
        while ((line = reader.readLine()) != null) {
            json.append(line);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    JSONObject jsonObj = JSONObject.fromObject(json.toString());
    String signature = jsonObj.getString("signature");
    String transactionId = jsonObj.getString("transaction_id");
    String transactionType = jsonObj.getString("transaction_type");
    String channelType = jsonObj.getString("channel_type");
    String transactionFee = jsonObj.getString("transaction_fee");
    StringBuffer toSign = new StringBuffer();
    toSign.append(BCCache.getAppID()).append(transactionId)
            .append(transactionType).append(channelType)
            .append(transactionFee);
    boolean status = verifySign(toSign.toString(), masterSecret, signature);
    //请不要修改或删除
    if (status) { //验证成功
        boolean b = verifyMoney(transactionFee, channelType, transactionId);
        if (!b) {
            logger.error("=============================》付款的钱和数据库里面存的钱不一致《=============================================");
        }
        //必须返回success
        return "success";
    } else { //验证失败
        return "fail";
    }


}

//校验支付的这笔钱是否和数据库里面存的钱相等-
boolean verifyMoney(String transactionFee, String channelType, String transactionId) {
    RpcResult thirdpartyItemInfo = showOrderProvider.getThirdpartyItemInfo(transactionId);
    Map map = (Map) thirdpartyItemInfo.getValue();
    String service_fee = map.get("service_fee").toString();
    if (transactionFee.equals(service_fee)) {
        SsisPublishServiceOrderItem orderItem = new SsisPublishServiceOrderItem();
        orderItem.setItemId(transactionId);
        orderItem.setPayTime(new Date());
        orderItem.setPayType(channelType);
        orderItem.setPayStatus("paid");
        RpcResult rpc = publishOrderProvider.updateThirdpartyItem(orderItem);
        if (!rpc.hasException()) {
            return true;
        }
    }
    return false;
}


//下面的方法不要修改


boolean verifySign(String text, String masterKey, String signature) {
    boolean isVerified = verify(text, signature, masterKey, "UTF-8");
    if (!isVerified) {
        return false;
    }
    return true;
}


boolean verify(String text, String sign, String key, String inputCharset) {
    text = text + key;
    String mysign = DigestUtils.md5Hex(getContentBytes(text, inputCharset));
    return mysign.equals(sign);
}

byte[] getContentBytes(String content, String charset) {
    if (charset == null || "".equals(charset)) {
        return content.getBytes();
    }
    try {
        return content.getBytes(charset);
    } catch (UnsupportedEncodingException e) {
        throw new RuntimeException("MD5签名过程中出现错误,指定的编码集不对,您目前指定的编码集是:" + charset);
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值