国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服務器之家 - 編程語言 - JAVA教程 - Java SpringMVC實現PC端網頁微信掃碼支付(完整版)

Java SpringMVC實現PC端網頁微信掃碼支付(完整版)

2020-06-29 11:20java教程網 JAVA教程

這篇文章主要介紹了Java SpringMVC實現PC端網頁微信掃碼支付(完整版)的相關資料,非常不錯具有一定的參考借鑒價值,需要的朋友可以參考下

一:前期微信支付掃盲知識

前提條件是已經有申請了微信支付功能的公眾號,然后我們需要得到公眾號APPID和微信商戶號,這個分別在微信公眾號和微信支付商家平臺上面可以發現。其實在你申請成功支付功能之后,微信會通過郵件把Mail轉給你的,有了這些信息之后,我們就可以去微信支付服務支持頁面:https://pay.weixin.qq.com/service_provider/index.shtml

打開這個頁面,點擊右上方的鏈接【開發文檔】會進入到API文檔說明頁面,看起來如下

Java SpringMVC實現PC端網頁微信掃碼支付(完整版)

選擇紅色圓圈的掃碼支付就是我們要做接入方式,鼠標移動到上面會提示你去查看開發文檔,如果這個都不知道怎么查看,可以洗洗睡了,你真的不合適做程序員,地址如下:

https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_1 在瀏覽器中打開之后會看到

Java SpringMVC實現PC端網頁微信掃碼支付(完整版)

我們重點要關注和閱讀的內容我已經用紅色橢圓標注好了,首先閱讀【接口規則】里面的協議規范,開玩笑這個都不讀你就想做微信支付,這個就好比你要去泡妞,得先收集點基本背景信息,了解對方特點,不然下面還怎么溝通。事實證明只有會泡妞得程序員才是好銷售。跑題了我們接下來要看一下【場景介紹】中的案例與規范,只看一下記得一定要微信支付的LOGO下載下來,是為了最后放到我們自己的掃碼支付網頁上,這樣看上去比較專業一點。之后重點關注【模式二】

我們這里就是要采用模式二的方式實現PC端頁面掃碼支付功能。

微信官方對模式二的解釋是這樣的“商戶后臺系統先調用微信支付的統一下單接口,微信后臺系統返回鏈接參數code_url,商戶后臺系統將code_url值生成二維碼圖片,用戶使用微信客戶端掃碼后發起支付。注意:code_url有效期為2小時,過期后掃碼不能再發起支付”。看明白了吧就是我們首先要調用微信提供統一下單接口,得到一個關鍵信息code_url(至于這個code_url是什么鬼,我也不知道),然后我們通過自己的程序把這個URL生成一個二維碼,生成二維碼我這里用了Google的zxing庫。然后把這個二維碼顯示在你的PC端網頁上就行啦。這樣終端用戶一掃碼就支付啦,支付就完成啦,看到這里你肯定很激動,發現微信支付如此簡單,等等還有個事情我們還不知道,客戶知道付錢了,我們服務器端還不知道呢,以微信開發人員的智商他們早就想到這個問題了,所以讓你在調用統一下單接口的時候其中有個必填的參數就是回調URL,就是如果客戶端付款成功之后微信會通過這個URL向我們自己的服務器提交一些數據,然后我們后臺解析這些數據,完成我們自己操作。這樣我們才知道客戶是否真的已經通過微信付款了。這樣整個流程才結束,這個就是模式二。微信用一個時序圖示這樣表示這個過程的。

Java SpringMVC實現PC端網頁微信掃碼支付(完整版)

表達起來比較復雜,看上去比較吃力,總結一下其實我們服務器該做的事情就如下件:

1. 通過統一下單接口傳入正確的參數(當然要包括我們的回調URL)與簽名驗證,從返回數據中得到code_url的對應數據

2. 根據code_url的數據我們自己生成一個二維碼圖片,顯示在瀏覽器網頁上

3. 在回調的URL中添加我們自己業務邏輯處理。

至此掃盲結束了,你終于知道掃碼支付什么個什么樣的流程了,下面我們就一起來扒扒它的相關API使用,做好每步處理。

二:開發過程

在開發代碼之前,請先準備幾件事情。

1. 添加ZXing的maven依賴

2. 添加jdom的maven依賴

