微信公众号支付开发全过程

需求:把游戏里的商城转移到微信公众号上



微信公众号支付开发的准备过程:

需要注册一个公众号,然后开通微信支付功能(需要5个工作日左右),然后就可以得到APPID,APP_SECRET,商户号,商户key等参数。

开始开发:

1. 调用统一下单接口,获取预支付ID
/** * 用户提交支付,获取微信支付订单接口 */ @RequestMapping(value="/pay") public ModelAndView
pay(HttpServletRequest request,HttpServletResponse response){ ModelAndView mv =
new ModelAndView(); String GZHID = "wxfd7c065eee11112222";// 微信公众号id String
GZHSecret = "b5b3a627f5d1f8888888888888";// 微信公众号密钥id String SHHID =
"111111111";// 财付通商户号 String SHHKEY = "mmmmmmmmmmmmmmm";// 商户号对应的密钥
/*------1.获取参数信息------- */ //商户订单号 String out_trade_no=
request.getParameter("state"); //价格 String money =
request.getParameter("money"); //金额转化为分为单位 String finalmoney =
WeChat.getMoney(money); //获取用户的code String code = request.getParameter("code");
/*------2.根据code获取微信用户的openId和access_token------- */ //注:
如果后台程序之前已经得到了用户的openId 可以不需要这一步,直接从存放openId的位置或session中获取就可以。
//toPay.jsp页面中提交的url路径也就不需要再经过微信重定向。写成:http://localhost:8080/项目名/wechat/pay?money=${sumPrice}&state=${orderId}
String openid=null; try { List<Object> list = accessToken(code);
openid=list.get(1).toString(); } catch (IOException e) {
logger.error("根据code获取微信用户的openId出现错误", e); mv.setViewName("error"); return mv;
} /*------3.生成预支付订单需要的的package数据------- */ //随机数 String nonce_str=
MD5.getMessageDigest(String.valueOf(new Random().nextInt(10000)).getBytes());
//订单生成的机器 IP String spbill_create_ip = request.getRemoteAddr(); //交易类型
:jsapi代表微信公众号支付 String trade_type = "JSAPI"; //这里notify_url是
微信处理完支付后的回调的应用系统接口url。 String notify_url
="http://69a6a38e.ngrok.natapp.cn/heyi-console/wechat/weixinNotify";
SortedMap<String, String> packageParams = new TreeMap<String, String>();
packageParams.put("appid", GZHID); packageParams.put("mch_id", SHHID);
packageParams.put("nonce_str", nonce_str); packageParams.put("body", "费用");
packageParams.put("out_trade_no", out_trade_no); packageParams.put("total_fee",
finalmoney); packageParams.put("spbill_create_ip", spbill_create_ip);
packageParams.put("notify_url", notify_url); packageParams.put("trade_type",
trade_type); packageParams.put("openid", openid);
/*------4.根据package数据生成预支付订单号的签名sign------- */ RequestHandler reqHandler = new
RequestHandler(request, response); reqHandler.init( GZHID, GZHSecret, SHHKEY);
String sign = reqHandler.createSign(packageParams);
/*------5.生成需要提交给统一支付接口https://api.mch.weixin.qq.com/pay/unifiedorder
的xml数据-------*/ String xml="<xml>"+ "<appid>"+ GZHID+"</appid>"+ "<mch_id>"+
SHHID+"</mch_id>"+ "<nonce_str>"+nonce_str+"</nonce_str>"+
"<sign>"+sign+"</sign>"+ "<body><![CDATA["+"费用"+"]]></body>"+
"<out_trade_no>"+out_trade_no+"</out_trade_no>"+
"<total_fee>"+finalmoney+"</total_fee>"+
"<spbill_create_ip>"+spbill_create_ip+"</spbill_create_ip>"+
"<notify_url>"+notify_url+"</notify_url>"+
"<trade_type>"+trade_type+"</trade_type>"+ "<openid>"+openid+"</openid>"+
"</xml>"; /*------6.调用统一支付接口https://api.mch.weixin.qq.com/pay/unifiedorder
生产预支付订单----------*/ String createOrderURL =
"https://api.mch.weixin.qq.com/pay/unifiedorder"; String prepay_id=""; try {
prepay_id = GetWxOrderno.getPayNo(createOrderURL, xml);
if(prepay_id.equals("")){ mv.addObject("ErrorMsg", "支付错误");
mv.setViewName("error"); return mv; } } catch (Exception e) {
logger.error("统一支付接口获取预支付订单出错", e); mv.setViewName("error"); return mv; }
/*将prepay_id存到库中*/ PageData p = new PageData(); p.put("shopId", out_trade_no);
p.put("prePayId", prepay_id); activityService.updatePrePayId(p);
/*------7.将预支付订单的id和其他信息生成签名并一起返回到jsp页面 ------- */ nonce_str=
MD5.getMessageDigest(String.valueOf(new Random().nextInt(10000)).getBytes());
SortedMap<String, String> finalpackage = new TreeMap<String, String>(); String
timestamp = String.valueOf(System.currentTimeMillis() / 1000); String packages
= "prepay_id="+prepay_id; finalpackage.put("appId", GZHID);
finalpackage.put("timeStamp", timestamp); finalpackage.put("nonceStr",
nonce_str); finalpackage.put("package", packages); finalpackage.put("signType",
"MD5"); String finalsign = reqHandler.createSign(finalpackage);
mv.addObject("appid", GZHID); mv.addObject("timeStamp", timestamp);
mv.addObject("nonceStr", nonce_str); mv.addObject("packageValue", packages);
mv.addObject("paySign", finalsign); mv.addObject("success","ok");
mv.setViewName("wechat/pay"); return mv; }
2. H5调起微信支付的内置JS
<script type="text/javascript"> function onBridgeReady(){
WeixinJSBridge.invoke( 'getBrandWCPayRequest', { "appId" :
"<%=paramsMap.get("appId") %>", //公众号名称,由商户传入
"timeStamp":"<%=paramsMap.get("timeStamp") %>", //时间戳,自1970年以来的秒数 "nonceStr" :
"<%=paramsMap.get("nonceStr")%>", //随机串 "package" :
"<%=paramsMap.get("package")%>", "signType" : "<%=paramsMap.get("signType")%>",
//微信签名方式: "paySign" : "<%=paramsMap.get("paySign")%>" //微信签名 }, function(res){
// 使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回 ok,但并不保证它绝对可靠。 if(res.err_msg
== "get_brand_wcpay_request:ok" ) {//成功
$("#tip_icon").addClass("weui_icon_success"); $("#tip").text("购买成功");
$("#amount").text("恭喜你,获得"+"<%=goodContent%>"); }else if(res.err_msg ==
"get_brand_wcpay_request:cancel" ) {//取消
$("#tip_icon").addClass("weui_icon_warn"); $("#tip").text("用户取消支付"); }else
if(res.err_msg == "get_brand_wcpay_request:fail" ) {//失败
$("#tip_icon").addClass("weui_icon_warn"); $("#tip").text("支付失败"); }else{
$("#tip").text(res.err_msg); } $(".confirm_container").show();
$("#chargeBtn").show(); } ); } if (typeof WeixinJSBridge == "undefined"){ if(
document.addEventListener ){ document.addEventListener('WeixinJSBridgeReady',
onBridgeReady, false); }else if (document.attachEvent){
document.attachEvent('WeixinJSBridgeReady', onBridgeReady);
document.attachEvent('onWeixinJSBridgeReady', onBridgeReady); } }else{
onBridgeReady(); } </script>
3.支付成功之后跳转回自己的系统的某个页面

