700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > Java微信支付——公众号支付JSAPI

Java微信支付——公众号支付JSAPI

时间:2019-01-07 00:32:21

相关推荐

Java微信支付——公众号支付JSAPI

一、获取微信支付四大参数

首先获取两个账号:

1、微信公众号已认证的服务号,并且需要开通微信支付功能;

微信公众平台:1)账户、密码 ; 2)公众APPID ; 3)APPSECEPT

2、微信商户平台账号

微信商户平台:1)账号、密码 ;2)商户ID ;3)API密钥(在商户平台的账户中心下,需要用户自行下载证书及安装)

注意:获取API密钥

二、平台配置

1、配置微信公众平台授权域名

支付过程需要获取用户openId,必须经过网页授权配置才可以,要不然获取不到openId。公众号设置——功能设置——网页授权域名设置, 点击设置,有操作说明。

2、配置商户平台支付目录

三、开发流程

微信支付原理调用官方文档的统一下单接口,将微信服务器返回的参数根据微信的需求加工,返回到前台。

官方文档:https://pay./wiki/doc/api/jsapi.php?chapter=9_1

其中必填参数:

1、appid(公众账号ID)

2、mch_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 支付人的微信公众号对应的唯一标识

1> 首先从官网把公众号支付的SDK与DEMO下载下来,可以使用里面的WXPayUtil工具类

2>获取必填项的值

1、appid 在刚开始获取微信支付四大参数中获的

2、mch_id 在刚开始获取微信支付四大参数中获的,商户号ID

3、nonce_str 随机字符串用WXPayUtil中的generateNonceStr()获取,生成UUID的方法

4、body 所支付的名称 (注意:一定要转换成UTF-8形式,不然后续获取prepay_id将获取不到)

5、out_trade_no 订单号,一定要保证唯一

6、total_fee 支付金额 ,单位是分(一定要换算成分进行操作)

7、spbill_create_ip IP地址

8、notify_url 回调地址

9、trade_type 支付类型 此支付类型为 "JSAPI"

