微信小程序支付的前置准备:
1.微信商户平台账号
2.微信小程序账号
3.微信小程序开通支付接口(个人暂时不支持开通支付)
前台需要的操作:
1.登录获取code,传给后台
2.获取后台传过来的值调用wx.requestPayment方法
后台需要的操作:
1.通过前台传过来的code来获取用户的openId
2.生成sign
3.获取perpay_id
4.再生成一次前台需要的paySign
具体操作:
登录获取code:
wx.login({
success: function(res){
// success
console.log('这里有code',res)
},
fail: function(res) {
// fail
},
complete: function(res) {
// complete
}
})
传到后台:
wx.request({
url: 'https://URL',//后台URL
data: {},//登录获取的code
method: 'GET', // OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT
// header: {}, // 设置请求的 header//后台规定的请求头
//调用了之后无操作一下三个方法可以不写
success: function(res){
// success
},
fail: function(res) {
// fail
},
complete: function(res) {
// complete
}
})
后台通过过code获取oppenid只需要访问这个链接:
https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=前台传过来的CODE&grant_type=authorization_code
生成sign和得到perpay_id(此处后台用JAVA由于后台代码太多,我就放在最后面,有需要的可以自己进行查看)
其中获取perpay_id生成的sign需要的参数是我遇到的一个坑,请一定要注意你往微信传的值都是sign需要的value,其中openId在参数里面写的是否,但是微信小程序支付用到的trade_type是JSAPI,所以微信小程序的openId也是必须的参数。
当这些都准备好了之后你就可以获取perpay_id
接口链接
URL地址:https://api.mch.weixin.qq.com/pay/unifiedorder
这个链接必须是xml格式的,前台是没法调用的。
有了perpay_id之后,在获取paySign(前台需要的)。这里不一定需要后台生成,前台也有相关的代码来生成。他需要的参数:
appId,nonceStr,package,signType,timeStamp,key
这是我遇到的坑二,因为你获取到了perpay_id时他会给你返回一个sign我之前以为是这个。
得到sign的代码:
/**
* 微信支付签名算法sign
* @param characterEncoding
* @param parameters
* @return
*/
@Test
public static String createSign(String characterEncoding,SortedMap<Object,Object> parameters){
StringBuffer sb = new StringBuffer();
Set es = parameters.entrySet();//所有参与传参的参数按照accsii排序(升序)
Iterator it = es.iterator();
while(it.hasNext()) {
Map.Entry entry = (Map.Entry)it.next();
String k = (String)entry.getKey();
Object v = entry.getValue();
if(null != v && !"".equals(v)
&& !"sign".equals(k) && !"key".equals(k)) {
sb.append(k + "=" + v + "&");
}
}
sb.append("key=" + WeChatPayUtils.key);
System.out.println("字符串:"+sb.toString());
String sign = MD5Util.MD5Encode(sb.toString(), characterEncoding).toUpperCase();
return sign;
}
MD5Util工具类代码如下:
package cn.cqzdkj.utils;
import java.security.MessageDigest;
public class MD5Util {
private static String byteArrayToHexString(byte b[]) {
StringBuffer resultSb = new StringBuffer();
for (int i = 0; i < b.length; i++)
resultSb.append(byteToHexString(b[i]));
return resultSb.toString();
}
private static String byteToHexString(byte b) {
int n = b;
if (n < 0)
n += 256;
int d1 = n / 16;
int d2 = n % 16;
return hexDigits[d1] + hexDigits[d2];
}
public static String MD5Encode(String origin, String charsetname) {
String resultString = null;
try {
resultString = new String(origin);
MessageDigest md = MessageDigest.getInstance("MD5");
if (charsetname == null || "".equals(charsetname))
resultString = byteArrayToHexString(md.digest(resultString
.getBytes()));
else
resultString = byteArrayToHexString(md.digest(resultString
.getBytes(charsetname)));
} catch (Exception exception) {
}
return resultString;
}
private static final String hexDigits[] = { "0", "1", "2", "3", "4", "5",
"6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };
}
然后在需要的地方直接调用上面的ctreasign这个方法就行了。
SortedMap<Object,Object> parameters = new TreeMap<Object,Object>();
parameters.put("appid", appid);
parameters.put("mch_id", mch_id);
parameters.put("nonce_str",nonce_str);
parameters.put("body", body);
parameters.put("out_trade_no", "20170215");
parameters.put("total_fee", 1);
parameters.put("spbill_create_ip", "x.x.x.x");
parameters.put("notify_url","http://xxxxx.com");
parameters.put("trade_type", "JSAPI");
parameters.put("openid", "oGY_ZvxxxxxM");
parameters.put("sign","");
String characterEncoding = "UTF-8";
String mySign = createSign(characterEncoding,parameters);
System.out.println("我 的签名是:"+mySign);
干活系列项目地址:
码云:https://gitee.com/mrxu314/xcx_gh
gitHub:https://github.com/mrxu0/xcx_gh
希望这篇文章能够帮助到你们
欢迎大家关注我的公众号吵吵日记: