关于微信学习之微信公众号支付开发

关于微信支付初学者一定有很多的疑问,首先我们需要结合一下自己的程序操作微信支付所需要的业务流程。

1、如我这边需要开发一个公众号支付:

  1. 首先用户扫码访问后台(或者通过公众号直接进入,点击一个支付请求按钮)
  2. 后台处理(分析)请求的数据,返回处理结果给前端
  3. 前端需要显示处理结果(金额、商品信息、等….)并弹出微信支付输入密码
  4. 用户输入密码后,请求微信并返回支付结果(这里是微信帮我们完成的)
  5. 支付完成,微信会返回支付结果回调,到了这里我们可以处理支付的结果,比如修改数据库状态
  6. 可能用户后悔了,我们需要做微信退款(关于退款这边就不多说了)

2、开发流程:

(1)获取用户授权(分为静默授权 和 非静默授权两种)

这里我们需要两个参数分别是:APP_ID 这个我们在公众号上都能得到。

我们调用微信的接口获取授权
https://open.weixin.qq.com/connect/oauth2/authorize


需要的参数是:
appid(公众号上开发平台需要的唯一应用ID)、
redirect_uri(需要授权的页面地址,这里的这个地址是必须在公众号里填写并且是完整域名的)、
scope(snsapi_base为静默授权)

这里是我拼接完成的URL:
https://open.weixin.qq.com/connect/oauth2/authorize?appid=APP_ID&redirect_uri=
URL地址 &response_type=code&scope=snsapi_base&state=随意字符串#wechat_redirect

接下来我们放到微信里面试一试吧!

静默授权我们看不到效果:吧scope改成【snsapi_userinfo
ps:静默授权会直接返回Code下面我们需要这个Code来做统一预支付接口
以下是微信上面运行的效果

(2)调用统一下单接口获取预支付id这里需要在公众号开发平台做回调URL
这里会使用授权返回的Code来调用预支付接口
微信官方给了个参数的详细说明:
https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1

后台处理逻辑我这边就不多做解释,只贴出关键代码,微信官方API文档,已经示例的Demo都有详细的注释。
我们需要建一个类存储交互必要的常量一遍以后使用
public class PayConfigUtil {
    public static String APP_ID = "*******************";//微信开放平台应用ID
    public static String APP_SECRET="*******************";//应用对应的凭证
    public static String MCH_ID = "*******************";//商业号
    public static String API_KEY = "*******************";//API key
    public static String UFDODER_URL="*******************";//微信开发平台应用id
    public static String NOTIFY_URL = "*******************";//回调地址
    public static String CHARTSET = "UTF-8";//字符编码

}


