第三篇、记录微信统一支付、扫码支付开发

项目中使用了微信的统一支付以及扫码支付,记录下学习记录

目录

项目中使用了微信的统一支付以及扫码支付,记录下学习记录

1、配置wechat4j.properties 文件

2.编写支付工具类

3.统一支付

3.扫码支付

4、工具类方法

5.Controller层调用

6.前台页面处理

7.总结


1、配置wechat4j.properties 文件

话不多说,直接上配置文件代码 



#url
wechat.url=
#token
wechat.token=wechatserver
#encodingaeskey
wechat.encodingaeskey=
wechat4j.config=/wechat4j-test.properties
#wechat appid
wechat.appid=xxxxxx
#wechat app secret
wechat.appsecret=xxxxx

wechat.mch.id=xxxx
#wechat mch api secret key, must be 32 length
wechat.mch.key=xxxx

配置文件里面主要使用的参数是wechat.mch.id 和wechat.mch.key 分别需要配置商户的id和key,配置好这个后可以进行下一步了。

 

2.编写支付工具类

在实际开发中,我是将统一支付、撤单、扫码支付等相关接口写到一个支付工具类中,方便多处地方调用。参考微信的官方文档,将其中需要传递的参数封装成一个实体类,方便具体controller中设定参数,具体参数如下:

private String config = "/wechat4j.properties";

	private String body;
	private String detail;
	private String attach;
	private String outTradeNo;
	private String userOpenId;
	private String notifyUrl;
	private String authCode;
    
    get..set 省略

3.统一支付

首先写下我自己实际使用中使用的类名称导入列表,方便用户使用中可以参考下,具体类使用的是哪个包下面的

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.ConnectException;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Formatter;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.UUID;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.servlet.http.HttpServletRequest;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jdom2.JDOMException;
import org.springframework.stereotype.Service;
import org.sword.wechat4j.common.Config;
import org.sword.wechat4j.pay.PayManager;
import org.sword.wechat4j.pay.protocol.unifiedorder.UnifiedorderRequest;
import org.sword.wechat4j.pay.protocol.unifiedorder.UnifiedorderResponse;
import org.sword.wechat4j.util.RandomStringGenerator;

import com.jfinal.kit.StrKit;
import com.sdhr.shu.bean.extend.BizException;
import com.sdhr.shu.common.Constants;

import net.sf.json.JSONObject;

也不会写什么具体解释了,直接贴代码吧,这个方法主要是统一支付的函数,其中可能用到了一些其他的工具类方法,下面尽量全部写进来。

/**
	 * 支付入口
	 * 
	 * @param recordId
	 * @param payMoney  支付金额
	 * @param request
	 * @param notifyUrl 回调url
	 */
	public Map<String, String> ToPayment(Double payMoney, HttpServletRequest request) throws Exception {
		// Integer min =
		// Integer.valueOf(ReadPropertiesUtils.getInstance().getProperty("order_pay_wechat_expiretime"));
		Integer min = 30;
		Date start = new Date();
		Calendar date = Calendar.getInstance();
		date.setTime(start);
		date.set(Calendar.MINUTE, date.get(Calendar.MINUTE) + min);
		Date end = date.getTime();
		// 支付开始时间
		String timeStart = DateUtil.formatDateTime(start, DateFormatter.SDF_YMDHMS4);
		// 支付结束时间
		String timeExpire = DateUtil.formatDateTime(end, DateFormatter.SDF_YMDHMS4);

		// 统一下单
		UnifiedorderRequest unifiedorderRequest = new UnifiedorderRequest(config);
		unifiedorderRequest.setNonce_str(RandomStringGenerator.generate());// 随机字符串
		unifiedorderRequest.setBody(body);// 商品描述
		unifiedorderRequest.setDetail(detail);// 商品详情
		unifiedorderRequest.setAttach(attach); // 随便写,会原样带回
		unifiedorderRequest.setOut_trade_no(outTradeNo); // 我们自己的交易订单号
		unifiedorderRequest.setTotal_fee((int) (payMoney * 100)); // 钱,单位是分
		unifiedorderRequest.setSpbill_create_ip(Utils.getIpAddr(request));// ip地址
		unifiedorderRequest.setTime_start(timeStart);
		unifiedorderRequest.setTime_expire(timeExpire);
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
		unifiedorderRequest.setTime_start(sdf.format(new Date()));
		unifiedorderRequest.setTrade_type("JSAPI");// 交易类型
		// 获取支付用户的openId
		unifiedorderRequest.setOpenid(userOpenId);
		unifiedorderRequest.setNotify_url(notifyUrl);// 通知地址
		UnifiedorderResponse unifiedorderResponse = PayManager.unifiedorder(unifiedorderRequest, config);

		String prepayId = unifiedorderResponse.getPrepay_id();
		if (prepayId == null) {
			throw new BizException("E110", Message.getMessage("E110"));
		}
		String jsParam = null;
		if (prepayId != null && prepayId.length() > 10) {
			// 生成微信支付参数,此处拼接为完整的JSON格式,符合支付调起传入格式
			jsParam = createPackageValue(Config.instance(config).getAppid(), Config.instance(config).getMchKey(),
					prepayId);
			// 此处可以添加订单的处理逻辑
			logger.info("生成的微信调起JS参数为:" + jsParam);
			logger.debug("-----ToPayment---------outTradeNo:" + outTradeNo + ",totalMoney:" + payMoney);
		}
		Map<String, String> map = new HashMap<String, String>();
		map.put("prepayId", prepayId);
		map.put("jsParam", jsParam);
		map.put("outTradeNo", outTradeNo);
		return map;
	}