10、openid 支付人的微信公众号对应的唯一标识,每个人的openid在不同的公众号不一样。(获取openid属于微信公众号网页授权的,参考微信网页授权:https://mp./wiki?t=resource/res_main&id=mp1421140842)

11、sign 签名:用WXPayUtil中的generateSignature(finalMap<String,String> data,String key)方法,data是将除了sign外其他10个参数放到map中,key是四大配置参数中的API密钥(paternerKey)

3>获取openid

1、用户同意授权,获取code

参考访问地址:https://open./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,可以写到前台页面a标签中或者在后台访问,redirect_uri可以链接到本项目的方法并可获取code。

<a href="https://open./connect/oauth2/authorize?appid=wx15c*********&redirect_uri=http%3a%2f%%2fpay.jsp&response_type=code&scope=snsapi_base#wechat_redirect">获取code</a>

2、通过code获取网页授权access_token(access_token中含有openid)

参考访问地址:https://api./sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code

注意事项:1、CODE需要换成第一步获取的code

通过参考地址,在后台中用http相关类发送get请求,返回的json结果为:

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

4>获取十一个必填项之后,使用WXPayUtil工具类中的public static String mapToXml(Map<String,String> data)方法将有11个参数的map转成XML格式,用post请求的方法,请求微信统一下单接口:https://api.mch./pay/unifiedorder,发送后会返回String类型的返回值,会得到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[wx11101639507cbf6ffd8b0779950874]]></prepay_id><trade_type><![CDATA[JSAPI]]></trade_type></xml>

到此时后台获取的数据已经全部完成,最后就是获取prepay_id。使用WXPayUtil类中的public static Map<String,String> xmlToMap(String strXML)方法,将刚才返回的XML格式的字符串转成map,map中获取prepay_id。

5>前台

1、appId : 四大参数之一的APPID

2、timestamp:时间戳

3、nonceStr:随机字符串,再次用WXPayUtil中的generateNonceStr()获取

4、package:使用的就是后台最后获取的prepay_id,但是还不是直接取值,还非要固定格式的,值的格式:“prepay_id=wx35465465....5656”

5、signType:MD5

6、paySign:还是签名算法,按照上面的方法,用WXPayUtil中的public static String generateSignature(final Map<String,String> data,String key)方法,data是将除了paySign外,其他5个参数放到map中,key是四大配置参数中的API密钥(paternerKey)

function onBridgeReady(){WeixinJSBridge.invoke( 'getBrandWCPayRequest', {"appId":appId,//公众号名称,由商户传入"timeStamp":timeStamp, //时间戳,自1970年以来的秒数"nonceStr":nonceStr, //随机串"package":package,"signType":signType, //微信签名方式:"paySign":paySign //微信签名 }, function(res){if(res.err_msg == "get_brand_wcpay_request:ok" ) {console.log('支付成功');//支付成功后跳转的页面}else if(res.err_msg == "get_brand_wcpay_request:cancel"){console.log('支付取消');}else if(res.err_msg == "get_brand_wcpay_request:fail"){console.log('支付失败');WeixinJSBridge.call('closeWindow');} //使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。}); }

6>以下是参考代码

1》把四大参数和所需要的访问地址放到wechatPay.properties中

######微信支付配置文件############应用idwechat.appid=wxdb384*********7######商户IDwechat.mch_id=154*******1######appSecret密钥wechat.appSecret=1636e***********a57222######支付类型wechat.trade_type=JSAPI######API密钥wechat.paternerKey=wxdb384e**********4eb0e4de######域名wechat.ym=######返回结果回调函数wechat.afterUrl=phone/wxpay/afterUrl######获取code的urlwechat.code=https://open./connect/oauth2/authorize######获取Access_token的urlwechat.access_token=https://api./sns/oauth2/access_token######获取统一下单urlwechat.unifiedorder_url=https://api.mch./pay/unifiedorder

/****在类中获取值***/public void loadData() {rb = ResourceBundle.getBundle("wechatPay");wxAppid = rb.getString("wechat.appid");// 微信APPidwxAppSecret = rb.getString("wechat.appSecret");// 微信APPSECEPTwxMchId = rb.getString("wechat.mch_id");// 微信商户IDwxTradeType = rb.getString("wechat.trade_type");// 支付的方式wxAfterUrl = rb.getString("wechat.afterUrl");// 成功之后回调函数wxPaternerKey = rb.getString("wechat.paternerKey");// 微信api密钥wxUnifiedorderUrl = rb.getString("wechat.unifiedorder_url");// 统一下单地址}

2》后台发送get(post)请求的方法

package mon.pay;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.PrintWriter;import .URL;import .URLConnection;import java.util.List;import java.util.Map;public class HttpRequest {/*** 向指定URL发送GET方法的请求* * @param url* 发送请求的URL* @param param* 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。* @return URL 所代表远程资源的响应结果*/public static String sendGet(String url, String param) {String result = "";BufferedReader in = null;try {String urlNameString = url + "?" + param;System.out.println(urlNameString);URL realUrl = new URL(urlNameString);// 打开和URL之间的连接URLConnection connection = realUrl.openConnection();// 设置通用的请求属性connection.setRequestProperty("accept", "*/*");connection.setRequestProperty("connection", "Keep-Alive");connection.setRequestProperty("user-agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");// 建立实际的连接connection.connect();// 获取所有响应头字段Map<String, List<String>> map = connection.getHeaderFields();// 遍历所有的响应头字段for (String key : map.keySet()) {System.out.println(key + "--->" + map.get(key));}// 定义 BufferedReader输入流来读取URL的响应in = new BufferedReader(new InputStreamReader(connection.getInputStream()));String line;while ((line = in.readLine()) != null) {result += line;}} catch (Exception e) {System.out.println("发送GET请求出现异常!" + e);e.printStackTrace();}// 使用finally块来关闭输入流finally {try {if (in != null) {in.close();}} catch (Exception e2) {e2.printStackTrace();}}return result;}/*** 向指定 URL 发送POST方法的请求* * @param url* 发送请求的 URL* @param param* 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。* @return 所代表远程资源的响应结果*/public static String sendPost(String url, String param) {PrintWriter out = null;BufferedReader in = null;String result = "";try {URL realUrl = new URL(url);// 打开和URL之间的连接URLConnection conn = realUrl.openConnection();// 设置通用的请求属性conn.setRequestProperty("accept", "*/*");conn.setRequestProperty("connection", "Keep-Alive");conn.setRequestProperty("user-agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");// 发送POST请求必须设置如下两行conn.setDoOutput(true);conn.setDoInput(true);// 获取URLConnection对象对应的输出流//out = new PrintWriter(conn.getOutputStream());// 获取URLConnection对象对应的输出流(进行编码)out = new PrintWriter(new OutputStreamWriter(conn.getOutputStream(),"UTF-8"));// 发送请求参数out.print(param);// flush输出流的缓冲out.flush();// 定义BufferedReader输入流来读取URL的响应in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"));String line;while ((line = in.readLine()) != null) {result += line;}} catch (Exception e) {System.out.println("发送 POST 请求出现异常!" + e);e.printStackTrace();}// 使用finally块来关闭输出流、输入流finally {try {if (out != null) {out.close();}if (in != null) {in.close();}} catch (IOException ex) {ex.printStackTrace();}}return result;}}

3》从微信官网下载的SDK和DEMO中使用微信中的WXPayUtil类

package mon.pay.wechat;import mon.pay.wechat.WXPayConstants.SignType;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.w3c.dom.Node;import org.w3c.dom.NodeList;import javax.crypto.Mac;import javax.crypto.spec.SecretKeySpec;import javax.xml.parsers.DocumentBuilder;import javax.xml.transform.OutputKeys;import javax.xml.transform.Transformer;import javax.xml.transform.TransformerFactory;import javax.xml.transform.dom.DOMSource;import javax.xml.transform.stream.StreamResult;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.StringWriter;import java.security.MessageDigest;import java.security.SecureRandom;import java.util.*;public class WXPayUtil {private static final String SYMBOLS = "0123456789abcd**************LMNOPQRSTUVWXYZ";private static final Random RANDOM = new SecureRandom();/*** XML格式字符串转换为Map** @param strXML* XML字符串* @return XML数据转换后的Map* @throws Exception*/public static Map<String, String> xmlToMap(String strXML) throws Exception {try {Map<String, String> data = new HashMap<String, String>();DocumentBuilder documentBuilder = WXPayXmlUtil.newDocumentBuilder();InputStream stream = new ByteArrayInputStream(strXML.getBytes("UTF-8"));org.w3c.dom.Document doc = documentBuilder.parse(stream);doc.getDocumentElement().normalize();NodeList nodeList = doc.getDocumentElement().getChildNodes();for (int idx = 0; idx < nodeList.getLength(); ++idx) {Node node = nodeList.item(idx);if (node.getNodeType() == Node.ELEMENT_NODE) {org.w3c.dom.Element element = (org.w3c.dom.Element) node;data.put(element.getNodeName(), element.getTextContent());}}try {stream.close();} catch (Exception ex) {// do nothing}return data;} catch (Exception ex) {WXPayUtil.getLogger().warn("Invalid XML, can not convert to map. Error message: {}. XML content: {}",ex.getMessage(), strXML);throw ex;}}/*** 将Map转换为XML格式的字符串** @param data* Map类型数据* @return XML格式的字符串* @throws Exception*/public static String mapToXml(Map<String, String> data) throws Exception {org.w3c.dom.Document document = WXPayXmlUtil.newDocument();org.w3c.dom.Element root = document.createElement("xml");document.appendChild(root);for (String key : data.keySet()) {String value = data.get(key);if (value == null) {value = "";}value = value.trim();org.w3c.dom.Element filed = document.createElement(key);filed.appendChild(document.createTextNode(value));root.appendChild(filed);}TransformerFactory tf = TransformerFactory.newInstance();Transformer transformer = tf.newTransformer();DOMSource source = new DOMSource(document);transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");transformer.setOutputProperty(OutputKeys.INDENT, "yes");StringWriter writer = new StringWriter();StreamResult result = new StreamResult(writer);transformer.transform(source, result);String output = writer.getBuffer().toString(); // .replaceAll("\n|\r",// "");try {writer.close();} catch (Exception ex) {}return output;}/*** 生成带有 sign 的 XML 格式字符串** @param data* Map类型数据* @param key* API密钥* @return 含有sign字段的XML*/public static String generateSignedXml(final Map<String, String> data,String key) throws Exception {return generateSignedXml(data, key, SignType.MD5);}/*** 生成带有 sign 的 XML 格式字符串** @param data* Map类型数据* @param key* API密钥* @param signType* 签名类型* @return 含有sign字段的XML*/public static String generateSignedXml(final Map<String, String> data,String key, SignType signType) throws Exception {String sign = generateSignature(data, key, signType);data.put(WXPayConstants.FIELD_SIGN, sign);return mapToXml(data);}/*** 判断签名是否正确** @param xmlStr* XML格式数据* @param key* API密钥* @return 签名是否正确* @throws Exception*/public static boolean isSignatureValid(String xmlStr, String key)throws Exception {Map<String, String> data = xmlToMap(xmlStr);if (!data.containsKey(WXPayConstants.FIELD_SIGN)) {return false;}String sign = data.get(WXPayConstants.FIELD_SIGN);return generateSignature(data, key).equals(sign);}/*** 判断签名是否正确,必须包含sign字段,否则返回false。使用MD5签名。** @param data* Map类型数据* @param key* API密钥* @return 签名是否正确* @throws Exception*/public static boolean isSignatureValid(Map<String, String> data, String key)throws Exception {return isSignatureValid(data, key, SignType.MD5);}/*** 判断签名是否正确,必须包含sign字段,否则返回false。** @param data* Map类型数据* @param key* API密钥* @param signType* 签名方式* @return 签名是否正确* @throws Exception*/public static boolean isSignatureValid(Map<String, String> data,String key, SignType signType) throws Exception {if (!data.containsKey(WXPayConstants.FIELD_SIGN)) {return false;}String sign = data.get(WXPayConstants.FIELD_SIGN);return generateSignature(data, key, signType).equals(sign);}/*** 生成签名** @param data* 待签名数据* @param key* API密钥* @return 签名*/public static String generateSignature(final Map<String, String> data,String key) throws Exception {return generateSignature(data, key, SignType.MD5);}/*** 生成签名. 注意,若含有sign_type字段,必须和signType参数保持一致。** @param data* 待签名数据* @param key* API密钥* @param signType* 签名方式* @return 签名*/public static String generateSignature(final Map<String, String> data,String key, SignType signType) throws Exception {Set<String> keySet = data.keySet();String[] keyArray = keySet.toArray(new String[keySet.size()]);Arrays.sort(keyArray);StringBuilder sb = new StringBuilder();for (String k : keyArray) {if (k.equals(WXPayConstants.FIELD_SIGN)) {continue;}if (data.get(k).trim().length() > 0) // 参数值为空,则不参与签名sb.append(k).append("=").append(data.get(k).trim()).append("&");}sb.append("key=").append(key);if (SignType.MD5.equals(signType)) {return MD5(sb.toString()).toUpperCase();} else if (SignType.HMACSHA256.equals(signType)) {return HMACSHA256(sb.toString(), key);} else {throw new Exception(String.format("Invalid sign_type: %s", signType));}}/*** 获取随机字符串 Nonce Str** @return String 随机字符串*/public static String generateNonceStr() {char[] nonceChars = new char[32];for (int index = 0; index < nonceChars.length; ++index) {nonceChars[index] = SYMBOLS.charAt(RANDOM.nextInt(SYMBOLS.length()));}return new String(nonceChars);}/*** 生成 MD5** @param data* 待处理数据* @return MD5结果*/public static String MD5(String data) throws Exception {java.security.MessageDigest md = MessageDigest.getInstance("MD5");byte[] array = md.digest(data.getBytes("UTF-8"));StringBuilder sb = new StringBuilder();for (byte item : array) {sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));}return sb.toString().toUpperCase();}/*** 生成 HMACSHA256* * @param data* 待处理数据* @param key* 密钥* @return 加密结果* @throws Exception*/public static String HMACSHA256(String data, String key) throws Exception {Mac sha256_HMAC = Mac.getInstance("HmacSHA256");SecretKeySpec secret_key = new SecretKeySpec(key.getBytes("UTF-8"),"HmacSHA256");sha256_HMAC.init(secret_key);byte[] array = sha256_HMAC.doFinal(data.getBytes("UTF-8"));StringBuilder sb = new StringBuilder();for (byte item : array) {sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));}return sb.toString().toUpperCase();}/*** 日志* * @return*/public static Logger getLogger() {Logger logger = LoggerFactory.getLogger("wxpay java sdk");return logger;}/*** 获取当前时间戳,单位秒* * @return*/public static long getCurrentTimestamp() {return System.currentTimeMillis() / 1000;}/*** 获取当前时间戳,单位毫秒* * @return*/public static long getCurrentTimestampMs() {return System.currentTimeMillis();}/*** 流转换xml字符串* * @param in* @param charset* @return*/public static String inputStream2String(InputStream in, String charset) {if (charset == null) {charset = "UTF-8";}ByteArrayOutputStream outputStream = new ByteArrayOutputStream();String result = null;int bufferSize = 2048;byte[] data = new byte[bufferSize];int count = -1;try {while ((count = in.read(data, 0, bufferSize)) != -1) {outputStream.write(data, 0, count);}result = new String(outputStream.toByteArray(), charset);} catch (Exception e) {e.printStackTrace();} finally {try {if (outputStream != null) {outputStream.close();}} catch (IOException e) {e.printStackTrace();}}return result;}}

4》首先获取code,我是后台重定向获取的

/*** 支付* * @return*/@RequestMapping("/pay")public String pay( HttpServletRequest request) {ResourceBundle rb = ResourceBundle.getBundle("wechatPay");String url = rb.getString("wechat.code");// 获取code的urlString appid = rb.getString("wechat.appid");// 获取appidString ym = rb.getString("wechat.ym");// 获取域名url = url+ "?appid="+ appid+ "&redirect_uri=http%3a%2f%2f"+ ym+ "%2fphone%2fwxpay%2fgetCode%3fmeetingId%3d"+ id+ "%26orderId%3d"+ orderId+ "&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect";return "redirect:" + url;}

后台中redirect_uri中指定的方法将会获得code(request.getParameter("code")),发送到前台。

5》获取openid

/*** 获取access_token* * @param code* @return*/public String getOpenId(String code) {loadData();String accessTokenUrl = rb.getString("wechat.access_token");String param = "appid=" + wxAppid + "&secret=" + wxAppSecret + "&code="+ code + "&grant_type=authorization_code";String result = HttpRequest.sendGet(accessTokenUrl, param);JSONObject jo = new JSONObject(result);String openid = jo.get("openid") + "";return openid;}

6》获取prepay_id

/*** 获取getPrepay_id* * @param openId* 获取openId* @param orderId* 订单号* @param orderName* 所支付的名称* @param money* 支付费用单位分* @param request* @return*/public String getPrepay_id(String openId, String orderId, String orderName,String money, HttpServletRequest request) {loadData();// 拼接统一下单地址参数Map<String, String> paraMap = new HashMap<String, String>();// 获取请求ip地址String ip = request.getHeader("x-forwarded-for");if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {ip = request.getHeader("Proxy-Client-IP");}if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {ip = request.getHeader("WL-Proxy-Client-IP");}if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {ip = request.getRemoteAddr();}if (ip.indexOf(",") != -1) {String[] ips = ip.split(",");ip = ips[0].trim();}paraMap.put("appid", wxAppid);orderName = orderName.replace(" ", "");try {paraMap.put("body", new String(orderName.getBytes("ISO8859-1"),"utf-8"));} catch (UnsupportedEncodingException e1) {// TODO Auto-generated catch blocke1.printStackTrace();}paraMap.put("mch_id", wxMchId);paraMap.put("nonce_str", WXPayUtil.generateNonceStr());paraMap.put("openid", openId);paraMap.put("out_trade_no", orderId);// 订单号paraMap.put("spbill_create_ip", ip);paraMap.put("total_fee", money);paraMap.put("trade_type", wxTradeType);paraMap.put("notify_url", request.getServerName() + "/" + wxAfterUrl);// 此路径是微信服务器调用支付结果通知路径随意写String prepay_id = "";// 预支付idtry {String sign = WXPayUtil.generateSignature(paraMap, wxPaternerKey);paraMap.put("sign", sign);String xml = WXPayUtil.mapToXml(paraMap);// 将所有参数(map)转xml格式String xmlStr = HttpRequest.sendPost(wxUnifiedorderUrl, xml);// 发送post请求"统一下单接口"返回预支付id:prepay_id// 以下内容是返回前端页面的json数据Map<String, String> map = WXPayUtil.xmlToMap(xmlStr);if (xmlStr.indexOf("SUCCESS") != -1) {prepay_id = (String) map.get("prepay_id");}} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}return prepay_id;}

7》往前台发送数据

/*** 往前台发送数据* * @param prepay_id* @return*/public Map<String, String> sendMap(String prepay_id) {loadData();Map<String, String> payMap = new HashMap<String, String>();payMap.put("appId", wxAppid);payMap.put("timeStamp", WXPayUtil.getCurrentTimestamp() + "");payMap.put("nonceStr", WXPayUtil.generateNonceStr());payMap.put("signType", "MD5");payMap.put("package", "prepay_id=" + prepay_id);String paySign;try {paySign = WXPayUtil.generateSignature(payMap, wxPaternerKey);payMap.put("paySign", paySign);payMap.put("packageMsg", "prepay_id=" + prepay_id);System.out.println(payMap);return payMap;} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();return null;}}

8》前台js

<script type="text/javascript">var appId,timeStamp,nonceStr,packageMsg,signType,paySign;//微信支付function wxpay(){var code ="${wxcode}";if(code){var url ="${prefix}/phone/wxpay/getMessage?code="+code+"&meetingId=${meeting.id}&orderId=${orderId}";$.get(url,function(data) {var result = data.body.msg;appId = result.appId;timeStamp = result.timeStamp;nonceStr = result.nonceStr;packageMsg = result.packageMsg;signType = result.signType;paySign = result.paySign;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();}});} else {alert("服务器错误")}}function onBridgeReady(){WeixinJSBridge.invoke( 'getBrandWCPayRequest', {"appId":appId,//公众号名称,由商户传入"timeStamp":timeStamp, //时间戳,自1970年以来的秒数"nonceStr":nonceStr, //随机串"package":packageMsg,"signType":signType, //微信签名方式:"paySign":paySign //微信签名 }, function(res){if(res.err_msg == "get_brand_wcpay_request:ok" ) {console.log('支付成功');//支付成功后跳转的页面}else if(res.err_msg == "get_brand_wcpay_request:cancel"){console.log('支付取消');layer.msg('支付取消', {icon: 1,time:1000});}else if(res.err_msg == "get_brand_wcpay_request:fail"){console.log('支付失败');layer.msg('支付失败', {icon: 1,time:1000});/* WeixinJSBridge.call('closeWindow'); */} //使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。window.location.href="${prefix}/phone/meeting/meetingDetail?id=${meeting.id}";}); }</script>

9》支付成功后回调

/*** 返回结果* * @return*/@RequestMapping("/afterUrl")public String afterUrl(HttpServletRequest request,HttpServletResponse response) {InputStream is = null;try {is = request.getInputStream();// 获取请求的流信息(这里是微信发的xml格式所有只能使用流来读)String xml = WXPayUtil.inputStream2String(is, "UTF-8");Map<String, String> notifyMap = WXPayUtil.xmlToMap(xml);// 将微信发的xml转mapif (notifyMap.get("return_code").equals("SUCCESS")) {if (notifyMap.get("result_code").equals("SUCCESS")) {String orderId = notifyMap.get("out_trade_no");// 商户订单号String meetingId = orderPayService.saveOrderPay(orderId);return "redirect:/phone/meeting/meetingDetail?id="+meetingId;}}// 告诉微信服务器收到信息了,不要在调用回调action了========这里很重要回复微信服务器信息用流发送一个xml即可response.getWriter().write("<xml><return_code><![CDATA[SUCCESS]]></return_code></xml>");is.close();} catch (Exception e) {e.printStackTrace();}return "redirect:/phone/meeting/meetinglist";}

7>参考文献

/javaYouCome/article/details/79473743

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。