最近公司项目需要整合微信支付Native版本(网页扫码支付),不同的支付实操也大同小异,修改部分参数即可,看了下微信支付的官方文档,已经推出了更加方便安全V3支付接口,目前为了快速集成,先奉上V1版本的接入完整示例:

  1. 首先是要拿到开发所需要的配置项(appId 微信商户绑定的公众号ID、mchId 商户号 、partnerKey 商户秘钥-微信商户后台-Api安全设置自行设置,需要用户自行牢记该秘钥且不要泄露)
  2. 添加项目依赖
<dependency>
	<groupId>com.github.javen205</groupId>
	<artifactId>IJPay-WxPay</artifactId>
	<version>2.7.2</version>
</dependency>
  1. 添加微信配置
@Bean
    public WxPayApiConfig wxPayApiConfig() {
        WxPayApiConfig wxPayApiConfig = new WxPayApiConfig();
        wxPayApiConfig.setAppId(app_id);
        wxPayApiConfig.setMchId(mch_id);
        wxPayApiConfig.setDomain(domain);
        wxPayApiConfig.setPartnerKey(partnerKey);
        WxPayApiConfigKit.putApiConfig(wxPayApiConfig);
        return wxPayApiConfig;
    }

IJPay中微信配置绑定线程私有对象ThreadLocal,详情可阅读com.ijpay.wxpay.WxPayApiConfigKit的源码,如果我们项目中只用到了一个微信支付实体,我们就在加载配置的地方调用WxPayApiConfigKit.putApiConfig(wxPayApiConfig); 使其成为我们所有线程的默认微信支付配置。
当我们调用WxPayApiConfigKit.getWxPayApiConfig();时,就会获取到我们先前设置的Config对象

  1. 微信统一下单
    对接过微信支付的朋友都应该清楚,微信提供了一个统一下单的接口,IJPay也帮助我们省略了很多代码,微信Native支付下单示例:
/**
     * 系统内部下单接口
     *
     * @param orderCode 订单号
     * @param goodsName 订单描述
     * @param amount    订单金额
     */
    public static String createOrder(String orderCode, String goodsName, BigDecimal amount) {
        WxPayApiConfig wxPayApiConfig = WxPayApiConfigKit.getWxPayApiConfig();
        Map<String, String> params = UnifiedOrderModel
                .builder()
                .appid(wxPayApiConfig.getAppId())
                .mch_id(wxPayApiConfig.getMchId())
                .nonce_str(WxPayKit.generateStr())
                .out_trade_no(orderCode)
                .total_fee(formatAmount(amount))
                .spbill_create_ip("8.8.8.8")
                .notify_url(wxPayApiConfig.getDomain()+"/api/order/callback")
                .body(goodsName)
                .trade_type(TradeType.NATIVE.getTradeType())
                .build()
                .createSign(wxPayApiConfig.getPartnerKey(), SignType.MD5);
        String xmlResult = WxPayApi.pushOrder(false, params);
        Map<String, String> result = WxPayKit.xmlToMap(xmlResult);
        log.debug("统一下单返回:\n {}", result);
        if (!WxPayKit.codeIsOk(result.get("result_code"))) {
            throw new MyOrderException("创建订单失败,请稍后重试");
        }
        return result.get("code_url"); // 获取到的是微信支付二维码链接 生成二维码扫码即可
    }

注意:
1.微信支付中的total_fee 总金额字段 单位为分 需要将BigDecimal对象转成分为单位
eg: return String.valueOf(amount.multiply(new BigDecimal(100)).intValue());
2.notify_url 为微信支付通知回调地址,不允许携带查询参数 (eg:?key=wx)
3,.示范例子为Native支付,其他类型的支付需要的必传参数查看微信支付官方文档,逐个添加即可,例如小程序支付需要提供openId

  1. 根据上述步骤应该可以正常下单,最后还差支付回调就基本大功告成啦:
/**
     * 订单回调地址
     */
    @RequestMapping("callback")
    public String callback(HttpServletRequest request) {
        String data = HttpKit.readData(request);
        Map<String, String> result = WxPayKit.xmlToMap(data);
        boolean verifyNotify = WxPayKit
                .verifyNotify(result, WxPayApiConfigKit.getWxPayApiConfig().getPartnerKey());
        if (!verifyNotify) {
            log.warn("接收到验证不通过订单回调:{}", data);
            return "fail";
        }
        log.debug("微信支付回调:\n {}", result);
        if (WxPayKit.codeIsOk(result.get("return_code"))) {
            String orderCode = result.get("out_trade_no");
            log.debug("收到订单号为:{} 的支付回调通知", orderCode);
            //todo  这里编写完成支付的逻辑
        }
        return "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
    }

注意:微信支付回调一定要校验是否由微信服务器发起的
boolean verifyNotify = WxPayKit
.verifyNotify(result, WxPayApiConfigKit.getWxPayApiConfig().getPartnerKey());
这里就是微信商户秘钥需要保密的一大原因,如果泄露,可以被人为的伪造微信的回调,
如果真的泄密了,也不要太慌,微信支付是支持订单查询的,具体接口查看微信支付文档,获取到微信支付回调后,主动去查询该订单的支付状态为最安全保险的做法!

暂时收工,如果对V3有需求,后续再补充V3支付的集成。