微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

微信公众号支付H5调用支付解析

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

一、配置公众号微信支付

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

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

二、开发流程

借用微信公众号支付api(地址 ),我们需要开发的为红色标记出的。如下:

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

调用统一下单接口,这样就能获取微信支付的prepay_id()。

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

3.1 获取openid

可以通过网页授权形式(

在微信中发送如下链接

3.2 后台支付

代码如下,包含预处理订单,支付订单等接口。

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 {
// 获取openid
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<String,String> paraMap = new HashMap<String,String>();
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);

// 统一下单 https://api.mch.weixin.qq.com/pay/unifiedorder
String url = "https://api.mch.weixin.qq.com/pay/unifiedorder";

String xml = ArrayToXml(paraMap,false);

String xmlStr = HttpKit.post(url,xml);

// 预付商品id
String prepay_id = "";

if (xmlStr.indexOf("SUCCESS") != -1) {
Map<String,String> map = doXMLParse(xmlStr);
prepay_id = (String) map.get("prepay_id");
}

Map<String,String> payMap = new HashMap<String,String>();
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,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<String,appid);
paraMap.put("body",body);
paraMap.put("mch_id",create_nonce_str());
paraMap.put("out_trade_no",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,xml);

// 预付商品id
String prepay_id = "";

Map<String,String> 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<String,String>();
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,JsonUtil.warpJsonNodeResponse(JsonUtil.objectToJsonNode(payMap)).toString()));
}

@RequestMapping("/appPay_notify")
public void appPayNotify(HttpServletRequest request,HttpServletResponse response) throws Exception{
//String xml = "<![CDATA[wxb4dc385f953b356e]]><![CDATA[CCB_CREDIT]]><![CDATA[1]]><![CDATA[CNY]]><![CDATA[Y]]><![CDATA[1228442802]]><![CDATA[1002477130]]><![CDATA[o-HREuJzRr3moMvv990VdfnQ8x4k]]><![CDATA[1000000000051249]]><![CDATA[SUCCESS]]><![CDATA[SUCCESS]]><![CDATA[1269E03E43F2B8C388A414EDAE185CEE]]><![CDATA[20150324100405]]>1<![CDATA[JSAPI]]><![CDATA[1009530574201503240036299496]]>";
response.setCharacterEncoding("UTF-8");
response.setContentType("text/xml");
ServletInputStream in = request.getInputStream();
String xmlMsg = Tools.inputStream2String(in);

Map<String,String> map = doXMLParse(xmlMsg);
String return_code = map.get("return_code");
String return_msg = map.get("return_msg");

map = new HashMap<String,String>();
map.put("return_code",return_code);
map.put("return_msg",return_msg);

//响应xml
String resXml = ArrayToXml(map,true);
response.getWriter().write(resXml);
}

@RequestMapping("/orderquery.do")
public void orderquery(HttpServletRequest request,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<String,String> map = new HashMap<String,String>();
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<String,String> orderMap = doXMLParse(xmlStr);

WebUtil.response(response,JsonUtil.warpJsonNodeResponse(JsonUtil.objectToJsonNode(orderMap)).toString()));
}

/**

  • map转成xml
  • @param arr
  • @return
    */
    public String ArrayToXml(Map<String,String> parm,boolean isAddCDATA) {
    StringBuffer strbuff = new StringBuffer();
    if (parm != null ) {
    for (Entry<String,String> entry : parm.entrySet()) {
    strbuff.append("<").append(entry.getKey()).append(">");
    if (isAddCDATA) {
    strbuff.append(<![CDATA[).append(entry.getValue()).append(]]>);
    }else {
    strbuff.append(entry.getValue());
    }
    strbuff.append("<").append(entry.getKey()).append(">");
    }
    }
    return strbuff.append(
    ).toString();
    }

// 获取openId
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<String,String> 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<String,String> doXMLParse(String xml)
throws XmlPullParserException,IOException {

InputStream inputStream = new ByteArrayInputStream(xml.getBytes());

Map<String,String> map = null;

XmlPullParser pullParser = XmlPullParserFactory.newInstance()
.newPullParser();

pullParser.setInput(inputStream,"UTF-8"); // 为xml设置要解析的xml数据

int eventType = pullParser.getEventType();

while (eventType != XmlPullParser.END_DOCUMENT) {
switch (eventType) {
case XmlPullParser.START_DOCUMENT:
map = new HashMap<String,String>();
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工具类

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 value){
String r = (String)request.getSession().getAttribute(key);
if (r == null){
r = value;
}
return r;
}

}

HttpKit 网络请求工具类

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;
}

