mirror of
https://github.com/dromara/payment-spring-boot.git
synced 2026-03-14 13:53:42 +08:00
Compare commits
62 Commits
1.0.15.REL
...
2.0.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2bd091e268 | ||
|
|
1ba456f5dd | ||
|
|
0635d59666 | ||
|
|
5941907d7c | ||
|
|
348fe9b5f1 | ||
|
|
fa0cc541de | ||
|
|
85fde9bb68 | ||
|
|
da0fe928eb | ||
|
|
1c27375d93 | ||
|
|
4271491bc3 | ||
|
|
730c15b6b8 | ||
|
|
dc6e48d538 | ||
|
|
36259fc8ac | ||
|
|
e6e704cc28 | ||
|
|
8578300d1c | ||
|
|
d7cdebc731 | ||
|
|
97d87ce6f0 | ||
|
|
99136f9bd6 | ||
|
|
571bd2e563 | ||
|
|
aef8ef9ac3 | ||
|
|
f630301bc3 | ||
|
|
f7ba4dd306 | ||
|
|
997f004708 | ||
|
|
5e63779f36 | ||
|
|
30613a2fdd | ||
|
|
e9388f62c1 | ||
|
|
685839089f | ||
|
|
7b9bdd21f7 | ||
|
|
8c4ecad809 | ||
|
|
e24aa83ba0 | ||
|
|
d6d5e33dae | ||
|
|
f4df8d271e | ||
|
|
fec2468b6f | ||
|
|
0fadd3dbc0 | ||
|
|
38f6fb4e06 | ||
|
|
2fd1d0c1f9 | ||
|
|
dccc105807 | ||
|
|
2fa018a0c9 | ||
|
|
e370610e2e | ||
|
|
0f2b8762cb | ||
|
|
843afa4b1c | ||
|
|
b177174589 | ||
|
|
f80245e302 | ||
|
|
0213ddcb23 | ||
|
|
e914be40ad | ||
|
|
c53ee8bf24 | ||
|
|
0d80d4191c | ||
|
|
c6331a08f7 | ||
|
|
402fda7cf9 | ||
|
|
9cc3e96dff | ||
|
|
9ccbe1e977 | ||
|
|
6b78b30b75 | ||
|
|
bd782503ea | ||
|
|
110b8b5cfc | ||
|
|
55440b1275 | ||
|
|
59be1e96ad | ||
|
|
6534d4c0f6 | ||
|
|
0faa855f90 | ||
|
|
4fc6aad767 | ||
|
|
c55df6f576 | ||
|
|
3398f7e2b7 | ||
|
|
c5d19c68c0 |
27
.github/ISSUE_TEMPLATE/issues.md
vendored
Normal file
27
.github/ISSUE_TEMPLATE/issues.md
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
---
|
||||
name: issues
|
||||
about: 向维护者提问以帮助改进
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**提问前的思考**
|
||||
1. 我是否已经认真阅读了文档和相关操作说明
|
||||
2. 其它ISSUES是否已经有了解决方案
|
||||
|
||||
**描述问题**
|
||||
提问时应该按照以下要点清晰地描述问题,才能得到可靠的答复
|
||||
|
||||
**环境版本信息**
|
||||
问题发生的环境,不限于软件版本、运行时环境、操作系统等
|
||||
|
||||
**操作行为**
|
||||
产生问题的操作行为
|
||||
|
||||
**期望的结果**
|
||||
清晰地描述期望达成的结果
|
||||
|
||||
**代码与截图**
|
||||
通常不建议使用代码截图,这样不太方便维护者进行Preview。代码应该使用Markdown代码块进行格式化。因交互导致的问题才建议使用截图辅助排查。
|
||||
374
README.md
374
README.md
@@ -1,79 +1,355 @@
|
||||
[](https://github.com/NotFound403/payment-spring-boot/actions/workflows/main.yml)
|
||||
<div align="center" style="margin-bottom: 10px"><h1>最全最好用的微信支付V3 Spring Boot 组件</h1></div>
|
||||
|
||||
# 最好用的微信支付V3 Spring Boot 组件
|
||||
<p align="center">
|
||||
<a target="_blank" href="https://github.com/dromara/payment-spring-boot/blob/release/LICENSE">
|
||||
<img alt="" src="https://img.shields.io/github/license/dromara/payment-spring-boot"/>
|
||||
</a>
|
||||
<a target="_blank" href="https://felord.cn">
|
||||
<img alt="" src="https://img.shields.io/badge/java-8-red"/>
|
||||
</a>
|
||||
<a target="_blank" href="https://spring.io">
|
||||
<img alt="" src="https://img.shields.io/badge/spring%20boot-2.4%2B-brightgreen"/>
|
||||
</a>
|
||||
<a target="_blank" href="https://mvnrepository.com/artifact/cn.felord/payment-spring-boot">
|
||||
<img alt="" src="https://img.shields.io/maven-central/v/cn.felord/payment-spring-boot.svg?style=flat-square"/>
|
||||
</a>
|
||||
<a target="_blank" href="https://github.com/dromara/payment-spring-boot">
|
||||
<img alt="" src="https://img.shields.io/github/stars/dromara/payment-spring-boot?style=social"/>
|
||||
</a>
|
||||
<a target="_blank" href="https://gitee.com/dromara/payment-spring-boot/stargazers">
|
||||
<img alt="" src="https://gitee.com/felord/payment-spring-boot/badge/star.svg?theme=white"/>
|
||||
</a>
|
||||
<a target="_blank" href="https://work.weixin.qq.com/kfid/kfc9d9d759f27f087e1">
|
||||
<img alt="点击立即微信咨询" src="https://img.shields.io/badge/%E7%82%B9%E5%87%BB-%E5%BE%AE%E4%BF%A1%E5%92%A8%E8%AF%A2-brightgreen"/>
|
||||
</a>
|
||||
<a target="_blank" href="#">
|
||||
<img alt="点击加入QQ交流①群(满)" src="https://img.shields.io/badge/QQ%E4%BA%A4%E6%B5%81%E7%BE%A4-945342113(满)-ff69b4"/>
|
||||
</a>
|
||||
<a target="_blank" href="https://jq.qq.com/?_wv=1027&k=cCiv8Vlv">
|
||||
<img alt="点击加入QQ交流②群" src="https://img.shields.io/badge/QQ%E4%BA%A4%E6%B5%81%E7%BE%A4-549174561-ff69b4"/>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
为了满足业务中出现app支付、公众号支付、小程序支付等多appid并存的场景,对原有的进行了增强开发出了多租户版本。
|
||||
|
||||
请给[Payment Spring Boot](https://github.com/NotFound403/payment-spring-boot) **Star**以鼓励,谢谢。
|
||||
<p align="center">如果你感觉这个项目不错,请点击右上角的Star以鼓励作者,谢谢。</p>
|
||||
|
||||
## 简介
|
||||
|
||||
Java微信支付V3支付Spring Boot
|
||||
Starter,支持微信优惠券,代金券、商家券、智慧商圈、商家转账到零钱、公众号支付、微信小程序支付、分账、支付分、商家券、合单支付、先享卡、电商收付通等全部微信支付功能API,同时满足多个服务商、多个商户开发需求。一键集成,屏蔽了复杂度,API友好,上手快,欢迎star。
|
||||
|
||||
## Maven 最新中央仓库坐标
|
||||
|
||||
```xml
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.felord</groupId>
|
||||
<artifactId>payment-spring-boot-starter</artifactId>
|
||||
<version>1.0.15.RELEASE</version>
|
||||
<version>1.0.19.RELEASE</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
## JDK问题
|
||||
|
||||
**推荐使用Open JDK**,原因参见[FBI Warning](https://github.com/NotFound403/payment-spring-boot/issues/5)
|
||||
**推荐使用Open JDK**,原因参见[FBI Warning](https://github.com/dromara/payment-spring-boot/issues/5)
|
||||
|
||||
## 文档地址
|
||||
- [payment-spring-boot GitHub文档](https://notfound403.github.io/payment-spring-boot)
|
||||
- [payment-spring-boot Gitee文档](https://felord.gitee.io/payment-spring-boot)
|
||||
|
||||
- [payment-spring-boot GitHub文档](https://dromara.github.io/payment-spring-boot)
|
||||
|
||||
## API清单
|
||||
|
||||
目前已经实现绝大部分微信支付直连商户和服务商的接口,具体的API明细可查看[API清单](https://dromara.github.io/payment-spring-boot/#/wechat_v3_api)
|
||||
> 随着版本迭代功能会增加,也可通过API注册表类`WechatPayV3Type`进行API接口检索。
|
||||
|
||||
## CHANGELOG
|
||||
|
||||
更新日志[CHANGELOG](https://dromara.github.io/payment-spring-boot/#/changelog)
|
||||
|
||||
## 使用入门
|
||||
|
||||
### 集成配置
|
||||
|
||||
关于集成配置请详细阅读[payment-spring-boot GitHub文档](https://dromara.github.io/payment-spring-boot)
|
||||
中[快速接入](https://dromara.github.io/payment-spring-boot/#/quick_start)章节
|
||||
|
||||
### 调用示例
|
||||
|
||||
#### 开启支付
|
||||
|
||||
需要手动通过`@EnableMobilePay`注解开启支付
|
||||
|
||||
```java
|
||||
import cn.felord.payment.autoconfigure.EnableMobilePay;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@EnableMobilePay
|
||||
@Configuration
|
||||
public class PayConfig {
|
||||
}
|
||||
```
|
||||
|
||||
#### 支付接口调用
|
||||
|
||||
这里简单以小程序支付为例,写了一个Spring MVC 控制器,在实践中建议对`WechatApiProvider`进行二次封装作服务层调用
|
||||
|
||||
```java
|
||||
import cn.felord.payment.wechat.enumeration.TradeBillType;
|
||||
import cn.felord.payment.wechat.v3.WechatApiProvider;
|
||||
import cn.felord.payment.wechat.v3.WechatDirectPayApi;
|
||||
import cn.felord.payment.wechat.v3.model.*;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Profile;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.Month;
|
||||
|
||||
/**
|
||||
* 支付接口开发样例,以小程序支付为例.
|
||||
*/
|
||||
@Profile({"wechat", "dev"})
|
||||
@RestController
|
||||
@RequestMapping("/marketing")
|
||||
public class PayController {
|
||||
@Autowired
|
||||
private WechatApiProvider wechatApiProvider;
|
||||
String TENANT_ID = "mobile";
|
||||
|
||||
/**
|
||||
* 总流程建议为 生成商品订单 -> 生成对应的支付订单 -> 支付操作 -> 支付结果回调更新 -> 结束
|
||||
* <p>
|
||||
* 此处建议在商品订单生成之后调用
|
||||
*
|
||||
* @param orderId 商品订单id
|
||||
* @return the object node
|
||||
*/
|
||||
@PostMapping("/js")
|
||||
public ObjectNode js(@RequestParam String orderId) {
|
||||
|
||||
//TODO
|
||||
// 查询该orderId下是否生成了支付订单
|
||||
// 如果没有
|
||||
// 新增支付订单存入数据库 并标明支付状态为【待支付】
|
||||
// 根据新生成的支付订单信息向微信支付发起支付 并根据返回结果进行处理
|
||||
// 如果有状态为待支付
|
||||
// 根据待支付订单信息向微信支付发起支付 并根据返回结果进行处理
|
||||
// 如果有状态为待支付之外的状态
|
||||
// 根据产品的业务设计自行实现
|
||||
// 支付状态更新逻辑在【回调接口 /wxpay/callbacks/transaction】中处理 需要幂等处理
|
||||
|
||||
// 开发时需要指定使用的商户租户配置 这里为 mobile 请参考 application-wechat.yml
|
||||
|
||||
|
||||
## 目前已经实现所有服务商和直连商户接口
|
||||
PayParams payParams = new PayParams();
|
||||
|
||||
- 实现微信支付多商户
|
||||
- 集成支付宝SDK、快速接入Spring Boot
|
||||
- 实现微信支付V3 基础支付
|
||||
- 实现微信支付V3 合单支付
|
||||
- 实现微信支付V3 代金券
|
||||
- 实现微信支付V3 微信支付分
|
||||
- 实现微信支付V3 先享卡
|
||||
- 实现微信支付V3 商家券
|
||||
- 实现微信支付V3 批量转账到零钱
|
||||
payParams.setDescription("felord.cn");
|
||||
//
|
||||
// 商户侧唯一订单号 建议为商户侧支付订单号 订单表主键 或者唯一标识字段
|
||||
payParams.setOutTradeNo("X135423420201521613448");
|
||||
// 需要定义回调通知
|
||||
payParams.setNotifyUrl("/wxpay/callbacks/transaction");
|
||||
Amount amount = new Amount();
|
||||
amount.setTotal(100);
|
||||
payParams.setAmount(amount);
|
||||
// 此类支付 Payer 必传 且openid需要同appid有绑定关系 具体去看文档
|
||||
Payer payer = new Payer();
|
||||
payer.setOpenid("ooadI5kQYrrCqpgbisvC8bEw_oUc");
|
||||
payParams.setPayer(payer);
|
||||
|
||||
更新日志参考[changelog](https://notfound403.github.io/payment-spring-boot/#/changelog)
|
||||
return wechatApiProvider.directPayApi(TENANT_ID)
|
||||
.jsPay(payParams)
|
||||
.getBody();
|
||||
}
|
||||
|
||||
## 核心API结构
|
||||

|
||||
|
||||
- `WechatPartnerProfitsharingApi` 微信支付服务商V3分账
|
||||
- `WechatBrandProfitsharingApi` 微信支付服务商V3连锁品牌分账
|
||||
- `WechatPayCallback` 微信支付V3回调通知工具封装
|
||||
- `WechatAllocationApi` 微信支付V2分账(未来会移除)
|
||||
- `WechatMarketingFavorApi` 微信支付代金券V3
|
||||
- `WechatCombinePayApi` 微信支付合单支付V3
|
||||
- `WechatPayScoreApi` 微信支付分V3
|
||||
- `WechatPayRedpackApi` 微信支付V2现金红包
|
||||
- `WechatDiscountCardApi` 微信支付V3先享卡
|
||||
- `WechatProfitsharingApi` 微信支付直连商户V3分账
|
||||
- `WechatPartnerPayApi` 微信支付服务商模式V3普通支付
|
||||
- `WechatMarketingBusiFavorApi` 微信支付V3商家券
|
||||
- `WechatPayTransfersApi` 微信支付V2企业付款到零钱,目前不包括到银行卡
|
||||
- `WechatDirectPayApi` 微信支付直连模式V3普通支付
|
||||
- `WechatPayScoreParkingApi` 微信支付分V3停车服务
|
||||
- `WechatBatchTransferApi` 微信支付V3批量转账到零钱
|
||||
- `WechatPartnerSpecialMchApi` 微信支付V3服务商商户进件
|
||||
- `WechatMediaApi` 微信支付V3媒体上传
|
||||
- `WechatEcommerceApi` 电商收付通
|
||||
- `WechatSmartGuideApi` 服务商或者直连商户-经营能力-支付即服务
|
||||
- `WechatGoldPlanApi` 服务商-经营能力-点金计划
|
||||
/**
|
||||
* 下载对账单 如果要解析内容的话自行实现
|
||||
*
|
||||
* @return the response entity
|
||||
*/
|
||||
@GetMapping("/tradebill")
|
||||
public ResponseEntity<Resource> download() {
|
||||
WechatDirectPayApi wechatDirectPayApi = wechatApiProvider.directPayApi(TENANT_ID);
|
||||
|
||||
> 随着版本迭代功能会增加。
|
||||
TradeBillParams tradeBillParams = new TradeBillParams();
|
||||
tradeBillParams.setBillDate(LocalDate.of(2021, Month.MAY, 20));
|
||||
tradeBillParams.setBillType(TradeBillType.ALL);
|
||||
return wechatDirectPayApi.downloadTradeBill(tradeBillParams);
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载申请资金账单 如果要解析内容的话自行实现
|
||||
*
|
||||
* @return the response entity
|
||||
*/
|
||||
@GetMapping("/fundflowbill")
|
||||
public ResponseEntity<Resource> fundFlowBill() {
|
||||
WechatDirectPayApi wechatDirectPayApi = wechatApiProvider.directPayApi(TENANT_ID);
|
||||
|
||||
FundFlowBillParams fundFlowBillParams = new FundFlowBillParams();
|
||||
fundFlowBillParams.setBillDate(LocalDate.of(2021, Month.MAY, 20));
|
||||
|
||||
return wechatDirectPayApi.downloadFundFlowBill(fundFlowBillParams);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 回调示例
|
||||
|
||||
回调可通过以下示例实现,多租户的回调可将租户ID`tenantId`作为路径参数来实现
|
||||
|
||||
```java
|
||||
import cn.felord.payment.wechat.v3.WechatApiProvider;
|
||||
import cn.felord.payment.wechat.v3.WechatMarketingFavorApi;
|
||||
import cn.felord.payment.wechat.v3.WechatPayCallback;
|
||||
import cn.felord.payment.wechat.v3.model.ResponseSignVerifyParams;
|
||||
import lombok.SneakyThrows;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Profile;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestHeader;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 注意为了演示该配置在使用微信配置application-wechat.yaml才生效
|
||||
* <p>
|
||||
* 务必保证回调接口的幂等性
|
||||
* <p>
|
||||
* 微信回调控制器,当支付成功、代金券核销成功后,微信支付服务器会通过回调进行通知商户侧。
|
||||
* 商户侧可以根据微信的回调通知进行支付的后续处理,例如支付状态的变更等等。
|
||||
* 需要注意的是回调接口需要白名单放行。
|
||||
* <p>
|
||||
* 开发者只需要编写对结果的{@link java.util.function.Consumer}即可。
|
||||
* <p>
|
||||
* 请注意:返回的格格式必须是{@link WechatPayCallback} 给出的格式,不能被包装和更改,切记!
|
||||
* @author felord.cn
|
||||
* @since 1.0.0.RELEASE
|
||||
*/
|
||||
@Profile({"wechat", "dev"})
|
||||
@RestController
|
||||
@RequestMapping("/wxpay/callbacks")
|
||||
public class CallbackController {
|
||||
private static final String TENANT_ID = "mobile";
|
||||
@Autowired
|
||||
private WechatApiProvider wechatApiProvider;
|
||||
|
||||
|
||||
/**
|
||||
* 代金券核销通知.
|
||||
* <p>
|
||||
* 需要手动调用{@link WechatMarketingFavorApi#setMarketingFavorCallback(String)} 设置,一次性操作!
|
||||
*
|
||||
* @param wechatpaySerial the wechatpay serial
|
||||
* @param wechatpaySignature the wechatpay signature
|
||||
* @param wechatpayTimestamp the wechatpay timestamp
|
||||
* @param wechatpayNonce the wechatpay nonce
|
||||
* @param request the request
|
||||
* @return the map
|
||||
*/
|
||||
@SneakyThrows
|
||||
@PostMapping("/coupon")
|
||||
public Map<String, ?> couponCallback(
|
||||
@RequestHeader("Wechatpay-Serial") String wechatpaySerial,
|
||||
@RequestHeader("Wechatpay-Signature") String wechatpaySignature,
|
||||
@RequestHeader("Wechatpay-Timestamp") String wechatpayTimestamp,
|
||||
@RequestHeader("Wechatpay-Nonce") String wechatpayNonce,
|
||||
HttpServletRequest request) {
|
||||
String body = request.getReader().lines().collect(Collectors.joining());
|
||||
// 对请求头进行验签 以确保是微信服务器的调用
|
||||
ResponseSignVerifyParams params = new ResponseSignVerifyParams();
|
||||
params.setWechatpaySerial(wechatpaySerial);
|
||||
params.setWechatpaySignature(wechatpaySignature);
|
||||
params.setWechatpayTimestamp(wechatpayTimestamp);
|
||||
params.setWechatpayNonce(wechatpayNonce);
|
||||
params.setBody(body);
|
||||
return wechatApiProvider.callback(TENANT_ID).couponCallback(params, data -> {
|
||||
//TODO 对回调解析的结果进行消费 需要保证消费的幂等性 微信有可能多次调用此接口
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信支付成功回调.
|
||||
* <p>
|
||||
* 无需开发者判断,只有扣款成功微信才会回调此接口
|
||||
*
|
||||
* @param wechatpaySerial the wechatpay serial
|
||||
* @param wechatpaySignature the wechatpay signature
|
||||
* @param wechatpayTimestamp the wechatpay timestamp
|
||||
* @param wechatpayNonce the wechatpay nonce
|
||||
* @param request the request
|
||||
* @return the map
|
||||
*/
|
||||
@SneakyThrows
|
||||
@PostMapping("/transaction")
|
||||
public Map<String, ?> transactionCallback(
|
||||
@RequestHeader("Wechatpay-Serial") String wechatpaySerial,
|
||||
@RequestHeader("Wechatpay-Signature") String wechatpaySignature,
|
||||
@RequestHeader("Wechatpay-Timestamp") String wechatpayTimestamp,
|
||||
@RequestHeader("Wechatpay-Nonce") String wechatpayNonce,
|
||||
HttpServletRequest request) {
|
||||
String body = request.getReader().lines().collect(Collectors.joining());
|
||||
// 对请求头进行验签 以确保是微信服务器的调用
|
||||
ResponseSignVerifyParams params = new ResponseSignVerifyParams();
|
||||
params.setWechatpaySerial(wechatpaySerial);
|
||||
params.setWechatpaySignature(wechatpaySignature);
|
||||
params.setWechatpayTimestamp(wechatpayTimestamp);
|
||||
params.setWechatpayNonce(wechatpayNonce);
|
||||
params.setBody(body);
|
||||
return wechatApiProvider.callback(TENANT_ID).transactionCallback(params, data -> {
|
||||
//TODO 对回调解析的结果进行消费 需要保证消费的幂等性 微信有可能多次调用此接口
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信合单支付成功回调.
|
||||
* <p>
|
||||
* 无需开发者判断,只有扣款成功微信才会回调此接口
|
||||
*
|
||||
* @param wechatpaySerial the wechatpay serial
|
||||
* @param wechatpaySignature the wechatpay signature
|
||||
* @param wechatpayTimestamp the wechatpay timestamp
|
||||
* @param wechatpayNonce the wechatpay nonce
|
||||
* @param request the request
|
||||
* @return the map
|
||||
*/
|
||||
@SneakyThrows
|
||||
@PostMapping("/combine_transaction")
|
||||
public Map<String, ?> combineTransactionCallback(
|
||||
@RequestHeader("Wechatpay-Serial") String wechatpaySerial,
|
||||
@RequestHeader("Wechatpay-Signature") String wechatpaySignature,
|
||||
@RequestHeader("Wechatpay-Timestamp") String wechatpayTimestamp,
|
||||
@RequestHeader("Wechatpay-Nonce") String wechatpayNonce,
|
||||
HttpServletRequest request) {
|
||||
String body = request.getReader().lines().collect(Collectors.joining());
|
||||
// 对请求头进行验签 以确保是微信服务器的调用
|
||||
ResponseSignVerifyParams params = new ResponseSignVerifyParams();
|
||||
params.setWechatpaySerial(wechatpaySerial);
|
||||
params.setWechatpaySignature(wechatpaySignature);
|
||||
params.setWechatpayTimestamp(wechatpayTimestamp);
|
||||
params.setWechatpayNonce(wechatpayNonce);
|
||||
params.setBody(body);
|
||||
return wechatApiProvider.callback(TENANT_ID).combineTransactionCallback(params, data -> {
|
||||
//TODO 对回调解析的结果进行消费 需要保证消费的幂等性 微信有可能多次调用此接口
|
||||
});
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 开源协议
|
||||
|
||||
**Apache 2.0**
|
||||
|
||||
## 仓库地址
|
||||
- [GitHub](https://github.com/NotFound403/payment-spring-boot)
|
||||
- [Gitee](https://gitee.com/felord/payment-spring-boot)
|
||||
|
||||
## QQ交流群
|
||||
为了交流解惑,新建QQ群,可通过扫码进入。
|
||||
|
||||

|
||||
- [GitHub](https://github.com/dromara/payment-spring-boot)
|
||||
- [Gitee](https://gitee.com/dromara/payment-spring-boot)
|
||||
|
||||
|
||||
@@ -1,3 +1,20 @@
|
||||
<!--
|
||||
~ Copyright 2019-2022 felord.cn
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ https://www.apache.org/licenses/LICENSE-2.0
|
||||
~ Website:
|
||||
~ https://felord.cn
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<!-- NewPage -->
|
||||
<html lang="zh">
|
||||
@@ -137,7 +154,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
|
||||
<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../cn/felord/payment/wechat/v3/model/StocksQueryParams.html#createEndTime">createEndTime</a></span></code>
|
||||
<div class="block">选填
|
||||
|
||||
终止时间 最终满足格式 <code>yyyy-MM-dd'T'HH:mm:ss.SSSXXX</code></div>
|
||||
终止时间 最终满足格式 <code>yyyy-MM-dd'T'HH:mm:ssXXX</code></div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="rowColor">
|
||||
@@ -145,7 +162,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
|
||||
<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../cn/felord/payment/wechat/v3/model/StocksQueryParams.html#createStartTime">createStartTime</a></span></code>
|
||||
<div class="block">选填
|
||||
|
||||
起始时间 最终满足格式 <code>yyyy-MM-dd'T'HH:mm:ss.SSSXXX</code></div>
|
||||
起始时间 最终满足格式 <code>yyyy-MM-dd'T'HH:mm:ssXXX</code></div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="altColor">
|
||||
@@ -252,7 +269,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
|
||||
<pre>private <a href="https://docs.oracle.com/javase/8/docs/api/java/time/OffsetDateTime.html?is-external=true" title="java.time中的类或接口">OffsetDateTime</a> createStartTime</pre>
|
||||
<div class="block">选填
|
||||
<p>
|
||||
起始时间 最终满足格式 <code>yyyy-MM-dd'T'HH:mm:ss.SSSXXX</code></div>
|
||||
起始时间 最终满足格式 <code>yyyy-MM-dd'T'HH:mm:ssXXX</code></div>
|
||||
</li>
|
||||
</ul>
|
||||
<a name="createEndTime">
|
||||
@@ -264,7 +281,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
|
||||
<pre>private <a href="https://docs.oracle.com/javase/8/docs/api/java/time/OffsetDateTime.html?is-external=true" title="java.time中的类或接口">OffsetDateTime</a> createEndTime</pre>
|
||||
<div class="block">选填
|
||||
<p>
|
||||
终止时间 最终满足格式 <code>yyyy-MM-dd'T'HH:mm:ss.SSSXXX</code></div>
|
||||
终止时间 最终满足格式 <code>yyyy-MM-dd'T'HH:mm:ssXXX</code></div>
|
||||
</li>
|
||||
</ul>
|
||||
<a name="status">
|
||||
|
||||
@@ -1,3 +1,20 @@
|
||||
<!--
|
||||
~ Copyright 2019-2022 felord.cn
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ https://www.apache.org/licenses/LICENSE-2.0
|
||||
~ Website:
|
||||
~ https://felord.cn
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<!-- NewPage -->
|
||||
<html lang="zh">
|
||||
@@ -1780,7 +1797,7 @@
|
||||
<dd>
|
||||
<div class="block">选填
|
||||
|
||||
终止时间 最终满足格式 <code>yyyy-MM-dd'T'HH:mm:ss.SSSXXX</code></div>
|
||||
终止时间 最终满足格式 <code>yyyy-MM-dd'T'HH:mm:ssXXX</code></div>
|
||||
</dd>
|
||||
<dt><span class="memberNameLink"><a href="cn/felord/payment/wechat/v3/WechatPayScoreApi.html#createServiceOrder-cn.felord.payment.wechat.v3.model.payscore.UserServiceOrderParams-">createServiceOrder(UserServiceOrderParams)</a></span> - 类 中的方法cn.felord.payment.wechat.v3.<a href="cn/felord/payment/wechat/v3/WechatPayScoreApi.html" title="cn.felord.payment.wechat.v3中的类">WechatPayScoreApi</a></dt>
|
||||
<dd>
|
||||
@@ -1796,7 +1813,7 @@
|
||||
<dd>
|
||||
<div class="block">选填
|
||||
|
||||
起始时间 最终满足格式 <code>yyyy-MM-dd'T'HH:mm:ss.SSSXXX</code></div>
|
||||
起始时间 最终满足格式 <code>yyyy-MM-dd'T'HH:mm:ssXXX</code></div>
|
||||
</dd>
|
||||
<dt><span class="memberNameLink"><a href="cn/felord/payment/wechat/v3/WechatMarketingBusiFavorApi.html#createStock-cn.felord.payment.wechat.v3.model.busifavor.BusiFavorCreateParams-">createStock(BusiFavorCreateParams)</a></span> - 类 中的方法cn.felord.payment.wechat.v3.<a href="cn/felord/payment/wechat/v3/WechatMarketingBusiFavorApi.html" title="cn.felord.payment.wechat.v3中的类">WechatMarketingBusiFavorApi</a></dt>
|
||||
<dd>
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
<dependency>
|
||||
<groupId>cn.felord</groupId>
|
||||
<artifactId>payment-spring-boot-starter</artifactId>
|
||||
<version>1.0.15.RELEASE</version>
|
||||
<version>1.0.19.RELEASE</version>
|
||||
</dependency>
|
||||
```
|
||||
## 采用技术
|
||||
|
||||
@@ -2,6 +2,6 @@
|
||||
* [项目简介](README.md)
|
||||
* [快速接入](quick_start.md)
|
||||
* [JavaDoc](apidocs/index.html ':ignore')
|
||||
* [微信支付V3接口文档](wechat_v3_api.md)
|
||||
* [Payment微信支付V3接口文档](wechat_v3_api.md)
|
||||
* [日常踩坑](stackoverflow.md)
|
||||
* [更新日志](changelog.md)
|
||||
|
||||
@@ -1,3 +1,29 @@
|
||||
## 1.0.18.RELEASE
|
||||
### 微信支付
|
||||
|
||||
- enhance: 使用`ResourceLoader`加载资源以改善Docker容器环境下的文件挂载问题
|
||||
- enhance: 修改了微信支付配置加载机制,现在可以借助于`WechatTenantService`实现不停机维护微信支付参数的能力
|
||||
- factor: 移除过时的V2退款API相关参数`RefundModel`和`RefundQueryModel`
|
||||
- docs: 更新文档地址到[dromara.org](https://gitee.com/dromara),现在你可以通过[https://dromara.org/payment-spring-boot/](https://dromara.org/payment-spring-boot/)访问项目文档
|
||||
- docs: 修正文档描述错误
|
||||
|
||||
## 1.0.17.RELEASE
|
||||
### 微信支付
|
||||
- feat: 直连商户合单支付增加查询单笔退款
|
||||
- feat: 支付分增加退款独立的API
|
||||
- factor: 营销图片上传API现在由WechatMediaApi#marketingImageUpload实现,以代替WechatMarketingFavorApi#marketingImageUpload,旧实现已标记为过时
|
||||
- factor:时间格式优化,移除时区限制为东八区,由LocalDateTime改为OffsetDateTime
|
||||
- docs: 现在可以通过API清单检索API了
|
||||
|
||||
## 1.0.16.RELEASE
|
||||
### 微信支付
|
||||
- feat: 直连商户-委托营销相关API实现
|
||||
- enhance:基础支付增加电子发票入口开放标识
|
||||
- enhance:商家转账到零钱-发起商家转账 增加转账场景ID
|
||||
- enhance: 增加抽象接口`WechatTenantService`负责从配置文件或者其它数据源检索租户配置信息,提供默认实现`InMemoryWechatTenantService`向下兼容 #88
|
||||
- refactor: 服务商商户进件请求不再需要银行证明材料信息`BankAccountInfo`,已标记为废弃,涉及特约商户进件和电商收付通
|
||||
- upgrade: bcprov-jdk15to18 1.67 升级到 1.69
|
||||
|
||||
## 1.0.15.RELEASE
|
||||
### 微信支付
|
||||
- feat: 增加服务商退款API
|
||||
@@ -177,4 +203,4 @@
|
||||
- 多租户
|
||||
- 支付宝
|
||||
- 仅仅引入支付宝SDK,后续维护以支付宝SDK变动为准
|
||||
- 支付宝暂时不支持多租户
|
||||
- 支付宝暂时不支持多租户
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<dependency>
|
||||
<groupId>cn.felord</groupId>
|
||||
<artifactId>payment-spring-boot-starter</artifactId>
|
||||
<version>1.0.15.RELEASE</version>
|
||||
<version>1.0.19.RELEASE</version>
|
||||
</dependency>
|
||||
```
|
||||
> 基于 **Spring Boot 2.x**
|
||||
|
||||
@@ -1,112 +1,236 @@
|
||||
## 入口类
|
||||
|
||||
`WechatApiProvider`是本项目微信支付的入口类,已被注入**Spring IoC**。它目前包含以下几个**API**(后续会增加)。
|
||||
`WechatApiProvider`是本项目微信支付的入口类,已被注入**Spring IoC**,由它来初始化微信支付相关的**API**,具体分为**直连商户
|
||||
**和**服务商**两个体系。
|
||||
|
||||
### 代金券API
|
||||
> 以下清单请搭配微信支付文档使用。
|
||||
|
||||
`WechatMarketingFavorApi`是微信支付营销工具-[代金券相关API](https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pages/convention.shtml)的封装。
|
||||
### 直连商户
|
||||
|
||||
#### 创建代金券批次API
|
||||
#### 基础支付
|
||||
|
||||
`WechatResponseEntity<ObjectNode> createStock(StocksCreateParams params)`
|
||||
- [x] `WechatDirectPayApi` 基础支付,通过`WechatApiProvider#directPayApi`初始化
|
||||
- [x] `jsPay` JSAPI/小程序下单
|
||||
- [x] `appPay` APP下单
|
||||
- [x] `h5Pay` H5下单
|
||||
- [x] `nativePay` Native下单
|
||||
- [x] 查询订单
|
||||
1. `queryTransactionById` 微信支付订单号查询
|
||||
2. `queryTransactionByOutTradeNo` 商户订单号查询
|
||||
- [x] `close` 关闭订单
|
||||
- [x] `WechatPayCallback#transactionCallback` 支付通知,参见下面回调说明
|
||||
- [x] `refund` 申请退款
|
||||
- [x] `queryRefundInfo` 查询单笔退款
|
||||
- [x] `WechatPayCallback#refundCallback` 退款结果通知,参见下面回调说明
|
||||
- [x] `downloadTradeBill` 申请交易账单,直接下载为gzip或者txt文件
|
||||
- [x] `downloadFundFlowBill` 申请资金账单,直接下载为gzip或者txt文件
|
||||
- [x] `WechatCombinePayApi` 合单支付,通过`WechatApiProvider#combinePayApi`初始化
|
||||
- [x] `jsPay` 合单JSAPI/小程序下单
|
||||
- [x] `appPay` 合单APP下单
|
||||
- [x] `h5Pay` 合单H5下单
|
||||
- [x] `nativePay` 合单Native下单
|
||||
- [x] `queryTransactionByOutTradeNo` 查询订单,**合单支付目前只支持商户订单号查询**
|
||||
- [x] `close` 合单关闭订单
|
||||
- [x] `WechatPayCallback#combineTransactionCallback` 合单支付通知,参见下面回调说明
|
||||
- [x] `refund` 合单申请退款
|
||||
- [x] `queryRefundInfo` 合单查询单笔退款
|
||||
- [x] `WechatPayCallback#refundCallback` 退款结果通知,参见下面回调说明
|
||||
- [x] `downloadTradeBill` 申请交易账单,直接下载为gzip或者txt文件
|
||||
- [x] `downloadFundFlowBill` 申请资金账单,直接下载为gzip或者txt文件
|
||||
- [ ] ~~付款码支付~~,暂时没有V3接口,可通过payment spring boot 提供的V2扩展功能自行实现。
|
||||
|
||||
#### 激活代金券批次API
|
||||
#### 经营能力
|
||||
|
||||
`WechatResponseEntity<ObjectNode> startStock(String stockId)`
|
||||
##### 微信支付分
|
||||
|
||||
#### 发放代金券API
|
||||
- [x] `WechatPayScoreApi` 微信支付分,通过`WechatApiProvider#payScoreApi`初始化
|
||||
- [x] 公共API
|
||||
- [x] `createServiceOrder` 创建支付分订单
|
||||
- [x] `queryServiceOrder` 查询支付分订单
|
||||
- [x] `cancelServiceOrder` 取消支付分订单
|
||||
- [x] `modifyServiceOrder` 修改订单金额
|
||||
- [x] `completeServiceOrder` 完结支付分订单
|
||||
- [x] `syncServiceOrder` 同步服务订单信息
|
||||
- [x] `WechatPayCallback#payscoreUserOrderCallback` 支付成功回调通知,参见下面回调说明
|
||||
- [x] `refund` 支付分申请退款
|
||||
- [x] `queryRefundInfo` 支付分查询单笔退款
|
||||
- [x] `WechatPayCallback#refundCallback` 支付分退款结果通知,参见下面回调说明
|
||||
- [x] 免确认预授权模式
|
||||
- [x] `permissions` 商户预授权
|
||||
- [x] `queryPermissionsByAuthCode` 查询与用户授权记录(授权协议号)
|
||||
- [x] `terminatePermissionsByAuthCode` 解除用户授权关系(授权协议号)
|
||||
- [x] `queryPermissionsByOpenId` 查询与用户授权记录(openid)
|
||||
- [x] `terminatePermissionsByOpenId` 解除用户授权关系(openid)
|
||||
- [x] `WechatPayCallback#permissionCallback` 开启/解除授权服务回调通知,参见下面回调说明
|
||||
- [x] 需确认模式
|
||||
- [x] `WechatPayCallback#payscoreUserOrderCallback` 确认订单回调通知,参见下面回调说明
|
||||
|
||||
`WechatResponseEntity<ObjectNode> sendStock(StocksSendParams params)`
|
||||
##### 支付即服务
|
||||
|
||||
#### 暂停代金券批次API
|
||||
- [x] `WechatSmartGuideApi` 支付即服务,通过`WechatApiProvider#smartGuideApi`初始化
|
||||
- [x] `register` 服务人员注册
|
||||
- [x] `assign` 服务人员分配
|
||||
- [x] `query` 服务人员查询
|
||||
- [x] `modify` 服务人员信息更新
|
||||
|
||||
`WechatResponseEntity<ObjectNode> pauseStock(String stockId)`
|
||||
#### 行业方案
|
||||
|
||||
#### 重启代金券批次API
|
||||
##### 智慧商圈
|
||||
|
||||
`WechatResponseEntity<ObjectNode> restartStock(String stockId)`
|
||||
- [x] `WechatBusinessCircleApi` 智慧商圈,通过`WechatApiProvider#businessCircleApi`初始化
|
||||
- [ ] 商圈会员积分服务授权结果通知回调(未实现)
|
||||
- [x] `WechatPayCallback#mallTransactionCallback` 商圈会员场内支付结果通知,参见下面回调说明
|
||||
- [x] `apply` 商圈积分同步
|
||||
- [x] `WechatPayCallback#mallRefundCallback` 商圈会员场内退款通知,参见下面回调说明
|
||||
- [x] `queryAuthStatus` 商圈积分授权查询
|
||||
- [ ] 商圈会员待积分状态查询(未实现)
|
||||
- [ ] 商圈会员停车状态同步(未实现)
|
||||
|
||||
#### 条件查询批次列表API
|
||||
通过此接口可查询多个批次的信息,包括批次的配置信息以及批次概况数据。
|
||||
##### 微信支付分停车服务
|
||||
|
||||
`WechatResponseEntity<ObjectNode> queryStocksByMch(StocksQueryParams params)`
|
||||
- [x] `WechatPayScoreParkingApi` 微信支付分停车服务,通过`WechatApiProvider#payScoreParkingApi`初始化
|
||||
- [x] `find` 查询车牌服务开通信息
|
||||
- [x] `parking` 创建停车入场
|
||||
- [x] `transactionsParking` 扣费受理
|
||||
- [x] `queryTransactionByOutTradeNo` 查询订单
|
||||
- [x] `WechatPayCallback#payscoreParkingCallback` 停车入场状态变更通知,参见下面回调说明
|
||||
- [x] `WechatPayCallback#payscoreTransParkingCallback` 订单支付结果通知,参见下面回调说明
|
||||
- [x] `refund` 申请退款
|
||||
- [x] `queryRefundInfo` 查询单笔退款
|
||||
- [x] `WechatPayCallback#refundCallback` 退款结果通知,参见下面回调说明
|
||||
|
||||
#### 查询批次详情API
|
||||
#### 营销工具
|
||||
|
||||
`WechatResponseEntity<ObjectNode> queryStockDetail(String stockId)`
|
||||
##### 代金券
|
||||
|
||||
#### 查询代金券详情API
|
||||
- [x] `WechatMarketingFavorApi` 代金券,通过`WechatApiProvider#payScoreParkingApi`初始化
|
||||
- [x] `createStock` 创建代金券批次
|
||||
- [x] `startStock` 激活代金券批次
|
||||
- [x] `sendStock` 发放代金券
|
||||
- [x] `pauseStock` 暂停代金券批次
|
||||
- [x] `restartStock` 重启代金券批次
|
||||
- [x] `queryStocksByMch` 条件查询批次列表
|
||||
- [x] `queryStockDetail` 查询批次详情
|
||||
- [x] `queryCouponDetails` 查询代金券详情
|
||||
- [x] `queryMerchantsByStockId` 查询代金券可用商户
|
||||
- [x] `queryStockItems` 查询代金券可用单品
|
||||
- [x] `queryUserCouponsByMchId` 根据商户号查用户的券
|
||||
- [x] `downloadStockUseFlow` 下载批次核销明细
|
||||
- [x] `downloadStockRefundFlow` 下载批次退款明细
|
||||
- [x] `setMarketingFavorCallback` 设置消息通知地址
|
||||
- [x] `WechatPayCallback#couponCallback` 核销事件回调通知,参见下面回调说明
|
||||
- [x] `sendCouponsCard` 发放消费卡
|
||||
|
||||
`WechatResponseEntity<ObjectNode> queryCouponDetails(CouponDetailsQueryParams params)`
|
||||
> `sendCouponsCard` 发放消费卡,功能仅向指定邀约商户开放,如有需要请联系微信支付运营经理。
|
||||
|
||||
#### 查询代金券可用商户API
|
||||
##### 商家券
|
||||
|
||||
`WechatResponseEntity<ObjectNode> queryMerchantsByStockId(StocksQueryParams params)`
|
||||
- [x] `WechatMarketingBusiFavorApi` 商家券,通过`WechatApiProvider#busiFavorApi`初始化
|
||||
- [x] `createStock` 创建商家券券批次
|
||||
- [x] `queryStockDetail` 查询商家券详情
|
||||
- [x] `use` 核销用户券
|
||||
- [x] `queryUserStocks` 根据过滤条件查询用户券
|
||||
- [x] `queryUserCoupon` 查询用户单张券详情
|
||||
- [x] `uploadCouponCodes` 上传预存code
|
||||
- [x] `setCallbacks` 设置商家券事件通知地址
|
||||
- [x] `getCallbacks` 查询商家券事件通知地址
|
||||
- [x] `associate` 关联订单信息
|
||||
- [x] `disassociate` 取消关联订单信息
|
||||
- [x] `budget` 修改批次预算
|
||||
- [x] `updateStock` 修改商家券基本信息
|
||||
- [x] `refund` 申请退券
|
||||
- [x] `deactivate` 使券失效
|
||||
- [x] `payMakeup` 营销补差付款
|
||||
- [x] `queryMakeup` 查询营销补差付款单详情
|
||||
- [x] `payMakeup` 营销补差付款
|
||||
- [x] `WechatPayCallback#busiFavorReceiveCallback` 领券事件回调通知,参见下面回调说明
|
||||
|
||||
#### 查询代金券可用单品API
|
||||
##### 委托营销
|
||||
|
||||
`WechatResponseEntity<ObjectNode> queryStockItems(StocksQueryParams params)`
|
||||
- [x] `WechatMarketingPartnershipApi` 委托营销,通过`WechatApiProvider#marketingshipApi`初始化
|
||||
- [x] `build` 建立合作关系
|
||||
- [x] `query` 查询合作关系列表
|
||||
|
||||
#### 根据商户号查用户的券API
|
||||
##### 支付有礼
|
||||
|
||||
`WechatResponseEntity<ObjectNode> queryUserCouponsByMchId(UserCouponsQueryParams params)`
|
||||
- [x] `WechatMarketingPayGiftActivityApi` 支付有礼,通过`WechatApiProvider#marketingPayGiftActivityApi`初始化
|
||||
- [x] `create` 创建全场满额送活动
|
||||
- [x] `details` 查询活动详情接口
|
||||
- [x] `merchants` 查询活动发券商户号
|
||||
- [x] `goods` 查询活动指定商品列表
|
||||
- [x] `terminate` 终止活动
|
||||
- [x] `addMches` 新增活动发券商户号
|
||||
- [x] `page` 获取支付有礼活动列表
|
||||
- [x] `deleteMch` 删除活动发券商户号
|
||||
|
||||
#### 下载批次核销明细API
|
||||
##### 图片上传(营销专用)
|
||||
|
||||
`WechatResponseEntity<ObjectNode> downloadStockUseFlow(String stockId)`
|
||||
- [x] 参见 **其它能力**
|
||||
|
||||
#### 下载批次退款明细API
|
||||
##### 现金红包(基于V2)
|
||||
|
||||
`WechatResponseEntity<ObjectNode> downloadStockRefundFlow(String stockId)`
|
||||
- [x] `WechatPayRedpackApi` 现金红包,通过`WechatApiProvider#redpackApi`初始化
|
||||
- [x] `sendRedpack` 发放随机红包
|
||||
- [x] `sendRedpack` 发放裂变红包
|
||||
- [x] `redpackInfo` 查询红包信息
|
||||
|
||||
#### 营销图片上传API
|
||||
> 重要:**基于V2实现,因此需要在配置文件中配置v2支付对应的`appSecret`参数**
|
||||
|
||||
`WechatResponseEntity<ObjectNode> marketingImageUpload(MultipartFile file)`
|
||||
#### 资金应用
|
||||
|
||||
#### 代金券核销回调通知API
|
||||
##### 商家转账到零钱
|
||||
|
||||
`WechatResponseEntity<ObjectNode> setMarketingFavorCallback(String notifyUrl)`
|
||||
- [x] `WechatBatchTransferApi` 商家转账到零钱,通过`WechatApiProvider#batchTransferApi`初始化
|
||||
- [x] `batchTransfer` 发起批量转账
|
||||
- [x] 查询转账批次单
|
||||
1. `queryBatchByBatchId` 通过微信批次单号查询批次单
|
||||
2. `queryBatchByOutBatchNo` 通过商家批次单号查询批次单
|
||||
- [x] 查询转账明细单
|
||||
1. `queryBatchDetailByWechat` 通过微信明细单号查询明细单
|
||||
2. `queryBatchDetailByMch` 通过商家明细单号查询明细单
|
||||
- [x] 申请转账电子回单
|
||||
1. `receiptBill` 转账账单电子回单申请受理接口
|
||||
2. `downloadBill` 查询转账账单电子回单接口,附带下载能力
|
||||
- [x] 申请转账明细电子回单
|
||||
1. `transferElectronic` 受理转账明细电子回单
|
||||
2. `queryTransferElectronicResult` 查询转账账单电子回单接口
|
||||
|
||||
### 普通支付-直连模式API
|
||||
##### 分账
|
||||
|
||||
`WechatDirectPayApi`是微信基础支付工具-[普通支付-直连模式API](https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pages/transactions.shtml)的封装。
|
||||
- [x] `WechatProfitsharingApi` 分账,通过`WechatApiProvider#profitsharingApi`初始化
|
||||
- [x] `profitsharingOrders` 请求分账
|
||||
- [x] `queryProfitsharingOrder` 查询分账结果
|
||||
- [x] `returnOrders` 请求分账回退
|
||||
- [x] `queryReturnOrders` 查询分账回退结果
|
||||
- [x] `unfreeze` 解冻剩余资金
|
||||
- [x] `queryAmounts` 查询剩余待分金额
|
||||
- [x] `addReceivers` 添加分账接收方
|
||||
- [x] `deleteReceivers` 删除分账接收方
|
||||
- [x] `downloadMerchantBills` 申请分账账单
|
||||
|
||||
#### APP下单API
|
||||
#### 风险合规
|
||||
|
||||
`WechatResponseEntity<ObjectNode> appPay(PayParams payParams)`
|
||||
##### 消费者投诉2.0
|
||||
|
||||
#### JSAPI/小程序下单API
|
||||
- [ ] 功能实现中……
|
||||
|
||||
`WechatResponseEntity<ObjectNode> jsPay(PayParams payParams)`
|
||||
#### 其它能力
|
||||
|
||||
#### Native下单API
|
||||
##### 清关报关
|
||||
|
||||
`WechatResponseEntity<ObjectNode> nativePay(PayParams payParams)`
|
||||
- [ ] 清关报关 暂时没有V3接口,可通过payment spring boot 提供的V2扩展功能自行实现。
|
||||
|
||||
#### H5下单API
|
||||
##### 媒体上传
|
||||
|
||||
`WechatResponseEntity<ObjectNode> h5Pay(PayParams payParams)`
|
||||
> 包含图片上传和视频上传
|
||||
|
||||
#### 微信支付订单号查询API
|
||||
- [x] `WechatMediaApi` 媒体上传,通过`WechatApiProvider#mediaApi`初始化
|
||||
- [x] `mediaImageUpload` 图片上传
|
||||
- [x] `mediaVideoUpload` 视频上传
|
||||
- [x] `marketingImageUpload` 营销图片上传
|
||||
|
||||
`WechatResponseEntity<ObjectNode> queryTransactionById(TransactionQueryParams params)`
|
||||
> 通过营销**图片上传API**上传图片后可获得图片url地址。图片url可在微信支付营销相关的API使用,包括商家券、代金券、支付有礼等。
|
||||
|
||||
#### 商户订单号查询API
|
||||
### 服务商
|
||||
|
||||
`WechatResponseEntity<ObjectNode> queryTransactionByOutTradeNo(TransactionQueryParams params)`
|
||||
|
||||
#### 关单API
|
||||
|
||||
`WechatResponseEntity<ObjectNode> close(String outTradeNo)`
|
||||
|
||||
### 回调API
|
||||
|
||||
所有需要回调处理的微信支付业务通过`WechatPayCallback`来进行处理。
|
||||
|
||||
#### 微信支付代金券核销回调API
|
||||
|
||||
`Map<String, ?> couponCallback(ResponseSignVerifyParams params, Consumer<CouponConsumeData> couponConsumeDataConsumer)`
|
||||
|
||||
#### 微信支付普通支付回调API
|
||||
|
||||
`Map<String, ?> transactionCallback(ResponseSignVerifyParams params, Consumer<TransactionConsumeData> couponConsumeDataConsumer)`
|
||||
施工中……
|
||||
@@ -1,15 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright 2019-2022 felord.cn
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ https://www.apache.org/licenses/LICENSE-2.0
|
||||
~ Website:
|
||||
~ https://felord.cn
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>cn.felord</groupId>
|
||||
<artifactId>payment-spring-boot</artifactId>
|
||||
<version>1.0.15.RELEASE</version>
|
||||
<version>1.0.19.RELEASE</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>payment-spring-boot-autoconfigure</artifactId>
|
||||
<version>1.0.15.RELEASE</version>
|
||||
<version>1.0.19.RELEASE</version>
|
||||
<packaging>jar</packaging>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -47,6 +64,42 @@
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.squareup.retrofit2</groupId>
|
||||
<artifactId>retrofit</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.squareup.retrofit2</groupId>
|
||||
<artifactId>adapter-rxjava3</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.squareup.retrofit2</groupId>
|
||||
<artifactId>converter-jaxb</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.squareup.retrofit2</groupId>
|
||||
<artifactId>converter-jackson</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.datatype</groupId>
|
||||
<artifactId>jackson-datatype-jsr310</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.squareup.okhttp3</groupId>
|
||||
<artifactId>okhttp</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.squareup.okhttp3</groupId>
|
||||
<artifactId>logging-interceptor</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcprov-jdk15to18</artifactId>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -14,7 +13,6 @@
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package cn.felord.payment;
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -14,7 +13,6 @@
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package cn.felord.payment.alipay;
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -14,7 +13,6 @@
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package cn.felord.payment.alipay;
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -14,7 +13,6 @@
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package cn.felord.payment.autoconfigure;
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -14,12 +13,12 @@
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package cn.felord.payment.autoconfigure;
|
||||
|
||||
import cn.felord.payment.alipay.AliPayConfiguration;
|
||||
import cn.felord.payment.wechat.WechatPayConfiguration;
|
||||
import cn.felord.payment.wechat.WechatTenantServiceConfiguration;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
@@ -28,6 +27,6 @@ import org.springframework.context.annotation.Import;
|
||||
* @since 1.0.0.RELEASE
|
||||
*/
|
||||
@Configuration
|
||||
@Import({WechatPayConfiguration.class, AliPayConfiguration.class})
|
||||
@Import({WechatPayConfiguration.class, WechatTenantServiceConfiguration.class, AliPayConfiguration.class})
|
||||
public class PayConfiguration {
|
||||
}
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* Website:
|
||||
* https://felord.cn
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package cn.felord.payment.wechat;
|
||||
|
||||
import cn.felord.payment.wechat.v3.KeyPairFactory;
|
||||
import cn.felord.payment.wechat.v3.WechatMetaBean;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springframework.core.io.FileSystemResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.ResourceUtils;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 从配置文件中加载租户信息,默认实现,可被覆盖
|
||||
*
|
||||
* @author dax
|
||||
* @since 2023/2/3 11:40
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
public class InMemoryWechatTenantService implements WechatTenantService {
|
||||
private final WechatPayProperties wechatPayProperties;
|
||||
private final ResourceLoader resourceLoader;
|
||||
private final Set<WechatMetaBean> cache = new HashSet<>();
|
||||
|
||||
@Override
|
||||
public Set<WechatMetaBean> loadTenants() {
|
||||
if (CollectionUtils.isEmpty(cache)) {
|
||||
Map<String, WechatPayProperties.V3> v3Map = wechatPayProperties.getV3();
|
||||
KeyPairFactory keyPairFactory = new KeyPairFactory();
|
||||
Set<WechatMetaBean> beans = v3Map.entrySet()
|
||||
.stream()
|
||||
.map(entry -> {
|
||||
WechatPayProperties.V3 v3 = entry.getValue();
|
||||
String tenantId = entry.getKey();
|
||||
String certPath = v3.getCertPath();
|
||||
String certAbsolutePath = v3.getCertAbsolutePath();
|
||||
String mchId = v3.getMchId();
|
||||
Resource resource = certAbsolutePath != null ? new FileSystemResource(certAbsolutePath) :
|
||||
resourceLoader.getResource(certPath == null ? "classpath:wechat/apiclient_cert.p12" :
|
||||
certPath.startsWith(ResourceUtils.CLASSPATH_URL_PREFIX) ? certPath : ResourceUtils.CLASSPATH_URL_PREFIX + certPath);
|
||||
WechatMetaBean wechatMetaBean = keyPairFactory.initWechatMetaBean(resource, mchId);
|
||||
wechatMetaBean.setV3(v3);
|
||||
wechatMetaBean.setTenantId(tenantId);
|
||||
return wechatMetaBean;
|
||||
})
|
||||
.collect(Collectors.toSet());
|
||||
cache.addAll(beans);
|
||||
}
|
||||
return cache;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -14,22 +13,17 @@
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package cn.felord.payment.wechat;
|
||||
|
||||
|
||||
import cn.felord.payment.wechat.v3.*;
|
||||
import cn.felord.payment.wechat.v3.SignatureProvider;
|
||||
import cn.felord.payment.wechat.v3.WechatApiProvider;
|
||||
import cn.felord.payment.wechat.v3.WechatMetaContainer;
|
||||
import cn.felord.payment.wechat.v3.WechatPayClient;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Conditional;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.FileSystemResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* The type Wechat pay configuration.
|
||||
@@ -38,40 +32,18 @@ import java.util.Map;
|
||||
* @since 1.0.0.RELEASE
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@Conditional(WechatPayConfiguredCondition.class)
|
||||
@EnableConfigurationProperties(WechatPayProperties.class)
|
||||
public class WechatPayConfiguration {
|
||||
/**
|
||||
* The constant CERT_ALIAS.
|
||||
*/
|
||||
private static final String CERT_ALIAS = "Tenpay Certificate";
|
||||
|
||||
/**
|
||||
* 微信支付公私钥 以及序列号等元数据.
|
||||
*
|
||||
* @param wechatPayProperties the wechat pay properties
|
||||
* @param wechatTenantService the wechat tenant service
|
||||
* @return the wechat cert bean
|
||||
*/
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
WechatMetaContainer wechatMetaContainer(WechatPayProperties wechatPayProperties) {
|
||||
|
||||
Map<String, WechatPayProperties.V3> v3Map = wechatPayProperties.getV3();
|
||||
WechatMetaContainer container = new WechatMetaContainer();
|
||||
KeyPairFactory keyPairFactory = new KeyPairFactory();
|
||||
v3Map.keySet().forEach(tenantId -> {
|
||||
WechatPayProperties.V3 v3 = v3Map.get(tenantId);
|
||||
String certPath = v3.getCertPath();
|
||||
String certAbsolutePath = v3.getCertAbsolutePath();
|
||||
String mchId = v3.getMchId();
|
||||
Resource resource = certAbsolutePath != null ? new FileSystemResource(certAbsolutePath) :
|
||||
new ClassPathResource(certPath == null ? "wechat/apiclient_cert.p12" : certPath);
|
||||
WechatMetaBean wechatMetaBean = keyPairFactory.initWechatMetaBean(resource, CERT_ALIAS, mchId);
|
||||
wechatMetaBean.setV3(v3);
|
||||
wechatMetaBean.setTenantId(tenantId);
|
||||
container.addWechatMeta(tenantId, wechatMetaBean);
|
||||
});
|
||||
return container;
|
||||
WechatMetaContainer wechatMetaContainer(WechatTenantService wechatTenantService) {
|
||||
return new WechatMetaContainer(wechatTenantService);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -14,7 +13,6 @@
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package cn.felord.payment.wechat;
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -14,7 +13,6 @@
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package cn.felord.payment.wechat;
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -14,7 +13,6 @@
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package cn.felord.payment.wechat;
|
||||
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* Website:
|
||||
* https://felord.cn
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package cn.felord.payment.wechat;
|
||||
|
||||
import cn.felord.payment.wechat.v3.WechatMetaBean;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 加载租户信息服务
|
||||
*
|
||||
* @author felord.cn
|
||||
* @since 1.0.16.RELEASE
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface WechatTenantService {
|
||||
Set<WechatMetaBean> loadTenants();
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* Website:
|
||||
* https://felord.cn
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package cn.felord.payment.wechat;
|
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Conditional;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
|
||||
/**
|
||||
* The type Wechat tenant service configuration.
|
||||
*
|
||||
* @author felord.cn
|
||||
* @since 1.0.16.RELEASE
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@Conditional(WechatPayConfiguredCondition.class)
|
||||
@EnableConfigurationProperties(WechatPayProperties.class)
|
||||
public class WechatTenantServiceConfiguration {
|
||||
|
||||
/**
|
||||
* Wechat tenant service wechat tenant service.
|
||||
*
|
||||
* @param wechatPayProperties the wechat pay properties
|
||||
* @return the wechat tenant service
|
||||
*/
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public WechatTenantService wechatTenantService(WechatPayProperties wechatPayProperties, ResourceLoader resourceLoader) {
|
||||
return new InMemoryWechatTenantService(wechatPayProperties, resourceLoader);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* Website:
|
||||
* https://felord.cn
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package cn.felord.payment.wechat.enumeration;
|
||||
|
||||
/**
|
||||
* The enum Activity status.
|
||||
*
|
||||
* @author dax
|
||||
* @since 1.0.19.RELEASE
|
||||
*/
|
||||
public enum ActivityStatus {
|
||||
/**
|
||||
* 状态未知
|
||||
*/
|
||||
ACT_STATUS_UNKNOWN,
|
||||
/**
|
||||
* 已创建
|
||||
*/
|
||||
CREATE_ACT_STATUS,
|
||||
/**
|
||||
* 运行中
|
||||
*/
|
||||
ONGOING_ACT_STATUS,
|
||||
/**
|
||||
* 已终止
|
||||
*/
|
||||
TERMINATE_ACT_STATUS,
|
||||
|
||||
/**
|
||||
* 已暂停
|
||||
*/
|
||||
STOP_ACT_STATUS,
|
||||
|
||||
/**
|
||||
* 已过期
|
||||
*/
|
||||
OVER_TIME_ACT_STATUS,
|
||||
|
||||
/**
|
||||
* 创建活动失败
|
||||
*/
|
||||
CREATE_ACT_FAILED
|
||||
}
|
||||
@@ -15,11 +15,17 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package cn.felord.payment.wechat.v2.model;
|
||||
package cn.felord.payment.wechat.enumeration;
|
||||
|
||||
/**
|
||||
* @author felord.cn
|
||||
* @since 1.0.4.RELEASE
|
||||
* The enum Award type.
|
||||
*
|
||||
* @author dax
|
||||
* @since 1.0.19.RELEASE
|
||||
*/
|
||||
public class RefundQueryModel {
|
||||
public enum AwardType {
|
||||
/**
|
||||
* 商家券
|
||||
*/
|
||||
BUSIFAVOR
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -14,7 +13,6 @@
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package cn.felord.payment.wechat.enumeration;
|
||||
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* Website:
|
||||
* https://felord.cn
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package cn.felord.payment.wechat.enumeration;
|
||||
|
||||
/**
|
||||
* The enum Business type.
|
||||
*
|
||||
* @author felord.cn
|
||||
* @since 1.0.16.RELEASE
|
||||
*/
|
||||
public enum BusinessType {
|
||||
/**
|
||||
* 代金券批次(暂不支持合作方为商户的场景)
|
||||
*/
|
||||
FAVOR_STOCK,
|
||||
/**
|
||||
* 商家券批次
|
||||
*/
|
||||
BUSIFAVOR_STOCK
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -29,41 +28,57 @@ public enum CouponBgColor {
|
||||
/**
|
||||
* Color 010 coupon bg color.
|
||||
*/
|
||||
COLOR010,
|
||||
COLOR010("Color010"),
|
||||
/**
|
||||
* COLOR 020 coupon bg color.
|
||||
*/
|
||||
COLOR020,
|
||||
COLOR020("Color010"),
|
||||
/**
|
||||
* COLOR 030 coupon bg color.
|
||||
*/
|
||||
COLOR030,
|
||||
COLOR030("Color010"),
|
||||
/**
|
||||
* COLOR 040 coupon bg color.
|
||||
*/
|
||||
COLOR040,
|
||||
COLOR040("Color010"),
|
||||
/**
|
||||
* COLOR 050 coupon bg color.
|
||||
*/
|
||||
COLOR050,
|
||||
COLOR050("Color010"),
|
||||
/**
|
||||
* COLOR 060 coupon bg color.
|
||||
*/
|
||||
COLOR060,
|
||||
COLOR060("Color010"),
|
||||
/**
|
||||
* COLOR 070 coupon bg color.
|
||||
*/
|
||||
COLOR070,
|
||||
COLOR070("Color010"),
|
||||
/**
|
||||
* COLOR 080 coupon bg color.
|
||||
*/
|
||||
COLOR080,
|
||||
COLOR080("Color010"),
|
||||
/**
|
||||
* COLOR 090 coupon bg color.
|
||||
*/
|
||||
COLOR090,
|
||||
COLOR090("Color010"),
|
||||
/**
|
||||
* COLOR 100 coupon bg color.
|
||||
*/
|
||||
COLOR100
|
||||
COLOR100("Color010");
|
||||
|
||||
|
||||
private final String value;
|
||||
|
||||
CouponBgColor(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets value.
|
||||
*
|
||||
* @return the value
|
||||
*/
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -14,7 +13,6 @@
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package cn.felord.payment.wechat.enumeration;
|
||||
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* Website:
|
||||
* https://felord.cn
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package cn.felord.payment.wechat.enumeration;
|
||||
|
||||
/**
|
||||
* The enum Delivery purpose.
|
||||
*
|
||||
* @author felord.cn
|
||||
* @since 1.0.19.RELEASE
|
||||
*/
|
||||
public enum DeliveryPurpose {
|
||||
/**
|
||||
* 拉用户回店消费
|
||||
*/
|
||||
OFF_LINE_PAY,
|
||||
/**
|
||||
* 引导用户前往小程序消费
|
||||
*/
|
||||
JUMP_MINI_APP
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* Website:
|
||||
* https://felord.cn
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package cn.felord.payment.wechat.enumeration;
|
||||
|
||||
/**
|
||||
* @author dax
|
||||
* @since 1.0.19.RELEASE
|
||||
*/
|
||||
public enum DeliveryUserCategory {
|
||||
/**
|
||||
* 所有用户
|
||||
*/
|
||||
DELIVERY_ALL_PERSON,
|
||||
/**
|
||||
* 会员用户
|
||||
*/
|
||||
DELIVERY_MEMBER_PERSON
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* Website:
|
||||
* https://felord.cn
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package cn.felord.payment.wechat.enumeration;
|
||||
|
||||
/**
|
||||
* The enum Partner type.
|
||||
*
|
||||
* @author felord.cn
|
||||
* @since 1.0.16.RELEASE
|
||||
*/
|
||||
public enum PartnerType {
|
||||
/**
|
||||
* 合作方为APPID
|
||||
*/
|
||||
APPID,
|
||||
/**
|
||||
* 合作方为商户
|
||||
*/
|
||||
MERCHANT
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* Website:
|
||||
* https://felord.cn
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package cn.felord.payment.wechat.enumeration;
|
||||
|
||||
/**
|
||||
* 合作状态
|
||||
*
|
||||
* @author felord.cn
|
||||
* @since 1.0.16.RELEASE
|
||||
*/
|
||||
public enum PartnershipState {
|
||||
/**
|
||||
* 已建立合作状态
|
||||
*/
|
||||
ESTABLISHED,
|
||||
/**
|
||||
* 已终止合作状态
|
||||
*/
|
||||
TERMINATED
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* Website:
|
||||
* https://felord.cn
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package cn.felord.payment.wechat.enumeration;
|
||||
|
||||
/**
|
||||
* The enum Send content.
|
||||
*
|
||||
* @author dax
|
||||
* @since 1.0.19.RELEASE
|
||||
*/
|
||||
public enum SendContent {
|
||||
/**
|
||||
* 单张券
|
||||
*/
|
||||
SINGLE_COUPON,
|
||||
/**
|
||||
* 礼包
|
||||
*/
|
||||
GIFT_PACKAGE
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -14,7 +13,6 @@
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package cn.felord.payment.wechat.enumeration;
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -14,7 +13,6 @@
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package cn.felord.payment.wechat.enumeration;
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -14,7 +13,6 @@
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package cn.felord.payment.wechat.enumeration;
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -14,7 +13,6 @@
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package cn.felord.payment.wechat.enumeration;
|
||||
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* Website:
|
||||
* https://felord.cn
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package cn.felord.payment.wechat.enumeration;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* @author dax
|
||||
* @since 2023/2/1 8:59
|
||||
*/
|
||||
@Getter
|
||||
public enum WechatPayAlgorithms {
|
||||
RSA("WECHATPAY2-SHA256-RSA2048"),
|
||||
SM3("WECHATPAY2-SM2-WITH-SM3");
|
||||
|
||||
private final String algorithm;
|
||||
|
||||
WechatPayAlgorithms(String algorithm) {
|
||||
this.algorithm = algorithm;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -14,7 +13,6 @@
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package cn.felord.payment.wechat.enumeration;
|
||||
|
||||
@@ -496,6 +494,69 @@ public enum WechatPayV3Type {
|
||||
*/
|
||||
MARKETING_BUSI_FAVOR_SUBSIDY_QUERY(HttpMethod.GET, "%s/v3/marketing/busifavor/subsidy/pay-receipts/{subsidy_receipt_id}"),
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
/**
|
||||
* 建立合作关系API.
|
||||
*
|
||||
* @since 1.0.16.RELEASES
|
||||
*/
|
||||
MARKETING_PARTNERSHIPS_BUILD(HttpMethod.POST, "%s/v3/marketing/partnerships/build"),
|
||||
/**
|
||||
* 查询合作关系列表API.
|
||||
*
|
||||
* @since 1.0.16.RELEASES
|
||||
*/
|
||||
MARKETING_PARTNERSHIPS_GET(HttpMethod.GET, "%s/v3/marketing/partnerships"),
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
/**
|
||||
* 创建全场满额送活动API
|
||||
*
|
||||
* @since 1.0.19.RELEASES
|
||||
*/
|
||||
MARKETING_PAYGIFTACTIVITY(HttpMethod.POST, "%s/v3/marketing/paygiftactivity/unique-threshold-activity"),
|
||||
/**
|
||||
* 查询活动详情接口API
|
||||
*
|
||||
* @since 1.0.19.RELEASES
|
||||
*/
|
||||
MARKETING_PAYGIFTACTIVITY_DETAIL(HttpMethod.GET, "%s/v3/marketing/paygiftactivity/activities/{activity_id}"),
|
||||
/**
|
||||
* 查询活动发券商户号API
|
||||
*
|
||||
* @since 1.0.19.RELEASES
|
||||
*/
|
||||
MARKETING_PAYGIFTACTIVITY_MCH(HttpMethod.GET, "%s/v3/marketing/paygiftactivity/activities/{activity_id}/merchants"),
|
||||
/**
|
||||
* 查询活动指定商品列表API
|
||||
*
|
||||
* @since 1.0.19.RELEASES
|
||||
*/
|
||||
MARKETING_PAYGIFTACTIVITY_GOODS(HttpMethod.GET, "%s/v3/marketing/paygiftactivity/activities/{activity_id}/goods"),
|
||||
/**
|
||||
* 终止活动API
|
||||
*
|
||||
* @since 1.0.19.RELEASES
|
||||
*/
|
||||
MARKETING_PAYGIFTACTIVITY_TERMINATE(HttpMethod.POST, "%s/v3/marketing/paygiftactivity/activities/{activity_id}/terminate"),
|
||||
/**
|
||||
* 新增活动发券商户号API
|
||||
*
|
||||
* @since 1.0.19.RELEASES
|
||||
*/
|
||||
MARKETING_PAYGIFTACTIVITY_MCH_ADD(HttpMethod.POST, "%s/v3/marketing/paygiftactivity/activities/{activity_id}/merchants/add"),
|
||||
/**
|
||||
* 获取支付有礼活动列表API
|
||||
*
|
||||
* @since 1.0.19.RELEASES
|
||||
*/
|
||||
MARKETING_PAYGIFTACTIVITY_ACTIVITIES(HttpMethod.GET, "%s/v3/marketing/paygiftactivity/activities"),
|
||||
/**
|
||||
* 删除活动发券商户号API
|
||||
*
|
||||
* @since 1.0.19.RELEASES
|
||||
*/
|
||||
MARKETING_PAYGIFTACTIVITY_MCH_DEL(HttpMethod.POST, "%s/v3/marketing/paygiftactivity/activities/{activity_id}/merchants/delete"),
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
/**
|
||||
* 发起批量转账API.
|
||||
*
|
||||
|
||||
@@ -73,7 +73,7 @@ import java.util.stream.Collectors;
|
||||
*/
|
||||
@Getter
|
||||
public abstract class BaseModel {
|
||||
public static final String HMAC_SHA256="HMAC-SHA256";
|
||||
public static final String HMAC_SHA256 = "HMAC-SHA256";
|
||||
private static final XmlMapper XML_MAPPER = new XmlMapper();
|
||||
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
|
||||
|
||||
@@ -84,8 +84,7 @@ public abstract class BaseModel {
|
||||
.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
|
||||
OBJECT_MAPPER
|
||||
// .configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, true)
|
||||
.setSerializationInclusion(JsonInclude.Include.NON_NULL)
|
||||
.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
|
||||
.setSerializationInclusion(JsonInclude.Include.NON_NULL);
|
||||
}
|
||||
|
||||
|
||||
@@ -165,7 +164,7 @@ public abstract class BaseModel {
|
||||
@SneakyThrows
|
||||
private String hmacSha256(String src) {
|
||||
String algorithm = "HmacSHA256";
|
||||
Mac sha256HMAC = Mac.getInstance(algorithm,"BC");
|
||||
Mac sha256HMAC = Mac.getInstance(algorithm, "BC");
|
||||
SecretKeySpec secretKeySpec = new SecretKeySpec(appSecret.getBytes(), algorithm);
|
||||
sha256HMAC.init(secretKeySpec);
|
||||
byte[] bytes = sha256HMAC.doFinal(src.getBytes(StandardCharsets.UTF_8));
|
||||
@@ -182,7 +181,7 @@ public abstract class BaseModel {
|
||||
@SneakyThrows
|
||||
private <T> String link(T t) {
|
||||
Assert.hasText(appSecret, "wechat pay appSecret is required");
|
||||
String json = OBJECT_MAPPER
|
||||
String json = OBJECT_MAPPER
|
||||
.writeValueAsString(t);
|
||||
|
||||
TreeMap<String, String> map = OBJECT_MAPPER.readValue(json, new TypeReference<TreeMap<String, String>>() {
|
||||
@@ -200,8 +199,8 @@ public abstract class BaseModel {
|
||||
public JsonNode request(String mchId, HttpMethod method, String url) {
|
||||
String xml = this.xml();
|
||||
RequestEntity<String> body = RequestEntity.method(method, UriComponentsBuilder.fromHttpUrl(url)
|
||||
.build()
|
||||
.toUri())
|
||||
.build()
|
||||
.toUri())
|
||||
.contentType(MediaType.valueOf("application/x-www-form-urlencoded;charset=UTF-8"))
|
||||
.body(xml);
|
||||
ResponseEntity<String> responseEntity = this.getRestTemplateClientAuthentication(mchId)
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -14,7 +13,6 @@
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package cn.felord.payment.wechat.v3;
|
||||
|
||||
|
||||
@@ -1,3 +1,20 @@
|
||||
/*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* Website:
|
||||
* https://felord.cn
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package cn.felord.payment.wechat.v3;
|
||||
|
||||
import cn.felord.payment.wechat.v3.model.PageParams;
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -14,7 +13,6 @@
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package cn.felord.payment.wechat.v3;
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -14,17 +13,18 @@
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package cn.felord.payment.wechat.v3;
|
||||
|
||||
|
||||
import cn.felord.payment.PayException;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.FileSystemResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
|
||||
import java.security.*;
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyStore;
|
||||
import java.security.KeyStoreException;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
import java.security.cert.X509Certificate;
|
||||
|
||||
/**
|
||||
@@ -34,17 +34,20 @@ import java.security.cert.X509Certificate;
|
||||
* @since 1.0.0.RELEASE
|
||||
*/
|
||||
public class KeyPairFactory {
|
||||
|
||||
private static final String CERT_ALIAS = "Tenpay Certificate";
|
||||
private static final KeyStore PKCS12_KEY_STORE;
|
||||
|
||||
static {
|
||||
try {
|
||||
PKCS12_KEY_STORE = KeyStore.getInstance("PKCS12");
|
||||
} catch (KeyStoreException e) {
|
||||
throw new PayException(" wechat pay keystore initialization failed");
|
||||
}
|
||||
}
|
||||
static {
|
||||
try {
|
||||
PKCS12_KEY_STORE = KeyStore.getInstance("PKCS12");
|
||||
} catch (KeyStoreException e) {
|
||||
throw new PayException(" wechat pay keystore initialization failed");
|
||||
}
|
||||
}
|
||||
|
||||
public WechatMetaBean initWechatMetaBean(Resource resource, String keyPass) {
|
||||
return this.initWechatMetaBean(resource, CERT_ALIAS, keyPass);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取公私钥.
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -14,7 +13,6 @@
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package cn.felord.payment.wechat.v3;
|
||||
|
||||
@@ -29,11 +27,7 @@ import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.RequestEntity;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.http.*;
|
||||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
import org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter;
|
||||
import org.springframework.util.AlternativeJdkIdGenerator;
|
||||
@@ -56,8 +50,7 @@ import java.security.cert.Certificate;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneOffset;
|
||||
import java.time.Instant;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -137,7 +130,7 @@ public class SignatureProvider {
|
||||
@SneakyThrows
|
||||
public String requestSign(String tenantId, String method, String canonicalUrl, String body) {
|
||||
|
||||
long timestamp = LocalDateTime.now().toEpochSecond(ZoneOffset.of("+8"));
|
||||
long timestamp = Instant.now().getEpochSecond();
|
||||
String nonceStr = nonceStrGenerator.generateId()
|
||||
.toString()
|
||||
.replaceAll("-", "");
|
||||
@@ -177,7 +170,6 @@ public class SignatureProvider {
|
||||
* @param params the params
|
||||
* @return the boolean
|
||||
*/
|
||||
@SneakyThrows
|
||||
public boolean responseSignVerify(ResponseSignVerifyParams params) {
|
||||
|
||||
String wechatpaySerial = params.getWechatpaySerial();
|
||||
@@ -189,16 +181,18 @@ public class SignatureProvider {
|
||||
return CERTIFICATE_SET.stream()
|
||||
.filter(cert -> Objects.equals(wechatpaySerial, cert.getWechatPaySerial()))
|
||||
.findAny()
|
||||
.orElseThrow(()->new PayException("cannot obtain the certificate"));
|
||||
.orElseThrow(() -> new PayException("cannot obtain the certificate"));
|
||||
});
|
||||
|
||||
|
||||
final String signatureStr = createSign(params.getWechatpayTimestamp(), params.getWechatpayNonce(), params.getBody());
|
||||
Signature signer = Signature.getInstance("SHA256withRSA", BC_PROVIDER);
|
||||
signer.initVerify(certificate.getX509Certificate());
|
||||
signer.update(signatureStr.getBytes(StandardCharsets.UTF_8));
|
||||
|
||||
return signer.verify(Base64Utils.decodeFromString(params.getWechatpaySignature()));
|
||||
try {
|
||||
final String signatureStr = createSign(params.getWechatpayTimestamp(), params.getWechatpayNonce(), params.getBody());
|
||||
Signature signer = Signature.getInstance("SHA256withRSA", BC_PROVIDER);
|
||||
signer.initVerify(certificate.getX509Certificate());
|
||||
signer.update(signatureStr.getBytes(StandardCharsets.UTF_8));
|
||||
return signer.verify(Base64Utils.decodeFromString(params.getWechatpaySignature()));
|
||||
}catch (Exception e){
|
||||
throw new PayException("An exception occurred during the response verification, the cause: "+e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -237,8 +231,8 @@ public class SignatureProvider {
|
||||
}
|
||||
ArrayNode certificates = bodyObjectNode.withArray("data");
|
||||
if (certificates.isArray() && certificates.size() > 0) {
|
||||
CERTIFICATE_SET.forEach( x509WechatCertificateInfo -> {
|
||||
if (Objects.equals(tenantId,x509WechatCertificateInfo.getTenantId())){
|
||||
CERTIFICATE_SET.forEach(x509WechatCertificateInfo -> {
|
||||
if (Objects.equals(tenantId, x509WechatCertificateInfo.getTenantId())) {
|
||||
CERTIFICATE_SET.remove(x509WechatCertificateInfo);
|
||||
}
|
||||
});
|
||||
@@ -259,7 +253,7 @@ public class SignatureProvider {
|
||||
x509WechatCertificateInfo.setWechatPaySerial(responseSerialNo);
|
||||
x509WechatCertificateInfo.setTenantId(tenantId);
|
||||
x509WechatCertificateInfo.setX509Certificate((X509Certificate) certificate);
|
||||
CERTIFICATE_SET.add( x509WechatCertificateInfo);
|
||||
CERTIFICATE_SET.add(x509WechatCertificateInfo);
|
||||
} catch (CertificateException e) {
|
||||
throw new PayException("An error occurred while generating the wechat v3 certificate, reason : " + e.getMessage());
|
||||
}
|
||||
@@ -361,7 +355,7 @@ public class SignatureProvider {
|
||||
*/
|
||||
public X509WechatCertificateInfo getCertificate(String tenantId) {
|
||||
|
||||
return CERTIFICATE_SET.stream()
|
||||
return CERTIFICATE_SET.stream()
|
||||
.filter(cert -> Objects.equals(tenantId, cert.getTenantId()))
|
||||
.findAny()
|
||||
.orElseGet(() -> {
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -14,7 +13,6 @@
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package cn.felord.payment.wechat.v3;
|
||||
|
||||
@@ -44,17 +42,6 @@ public class WechatApiProvider {
|
||||
this.wechatPayClient = wechatPayClient;
|
||||
}
|
||||
|
||||
/**
|
||||
* 代金券.
|
||||
*
|
||||
* @param tenantId the tenant id
|
||||
* @return the wechat marketing favor api
|
||||
* @since 1.0.0.RELEASE
|
||||
*/
|
||||
public WechatMarketingFavorApi favorApi(String tenantId) {
|
||||
return new WechatMarketingFavorApi(this.wechatPayClient, tenantId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 普通支付-直连模式.
|
||||
*
|
||||
@@ -66,7 +53,6 @@ public class WechatApiProvider {
|
||||
return new WechatDirectPayApi(wechatPayClient, tenantId);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 普通支付-服务商模式.
|
||||
*
|
||||
@@ -122,6 +108,17 @@ public class WechatApiProvider {
|
||||
return new WechatDiscountCardApi(wechatPayClient, tenantId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 代金券.
|
||||
*
|
||||
* @param tenantId the tenant id
|
||||
* @return the wechat marketing favor api
|
||||
* @since 1.0.0.RELEASE
|
||||
*/
|
||||
public WechatMarketingFavorApi favorApi(String tenantId) {
|
||||
return new WechatMarketingFavorApi(this.wechatPayClient, tenantId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信支付商家券.
|
||||
*
|
||||
@@ -133,6 +130,27 @@ public class WechatApiProvider {
|
||||
return new WechatMarketingBusiFavorApi(wechatPayClient, tenantId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 委托营销-直连商户
|
||||
*
|
||||
* @param tenantId the tenant id
|
||||
* @return the wechat marketing partnership api
|
||||
*/
|
||||
public WechatMarketingPartnershipApi marketingshipApi(String tenantId) {
|
||||
return new WechatMarketingPartnershipApi(this.wechatPayClient, tenantId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付有礼-直连商户
|
||||
*
|
||||
* @param tenantId the tenant id
|
||||
* @return the wechat marketing pay gift activity api
|
||||
* @since 1.0.19.RELEASE
|
||||
*/
|
||||
public WechatMarketingPayGiftActivityApi marketingPayGiftActivityApi(String tenantId) {
|
||||
return new WechatMarketingPayGiftActivityApi(this.wechatPayClient, tenantId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量转账到零钱.
|
||||
* <p>
|
||||
@@ -200,7 +218,7 @@ public class WechatApiProvider {
|
||||
}
|
||||
|
||||
/**
|
||||
* 服务商微信支付分账,基于V3
|
||||
* 服务商-微信支付分账,基于V3
|
||||
*
|
||||
* @param tenantId the tenant id
|
||||
* @return the wechat partner profitsharing api
|
||||
@@ -210,7 +228,7 @@ public class WechatApiProvider {
|
||||
}
|
||||
|
||||
/**
|
||||
* 服务商品牌分账
|
||||
* 服务商-品牌分账
|
||||
*
|
||||
* @param tenantId the tenant id
|
||||
* @return the wechat brand profitsharing api
|
||||
@@ -264,7 +282,7 @@ public class WechatApiProvider {
|
||||
}
|
||||
|
||||
/**
|
||||
* 服务商智慧商圈
|
||||
* 服务商-智慧商圈
|
||||
*
|
||||
* @param tenantId the tenant id
|
||||
* @return the wechat business circle api
|
||||
@@ -275,7 +293,7 @@ public class WechatApiProvider {
|
||||
}
|
||||
|
||||
/**
|
||||
* 直连商户智慧商圈
|
||||
* 直连商户-智慧商圈
|
||||
*
|
||||
* @param tenantId the tenant id
|
||||
* @return the wechat business circle api
|
||||
@@ -307,4 +325,13 @@ public class WechatApiProvider {
|
||||
return new WechatCapitalApi(wechatPayClient, tenantId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 风险合规-消费者投诉2.0
|
||||
*
|
||||
* @param tenantId the tenant id
|
||||
* @return the wechat complaints api
|
||||
*/
|
||||
public WechatComplaintsApi complaintsApi(String tenantId) {
|
||||
return new WechatComplaintsApi(wechatPayClient, tenantId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ public class WechatBatchTransferApi extends AbstractApi {
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信批次单号查询批次单API
|
||||
* 通过微信批次单号查询批次单API
|
||||
*
|
||||
* @param queryBatchTransferParams the queryBatchTransferParams
|
||||
* @return the wechat response entity
|
||||
@@ -132,33 +132,7 @@ public class WechatBatchTransferApi extends AbstractApi {
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信明细单号查询明细单API
|
||||
*
|
||||
* @param queryBatchTransferDetailParams the queryBatchTransferDetailParams
|
||||
* @return the wechat response entity
|
||||
* @since 1.0.6.RELEASE
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> queryBatchDetailByWechat(QueryBatchTransferDetailParams queryBatchTransferDetailParams) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.BATCH_TRANSFER_DETAIL_WECHAT, queryBatchTransferDetailParams)
|
||||
.function((type, params) -> {
|
||||
Map<String, String> pathParams = new HashMap<>(2);
|
||||
pathParams.put("batch_id", params.getBatchIdOrOutBatchNo());
|
||||
pathParams.put("detail_id", params.getDetailIdOrOutDetailNo());
|
||||
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.expand(pathParams)
|
||||
.toUri();
|
||||
return Get(uri);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信批次单号查询批次单API
|
||||
* 通过商家批次单号查询批次单API
|
||||
*
|
||||
* @param queryBatchTransferParams the queryBatchTransferParams
|
||||
* @return the wechat response entity
|
||||
@@ -187,7 +161,33 @@ public class WechatBatchTransferApi extends AbstractApi {
|
||||
}
|
||||
|
||||
/**
|
||||
* 商家明细单号查询明细单API
|
||||
* 通过微信明细单号查询明细单API
|
||||
*
|
||||
* @param queryBatchTransferDetailParams the queryBatchTransferDetailParams
|
||||
* @return the wechat response entity
|
||||
* @since 1.0.6.RELEASE
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> queryBatchDetailByWechat(QueryBatchTransferDetailParams queryBatchTransferDetailParams) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.BATCH_TRANSFER_DETAIL_WECHAT, queryBatchTransferDetailParams)
|
||||
.function((type, params) -> {
|
||||
Map<String, String> pathParams = new HashMap<>(2);
|
||||
pathParams.put("batch_id", params.getBatchIdOrOutBatchNo());
|
||||
pathParams.put("detail_id", params.getDetailIdOrOutDetailNo());
|
||||
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.expand(pathParams)
|
||||
.toUri();
|
||||
return Get(uri);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过商家明细单号查询明细单API
|
||||
*
|
||||
* @param queryBatchTransferDetailParams the queryBatchTransferDetailParams
|
||||
* @return the wechat response entity
|
||||
@@ -260,7 +260,7 @@ public class WechatBatchTransferApi extends AbstractApi {
|
||||
}
|
||||
|
||||
/**
|
||||
* 转账明细电子回单受理API
|
||||
* 受理转账明细电子回单API
|
||||
* <p>
|
||||
* 受理转账明细电子回单接口,商户通过该接口可以申请受理转账明细单电子回单服务。
|
||||
* <p>
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* Website:
|
||||
* https://felord.cn
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package cn.felord.payment.wechat.v3;
|
||||
|
||||
import cn.felord.payment.wechat.WechatPayProperties;
|
||||
|
||||
@@ -1,3 +1,20 @@
|
||||
/*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* Website:
|
||||
* https://felord.cn
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package cn.felord.payment.wechat.v3;
|
||||
|
||||
import cn.felord.payment.wechat.enumeration.WeChatServer;
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -14,7 +13,6 @@
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package cn.felord.payment.wechat.v3;
|
||||
|
||||
@@ -211,4 +209,26 @@ public class WechatCombinePayApi extends AbstractApi {
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询单笔退款API
|
||||
*
|
||||
* @param outRefundNo the out refund no
|
||||
* @return the wechat response entity
|
||||
* @since 1.0.17.RELEASE
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> queryRefundInfo(String outRefundNo) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.QUERY_REFUND, outRefundNo)
|
||||
.function(((type, param) -> {
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.expand(param)
|
||||
.toUri();
|
||||
return Get(uri);
|
||||
}))
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* Website:
|
||||
* https://felord.cn
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package cn.felord.payment.wechat.v3;
|
||||
|
||||
/**
|
||||
* 风险合规-消费者投诉2.0
|
||||
*
|
||||
* @author felord.cn
|
||||
* @since 1.0.16.RELEASE
|
||||
*/
|
||||
public class WechatComplaintsApi extends AbstractApi{
|
||||
/**
|
||||
* Instantiates a new Abstract api.
|
||||
*
|
||||
* @param wechatPayClient the wechat pay client
|
||||
* @param tenantId the tenant id
|
||||
*/
|
||||
public WechatComplaintsApi(WechatPayClient wechatPayClient, String tenantId) {
|
||||
super(wechatPayClient, tenantId);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -14,7 +13,6 @@
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package cn.felord.payment.wechat.v3;
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -14,7 +13,6 @@
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package cn.felord.payment.wechat.v3;
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package cn.felord.payment.wechat.v3;
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -546,13 +545,17 @@ public class WechatMarketingFavorApi extends AbstractApi {
|
||||
/**
|
||||
* 营销图片上传API
|
||||
* <p>
|
||||
* 该接口标记过时,用{@link WechatMediaApi#marketingImageUpload(MultipartFile)}代替
|
||||
* <p>
|
||||
* 媒体图片只支持JPG、BMP、PNG格式,文件大小不能超过2M。
|
||||
* <p>
|
||||
* 通过本接口上传图片后可获得图片url地址。图片url可在微信支付营销相关的API使用,包括商家券、代金券、支付有礼等。
|
||||
*
|
||||
* @param file the file
|
||||
* @return the wechat response entity
|
||||
* @see WechatMediaApi#marketingImageUpload(MultipartFile)
|
||||
*/
|
||||
@Deprecated
|
||||
public WechatResponseEntity<ObjectNode> marketingImageUpload(MultipartFile file) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.MARKETING_IMAGE_UPLOAD, file)
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* Website:
|
||||
* https://felord.cn
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package cn.felord.payment.wechat.v3;
|
||||
|
||||
import cn.felord.payment.PayException;
|
||||
import cn.felord.payment.wechat.enumeration.WeChatServer;
|
||||
import cn.felord.payment.wechat.enumeration.WechatPayV3Type;
|
||||
import cn.felord.payment.wechat.v3.model.partnership.Partner;
|
||||
import cn.felord.payment.wechat.v3.model.partnership.PartnershipParams;
|
||||
import cn.felord.payment.wechat.v3.model.partnership.PartnershipQueryParams;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
import org.springframework.web.util.UriUtils;
|
||||
|
||||
import java.net.URI;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 委托营销-直连商户
|
||||
*
|
||||
* @author felord.cn
|
||||
* @since 1.0.16.RELEASE
|
||||
*/
|
||||
public class WechatMarketingPartnershipApi extends AbstractApi {
|
||||
/**
|
||||
* Instantiates a new Abstract api.
|
||||
*
|
||||
* @param wechatPayClient the wechat pay client
|
||||
* @param tenantId the tenant id
|
||||
*/
|
||||
public WechatMarketingPartnershipApi(WechatPayClient wechatPayClient, String tenantId) {
|
||||
super(wechatPayClient, tenantId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 建立合作关系API
|
||||
* <p>
|
||||
* 该接口主要为商户提供营销资源的授权能力,可授权给其他商户或小程序,方便商户间的互利合作。
|
||||
*
|
||||
* @param params the params
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> build(PartnershipParams params) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.MARKETING_PARTNERSHIPS_BUILD, params)
|
||||
.function((type, partnershipParams) -> {
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.toUri();
|
||||
String idempotencyKey = partnershipParams.getIdempotencyKey();
|
||||
partnershipParams.clearKey();
|
||||
HttpHeaders httpHeaders = new HttpHeaders();
|
||||
httpHeaders.add("Idempotency-Key", idempotencyKey);
|
||||
return Post(uri, partnershipParams, httpHeaders);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询合作关系列表API
|
||||
* <p>
|
||||
* 该接口主要为商户提供合作关系列表的查询能力。
|
||||
*
|
||||
* @param params the params
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> query(PartnershipQueryParams params) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.MARKETING_PARTNERSHIPS_GET, params)
|
||||
.function((type, partnershipParams) -> {
|
||||
MultiValueMap<String, String> queryParams = new LinkedMultiValueMap<>();
|
||||
Partner partner = params.getPartner();
|
||||
try {
|
||||
ObjectMapper mapper = this.getMapper();
|
||||
if (Objects.nonNull(partner)) {
|
||||
String partnerJson = mapper.writeValueAsString(partner);
|
||||
queryParams.add("partner", UriUtils.encode(partnerJson, StandardCharsets.UTF_8));
|
||||
}
|
||||
String authorizedDataJson = mapper.writeValueAsString(params.getAuthorizedData());
|
||||
|
||||
queryParams.add("authorized_data", UriUtils.encode(authorizedDataJson, StandardCharsets.UTF_8));
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new PayException(e);
|
||||
}
|
||||
Integer limit = params.getLimit();
|
||||
if (Objects.nonNull(limit)) {
|
||||
queryParams.add("limit", limit.toString());
|
||||
}
|
||||
Integer offset = params.getOffset();
|
||||
if (Objects.nonNull(offset)) {
|
||||
queryParams.add("offset", offset.toString());
|
||||
}
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA))
|
||||
.queryParams(queryParams)
|
||||
.build(false)
|
||||
.toUri();
|
||||
return Get(uri);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,232 @@
|
||||
/*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* Website:
|
||||
* https://felord.cn
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package cn.felord.payment.wechat.v3;
|
||||
|
||||
import cn.felord.payment.wechat.enumeration.WeChatServer;
|
||||
import cn.felord.payment.wechat.enumeration.WechatPayV3Type;
|
||||
import cn.felord.payment.wechat.v3.model.paygiftactivity.ActivitiesListPageRequest;
|
||||
import cn.felord.payment.wechat.v3.model.paygiftactivity.ActivitiesPageRequest;
|
||||
import cn.felord.payment.wechat.v3.model.paygiftactivity.DeleteActivityMchRequest;
|
||||
import cn.felord.payment.wechat.v3.model.paygiftactivity.GiftActivityParams;
|
||||
import cn.felord.payment.wechat.v3.model.paygiftactivity.NewActivityMchRequest;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 支付有礼
|
||||
*
|
||||
* @author dax
|
||||
* @since 1.0.19.RELEASE
|
||||
*/
|
||||
public class WechatMarketingPayGiftActivityApi extends AbstractApi {
|
||||
/**
|
||||
* Instantiates a new Abstract api.
|
||||
*
|
||||
* @param wechatPayClient the wechat pay client
|
||||
* @param tenantId the tenant id
|
||||
*/
|
||||
public WechatMarketingPayGiftActivityApi(WechatPayClient wechatPayClient, String tenantId) {
|
||||
super(wechatPayClient, tenantId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建全场满额送活动API
|
||||
*
|
||||
* @param params the params
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> create(GiftActivityParams params) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.MARKETING_PAYGIFTACTIVITY, params)
|
||||
.function((type, activityParams) -> {
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.toUri();
|
||||
return Post(uri, activityParams);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询活动详情接口API
|
||||
*
|
||||
* @param activityId the activity id
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> details(String activityId) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.MARKETING_PAYGIFTACTIVITY_DETAIL, activityId)
|
||||
.function((type, param) -> {
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.expand(param)
|
||||
.toUri();
|
||||
return Get(uri);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询活动发券商户号API
|
||||
*
|
||||
* @param request the request
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> merchants(ActivitiesPageRequest request) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.MARKETING_PAYGIFTACTIVITY_MCH, request)
|
||||
.function((type, params) -> {
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA))
|
||||
.queryParam("offset", params.getOffset())
|
||||
.queryParam("limit", params.getLimit())
|
||||
.build()
|
||||
.expand(params.getActivityId())
|
||||
.toUri();
|
||||
return Get(uri);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询活动指定商品列表API
|
||||
*
|
||||
* @param request the request
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> goods(ActivitiesPageRequest request) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.MARKETING_PAYGIFTACTIVITY_GOODS, request)
|
||||
.function((type, params) -> {
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA))
|
||||
.queryParam("offset", params.getOffset())
|
||||
.queryParam("limit", params.getLimit())
|
||||
.build()
|
||||
.expand(params.getActivityId())
|
||||
.toUri();
|
||||
return Get(uri);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 终止活动API
|
||||
*
|
||||
* @param activityId the activity id
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> terminate(String activityId) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.MARKETING_PAYGIFTACTIVITY_TERMINATE, activityId)
|
||||
.function((type, param) -> {
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.expand(param)
|
||||
.toUri();
|
||||
return Post(uri, Collections.emptyMap());
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增活动发券商户号API
|
||||
*
|
||||
* @param request the request
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> addMches(NewActivityMchRequest request) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.MARKETING_PAYGIFTACTIVITY_MCH_ADD, request)
|
||||
.function((type, params) -> {
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.expand(params.getActivityId())
|
||||
.toUri();
|
||||
Map<String, Object> body = new HashMap<>();
|
||||
body.put("merchant_id_list", params.getMerchantIdList());
|
||||
body.put("add_request_no", params.getAddRequestNo());
|
||||
return Post(uri, body);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取支付有礼活动列表API
|
||||
*
|
||||
* @param request the request
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> page(ActivitiesListPageRequest request) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.MARKETING_PAYGIFTACTIVITY_ACTIVITIES, request)
|
||||
.function((type, params) -> {
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA))
|
||||
.queryParam("offset", params.getOffset())
|
||||
.queryParam("limit", params.getLimit())
|
||||
.queryParam("activity_name", params.getActivityName())
|
||||
.queryParam("activity_status", params.getActivityStatus())
|
||||
.queryParam("award_type", params.getAwardType())
|
||||
.build()
|
||||
.toUri();
|
||||
return Get(uri);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除活动发券商户号API
|
||||
*
|
||||
* @param request the request
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> deleteMch(DeleteActivityMchRequest request) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.MARKETING_PAYGIFTACTIVITY_MCH_DEL, request)
|
||||
.function((type, params) -> {
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.expand(params.getActivityId())
|
||||
.toUri();
|
||||
Map<String, Object> body = new HashMap<>();
|
||||
body.put("merchant_id_list", params.getMerchantIdList());
|
||||
body.put("delete_request_no", params.getDeleteRequestNo());
|
||||
return Post(uri, body);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
}
|
||||
@@ -82,6 +82,7 @@ public class WechatMediaApi extends AbstractApi {
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private RequestEntity<?> uploadFunction(WechatPayV3Type type, MultipartFile file) {
|
||||
|
||||
@@ -108,4 +109,24 @@ public class WechatMediaApi extends AbstractApi {
|
||||
.header("Pay-TenantId", tenantId())
|
||||
.body(body);
|
||||
}
|
||||
|
||||
/**
|
||||
* 营销图片上传API
|
||||
* <p>
|
||||
* 媒体图片只支持JPG、BMP、PNG格式,文件大小不能超过2M。
|
||||
* <p>
|
||||
* 通过本接口上传图片后可获得图片url地址。图片url可在微信支付营销相关的API使用,包括商家券、代金券、支付有礼等。
|
||||
*
|
||||
* @param file the file
|
||||
* @return the wechat response entity
|
||||
* @since 1.0.17.RELEASE
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> marketingImageUpload(MultipartFile file) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.MARKETING_IMAGE_UPLOAD, file)
|
||||
.function(this::uploadFunction)
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -14,7 +13,6 @@
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package cn.felord.payment.wechat.v3;
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -14,12 +13,19 @@
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package cn.felord.payment.wechat.v3;
|
||||
|
||||
|
||||
import java.util.*;
|
||||
import cn.felord.payment.wechat.WechatTenantService;
|
||||
import lombok.AllArgsConstructor;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 配置容器
|
||||
@@ -27,32 +33,23 @@ import java.util.*;
|
||||
* @author felord.cn
|
||||
* @since 1.0.0.RELEASE
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
public class WechatMetaContainer {
|
||||
private final Map<String, WechatMetaBean> wechatMetaBeanMap = new HashMap<>();
|
||||
private final Set<String> tenantIds = new HashSet<>();
|
||||
|
||||
private final Map<String, WechatMetaBean> wechatMetaBeanMap = new ConcurrentHashMap<>();
|
||||
private final WechatTenantService wechatTenantService;
|
||||
|
||||
/**
|
||||
* Add wechat meta boolean.
|
||||
* Add wechat metas.
|
||||
*
|
||||
* @param tenantId the tenantId
|
||||
* @param wechatMetaBean the wechat meta bean
|
||||
* @return the boolean
|
||||
* @param wechatMetaBeans the wechat meta beans
|
||||
*/
|
||||
public WechatMetaBean addWechatMeta(String tenantId, WechatMetaBean wechatMetaBean) {
|
||||
tenantIds.add(tenantId);
|
||||
return this.wechatMetaBeanMap.put(tenantId, wechatMetaBean);
|
||||
public void addWechatMetas(Collection<WechatMetaBean> wechatMetaBeans) {
|
||||
wechatMetaBeans.forEach(this::addMeta);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove wechat meta wechat meta bean.
|
||||
*
|
||||
* @param tenantId the tenantId
|
||||
* @return the wechat meta bean
|
||||
*/
|
||||
public WechatMetaBean removeWechatMeta(String tenantId) {
|
||||
tenantIds.remove(tenantId);
|
||||
return this.wechatMetaBeanMap.remove(tenantId);
|
||||
private void addMeta(WechatMetaBean wechatMetaBean) {
|
||||
String tenantId = wechatMetaBean.getTenantId();
|
||||
wechatMetaBeanMap.put(tenantId, wechatMetaBean);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -62,7 +59,14 @@ public class WechatMetaContainer {
|
||||
* @return the wechat meta
|
||||
*/
|
||||
public WechatMetaBean getWechatMeta(String tenantId) {
|
||||
return Objects.requireNonNull(this.wechatMetaBeanMap.get(tenantId));
|
||||
WechatMetaBean wechatMetaBean = this.wechatMetaBeanMap.get(tenantId);
|
||||
if (Objects.nonNull(wechatMetaBean)) {
|
||||
return wechatMetaBean;
|
||||
} else {
|
||||
this.addWechatMetas(wechatTenantService.loadTenants());
|
||||
return Objects.requireNonNull(this.wechatMetaBeanMap.get(tenantId),
|
||||
"cant obtain the config with tenant: "+tenantId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -71,6 +75,9 @@ public class WechatMetaContainer {
|
||||
* @return the properties keys
|
||||
*/
|
||||
public Set<String> getTenantIds() {
|
||||
return tenantIds;
|
||||
return wechatTenantService.loadTenants()
|
||||
.stream()
|
||||
.map(WechatMetaBean::getTenantId)
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ public class WechatPartnerPayApi extends AbstractApi {
|
||||
WechatMetaBean wechatMetaBean = wechatMetaContainer.getWechatMeta(tenantId());
|
||||
PrivateKey privateKey = wechatMetaBean.getKeyPair().getPrivate();
|
||||
|
||||
String subAppid = partnerPayParams.getSubAppid();
|
||||
String spAppid = partnerPayParams.getSpAppid();
|
||||
long epochSecond = LocalDateTime.now()
|
||||
.toEpochSecond(ZoneOffset.of("+8"));
|
||||
String timestamp = String.valueOf(epochSecond);
|
||||
@@ -89,9 +89,8 @@ public class WechatPartnerPayApi extends AbstractApi {
|
||||
.toString()
|
||||
.replaceAll("-", "");
|
||||
String prepayId = body.get("prepay_id").asText();
|
||||
String paySign = signatureProvider.doRequestSign(privateKey, subAppid, timestamp, nonceStr, prepayId);
|
||||
|
||||
body.put("appid", subAppid);
|
||||
String paySign = signatureProvider.doRequestSign(privateKey, spAppid, timestamp, nonceStr, prepayId);
|
||||
body.put("appid", spAppid);
|
||||
body.put("partnerid", partnerPayParams.getSubMchid());
|
||||
body.put("prepayid", prepayId);
|
||||
body.put("package", "Sign=WXPay");
|
||||
@@ -129,7 +128,7 @@ public class WechatPartnerPayApi extends AbstractApi {
|
||||
WechatMetaBean wechatMetaBean = wechatMetaContainer.getWechatMeta(tenantId());
|
||||
PrivateKey privateKey = wechatMetaBean.getKeyPair().getPrivate();
|
||||
|
||||
String subAppid = partnerPayParams.getSubAppid();
|
||||
String spAppid = partnerPayParams.getSpAppid();
|
||||
long epochSecond = LocalDateTime.now()
|
||||
.toEpochSecond(ZoneOffset.of("+8"));
|
||||
String timestamp = String.valueOf(epochSecond);
|
||||
@@ -138,9 +137,8 @@ public class WechatPartnerPayApi extends AbstractApi {
|
||||
.toString()
|
||||
.replaceAll("-", "");
|
||||
String packageStr = "prepay_id=" + body.get("prepay_id").asText();
|
||||
String paySign = signatureProvider.doRequestSign(privateKey, subAppid, timestamp, nonceStr, packageStr);
|
||||
|
||||
body.put("appId", subAppid);
|
||||
String paySign = signatureProvider.doRequestSign(privateKey, spAppid, timestamp, nonceStr, packageStr);
|
||||
body.put("appid", spAppid);
|
||||
body.put("timeStamp", timestamp);
|
||||
body.put("nonceStr", nonceStr);
|
||||
body.put("package", packageStr);
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -14,7 +13,6 @@
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package cn.felord.payment.wechat.v3;
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -14,7 +13,6 @@
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package cn.felord.payment.wechat.v3;
|
||||
|
||||
@@ -22,6 +20,7 @@ import cn.felord.payment.wechat.WechatPayProperties;
|
||||
import cn.felord.payment.wechat.enumeration.TarType;
|
||||
import cn.felord.payment.wechat.enumeration.WeChatServer;
|
||||
import cn.felord.payment.wechat.enumeration.WechatPayV3Type;
|
||||
import cn.felord.payment.wechat.v3.model.RefundParams;
|
||||
import cn.felord.payment.wechat.v3.model.payscore.*;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
@@ -248,21 +247,18 @@ public class WechatPayScoreApi extends AbstractApi {
|
||||
}
|
||||
|
||||
/**
|
||||
* 商户发起催收扣款API
|
||||
* 同步服务订单信息API
|
||||
* <p>
|
||||
* 前置条件:服务订单支付状态处于“待支付”状态
|
||||
* 前提条件:同步商户渠道收款成功信息时,即场景类型=“Order_Paid”,订单的状态需为[MCH_COMPLETE:商户完结订单]
|
||||
* <p>
|
||||
* 当微信支付分订单支付状态处于“待支付”时,商户可使用该接口向用户发起收款。
|
||||
* <p>
|
||||
* 注意:
|
||||
* • 此能力不影响微信支付分代商户向用户发起收款的策略。
|
||||
* 由于收款商户进行的某些“线下操作”会导致微信支付侧的订单状态与实际情况不符。例如,用户通过线下付款的方式已经完成支付,而微信支付侧并未支付成功,此时可能导致用户重复支付。因此商户需要通过订单同步接口将订单状态同步给微信支付,修改订单在微信支付系统中的状态。
|
||||
*
|
||||
* @param params the params
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> payServiceOrder(PayServiceOrderParams params) {
|
||||
public WechatResponseEntity<ObjectNode> syncServiceOrder(SyncServiceOrderParams params) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.PAY_SCORE_PAY_USER_SERVICE_ORDER, params)
|
||||
this.client().withType(WechatPayV3Type.PAY_SCORE_SYNC_USER_SERVICE_ORDER, params)
|
||||
.function((wechatPayV3Type, orderParams) -> {
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
@@ -280,18 +276,69 @@ public class WechatPayScoreApi extends AbstractApi {
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步服务订单信息API
|
||||
* 申请退款API
|
||||
*
|
||||
* @param refundParams the refund params
|
||||
* @return the wechat response entity
|
||||
* @since 1.0.17.RELEASE
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> refund(RefundParams refundParams) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.REFUND, refundParams)
|
||||
.function(((type, params) -> {
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.toUri();
|
||||
WechatPayProperties.V3 v3 = this.wechatMetaBean().getV3();
|
||||
String notifyUrl = params.getNotifyUrl();
|
||||
if (StringUtils.hasText(notifyUrl)) {
|
||||
params.setNotifyUrl(v3.getDomain().concat(notifyUrl));
|
||||
}
|
||||
return Post(uri, params);
|
||||
}))
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询单笔退款API
|
||||
*
|
||||
* @param outRefundNo the out refund no
|
||||
* @return the wechat response entity
|
||||
* @since 1.0.17.RELEASE
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> queryRefundInfo(String outRefundNo) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.QUERY_REFUND, outRefundNo)
|
||||
.function(((type, param) -> {
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.expand(param)
|
||||
.toUri();
|
||||
return Get(uri);
|
||||
}))
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 商户发起催收扣款API
|
||||
* <p>
|
||||
* 前提条件:同步商户渠道收款成功信息时,即场景类型=“Order_Paid”,订单的状态需为[MCH_COMPLETE:商户完结订单]
|
||||
* 前置条件:服务订单支付状态处于“待支付”状态
|
||||
* <p>
|
||||
* 由于收款商户进行的某些“线下操作”会导致微信支付侧的订单状态与实际情况不符。例如,用户通过线下付款的方式已经完成支付,而微信支付侧并未支付成功,此时可能导致用户重复支付。因此商户需要通过订单同步接口将订单状态同步给微信支付,修改订单在微信支付系统中的状态。
|
||||
* 当微信支付分订单支付状态处于“待支付”时,商户可使用该接口向用户发起收款。
|
||||
* <p>
|
||||
* 注意:
|
||||
* • 此能力不影响微信支付分代商户向用户发起收款的策略。
|
||||
*
|
||||
* @param params the params
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> syncServiceOrder(SyncServiceOrderParams params) {
|
||||
public WechatResponseEntity<ObjectNode> payServiceOrder(PayServiceOrderParams params) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.PAY_SCORE_SYNC_USER_SERVICE_ORDER, params)
|
||||
this.client().withType(WechatPayV3Type.PAY_SCORE_PAY_USER_SERVICE_ORDER, params)
|
||||
.function((wechatPayV3Type, orderParams) -> {
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
@@ -490,7 +537,7 @@ public class WechatPayScoreApi extends AbstractApi {
|
||||
queryParams.add("bill_date", billDate.format(DateTimeFormatter.ISO_DATE));
|
||||
queryParams.add("tar_type", TarType.GZIP.name());
|
||||
queryParams.add("encryption_algorithm", "AEAD_AES_256_GCM");
|
||||
queryParams.add("service_id",billParams.getServiceId());
|
||||
queryParams.add("service_id", billParams.getServiceId());
|
||||
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA))
|
||||
.queryParams(queryParams)
|
||||
|
||||
@@ -20,6 +20,7 @@ package cn.felord.payment.wechat.v3;
|
||||
import cn.felord.payment.wechat.WechatPayProperties;
|
||||
import cn.felord.payment.wechat.enumeration.WeChatServer;
|
||||
import cn.felord.payment.wechat.enumeration.WechatPayV3Type;
|
||||
import cn.felord.payment.wechat.v3.model.RefundParams;
|
||||
import cn.felord.payment.wechat.v3.model.ResponseSignVerifyParams;
|
||||
import cn.felord.payment.wechat.v3.model.payscore.parking.ParkingServiceQueryParams;
|
||||
import cn.felord.payment.wechat.v3.model.payscore.parking.ParkingParams;
|
||||
@@ -27,6 +28,7 @@ import cn.felord.payment.wechat.v3.model.payscore.parking.TransParkingParams;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
import java.net.URI;
|
||||
@@ -157,4 +159,53 @@ public class WechatPayScoreParkingApi extends AbstractApi {
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 申请退款API
|
||||
*
|
||||
* @param refundParams the refund params
|
||||
* @return the wechat response entity
|
||||
* @since 1.0.17.RELEASE
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> refund(RefundParams refundParams) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.REFUND, refundParams)
|
||||
.function(((type, params) -> {
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.toUri();
|
||||
WechatPayProperties.V3 v3 = this.wechatMetaBean().getV3();
|
||||
String notifyUrl = params.getNotifyUrl();
|
||||
if (StringUtils.hasText(notifyUrl)) {
|
||||
params.setNotifyUrl(v3.getDomain().concat(notifyUrl));
|
||||
}
|
||||
return Post(uri, params);
|
||||
}))
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 查询单笔退款API
|
||||
*
|
||||
* @param outRefundNo the out refund no
|
||||
* @return the wechat response entity
|
||||
* @since 1.0.17.RELEASE
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> queryRefundInfo(String outRefundNo) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.QUERY_REFUND, outRefundNo)
|
||||
.function(((type, param) -> {
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.expand(param)
|
||||
.toUri();
|
||||
return Get(uri);
|
||||
}))
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -14,7 +13,6 @@
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package cn.felord.payment.wechat.v3;
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -14,7 +13,6 @@
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package cn.felord.payment.wechat.v3;
|
||||
|
||||
|
||||
@@ -109,9 +109,9 @@ public class WechatSmartGuideApi extends AbstractApi {
|
||||
}
|
||||
|
||||
/**
|
||||
* 服务人员分配API
|
||||
* 服务人员查询API
|
||||
* <p>
|
||||
* 用于开发者在顾客下单后为顾客分配服务人员使用。
|
||||
* 用于商户开发者查询已注册的服务人员ID等信息。
|
||||
* <p>
|
||||
* 成功返回后请自行使用{@link SignatureProvider#decryptResponseMessage(String, String)}解密敏感字段。
|
||||
*
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* Website:
|
||||
* https://felord.cn
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package cn.felord.payment.wechat.v3.client;
|
||||
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
|
||||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||
import okhttp3.ConnectionPool;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.logging.HttpLoggingInterceptor;
|
||||
import retrofit2.Retrofit;
|
||||
import retrofit2.adapter.rxjava3.RxJava3CallAdapterFactory;
|
||||
import retrofit2.converter.jackson.JacksonConverterFactory;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* The type Retrofit factory.
|
||||
*
|
||||
* @author dax
|
||||
* @since 2023 /5/21
|
||||
*/
|
||||
public final class RetrofitFactory {
|
||||
|
||||
/**
|
||||
* The constant JACKSON_CONVERTER_FACTORY.
|
||||
*/
|
||||
public static final JacksonConverterFactory JACKSON_CONVERTER_FACTORY = JacksonConverterFactoryBuilder.build();
|
||||
|
||||
/**
|
||||
* Create retrofit.
|
||||
*
|
||||
* @param baseUrl the base url
|
||||
* @return the retrofit
|
||||
*/
|
||||
public static Retrofit create(String baseUrl) {
|
||||
return create(baseUrl, new ConnectionPool());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create retrofit.
|
||||
*
|
||||
* @param baseUrl the base url
|
||||
* @param connectionPool the connection pool
|
||||
* @return the retrofit
|
||||
*/
|
||||
public static Retrofit create(String baseUrl, ConnectionPool connectionPool) {
|
||||
return create(baseUrl, connectionPool, HttpLoggingInterceptor.Level.NONE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create retrofit.
|
||||
*
|
||||
* @param baseUrl the base url
|
||||
* @param connectionPool the connection pool
|
||||
* @param level the level
|
||||
* @return the retrofit
|
||||
*/
|
||||
public static Retrofit create(String baseUrl, ConnectionPool connectionPool, HttpLoggingInterceptor.Level level) {
|
||||
return new Retrofit.Builder()
|
||||
.baseUrl(baseUrl)
|
||||
.client(okHttpClient(connectionPool, level))
|
||||
.addCallAdapterFactory(RxJava3CallAdapterFactory.create())
|
||||
.addConverterFactory(JACKSON_CONVERTER_FACTORY)
|
||||
.build();
|
||||
}
|
||||
|
||||
private static OkHttpClient okHttpClient(ConnectionPool connectionPool, HttpLoggingInterceptor.Level level) {
|
||||
HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();
|
||||
httpLoggingInterceptor.level(level);
|
||||
return new OkHttpClient.Builder()
|
||||
.connectionPool(connectionPool)
|
||||
.addInterceptor(httpLoggingInterceptor)
|
||||
.retryOnConnectionFailure(true)
|
||||
.connectTimeout(30, TimeUnit.SECONDS)
|
||||
.readTimeout(30, TimeUnit.SECONDS)
|
||||
.writeTimeout(30, TimeUnit.SECONDS)
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The type Jackson converter factory builder.
|
||||
*/
|
||||
static final class JacksonConverterFactoryBuilder {
|
||||
private JacksonConverterFactoryBuilder() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Build jackson converter factory.
|
||||
*
|
||||
* @return the jackson converter factory
|
||||
*/
|
||||
public static JacksonConverterFactory build() {
|
||||
ObjectMapper objectMapper = new ObjectMapper().setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE)
|
||||
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
|
||||
// empty string error
|
||||
.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true)
|
||||
.setSerializationInclusion(JsonInclude.Include.NON_NULL)
|
||||
.registerModule(new JavaTimeModule());
|
||||
return JacksonConverterFactory.create(objectMapper);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,9 +20,11 @@ package cn.felord.payment.wechat.v3.model;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.OffsetDateTime;
|
||||
|
||||
/**
|
||||
* The type Abstract pay params.
|
||||
*
|
||||
* @author felord.cn
|
||||
* @since 1.0.8.RELEASE
|
||||
*/
|
||||
@@ -42,8 +44,8 @@ public abstract class AbstractPayParams {
|
||||
/**
|
||||
* 订单失效时间 rfc 3339 YYYY-MM-DDTHH:mm:ss+TIMEZONE
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssXXX", timezone = "GMT+8")
|
||||
private LocalDateTime timeExpire;
|
||||
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssXXX")
|
||||
private OffsetDateTime timeExpire;
|
||||
/**
|
||||
* 附加数据,在查询API和支付通知中原样返回,可作为自定义参数使用
|
||||
*/
|
||||
@@ -68,6 +70,13 @@ public abstract class AbstractPayParams {
|
||||
* 支付者 JSAPI/小程序下单 必传
|
||||
*/
|
||||
private Payer payer;
|
||||
/**
|
||||
* 电子发票入口开放标识
|
||||
* <p>
|
||||
* 传入{@code true}时,支付成功消息和支付详情页将出现开票入口。需要在微信支付商户平台或微信公众平台开通电子发票功能,传此字段才可生效。
|
||||
* @since 1.0.16.RELEASE
|
||||
*/
|
||||
private Boolean supportFapiao;
|
||||
/**
|
||||
* 场景信息
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -14,7 +13,6 @@
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package cn.felord.payment.wechat.v3.model;
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -14,7 +13,6 @@
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package cn.felord.payment.wechat.v3.model;
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -14,7 +13,6 @@
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package cn.felord.payment.wechat.v3.model;
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -14,7 +13,6 @@
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package cn.felord.payment.wechat.v3.model;
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -14,7 +13,6 @@
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package cn.felord.payment.wechat.v3.model;
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -14,7 +13,6 @@
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package cn.felord.payment.wechat.v3.model;
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
||||
@@ -53,6 +53,6 @@ public class CouponsCardSendParams {
|
||||
/**
|
||||
* 请求发卡时间,由于系统限制,暂不支持传入早于当前时间24小时以上的时间进行发券请求。
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX", timezone = "GMT+8")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssXXX")
|
||||
private OffsetDateTime sendTime;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -14,7 +13,6 @@
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package cn.felord.payment.wechat.v3.model;
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -14,7 +13,6 @@
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package cn.felord.payment.wechat.v3.model;
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -14,7 +13,6 @@
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package cn.felord.payment.wechat.v3.model;
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -14,7 +13,6 @@
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package cn.felord.payment.wechat.v3.model;
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -14,7 +13,6 @@
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package cn.felord.payment.wechat.v3.model;
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -14,7 +13,6 @@
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package cn.felord.payment.wechat.v3.model;
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -14,7 +13,6 @@
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package cn.felord.payment.wechat.v3.model;
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -14,7 +13,6 @@
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package cn.felord.payment.wechat.v3.model;
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -14,7 +13,6 @@
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package cn.felord.payment.wechat.v3.model;
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -14,7 +13,6 @@
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package cn.felord.payment.wechat.v3.model;
|
||||
|
||||
@@ -33,7 +31,7 @@ public class PatternInfo {
|
||||
/**
|
||||
* 背景色
|
||||
*/
|
||||
private CouponBgColor backgroundColor;
|
||||
private String backgroundColor;
|
||||
/**
|
||||
* 券详情图片
|
||||
*/
|
||||
@@ -51,4 +49,16 @@ public class PatternInfo {
|
||||
*/
|
||||
private String merchantName;
|
||||
|
||||
/**
|
||||
* Sets background color.
|
||||
*
|
||||
* @param backgroundColor the background color
|
||||
*/
|
||||
public void setBackgroundColor(CouponBgColor backgroundColor) {
|
||||
this.backgroundColor = backgroundColor.name();
|
||||
}
|
||||
|
||||
private void setBackgroundColor(String backgroundColor) {
|
||||
this.backgroundColor = backgroundColor;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -14,7 +13,6 @@
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package cn.felord.payment.wechat.v3.model;
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -14,7 +13,6 @@
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package cn.felord.payment.wechat.v3.model;
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -14,7 +13,6 @@
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package cn.felord.payment.wechat.v3.model;
|
||||
|
||||
@@ -22,7 +20,7 @@ import cn.felord.payment.wechat.v3.model.profitsharing.Receiver;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.OffsetDateTime;
|
||||
|
||||
/**
|
||||
* 微信支付分账通知参数
|
||||
@@ -79,7 +77,7 @@ public class ProfitSharingConsumeData {
|
||||
* <p>
|
||||
* Rfc3339标准
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssXXX", timezone = "GMT+8")
|
||||
private LocalDateTime successTime;
|
||||
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssXXX")
|
||||
private OffsetDateTime successTime;
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -14,7 +13,6 @@
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package cn.felord.payment.wechat.v3.model;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user