這個星期寫了下微信支付模式二,在這里進行下整理
微信支付官方檔案
1. 需要的配置..具體看下面的鏈接.
https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=3_1
2. 熟悉微信的支付流程(模式二)
https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_5
3.將下面的配置填好,我是寫在yml里面.第一個沒用到,說是公眾號那里用到了,可以不用
.
4.下載微信里面的sdk,然后全部放入專案里面

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

下面就是具體的代碼...微信支付模式二是先將金額訂單號等一些引數放入二維碼中,這個二維碼只有2個小時,然后顧客掃碼支付
需要的jar包
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.3.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.jdom/jdom -->
<dependency>
<groupId>org.jdom</groupId>
<artifactId>jdom</artifactId>
<version>1.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/xml-apis/xml-apis -->
<dependency>
<groupId>xml-apis</groupId>
<artifactId>xml-apis</artifactId>
<version>1.4.01</version>
</dependency>
5.先是寫二維碼的
util ---2個
/**
* @ClassName: QRCodeUtil
* @Description: 二維碼工具類
*/
public class QRCodeUtil {
/**
* 生成base64二維碼
*
* @param content
* @return
* @throws Exception
*/
public static String createQrCode(String content) throws Exception {
try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
hints.put(EncodeHintType.MARGIN, 1);
BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, 400, 400, hints);
int width = bitMatrix.getWidth();
int height = bitMatrix.getHeight();
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
image.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);
}
}
ImageIO.write(image, "JPG", out);
return Base64.encodeBase64String(out.toByteArray());
}
}
}
public class CommonUtil {
public static String httpsRequest(String requestUrl, String requestMethod, String outputStr) {
try {
URL url = new URL(requestUrl);
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setUseCaches(false);
// 設定請求方式(GET/POST)
conn.setRequestMethod(requestMethod);
conn.setRequestProperty("content-type", "application/x-www-form-urlencoded");
// 當outputStr不為null時向輸出流寫資料
if (null != outputStr) {
OutputStream outputStream = conn.getOutputStream();
// 注意編碼格式
outputStream.write(outputStr.getBytes("UTF-8"));
outputStream.close();
}
// 從輸入流讀取回傳內容
InputStream inputStream = conn.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String str = null;
StringBuffer buffer = new StringBuffer();
while ((str = bufferedReader.readLine()) != null) {
buffer.append(str);
}
// 釋放資源
bufferedReader.close();
inputStreamReader.close();
inputStream.close();
inputStream = null;
conn.disconnect();
return buffer.toString();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
controller ----這里可以直接傳引數,訂單號,型別

serviceImpl
@Override
public ApiResult toPay(String orderUserId, String payType) {
OrderUserInfoDto orderUserInfoDto = orderUserInfoService.getByPk(orderUserId);
if (Checker.BeNull(orderUserInfoDto)) {
return ApiResult.result(ApiResult.defaultErrorCode, "未知的訂單號");
}
if (!"0".equals(orderUserInfoDto.getPayStatus())) {
return ApiResult.result(ApiResult.defaultErrorCode, "未知的支付狀態");
}
if(!"3".equals(orderUserInfoDto.getStatus())){
return ApiResult.result(ApiResult.defaultErrorCode,"未知的訂單狀態");
}
// 1為微信支付
if ("1".equals(payType)) {
SortedMap<String, String> parameters = new TreeMap<String, String>();
// 公眾賬號ID-------appId
parameters.put("appid", weChatConfig.getWxAppId());
// 商戶號---------mch_id
parameters.put("mch_id", weChatConfig.getWxMchId());
// 隨機字串------nonce_str
parameters.put("nonce_str", WXPayUtil.generateNonceStr());
// 商品描述-------body
parameters.put("body", weChatConfig.getBody());
// 商戶訂單號------out_trade_no
parameters.put("out_trade_no", orderUserId);
// 標價幣種-------fee_type(默認為人民幣)
parameters.put("fee_type", "CNY");
// 標價金額-------total_fee(默認為分)
BigDecimal transValue = https://www.cnblogs.com/xd1105/p/new BigDecimal("100");
// 計算微信的總金額乘以100
BigDecimal bTotalPrice = orderUserInfoDto.getTotalPrice().multiply(transValue);
int totalFee = bTotalPrice.intValue();
parameters.put("total_fee", String.valueOf(totalFee));
// 通知地址-------notify_url(回呼地址)
parameters.put("notify_url", weChatConfig.getNotifyUrl());
// 交易型別-----trade_type
parameters.put("trade_type", "NATIVE");
// 簽名-----------sign
String generateSignature = null;
try {
generateSignature = WXPayUtil.generateSignature(parameters, weChatConfig.getWxApiKey(),
WXPayConstants.SignType.MD5);
} catch (Exception e) {
e.printStackTrace();
}
parameters.put("sign", generateSignature);
String generateSignedXml = null;
try {
generateSignedXml = WXPayUtil.generateSignedXml(parameters, weChatConfig.getWxApiKey());
} catch (Exception e) {
e.printStackTrace();
}
log.info("二維碼資訊------" + generateSignedXml);
String result = CommonUtil.httpsRequest(weChatConfig.getWxPayUnifiedorderUrl(), "POST", generateSignedXml);
Map<String, String> map;
try {
map = WXPayUtil.xmlToMap(result);
String returnCode = map.get("return_code");
String resultCode = map.get("result_code");
if (returnCode.equalsIgnoreCase("SUCCESS") && resultCode.equalsIgnoreCase("SUCCESS")) {
String content = map.get("code_url");
String imgs = QRCodeUtil.createQrCode(content);
return ApiResult.result("data:image/jpeg;base64," + imgs);
} else {
return ApiResult.result(ApiResult.defaultErrorCode, "微信簽名錯誤");
}
} catch (Exception e) {
e.printStackTrace();
}
}
return ApiResult.result(ApiResult.defaultErrorCode, "未知錯誤");
}
6,支付回呼-----就是二維碼的那個回呼地址,如果是本地測驗的話,可能下載個花生殼將本地的地址映射出去
controller

serviceImpl --->這里主要注意就是第一次回呼成功的話,要把正確的資訊回傳給微信,不然微信會在那幾個時間一直回呼,這個回呼就會一直改狀態
public String weChatNotify(HttpServletRequest request, HttpServletResponse response) {
// 讀取引數
InputStream inputStream;
StringBuffer sb = new StringBuffer();
inputStream = request.getInputStream();
String s;
BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
while ((s = in.readLine()) != null) {
sb.append(s);
}
in.close();
inputStream.close();
// 決議xml成map
Map<String, String> map = WXPayUtil.xmlToMap(sb.toString());
log.info("支付回呼---" + map.toString());
String res = "OK";
String resXml = "<xml>" + "<return_code><![CDATA["+map.get("return_code").toString()+"]]></return_code>"
+ "<return_msg><![CDATA["+res+"]]></return_msg>" + "</xml>";
// 判斷簽名是否正確
if (WXPayUtil.isSignatureValid(map, weChatConfig.getWxApiKey())) {
if ("SUCCESS".equals(map.get("return_code").toString())) {
// 用戶訂單號
String orderUserId = (String) map.get("out_trade_no");
// 微信支付訂單號
String payOrderId = (String) map.get("transaction_id");
// 支付時間
String endTime = (String) map.get("time_end");
// 支付金額
BigDecimal total_fee = new BigDecimal(map.get("total_fee").toString());
/**
* 1,判斷是否有這個訂單號 2,判斷支付金額與用于訂單表的金額是否一致 3,修改支付狀態,并修改商戶的狀態,
*/
log.info("用戶訂單id--------"+orderUserId);
OrderUserInfoDto orderUserInfoDto = orderUserInfoService.getByPk(orderUserId);
if (Checker.BeNull(orderUserInfoDto)) {
return "未知的訂單號";
}
if (!"0".equals(orderUserInfoDto.getPayStatus())) {
return "未知的支付狀態";
}
if (!"3".equals(orderUserInfoDto.getStatus())) {
return "未知的訂單狀態";
}
if (total_fee.compareTo(orderUserInfoDto.getTotalPrice().multiply(new BigDecimal("100"))) != 0) {
return "支付金額與用戶訂單金額不一致";
}
// 用戶訂單表的修改
OrderUserInfoDto orderUserInfoDto1 = new OrderUserInfoDto();
orderUserInfoDto1.setId(orderUserId);
orderUserInfoDto1.setStatus("4");
orderUserInfoDto1.setPayStatus("1");
orderUserInfoDto1.setPayType("1");
orderUserInfoDto1.setPaySerial(payOrderId);
log.info("----------------時間---"+endTime);
orderUserInfoDto1.setPayTime(dateTime(endTime));
orderUserInfoService.updateByPk(orderUserInfoDto1);
// 商戶訂單表的修改
List<OrderMerchantInfoDto> orderMerchantInfoDtoList = orderMerchantInfoService
.listByField("order_user_info_id", orderUserId);
for (OrderMerchantInfoDto merchantInfoDto : orderMerchantInfoDtoList) {
if ("3".equals(merchantInfoDto.getStatus())) {
String id = merchantInfoDto.getId();
OrderMerchantInfoDto orderMerchantInfoDto = new OrderMerchantInfoDto();
orderMerchantInfoDto.setId(id);
orderMerchantInfoDto.setStatus("4");
orderMerchantInfoDto.setPayStatus("1");
orderMerchantInfoDto.setPayTime(dateTime(endTime));
orderMerchantInfoService.updateByPk(orderMerchantInfoDto);
}
}
log.info(resXml);
return resXml;
} else {
return "錯誤的簽名";
}
}
return "未知錯誤";
}
7,客戶支付成功了,但是狀態沒改,可以寫個定時任務,查詢當天未支付的訂單是否支付,我這里只寫了通過訂單號和型別查詢單個的是否支付
controller

serviceImpl
@Override
public ApiResult weChatNotifyDto(String orderUserId, String payType) {
/**
* 1,資料庫進行查詢,如果顯示已支付則直接回傳成功
* 2,未支付,呼叫微信介面
*/
OrderUserInfoDto orderUserInfoDto = orderUserInfoService.getByPk(orderUserId);
if("1".equals(orderUserInfoDto.getPayStatus())){
return ApiResult.result("支付已完成");
}
Map<String,String> data = https://www.cnblogs.com/xd1105/p/new HashMap<>();
data.put("appid", weChatConfig.getWxAppId());
data.put("mch_id", weChatConfig.getWxMchId());
data.put("nonce_str", WXPayUtil.generateNonceStr());
data.put("out_trade_no", orderUserId);
// 簽名-----------sign
String generateSignature = null;
try {
generateSignature = WXPayUtil.generateSignature(data, weChatConfig.getWxApiKey(),
WXPayConstants.SignType.MD5);
} catch (Exception e) {
e.printStackTrace();
}
data.put("sign", generateSignature);
Map<String, String> result = null;
try {
result = wxPay.orderQuery(data);
} catch (Exception e) {
e.printStackTrace();
}
// 如果用戶已支付
if("SUCCESS".equals(result.get("return_code")) && "SUCCESS".equals(result.get("trade_state"))){
//修改狀態
// 微信支付訂單號
String payOrderId = result.get("transaction_id");
// 支付時間
String endTime = result.get("time_end");
// 用戶訂單表的修改
OrderUserInfoDto orderUserInfoDto1 = new OrderUserInfoDto();
orderUserInfoDto1.setId(orderUserId);
orderUserInfoDto1.setStatus("4");
orderUserInfoDto1.setPayStatus("1");
orderUserInfoDto1.setPayType("1");
orderUserInfoDto1.setPaySerial(payOrderId);
orderUserInfoDto1.setPayTime(dateTime(endTime));
orderUserInfoService.updateByPk(orderUserInfoDto1);
// 商戶訂單表的修改
List<OrderMerchantInfoDto> orderMerchantInfoDtoList = orderMerchantInfoService
.listByField("order_user_info_id", orderUserId);
for (OrderMerchantInfoDto merchantInfoDto : orderMerchantInfoDtoList) {
if ("3".equals(merchantInfoDto.getStatus())) {
String id = merchantInfoDto.getId();
OrderMerchantInfoDto orderMerchantInfoDto = new OrderMerchantInfoDto();
orderMerchantInfoDto.setId(id);
orderMerchantInfoDto.setStatus("4");
orderMerchantInfoDto.setPayStatus("1");
orderMerchantInfoDto.setPayTime(dateTime(endTime));
orderMerchantInfoService.updateByPk(orderMerchantInfoDto);
}
}
return ApiResult.result("支付已完成");
}
return ApiResult.result(ApiResult.defaultErrorCode, "訂單未支付");
}
暫時先這樣,有時間再補充
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/213730.html
標籤:Java