3.扫码支付

扫码支付对比统一支付相对参数会简单点,具体代码如下:

public Map<String, String> scanQRCodePay(String payMoney, HttpServletRequest request)
			throws JDOMException, IOException {
		Integer min = 30;
		Date start = new Date();
		Calendar date = Calendar.getInstance();
		date.setTime(start);
		date.set(Calendar.MINUTE, date.get(Calendar.MINUTE) + min);
		Date end = date.getTime();
		// 支付开始时间
		String timeStart = DateUtil.formatDateTime(start, DateFormatter.SDF_YMDHMS4);
		// 支付结束时间
		String timeExpire = DateUtil.formatDateTime(end, DateFormatter.SDF_YMDHMS4);
		SortedMap<String, String> params = new TreeMap<String, String>();
		params.put("appid", Config.instance().getAppid());
		params.put("mch_id", Config.instance().getMchId());
		params.put("nonce_str", RandomStringGenerator.generate());
		params.put("body", body);
		params.put("attach", attach);
		params.put("out_trade_no", outTradeNo);
		params.put("total_fee", payMoney);
		params.put("spbill_create_ip", Utils.getIpAddr(request));
		params.put("auth_code", authCode);
		params.put("time_start", timeStart);
		params.put("time_expire", timeExpire);
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
		params.put("time_start", sdf.format(new Date()));
		long curren = System.currentTimeMillis();
		curren += 15 * 60 * 1000;
		Date dateExpire = new Date(curren);
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
		params.put("time_expire", dateFormat.format(dateExpire));
		String sign = createSign(params, Config.instance(config).getMchKey());
		params.put("sign", sign);
		String httpRequest = httpRequest(Constants.MICROPAYURI, "POST", toXml(params));
		Map<String, String> xmlMap = XMLUtil.doXMLParse(httpRequest);
		return xmlMap;
	}

4、工具类方法

package com.sdhr.shu.util;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;
import java.io.ByteArrayInputStream;
public class XMLUtil {
    /**
     * 解析xml,返回第一级元素键值对。如果第一级元素有子节点,则此节点的值是子节点的xml数据。
     * @param strxml
     * @return
     * @throws JDOMException
     * @throws IOException
     */
    public static Map doXMLParse(String strxml) throws JDOMException, IOException {
        strxml = strxml.replaceFirst("encoding=\".*\"", "encoding=\"UTF-8\"");
        if(null == strxml || "".equals(strxml)) {
            return null;
        }
         
        Map m = new HashMap();
         
        InputStream in = new ByteArrayInputStream(strxml.getBytes("UTF-8"));
        SAXBuilder builder = new SAXBuilder();
        Document doc = builder.build(in);
        Element root = doc.getRootElement();
        List list = root.getChildren();
        Iterator it = list.iterator();
        while(it.hasNext()) {
            Element e = (Element) it.next();
            String k = e.getName();
            String v = "";
            List children = e.getChildren();
            if(children.isEmpty()) {
                v = e.getTextNormalize();
            } else {
                v = XMLUtil.getChildrenText(children);
            }
             
            m.put(k, v);
        }
         
        //关闭流
        in.close();
         
        return m;
    }
     
