一次性解决微信支付-JSAPI支付问题(想把微信支付JSAPI文档撰写者按在地上摩擦)

        最近一个项目需要接入微信支付,所以在现有的项目中接入这个功能,但是最终发现,微信支付是个大坑,至少我认为微信支付文档的撰写者应该是小学水平,又或者是幼儿园水平,写文档的能力简直无语,很多关键性的细节居然是概括或者全局描述,一个简单的支付校验,整整花去我一天时间,真的是怀疑了自己的智商。

        至于说怎么解决的,是因为我终于看到两字”假如“,原来参数举例是不对的,只是打了个比方,参数格式也不是蛇形的,也只是打了个比方,这个时候,真的想把微信支付的文档撰写者按在地上摩擦,以下是截图证据:

好了废话不多说了,下面开始说明:

一、准备工作:

1、微信公众号,appid和appsecret(这里不做赘述,相信大家都没有问题)

2、商户号,mchId,证书,申请授权目录,申请商户API密钥(基本没有问题,如果有问题,给我留言,我来补上)

3、下载微信支付JSAPI的demo,地址是https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1,下载完了以后不能直接使用,因为按照sdk中的readme,是无法正常使用的(对的,这个就是微信的sdk和demo,就是这么神奇,官方出的也不能用)。

二、下面是对这些不完整进行修改的地方修改如下:

1、WXPayConfig.java文件,所有的abstract前加上public,其中有一个处理doMain的需要具体实现,如下:

/**
 * 获取WXPayDomain, 用于多域名容灾自动切换
 *
 * @return
 */
abstract IWXPayDomain getWXPayDomain();

改成

 /**
 * 获取WXPayDomain, 用于多域名容灾自动切换
 *
 * @return
 */
public IWXPayDomain getWXPayDomain() {
	IWXPayDomain iwxPayDomain = new IWXPayDomain() {
		public void report(String domain, long elapsedTimeMillis, Exception ex) {

		}

		public DomainInfo getDomain(WXPayConfig config) {
			return new IWXPayDomain.DomainInfo(WXPayConstants.DOMAIN_API, true);
		}
	};
	return iwxPayDomain;
}

 2、然后编译成jar包,在引用的过程,需要创建一个WXConfig.java,复制下面代码:

import com.github.wxpay.sdk.IWXPayDomain;
import com.github.wxpay.sdk.WXPayConfig;
import com.github.wxpay.sdk.WXPayConstants;

import java.io.*;
public class WXConfig extends WXPayConfig {

    private byte[] certData;

    public WXConfig() throws Exception {
        //此处是微信支付安全证书存放的位置,证书需自行下载
        //下载地址:登录微信商户平台-账户中心-API安全-API证书
        //动态读取安全证书写法可参考我的另一篇文章:
        //https://blog.csdn.net/qq_36928715/article/details/104656618
//        String certPath = "F:/cert/apiclient_cert.p12";
        String certPath = "/data/cert/apiclient_cert.p12";
        File file = new File(certPath);
        InputStream certStream = new FileInputStream(file);
        this.certData = new byte[(int) file.length()];
        certStream.read(this.certData);
        certStream.close();
    }

    //微信公众号appid
    public String getAppID() {
        return "wx2323423423423423";
    }

    //商户号
    public String getMchID() {
        return "160923423423";
    }

    public String getKey() {
        return "GHJs34223423423423423423423";//32位商户api密钥
    }

    public InputStream getCertStream() {
        ByteArrayInputStream certBis = new ByteArrayInputStream(this.certData);
        return certBis;
    }

    public int getHttpConnectTimeoutMs() {
        return 8000;
    }

    public int getHttpReadTimeoutMs() {
        return 10000;
    }

}

3、然后统一下单,且计算paySign,paySign签名的值是appId,nonceStr,timeStamp,package四个参数(跟官方文档提的那个一毛线关系都没有,因为他写了个假如,所以他也没说是真的,就让你自己猜吧,加密方式必须是MD5,不要问为什么,官方就是这么high),尽量调用微信sdk内置的签名方法,代码如下:

WXConfig config = new WXConfig();
WXPay wxpay = new WXPay(config);

Map<String, String> data = new HashMap<String, String>();
data.put("body", "腾讯充值中心-QQ会员充值");
data.put("out_trade_no", "2016090910595900000012");
data.put("device_info", "WEB");
data.put("fee_type", "CNY");
data.put("total_fee", "1");
data.put("spbill_create_ip", "123.12.12.123");
data.put("notify_url", "http://www.example.com/wxpay/notify");
data.put("trade_type", "JSAPI");  
data.put("product_id", "12");
data.put("openid", "dhajkgdhjaghj13267816381");
data.put("sign_type", "MD5");


Map<String, String> resp = wxpay.unifiedOrder(data);
//后端生成paySign给前端,放置签名失败
Date date=new Date();
String sec=String.valueOf(date.getTime()/1000);
Map map = new HashMap();
map.put("appId", config.getAppID());// 公众号id
map.put("nonceStr",resp.get("nonce_str"));// 随机字符串
map.put("timeStamp",sec);
map.put("package", "prepay_id="+resp.get("prepay_id"));
map.put("signType", "MD5");
String sign = WXPayUtil.generateSignature(map,config.getKey());
map.put("paySign", sign);

4、前端调用:

WeixinJSBridge.invoke('getBrandWCPayRequest', {
   "appId": wxObj.appid,//公众号ID,由商户传入
   "timeStamp": wxObj.timeStamp,//不要自己生成,取后端传回的
   "nonceStr": wxObj.nonceStr, //不要自己生成,取后端传回的随机串
   "package": "prepay_id=" + wxObj.prepayId,//预付订单
   "signType": "MD5",//微信签名方式:
   "paySign": wxObj.signType //不要自己生成,取后端传回的微信签名 
 },
   function (res) {
	if (res.err_msg == "get_brand_wcpay_request:ok") {
	  // 使用以上方式判断前端返回,微信团队郑重提示:
	  //res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
	  console.log(res);
	}
});

5、到此就OK了。下面我会把修好的sdk和调用的代码上传,提供下载:

微信支付JSAPI支付修改版本wxpay-sdk-3.0.9

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

极羽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值