Java微信掃碼支付模式二Demo ,整合官網直接運行版本

下載

代碼下載鏈接: 點擊下載

概述

技術:spirngboot+微信掃碼支付模式二+google生成二維碼+html+jquery+mevan
運行環境:eclipse/idea+java jdk 1.8+
場景介紹:掃碼支付模式二,用於web網站。用戶點擊支付後,根據商品生成的二維碼,用戶掃碼完成支付,手機提示支付成功,微信支付系統把交易結果發送到回調接口中。

詳細

一、相關配置

微信公衆號AppID(登錄微信公衆平臺–>開發–>基本設置–>開發者ID(AppID))

微信公衆號AppSecret(登錄微信公衆平臺–>開發–>基本設置–>開發者密碼(AppSecret))

微信支付商戶號(登錄微信商戶平臺–>賬戶中心–>商戶信息–>基本賬戶信息–>微信支付商戶號)

微信支付商戶API**(登錄微信商戶平臺–>賬戶中心–>API安全–>API**–>設置API**)

application.properties 文件 (Demo上都有官網的默認值,不需要修改直接使用,省心!)
在這裏插入圖片描述

支付掃碼模式二,流程圖
https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_5

SDK與DEMO下載
https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=11_1

二、目錄結構

在這裏插入圖片描述

三、準備工作

(1)內網穿透工具

讓外網能直接訪問,你本地的服務,場景用於,接口調試,支付方面等等。

爲了大家找了一個,免費配置簡單的。絕對不是賣廣告,之前用過花生殼,麻煩到要死坑哇~,現在的所有穿透都要身份證登記,很正常國家出了對應的法規。

下載地址:https://natapp.cn/#download

配置和使用說明:http://www.noobyard.com/article/p-ckiarvwt-sq.html

四、功能講解

(1)訪問首頁

打開WxPayController.java

/* 二維碼首頁*/
@RequestMapping(value = {"/"}, method = RequestMethod.GET)
public String wxPayList(Model model){
//商戶訂單號
model.addAttribute(「outTradeNo」,WxUtil.mchOrderNo());
return 「/wxPayList」;
}

我們和穿透工具連在一起使用
SpringBoot 默認端口號爲:8080,穿透工具映射端口設置爲:8080
雙擊,natapp.exe 執行
在這裏插入圖片描述

127.0.0:8080 <=> http://9xnrh8.natappfree.cc
在這裏插入圖片描述
在這裏插入圖片描述
修改,application.properties
劃重點,添加內網穿透鏈接記得重啓服務
在這裏插入圖片描述

(2)生成二維碼

從頁面看到,有訂單流水號和支付金額,0.01 代表一分錢。支付金額可以修改的,點擊’生成二維碼’按鈕,然後把訂單流水號和支付金額傳到後臺。
控制類:

final private String signType = WxConstants.SING_MD5;
/* 統一下單-生成二維碼*/
@RequestMapping(value = {"/wxPay/payUrl"})
public void payUrl(HttpServletRequest request, HttpServletResponse response,
@RequestParam(value = 「totalFee」)Double totalFee,
@RequestParam(value = 「outTradeNo」)String outTradeNo) throws Exception{
WxUtil.writerPayImage(response,wxMenuService.wxPayUrl(totalFee,outTradeNo,signType));
}

實現類:

@Override
public String wxPayUrl(Double totalFee,String outTradeNo,String signType) throws Exception {
HashMap<String, String> data = new HashMap<String, String>();
//公衆賬號ID
data.put(「appid」, WxConfig.appID);
//商戶號
data.put(「mch_id」, WxConfig.mchID);
//隨機字符串
data.put(「nonce_str」, WxUtil.getNonceStr());
//商品描述
data.put(「body」,「測試支付」);
//商戶訂單號
data.put(「out_trade_no」,outTradeNo);
//標價幣種
data.put(「fee_type」,「CNY」);
//標價金額
data.put(「total_fee」,String.valueOf(Math.round(totalFee * 100)));
//用戶的IP
data.put(「spbill_create_ip」,「123.12.12.123」);
//通知地址
data.put(「notify_url」,WxConfig.unifiedorderNotifyUrl);
//交易類型
data.put(「trade_type」,「NATIVE」);
//簽名類型
data.put(「sign_type」,signType);
//簽名
data.put(「sign」,WxUtil.getSignature(data, WxConfig.key,signType));
String requestXML = WxUtil.mapToXml(data);
String reponseString = HttpsClient.httpsRequestReturnString(WxConstants.PAY_UNIFIEDORDER,HttpsClient.METHOD_POST,requestXML);
Map<String,String> resultMap = WxUtil.processResponseXml(reponseString,signType);
if(resultMap.get(WxConstants.RETURN_CODE).equals(「SUCCESS」)){
return resultMap.get(「code_url」);
}
return null;
}

