1.使用到的jar包

	<!--微信支付 -->
	 <dependency>
	    <groupId>com.github.wxpay</groupId>
	    <artifactId>wxpay-sdk</artifactId>
	    <version>3.0.9</version>
     </dependency>

	<!--httpclient-->
	<dependency>
	    <groupId>org.apache.httpcomponents</groupId>
	    <artifactId>httpclient</artifactId>              
	</dependency>
	

2.ServiceImpl中写统一下单接口

public Map createNative(String out_trade_no, String total_fee) {
		// TODO 自动生成的方法存根
		Map<String,String> param=new HashMap<>();
		param.put("appid", appid);	//小程序id
		param.put("mch_id", partner);//商户号
		param.put("nonce_str", WXPayUtil.generateNonceStr());//随机字符串        
		param.put("body", "测试数据");//商品描述
		param.put("out_trade_no", out_trade_no);//商户订单号
		param.put("total_fee",total_fee);//总金额(分)
		param.put("spbill_create_ip", "127.0.0.1");//IP
		param.put("notify_url", notifyurl);//回调地址
		param.put("trade_type", "NATIVE");//交易类型
		param.put("product_id",out_trade_no);//订单
		try {
            //2.生成要发送的xml 
            //partnerkey 商户秘钥
            String xmlParam = WXPayUtil.generateSignedXml(param, partnerkey);
            HttpClientM client = new HttpClientM("https://api.mch.weixin.qq.com/pay/unifiedorder");
            client.setHttps(true);
            client.setXmlParam(xmlParam);
            client.post();        
            //3.获得结果 
            String result = client.getContent();
            System.out.println(result);
            Map<String, String> resultMap = WXPayUtil.xmlToMap(result);            
            Map<String, String> map=new HashMap<>();
            map.put("code_url", resultMap.get("code_url"));//二维码支付地址
            map.put("total_fee", total_fee);//总金额
            map.put("out_trade_no",out_trade_no);//订单号
            return map;
        } catch (Exception e) {
            e.printStackTrace();
            return new HashMap<>();
        }            
	}

上面用到的HttpClientM类

package com.pj.project.wxpay;

import java.io.IOException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.text.ParseException;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.net.ssl.SSLContext;

import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContextBuilder;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

/**
 * http请求客户端
 * 
 * @author ren
 * 
 */
public class HttpClientM {

	private String url;
	private Map<String, String> param;
	private int statusCode;
	private String content;
	private String xmlParam;
	private boolean isHttps;

	public boolean isHttps() {
		return isHttps;
	}

	public void setHttps(boolean isHttps) {
		this.isHttps = isHttps;
	}

	public String getXmlParam() {
		return xmlParam;
	}

	public void setXmlParam(String xmlParam) {
		this.xmlParam = xmlParam;
	}

	public HttpClientM(String url, Map<String, String> param) {
		this.url = url;
		this.param = param;
	}

	public HttpClientM(String url) {
		this.url = url;
	}

	public void setParameter(Map<String, String> map) {
		param = map;
	}

	public void addParameter(String key, String value) {
		if (param == null)
			param = new HashMap<String, String>();
		param.put(key, value);
	}

	public void post() throws ClientProtocolException, IOException {
		HttpPost http = new HttpPost(url);
		setEntity(http);
		execute(http);
	}

	public void put() throws ClientProtocolException, IOException {
		HttpPut http = new HttpPut(url);
		setEntity(http);
		execute(http);
	}

	public void get() throws ClientProtocolException, IOException {
		if (param != null) {
			StringBuilder url = new StringBuilder(this.url);
			boolean isFirst = true;
			for (String key : param.keySet()) {
				if (isFirst)
					url.append("?");
				else
					url.append("&");
				url.append(key).append("=").append(param.get(key));
			}
			this.url = url.toString();
		}
		HttpGet http = new HttpGet(url);
		execute(http);
	}

