首页 > 编程 > Java > 正文

微信支付H5调用支付详解(java版)

2019-11-26 13:29:29
字体:
来源:转载
供稿:网友

最近项目需要微信支付,然后看了下微信公众号支付,,虽然不难,但是细节还是需要注意的,用了大半天时间写了个demo,并且完整的测试了一下支付流程,下面分享一下微信公众号支付的经验。

一、配置公众号微信支付 

需要我们配置微信公众号支付地址和测试白名单。

比如:支付JS页面的地址为 http://www.xxx.com/shop/pay/

那此处配置www.xxx.com/shop/pay/

二、开发流程

借用微信公众号支付api(地址 http://pay.weixin.qq.com/wiki/doc/api/index.PHP?chapter=7_4),我们需要开发的为红色标记出的。如下:

三、向微信服务器端下订单

调用统一下单接口,这样就能获取微信支付的prepay_id(http://pay.weixin.qq.com/wiki/doc/api/index.php?chapter=9_1)。

在调用该接口前有几个字段是H5支付必须填写的openid

3.1 获取openid

可以通过网页授权形式(http://mp.weixin.qq.com/wiki/17/c0f37d5704f0b64713d5d2c37b468d75.html

在微信中发送如下链接
https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx520c15f417810387&redirect_uri=要跳转的下订单的url&response_type=code&scope=snsapi_base&state=123#wechat_redirect

3.2 下订单获取prepay_id

代码如下,实际上是通过post发送一个xml 文件,获取微信服务器端发送过来的prepay_id。

import java.io.ByteArrayInputStream; import javaioIOException; import javaioInputStream; import javaioUnsupportedEncodingException; import javautilDate; import javautilHashMap; import javautilIterator; import javautilMap; import javautilMapEntry; import javautilRandom;  import javaxservlethttpHttpServletRequest; import javaxservlethttpHttpServletResponse;  import orgapachecommonscodecdigestDigestUtils; import orgspringframeworkstereotypeController; import orgspringframeworkwebbindannotationRequestMapping; import orgxmlpullvXmlPullParser; import orgxmlpullvXmlPullParserException; import orgxmlpullvXmlPullParserFactory;  import comfasterxmljacksondatabindJsonNode; import comgsonoauthOauth; import comgsonoauthPay; import comgsonutilHttpKit; import comsyutilDatetimeUtil; import comsyutilJsonUtil;  @Controller @RequestMapping("/pay") public class WXPayController {    @RequestMapping(value = "wxprepaydo")   public void jspay(HttpServletRequest request, HttpServletResponse response, String callback) throws Exception {     // 获取openid     String openId = SessionUtilgetAtt(request, "openId");     if (openId == null) {       openId = getUserOpenId(request);     }      String appid = "wx16691fcb0523c1a4";     String paternerKey = "ININGFENG1234567fdfwfdfd1ss234567";          String out_trade_no = getTradeNo();     Map<String, String> paraMap = new HashMap<String, String>();     paraMapput("appid", appid);     paraMapput("attach", "测试");     paraMapput("body", "测试购买支付");     paraMapput("mch_id", "10283271");     paraMapput("nonce_str", create_nonce_str());     paraMapput("openid", openId);     paraMapput("out_trade_no", out_trade_no);     paraMapput("spbill_create_ip", getAddrIp(request));     paraMapput("total_fee", "1");     paraMapput("trade_type", "JSAPI");     paraMapput("notify_url", "http://wwwxxxco/bank/page/wxnotify");     String sign = getSign(paraMap, paternerKey);     paraMapput("sign", sign);      // 统一下单 https://apimchweixinqqcom/pay/unifiedorder     String url = "https://apimchweixinqqcom/pay/unifiedorder";      String xml = ArrayToXml(paraMap);      String xmlStr = HttpKitpost(url, xml);      // 预付商品id     String prepay_id = "";      if (xmlStrindexOf("SUCCESS") != -1) {       Map<String, String> map = doXMLParse(xmlStr);       prepay_id = (String) mapget("prepay_id");     }      Map<String, String> payMap = new HashMap<String, String>();     payMapput("appId", appid);     payMapput("timeStamp", create_timestamp());     payMapput("nonceStr", create_nonce_str());     payMapput("signType", "MD5");     payMapput("package", "prepay_id=" + prepay_id);     String paySign = getSign(payMap, paternerKey);          payMapput("pg", prepay_id);     payMapput("paySign", paySign);               WebUtilresponse(response, WebUtilpackJsonp(callback, JsonUtilwarpJsonNodeResponse(JsonUtilobjectToJsonNode(payMap))toString()));   }    /**    * map转成xml    *    * @param arr    * @return    */   public String ArrayToXml(Map<String, String> arr) {     String xml = "<xml>";      Iterator<Entry<String, String>> iter = arrentrySet()iterator();     while (iterhasNext()) {       Entry<String, String> entry = iternext();       String key = entrygetKey();       String val = entrygetValue();       xml += "<" + key + ">" + val + "</" + key + ">";     }      xml += "</xml>";     return xml;   }    // 获取openId   private String getUserOpenId(HttpServletRequest request) throws Exception {     String code = requestgetParameter("code");     if (code == null) {       String openId = requestgetParameter("openId");       return openId;     }     Oauth o = new Oauth();     String token = ogetToken(code);     JsonNode node = JsonUtilStringToJsonNode(token);     String openId = nodeget("openid")asText();     return openId;   }    private String create_nonce_str() {       String chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";       String res = "";       for (int i = 0; i < 16; i++) {         Random rd = new Random();         res += charscharAt(rdnextInt(charslength() - 1));       }       return res;   }      private String getAddrIp(HttpServletRequest request){     return requestgetRemoteAddr();   }    private String create_timestamp() {     return LongtoString(SystemcurrentTimeMillis() / 1000);   }      private String getTradeNo(){     String timestamp = DatetimeUtilformatDate(new Date(), DatetimeUtilDATETIME_PATTERN);     return "HZNO" + timestamp;   }      private String getSign(Map<String, String> params, String paternerKey )       throws UnsupportedEncodingException {     String string1 = PaycreateSign(params, false);     String stringSignTemp = string1 + "&key=" + paternerKey;     String signValue = DigestUtilsmd5Hex(stringSignTemp)toUpperCase();     return signValue;   }    private Map<String, String> doXMLParse(String xml)       throws XmlPullParserException, IOException {      InputStream inputStream = new ByteArrayInputStream(xmlgetBytes());      Map<String, String> map = null;      XmlPullParser pullParser = XmlPullParserFactorynewInstance()         newPullParser();      pullParsersetInput(inputStream, "UTF-8"); // 为xml设置要解析的xml数据      int eventType = pullParsergetEventType();      while (eventType != XmlPullParserEND_DOCUMENT) {       switch (eventType) {       case XmlPullParserSTART_DOCUMENT:         map = new HashMap<String, String>();         break;        case XmlPullParserSTART_TAG:         String key = pullParsergetName();         if (keyequals("xml"))           break;          String value = pullParsernextText();         mapput(key, value);          break;        case XmlPullParserEND_TAG:         break;        }        eventType = pullParsernext();      }      return map;   }  } 

四、H5支付

H5支付其实很简单,只需要调用微信内嵌浏览器的js方法就行(http://pay.weixin.qq.com/wiki/doc/api/index.php?chapter=7_7

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="spring" uri="http://wwwspringframeworkorg/tags" %> <%   String path = requestgetContextPath();   String basePath = requestgetScheme() + "://" + requestgetServerName() + ":" + requestgetServerPort() + path + "/"; %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 01 Transitional//EN" "http://wwwworg/TR/html4/loosedtd"> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=0, maximum-scale=0, user-scalable=0" /> <meta name="apple-mobile-web-app-capable" content="yes" /> <meta name="apple-mobile-web-app-status-bar-style" content="black" /> <meta name="format-detection" content="telephone=no" /> <title>测试支付</title> <link href="/css/csscss?v=0" rel="stylesheet" type="text/css"> </head>  <body>   <div class="index_box">     <div class="apply_name">微信js支付测试</div>               <div class="branch_con">       <ul>         <li><span class="name">测试支付信息</span></li>       </ul>       <p class="cz_btn"><a href="javascript:pay();" class="btn_1">立即支付</a></p>     </div>   </div>    <script type="text/javascript" src="/js/zeptominjs"></script>   <script type="text/javascript" src="/js/commonjs"></script>   <script type="text/javascript">       var appId = urlparameter("appId");   var timeStamp = urlparameter("timeStamp");   var nonceStr = urlparameter("nonceStr");   var pg = urlparameter("pg");   var signType = urlparameter("signType");   var paySign = urlparameter("paySign");          function onBridgeReady(){             WeixinJSBridgeinvoke(         'getBrandWCPayRequest', {           "appId" : appId,   //公众号名称,由商户传入              "timeStamp": timeStamp,     //时间戳,自1970年以来的秒数              "nonceStr" : nonceStr, //随机串              "package" : "prepay_id=" + pg,              "signType" : signType,     //微信签名方式:              "paySign" : paySign  //微信签名          },                  function(res){              if(reserr_msg == "get_brand_wcpay_request:ok" ) {                          alert("支付成功");           }   // 使用以上方式判断前端返回,微信团队郑重提示:reserr_msg将在用户支付成功后返回  ok,但并不保证它绝对可靠。          }       );      }             function pay(){              if (typeof WeixinJSBridge == "undefined"){         if( documentaddEventListener ){           documentaddEventListener('WeixinJSBridgeReady', onBridgeReady, false);         }else if (documentattachEvent){           documentattachEvent('WeixinJSBridgeReady', onBridgeReady);            documentattachEvent('onWeixinJSBridgeReady', onBridgeReady);         }       }else{         onBridgeReady();       }             }   </script> </body> </html> 

效果如下

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持武林网。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表