Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

新的微信支付证书下载机制 #194

Merged
merged 9 commits into from
Jul 14, 2023
53 changes: 30 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

# 微信支付 APIv3 Java SDK

[微信支付 APIv3](https://wechatpay-api.gitbook.io/wechatpay-api-v3/) 官方 Java 语言客户端开发库。
[微信支付 APIv3](https://pay.weixin.qq.com/docs/merchant/development/interface-rules/introduction.html) 官方 Java 语言客户端开发库。

开发库由 `core` 和 `service` 组成:

Expand All @@ -21,9 +21,9 @@

- Java 1.8+。
- [成为微信支付商户](https://pay.weixin.qq.com/index.php/apply/applyment_home/guide_normal)。
- [商户 API 证书](https://wechatpay-api.gitbook.io/wechatpay-api-v3/ren-zheng/zheng-shu#shang-hu-api-zheng-shu):指由商户申请的,包含商户的商户号、公司名称、公钥信息的证书。
- [商户 API 私钥](https://wechatpay-api.gitbook.io/wechatpay-api-v3/ren-zheng/zheng-shu#shang-hu-api-si-yao):商户申请商户API证书时,会生成商户私钥,并保存在本地证书文件夹的文件 apiclient_key.pem 中。
- [APIv3 密钥](https://wechatpay-api.gitbook.io/wechatpay-api-v3/ren-zheng/api-v3-mi-yao):为了保证安全性,微信支付在回调通知和平台证书下载接口中,对关键信息进行了 AES-256-GCM 加密。APIv3 密钥是加密时使用的对称密钥。
- [商户 API 证书](https://pay.weixin.qq.com/docs/merchant/development/interface-rules/privatekey-and-certificate.html#%E5%95%86%E6%88%B7api%E8%AF%81%E4%B9%A6):指由商户申请的,包含[证书序列号](https://pay.weixin.qq.com/docs/merchant/development/interface-rules/certificate-faqs.html#%E5%A6%82%E4%BD%95%E6%9F%A5%E7%9C%8B%E8%AF%81%E4%B9%A6%E5%BA%8F%E5%88%97%E5%8F%B7)、商户的商户号、公司名称、公钥信息的证书。
- [商户 API 私钥](https://pay.weixin.qq.com/docs/merchant/development/interface-rules/privatekey-and-certificate.html#%E5%95%86%E6%88%B7api%E7%A7%81%E9%92%A5):商户申请商户API证书时,会生成商户私钥,并保存在本地证书文件夹的文件 apiclient_key.pem 中。
- [APIv3 密钥](https://pay.weixin.qq.com/docs/merchant/development/interface-rules/apiv3key.html):为了保证安全性,微信支付在回调通知和平台证书下载接口中,对关键信息进行了 AES-256-GCM 加密。APIv3 密钥是加密时使用的对称密钥。

## 快速开始

Expand Down Expand Up @@ -69,13 +69,13 @@ import com.wechat.pay.java.service.payments.nativepay.model.PrepayResponse;
public class QuickStart {

/** 商户号 */
public static String merchantId = "";
public static String merchantId = "190000****";
/** 商户API私钥路径 */
public static String privateKeyPath = "";
public static String privateKeyPath = "/Users/yourname/your/path/apiclient_key.pem";
/** 商户证书序列号 */
public static String merchantSerialNumber = "";
public static String merchantSerialNumber = "5157F09EFDC096DE15EBE81A47057A72********";
/** 商户APIV3密钥 */
public static String apiV3key = "";
public static String apiV3key = "...";

public static void main(String[] args) {
// 使用自动更新平台证书的RSA配置
Expand Down Expand Up @@ -153,13 +153,22 @@ PrepayRequest request = new PrepayRequest();
PrepayWithRequestPaymentResponse response = service.prepayWithRequestPayment(request);
```

### 上传图片

```java
import com.wechat.pay.java.service.file.FileUploadService;
import com.wechat.pay.java.service.file.model.FileUploadResponse;

FileUploadService fileService = new FileUploadService.Builder().config(config).build();
FileUploadResponse fileUploadResponse = fileUploadService.uploadImage(uploadUrl, meta, imagePath);
```

### 更多示例

为了方便开发者快速上手,微信支付给每个服务生成了示例代码 `XxxServiceExample.java`,可以在 [example](service/src/example) 中查看。
例如:

- [JsapiServiceExtensionExample.java](service/src/example/java/com/wechat/pay/java/service/payments/jsapi/JsapiServiceExtensionExample.java)
- [FileServiceExample.java](service/src/example/java/com/wechat/pay/java/service/file/FileUploadServiceExample.java)

## 错误处理

Expand Down Expand Up @@ -200,9 +209,9 @@ Config config =

> **Note**
>
> 每个商户号只能创建一个 `RSAAutoCertificateConfig`。同一个商户号构造多个实例,会抛出 `IllegalStateException` 异常
> 从 v0.2.10 开始,不再限制每个商户号只能创建一个 `RSAAutoCertificateConfig`。但每次创建实例时,SDK 会使用新传入的私钥等参数覆盖定时更新证书的配置。如果配置不正确,将影响证书的更新
>
> 我们建议你将配置类作为全局变量。如果你的程序是多线程,建议使用**多线程安全**的单例模式
> 为了获得更好的性能,我们建议你将配置类作为全局变量。复用 `RSAAutoCertificateConfig` 可以减少不必要的初始化,避免浪费资源

### 使用本地的微信支付平台证书

Expand Down Expand Up @@ -264,9 +273,9 @@ Transaction transaction = parser.parse(requestParam, Transaction.class);

常用的通知回调对象类型:

+ 支付 `Transaction`
+ 退款 `RefundNotification`
+ 若 SDK 暂不支持的类型,请使用 `Map.class`,嵌套的 Json 对象将被转换成 `LinkedTreeMap`
- 支付 `Transaction`
- 退款 `RefundNotification`
- 若 SDK 暂不支持的类型,请使用 `Map.class`,嵌套的 Json 对象将被转换成 `LinkedTreeMap`

你既可以为每个通知回调使用不同的 HTTP 端点,也可以使用一个端点根据 `event_type` 处理不同的通知回调。
我们建议,不同的通知回调使用不同的端点,直接调用 SDK 处理通知回调,避免商户自己解析报文。因为 SDK 会先验证通知回调的有效性,可有效防止"坏人"的报文攻击。
Expand Down Expand Up @@ -311,7 +320,7 @@ inputStream.close();
- 微信支付要求加密上送的敏感信息
- 微信支付会加密下行的敏感信息

详见 [接口规则 - 敏感信息加解密](https://wechatpay-api.gitbook.io/wechatpay-api-v3/qian-ming-zhi-nan-1/min-gan-xin-xi-jia-mi)。
详见 [接口规则 - 敏感信息加解密](https://pay.weixin.qq.com/docs/merchant/development/interface-rules/sensitive-data-encryption.html)。

### 自动加解密

Expand Down Expand Up @@ -391,10 +400,10 @@ JsapiService service = new JsapiService.Builder().httpclient(httpClient).build()

假设 `api.mch.weixin.qq.com` 解析得到 [ip1a, ip1b],`api2.wechatpay.cn` 解析得到 [ip2a, ip2b],不同的重试策略组合对应的尝试顺序为:

+ 默认:[ip1a, ip1b]
+ disableRetryOnConnectionFailure:[ip1a]
+ enableRetryMultiDomain:[ipa1, ip1b, ip2a, ip2b]
+ (推荐)disableRetryOnConnectionFailure + enableRetryMultiDomain: [ip1a, ip2a]
- 默认:[ip1a, ip1b]
- disableRetryOnConnectionFailure:[ip1a]
- enableRetryMultiDomain:[ipa1, ip1b, ip2a, ip2b]
- (推荐)disableRetryOnConnectionFailure + enableRetryMultiDomain: [ip1a, ip2a]

以下是采用推荐重试策略的示例代码:

Expand Down Expand Up @@ -435,7 +444,7 @@ JsapiService service = new JsapiService.Builder().httpclient(httpClient).build()
如果你是自动获取微信支付平台证书,可以通过以下方法获取证书序列号。

```java
PrivateEncryptor encryptor = config.createEncryptor();
PrivacyEncryptor encryptor = config.createEncryptor();
String wechatPayCertificateSerialNumber = encryptor.getWechatpaySerial();
```

Expand All @@ -461,9 +470,7 @@ String wechatPayCertificateSerialNumber = encryptor.getWechatpaySerial();

### 为什么快速开始的示例程序执行后,程序不会退出?

是的,因为示例使用了自动更新微信支付平台证书,它会启动一个背景线程以定时更新证书。这个线程不会自动退出。

你可以主动终止程序,退出不会有副作用。 我们也在考虑如何提供优雅的退出方式。
在 v0.2.10 中,我们将定时更新证书的线程设置为后台线程,程序可以正常退出了。

## 如何参与开发

Expand Down

This file was deleted.

Loading