微信支付对接


微信支付对接

前期准备工作
去官方申请账号并申请相关支付功能,并且生成对应的公钥与私钥。


一、如果对接微信支付

微信支付不用于支付宝支付,在传参上没有支付宝那么的傻瓜方式,需要我们自己按照他的要求拼装参数。

二、开始对接

1.申请交易

引入微信支付SDK

	<!-- 微信支付sdk -->
	<!-- https://mvnrepository.com/artifact/com.github.binarywang/weixin-java-pay -->
	<dependency>
		<groupId>com.github.binarywang</groupId>
		<artifactId>weixin-java-pay</artifactId>
		<version>4.1.0</version>
	</dependency>

创建调用工具类

public class ApiURLConsts {

    /***
     * 统一下单
     */
    public static final String UNIFIEDORDER = "https://api.mch.weixin.qq.com/pay/unifiedorder";

    /***
     * 订单查询
     */
    public static final  String ORDER_QUERY = "https://api.mch.weixin.qq.com/pay/orderquery";

}

下文中 OpenTM.XXXX 这个方法是我系统内自己的方法用来获取数据库中配置好的 Appid 商户号之类的,这个大家换成自己的就行。

@Override
public JSONObject getWXPayOrderInfoNative(OrderEntity entity){
    if (null != entity && PsopConstant.OrderStatus.INIT.equals(entity.getStatus())) {
        long money4wx = Long.valueOf(entity.getPrice());
        String openId="";
        Optional<MemberEntity> memberEntity = memberDao.findById(entity.getMemberId());
        if (memberEntity.isPresent()){
            openId = memberEntity.get().getOpenId();
        }
        SortedMap<String, String> params = new TreeMap<String, String>();
        params.put("mch_id", OpenTM.getWXpayMchid());
        params.put("appid", OpenTM.getWXpayAppid());
        params.put("device_info","WEB");
        params.put("nonce_str", RandomStringUtils.randomAlphanumeric(20));
        params.put("body", "充值备注");
        params.put("out_trade_no", entity.getId() + "");
        params.put("total_fee", money4wx + "00");// 单位 分
        params.put("spbill_create_ip", OpenTM.getWXPayIP());
        params.put("notify_url", OpenTM.getWXpayNotifyUrl());
        params.put("trade_type", "NATIVE");
//            params.put("openid", openId);
        //交易结束时间:订单产生多久后不支付订单失效,请求支付必传参数prepay_id只有两小时的有效期
        //Date endDate = DateUtil.getDateAfterHours(1);
        //String time_expire = DateUtil.getDateStr("yyyyMMddHHmmss", endDate);
        // params.put("time_expire",time_expire);
        params.put("sign", WechatPayUtil.createSign("UTF-8", params));
        String requestXML = WechatPayUtil.getRequestXml(params);
        logger.info(requestXML);
        String result = WechatPayUtil.httpsRequest(ApiURLConsts.UNIFIEDORDER, "POST", requestXML);
        logger.info(result);
        /**统一下单接口返回正常的prepay_id(预支付交易会话标识),再按签名规范重新生成签名后,将数据传输给APP。
         参与签名的字段名为appId,partnerId,prepayId,nonceStr,timeStamp,package。注意:package的值格式为Sign=WXPay
         **/
        //调起支付接口
        try {
            Map<String, String> map = XMLUtil.doXMLParse(result);
            logger.info(JSONHelper.bean2JSONStr(map));
            SortedMap<String, String> parameterMap2 = new TreeMap<String, String>();

            parameterMap2.put("appId", OpenTM.getWXpayAppid());
            parameterMap2.put("nonceStr", RandomStringUtils.randomAlphanumeric(20));
            parameterMap2.put("package", "prepay_id=" + map.get("prepay_id"));
            parameterMap2.put("signType", "MD5");
            parameterMap2.put("timeStamp", (System.currentTimeMillis() + "").substring(0, 10));
            parameterMap2.put("code_url", map.get("code_url"));
            //parameterMap2.put("partnerid", OpenTM.getWXpayMchid());
            //parameterMap2.put("prepayid", map.get("prepay_id"));
            //本来生成的时间戳是13位,但是ios必须是10位,所以截取了一下
            String sign2 = WechatPayUtil.createSign("UTF-8", parameterMap2);
            parameterMap2.put("paySign", sign2);

            return JSONHelper.map2JSONObj(parameterMap2);
        } catch (Exception e) {
            logger.error("读取微信返回结果异常");
            logger.error(e.getLocalizedMessage());
        }
    }
    return JSONHelper.success("");
}
以上是相关业务代码,需要注意的是微信传入钱的单位是以分位单位,传入 1 元支付 0.01 元,由于我们的最小充值单位是1元而且都是整数,所以我这里直接补了 00 前端就不做任何处理了。