遇到的问题:

1.在微信商户平台里面需要设置api秘钥(paternerKey),所谓paternerKey意思就是伙伴的秘钥,也就是合作商的秘钥。

需要自定义一个字符串,然后用MD5加密成32位的字符串,然后设置。



2.统一下单接口的容易出错的参数:


1)trade_type==交易类型==取值如下:JSAPI,NATIVE,APP。我们这里使用的JSAPI。标题已经说了,是微信公众号支付。他们的区别,请参考https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_2。


ps:JSAPI--公众号支付、NATIVE--原生扫码支付、APP--app支付,统一下单接口trade_type的传参可参考这里。MICROPAY--刷卡支付,刷卡支付有单独的支付接口,不调用统一下单接口。

2)notify_url==通知地址==接收微信支付异步通知回调地址,通知url必须为直接可访问的url,不能携带参数。


3)sign==签名==官方给的签名算法。https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_3。获取预支付ID时,如果返回值是【签名错误】。那真是的你的签名错了,请仔细核对生成sign的参数名称、参数值和调用统一下单接口的参数名称和参数值

3.要想支付成功,需要在商户号设置支付授权目录。路径应为支付页面的上一级路径。


======================================大功告成=============================================

 

 

友情链接
KaDraw流程图
API参考文档
OK工具箱
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:[email protected]
QQ群:637538335
关注微信