//微信授权并发送订单
    @RequestMapping(value="interface/weixin_pay")
    @ResponseBody
    public String weixin_pay(String money,String phone,String code,HttpServletResponse response,HttpServletRequest request) throws Exception {
        Results results=new Results();
        PrintWriter out =response.getWriter();
            //金额转化为分为单位
            String order_price =((int)((Double.parseDouble(money)) * 100)) + "";
            String openid = getOpenId(code,PayConfigUtil.APP_ID,PayConfigUtil.API_KEY);
            String currTime = PayCommonUtil.getCurrTime();
            //8位日期
            String strTime = currTime.substring(8, currTime.length());
            //四位随机数
            String strRandom =PayCommonUtil.buildRandom(4) + "";
            //10位序列号,可以自行调整。
            String strReq = strTime + strRandom;
            String appid=PayConfigUtil.APP_ID;
            //随机数 
            String nonce_str = strReq;
            //商户订单号
            String out_trade_no ="HZXY"+currTime+"WX"; //订单号 
            results.setTradeNo(out_trade_no);
            //订单生成的机器 IP
            String spbill_create_ip = request.getRemoteAddr();
            SortedMap<Object, Object> packageParams = new TreeMap<Object, Object>();
            packageParams.put("appid", PayConfigUtil.APP_ID);  
            packageParams.put("mch_id", PayConfigUtil.MCH_ID);  
            packageParams.put("nonce_str", nonce_str);  
            packageParams.put("body", phone);   
            packageParams.put("out_trade_no", out_trade_no);  
            packageParams.put("total_fee", order_price);    
            packageParams.put("spbill_create_ip", spbill_create_ip);  
            packageParams.put("notify_url", PayConfigUtil.NOTIFY_URL);      
            packageParams.put("trade_type", "JSAPI");  
            packageParams.put("openid", openid);
            System.out.println("openid"+openid);
            RequestHandler reqHandler = new RequestHandler(request, response);
            reqHandler.init(appid, PayConfigUtil.APP_SECRET, PayConfigUtil.API_KEY);
            String sign = reqHandler.createSign(packageParams);
            packageParams.put("sign", sign);
            System.out.println("aa"+sign);
            String requestXML = PayCommonUtil.getRequestXml(packageParams);
            String resXml = HttpUtil.postData(PayConfigUtil.UFDODER_URL, requestXML);
            Map map = XMLUtil.doXMLParse(resXml);
            String prepay_id = (String) map.get("prepay_id");
            String time=String.valueOf(System.currentTimeMillis() / 1000);
            SortedMap<Object, Object> finalpackage = new TreeMap<Object, Object>();
            String timestamp = time;
            String packages = "prepay_id="+prepay_id;
            finalpackage.put("appId", appid);  
            finalpackage.put("timeStamp", timestamp);  
            finalpackage.put("nonceStr", nonce_str);  
            finalpackage.put("package", packages);  
            finalpackage.put("signType", "MD5");
            String paySign = reqHandler.createSign(finalpackage);
            System.out.println("dd"+paySign);
            results.setTimestamp(timestamp);
            results.setNonceStr(nonce_str);
            results.setPaySign(paySign);
            results.setAppId(appid);
            results.setOpenId(openid);
            results.setPrepay_id(packages);
        }else{
            results.setEquipment("3");
        }
        out.print(JsonUtil.getJsonString4JavaPOJO(results));
        return null;
    }
这里微信官方的Api 有预支付参数的详细介绍这边就不多说了,我们这边主要存入金额,与用户授权成功之后返回的Code,
当然这个需要用户前端点击支付传递过来,后端解析完成,通过微信官方的API 生成xml报文,返回给前端处理

(3)前端页面使用微信支付内置的接收请求js


    $.ajax({
                cache: true,
                type: "POST",
                url:url,
                data:{"type":type,"money":spans,"phone":phone,"code":code},// 你的formid
                async: false,
                success: function(res){  
                var obj = eval("("+res+")");
                equipment=obj.equipment;
                if(equipment=="1"){
                window.location.href=obj.orderNumber;
                }else if(equipment=="2"){
                 WeixinJSBridge.invoke('getBrandWCPayRequest',{
                        "appId" : obj.appId, //公众号名称,由商户传入  
                        "timeStamp" : obj.timestamp, //时间戳,自 1970 年以来的秒数  
                        "nonceStr" : obj.nonceStr, //随机串  
                        "package" :obj.prepay_id, //商品包信息
                        "signType" : "MD5", //微信签名方式:  
                        "paySign" : obj.sign //微信签名  
                 },function(res) {
                    /* WeixinJSBridge.log(res.err_msg); */
                    if (res.err_msg == 'get_brand_wcpay_request:ok') {
                    if(status!=1){
                    window.location.href="index.jsp?qrCode="+cabinetNo; 
                    }else{
                    window.location.href="index.jsp?qrCode="+cabinetNo; 
                    }
                    } else if (res.err_msg == "get_brand_wcpay_request:cancel") {
                       window.location.href="index.jsp?qrCode="+cabinetNo;
                    } else {
                    }
                    });
                }else if(equipment=="3"){
                 alert("当前手机号码不存在!");
                }
                },  
                error: function(res){ 
                  alert("请求失败!");
                  }  
                });
                这里是输入正确的密码或者指纹验证完成,微信API会返回页面一个确认支付完成的页面,
                而支付完成的页面跳转也在这边完成。

(4)支付完成后微信返回回调,后台处理结果
完成以上三个步骤之后 微信会返回一个回调给服务器。
就是前面配置的NOTIFY_URL ,这个地址必须是域名,并且在微信商户平台设置

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

梦想飞翔的鸟

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

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

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

打赏作者

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

抵扣说明:

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

余额充值