    /**
     * 获取子结点的xml
     * @param children
     * @return String
     */
    public static String getChildrenText(List children) {
        StringBuffer sb = new StringBuffer();
        if(!children.isEmpty()) {
            Iterator it = children.iterator();
            while(it.hasNext()) {
                Element e = (Element) it.next();
                String name = e.getName();
                String value = e.getTextNormalize();
                List list = e.getChildren();
                sb.append("<" + name + ">");
                if(!list.isEmpty()) {
                    sb.append(XMLUtil.getChildrenText(list));
                }
                sb.append(value);
                sb.append("</" + name + ">");
            }
        }
         
        return sb.toString();
    }
     
    /**
     * 获取xml编码字符集
     * @param strxml
     * @return
     * @throws IOException
     * @throws JDOMException
     */
    public static String getXMLEncoding(String strxml) throws JDOMException, IOException {
        InputStream in = HttpClientUtil.String2Inputstream(strxml);
        SAXBuilder builder = new SAXBuilder();
        Document doc = builder.build(in);
        in.close();
        return (String)doc.getProperty("encoding");
    }
     
    /**
     * 支付成功,返回微信那服务器
     * @param return_code
     * @param return_msg
     * @return
     */
    public static String setXML(String return_code, String return_msg) {
        return "<xml><return_code><![CDATA[" + return_code + "]]></return_code><return_msg><![CDATA[" + return_msg + "]]></return_msg></xml>";
    }
     