/**

  • @return 返回类型:
  • @throws IOException
  • @throws UnsupportedEncodingException
  • @throws NoSuchProviderException
  • @throws NoSuchAlgorithmException
  • @throws KeyManagementException
  • @description 功能描述: get 请求
    */
    public static String get(String url) throws KeyManagementException,NoSuchAlgorithmException,NoSuchProviderException,UnsupportedEncodingException,IOException,InterruptedException {
    return get(url,null);
    }

/**

  • @return 返回类型:
  • @throws IOException
  • @throws NoSuchProviderException
  • @throws NoSuchAlgorithmException
  • @throws KeyManagementException
  • @throws UnsupportedEncodingException
  • @description 功能描述: get 请求
    */
    public static String get(String url,String> params) throws KeyManagementException,params,null);
    }

/**

  • @return 返回类型:
  • @throws IOException
  • @throws NoSuchProviderException
  • @throws NoSuchAlgorithmException
  • @throws KeyManagementException
  • @description 功能描述: POST 请求
    */
    public static String post(String url,String> params) throws IOException,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,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

// 发货通知接口
private static final String DELIVERNOTIFY_URL = "https://api.weixin.qq.com/pay/delivernotify?access_token=";

/**

  • 参与 paySign 签名的字段包括:appid、timestamp、noncestr、package 以及 appkey。
  • 这里 signType 并不参与签名微信的Package参数
  • @param params
  • @return
  • @throws UnsupportedEncodingException
    */
    public static String getPackage(Map<String,String> 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);
    }

/**

  • 构造签名
  • @param params
  • @param encode
  • @return
  • @throws UnsupportedEncodingException
    */
    public static String createSign(Map<String,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();
    }

/**

  • @param params
  • @param paternerKey
  • @return
  • @throws UnsupportedEncodingException
    */
    private static String packageSign(Map<String,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;
    }

/**

  • 支付签名
  • @param timestamp
  • @param noncestr
  • @param packages
  • @return
  • @throws UnsupportedEncodingException
    */
    public static String paySign(String timestamp,String noncestr,String packages) throws UnsupportedEncodingException {
    Map<String,String> paras = new HashMap<String,String>();
    paras.put("appid",ConfKit.get("AppId"));
    paras.put("timestamp",timestamp);
    paras.put("noncestr",noncestr);
    paras.put("package",packages);
    paras.put("appkey",ConfKit.get("paySignKey"));
    // appid、timestamp、noncestr、package 以及 appkey。
    String string1 = createSign(paras,false);
    String paySign = DigestUtils.shaHex(string1);
    return paySign;
    }

/**

  • 支付回调校验签名
  • @param timestamp
  • @param noncestr
  • @param openid
  • @param issubscribe
  • @param appsignature
  • @return
  • @throws UnsupportedEncodingException
    */
    public static boolean verifySign(long timestamp,String openid,int issubscribe,String appsignature) throws UnsupportedEncodingException {
    Map<String,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));
    // appid、appkey、productid、timestamp、noncestr、openid、issubscribe
    String string1 = createSign(paras,false);
    String paySign = DigestUtils.shaHex(string1);
    return paySign.equalsIgnoreCase(appsignature);
    }

/**

  • 发货通知签名
  • @param paras
  • @return
  • @throws UnsupportedEncodingException
  • @参数 appid、appkey、openid、transid、out_trade_no、deliver_timestamp、deliver_status、deliver_msg;
    */
    private static String deliverSign(Map<String,String> paras) throws UnsupportedEncodingException {
    paras.put("appkey",ConfKit.get("paySignKey"));
    String string1 = createSign(paras,false);
    String paySign = DigestUtils.shaHex(string1);
    return paySign;
    }

/**

  • 发货通知
  • @param access_token
  • @param openid
  • @param transid
  • @param out_trade_no
  • @return
  • @throws IOException
  • @throws NoSuchProviderException
  • @throws NoSuchAlgorithmException
  • @throws KeyManagementException
  • @throws InterruptedException
  • @throws ExecutionException
    */

public static boolean delivernotify(String access_token,String transid,String out_trade_no) throws IOException,InterruptedException {
Map<String,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 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,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 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 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) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}

}

四、微信H5调起支付

这个url需要后台实现,其实现功能如下: 1、接受微信服务器端发送的支付结果。 2、向微信服务器发送支付结果

具体 参考微信aip() 具体代码如下: 4.1、授权向后台发起生成统一下订单页面 wxrepay.jsp

rush:xhtml;"> <%@ 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(); %> 微信<a href="https://www.jb51.cc/tag/gongzhonghaozhifu/" target="_blank" class="keywords">公众号支付</a>
Box">

<div class="branch_con">

<script type="text/javascript" src="../js/common.js?t=<%=t%>">

