参考微信小程序支付官网 https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=7_3&index=1
后台用 Java 来实现
我用的是 wxpay-sdk这个库,这个库封装了微信统一下单接口、签名等方法,使用起来非常方便。
1. 在 mavne配置文件中添加以下依赖。
com.github.wxpay
wxpay-sdk
0.0.3
2. 编写WxPayConfig类,配置微信支付相关参数(appid,商户号,商户平台key等)
package *****;
import com.github.wxpay.sdk.WXPayConfig;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
/** 配置我们自己的信息 */
public class WxPayConfig implements WXPayConfig {
/** 加载证书 这里证书需要到微信商户平台进行下载 不做退款流程的话不需要*/
private byte [] certData;
public WxPayConfig() throws Exception{
// InputStream certStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("cert/wxpay/apiclient_cert.p12");
// this.certData = IOUtils.toByteArray(certStream);
// certStream.close();
}
/** 设置我们自己的appid
* */
@Override
public String getAppID() {
return "wx--xxxxxxxx";
}
/**
* 微信商户平台 商户号
* */
@Override
public String getMchID() {
return "151460xxxxxx";
}
/**
*
* 微信商户平台 秘钥
* */
@Override
public String getKey() {
return "xxxxxxx.....";
}
@Override
public InputStream getCertStream() {
return new ByteArrayInputStream(this.certData);
}
@Override
public int getHttpConnectTimeoutMs() {
return 0;
}
@Override
public int getHttpReadTimeoutMs() {
return 0;
}
}
3. 生成支付所需参数
小程序端调起微信支付需要几个参数 timeStamp、nonceStr、package、signType、paySign。
wx.requestPayment(
{
'timeStamp': '',
'nonceStr': '',
'package': '',
'signType': 'MD5',
'paySign': '',
'success':function(res){},
'fail':function(res){},
'complete':function(res){}
})
这些参数在后台生成。后台接口如下(仅供参考)
import com.github.wxpay.sdk.WXPayUtil;
import com.github.wxpay.sdk.WXPay;
import xxx.xxx.WxPayConfig;
/**
* 微信小程序 获取支付参数
*
* @param orderId
* @return
*/
@RequestMapping("/wxPrePay")
public Map wxPrePay() {
WxPayConfig ourWxPayConfig;
Map map = new HashMap<>();
try {
ourWxPayConfig = new WxPayConfig();
WXPay wxPay = new WXPay(ourWxPayConfig);
// 根据微信支付api来设置
Map data = new HashMap<>();
data.put("mch_id", ourWxPayConfig.getMchID()); // 商户号
data.put("nonce_str", WXPayUtil.generateNonceStr()); // 随机字符串小于32位
data.put("appid", ourWxPayConfig.getAppID());
data.put("trade_type", "JSAPI"); // 交易类型
data.put("openid", "xxxxxx");//支付用户的 openid,自行实现
data.put("notify_url", "https://xxx.xxx.xxx"); // 微信支付 回调地址
data.put("total_fee", "100.00");// 订单总金额,注意金额单位是 分,并且必须是字符串
data.put("out_trade_no", "8adfw23sfsfsd"); // 交易号
data.put("body", "xxxx订单");
String _sign = WXPayUtil.generateSignature(data, ourWxPayConfig.getKey()); // 签名
data.put("sign", _sign);
/** wxPay.unifiedOrder 这个方法中调用微信统一下单接口 */
Map respData = wxPay.unifiedOrder(data);
//统一下单成功后,获取到 prepay_id(预支付订单ID) 参数,然后拼接 package参数
System.out.println("return==" + respData);
if (respData.get("return_code").equals("SUCCESS")) {
// 返回给APP端的参数,APP端再调起支付接口
Map _repData = new HashMap<>();
_repData.put("appId", ourWxPayConfig.getAppID());
//拼接 package参数
_repData.put("package", "prepay_id="+respData.get("prepay_id"));
_repData.put("nonceStr", respData.get("nonce_str"));
_repData.put("signType", "MD5");
_repData.put("timeStamp", String.valueOf(System.currentTimeMillis() / 1000));
//参数准备好后,进行二次签名
String sign = WXPayUtil.generateSignature(_repData, ourWxPayConfig.getKey());
//组装返回给微信小程序端 的支付参数
Map resmap = new HashMap<>();
resmap.put("nonceStr", _repData.get("nonceStr").toString());
resmap.put("signType", _repData.get("signType").toString());
resmap.put("sign", sign);
resmap.put("timeStamp", _repData.get("timeStamp").toString());
resmap.put("package", _repData.get("package").toString());
return resmap;
} else {
System.out.println("------pay---fail=-------");
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
4.小程序端调用 上面的接口,获取到支付参数,即可调起微信支付。
pay(data){
wx.requestPayment(
{
'timeStamp': data.timeStamp,
'nonceStr': data.nonceStr,
'package': data.package,
'signType': data.signType,
'paySign': data.sign,
'success': function (res) {
wx.showToast({ icon: 'success', title: '支付成功' })
},
'fail': function (res) {
console.log('pay fail', res)
wx.showToast({ icon: 'none', title: '支付失败' })
},
'complete': function (res) {
//console.log('pay complete', res)
}
}
)
}