当前位置:网站首页>Wechat payment -jsapi: code implementation (payment asynchronous callback, Chinese parameter solution)
Wechat payment -jsapi: code implementation (payment asynchronous callback, Chinese parameter solution)
2022-07-03 15:24:00 【Don't wear perfume】
The conditions required for wechat payment have been configured , The next step is to implement ( The following is for reference only )
One , Preparation before implementation
①, Read official payment documents , Mainly business process https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_4
②, official demo download https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1
③,js Payment request method selection ( I chose chooseWXPay, Choose this according to your own situation )
1. Merchant platform : Web page through JavaScript call getBrandWCPayRequest Interface , Initiate wechat payment request
2. Public platform : call chooseWXPay Realization

3. Difference between them : choice getBrandWCPayRequest Words , The payment page does not need to introduce any js, choose chooseWXPay Words , Need to introduce JS file
Two , Code implementation

1. Front end page core code
①, introduce js
<script src="http://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>②,config Interface injection authority verification (requestUrl Is the routing address of the current page )
var reUrl =window.location.href; $.ajax({
url: "/wxPay/getWXConfig?requestUrl="+encodeURIComponent(reUrl),
dataType: "json",
async: false,
type: "GET",
success: function (data) {
wx.config({
debug: false, // Turn on debugging mode , Call all api The return value of will be on the client side alert come out , To see the parameters passed in , Can be in pc End open , The parameter information will go through log play , Only in pc Only when the end is printed .
appId: data.appId, // Required , The only sign of official account number
timestamp:data.timestamp, // Required , Generate signature timestamp
nonceStr: data.nonceStr, // Required , Generate a random string of signatures
signature: data.signature,// Required , Signature
jsApiList: ['chooseWXPay'] // Required , Required JS Interface list
});
}
});geWxConfig The implementation method of can refer to : Wechat sharing development : Code implementation [ front end + Back end ]( Two )
③, Payment calls the unified order interface ( Please define the back-end interface according to your business )
<button style="width:90%; margin-left:5%; margin-bottom:20px; height:40px;line-height:40px;background-color:#4395FF;color:white;border:none; font-size:11pt;font-weight:bold " onclick="SaveOrWxPay();"> Save and pay </button> function SaveOrWxPay() {
$.ajax({
url: "/wxPay/pay2?openId="+ GetPar("token")+"&totalFee="+$("#labTotalCost").text()+"&operationNO="+$("#labOperationNO").text()+"&userName="+$("#UserName").val()+"&userPhone="+$("#UserPhone").val(),
dataType: "json",
async: false,
type: "GET",
success: function (data) {
wx.chooseWXPay({
timestamp: data.timeStamp, // Payment signature time stamp , Pay attention to wechat jssdk All uses in timestamp Fields are all lowercase . But the latest version of the payment background generation signature uses timeStamp The field name should be capitalized S character
nonceStr: data.nonceStr, // Payment signature random string , Not longer than 32 position
package: data.package, // Returned by unified payment interface prepay_id Parameter values , The submission format is as follows :prepay_id=\*\*\*)
signType: data.signType, // Signature method , The default is 'SHA1', To use the new version of payment, you need to transfer in 'MD5'
paySign: data.paySign, // Payment signature
success: function (res) {
// Click here after successful payment [ complete ] After the callback , It can be processed according to its own business needs
},
});
}
});
}2. Back end core code