	/**
	 * set http post,put param
	 */
	private void setEntity(HttpEntityEnclosingRequestBase http) {
		if (param != null) {
			List<NameValuePair> nvps = new LinkedList<NameValuePair>();
			for (String key : param.keySet())
				nvps.add(new BasicNameValuePair(key, param.get(key))); // 参数
			http.setEntity(new UrlEncodedFormEntity(nvps, Consts.UTF_8)); // 设置参数
		}
		if (xmlParam != null) {
			http.setEntity(new StringEntity(xmlParam, Consts.UTF_8));
		}
	}

	private void execute(HttpUriRequest http) throws ClientProtocolException, IOException {
		CloseableHttpClient httpClient = null;
		try {
			if (isHttps) {
				SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
					// 信任所有
					public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
						return true;
					}
				}).build();
				SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext);
				httpClient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
			} else {
				httpClient = HttpClients.createDefault();
			}
			CloseableHttpResponse response = httpClient.execute(http);
			try {
				if (response != null) {
					if (response.getStatusLine() != null)
						statusCode = response.getStatusLine().getStatusCode();
					HttpEntity entity = response.getEntity();
					// 响应内容
					content = EntityUtils.toString(entity, Consts.UTF_8);
				}
			} finally {
				response.close();
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			httpClient.close();
		}
	}

	public int getStatusCode() {
		return statusCode;
	}

	public String getContent() throws ParseException, IOException {
		return content;
	}
}

Controller调用Service中的方法

   @RequestMapping("/createNative")
   public AjaxJson createNativePay(){
    	//雪花算法类 随机生成号码
    	IdWorker idworker=new IdWorker(); 
    	long oid=idworker.nextId();
    	//订单实体类
    	SfOrders sfOrders=new SfOrders();
    	//set订单id
    	sfOrders.setOid(oid);
    	//支付状态
    	sfOrders.setPay_id(2);
    	//添加到数据库
    	int x=ordersMapper.add(sfOrders);    	
    	//判断是否添加成功
    	if(x>=1) {
    		//获取插入的id
    		Long keyid=publicMapper.getPrimarykey();
    		//转换keyid类型
    		int k=keyid.intValue();	
    		//根据id查询这一条数据
    		SfOrders orders=ordersMapper.getById(k);
    		//根据订单id,支付金额生成二维码
	    	Map map=weixinPayService.createNative(orders.getOid()+"","1");
	    	return AjaxJson.getSuccessData(map);     
    	}
		return AjaxJson.getSuccess();
    }

页面写法,有想要测试的话朋友可以试试点击下载生成二维码的包qrcode.js

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
		<!-- 所有的 css & js 资源 -->
		<link rel="stylesheet" href="https://unpkg.com/element-ui@2.13.0/lib/theme-chalk/index.css">
		<link rel="stylesheet" href="../../static/sa.css">
		<script src="https://unpkg.com/vue@2.6.10/dist/vue.min.js"></script>
		<script src="https://unpkg.com/element-ui@2.13.0/lib/index.js"></script>
		<script src="https://unpkg.com/jquery@3.4.1/dist/jquery.min.js"></script>
		<script src="https://www.layuicdn.com/layer-v3.1.1/layer.js"></script>
		<script src="../../static/sa.js"></script>
		<script src="../../static/qrcode/qrcode.js"></script>
		<style>
		</style>
	</head>
	<body>
		<div class="vue-box">
			<div class="c-item" style="min-width: 0px;">
				<el-button @click="queryCode()">点击事件二维码</el-button>
			</div>
		</div>

		<div id="code"></div>

		<script>
			var app = new Vue({
				el: '.vue-box',
				data: {
					code_url: '',
					out_trade_no: '' 
				},
				
				methods: {
					queryCode: function() {
						//  统一下单 
						// ajax返回 下单的数据  
						sa.ajax('/pay/createNative', function(res) {
							console.log(res);
							new QRCode(document.getElementById('code'), res.data.code_url); // 创建二维码
							this.out_trade_no = res.data.out_trade_no; //  赋值  res里获取的赋值给data里面的 
							console.log(res.data.out_trade_no + "----------订单id")
						}.bind(this), {});
					},	
				},
				created: function() {

				}
			})
		</script>
	</body>