最終返回一個,二維碼鏈接 → 轉成二維碼圖片

/** 生成支付二維碼 @param response 響應 @param contents url鏈接 @throws Exception*/
public static void writerPayImage(HttpServletResponse response, String contents) throws Exception{
ServletOutputStream out = response.getOutputStream();
try {
Map<EncodeHintType,Object> hints = new HashMap<EncodeHintType,Object>();
hints.put(EncodeHintType.CHARACTER_SET,「UTF-8」);
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
hints.put(EncodeHintType.MARGIN, 0);
BitMatrix bitMatrix = new MultiFormatWriter().encode(contents, BarcodeFormat.QR_CODE,300,300,hints);
MatrixToImageWriter.writeToStream(bitMatrix,「jpg」,out);
}catch (Exception e){
throw new Exception(「生成二維碼失敗!」);
}finally {
if(out != null){
out.flush();
out.close();
}
}
}

在這裏插入圖片描述

啓動一個定時器,每個2秒去掃描是否已經支付~

(3)支付

在這裏插入圖片描述

在這裏插入圖片描述

(4)支付完畢

在這裏插入圖片描述

(5)回調接口

收到微信支付結果通知後,請嚴格按照示例返回參數給微信支付

/統一下單-通知鏈接/
@RequestMapping(value = {"/wxPay/unifiedorderNotify"})
public void unifiedorderNotify(HttpServletRequest request, HttpServletResponse response) throws Exception{
//商戶訂單號
String outTradeNo = null;
String xmlContent = 「」 +
「<return_code><![CDATA[FAIL]]></return_code>」 +
「<return_msg><![CDATA[簽名失敗]]></return_msg>」 +
「」;
try{
String requstXml = WxUtil.getStreamString(request.getInputStream());
System.out.println("requstXml : " + requstXml);
Map<String,String> map = WxUtil.xmlToMap(requstXml);
String returnCode= map.get(WxConstants.RETURN_CODE);
//校驗一下
if(StringUtils.isNotBlank(returnCode) && StringUtils.equals(returnCode,「SUCCESS」) && WxUtil.isSignatureValid(map, WxConfig.key,signType)){
//商戶訂單號
outTradeNo = map.get(「out_trade_no」);
System.out.println("outTradeNo : "+ outTradeNo);
//微信支付訂單號
String transactionId = map.get(「transaction_id」);
System.out.println("transactionId : "+ transactionId);
//支付完成時間
SimpleDateFormat payFormat= new SimpleDateFormat(「yyyyMMddHHmmss」);
Date payDate = payFormat.parse(map.get(「time_end」));
SimpleDateFormat systemFormat= new SimpleDateFormat(「yyyy-MM-dd HH:mm:ss」);
System.out.println(「支付時間:」 + systemFormat.format(payDate));
//臨時緩存
WxConfig.setPayMap(outTradeNo,「SUCCESS」);
xmlContent = 「」 +
「<return_code><![CDATA[SUCCESS]]></return_code>」 +
「<return_msg><![CDATA[OK]]></return_msg>」 +
「」;
}
}catch (Exception e){
e.printStackTrace();
}
WxUtil.responsePrint(response,xmlContent);
}

在這裏插入圖片描述

更多的信息,請看官網
官網相關鏈接:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=9_7&index=8

(6)微信支付,關於XML解析存在的安全問題指引

代碼已修改
在這裏插入圖片描述

更多的信息,請看官網
官網相關鏈接:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=23_5

因爲相關配置,我是從官網下載的,所以支付後還有退款功能(退款要等很多天,請耐心等待),是不是很神奇~
在這裏插入圖片描述

代碼下載鏈接: 點擊下載

還有微信登錄,自定義微信公衆號菜單創建-修改-刪除功能(前臺-數據庫保存),微信公衆號接受、回覆信息Demo

但是,沒有官網例子直接運行的,很多地方不能截圖,後面我想想怎麼做吧~

謝謝大家觀看~