    public static String createXML(Map<String,Object> map){
        Set<Entry<String,Object>> set=map.entrySet();
        set.iterator();
        return null;
    }
     
}
/**
	 * 创建md5摘要,规则是:按参数名称a-z排序,遇到空值的参数不参加签名。
	 */
	private static String createSign(SortedMap<String, String> packageParams, String AppKey) {
		StringBuffer sb = new StringBuffer();
		Set es = packageParams.entrySet();
		Iterator it = es.iterator();
		while (it.hasNext()) {
			Map.Entry entry = (Map.Entry) it.next();
			String k = (String) entry.getKey();
			String v = (String) entry.getValue();
			if (null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) {
				sb.append(k + "=" + v + "&");
			}
		}
		sb.append("key=" + AppKey);
		String sign = Md5Util.MD5Encode(sb.toString(), "UTF-8").toUpperCase();
		return sign;
	}

	/**
	 * 方法名:byteToHex</br>
	 * 详述:字符串加密辅助方法 </br>
	 * 开发人员:souvc </br>
	 * 创建时间:2016-1-5 </br>
	 * 
	 * @param hash
	 * @return 说明返回值含义
	 * @throws 说明发生此异常的条件
	 */
	private static String byteToHex(final byte[] hash) {
		Formatter formatter = new Formatter();
		for (byte b : hash) {
			formatter.format("%02x", b);
		}
		String result = formatter.toString();
		formatter.close();
		return result;

	}

	/**
	 * 方法名:httpRequest</br>
	 * 详述:发送http请求</br>
	 * 开发人员:souvc </br>
	 * 创建时间:2016-1-5 </br>
	 * 
	 * @param requestUrl
	 * @param requestMethod
	 * @param outputStr
	 * @return 说明返回值含义
	 * @throws 说明发生此异常的条件
	 */
	public static String httpRequest(String requestUrl, String requestMethod, String outputStr) {
		JSONObject jsonObject = null;
		StringBuffer buffer = new StringBuffer();
		try {
			TrustManager[] tm = { new MyX509TrustManager() };
			SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
			sslContext.init(null, tm, new java.security.SecureRandom());
			SSLSocketFactory ssf = sslContext.getSocketFactory();
			URL url = new URL(requestUrl);
			HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection();
			httpUrlConn.setSSLSocketFactory(ssf);
			httpUrlConn.setDoOutput(true);
			httpUrlConn.setDoInput(true);
			httpUrlConn.setUseCaches(false);
			httpUrlConn.setRequestMethod(requestMethod);
			if ("GET".equalsIgnoreCase(requestMethod))
				httpUrlConn.connect();
			if (null != outputStr) {
				OutputStream outputStream = httpUrlConn.getOutputStream();
				outputStream.write(outputStr.getBytes("UTF-8"));
				outputStream.close();
			}
			InputStream inputStream = httpUrlConn.getInputStream();
			InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
			BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
			String str = null;
			while ((str = bufferedReader.readLine()) != null) {
				buffer.append(str);
			}
			bufferedReader.close();
			inputStreamReader.close();
			inputStream.close();
			inputStream = null;
			httpUrlConn.disconnect();
			// jsonObject = JSONObject.fromObject(buffer.toString());
		} catch (ConnectException ce) {
			ce.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return buffer.toString();
	}

/**
	 * 微信下单map to xml
	 * 
	 * @param params 参数
	 * @return {String}
	 */
	public static String toXml(Map<String, String> params) {
		StringBuilder xml = new StringBuilder();
		xml.append("<xml>");
		for (Entry<String, String> entry : params.entrySet()) {
			String key = entry.getKey();
			String value = entry.getValue();
			// 略过空值
			if (StrKit.isBlank(value))
				continue;
			xml.append("<").append(key).append(">");
			xml.append(entry.getValue());
			xml.append("</").append(key).append(">");
		}
		xml.append("</xml>");
		return xml.toString();
	}

5.Controller层调用

实际controller层使用的时候,我使用的方法是使用@Autowried 方法注入了一个微信支付相关bean,直接根据相关需要传递的参数设置好后,调用统一支付接口,或者扫码支付接口。下面举简单例子吧。

需要注意的是,微信是区分为预支付和实际支付两种,预支付就是我们将我们本地产生的金额、第三方订单号、交易详细等相关信息封装好请求微信支付接口,需要设定好回调url,在实际支付的接口中根据返回值做相关本地业务逻辑处理。

	@Autowired
	private WechatPayUtil wc;

/**
*预支付
**/
public OutputBean prePay(HttpServletRequest request){
    。。。 具体业务逻辑处理,返回订单号等信息。。。
            wc.setBody("收费");
			wc.setDetail("xxx收费");
			wc.setNotifyUrl("回调url");
			wc.setUserOpenId("用户openid");
            wc.setOutTradeNo("订单号");
            wc.setAttach("附加数据");
            map = wc.ToPayment(“金额”, request);//request 必须是请求url
}

public String realPay(HttpServletRequest request, HttpServletResponse response){
            logger.info("--- 微信支付回调 ---");
            InputStream inStream = request.getInputStream();
	        ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
	        byte[] buffer = new byte[1024];
	        int len = 0;
	        while ((len = inStream.read(buffer)) != -1) {
	            outSteam.write(buffer, 0, len);
	        }
	        outSteam.close();
	        inStream.close();
	        String result = new String(outSteam.toByteArray(), "utf-8");
	        Map<String, String> map = null;
	        map = XMLUtil.doXMLParse(result); //解析微信回调参数

            if (map.get("return_code").equals("SUCCESS")) {
	            if (map.get("result_code").equals("SUCCESS")) {
                    //支付成功,相关处理,具体可以参考微信支付开发文档
                }
            }
}

扫码支付与统一下单比较类似,具体实现方法已经贴出来了,这里不做展示,需要注意的是需要对支付订单结果返回值判断做详细点,因为可能出现问题是,5次内微信是小额免密支付的,但5次后需要输入密码,而且因为网路传输问题,对订单的返回都是有影响的,需要间隔5秒左右(官方推荐)再次查询订单状况,根据实际返回情况做页面显示和具体业务逻辑处理。在这里我贴下我自己的判断逻辑,希望大佬指教。

 

if(!Utils.isNullOrEmpty(returnCode) && "SUCCESS".equals(returnCode)){
				String resultCode = map.get("result_code");
				String sign = map.get("sign");
				if(!Utils.isNullOrEmpty(resultCode) && "SUCCESS".equals(resultCode)){
					logger.info("-- 收款成功 ---");
					
					wxScanPayOutPutBean.setErrorCode("SUCCESS");
					wxScanPayOutPutBean.setErrorMsg("付款成功");
					flag = true;
				}else {
					// 通信成功,但支付失败
					if("USERPAYING".equals(errorCode) || "BANKERROR".equals(errorCode) || "SYSTEMERROR".equals(errorCode) ){
						//间隔5秒查询订单,直至支付超时
				        // 查询订单
						
						String tradeState = "";
						for(int times = 0;times<=6;times++){
							Thread.sleep(5000);
							OrderqueryRequest orderqueryRequest = new OrderqueryRequest();
					        orderqueryRequest.setAppid(map.get("appid"));
					        orderqueryRequest.setMch_id(map.get("mch_id"));
					        orderqueryRequest.setOut_trade_no(preBillUuid);
					        orderqueryRequest.setNonce_str(RandomStringGenerator.generate());
					        orderqueryRequest.setSign(map.get("sign"));
					        OrderqueryResponse orderqueryResponse = PayManager.orderquery(orderqueryRequest);
					        System.out.println(orderqueryResponse);
					        if(!Utils.isNullOrEmpty(orderqueryResponse.getResult_code()) && "SUCCESS".equals(orderqueryResponse.getResult_code())){
					        	if("SUCCESS".equals(orderqueryResponse.getTrade_state())){
					    
					        		wxScanPayOutPutBean.setErrorMsg("付款成功");
					        		flag = true;
					        		break;
					        	}else {
					        		wxScanPayOutPutBean.setErrorCode(orderqueryResponse.getTrade_state());
					        		wxScanPayOutPutBean.setErrorMsg(orderqueryResponse.getTrade_state_desc());
					        	}
					        }
						}
						if(Utils.isNullOrEmpty(tradeState) || !"SUCCESS".equals(tradeState)){
							//撤销订单
							
							Map<String, String> reverseOrder = wc.reverseOrder(preBillUuid);
							if(null != reverseOrder){
								if(!Utils.isNullOrEmpty(reverseOrder.get("return_code")) && "SUCCESS".equals(reverseOrder.get("return_code"))){
						        	flag = false;
						        	if(!Utils.isNullOrEmpty(reverseOrder.get("result_code")) && "SUCCESS".equals(reverseOrder.get("result_code"))){
						        		wxScanPayOutPutBean.setResult(2);//支付失败,请重新支付
							        	wxScanPayOutPutBean.setErrorCode("FAIL");
							        	wxScanPayOutPutBean.setErrorMsg("收款失败,订单已被撤销,请重试");
						        	}else if("REVERSE_EXPIRE".equals(reverseOrder.get("result_code"))){
						        		wxScanPayOutPutBean.setResult(2);//支付失败,请重新支付
							        	wxScanPayOutPutBean.setErrorCode("FAIL");
							        	wxScanPayOutPutBean.setErrorMsg("收款失败,订单已过期无法撤销");
						        	}else {
						        		wxScanPayOutPutBean.setResult(5);
										wxScanPayOutPutBean.setErrorCode(errorCode);
										wxScanPayOutPutBean.setErrorMsg("系统错误");
						        	}
						        	
						        }
							}else {
								wxScanPayOutPutBean.setResult(2);//支付失败,请重新支付
					        	wxScanPayOutPutBean.setErrorCode("FAIL");
					        	wxScanPayOutPutBean.setErrorMsg("收款失败,请重试");
							}
							System.err.println(reverseOrder);
					        
						}
						
				        
					}else if ("ORDERPAID".equals(errorCode) ) {
						// 通知前台已经订单已经支付,或已关闭,不能继续扫码
						wxScanPayOutPutBean.setResult(3);
						wxScanPayOutPutBean.setErrorCode(errorCode);
						wxScanPayOutPutBean.setErrorMsg(err_code_des);
					}else if ("AUTHCODEEXPIRE".equals(errorCode) || "NOTENOUGH".equals(errorCode) || "NOTSUPORTCARD".equals(errorCode) || "ORDERREVERSED".equals(errorCode) || "BUYER_MISMATCH".equals(errorCode) || "AUTH_CODE_INVALID".equals(errorCode) || "ORDERCLOSED".equals(errorCode) ) {
						// 重新扫码,通知前台错误结果
						wxScanPayOutPutBean.setResult(4);
						wxScanPayOutPutBean.setErrorCode(errorCode);
						wxScanPayOutPutBean.setErrorMsg(err_code_des);
					}else {
						// 通知前台系统错误,不能扫码
						wxScanPayOutPutBean.setResult(5);
						wxScanPayOutPutBean.setErrorCode(errorCode);
						wxScanPayOutPutBean.setErrorMsg("系统错误");
					}
				}

6.前台页面处理

首先需要引入微信js

 <script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.2.0.js" ></script>

在首先调用预支付接口产生费用后,将相关参数封装为json格式字符串传递到微信支付接口

                 var prepayId = thatData['prepayId'];
	        	 var jsParam = thatData['jsParam'];
	        	 var outTradeNo = thatData['outTradeNo'];
                 toPay(jsParam);


function toPay(jsParam){
			var obj = JSON.parse(jsParam);
		   WeixinJSBridge.invoke(
		       'getBrandWCPayRequest',obj,
		       function(res){
		    	//   loading();
		            WeixinJSBridge.log(res.err_msg);
		            if(res.err_msg == "get_brand_wcpay_request:ok"){
		                window.location.href = "xxxxx";//去支付成功页面
		            }else if(res.err_msg == "get_brand_wcpay_request:cancel"){
		            	window.location.href = "支付取消处理"
		            }else{
		            	$.toast("支付失败", "forbidden", function() {
		            		window.location.href = "支付失败处理"
		                });
		            }
		        }
		   ); 
		}

扫码支付配置如下,需要先配置js  wx.config相关参数,js必须要提前引入

<script src='https://res.wx.qq.com/open/js/jweixin-1.0.0.js'></script>
	      <script>
	      /*    $(function(){
	    	 $.ajax({     
			        type: "Post",     
			        //方法所在页面和方法名      
			        url: "/shu-wechat-client/park/charge/getWxConfig",   
			        data:{}, 
			        dataType: "json",     
			        success: function(data) { */
			        	 wx.config({
					 		    debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
					 		    appId: "${sessionScope.appId}", // 必填,公众号的唯一标识
					 		    timestamp: "${sessionScope.timestamp}", // 必填,生成签名的时间戳
					 		    nonceStr:  "${sessionScope.nonceStr}", // 必填,生成签名的随机串
					 		    signature: "${sessionScope.signature}",// 必填,签名,见附录1
					 		    jsApiList: ['checkJsApi','scanQRCode'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
					 		});
			      /*   },     
			        error: function(err) {
			       	 Lalert("请求出错");
			        }     
			    });  
	      }) */
	     
		     
    	</script> 

实际扫码收款操作

wx.ready(function() {
		  wx.checkJsApi({  
	            jsApiList : ['scanQRCode'],  
	            success : function(res) {  
	            }  
      	 	});  
		});
		
		//var result ;
		$("#scanQrcode").click(function(){
			$("#payimg").attr("src","/shu-wechat-client/img/parkpay/nopay.png");
            $(".pay-state-word").text("支付中");
            wx.scanQRCode({  
                needResult : 1, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果,  
                scanType : [ "qrCode", "barCode" ], // 可以指定扫二维码还是一维码,默认二者都有  
                success : function(res) {  
                     var result = res.resultStr; // 当needResult 为 1 时,扫码返回的结果  
                     loading("支付中...");
                     scanToPayFuction(result); //调用后台实际扫码接口,并根据返回值做处理
                     
                }  
            });  
		});
		

7.总结

之上就是我自己做微信统一支付以及扫码支付的一个做法吧,在这里记录下,以后遇到也能够有解决的回溯,也希望能够帮助到一些需要这些知识的人,可能写的不太好,或者有些方法不是很完善,希望大佬指点下,谢谢。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值