原文地址:http://blog.csdn.net/fengshizty/article/details/45564685
微信公众号支付
最近项目需要微信支付,然后看了下微信公众号支付,,虽然不难,但是细节还是需要注意的,用了大半天时间写了个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 后台支付
代码如下,包含预处理订单,支付订单等接口。
package org.andy.controller;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
import com.fasterxml.jackson.databind.JsonNode;
import com.gson.oauth.Oauth;
import com.gson.oauth.Pay;
import com.gson.util.HttpKit;
import com.gson.util.Tools;
import org.andy.util.DatetimeUtil;
import org.andy.util.JsonUtil;
import org.andy.util.SessionUtil;
import org.andy.util.WebUtil;
@Controller
@RequestMapping ( “/pay” )
public class WXPayController {
@RequestMapping (value = “wxprepay” )
public void jspay(HttpServletRequest request, HttpServletResponse response, String callback) throws Exception {
String openId = SessionUtil.getAtt(request, ”openId” );
if (openId == null ) {
openId = getUserOpenId(request);
}
String appid = ”wx16691fcb0523c1a4” ;
String partnerid = ”22223670” ;
String paternerKey = ”fjfjfjfjf1234567FFFFFFFFF1234567” ;
String out_trade_no = getTradeNo();
Map paraMap = new HashMap();
paraMap.put(”appid” , appid);
paraMap.put(”attach” , “测试支付” );
paraMap.put(”body” , “测试购买Beacon支付” );
paraMap.put(”mch_id” , partnerid);
paraMap.put(”nonce_str” , create_nonce_str());
paraMap.put(”openid” , openId);
paraMap.put(”out_trade_no” , out_trade_no);
paraMap.put(”spbill_create_ip” , getAddrIp(request));
paraMap.put(”total_fee” , “1” );
paraMap.put(”trade_type” , “JSAPI” );
paraMap.put(”notify_url” , “http://www.xxx.co/wxpay/pay/appPay_notify.shtml” );
String sign = getSign(paraMap, paternerKey);
paraMap.put(”sign” , sign);
String url = ”https://api.mch.weixin.qq.com/pay/unifiedorder” ;
String xml = ArrayToXml(paraMap, false );
String xmlStr = HttpKit.post(url, xml);
String prepay_id = ”“ ;
if (xmlStr.indexOf( “SUCCESS” ) != - 1 ) {
Map map = doXMLParse(xmlStr);
prepay_id = (String) map.get(”prepay_id” );
}
Map payMap = new HashMap();
payMap.put(”appId” , appid);
payMap.put(”timeStamp” , create_timestamp());
payMap.put(”nonceStr” , create_nonce_str());
payMap.put(”signType” , “MD5” );
payMap.put(”package” , “prepay_id=” + prepay_id);
String paySign = getSign(payMap, paternerKey);
payMap.put(”pg” , prepay_id);
payMap.put(”paySign” , paySign);
WebUtil.response(response, WebUtil.packJsonp(callback, JsonUtil.warpJsonNodeResponse(JsonUtil.objectToJsonNode(payMap)).toString()));
}
@RequestMapping (value = “appPay” )
public void appPay(HttpServletRequest request, HttpServletResponse response, String body, String detail, String total_fee, String spbill_create_ip,
String notify_url, String trade_type, String callback) throws Exception {
String appid = ”wx16691fcb0523c1a4” ;
String partnerid = ”22223670” ;
String paternerKey = ”fjfjfjfjf1234567FFFFFFFFF1234567” ;
String out_trade_no = getTradeNo();
Map paraMap = new HashMap();
paraMap.put(”appid” , appid);
paraMap.put(”body” , body);
paraMap.put(”mch_id” , partnerid);
paraMap.put(”nonce_str” , create_nonce_str());
paraMap.put(”out_trade_no” , out_trade_no);
paraMap.put(”spbill_create_ip” , spbill_create_ip);
paraMap.put(”total_fee” , total_fee);
paraMap.put(”trade_type” , trade_type);
paraMap.put(”notify_url” , notify_url);
String sign = getSign(paraMap, paternerKey);
paraMap.put(”sign” , sign);
String url = ”https://api.mch.weixin.qq.com/pay/unifiedorder” ;
String xml = ArrayToXml(paraMap, false );
String xmlStr = HttpKit.post(url, xml);
String prepay_id = ”“ ;
Map map = doXMLParse(xmlStr);
if (xmlStr.indexOf( “SUCCESS” ) != - 1 ) {
prepay_id = (String) map.get(”prepay_id” );
}
String result_code = map.get(”result_code” );
String err_code_des = map.get(”err_code_des” );
Map payMap = new HashMap();
payMap.put(”appid” , appid);
payMap.put(”partnerid” , partnerid);
payMap.put(”prepayid” , prepay_id);
payMap.put(”package” , “Sign=WXPay” );
payMap.put(”noncestr” , create_nonce_str());
payMap.put(”timestamp” , create_timestamp());
String paySign = getSign(payMap, paternerKey);
payMap.put(”sign” , paySign);
payMap.put(”result_code” , result_code);
payMap.put(”err_code_des” , err_code_des);
WebUtil.response(response, WebUtil.packJsonp(callback, JsonUtil.warpJsonNodeResponse(JsonUtil.objectToJsonNode(payMap)).toString()));
}
@RequestMapping ( “/appPay_notify” )
public void appPayNotify(HttpServletRequest request, HttpServletResponse response) throws Exception{
response.setCharacterEncoding(”UTF-8” );
response.setContentType(”text/xml” );
ServletInputStream in = request.getInputStream();
String xmlMsg = Tools.inputStream2String(in);
Map map = doXMLParse(xmlMsg);
String return_code = map.get(”return_code” );
String return_msg = map.get(”return_msg” );
map = new HashMap();
map.put(”return_code” , return_code);
map.put(”return_msg” , return_msg);
String resXml = ArrayToXml(map, true );
response.getWriter().write(resXml);
}
@RequestMapping ( “/orderquery.do” )
public void orderquery(HttpServletRequest request, HttpServletResponse response, String transaction_id, String out_trade_no, String callback) throws Exception{
String url = ”https://api.mch.weixin.qq.com/pay/orderquery” ;
String appid = ”wx16691fcb0523c1a4” ;
String partnerid = ”22223670” ;
String paternerKey = ”fjfjfjfjf1234567FFFFFFFFF1234567” ;
Map map = new HashMap();
map.put(”appid” , appid);
map.put(”mch_id” , partnerid);
if (transaction_id != null && !transaction_id.equals( “” )){
map.put(”transaction_id” , transaction_id);
}else {
map.put(”out_trade_no” , out_trade_no);
}
map.put(”nonce_str” , create_nonce_str());
String paySign = getSign(map, paternerKey);
map.put(”sign” , paySign);
String xml = ArrayToXml(map, false );
String xmlStr = HttpKit.post(url, xml);
Map orderMap = doXMLParse(xmlStr);
WebUtil.response(response, WebUtil.packJsonp(callback, JsonUtil.warpJsonNodeResponse(JsonUtil.objectToJsonNode(orderMap)).toString()));
}
public String ArrayToXml(Map parm, boolean isAddCDATA) {
StringBuffer strbuff = new StringBuffer();
if (parm != null ) {
for (Entry entry : parm.entrySet()) {
strbuff.append(”<” ).append(entry.getKey()).append( “>” );
if (isAddCDATA) {
strbuff.append();
}else {
strbuff.append(entry.getValue());
}
strbuff.append(”<” ).append(entry.getKey()).append( “>” );
}
}
return strbuff.append().toString();
}
private String getUserOpenId(HttpServletRequest request) throws Exception {
String code = request.getParameter(”code” );
if (code == null ) {
String openId = request.getParameter(”openId” );
return openId;
}
Oauth o = new Oauth();
String token = o.getToken(code);
JsonNode node = JsonUtil.StringToJsonNode(token);
String openId = node.get(”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 += chars.charAt(rd.nextInt(chars.length() - 1 ));
}
return res;
}
private String getAddrIp(HttpServletRequest request){
return request.getRemoteAddr();
}
private String create_timestamp() {
return Long.toString(System.currentTimeMillis() / 1000 );
}
private String getTradeNo(){
String timestamp = DatetimeUtil.formatDate(new Date(), DatetimeUtil.DATETIME_PATTERN);
return “HZNO” + timestamp;
}
private String getSign(Map params, String paternerKey )
throws UnsupportedEncodingException {
String string1 = Pay.createSign(params, false );
String stringSignTemp = string1 + ”&key=” + paternerKey;
String signValue = DigestUtils.md5Hex(stringSignTemp).toUpperCase();
return signValue;
}
private Map doXMLParse(String xml)
throws XmlPullParserException, IOException {
InputStream inputStream = new ByteArrayInputStream(xml.getBytes());
Map map = null ;
XmlPullParser pullParser = XmlPullParserFactory.newInstance()
.newPullParser();
pullParser.setInput(inputStream, ”UTF-8” );
int eventType = pullParser.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
switch (eventType) {
case XmlPullParser.START_DOCUMENT:
map = new HashMap();
break ;
case XmlPullParser.START_TAG:
String key = pullParser.getName();
if (key.equals( “xml” ))
break ;
String value = pullParser.nextText();
map.put(key, value);
break ;
case XmlPullParser.END_TAG:
break ;
}
eventType = pullParser.next();
}
return map;
}
}
wxprepay.shtm接口是预处理订单接口向微信服务器下订单。
appPay.shtml接口是支付接口。
appPay_notify.shtml接口是微信支付后异步通知结果接口。
orderquery.shtml接口是订单查询接口
3.3、涉及到的工具类
SessionUtil.Java工具类
package org.andy.util;
import javax.servlet.http.HttpServletRequest;
public class SessionUtil {
public static void addAtt(HttpServletRequest request, String key, Object value){
request.getSession().setAttribute(key, value);
}
public static void removeAtt(HttpServletRequest request, String key){
request.getSession().removeAttribute(key);
}
public static String getAtt(HttpServletRequest request, String key){
return (String)request.getSession().getAttribute(key);
}
public static Object getAttObj(HttpServletRequest request, String key){
return request.getSession().getAttribute(key);
}
public static String optAtt(HttpServletRequest request, String key, String value){
String r = (String)request.getSession().getAttribute(key);
if (r == null ){
r = value;
}
return r;
}
}
HttpKit 网络请求工具类
public class HttpKit {
private static final String DEFAULT_CHARSET = “UTF-8” ;
public static String get(String url, Map params, Map headers) throws IOException, ExecutionException, InterruptedException {
AsyncHttpClient http = new AsyncHttpClient();
AsyncHttpClient.BoundRequestBuilder builder = http.prepareGet(url);
builder.setBodyEncoding(DEFAULT_CHARSET);
if (params != null && !params.isEmpty()) {
Set keys = params.keySet();
for (String key : keys) {
builder.addQueryParameter(key, params.get(key));
}
}
if (headers != null && !headers.isEmpty()) {
Set keys = headers.keySet();
for (String key : keys) {
builder.addHeader(key, params.get(key));
}
}
Future f = builder.execute();
String body = f.get().getResponseBody(DEFAULT_CHARSET);
http.close();
return body;
}
public static String get(String url) throws KeyManagementException, NoSuchAlgorithmException, NoSuchProviderException, UnsupportedEncodingException, IOException, ExecutionException, InterruptedException {
return get(url, null );
}
public static String get(String url, Map params) throws KeyManagementException, NoSuchAlgorithmException, NoSuchProviderException, UnsupportedEncodingException, IOException, ExecutionException, InterruptedException {
return get(url, params, null );
}
public static String post(String url, Map params) throws IOException, ExecutionException, InterruptedException {
AsyncHttpClient http = new AsyncHttpClient();
AsyncHttpClient.BoundRequestBuilder builder = http.preparePost(url);
builder.setBodyEncoding(DEFAULT_CHARSET);
if (params != null && !params.isEmpty()) {
Set keys = params.keySet();
for (String key : keys) {
builder.addParameter(key, params.get(key));
}
}
Future f = builder.execute();
String body = f.get().getResponseBody(DEFAULT_CHARSET);
http.close();
return body;
}
public static String post(String url, String s) throws IOException, ExecutionException, InterruptedException {
AsyncHttpClient http = new AsyncHttpClient();
AsyncHttpClient.BoundRequestBuilder builder = http.preparePost(url);
builder.setBodyEncoding(DEFAULT_CHARSET);
builder.setBody(s);
Future f = builder.execute();
String body = f.get().getResponseBody(DEFAULT_CHARSET);
http.close();
return body;
}
}
支付工具类pay.java
public class Pay {
private static final String DELIVERNOTIFY_URL = “https://api.weixin.qq.com/pay/delivernotify?access_token=” ;
public static String getPackage(Map params) throws UnsupportedEncodingException {
String partnerKey = ConfKit.get(”partnerKey” );
String partnerId = ConfKit.get(”partnerId” );
String notifyUrl = ConfKit.get(”notify_url” );
params.put(”bank_type” , “WX” );
params.put(”attach” , “yongle” );
params.put(”partner” , partnerId);
params.put(”notify_url” , notifyUrl);
params.put(”input_charset” , “UTF-8” );
return packageSign(params, partnerKey);
}
public static String createSign(Map params, boolean encode) throws UnsupportedEncodingException {
Set keysSet = params.keySet();
Object[] keys = keysSet.toArray();
Arrays.sort(keys);
StringBuffer temp = new StringBuffer();
boolean first = true ;
for (Object key : keys) {
if (first) {
first = false ;
} else {
temp.append(”&” );
}
temp.append(key).append(”=” );
Object value = params.get(key);
String valueString = ”“ ;
if ( null != value) {
valueString = value.toString();
}
if (encode) {
temp.append(URLEncoder.encode(valueString, ”UTF-8” ));
} else {
temp.append(valueString);
}
}
return temp.toString();
}
private static String packageSign(Map params, String paternerKey) throws UnsupportedEncodingException {
String string1 = createSign(params, false );
String stringSignTemp = string1 + ”&key=” + paternerKey;
String signValue = DigestUtils.md5Hex(stringSignTemp).toUpperCase();
String string2 = createSign(params, true );
return string2 + “&sign=” + signValue;
}
public static String paySign(String timestamp, String noncestr,String packages) throws UnsupportedEncodingException {
Map paras = new HashMap();
paras.put(”appid” , ConfKit.get( “AppId” ));
paras.put(”timestamp” , timestamp);
paras.put(”noncestr” , noncestr);
paras.put(”package” , packages);
paras.put(”appkey” , ConfKit.get( “paySignKey” ));
String string1 = createSign(paras, false );
String paySign = DigestUtils.shaHex(string1);
return paySign;
}
public static boolean verifySign( long timestamp,
String noncestr, String openid, int issubscribe, String appsignature) throws UnsupportedEncodingException {
Map paras = new HashMap();
paras.put(”appid” , ConfKit.get( “AppId” ));
paras.put(”appkey” , ConfKit.get( “paySignKey” ));
paras.put(”timestamp” , String.valueOf(timestamp));
paras.put(”noncestr” , noncestr);
paras.put(”openid” , openid);
paras.put(”issubscribe” , String.valueOf(issubscribe));
String string1 = createSign(paras, false );
String paySign = DigestUtils.shaHex(string1);
return paySign.equalsIgnoreCase(appsignature);
}
private static String deliverSign(Map paras) throws UnsupportedEncodingException {
paras.put(”appkey” , ConfKit.get( “paySignKey” ));
String string1 = createSign(paras, false );
String paySign = DigestUtils.shaHex(string1);
return paySign;
}
public static boolean delivernotify(String access_token, String openid, String transid, String out_trade_no) throws IOException, ExecutionException, InterruptedException {
Map paras = new HashMap();
paras.put(”appid” , ConfKit.get( “AppId” ));
paras.put(”openid” , openid);
paras.put(”transid” , transid);
paras.put(”out_trade_no” , out_trade_no);
paras.put(”deliver_timestamp” , (System.currentTimeMillis() / 1000 ) + “” );
paras.put(”deliver_status” , “1” );
paras.put(”deliver_msg” , “ok” );
String app_signature = deliverSign(paras);
paras.put(”app_signature” , app_signature);
paras.put(”sign_method” , “sha1” );
String json = HttpKit.post(DELIVERNOTIFY_URL.concat(access_token), JSONObject.toJSONString(paras));
if (StringUtils.isNotBlank(json)) {
JSONObject object = JSONObject.parseObject(json);
if (object.containsKey( “errcode” )) {
int errcode = object.getIntValue( “errcode” );
return errcode == 0 ;
}
}
return false ;
}
}
流转化Tools.java工具类
public final class Tools {
public static final String inputStream2String(InputStream in) throws UnsupportedEncodingException, IOException{
if (in == null )
return “” ;
StringBuffer out = new StringBuffer();
byte [] b = new byte [ 4096 ];
for ( int n; (n = in.read(b)) != - 1 ;) {
out.append(new String(b, 0 , n, “UTF-8” ));
}
return out.toString();
}
public static final boolean checkSignature(String token,String signature,String timestamp,String nonce){
List params = new ArrayList();
params.add(token);
params.add(timestamp);
params.add(nonce);
Collections.sort(params,new Comparator() {
@Override
public int compare(String o1, String o2) {
return o1.compareTo(o2);
}
});
String temp = params.get(0 )+params.get( 1 )+params.get( 2 );
return SHA1.encode(temp).equals(signature);
}
}
相应前端数据工具WebUtil.java工具类
public class WebUtil {
public static Object getSessionAttribute(HttpServletRequest req, String key) {
Object ret = null ;
try {
ret = req.getSession(false ).getAttribute(key);
} catch (Exception e) {
}
return ret;
}
public static void response(HttpServletResponse response, String result) {
try {
response.setContentType(”application/json;charset=utf-8” );
response.getWriter().write(result);
} catch (IOException e) {
e.printStackTrace();
}
}
public static void response(HttpServletResponse response, ResponseMessage result) {
try {
response.setContentType(”application/json;charset=utf-8” );
response.getWriter().write(JsonUtil.objectToJsonNode(result).toString());
} catch (Exception e) {
e.printStackTrace();
}
}
public static String packJsonp(String callback, String json) {
if (json == null ) {
json = ”“ ;
}
if (callback == null || callback.isEmpty()) {
return json;
}
return callback + “&&” + callback + ‘(‘ + json + ‘)’ ;
}
public static String packJsonp(String callback, ResponseMessage response) {
String json = null ;
if (response == null ) {
json = ”“ ;
} else {
json = JsonUtil.objectToJsonNode(response).toString();
}
if (callback == null || callback.isEmpty()) {
return json;
}
return callback + “&&” + callback + ‘(‘ + json + ‘)’ ;
}
}
Json转换工具JsonUtil.java
public class JsonUtil {
public static ObjectNode warpJsonNodeResponse(JsonNode obj){
ObjectNode objectNode=createObjectNode();
objectNode.put(”code” , 1 );
objectNode.put(”response” , obj);
return objectNode;
}
public static JsonNode objectToJsonNode(Object obj){
try {
ObjectMapper objectMapper = new ObjectMapper();
String objJson=objectMapper.writeValueAsString(obj);
JsonNode jsonNode = objectMapper.readTree(objJson);
return jsonNode;
} catch (JsonProcessingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null ;
}
}
四、微信H5调起支付
这个url需要后台实现,其实现功能如下:
1、接受微信服务器端发送的支付结果。
2、向微信服务器发送支付结果
具体 参考微信aip(http://pay.weixin.qq.com/wiki/doc/api/index.php?chapter=9_7)
具体代码如下:
4.1、授权向后台发起生成统一下订单页面
wxrepay.jsp
<%@ page language= “java” contentType= “text/html; charset=UTF-8” pageEncoding= “UTF-8” %>
<%@ taglib prefix=”spring” uri= “http://www.springframework.org/tags” %>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + ”://” + request.getServerName() + “:” + request.getServerPort() + path + “/” ;
long t = System.currentTimeMillis();
%>
”-//W3C//DTD HTML 4.01 Transitional//EN” “http://www.w3.org/TR/html4/loose.dtd” >
”utf-8” />
”viewport” content= “width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0” />
”apple-mobile-web-app-capable” content= “yes” />
”apple-mobile-web-app-status-bar-style” content= “black” />
”format-detection” content= “telephone=no” />
微信公众号支付
”../css/css.css?t=<%=t%>” rel= “stylesheet” type= “text/css” >
class
= “index_box” >
class= “apply_name” >商品
首先 是请求服务端wxprepay.shml接口,后台向微信支付平台获取支付订单信息,返回前台,wxpay.jsp页面
4.2、确认支付页面
<%@ page language= “java” contentType= “text/html; charset=UTF-8” pageEncoding= “UTF-8” %>
<%@ taglib prefix=”spring” uri= “http://www.springframework.org/tags” %>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + ”://” + request.getServerName() + “:” + request.getServerPort() + path + “/” ;
long t = System.currentTimeMillis();
%>
”-//W3C//DTD HTML 4.01 Transitional//EN” “http://www.w3.org/TR/html4/loose.dtd” >
”utf-8” />
”viewport” content= “width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0” />
”apple-mobile-web-app-capable” content= “yes” />
”apple-mobile-web-app-status-bar-style” content= “black” />
”format-detection” content= “telephone=no” />
微信公众号支付
”../css/css.css?t=<%=t%>” rel= “stylesheet” type= “text/css” >
class
= “index_box” >
class= “apply_name” >微信js支付测试
4.2、前台涉及到的工具类
JavaScript工具类common.js,样式css.css就不贴了没意义。
var path= “wxpay” ;
var mainpath = “/wxpay” ;
var appid = “wx16691fcb0523c1a4” ;
var urlpre = “http://www.xxx.com/wxpay/page” ;
var urlhost = “http://www.xxx.com/” ;
$(document).ready(function (){
$(”.refresher” ).click( function (){
refresh();
});
$(”#goback” ).click( function (){
goback();
});
});
function popupMsg(msg){
alert(msg);
}
function printUtilViaGet(panel, requestdata, ajaxurl, printfunction){
$.ajax({
type: ’GET’ ,
url: ajaxurl,
data: requestdata,
cache:false ,
dataType:”json” ,
async: false ,
success: function (response) {
if (response.code){
if (panel != null && panel.length > 0){
$(panel).html(”“ );
if (printfunction != null )
$(panel).html(printfunction(response.response));
}
return true ;
} else {
}
},
error: function (x, e) {
},
complete: function (x) {
}
});
return false ;
}
function ajaxUtilViaGet(requestdata, ajaxurl, succFunction, failFunction){
$.ajax({
url: ajaxurl,
type: ”GET” ,
dataType: ”json” ,
cache:false ,
data: requestdata,
async: false ,
success: function (response) {
if (response.code){
if (succFunction != null )
succFunction(response.response);
} else {
if (failFunction != null )
failFunction(response.response);
}
},
error: function (x, e) {
},
complete: function (x) {
}
});
return false ;
}
function printUtil(panel, requestdata, ajaxurl, printfunction, ajaxasync) {
if (isEmpty(ajaxasync)) {
ajaxasync = false ;
}
$.ajax({
type : ’POST’ ,
url : ajaxurl,
data : requestdata,
cache : false ,
dataType : ”json” ,
async : ajaxasync,
success : function (response) {
if (response.code) {
if (panel != null && panel.length > 0) {
$(panel).html(”“ );
if (printfunction != null )
$(panel).html(printfunction(response.response));
}
return true ;
} else {
}
},
error : function (x, e) {
},
complete : function (x) {
}
});
return false ;
}
function appendUtil(panel, requestdata, ajaxurl, printfunction, ajaxasync) {
if (isEmpty(ajaxasync)) {
ajaxasync = false ;
}
$.ajax({
type : ’POST’ ,
url : ajaxurl,
data : requestdata,
cache : false ,
dataType : ”json” ,
async : ajaxasync,
success : function (response) {
if (response.code) {
if (panel != null && panel.length > 0) {
if (printfunction != null )
$(panel).append(printfunction(response.response));
}
return true ;
} else {
}
},
error : function (x, e) {
},
complete : function (x) {
}
});
return false ;
}
function ajaxUtilAsync(requestdata, ajaxurl, succFunction, failFunction) {
$.ajax({
url : ajaxurl,
type : ”POST” ,
dataType : ”json” ,
cache : false ,
data : requestdata,
async : true ,
success : function (response) {
if ( typeof response.code == “number” ) {
if (response.code > 0) {
if (succFunction != null )
succFunction(response.response);
} else {
if (failFunction != null )
failFunction(response.response);
}
} else {
if (response.result) {
if (succFunction != null )
succFunction(response.response);
} else {
if (failFunction != null )
failFunction(response.response);
}
}
},
error : function (x, e) {
},
complete : function (x) {
}
});
return false ;
}
function ajaxUtil(requestdata, ajaxurl, succFunction, failFunction){
$.ajax({
url: ajaxurl,
type: ”POST” ,
dataType: ”json” ,
cache:false ,
data: requestdata,
async: false ,
success: function (response) {
if ( typeof response.code == “number” ){
if (response.code > 0){
if (succFunction != null )
succFunction(response.response);
} else {
if (failFunction != null )
failFunction(response.response);
}
} else {
if (response.result){
if (succFunction != null )
succFunction(response.response);
} else {
if (failFunction != null )
failFunction(response.response);
}
}
},
error: function (x, e) {
},
complete: function (x) {
}
});
return false ;
}
function loadSelection(panel, requestdata, ajaxurl, itemName){
ajaxUtil(requestdata, ajaxurl, function (response){
var list = response.list;
for ( var i = 0;i
$(panel).append(”+list[i][itemName]+ “’>” +list[i][itemName]+ “ ” );
}
}, null );
}
function ajaxSubmitRefresh(formId) {
var hideForm = $(formId);
var options = {
dataType : ”json” ,
beforeSubmit : function () {
},
success : function (result) {
if (result.result){
showMsg(”提交成功” );
} else {
alert(”提交失败!” );
}
},
error : function (result) {
alert(”提交失败!” );
}
};
hideForm.ajaxSubmit(options);
}
function ajaxSubmitWithJump(formId, nextPage) {
var hideForm = $(formId);
var options = {
dataType : ”json” ,
beforeSubmit : function () {
},
success : function (result) {
if (result.result){
alert(”提交成功” );
window.location.href = nextPage;
} else {
alert(”提交失败!” );
}
},
error : function (result) {
alert(”提交失败!” );
}
};
hideForm.ajaxSubmit(options);
}
function refresh(){
window.location.href = window.location.href;
}
function goback(){
history.go(-1);
}
function urlparameter(paras){
var url = location.href;
var paraString = url.substring(url.indexOf( “?” )+1,url.length).split( “&” );
var paraObj = {};
for ( var i=0; j=paraString[i]; i++){
paraObj[j.substring(0,j.indexOf(”=” )).toLowerCase()] = j.substring(j.indexOf( “=” )+1,j.length);
}
var returnValue = paraObj[paras.toLowerCase()];
if ( typeof (returnValue)== “undefined” ){
return “” ;
}else {
return returnValue;
}
}
String.prototype.endWith=function (str){
if (str== null ||str== “” || this .length==0||str.length> this .length)
return false ;
if ( this .substring( this .length-str.length)==str)
return true ;
else
return false ;
return true ;
};
String.prototype.startWith=function (str){
if (str== null ||str== “” || this .length==0||str.length> this .length)
return false ;
if ( this .substr(0,str.length)==str)
return true ;
else
return false ;
return true ;
};
function getFileUrl(sourceId) {
var url = “” ;
if (navigator.userAgent.indexOf( “MSIE” )>=1) {
url = document.getElementById(sourceId).value;
} else if (navigator.userAgent.indexOf( “Firefox” )>0) {
url = window.URL.createObjectURL(document.getElementById(sourceId).files.item(0));
} else if (navigator.userAgent.indexOf( “Chrome” )>0) {
url = window.URL.createObjectURL(document.getElementById(sourceId).files.item(0));
}
return url;
}
function preImg(sourceId, targetId) {
var url = getFileUrl(sourceId);
var imgPre = document.getElementById(targetId);
imgPre.src = url;
}
function initWX(){
$.ajax({
url:mainpath+’/wechatjs.do’ ,
type:’POST’ ,
dataType:’json’ ,
async: false ,
data: {url:location.href.split(’#’ )[0]},
success:function (result){
console.log(result);
var data=result[ ‘response’ ][ ‘map’ ];
if (result[ ‘code’ ]==1){
wx.config({
debug: false ,
appId:data[’appId’ ],
timestamp:data[’timestamp’ ],
nonceStr:data[’nonceStr’ ],
signature:data[’signature’ ],
jsApiList: [’onMenuShareTimeline’ , ‘onMenuShareAppMessage’ , ‘getLocation’ , ‘onMenuShareQQ’ , ‘onMenuShareWeibo’ ]
});
}else {
alert(”fail to get code” );
window.alert(’fail’ );
};
}
});
}
var EARTH_RADIUS = 6378137.0;
var PI = Math.PI;
function getRad(d){
return d*PI/180.0;
}
function getGreatCircleDistance(lat1,lng1,lat2,lng2){
var radLat1 = getRad(lat1);
var radLat2 = getRad(lat2);
var a = radLat1 - radLat2;
var b = getRad(lng1) - getRad(lng2);
var s = 2*Math.asin(Math.sqrt(Math.pow(Math.sin(a/2),2) + Math.cos(radLat1)*Math.cos(radLat2)*Math.pow(Math.sin(b/2),2)));
s = s*EARTH_RADIUS;
s = Math.round(s*10000)/10000.0;
s = Math.round(s);
return s;
}
Date.prototype.format = function (fmt)
{
var o = {
”M+” : this .getMonth()+1,
”d+” : this .getDate(),
”h+” : this .getHours(),
”m+” : this .getMinutes(),
”s+” : this .getSeconds(),
”q+” : Math.floor(( this .getMonth()+3)/3),
”S” : this .getMilliseconds()
};
if (/(y+)/.test(fmt))
fmt=fmt.replace(RegExp.1, (this .getFullYear()+ "" ).substr(4 - RegExp. 1.length));
for ( var k in o)
if ( new RegExp( “(“ + k + “)” ).test(fmt))
fmt = fmt.replace(RegExp.1, (RegExp. 1.length==1) ? (o[k]) : ((”00” + o[k]).substr(( “” + o[k]).length)));
return fmt;
};
function isEmpty(src){
if (( “undefined” == typeof src) || (src == null ) || ($.trim(src) == “” ) ){
return true ;
}
return false ;
}
function notEmpty(src){
return !isEmpty(src);
}
function wecharauto2burl(url) {
return “https://open.weixin.qq.com/connect/oauth2/authorize?appid=” + appid
+ ”&redirect_uri=” + encodeURIComponent(url)
+ ”&response_type=code&scope=snsapi_base&state=xybank#wechat_redirect” ;
}
function wecharauto2baseurl(url) {
return wecharauto2burl(urlpre+url);
}
function wecharauto2userinfourl(url) {
return “https://open.weixin.qq.com/connect/oauth2/authorize?appid=” + appid
+ ”&redirect_uri=” + encodeURIComponent(urlpre+url)
+ ”&response_type=code&scope=snsapi_userinfo&state=xybank#wechat_redirect” ;
}
function shareWeChat(title, link, imgUrl, desc){
wx.onMenuShareTimeline({
title: title,
link: link,
imgUrl: imgUrl,
success: function () {
},
cancel: function () {
}
});
wx.onMenuShareAppMessage({
title: title,
desc: desc,
link: link,
imgUrl: imgUrl,
type: ’link’ ,
dataUrl: ” ,
success: function () {
},
cancel: function () {
}
});
wx.onMenuShareQQ({
title: title,
desc: desc,
link: link,
imgUrl: imgUrl,
success: function () {
},
cancel: function () {
}
});
wx.onMenuShareWeibo({
title: title,
desc: desc,
link: link,
imgUrl: imgUrl,
success: function () {
},
cancel: function () {
}
});
}
五、支付结果
公众号调起效果如下:
支付成功后,微信服务器得到后台的Notify通知后,会发微信说明支付信息,支付凭证如下:
后续会全部更新微信app支付,微信支付退款,微信企业向个人付款,支付宝相关支付。而且会上传全部代码到csdn资源下载处。