Detailed explanation of WeChat payment in Java (1): API V3 version signature
java基础教程栏目介绍Java中的微信支付,实现API V3版本签名。
1、 前言
最近在折腾微信支付,证书还是比较烦人的,所以有必要分享一些经验,减少你在开发微信支付时的踩坑。目前微信支付的API已经发展到V3版本,采用了流行的Restful风格。
今天来分享微信支付的难点——签名,虽然有很多好用的SDK但是如果你想深入了解微信支付还是需要了解一下的。
2. Detailed explanation of WeChat payment in Java (1): API V3 version signature
为了保证资金敏感数据的安全性,确保我们业务中的资金往来交易万无一失。目前微信支付第三方签发的权威的CA证书(Detailed explanation of WeChat payment in Java (1): API V3 version signature)中提供的私钥来进行签名。通过商户平台你可以设置并获取Detailed explanation of WeChat payment in Java (1): API V3 version signature。
切记在第一次设置的时候会提示下载,后面就不再提供下载了,具体参考说明。
设置后找到zip
压缩包解压,里面有很多文件,对于JAVA开发来说只需要关注apiclient_cert.p12
这个证书文件就行了,它包含了公私钥
,我们需要把它放在服务端并利用Java解析.p12
文件获取公钥私钥。
务必保证证书在服务器端的安全,它涉及到资金安全。
Parsing the API certificate
The next step is to parse the certificate. There are many ways to parse the certificate on the Internet. Here I use a more "formal" method to parse, using the JDK security packagejava.security.KeyStore
to resolve.
The WeChat payment API certificate uses the PKCS12
algorithm. We use KeyStore
to obtain the carrier of the public and private key pair KeyPair
and the certificate serial numberserialNumber
, I encapsulated the tool class:
import org.springframework.core.io.ClassPathResource;import java.security.KeyPair;import java.security.KeyStore;import java.security.PrivateKey;import java.security.PublicKey;import java.security.cert.X509Certificate;/** * KeyPairFactory * * @author dax * @since 13:41 **/public class KeyPairFactory { private KeyStore store; private final Object lock = new Object(); /** * 获取公私钥. * * @param keyPath the key path * @param keyAlias the key alias * @param keyPass password * @return the key pair */ public KeyPair createPKCS12(String keyPath, String keyAlias, String keyPass) { ClassPathResource resource = new ClassPathResource(keyPath); char[] pem = keyPass.toCharArray(); try { synchronized (lock) { if (store == null) { synchronized (lock) { store = KeyStore.getInstance("PKCS12"); store.load(resource.getInputStream(), pem); } } } X509Certificate certificate = (X509Certificate) store.getCertificate(keyAlias); certificate.checkValidity(); // 证书的序列号 也有用 String serialNumber = certificate.getSerialNumber().toString(16).toUpperCase(); // 证书的 公钥 PublicKey publicKey = certificate.getPublicKey(); // 证书的私钥 PrivateKey storeKey = (PrivateKey) store.getKey(keyAlias, pem); return new KeyPair(publicKey, storeKey); } catch (Exception e) { throw new IllegalStateException("Cannot load keys from store: " + resource, e); } } }复制代码
If it looks familiar, you can see that it is a modified version of the public and private key extraction method used by JWT in the Spring Security tutorial of Fat Brother. You can compare the differences. place.
There are three parameters in this method, which must be explained here:
-
keyPath
API certificateapiclient_cert.p12
classpath
path, generally we will put it under theresources
path. Of course, you can modify the way to obtain the certificate input stream. -
keyAlias
The alias of the certificate is not available in this WeChat document. Brother Fat obtained it by DEBUG when loading the certificate and found that the value is fixed toTenpay Certificate
. -
keyPass
Certificate password, this default is the merchant number, it also needs to be used in other configurations ismchid
, that is, you use Super Administrator A string of numbers in the personal profile when logging into the WeChat merchant platform.
3. V3 signature
The signature of WeChat Pay V3 version is that we carry a specific signature in the HTTP request header when we call the specific WeChat Pay API. The encoding string is used by the WeChat payment server to verify the source of the request to ensure that the request is authentic and trustworthy.
Signature format
The specific format of the signature string, no less than five lines in total, each line ends with a newline character \n
.
HTTP请求方法\n URL\n 请求时间戳\n 请求随机串\n 请求报文主体\n复制代码
-
HTTP request method The request method required by the WeChat payment API you call, for example, APP payment is
POST
. -
URL For example, the APP payment document is
https://api.mch.weixin.qq.com/v3/pay/transactions/app
, except the domain name part Get the URL participating in the signature. If there are query parameters in the request, '?' and the corresponding query string should be appended to the end of the URL. Here is/v3/pay/transactions/app
. -
Request timestamp Server system timestamp, make sure the server time is correct and use
System.currentTimeMillis() / 1000
to obtain it. -
Request a random string Just find a tool to generate a string similar to
593BEC0C930BF1AFEB40B4A08C8FB242
. -
Request message body If it is GET the request is directly null character
""
; when the request method is# When ##POSTor
PUT, please use
to actually send the JSON message of. For image upload API, please use the
JSONmessage corresponding to
meta.
string to be signed in the above format, and ## the signature result #Base64 encodingGet the signature value. The corresponding core Java code is: /**
* V3 SHA256withRSA 签名.
*
* @param method 请求方法 GET POST PUT DELETE 等
* @param canonicalUrl 例如 https://api.mch.weixin.qq.com/v3/pay/transactions/app?version=1 ——> /v3/pay/transactions/app?version=1
* @param timestamp 当前时间戳 因为要配置到TOKEN 中所以 签名中的要跟TOKEN 保持一致
* @param nonceStr 随机字符串 要和TOKEN中的保持一致
* @param body 请求体 GET 为 "" POST 为JSON
* @param keyPair 商户API 证书解析的密钥对 实际使用的是其中的私钥
* @return the string
*/@SneakyThrowsString sign(String method, String canonicalUrl, long timestamp, String nonceStr, String body, KeyPair keyPair) {
String signatureStr = Stream.of(method, canonicalUrl, String.valueOf(timestamp), nonceStr, body)
.collect(Collectors.joining("\n", "", "\n"));
Signature sign = Signature.getInstance("SHA256withRSA");
sign.initSign(keyPair.getPrivate());
sign.update(signatureStr.getBytes(StandardCharsets.UTF_8)); return Base64Utils.encodeToString(sign.sign());
}复制代码
After the signature is generated, it will be combined with some parameters to form a
Token and place it in the Authorization# corresponding to the HTTP request. ##In the request header, the format is:
Authorization: WECHATPAY2-SHA256-RSA2048 {Token}复制代码
Token consists of the following five parts: - mchid
-
Merchant API certificate serial number serial_no - , used to declare the certificate used
Request random string nonce_str -
timestamp##Timestamp
-
signatureSignature value
-
Token Generated core code:
/** * 生成Token. * * @param mchId 商户号 * @param nonceStr 随机字符串 * @param timestamp 时间戳 * @param serialNo 证书序列号 * @param signature 签名 * @return the string */String token(String mchId, String nonceStr, long timestamp, String serialNo, String signature) { final String TOKEN_PATTERN = "mchid=\"%s\",nonce_str=\"%s\",timestamp=\"%d\",serial_no=\"%s\",signature=\"%s\""; // 生成token return String.format(TOKEN_PATTERN, wechatPayProperties.getMchId(), nonceStr, timestamp, serialNo, signature); }复制代码
Will generate Token
is placed in the request header according to the above format to complete the use of the signature.
5. SummaryIn this article we have conducted a complete analysis of the difficult signatures and the use of signatures in the WeChat Pay V3 version, and also explained the analysis of API certificates. I believe it can help you. Solve some specific problems in payment development.
java basic tutorial
Related article introduction: How to implement the mini program payment function
The above is the detailed content of Detailed explanation of WeChat payment in Java (1): API V3 version signature. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics

Java 8 introduces the Stream API, providing a powerful and expressive way to process data collections. However, a common question when using Stream is: How to break or return from a forEach operation? Traditional loops allow for early interruption or return, but Stream's forEach method does not directly support this method. This article will explain the reasons and explore alternative methods for implementing premature termination in Stream processing systems. Further reading: Java Stream API improvements Understand Stream forEach The forEach method is a terminal operation that performs one operation on each element in the Stream. Its design intention is

PHP is a scripting language widely used on the server side, especially suitable for web development. 1.PHP can embed HTML, process HTTP requests and responses, and supports a variety of databases. 2.PHP is used to generate dynamic web content, process form data, access databases, etc., with strong community support and open source resources. 3. PHP is an interpreted language, and the execution process includes lexical analysis, grammatical analysis, compilation and execution. 4.PHP can be combined with MySQL for advanced applications such as user registration systems. 5. When debugging PHP, you can use functions such as error_reporting() and var_dump(). 6. Optimize PHP code to use caching mechanisms, optimize database queries and use built-in functions. 7

PHP and Python each have their own advantages, and the choice should be based on project requirements. 1.PHP is suitable for web development, with simple syntax and high execution efficiency. 2. Python is suitable for data science and machine learning, with concise syntax and rich libraries.

PHP is suitable for web development, especially in rapid development and processing dynamic content, but is not good at data science and enterprise-level applications. Compared with Python, PHP has more advantages in web development, but is not as good as Python in the field of data science; compared with Java, PHP performs worse in enterprise-level applications, but is more flexible in web development; compared with JavaScript, PHP is more concise in back-end development, but is not as good as JavaScript in front-end development.

Capsules are three-dimensional geometric figures, composed of a cylinder and a hemisphere at both ends. The volume of the capsule can be calculated by adding the volume of the cylinder and the volume of the hemisphere at both ends. This tutorial will discuss how to calculate the volume of a given capsule in Java using different methods. Capsule volume formula The formula for capsule volume is as follows: Capsule volume = Cylindrical volume Volume Two hemisphere volume in, r: The radius of the hemisphere. h: The height of the cylinder (excluding the hemisphere). Example 1 enter Radius = 5 units Height = 10 units Output Volume = 1570.8 cubic units explain Calculate volume using formula: Volume = π × r2 × h (4

PHP and Python each have their own advantages and are suitable for different scenarios. 1.PHP is suitable for web development and provides built-in web servers and rich function libraries. 2. Python is suitable for data science and machine learning, with concise syntax and a powerful standard library. When choosing, it should be decided based on project requirements.

H5 is more flexible and customizable, but requires skilled technology; mini programs are quick to get started and easy to maintain, but are limited by the WeChat framework.

The reasons why PHP is the preferred technology stack for many websites include its ease of use, strong community support, and widespread use. 1) Easy to learn and use, suitable for beginners. 2) Have a huge developer community and rich resources. 3) Widely used in WordPress, Drupal and other platforms. 4) Integrate tightly with web servers to simplify development deployment.
