开发微信支付-公众号支付

走了不少的弯路,记录一下。
本博客借鉴自手把手教你–JAVA微信支付
尽信书,不如无书。

所需参数:
APPID(appid),APPSECEPT(appsecret),商户ID(mch_id),API密钥(paternerKey)
其他都好搞API密钥(paternerKey)进入商品平台操作下。

第一步:配置相关域名

1.进入商品平台设置授权目录:直接用一级域名即可
2.openid网页授权域名配置用于获取openid。

第二步:配置相关参数*

去官方下载例子
https://download.csdn.net/download/weixin_40927315/10855765
这里我打包好的一个积分,建议从官网下。
慢慢找的52个jar包
https://download.csdn.net/download/weixin_40927315/10856057

  1.    appid APPID (已有)
    
  2.    mch_id 商户ID (已有)
    
  3.    nonce_str 随机字符串
    
  4.    sign 签名
    
  5.    body 所支付的名称
    
  6.    out_trade_no 咱们自己所提供的订单号,需要唯一
    
  7.    total_fee 支付金额
    
  8.    spbill_create_ip  IP地址
    
  9.    notify_url 回调地址
    
  10.   trade_type 支付类型
    
  11.   openid 支付人的微信公众号对应的唯一标识
    

3:随机字符串用WXPayUtil中的generateNonceStr()即可,就是生成UUID的方法
4:用WXPayUtil中的generateSignature(finalMap<String, String> data, String key)方法,data是将除了sign外,其他10个参数放到map中,key是四大配置参数中的API秘钥(paternerKey)
8:用户端ip,估计就是用户点充值时的ip

    String ip = req.getHeader("x-forwarded-for");
      if ((ip == null) || (ip.length() == 0) || ("unknown".equalsIgnoreCase(ip))) {
        ip = req.getHeader("Proxy-Client-IP");
      }
      if ((ip == null) || (ip.length() == 0) || ("unknown".equalsIgnoreCase(ip))) {
        ip = req.getHeader("WL-Proxy-Client-IP");
      }
      if ((ip == null) || (ip.length() == 0) || ("unknown".equalsIgnoreCase(ip))) {
        ip = req.getRemoteAddr();
      }
      if (ip.indexOf(",") != -1) {
        String[] ips = ip.split(",");
        ip = ips[0].trim();
      }

10:公众号支付此处给“JSAPI”

11.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
注意:1. redirect_uri参数:授权后重定向的回调链接地址, 请使用 urlEncode 对链接进行处理。
2. scope:用snsapi_base 。
这里的回调链接地址用于接收code,snsapi_base为静默授权

11.2
取得code后,请求以下链接获取access_token: https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code

{ "access_token":"ACCESS_TOKEN",
"expires_in":7200,
"refresh_token":"REFRESH_TOKEN",
"openid":"OPENID",//就是这个值
"scope":"SCOPE" }

这里这个授权access_token和全局调用那个不一样,这个可以无限调用,这个access_token也有时间,但是基本
上我去调用的时候都只用了几秒用来判断用户身份,这里应该可以搞个机制把它存下来,专用于获取openid,
但是这个access_token不是唯一的,每个用户一个,不能像全局调用那个一样去判断。

ok,参数都到位了!
post请求的方法,请求微信"统一下单接口https://api.mch.weixin.qq.com/pay/unifiedorder
发送前先用WXPayUtil工具类中的public static String mapToXml(Map<String,String> data)方法将有11个参数的map转成XML格式

然后你坚持到这里的话会看到这个:

<xml>
  <return_code><![CDATA[SUCCESS]]></return_code>
  <return_msg><![CDATA[OK]]></return_msg>
  <appid><![CDATA[wx2421b1c4370ec43b]]></appid>
  <mch_id><![CDATA[10000100]]></mch_id>
  <nonce_str><![CDATA[IITRi8Iabbblz1Jc]]></nonce_str>
  <openid><![CDATA[oUpF8uMuAJO_M2pxb1Q9zNjWeS6o]]></openid>
  <sign><![CDATA[7921E432F65EB8ED0CE9755F0E86D72F]]></sign>
  <result_code><![CDATA[SUCCESS]]></result_code>
  <prepay_id><![CDATA[wx201411101639507cbf6ffd8b0779950874]]></prepay_id>
  <trade_type><![CDATA[JSAPI]]></trade_type>