首先是请求服务端wxprepay.shml接口,后台向微信支付平台获取支付订单信息,返回前台,wxpay.jsp页面 4.2、确认支付页面

<%@ 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(); %> 微信公众号支付

<div class="branch_con">

<script type="text/javascript" src="../js/common.js?t=<%=t%>">
<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(){

WeixinjsBridge.invoke(
'getBrandWCPayRequest',{
"appId" : appId,//公众号名称,由商户传入
"timeStamp": timeStamp,//时间戳,自1970年以来的秒数
"nonceStr" : nonceStr,//随机
"package" : "prepay_id=" + pg,"signType" : signType,//微信签名方式:
"paySign" : paySign //微信签名
},function(res){
if(res.err_msg == "get_brand_wcpay_request:ok" ) {

alert("支付成功");
} // 使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回 ok,但并不保证它绝对可靠。
}
);
}

function pay(){

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();
}

}

4.2、前台涉及到的工具类 javascript工具类common.js,样式css.css就不贴了没意义。

$(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 {
//alert(response.reason);
}
},error: function(x,e) {
//alert("error",x);
},complete: function(x) {
//alert("call complete");
}
});
return false;
}

function ajaxUtilViaGet(requestdata,succFunction,failFunction){
$.ajax({
url: ajaxurl,type: "GET",dataType: "json",success: function(response) {
if (response.code){
if (succFunction != null)
succFunction(response.response);
} else {
if (failFunction != null)
failFunction(response.response);
}
},complete: function(x) {
}
});
return false;
}
function printUtil(panel,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 {
// alert(response.reason);
}
},error : function(x,e) {
// alert("error",complete : function(x) {
// alert("call complete");
}
});
return false;
}
function appendUtil(panel,success : function(response) {
if (response.code) {
if (panel != null && panel.length > 0) {
if (printfunction != null)
$(panel).append(printfunction(response.response));
}
return true;
} else {
// alert(response.reason);
}
},complete : function(x) {
// alert("call complete");
}
});
return false;
}

function ajaxUtilAsync(requestdata,failFunction) {
$.ajax({
url : ajaxurl,type : "POST",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);
}
}
},complete : function(x) {
}
});
return false;
}

function ajaxUtil(requestdata,type: "POST",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);
}
}
},complete: function(x) {
}
});
return false;
}
function loadSelection(panel,itemName){
ajaxUtil(requestdata,function(response){
var list = response.list;
for (var i = 0;i<list.length;i++){
$(panel).append("");
}
},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",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) { // IE
url = document.getElementById(sourceId).value;
} else if(navigator.userAgent.indexOf("Firefox")>0) { // Firefox
url = window.URL.createObjectURL(document.getElementById(sourceId).files.item(0));
} else if(navigator.userAgent.indexOf("Chrome")>0) { // Chrome
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',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; //单位M
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 = 2Math.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的扩展,将 Date 转化为指定格式的String
//月(M)、日(d)、小时(h)、分(m)、秒(s)、季度(q) 可以用 1-2 个占位符,
//年(y)可以用 1-4 个占位符,毫秒(S)只能用 1 个占位符(是 1-3 位的数字)
//例子:
//(new Date()).Format("yyyy-MM-dd hh:mm:ss.S") ==> 2006-07-02 08:09:04.423
//(new Date()).Format("yyyy-M-d h:m:s.S") ==> 2006-7-2 8:9:4.18
Date.prototype.format = function(fmt)
{ //author: meizz
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);
}

//微信页面授权 snsapi_base方式
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";
    }

//页面授权针对snsapi_base方式授权的url
function wecharauto2baseurl(url) {
return wecharauto2burl(urlpre+url);
}

//页面授权针对snsapi_userinfo方式授权的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";
    }

//微信分享方法需放在wx.ready中
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,// 分享图标
type: 'link',// 分享类型,music、video或link,不填认为link
dataUrl: '',// 如果type是music或video,则要提供数据链接认为空
success: function () {
// 用户确认分享后执行的回调函数
},cancel: function () {
// 用户取消分享后执行的回调函数
}
});

//分享到QQ
wx.onMenuShareQQ({
title: title,cancel: function () {
// 用户取消分享后执行的回调函数
}
});

//分享到腾讯微博
wx.onMenuShareWeibo({
title: title,cancel: function () {
// 用户取消分享后执行的回调函数

}
});
}

五、支付结果

公众号调起效果如下:

支付成功后,微信服务器得到后台的Notify通知后,会发微信说明支付信息,支付凭证如下:

后续会全部更新微信app支付,微信支付退款,微信企业向个人付款,支付宝相关支付。而且会上传全部代码到csdn资源下载处,尽请关注。

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。