3.下載Java版本SDK演示程序,地址在這里

https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=11_1

我們需要MD5Util.java和XMLUtil.java兩個文件

4. 我們使用HttpClient版本是4.5.1,記得添加Maven依賴

上面準備工作做好以后,繼續往下看:

首先我們要調用微信的統一下單接口,我們點擊【API列表】中的統一下單會看到這樣頁面:

Java SpringMVC實現PC端網頁微信掃碼支付(完整版)

以本人調用實際情況為例,如下的參數是必須要有的,為了大家的方便我已經把它變成一個POJO的對象, 代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
public class UnifiedorderDto implements WeiXinConstants {
private String appid;
private String body;
private String device_info;
private String mch_id;
private String nonce_str;
private String notify_url;
private String openId;
private String out_trade_no;
private String spbill_create_ip;
private int total_fee;
private String trade_type;
private String product_id;
private String sign;
public UnifiedorderDto() {
this.appid = APPID;
this.mch_id = WXPAYMENTACCOUNT;
this.device_info = DEVICE_INFO_WEB;
this.notify_url = CALLBACK_URL;
this.trade_type = TRADE_TYPE_NATIVE;
}
public String getAppid() {
return appid;
}
public void setAppid(String appid) {
this.appid = appid;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
public String getDevice_info() {
return device_info;
}
public void setDevice_info(String device_info) {
this.device_info = device_info;
}
public String getMch_id() {
return mch_id;
}
public void setMch_id(String mch_id) {
this.mch_id = mch_id;
}
public String getNonce_str() {
return nonce_str;
}
public void setNonce_str(String nonce_str) {
this.nonce_str = nonce_str;
}
public String getNotify_url() {
return notify_url;
}
public void setNotify_url(String notify_url) {
this.notify_url = notify_url;
}
public String getOpenId() {
return openId;
}
public void setOpenId(String openId) {
this.openId = openId;
}
public String getOut_trade_no() {
return out_trade_no;
}
public void setOut_trade_no(String out_trade_no) {
this.out_trade_no = out_trade_no;
}
public String getSpbill_create_ip() {
return spbill_create_ip;
}
public void setSpbill_create_ip(String spbill_create_ip) {
this.spbill_create_ip = spbill_create_ip;
}
public int getTotal_fee() {
return total_fee;
}
public void setTotal_fee(int total_fee) {
this.total_fee = total_fee;
}
public String getTrade_type() {
return trade_type;
}
public void setTrade_type(String trade_type) {
this.trade_type = trade_type;
}
public String getSign() {
return sign;
}
public void setSign(String sign) {
this.sign = sign;
}
public String getProduct_id() {
return product_id;
}
public void setProduct_id(String product_id) {
this.product_id = product_id;
}
public String generateXMLContent() {
String xml = "<xml>" +
"" + this.appid + "</appid>" +
"" + this.body + "" +
"<device_info>WEB</device_info>" +
"<mch_id>" + this.mch_id + "</mch_id>" +
"<nonce_str>" + this.nonce_str + "</nonce_str>" +
"<notify_url>" + this.notify_url + "</notify_url>" +
"<out_trade_no>" + this.out_trade_no + "</out_trade_no>" +
"<product_id>" + this.product_id + "</product_id>" +
"<spbill_create_ip>" + this.spbill_create_ip+ "</spbill_create_ip>" +
"<total_fee>" + String.valueOf(this.total_fee) + "</total_fee>" +
"<trade_type>" + this.trade_type + "</trade_type>" +
"<sign>" + this.sign + "</sign>" +
"</xml>";
return xml;
}
public String makeSign() {
String content ="appid=" + this.appid +
"&body=" + this.body +
"&device_info=WEB" +
"&mch_id=" + this.mch_id +
"&nonce_str=" + this.nonce_str +
"?ify_url=" + this.notify_url +
"&out_trade_no=" + this.out_trade_no +
"&product_id=" + this.product_id +
"&spbill_create_ip=" + this.spbill_create_ip+
"&total_fee=" + String.valueOf(this.total_fee) +
"&trade_type=" + this.trade_type;
content = content + "&key=" + WeiXinConstants.MD5_API_KEY;
String esignature = WeiXinPaymentUtil.MD5Encode(content, "utf-8");
return esignature.toUpperCase();
}
}

其中各個成員變量的解釋可以參見【統一下單接口】的說明即可。

有這個之后我們就要要設置的內容填寫進去,去調用該接口得到返回數據,從中拿到code_url的數據然后據此生成一個二維圖片,把圖片的地址返回給PC端網頁,然后它就會顯示出來,這里要特別說明一下,我們自己PC端網頁在點擊微信支付的時候就會通過ajax方式調用我們自己后臺的SpringMVC Controller然后在Controller的對應方法中通過HTTPClient完成對微信統一下單接口調用解析返回的XML數據得到code_url的值,生成二維碼之后返回給前臺網頁。Controller中實現的代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
Map<string,object> result=new HashMap<string,object>();
UnifiedorderDto dto = new UnifiedorderDto();
if(cash == null || "".equals(cash)) {
result.put("error", "cash could not be zero");
return result;
}
int totalfee = 100*Integer.parseInt(cash);
logger.info("total recharge cash : " + totalfee);
dto.setProduct_id(String.valueOf(System.currentTimeMillis()));
dto.setBody("repair");
dto.setNonce_str(String.valueOf(System.nanoTime()));
LoginInfo loginInfo = LoginInfoUtil.getLoginInfo();
// 通過我們后臺訂單號+UUID為身份識別標志
dto.setOut_trade_no("你的訂單號+關鍵信息,微信回調之后傳回,你可以驗證");
dto.setTotal_fee(totalfee);
dto.setSpbill_create_ip("127.0.0.1");
// generate signature
dto.setSign(dto.makeSign());
logger.info("sign : " + dto.makeSign());
logger.info("xml content : " + dto.generateXMLContent());
try {
HttpClient httpClient = HttpClientBuilder.create().build();
HttpPost post = new HttpPost(WeiXinConstants.UNIFIEDORDER_URL);
post.addHeader("Content-Type", "text/xml; charset=UTF-8");
StringEntity xmlEntity = new StringEntity(dto.generateXMLContent(), ContentType.TEXT_XML);
post.setEntity(xmlEntity);
HttpResponse httpResponse = httpClient.execute(post);
String responseXML = EntityUtils.toString(httpResponse.getEntity(), "UTF-8");
logger.info("response xml content : " + responseXML);
// parse CODE_URL CONTENT
Map<string, string=""> resultMap = (Map<string, string="">)XMLUtil.doXMLParse(responseXML);
logger.info("response code_url : " + resultMap.get("code_url"));
String codeurl = resultMap.get("code_url");
if(codeurl != null && !"".equals(codeurl)) {
String imageurl = generateQrcode(codeurl);
result.put("QRIMAGE", imageurl);
}
post.releaseConnection();
} catch(Exception e) {
e.printStackTrace();
}
result.put("success", "1");
return result;</string,></string,></string,object></string,object>

生成二維碼的代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
private String generateQrcode(String codeurl) {
File foldler = new File(basePath + "qrcode");
if(!foldler.exists()) {
foldler.mkdirs();
}
String f_name = UUIDUtil.uuid() + ".png";
try {
File f = new File(basePath + "qrcode", f_name);
FileOutputStream fio = new FileOutputStream(f);
MultiFormatWriter multiFormatWriter = new MultiFormatWriter();
Map hints = new HashMap();
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8"); //設置字符集編碼類型
BitMatrix bitMatrix = null;
bitMatrix = multiFormatWriter.encode(codeurl, BarcodeFormat.QR_CODE, 300, 300,hints);
BufferedImage image = toBufferedImage(bitMatrix);
//輸出二維碼圖片流
ImageIO.write(image, "png", fio);
return ("qrcode/" + f_name);
} catch (Exception e1) {
e1.printStackTrace();
return null;
}
}

此時如何客戶端微信掃碼之后,微信就會通過回調我們制定URL返回數據給我們。在回調方法中完成我們自己的處理,這里要特別注意的是你的回調接口必須通過HTTP POST方法實現,否則無法接受到XML數據。回調處理的代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
@RequestMapping(value = "/your_callback_url", method = RequestMethod.POST)
@ResponseBody
public void finishPayment(HttpServletRequest request, HttpServletResponse response) {
try { logger.info("start to callback from weixin server: " + request.getRemoteHost());
Map<string, string=""> resultMap = new HashMap<string, string="">();
InputStream inputStream = request.getInputStream();
// 讀取輸入流
SAXBuilder saxBuilder= new SAXBuilder();
Document document = saxBuilder.build(inputStream);
// 得到xml根元素
Element root = document.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);
}
resultMap.put(k, v);
}
// 驗證簽名!!!
/*
String[] keys = resultMap.keySet().toArray(new String[0]);
Arrays.sort(keys);
String kvparams = "";
for(int i=0; i<keys.length; i++)="" {="" if(keys[i].equals("esign"))="" continue;="" }="" 簽名算法="" if(i="=" 0)="" kvparams="" +="(keys[i]" "=" + resultMap.get(keys[i]));
} else {
kvparams += (" &"="" keys[i]="" &key=" + WeiXinConstants.MD5_API_KEY;
String md5esign = WeiXinPaymentUtil.MD5Encode(esign, " utf-8");="" if(!md5esign.equals(resultmap.get("sign")))="" return;="" }*="" 關閉流="" 釋放資源="" inputstream.close();="" inputstream="null;" string="" returncode="resultMap.get("return_code");" outtradeno="resultMap.get("out_trade_no");" 以分為單位="" int="" nfee="Integer.parseInt(resultMap.get("total_fee"));" logger.info("out="" trade="" no="" :="" outtradeno);="" logger.info("total_fee="" nfee);="" 業務處理流程="" if("success".equals(returncode))="" todo:="" your="" business="" process="" add="" here="" response.getwriter().print(xmlutil.getretresultxml(resultmap.get("return_code"),="" resultmap.get("return_code")));="" else="" resultmap.get("return_msg")));="" catch(ioexception="" ioe)="" ioe.printstacktrace();="" catch="" (jdomexception="" e1)="" e1.printstacktrace();="" }

微信官方java版demo用到的xmlutil和md5util的兩個類記得拿過來改一下,演示代碼可以在它的官方演示頁面找到,相關maven依賴如下:

?
1
2
3
4
5
6
7
8
9
10
<dependency>
<groupid>jdom</groupid>
jdom</artifactid>
<version>1.1</version>
</dependency>
<dependency>
<groupid>com.google.zxing</groupid>
core</artifactid>
<version>3.3.0</version>
</dependency>

最后要特別注意的是關于簽名,簽名生成MD5的類我是從微信官網直接下載Java版Demo程序獲取的,建議你也是,因為這個是確保MD5簽名是一致的最佳選擇。具體的生成簽名的算法可以查看微信官方文檔,這里也強烈建議大家一定要官方API說明,你開發中所遇到各種問題90%都是因為不看官方文檔,而是輕信某人博客!這個才是我寫這篇文章的真正目的和用意,根據官方文檔,用我的Java代碼實現,微信PC端網頁掃碼支付必定在你的WEB應用中飛起來。

以上所述是小編給大家介紹的Java SpringMVC實現PC端網頁微信掃碼支付(完整版),希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對服務器之家網站的支持!

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 亚洲精品视频免费在线观看 | 日本1区2区 | 97超碰在线播放 | 中文字幕精品视频 | 中文字幕三区 | 亚洲成人一区二区三区四区 | 国产成人一区二区在线观看 | 亚洲大奶网 | 欧美日韩成人在线播放 | 色av综合| 成人国产在线 | 在线视频自拍 | 不卡视频一区 | 欧美日韩第一页 | 美女视频一区二区三区 | 亚洲国产精品成人 | 日本精品在线 | 久久久久99 | 特黄视频免费观看 | 成人欧美一区二区三区视频xxx | 国产成人jvid在线播放 | 成人刺激视频在线 | 青青草草 | 久热99 | 国产乱叫456 | av天天干| 91精品视频在线 | 中文字幕第18页 | 日韩欧美国产精品综合嫩v 在线视频 中文字幕 | 在线免费av观看 | 久久久久久久av | 亚洲三级免费观看 | 亚洲欧美在线一区 | 国产成人精品一区二区三区网站观看 | 亚洲精品免费在线视频 | 久久久免费少妇高潮毛片 | 99福利视频 | 久久午夜剧场 | 在线日韩一区 | 国产精品久久久久久久久久ktv | 午夜成人免费电影 |