</xml>

走到这里其实就为了得到prepay_id

第三步:支付

之前是预支付,现在可以用前端调用支付了。
首先:

1.        appId:

2.        timestamp:时间戳(newDate())

3.        nonceStr:随机字符串,再次用WXPayUtil中的generateNonceStr();

4.        package:”prepay_id=“+ prepay_id

5.        signType:MD5

6.    paySign:签名算法 ,用WXPayUtil中的publicstatic String generateSignature(final Map<String, String> data, Stringkey)方法,data是将除了paySign外,其他5个参数放到map中,keyAPI秘(paternerKey);
--------------------- -----------------------------------------------------------------------------------------------------------------------------

前端代码:
wx.config({
            debug: false,
            appId: "appId",
            timestamp:"<%=timeStamp%>",
            nonceStr:"<%=nonceStr%>",
            signature:"<%=map.get("signature")%>",
            jsApiList : ['chooseWXPay']
        });//end_config
        //步骤五
        wx.error(function(res) {
            alert("出错了:" + res.errMsg);
        });
function onBridgeReady(){
   
          wx.chooseWXPay({
          "appId":"appId",     //公众号名称,由商户传入     
          "timestamp":"<%=timeStamp%>",         //时间戳,自1970年以来的秒数     
          "nonceStr":"<%=nonceStr%>", //随机串     
          "package":"<%=packages%>",     
          "signType":"MD5",         //微信签名方式:     
          "paySign":"<%=paySign%>", //微信签名 
            success:function (res){
            // 支付成功后的回调函数
                 alert("支付成功!");
                 window.location.href="回调地址";
        },
        //如果你按照正常的jQuery逻辑,下面如果发送错误,一定是error,那你就太天真了,当然,jssdk文档中也有提到
        fail: function(res) {
            //接口调用失败时执行的回调函数。
               alert(res.errMsg);
        },
        complete: function(res) {
            //接口调用完成时执行的回调函数,无论成功或失败都会执行。
        },
        cancel: function(res) {
            //用户点击取消时的回调函数,仅部分有用户取消操作的api才会用到。
        },
        trigger: function(res) {
            //监听Menu中的按钮点击时触发的方法,该方法仅支持Menu中的相关接口。
        }
    }); 

===================================================================================
注意此处:前面是微信接口配置参数,后面是支付接口参数。有人说这里的时间戳必须一样,经本人测试纯属谣言,这里够幸运的话点下确定,调用onBridgeReady()可以直接调出微信支付的界面!
一般来说,这里会签名错误,一定要反复检查签名和参数,尤其package,这个是包名,不能当变量!

**最后简单说下回调地址,这个地址非常重要,你只有看到回调成功才是真的成功,
然后你要在回调里做业务处理!*
/*****************微信回调返回数据样例*******************
     $post = '<xml>
        <return_code><![CDATA[SUCCESS]]></return_code>
        <return_msg><![CDATA[OK]]></return_msg>
        <appid><![CDATA[wx2421b1c4370ec43b]]></appid>
        <mch_id><![CDATA[10000100]]></mch_id>
        <nonce_str><![CDATA[IITRi8Iabbblz1Jc]]></nonce_str>
        <sign><![CDATA[7921E432F65EB8ED0CE9755F0E86D72F]]></sign>
        <result_code><![CDATA[SUCCESS]]></result_code>
        <prepay_id><![CDATA[wx201411101639507cbf6ffd8b0779950874]]></prepay_id>
        <trade_type><![CDATA[APP]]></trade_type>
        </xml>';
     String wxNotifyXml = "";
      try {
        DataInputStream in = new DataInputStream(req.getInputStream());
        byte[] dataOrigin = new byte[req.getContentLength()];
        in.readFully(dataOrigin);

        if (in != null) in.close();
        wxNotifyXml = new String(dataOrigin);
      } catch (IOException e) {
        e.printStackTrace();
      }
 Map notifyMap = WXPayUtil.xmlToMap(wxNotifyXml);
 String  openid =(String)notifyMap.get("openid"); 

  if ((((String)notifyMap.get("return_code")).equals("SUCCESS")) && 
          (((String)notifyMap.get("result_code")).equals("SUCCESS"))) {
                    //业务处理代码
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

weixin_mmp14948

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

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

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

打赏作者

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

抵扣说明:

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

余额充值