之前做过微信公众号的项目,在微信公众号里可以购买公司提供的服务,因为项目是基于微信端,所以使用的是微信公众账号支付(wx_pub)(也叫微信 JSAPI 支付),现在项目改进,要求在微信浏览器外也能实现微信支付,微信外部浏览器的支付是微信h5支付(wx_wap)(也叫微信 WAP 支付)。
ping++号称几行代码就能搞定支付,对这两种常见场景的支付提供了很简便地调用方法。
两者区别:
wx_pub:适用于微信内置浏览器的程序,需要获取open_id。
wx_wap:适用于微信外部浏览器的程序,无需open_id,相对于简单。
因为微信公众号支付(wx_pub)需要获取open_id,因此在非微信浏览器我们经常会看到这种界面,这个界面就是为了拿到open_id。
如何获取微信open_id 官方文档
1.授权用静默授权即可,首先获取code
https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
如果用户同意授权,页面将跳转至 redirect_uri/?code=CODE&state=STATE。若用户禁止授权,则重定向后不会带上code参数,仅会带上state参数redirect_uri?state=STATE
2.获取code后,请求以下链接获取access_token:
https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
请求成功后,返回的数据中可获得openid,进而可进行下一步的支付。
微信h5支付是在Safari、谷歌、UC等非微信浏览器的网页直接唤起微信并调用支付,不需要获取open_id,相较简单
步骤如下:
服务端
首先服务端需要获取charge对象,Ping++的charge对象可查阅官方文档。
你可以创建一个 charge 对象向用户收款。charge 是一个支付凭据对象,所有和支付相关的要素信息都存储在这个对象中,你的服务端可以通过发起支付请求来创建一个新的 charge 对象,也可以随时查询一个或者多个 charge 对象的状态。每个 charge 对象都拥有一个标识 id,该 id 在 Ping++ 系统内唯一。
不同支付方式的charge对象里的支付渠道channel属性不一样,支付渠道额外参数extra属性值也不一样
常见的channel属性值:
extra属性:
wx_pub:open_id必传。点此参考 如何获取 open_id
。
wx_wap:需要传result_url,支付完成的回调地址,供支付成功前端跳转使用
Java代码:
String payChannel = isWxAgent?"wx_pub":"wx_wap";
Charge charge = pay(request,clientIp,amount.doubleValue(),payChannel,orderNo,subject,body,openId);
/** * 创建支付 * @param request * @param clientIp * @param amount * @param channel * @param orderNo * @param subject * @param body * @param successUrl * @return * @throws AuthenticationException * @throws InvalidRequestException * @throws APIConnectionException * @throws APIException * @throws ChannelException */private static Charge pay(HttpServletRequest request,String clientIp, double amount, String channel,String orderNo, String subject, String body,String openId) throws AuthenticationException, InvalidRequestException, APIConnectionException, APIException, ChannelException { Pingpp.apiKey = APIKEY; System.setProperty("https.protocols", "TLSv1.2"); Pingpp.privateKeyPath = request.getSession().getServletContext().getRealPath("/rsa_private_key.pem"); Map chargeParams = new HashMap(1); Map app = new HashMap(8); Map extra = new HashMap<>(1); if(StringUtils.isNotBlank(openId)){ extra.put("open_id",openId); }else{ extra.put("result_url","https://xxx.com/pay/success"); } app.put("id", APPID); chargeParams.put("app", app); chargeParams.put("amount", amount); chargeParams.put("channel", channel); chargeParams.put("currency", "cny"); chargeParams.put("client_ip", clientIp); chargeParams.put("order_no", orderNo); chargeParams.put("subject", subject); chargeParams.put("body", body); chargeParams.put("extra", extra); Charge charge = Charge.create(chargeParams); System.out.println("调用支付接口参数:"+JSONObject.toJSONString(charge)); return charge;}
前端
一:引入js文件
或者使用 npm 下载 npm install pingpp-js ,然后使用 :
var pingpp = require('pingpp-js');
二:点击支付按钮,请求后台接口,将支付方式,用户id等参数传给后台,后台处理后返回一个charge对象。
在 charge 正确的前提下,调用 js的createPayment方法后会直接跳入第三方的支付界面,然后用户完成支付动作。
var charge_url = "服务器接口地址";
$.ajax({
type:"post",
url:charge_url,
data:{
"pay_way":pay_way, //支付渠道 wx_pub或wx_wap
"user_id":user_id, //用户id
}
success:function(res){
var charge = res.data.charge;
console.log(charge);
//调用支付
wap_pay(charge);
}
});
//调用ping++ H5支付
function wap_pay(charge) {
pingpp.createPayment(object, function(result, err){
// object 需是 Charge/Order/Recharge 的 JSON 字符串
// 可按需使用 alert 方法弹出 log
//console.log(JSON.stringify(object));
console.log("result:" + result);
console.log("err.msg:" + err.msg);
console.log("err.extra:" + err.extra);
if (result == "success") {
// 只有微信JSAPI (wx_pub)、微信小程序(wx_lite)、QQ 公众号 (qpay_pub)、支付宝小程序(alipay_lite)支付成功的结果会在这里返回,其他的支付结果都会跳转到 extra 中对应的 URL
} else if (result == "fail") {
// Ping++ 对象 object 不正确或者微信JSAPI/微信小程序/QQ公众号支付失败时会在此处返回
} else if (result == "cancel") {
// 微信JSAPI、微信小程序、QQ 公众号、支付宝小程序支付取消支付
}
});
}
只有微信JSAPI (wx_pub)、微信小程序(wx_lite)、QQ 公众号 (qpay_pub)、支付宝小程序(alipay_lite)支付成功的结果会在这里返回,其他的支付结果都会跳转到 extra 中对应的 URL
注意:微信公众账号支付的结果会在“success”里返回,微信H5支付的结果会返回在服务端定义在extra的result_url链接,我当时支付成功没有跳转回调就是这里踩坑
最后附上ping++官方前端接入文档
原文作者技术博客:https://www.jianshu.com/u/ac4daaeecdfe
95后前端妹子一枚,爱阅读,爱交友,将工作中遇到的问题记录在这里,希望给每一个看到的你能带来一点帮助。
欢迎留言交流