</html>

写到这里了是可以去页面测试扫码支付的。

3.支付回调

 @RequestMapping("/wxnotify")
 public void wxnotify(HttpServletRequest request, HttpServletResponse response) {
       String resXml = "";
       InputStream inStream;
       try {
           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);
           }

           WXPayUtil.getLogger().info("wxnotify:微信支付----start----");

           // 获取微信调用我们notify_url的返回信息
           String result = new String(outSteam.toByteArray(), "utf-8");
           WXPayUtil.getLogger().info("wxnotify:微信支付----result----=" + result);

           // 关闭流
           outSteam.close();
           inStream.close();

           // xml转换为map
           Map<String, String> resultMap = WXPayUtil.xmlToMap(result);
           //判断状态 验证签名是否正确
           boolean isSuccess = false;
           
           if (WXPayConstants.SUCCESS.equalsIgnoreCase(resultMap.get(WXPayConstants.RESULT_CODE))) {

               WXPayUtil.getLogger().info("wxnotify:微信支付----返回成功");

               if (WXPayUtil.isSignatureValid(resultMap, WXPayConstants.API_KEY)) {
                  
                   WXPayUtil.getLogger().info("wxnotify:微信支付----验证签名成功");

                   resXml = resSuccessXml;
                   isSuccess = true;

               } else {
                   WXPayUtil.getLogger().error("wxnotify:微信支付----判断签名错误");
               }

           } else {
               WXPayUtil.getLogger().error("wxnotify:支付失败,错误信息:" + resultMap.get(WXPayConstants.ERR_CODE_DES));
               resXml = resFailXml;
           }
           // 回调方法,处理业务 - 修改订单状态
           WXPayUtil.getLogger().info("wxnotify:微信支付回调:修改的订单===>" + resultMap.get("out_trade_no"));
           int x=ordersService.updateByOid(resultMap.get("out_trade_no"));
           if (x>=1) {
               WXPayUtil.getLogger().info("wxnotify:微信支付回调:修改订单支付状态成功");
           } else {
               WXPayUtil.getLogger().error("wxnotify:微信支付回调:修改订单支付状态失败");
           }
           
       } catch (Exception e) {
           WXPayUtil.getLogger().error("wxnotify:支付回调发布异常:", e);
       } finally {
           try {
               // 处理业务完毕
               BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
               out.write(resXml.getBytes());
               out.flush();
               out.close();
           } catch (IOException e) {
               WXPayUtil.getLogger().error("wxnotify:支付回调发布异常:out:", e);
           }
       }

   }

上面定义的WXPayConstants这个类是自己封装的类。例如:

public class WXPayConstants {
	//返回code码
	public static final String RESULT_CODE = "result_code";	
	//返回成功状态
	public static final String SUCCESS = "SUCCESS";		
	//商户秘钥
	public static final String API_KEY = "lentonxxxxxxxxx";
	//返回错误状态		
	public static final String ERR_CODE_DES = "err_code_des";
	//返回失败状态	
	public static final String FAIL = "FAIL";	
}

定义的resSuccessXml,resFailXml写为常量用String接收,写在本类就可以。例如:

 /**
  * 返回成功xml
  */
 private String resSuccessXml = "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";

/**
 * 返回失败xml
 */
 private String resFailXml = "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[报文为空]]></return_msg></xml>";
写到这里就已经完成扫码支付了,如果有朋友是用这个方法做支付的话可以参考。有不懂的地方可以在下面留言。
接一篇退款的博客可点击👉 微信支付(native方式二)原路退款
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