2.微信回调方法

如果支付成功,微信官方会回调这个接口,带上相关支付信息。解析request获得对应的Map信息然后处理对应的业务即可。

@RequestMapping(value = "wechat/notify.json")
public void notify(HttpServletRequest request) {
    logger.info("微信支付回调参数");
    SortedMap<String, String> wxparams = new TreeMap<String, String>();
    try {
        String string = WechatPayUtil.inputStream2String(request.getInputStream(), "UTF-8");
        Map<String, String> map = XMLUtil.doXMLParse(string);
        wxparams.putAll(map);
    } catch (Exception e) {
        logger.error(e.getLocalizedMessage());
    }

    if (null == wxparams || wxparams.size() == 0) {
        logger.error("微信支付通知回调参数处理失败");
        WebUtil.ajaxOutXml(WechatPayUtil.setXML("FAIL", "参数格式校验错误"));
        return;
    }
    //1.验证签名
    boolean isWxpaySign = WechatPayUtil.isTenpaySign("utf-8", wxparams);
    if (!isWxpaySign) {
        logger.error("微信签名验证失败");
        WebUtil.ajaxOutXml(WechatPayUtil.setXML("FAIL", "签名验证失败"));
        return;
    }
    //2.验证appid
    if (!OpenTM.getWXpayAppid().equals(wxparams.get("appid"))) {
        logger.error("appid 错误");
        WebUtil.ajaxOutXml(WechatPayUtil.setXML("FAIL", "应用ID错误"));
        return;
    }
    //3.验证商户ID
    if (!OpenTM.getWXpayMchid().equals(wxparams.get("mch_id"))) {
        logger.error("mch_id 错误");
        WebUtil.ajaxOutXml(WechatPayUtil.setXML("FAIL", "商户ID错误"));
        return;
    }

    if ("SUCCESS".equals(wxparams.get("return_code")) && "SUCCESS".equals(wxparams.get("result_code"))) {
        logger.info("全部验证通过,处理自己的逻辑");
        //paymentService.saveWXpayNotify(wxparams);
        logger.info("微信支付回调只需要处理自己的逻辑,一切OK");
        try {
            String orderIdStr = wxparams.get("out_trade_no");
            String wxpayOrderIdStr = wxparams.get("transaction_id");
            String totalFee = wxparams.get("total_fee");

            logger.info("orderIdStr:{}  wxpayOrderIdStr:{}  totalFee:{} ", orderIdStr, wxpayOrderIdStr, totalFee);

            orderService.execReceiveWXPayNotify(orderIdStr, wxpayOrderIdStr, totalFee);
        } catch (Exception e) {
            e.printStackTrace();
        }
        WebUtil.ajaxOutXml(WechatPayUtil.setXML("SUCCESS", "处理成功"));
        return;
    } else {
        //记录通知信息
        WebUtil.ajaxOutXml(WechatPayUtil.setXML("SUCCESS", "处理成功"));
        return;
    }
}

总结

以上就是微信支付的相关代码,希望对大家有所帮助。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值