According to the unified order API, The necessary parameters are :
appid: Public accounts ID mch_id: Merchant number nonce_str: Random string sign: Signature
body: Commodity Description out_trade_no: Merchant order number total_fee: Bid price amount spbill_create_ip: terminal IP
trade_type: Type of transaction openid: User ID , Authorized to log in to official account to obtain
notify_url: Notice address ( We can process the business logic after successful payment in this , For example, modify the payment status )
①openid For reference Wechat authorized login : Mobile [unionid]( One ), Modify yourself
② Next is the core code about payment
/**
* @description: Wechat payment - Unified order
* @author: lvyq
* @date: 2020/9/16 16:30
* @version 1.0
*/
@ApiOperation(value = " Wechat payment - Unified order ")
@RequestMapping(value = "/pay2", method = {RequestMethod.POST, RequestMethod.GET})
public Object Orders(HttpServletRequest request, String openId, String tradeNo, String totalFee,String operationNO,String userName,String userPhone) {
CommonUtils commonUtils = new CommonUtils();
totalFee=String.format("%.0f", Float.valueOf(totalFee)*100);
//TODO The order number is temporarily self generated
tradeNo = new CommonUtils().getRandomStringByLength(32);
String nonce_str = WXPayUtil.generateNonceStr();
try {
Map<String, String> paraMap = new HashMap<>();
// Get request ip Address
String ip = commonUtils.getIPAddress(request);
paraMap.put("appid", appid);
paraMap.put("mch_id", mchid);
paraMap.put("nonce_str", nonce_str);
// Signature
String sign = WXPayUtil.generateSignature(paraMap, paternerKey);
paraMap.put("sign", sign);
paraMap.put("body", " Maintenance and management service fee settlement ");
paraMap.put("out_trade_no", tradeNo);
paraMap.put("total_fee", totalFee);
paraMap.put("spbill_create_ip", ip);
// TODO Payment asynchronous callback address
// Transcode Chinese here
String RuserName=URLEncoder.encode(userName, "UTF-8");
paraMap.put("notify_url", commonUtils.getDomainName(request).toString() + "/wxPay/callback2/"+operationNO+"/"+RuserName+"/"+userPhone);
System.out.print("notify_url==="+commonUtils.getDomainName(request).toString() + "/wxPay/callback2/"+operationNO+"/"+RuserName+"/"+userPhone);
paraMap.put("trade_type", "JSAPI");
paraMap.put("openid", openId);
paraMap.put("sign_type", "MD5");
// Put all the parameters (map) turn xml Format
// String xml = WXPayUtil.mapToXml(paraMap);
String xml = WXPayUtil.generateSignedXml(paraMap, paternerKey);
// send out post request " Unified order interface " Back to pre payment id:prepay_id
String xmlStr = HttpRequest.sendPost(unifiedorderUrl, xml);
String prepay_id = "";// Advance payment id
if (xmlStr.indexOf("SUCCESS") != -1) {
Map<String, String> map = WXPayUtil.xmlToMap(xmlStr);
prepay_id = (String) map.get("prepay_id");
}
Map<String, String> payMap = new HashMap<String, String>();
payMap.put("appId", appid);
payMap.put("timeStamp", WXPayUtil.getCurrentTimestamp() + "");
payMap.put("nonceStr", WXPayUtil.generateNonceStr());
payMap.put("signType", "MD5");
payMap.put("package", "prepay_id=" + prepay_id);
String paySign = WXPayUtil.generateSignature(payMap, paternerKey);
payMap.put("paySign", paySign);
return payMap;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* @description: Payment callback address
* @author: lvyq
* @date: 2020/9/17 16:06
* @version 1.0
*/
@ApiOperation(value = " Payment callback address ")
@RequestMapping(value = "/callback2/{operationNO}/{userName}/{userPhone}", method = {RequestMethod.POST, RequestMethod.GET})
public String CallBack(HttpServletRequest request, HttpServletResponse response,@PathVariable("operationNO") String operationNO,@PathVariable("userName") String userName,@PathVariable("userPhone") String userPhone) throws Exception {
InputStream is = null;
// decode
String RuserName=URLDecoder.decode(userName,"UTF-8");
System.out.print("RuserName==="+RuserName+"userName=="+userName);
try {
// Get the requested stream information ( This is from wechat xml All formats can only be read using streams )
is = request.getInputStream();
String xml = commonUtils.nputStream2String(is);
// Sent by wechat xml turn map
Map<String, String> notifyMap = WXPayUtil.xmlToMap(xml);
if (WXPayUtil.isSignatureValid(notifyMap,paternerKey)) {
if (notifyMap.get("return_code").equals("SUCCESS")) {
if (notifyMap.get("result_code").equals("SUCCESS")) {
//TODO Business code , Add, delete, modify and check the data ...
}
}
}else {
// Signature error , If there is no sign Field , It is also considered to be a signature error
}
// Tell the wechat server that it has received the message , Prevent repeated callback on wechat
response.getWriter().write("<xml><return_code><![CDATA[SUCCESS]]></return_code></xml>");
is.close();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}③, Attached below commonUtil Part of the code
package com.jmdz.util;
import com.alibaba.fastjson.JSONObject;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.net.ConnectException;
import java.net.URL;
import java.util.Random;
/**
* @description: Public tools
* @author: lvyq
* @date: 2020/9/15 11:35
* @version 1.0
*/
public class CommonUtils {
/**
* @description: Access to domain name ( agreement + domain name )
* @author: lvyq
* @date: 2020/9/15 11:36
* @version 1.0
*/
public String getDomainName(HttpServletRequest request){
// return request.getServerName()+":"+request.getServerPort();
return request.getScheme()+"://"+request.getServerName();
}
public String getIPAddress(HttpServletRequest request){
String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
if (ip.indexOf(",") != -1) {
String[] ips = ip.split(",");
ip = ips[0].trim();
}
return ip;
}
public static String getRandomStringByLength(int length) {
String base = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
Random random = new Random();
StringBuffer sb = new StringBuffer();
for (int i = 0; i < length; i++) {
int number = random.nextInt(base.length());
sb.append(base.charAt(number));
}
return sb.toString();
}
public static String nputStream2String(InputStream in) {
InputStreamReader reader = null;
try {
reader = new InputStreamReader(in, "UTF-8");
} catch (UnsupportedEncodingException e1) {
e1.printStackTrace();
}
BufferedReader br = new BufferedReader(reader);
StringBuilder sb = new StringBuilder();
String line = "";
try {
while ((line = br.readLine()) != null) {
sb.append(line);
}
} catch (IOException e) {
e.printStackTrace();
}
return sb.toString();
}
}
③.HttpRequest
package com.jmdz.util;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;
import java.util.Map;
public class HttpRequest {
/**
* Assign to URL send out GET Method request
*
* @param url
* Send requested URL
* @param param
* Request parameters , Request parameter should be name1=value1&name2=value2 In the form of .
* @return URL Response result of the remote resource represented
*/
public static String sendGet(String url, String param) {
String result = "";
BufferedReader in = null;
try {
String urlNameString = url + "?" + param;
System.out.println(urlNameString);
URL realUrl = new URL(urlNameString);
// Open and URL Connection between
URLConnection connection = realUrl.openConnection();
// Set common request properties
connection.setRequestProperty("accept", "*/*");
connection.setRequestProperty("connection", "Keep-Alive");
connection.setRequestProperty("user-agent",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
// Establish the actual connection
connection.connect();
// Get all response header fields
Map<String, List<String>> map = connection.getHeaderFields();
// Traverse all response header fields
for (String key : map.keySet()) {
System.out.println(key + "--->" + map.get(key));
}
// Definition BufferedReader Input stream to read URL Response
in = new BufferedReader(new InputStreamReader(
connection.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
result += line;
}
} catch (Exception e) {
System.out.println(" send out GET Exception in request !" + e);
e.printStackTrace();
}
// Use finally Block to close the input stream
finally {
try {
if (in != null) {
in.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
return result;
}
/**
* Assign to URL send out POST Method request
*
* @param url
* Send requested URL
* @param param
* Request parameters , Request parameter should be name1=value1&name2=value2 In the form of .
* @return Response result of the remote resource represented
*/
public static String sendPost(String url, String param) {
PrintWriter out = null;
BufferedReader in = null;
String result = "";
try {
URL realUrl = new URL(url);
// Open and URL Connection between
URLConnection conn = realUrl.openConnection();
// Set common request properties
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
// send out POST The request must be set to the following two lines
conn.setDoOutput(true);
conn.setDoInput(true);
// obtain URLConnection Object corresponding output stream
out = new PrintWriter(conn.getOutputStream());
// Send request parameters
out.print(param);
// flush Buffering of output streams
out.flush();
// Definition BufferedReader Input stream to read URL Response
in = new BufferedReader(
new InputStreamReader(conn.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
result += line;
}
} catch (Exception e) {
System.out.println(" send out POST Exception in request !"+e);
e.printStackTrace();
}
// Use finally Block to close the output stream 、 Input stream
finally{
try{
if(out!=null){
out.close();
}
if(in!=null){
in.close();
}
}
catch(IOException ex){
ex.printStackTrace();
}
}
return result;
}
}
④,WXPayUtil ( This official website provides demo There is , Just use it . I won't post code )
3、 ... and , See the effect




============================== Split line ==============================

1. in order to notify_url The interface accepts parameters , Our interface adopts restful. Forge a without parameters url
2. If the callback address contains Chinese, you cannot callback the address , Therefore, when placing a unified order , Code Chinese parameters , Decode when receiving
边栏推荐
- 视觉上位系统设计开发(halcon-winform)-3.图像控件
- C语言刷题~Leetcode与牛客网简单题
- 在MapReduce中利用MultipleOutputs输出多个文件
- 【pytorch学习笔记】Datasets and Dataloaders
- 秒杀系统3-商品列表和商品详情
- What are the composite types of Blackhorse Clickhouse, an OLAP database recognized in the industry
- [combinatorics] permutation and combination (set permutation, step-by-step processing example)
- XWiki安装使用技巧
- Kubernetes帶你從頭到尾捋一遍
- [cloud native training camp] module VIII kubernetes life cycle management and service discovery
猜你喜欢

Second kill system 3 - list of items and item details
![[attention mechanism] [first vit] Detr, end to end object detection with transformers the main components of the network are CNN and transformer](/img/9b/6ca8375ef8689a80d437665909ae30.png)
[attention mechanism] [first vit] Detr, end to end object detection with transformers the main components of the network are CNN and transformer

Kubernetes will show you from beginning to end

Concurrency-02-visibility, atomicity, orderliness, volatile, CAS, atomic class, unsafe

Visual host system design and development (Halcon WinForm)

Idea does not specify an output path for the module

Halcon and WinForm study section 2

Solve the problem that pushgateway data will be overwritten by multiple push

How to use annotations such as @notnull to verify and handle global exceptions

mysql innodb 存储引擎的特性—行锁剖析
随机推荐
Functional modules and application scenarios covered by the productization of user portraits
Popular understanding of ovo and ovr
What is one hot encoding? In pytoch, there are two ways to turn label into one hot coding
The markdown file obtains the pictures of the network and stores them locally and modifies the URL
Jvm-09 byte code introduction
Kubernetes带你从头到尾捋一遍
驱动与应用程序通信
QT common sentence notes
Chapter 04_ Logical architecture
WinDbg分析dump文件
软件安装信息、系统服务在注册表中的位置
Popular understanding of linear regression (II)
Kubernetes vous emmène du début à la fin
Kubernetes advanced training camp pod Foundation
互斥对象与临界区的区别
Seckill system 3- product list and product details
【云原生训练营】模块七 Kubernetes 控制平面组件:调度器与控制器
[attention mechanism] [first vit] Detr, end to end object detection with transformers the main components of the network are CNN and transformer
[pytorch learning notes] datasets and dataloaders
秒杀系统3-商品列表和商品详情