欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java調(diào)用微信支付功能的方法示例代碼

 更新時(shí)間:2020年08月14日 12:55:05   作者:迷途知返-  
這篇文章主要介紹了Java調(diào)用微信支付功能的方法示例代碼,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

Java 使用微信支付

前言百度搜了一下微信支付,都描述的不太好,于是乎打算自己寫(xiě)一個(gè)案例,希望以后拿來(lái)直接改造使用。
因?yàn)樯婕岸S碼的前端顯示,所以有前端的內(nèi)容

一. 準(zhǔn)備工作

所需微信公眾號(hào)信息配置

  • APPID:綁定支付的APPID(必須配置)
  • MCHID:商戶(hù)號(hào)(必須配置)
  • KEY:商戶(hù)支付密鑰,參考開(kāi)戶(hù)郵件設(shè)置(必須配置)
  • APPSECRET:公眾帳號(hào)secert(僅JSAPI支付的時(shí)候需要配置)

我這個(gè)案例用的是尚硅谷一位老師提供的,這里不方便提供出來(lái),需要大家自己找,或者公司提供

二. 構(gòu)建項(xiàng)目架構(gòu)

1.新建maven項(xiàng)目

在這里插入圖片描述

2.導(dǎo)入依賴(lài)

<parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-parent</artifactId>
  <version>2.2.1.RELEASE</version>
 </parent>
 <dependencies>
  <!--spring boot -->
  <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-web</artifactId>
  </dependency>
  <!--微信提供的sdk-->
  <dependency>
   <groupId>com.github.wxpay</groupId>
   <artifactId>wxpay-sdk</artifactId>
   <version>0.0.3</version>
  </dependency>
  <!--發(fā)送http請(qǐng)求-->
  <dependency>
   <groupId>org.apache.httpcomponents</groupId>
   <artifactId>httpclient</artifactId>
  </dependency>
  <!--模板引擎-->
  <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-freemarker</artifactId>
  </dependency>
 </dependencies>

在這里插入圖片描述

依賴(lài)中需要注意的是我導(dǎo)入了微信提供的sdk,以及freemarker模板引擎

3.編寫(xiě)配置文件application.properties

# 服務(wù)端口
server.port=8081
# 微信開(kāi)放平臺(tái) appid
wx.pay.app_id=
#商戶(hù)號(hào)
wx.pay.partner=
#商戶(hù)key
wx.pay.partnerkey=
#回調(diào)地址
wx.pay.notifyurl:

spring.freemarker.tempalte-loader-path=classpath:/templates
#  關(guān)閉緩存,及時(shí)刷新,上線生產(chǎn)環(huán)境需要修改為true
spring.freemarker.cache=false
spring.freemarker.charset=UTF-8
spring.freemarker.check-template-location=true
spring.freemarker.content-type=text/html
spring.freemarker.expose-request-attributes=true
spring.freemarker.expose-session-attributes=true
spring.freemarker.request-context-attribute=request
spring.freemarker.suffix=.ftl
spring.mvc.static-path-pattern: /static/**

在這里插入圖片描述

4.編寫(xiě)啟動(dòng)類(lèi)

@SpringBootApplication
@ComponentScan(basePackages = {"com.haiyang.wxpay"})
public class Application {

 public static void main(String[] args) {
  SpringApplication.run(Application.class, args);
 }
}

在這里插入圖片描述

5.創(chuàng)建常用包c(diǎn)ontroller,service,impl,utils

在這里插入圖片描述

6.創(chuàng)建兩個(gè)前端需要的文件夾 static和templates

在這里插入圖片描述

三. 代碼實(shí)現(xiàn)

1. 創(chuàng)建工具類(lèi)讀取配置文件的參數(shù)

@Component
public class WxPayUtils implements InitializingBean {

 @Value("${wx.pay.app_id}")
 private String appId;

 @Value("${wx.pay.partner}")
 private String partner;

 @Value("${wx.pay.partnerkey}")
 private String partnerKey;
 @Value("${wx.pay.notifyurl}")
 private String notifyUrl;


 public static String WX_PAY_APP_ID;
 public static String WX_PAY_PARTNER;
 public static String WX_PAY_PARTNER_KEY;
 public static String WX_OPEN_NOTIFY_URL;

 @Override
 public void afterPropertiesSet() throws Exception {
  WX_PAY_APP_ID = appId;
  WX_PAY_PARTNER = partner;
  WX_PAY_PARTNER_KEY = partnerKey;
  WX_OPEN_NOTIFY_URL = notifyUrl;
 }

}

在這里插入圖片描述

2. 構(gòu)建工具類(lèi)發(fā)送http請(qǐng)求

/**
 * http請(qǐng)求客戶(hù)端
 * 
 * @author qy
 * 
 */
