APP调用微信支付

最近项目中用到的微信支付,记录一下遇到的问题。。。

官方文档地址:https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=8_1

前期的一些准备工作就不记录,就是一些必须的参数,直接进入主题

1.统一下单

 1 /**
 2  * @Description: 统一下单
 3  * @Param: []
 4  * @return: void
 5  * @Author: Mr.Li
 6  * @Date: 2019/10/26
 7  */
 8 public static Map<String, String> payMoney(int classify, BigDecimal money, String orderNum, String goodsDescribe,
 9                                            String ipPath) {
10 
11     //订单分类 classify 1:发布红包,2:需求订单,3:技能,4:商品订单,5:会员升级,6:奖品运费
12     //微信支付金额的单位是分
13     String payMoney = money.multiply(new BigDecimal("100"))
14             .stripTrailingZeros().toPlainString();
15 
16     MyWxPayConfig ourWxPayConfig;
17     try {
18         ourWxPayConfig = new MyWxPayConfig();
19         WXPay wxPay = new WXPay(ourWxPayConfig);
20 
21         //orderNum商户系统内部订单号,要求32个字符内,只能是数字、大小写字母_-|*且在同一个商户号下唯一。
22         //商品描述交易字段格式根据不同的应用场景按照以下格式:APP——需传入应用市场上的APP名字-实际商品名称,天天爱消除-游戏充值。
23         String body = "XX-" + goodsDescribe;
24 
25         //根据微信支付api来设置
26         Map<String, String> data = new HashMap<>();
27         data.put("appid", ourWxPayConfig.getAppID());//微信开放平台审核通过的应用APPID
28         data.put("mch_id", ourWxPayConfig.getMchID()); //微信支付分配的商户号
29         data.put("trade_type", "APP"); //支付场景 APP 微信app支付 JSAPI 公众号支付  NATIVE 扫码支付
30         data.put("notify_url", ourWxPayConfig.getNotifyUrl());                     //回调地址
31         data.put("spbill_create_ip", "XXXXXXXXX");             //终端ip
32         data.put("total_fee", payMoney);       //订单总金额
33         data.put("fee_type", "CNY");                           //默认人民币
34         data.put("out_trade_no", orderNum);   //商户平台生成的唯一订单号
35         data.put("body", body);
36         data.put("nonce_str", WXPayUtil.generateNonceStr());   // 随机字符串,不长于32位
37         data.put("sign", WXPayUtil.generateSignature(data, ourWxPayConfig.getKey()));//签名
38         data.put("attach", classify + "");
39 
40         /** wxService.unifiedOrder 这个方法中调用微信统一下单接口 */
41         Map<String, String> respData;
42 
43         respData = wxPay.unifiedOrder(data);
44 
45         if (respData.get("return_code").equals("SUCCESS")) {
46 
47     //二次签名
49     //这里就是重点了,当时也是在这里卡了很久。统一下单成功之后,拿到微信后台返回结果.再次计算签名,
51     //而且注意的是二次签名和统一下单的时候计算签名的参数名不相同,也就是下面这些参数。
52     //当时做的时候不晓得要二次签名,就直接把统一下单的签名返回给前端,再调起微信支付,结果一直返回-1
53             String time = (System.currentTimeMillis() + "").substring(0, 10);//时间戳,必须是10位的
54             //返回给APP端的参数,APP端再调起支付接口
55             Map<String, String> repData = new HashMap<>();
56             repData.put("appid", ourWxPayConfig.getAppID());//appid
57             repData.put("partnerid", ourWxPayConfig.getMchID());//mchId
58             repData.put("prepayid", respData.get("prepay_id"));//统一下单成成之后返回的prepay_id
59             repData.put("package", "Sign=WXPay");//直接写死的
60             repData.put("noncestr", respData.get("nonce_str"));//统一下单成功之后返回的nonce_str
61             repData.put("timestamp", time);
62 
63             String sign = WXPayUtil.generateSignature(repData, ourWxPayConfig.getKey());//再次计算签名
64             repData.put("sign",sign);
65 
66         //将repDate返回给前端,就可以支付了
67             return repData;
68         }
69         return null;
70     } catch (Exception e) {
71         e.printStackTrace();
72         return null;
73     }
74 }

 

/**
 * @program: qimi_jfinal
 * @description:
 * @author: Mr.Li
 * @create: 2019-10-26 13:41
 **/
public class MyWxPayConfig implements WXPayConfig {

    /**
     * 加载证书 这里证书需要到微信商户平台进行下载
     */
    private byte[] certData;

    public MyWxPayConfig() throws Exception {
        InputStream certStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("cert/wxpay/apiclient_cert.p12");//证书需要到开放平台下载
        this.certData = IOUtils.toByteArray(certStream);
        certStream.close();
    }

    /**
     * @Description: 回调地址
     * 接收微信支付异步通知回调地址,通知url必须为直接可访问的url,不能携带参数。
     * @Param: []
     * @return: java.lang.String
     * @Author: Mr.Li
     * @Date: 2019/10/26
     */
    public String getNotifyUrl() {
        return "回调地址,必须是外网能够访问到的";
    }

    @Override
    public String getAppID() {
        return "appId";
    }

    @Override
    public String getMchID() {
        return "mchId";
    }

    @Override
    public String getKey() {
        return "密匙";
    }

    @Override
    public InputStream getCertStream() {
        return new ByteArrayInputStream(this.certData);
    }

    @Override
    public int getHttpConnectTimeoutMs() {
        return 0;
    }

    @Override
    public int getHttpReadTimeoutMs() {
        return 0;
    }

}

 

WXPayUtil工具类maven地址
<dependency>
<groupId>com.github.wxpay</groupId>
<artifactId>wxpay-sdk</artifactId>
<version>0.0.3</version>
</dependency>


2:支付结果回调
必须要公网能够访问的地址,回调的时候就是进行一些逻辑处理,比如修改订单状态,计算分佣之类的。。。
这里贴一个回调的结果示例,做个参考:

< xml >
< appid > < ![CDATA[xxxxxxxxxxxx]] > < /appid>
<attach><![CDATA[1]]></attach >
< bank_type > < ![CDATA[CFT]] > < /bank_type>
<cash_fee><![CDATA[10]]></cash_fee >
< fee_type > < ![CDATA[CNY]] > < /fee_type>
<is_subscribe><![CDATA[N]]></is_subscribe >
< mch_id > < ![CDATA[xxxxxxxxxxxx]] > < /mch_id>
<nonce_str><![CDATA[xxxxxxxxxxxx]]></nonce_str >
< openid > < ![CDATA[xxxxxxxxxxxx]] > < /openid>
<out_trade_no><![CDATA[157379534051324117318]]></out_trade_no >
< result_code > < ![CDATA[SUCCESS]] > < /result_code>
<return_code><![CDATA[SUCCESS]]></return_code >
< sign > < ![CDATA[FCC973FF36BECA44061F4CD6BB202C37]] > < /sign>
<time_end><![CDATA[20191115132156]]></time_end >
< total_fee > 10 < /total_fee><trade_type><![CDATA[APP]]></trade_type >
< transaction_id > < ![CDATA[4200000435201911152014409040]] > < /transaction_id>
</xml >

这个回调接收到的xml,转换成json就行了。

 

上面这些就是整个微信支付遇到的问题,主要是二次签名那里,微信的官方文档写的太简洁了!!!

感谢观看,如果能帮到你,那真是太好了。。。




 


 

 

 

posted @ 2019-11-27 11:32  路边一草鞋  阅读(1664)  评论(0编辑  收藏  举报