大鹏一日同风起,扶摇直上九万里。这篇文章主要讲述APP调用微信支付相关的知识,希望能为你提供帮助。
最近项目中用到的微信支付,记录一下遇到的问题。。。
官方文档地址:https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=8_1
前期的一些准备工作就不记录,就是一些必须的参数,直接进入主题
1.统一下单
/**
* @Description: 统一下单
* @Param: []
* @return: void
* @Author: Mr.Li
* @Date: 2019/10/26
*/
public static Map< String, String> payMoney(int classify, BigDecimal money, String orderNum, String goodsDescribe,
String ipPath) {
//订单分类 classify 1:发布红包,2:需求订单,3:技能,4:商品订单,5:会员升级,6:奖品运费
//微信支付金额的单位是分
String payMoney = money.multiply(new BigDecimal("100"))
.stripTrailingZeros().toPlainString();
MyWxPayConfig ourWxPayConfig;
try {
ourWxPayConfig = new MyWxPayConfig();
WXPay wxPay = new WXPay(ourWxPayConfig);
//orderNum商户系统内部订单号,要求32个字符内,只能是数字、大小写字母_-|*且在同一个商户号下唯一。
//商品描述交易字段格式根据不同的应用场景按照以下格式:APP— — 需传入应用市场上的APP名字-实际商品名称,天天爱消除-游戏充值。
String body = "XX-" + goodsDescribe;
//根据微信支付api来设置
Map< String, String> data = https://www.songbingjia.com/android/new HashMap< > ();
data.put("appid", ourWxPayConfig.getAppID()); //微信开放平台审核通过的应用APPID
data.put("mch_id", ourWxPayConfig.getMchID()); //微信支付分配的商户号
data.put("trade_type", "APP"); //支付场景 APP 微信app支付 JSAPI 公众号支付NATIVE 扫码支付
data.put("notify_url", ourWxPayConfig.getNotifyUrl()); //回调地址
data.put("spbill_create_ip", "XXXXXXXXX"); //终端ip
data.put("total_fee", payMoney); //订单总金额
data.put("fee_type", "CNY"); //默认人民币
data.put("out_trade_no", orderNum); //商户平台生成的唯一订单号
data.put("body", body);
data.put("nonce_str", WXPayUtil.generateNonceStr()); // 随机字符串,不长于32位
data.put("sign", WXPayUtil.generateSignature(data, ourWxPayConfig.getKey())); //签名
data.put("attach", classify + "");
/** wxService.unifiedOrder 这个方法中调用微信统一下单接口 */
Map< String, String> respData;
respData = https://www.songbingjia.com/android/wxPay.unifiedOrder(data);
if (respData.get("return_code").equals("SUCCESS")) {
//二次签名
//这里就是重点了,当时也是在这里卡了很久。统一下单成功之后,拿到微信后台返回结果.再次计算签名,
//而且注意的是二次签名和统一下单的时候计算签名的参数名不相同,也就是下面这些参数。
//当时做的时候不晓得要二次签名,就直接把统一下单的签名返回给前端,再调起微信支付,结果一直返回-1
String time = (System.currentTimeMillis() + "").substring(0, 10); //时间戳,必须是10位的
//返回给APP端的参数,APP端再调起支付接口
Map< String, String> repData = https://www.songbingjia.com/android/new HashMap< > ();
repData.put("appid", ourWxPayConfig.getAppID()); //appid
repData.put("partnerid", ourWxPayConfig.getMchID()); //mchId
repData.put("prepayid", respData.get("prepay_id")); //统一下单成成之后返回的prepay_id
repData.put("package", "Sign=WXPay"); //直接写死的
repData.put("noncestr", respData.get("nonce_str")); //统一下单成功之后返回的nonce_str
repData.put("timestamp", time);
String sign = WXPayUtil.generateSignature(repData, ourWxPayConfig.getKey()); //再次计算签名
repData.put("sign",sign);
//将repDate返回给前端,就可以支付了
return repData;
}
return null;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* @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 = https://www.songbingjia.com/android/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就行了。
上面这些就是整个微信支付遇到的问题,主要是二次签名那里,微信的官方文档写的太简洁了!!!
感谢观看,如果能帮到你,那真是太好了。。。
【APP调用微信支付】
推荐阅读
- uniapp实现tab选项卡
- 六(Appium元素定位xpath定位方式)
- 如何利用主题分析获得更好的用户体验
- 线框的问题,直接达到高保真!
- 可穿戴技术(它如何运作以及为什么起作用)
- 停止设计垃圾(设计持久接口的指南)
- 家庭智能物联网家庭(物联网的驯化)
- 前方危险(Telltale标志是时候引入UX专家了)
- Shopify设计技巧和UX最佳实践