public class HttpClient {
	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 HttpClient(String url, Map<String, String> param) {
		this.url = url;
		this.param = param;
	}

	public HttpClient(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))); // 參數(shù)
			http.setEntity(new UrlEncodedFormEntity(nvps, Consts.UTF_8)); // 設(shè)置參數(shù)
		}
		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();
					// 響應(yīng)內(nèi)容
					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;
	}

}

額~有點(diǎn)長(zhǎng)就不放圖片了 代碼都一樣

3. 新建controller

@Controller
@RequestMapping("/wxpay")
public class WxPayController {
 @RequestMapping("/pay")
 public String createPayQRcode(Model model) throws Exception{

  String price = "0.01";
  String no = getOrderNo();
  Map m = new HashMap();
  m.put("appid", WxPayUtils.WX_PAY_APP_ID);
  m.put("mch_id", WxPayUtils.WX_PAY_PARTNER);
  m.put("nonce_str", WXPayUtil.generateNonceStr());
  m.put("body","微信支付測(cè)試"); //主體信息
  m.put("out_trade_no", no); //訂單唯一標(biāo)識(shí)
  m.put("total_fee", getMoney(price));//金額
  m.put("spbill_create_ip", "127.0.0.1");//項(xiàng)目的域名
  m.put("notify_url", WxPayUtils.WX_OPEN_NOTIFY_URL);//回調(diào)地址
  m.put("trade_type", "NATIVE");//生成二維碼的類(lèi)型

  //3 發(fā)送httpclient請(qǐng)求,傳遞參數(shù)xml格式,微信支付提供的固定的地址
  HttpClient client = new HttpClient("https://api.mch.weixin.qq.com/pay/unifiedorder");
  //設(shè)置xml格式的參數(shù)
  //把xml格式的數(shù)據(jù)加密
  client.setXmlParam(WXPayUtil.generateSignedXml(m, WxPayUtils.WX_PAY_PARTNER_KEY));
  client.setHttps(true);
  //執(zhí)行post請(qǐng)求發(fā)送
  client.post();
  //4 得到發(fā)送請(qǐng)求返回結(jié)果
  //返回內(nèi)容,是使用xml格式返回
  String xml = client.getContent();
  //把xml格式轉(zhuǎn)換map集合,把map集合返回
  Map<String,String> resultMap = WXPayUtil.xmlToMap(xml);
  //最終返回?cái)?shù)據(jù) 的封裝
  Map map = new HashMap();
  map.put("no", no);
  map.put("price", price);
  map.put("result_code", resultMap.get("result_code"));
  map.put("code_url", resultMap.get("code_url"));

  model.addAttribute("map",map);
  return "pay";

 }

 @GetMapping("queryorder/{no}")
 @ResponseBody
 public String queryPayStatus(@PathVariable String no) throws Exception{
  //1、封裝參數(shù)
  Map m = new HashMap<>();
  m.put("appid", WxPayUtils.WX_PAY_APP_ID);
  m.put("mch_id", WxPayUtils.WX_PAY_PARTNER);
  m.put("out_trade_no", no);
  m.put("nonce_str", WXPayUtil.generateNonceStr());

  //2 發(fā)送httpclient
  HttpClient client = new HttpClient("https://api.mch.weixin.qq.com/pay/orderquery");
  client.setXmlParam(WXPayUtil.generateSignedXml(m, WxPayUtils.WX_PAY_PARTNER_KEY));
  client.setHttps(true);
  client.post();

  //3.得到訂單數(shù)據(jù)
  String xml = client.getContent();
  Map<String, String> resultMap = WXPayUtil.xmlToMap(xml);

  //4.判斷是否支付成功
  if(resultMap.get("trade_state").equals("SUCCESS")) {
   /*
     改變數(shù)據(jù)庫(kù)中的數(shù)據(jù)等操作
    */
   return "支付成功";
  }
  return "支付中";
 }

 @GetMapping("success")
 public String success(){
  return "success";
 }
 @RequestMapping("test")
 public String test(){
  return "pay";
 }
 /**
  * 生成訂單號(hào)
  * @return
  */
 public static String getOrderNo() {
  SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
  String newDate = sdf.format(new Date());
  String result = "";
  Random random = new Random();
  for (int i = 0; i < 3; i++) {
   result += random.nextInt(10);
  }
  return newDate + result;
 }
 /**
  * 元轉(zhuǎn)換成分
  * @param amount
  * @return
  */
 public static String getMoney(String amount) {
  if(amount==null){
   return "";
  }
  // 金額轉(zhuǎn)化為分為單位
  // 處理包含, ¥ 或者$的金額
  String currency = amount.replaceAll("\\$|\\¥|\\,", "");
  int index = currency.indexOf(".");
  int length = currency.length();
  Long amLong = 0l;
  if(index == -1){
   amLong = Long.valueOf(currency+"00");
  }else if(length - index >= 3){
   amLong = Long.valueOf((currency.substring(0, index+3)).replace(".", ""));
  }else if(length - index == 2){
   amLong = Long.valueOf((currency.substring(0, index+2)).replace(".", "")+0);
  }else{
   amLong = Long.valueOf((currency.substring(0, index+1)).replace(".", "")+"00");
  }
  return amLong.toString();
 }
}

在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

值得一提的是 這里我們用的是controller而不是restcontroller,因?yàn)槲覀冃枰故径S碼

4. 在templates文件中新建 訂單支付頁(yè)面(二維碼生成的頁(yè)面)

注意:文件名必須和生成二維碼方法中返回的字符串名稱(chēng)一樣 我這里叫 pay

先新建html頁(yè)面,然后再將后綴改成ftl(freemarker模板引擎的后綴名)

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>Title</title>
 <script src="/static/qrcode.js"></script>
 <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
</head>
<center>
 <div id="qrcode"></div>
</center>
<script type="text/javascript">
 new QRCode(document.getElementById("qrcode"), "${map.code_url}"); // 設(shè)置要生成二維碼的鏈接
</script>
<script type="text/javascript">
 var int=self.setInterval("querystatus()",3000);
 function querystatus() {
  $.get("/wxpay/queryorder/${map.no}",function(data,status){
   if (data==="支付中"){
    console.log("支付中");
   } else {
    clearInterval(int)
    window.location.href="/wxpay/success" rel="external nofollow" 
   }
  })
 }
</script>
</body>
</html>

在這里插入圖片描述

再創(chuàng)建支付成功跳轉(zhuǎn)的頁(yè)面 文件名要與支付成功方法返回的文件名一樣

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>Title</title>
</head>
<body>
<h1>支付成功</h1>
</body>
</html>

在這里插入圖片描述

引入 qrcode 生成二維碼的依賴(lài),放入static文件中
這里我提供下載鏈接
鏈接: https://pan.baidu.com/s/15-E3KpRCenAewh0ZaBLnjQ 提取碼: xhs9 復(fù)制這段內(nèi)容后打開(kāi)百度網(wǎng)盤(pán)手機(jī)App,操作更方便哦

引入完成后

在這里插入圖片描述

最后 我們啟動(dòng)項(xiàng)目來(lái)測(cè)試一下

瀏覽器輸入地址
http://localhost:8081/wxpay/pay
發(fā)現(xiàn)二維碼生成成功,并且定時(shí)器也沒(méi)問(wèn)題

在這里插入圖片描述

之后我們掃碼支付
成功跳轉(zhuǎn)到支付成功頁(yè)面 ~nice

在這里插入圖片描述

四. 總結(jié)

  • 首先就是生成二維碼,需要的幾個(gè)主要的參數(shù),訂單號(hào),金額,購(gòu)買(mǎi)的信息(主體信息),其余的參數(shù)除了一些可以不寫(xiě)的都是固定的
  • 生成二維碼然后展示在頁(yè)面上,用的qrcode插件,生成
  • 然后設(shè)置定時(shí)器,來(lái)實(shí)時(shí)查詢(xún)訂單是否支付
  • 查詢(xún)訂單信息的寫(xiě)法和生成二維碼的方式差不多 無(wú)非就是請(qǐng)求時(shí)少了幾個(gè)參數(shù),必須得帶上訂單號(hào)
  • 微信提供的查詢(xún)訂單接口返回?cái)?shù)據(jù)中 trade_state 代表支付狀態(tài) notpay沒(méi)有支付,seccess表示已成功
  • 定時(shí)器檢測(cè)到訂單支付成功就清除定時(shí)器,并且執(zhí)行支付成功之后的操作

實(shí)際項(xiàng)目中遠(yuǎn)沒(méi)有這么簡(jiǎn)單,并且所有的數(shù)據(jù)都要從數(shù)據(jù)庫(kù)中獲取,在這里我為了方便把價(jià)格固定寫(xiě)死的

到此這篇關(guān)于Java調(diào)用微信支付功能的方法示例代碼的文章就介紹到這了,更多相關(guān)Java調(diào)用微信支付內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論