Merge pull request #93 from NotFound403/1.0.17

1.0.17
This commit is contained in:
felord.cn
2023-02-25 16:41:16 +08:00
committed by GitHub
32 changed files with 495 additions and 201 deletions

View File

@@ -1,4 +1,3 @@
<div align="center" style="margin-bottom: 10px"><h1>最全最好用的微信支付V3 Spring Boot 组件</h1></div> <div align="center" style="margin-bottom: 10px"><h1>最全最好用的微信支付V3 Spring Boot 组件</h1></div>
<p align="center"> <p align="center">
@@ -33,22 +32,26 @@
## 简介 ## 简介
Java微信支付V3支付Spring Boot Starter支持微信优惠券代金券、商家券、智慧商圈、商家转账到零钱、公众号支付、微信小程序支付、分账、支付分、商家券、合单支付、先享卡、电商收付通等全部微信支付功能API同时满足多个服务商、多个商户开发需求。一键集成屏蔽了复杂度API友好上手快欢迎star。 Java微信支付V3支付Spring Boot
Starter支持微信优惠券代金券、商家券、智慧商圈、商家转账到零钱、公众号支付、微信小程序支付、分账、支付分、商家券、合单支付、先享卡、电商收付通等全部微信支付功能API同时满足多个服务商、多个商户开发需求。一键集成屏蔽了复杂度API友好上手快欢迎star。
## Maven 最新中央仓库坐标 ## Maven 最新中央仓库坐标
```xml ```xml
<dependency> <dependency>
<groupId>cn.felord</groupId> <groupId>cn.felord</groupId>
<artifactId>payment-spring-boot-starter</artifactId> <artifactId>payment-spring-boot-starter</artifactId>
<version>1.0.16.RELEASE</version> <version>1.0.17.RELEASE</version>
</dependency> </dependency>
``` ```
## JDK问题 ## JDK问题
**推荐使用Open JDK**,原因参见[FBI Warning](https://github.com/NotFound403/payment-spring-boot/issues/5) **推荐使用Open JDK**,原因参见[FBI Warning](https://github.com/NotFound403/payment-spring-boot/issues/5)
## 文档地址 ## 文档地址
- [payment-spring-boot GitHub文档](https://notfound403.github.io/payment-spring-boot) - [payment-spring-boot GitHub文档](https://notfound403.github.io/payment-spring-boot)
## 目前已经实现所有服务商和直连商户接口 ## 目前已经实现所有服务商和直连商户接口
@@ -65,39 +68,27 @@ Java微信支付V3支付Spring Boot Starter支持微信优惠券代金券
更新日志参考[changelog](https://notfound403.github.io/payment-spring-boot/#/changelog) 更新日志参考[changelog](https://notfound403.github.io/payment-spring-boot/#/changelog)
## 核心API结构 ## API清单
![](https://asset.felord.cn/blog/20220613092244.png)
- `WechatPartnerProfitsharingApi` 微信支付服务商V3分账 API结构如下
- `WechatBrandProfitsharingApi` 微信支付服务商V3连锁品牌分账 ![](https://asset.felord.cn/blog/20220613092244.png)
- `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` 服务商-经营能力-点金计划
> 随着版本迭代功能会增加可通过API注册表类`WechatPayV3Type`进行API接口检索。 > 随着版本迭代功能会增加可通过API注册表类`WechatPayV3Type`进行API接口检索。
## 使用入门 ## 使用入门
### 集成配置 ### 集成配置
关于集成配置请详细阅读[payment-spring-boot GitHub文档](https://notfound403.github.io/payment-spring-boot)中[快速接入](https://notfound403.github.io/payment-spring-boot/#/quick_start)章节
关于集成配置请详细阅读[payment-spring-boot GitHub文档](https://notfound403.github.io/payment-spring-boot)
中[快速接入](https://notfound403.github.io/payment-spring-boot/#/quick_start)章节
### 调用示例 ### 调用示例
#### 开启支付 #### 开启支付
需要手动通过`@EnableMobilePay`注解开启支付 需要手动通过`@EnableMobilePay`注解开启支付
```java ```java
import cn.felord.payment.autoconfigure.EnableMobilePay; import cn.felord.payment.autoconfigure.EnableMobilePay;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
@@ -109,7 +100,9 @@ public class PayConfig {
``` ```
#### 支付接口调用 #### 支付接口调用
这里简单以小程序支付为例写了一个Spring MVC 控制器,在实践中建议对`WechatApiProvider`进行二次封装作服务层调用 这里简单以小程序支付为例写了一个Spring MVC 控制器,在实践中建议对`WechatApiProvider`进行二次封装作服务层调用
```java ```java
import cn.felord.payment.wechat.enumeration.TradeBillType; import cn.felord.payment.wechat.enumeration.TradeBillType;
import cn.felord.payment.wechat.v3.WechatApiProvider; import cn.felord.payment.wechat.v3.WechatApiProvider;
@@ -135,6 +128,7 @@ public class PayController {
@Autowired @Autowired
private WechatApiProvider wechatApiProvider; private WechatApiProvider wechatApiProvider;
String TENANT_ID = "mobile"; String TENANT_ID = "mobile";
/** /**
* 总流程建议为 生成商品订单 -> 生成对应的支付订单 -> 支付操作 -> 支付结果回调更新 -> 结束 * 总流程建议为 生成商品订单 -> 生成对应的支付订单 -> 支付操作 -> 支付结果回调更新 -> 结束
* <p> * <p>
@@ -213,7 +207,9 @@ public class PayController {
} }
} }
``` ```
#### 回调示例 #### 回调示例
回调可通过以下示例实现多租户的回调可将租户ID`tenantId`作为路径参数来实现 回调可通过以下示例实现多租户的回调可将租户ID`tenantId`作为路径参数来实现
```java ```java
@@ -248,7 +244,7 @@ import java.util.stream.Collectors;
* @author felord.cn * @author felord.cn
* @since 1.0.0.RELEASE * @since 1.0.0.RELEASE
*/ */
@Profile({"wechat","dev"}) @Profile({"wechat", "dev"})
@RestController @RestController
@RequestMapping("/wxpay/callbacks") @RequestMapping("/wxpay/callbacks")
public class CallbackController { public class CallbackController {
@@ -358,16 +354,17 @@ public class CallbackController {
} }
``` ```
## 开源协议 ## 开源协议
**Apache 2.0** **Apache 2.0**
## 仓库地址 ## 仓库地址
- [GitHub](https://github.com/NotFound403/payment-spring-boot) - [GitHub](https://github.com/NotFound403/payment-spring-boot)
- [Gitee](https://gitee.com/felord/payment-spring-boot) - [Gitee](https://gitee.com/felord/payment-spring-boot)
## QQ交流群 ## QQ交流群
为了交流解惑新建QQ群可通过扫码进入。 为了交流解惑新建QQ群可通过扫码进入。
![QQ交流群](./docs/img/qqun.png) ![QQ交流群](./docs/img/qqun.png)

View File

@@ -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"> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!-- NewPage --> <!-- NewPage -->
<html lang="zh"> <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> <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">选填 <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> </td>
</tr> </tr>
<tr class="rowColor"> <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> <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">选填 <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> </td>
</tr> </tr>
<tr class="altColor"> <tr class="altColor">
@@ -252,7 +269,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
<pre>private&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/time/OffsetDateTime.html?is-external=true" title="java.time中的类或接口">OffsetDateTime</a> createStartTime</pre> <pre>private&nbsp;<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">选填 <div class="block">选填
<p> <p>
起始时间 最终满足格式 <code>yyyy-MM-dd'T'HH:mm:ss.SSSXXX</code></div> 起始时间 最终满足格式 <code>yyyy-MM-dd'T'HH:mm:ssXXX</code></div>
</li> </li>
</ul> </ul>
<a name="createEndTime"> <a name="createEndTime">
@@ -264,7 +281,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
<pre>private&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/time/OffsetDateTime.html?is-external=true" title="java.time中的类或接口">OffsetDateTime</a> createEndTime</pre> <pre>private&nbsp;<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">选填 <div class="block">选填
<p> <p>
终止时间 最终满足格式 <code>yyyy-MM-dd'T'HH:mm:ss.SSSXXX</code></div> 终止时间 最终满足格式 <code>yyyy-MM-dd'T'HH:mm:ssXXX</code></div>
</li> </li>
</ul> </ul>
<a name="status"> <a name="status">

View File

@@ -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"> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!-- NewPage --> <!-- NewPage -->
<html lang="zh"> <html lang="zh">
@@ -1780,7 +1797,7 @@
<dd> <dd>
<div class="block">选填 <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> </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> <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> <dd>
@@ -1796,7 +1813,7 @@
<dd> <dd>
<div class="block">选填 <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> </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> <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> <dd>

View File

@@ -35,7 +35,7 @@
<dependency> <dependency>
<groupId>cn.felord</groupId> <groupId>cn.felord</groupId>
<artifactId>payment-spring-boot-starter</artifactId> <artifactId>payment-spring-boot-starter</artifactId>
<version>1.0.16.RELEASE</version> <version>1.0.17.RELEASE</version>
</dependency> </dependency>
``` ```
## 采用技术 ## 采用技术

View File

@@ -4,7 +4,7 @@
<dependency> <dependency>
<groupId>cn.felord</groupId> <groupId>cn.felord</groupId>
<artifactId>payment-spring-boot-starter</artifactId> <artifactId>payment-spring-boot-starter</artifactId>
<version>1.0.16.RELEASE</version> <version>1.0.17.RELEASE</version>
</dependency> </dependency>
``` ```
> 基于 **Spring Boot 2.x** > 基于 **Spring Boot 2.x**

View File

@@ -1,112 +1,227 @@
## 入口类 ## 入口类
`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` APP下单
- [x] `appPay` JSAPI/小程序下单
- [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` 合单APP下单
- [x] `appPay` 合单JSAPI/小程序下单
- [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)` - [ ] 功能实现中……
#### 下载批次核销明细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` 查询转账账单电子回单接口
- [x] 申请转账电子回单
1. `` 转账账单电子回单申请受理接口
2. `` 查询转账账单电子回单接口
### 普通支付-直连模式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)`

View File

@@ -22,11 +22,11 @@
<parent> <parent>
<groupId>cn.felord</groupId> <groupId>cn.felord</groupId>
<artifactId>payment-spring-boot</artifactId> <artifactId>payment-spring-boot</artifactId>
<version>1.0.16.RELEASE</version> <version>1.0.17.RELEASE</version>
</parent> </parent>
<artifactId>payment-spring-boot-autoconfigure</artifactId> <artifactId>payment-spring-boot-autoconfigure</artifactId>
<version>1.0.16.RELEASE</version> <version>1.0.17.RELEASE</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@@ -103,7 +103,7 @@ public class WechatBatchTransferApi extends AbstractApi {
} }
/** /**
* 微信批次单号查询批次单API * 通过微信批次单号查询批次单API
* *
* @param queryBatchTransferParams the queryBatchTransferParams * @param queryBatchTransferParams the queryBatchTransferParams
* @return the wechat response entity * @return the wechat response entity
@@ -132,33 +132,7 @@ 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 queryBatchTransferParams the queryBatchTransferParams * @param queryBatchTransferParams the queryBatchTransferParams
* @return the wechat response entity * @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 * @param queryBatchTransferDetailParams the queryBatchTransferDetailParams
* @return the wechat response entity * @return the wechat response entity
@@ -260,7 +260,7 @@ public class WechatBatchTransferApi extends AbstractApi {
} }
/** /**
* 转账明细电子回单受理API * 受理转账明细电子回单API
* <p> * <p>
* 受理转账明细电子回单接口,商户通过该接口可以申请受理转账明细单电子回单服务。 * 受理转账明细电子回单接口,商户通过该接口可以申请受理转账明细单电子回单服务。
* <p> * <p>

View File

@@ -209,4 +209,26 @@ public class WechatCombinePayApi extends AbstractApi {
.request(); .request();
return wechatResponseEntity; 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;
}
} }

View File

@@ -545,13 +545,17 @@ public class WechatMarketingFavorApi extends AbstractApi {
/** /**
* 营销图片上传API * 营销图片上传API
* <p> * <p>
* 该接口标记过时,用{@link WechatMediaApi#marketingImageUpload(MultipartFile)}代替
* <p>
* 媒体图片只支持JPG、BMP、PNG格式文件大小不能超过2M。 * 媒体图片只支持JPG、BMP、PNG格式文件大小不能超过2M。
* <p> * <p>
* 通过本接口上传图片后可获得图片url地址。图片url可在微信支付营销相关的API使用包括商家券、代金券、支付有礼等。 * 通过本接口上传图片后可获得图片url地址。图片url可在微信支付营销相关的API使用包括商家券、代金券、支付有礼等。
* *
* @param file the file * @param file the file
* @return the wechat response entity * @return the wechat response entity
* @see WechatMediaApi#marketingImageUpload(MultipartFile)
*/ */
@Deprecated
public WechatResponseEntity<ObjectNode> marketingImageUpload(MultipartFile file) { public WechatResponseEntity<ObjectNode> marketingImageUpload(MultipartFile file) {
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>(); WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
this.client().withType(WechatPayV3Type.MARKETING_IMAGE_UPLOAD, file) this.client().withType(WechatPayV3Type.MARKETING_IMAGE_UPLOAD, file)

View File

@@ -82,6 +82,7 @@ public class WechatMediaApi extends AbstractApi {
.request(); .request();
return wechatResponseEntity; return wechatResponseEntity;
} }
@SneakyThrows @SneakyThrows
private RequestEntity<?> uploadFunction(WechatPayV3Type type, MultipartFile file) { private RequestEntity<?> uploadFunction(WechatPayV3Type type, MultipartFile file) {
@@ -108,4 +109,24 @@ public class WechatMediaApi extends AbstractApi {
.header("Pay-TenantId", tenantId()) .header("Pay-TenantId", tenantId())
.body(body); .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;
}
} }

View File

@@ -20,6 +20,7 @@ import cn.felord.payment.wechat.WechatPayProperties;
import cn.felord.payment.wechat.enumeration.TarType; import cn.felord.payment.wechat.enumeration.TarType;
import cn.felord.payment.wechat.enumeration.WeChatServer; import cn.felord.payment.wechat.enumeration.WeChatServer;
import cn.felord.payment.wechat.enumeration.WechatPayV3Type; import cn.felord.payment.wechat.enumeration.WechatPayV3Type;
import cn.felord.payment.wechat.v3.model.RefundParams;
import cn.felord.payment.wechat.v3.model.payscore.*; import cn.felord.payment.wechat.v3.model.payscore.*;
import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.ObjectNode;
import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.LinkedMultiValueMap;
@@ -246,21 +247,18 @@ public class WechatPayScoreApi extends AbstractApi {
} }
/** /**
* 商户发起催收扣款API * 同步服务订单信息API
* <p> * <p>
* 前条件:服务订单支付状态处于“待支付”状态 * 前条件:同步商户渠道收款成功信息时,即场景类型=“Order_Paid”订单的状态需为[MCH_COMPLETE:商户完结订单]
* <p> * <p>
* 当微信支付分订单支付状态处于“待支付”时,商户可使用该接口向用户发起收款 * 由于收款商户进行的某些“线下操作”会导致微信支付侧的订单状态与实际情况不符。例如,用户通过线下付款的方式已经完成支付,而微信支付侧并未支付成功,此时可能导致用户重复支付。因此商户需要通过订单同步接口将订单状态同步给微信支付,修改订单在微信支付系统中的状态
* <p>
* 注意:
* • 此能力不影响微信支付分代商户向用户发起收款的策略。
* *
* @param params the params * @param params the params
* @return the wechat response entity * @return the wechat response entity
*/ */
public WechatResponseEntity<ObjectNode> payServiceOrder(PayServiceOrderParams params) { public WechatResponseEntity<ObjectNode> syncServiceOrder(SyncServiceOrderParams params) {
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>(); 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) -> { .function((wechatPayV3Type, orderParams) -> {
URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA)) URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA))
.build() .build()
@@ -278,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> * <p>
* 前条件:同步商户渠道收款成功信息时,即场景类型=“Order_Paid”订单的状态需为[MCH_COMPLETE:商户完结订单] * 前条件:服务订单支付状态处于“待支付”状态
* <p> * <p>
* 由于收款商户进行的某些“线下操作”会导致微信支付侧的订单状态与实际情况不符。例如,用户通过线下付款的方式已经完成支付,而微信支付侧并未支付成功,此时可能导致用户重复支付。因此商户需要通过订单同步接口将订单状态同步给微信支付,修改订单在微信支付系统中的状态 * 当微信支付分订单支付状态处于“待支付”时,商户可使用该接口向用户发起收款
* <p>
* 注意:
* • 此能力不影响微信支付分代商户向用户发起收款的策略。
* *
* @param params the params * @param params the params
* @return the wechat response entity * @return the wechat response entity
*/ */
public WechatResponseEntity<ObjectNode> syncServiceOrder(SyncServiceOrderParams params) { public WechatResponseEntity<ObjectNode> payServiceOrder(PayServiceOrderParams params) {
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>(); 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) -> { .function((wechatPayV3Type, orderParams) -> {
URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA)) URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA))
.build() .build()
@@ -488,7 +537,7 @@ public class WechatPayScoreApi extends AbstractApi {
queryParams.add("bill_date", billDate.format(DateTimeFormatter.ISO_DATE)); queryParams.add("bill_date", billDate.format(DateTimeFormatter.ISO_DATE));
queryParams.add("tar_type", TarType.GZIP.name()); queryParams.add("tar_type", TarType.GZIP.name());
queryParams.add("encryption_algorithm", "AEAD_AES_256_GCM"); 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)) URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA))
.queryParams(queryParams) .queryParams(queryParams)

View File

@@ -20,6 +20,7 @@ package cn.felord.payment.wechat.v3;
import cn.felord.payment.wechat.WechatPayProperties; import cn.felord.payment.wechat.WechatPayProperties;
import cn.felord.payment.wechat.enumeration.WeChatServer; import cn.felord.payment.wechat.enumeration.WeChatServer;
import cn.felord.payment.wechat.enumeration.WechatPayV3Type; 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.ResponseSignVerifyParams;
import cn.felord.payment.wechat.v3.model.payscore.parking.ParkingServiceQueryParams; import cn.felord.payment.wechat.v3.model.payscore.parking.ParkingServiceQueryParams;
import cn.felord.payment.wechat.v3.model.payscore.parking.ParkingParams; 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 com.fasterxml.jackson.databind.node.ObjectNode;
import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap; import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;
import org.springframework.web.util.UriComponentsBuilder; import org.springframework.web.util.UriComponentsBuilder;
import java.net.URI; import java.net.URI;
@@ -157,4 +159,53 @@ public class WechatPayScoreParkingApi extends AbstractApi {
.request(); .request();
return wechatResponseEntity; 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;
}
} }

View File

@@ -109,9 +109,9 @@ public class WechatSmartGuideApi extends AbstractApi {
} }
/** /**
* 服务人员分配API * 服务人员查询API
* <p> * <p>
* 用于开发者在顾客下单后为顾客分配服务人员使用 * 用于商户开发者查询已注册的服务人员ID等信息
* <p> * <p>
* 成功返回后请自行使用{@link SignatureProvider#decryptResponseMessage(String, String)}解密敏感字段。 * 成功返回后请自行使用{@link SignatureProvider#decryptResponseMessage(String, String)}解密敏感字段。
* *

View File

@@ -20,7 +20,7 @@ package cn.felord.payment.wechat.v3.model;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data; import lombok.Data;
import java.time.LocalDateTime; import java.time.OffsetDateTime;
/** /**
* The type Abstract pay params. * The type Abstract pay params.
@@ -44,8 +44,8 @@ public abstract class AbstractPayParams {
/** /**
* 订单失效时间 rfc 3339 YYYY-MM-DDTHH:mm:ss+TIMEZONE * 订单失效时间 rfc 3339 YYYY-MM-DDTHH:mm:ss+TIMEZONE
*/ */
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssXXX", timezone = "GMT+8") @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssXXX")
private LocalDateTime timeExpire; private OffsetDateTime timeExpire;
/** /**
* 附加数据在查询API和支付通知中原样返回可作为自定义参数使用 * 附加数据在查询API和支付通知中原样返回可作为自定义参数使用
*/ */

View File

@@ -53,6 +53,6 @@ public class CouponsCardSendParams {
/** /**
* 请求发卡时间,由于系统限制暂不支持传入早于当前时间24小时以上的时间进行发券请求。 * 请求发卡时间,由于系统限制暂不支持传入早于当前时间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; private OffsetDateTime sendTime;
} }

View File

@@ -20,7 +20,7 @@ import cn.felord.payment.wechat.v3.model.profitsharing.Receiver;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data; import lombok.Data;
import java.time.LocalDateTime; import java.time.OffsetDateTime;
/** /**
* 微信支付分账通知参数 * 微信支付分账通知参数
@@ -77,7 +77,7 @@ public class ProfitSharingConsumeData {
* <p> * <p>
* Rfc3339标准 * Rfc3339标准
*/ */
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssXXX", timezone = "GMT+8") @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssXXX")
private LocalDateTime successTime; private OffsetDateTime successTime;
} }

View File

@@ -20,7 +20,7 @@ import cn.felord.payment.wechat.enumeration.RefundStatus;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data; import lombok.Data;
import java.time.LocalDateTime; import java.time.OffsetDateTime;
/** /**
* 微信支付退款结果通知解密 * 微信支付退款结果通知解密
@@ -57,8 +57,8 @@ public class RefundConsumeData {
/** /**
* 退款成功时间 * 退款成功时间
*/ */
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssXXX", timezone = "GMT+8") @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssXXX")
private LocalDateTime successTime; private OffsetDateTime successTime;
/** /**
* 退款入账账户 * 退款入账账户
*/ */

View File

@@ -45,12 +45,12 @@ public class StocksCreateParams {
/** /**
* 批次开始时间 rfc 3339 yyyy-MM-ddTHH:mm:ss.sss+TIMEZONE * 批次开始时间 rfc 3339 yyyy-MM-ddTHH:mm:ss.sss+TIMEZONE
*/ */
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX", timezone = "GMT+8") @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssXXX")
private OffsetDateTime availableBeginTime; private OffsetDateTime availableBeginTime;
/** /**
* 批次结束时间 rfc 3339 yyyy-MM-ddTHH:mm:ss.sss+TIMEZONE * 批次结束时间 rfc 3339 yyyy-MM-ddTHH:mm:ss.sss+TIMEZONE
*/ */
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX", timezone = "GMT+8") @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssXXX")
private OffsetDateTime availableEndTime; private OffsetDateTime availableEndTime;
/** /**
* 可创建代金券的类型包含预充值和免充值两种类型。此字段用来标识制券 <strong>是否无资金流</strong> * 可创建代金券的类型包含预充值和免充值两种类型。此字段用来标识制券 <strong>是否无资金流</strong>

View File

@@ -46,13 +46,13 @@ public class StocksQueryParams {
/** /**
* 选填 * 选填
* <p> * <p>
* 起始时间 最终满足格式 {@code yyyy-MM-dd'T'HH:mm:ss.SSSXXX} * 起始时间 最终满足格式 {@code yyyy-MM-dd'T'HH:mm:ssXXX}
*/ */
private OffsetDateTime createStartTime; private OffsetDateTime createStartTime;
/** /**
* 选填 * 选填
* <p> * <p>
* 终止时间 最终满足格式 {@code yyyy-MM-dd'T'HH:mm:ss.SSSXXX} * 终止时间 最终满足格式 {@code yyyy-MM-dd'T'HH:mm:ssXXX}
*/ */
private OffsetDateTime createEndTime; private OffsetDateTime createEndTime;
/** /**

View File

@@ -21,7 +21,7 @@ import cn.felord.payment.wechat.enumeration.TradeType;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data; import lombok.Data;
import java.time.LocalDateTime; import java.time.OffsetDateTime;
import java.util.List; import java.util.List;
/** /**
@@ -88,8 +88,8 @@ public class TransactionConsumeData {
/** /**
* 支付完成时间 YYYY-MM-DDTHH:mm:ss+TIMEZONE * 支付完成时间 YYYY-MM-DDTHH:mm:ss+TIMEZONE
*/ */
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssXXX", timezone = "GMT+8") @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssXXX")
private LocalDateTime successTime; private OffsetDateTime successTime;
/** /**
* 在 1.0.0.RELEASE 直接返回了枚举字符串1.0.2.RELEASE 中变更为枚举 * 在 1.0.0.RELEASE 直接返回了枚举字符串1.0.2.RELEASE 中变更为枚举
* *

View File

@@ -20,7 +20,7 @@ package cn.felord.payment.wechat.v3.model.busifavor;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data; import lombok.Data;
import java.time.LocalDateTime; import java.time.OffsetDateTime;
/** /**
* 商家券领券事件回调通知解密 * 商家券领券事件回调通知解密
@@ -49,8 +49,8 @@ public class BusiFavorReceiveConsumeData {
/** /**
* 发放时间 rfc 3339 yyyy-MM-ddTHH:mm:ss+TIMEZONE * 发放时间 rfc 3339 yyyy-MM-ddTHH:mm:ss+TIMEZONE
*/ */
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssXXX", timezone = "GMT+8") @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssXXX")
private LocalDateTime sendTime; private OffsetDateTime sendTime;
/** /**
* 微信用户在appid下的唯一标识。 * 微信用户在appid下的唯一标识。
*/ */

View File

@@ -19,7 +19,7 @@ package cn.felord.payment.wechat.v3.model.busifavor;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data; import lombok.Data;
import java.time.LocalDateTime; import java.time.OffsetDateTime;
/** /**
* 核销用户券请求参数 * 核销用户券请求参数
@@ -44,8 +44,8 @@ public class BusiFavorUseParams {
/** /**
* 请求核销时间 * 请求核销时间
*/ */
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssXXX", timezone = "GMT+8") @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssXXX")
private LocalDateTime useTime; private OffsetDateTime useTime;
/** /**
* 核销请求单据号,商户侧保证唯一 * 核销请求单据号,商户侧保证唯一
*/ */

View File

@@ -19,7 +19,7 @@ package cn.felord.payment.wechat.v3.model.busifavor;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data; import lombok.Data;
import java.time.LocalDateTime; import java.time.OffsetDateTime;
import java.util.List; import java.util.List;
/** /**
@@ -54,13 +54,13 @@ public class CouponAvailableTime {
/** /**
* 批次开始时间 rfc 3339 yyyy-MM-ddTHH:mm:ss+TIMEZONE * 批次开始时间 rfc 3339 yyyy-MM-ddTHH:mm:ss+TIMEZONE
*/ */
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssXXX", timezone = "GMT+8") @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssXXX")
private LocalDateTime availableBeginTime; private OffsetDateTime availableBeginTime;
/** /**
* 批次结束时间 rfc 3339 yyyy-MM-ddTHH:mm:ss+TIMEZONE * 批次结束时间 rfc 3339 yyyy-MM-ddTHH:mm:ss+TIMEZONE
*/ */
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssXXX", timezone = "GMT+8") @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssXXX")
private LocalDateTime availableEndTime; private OffsetDateTime availableEndTime;
/** /**
* 固定周期有效时间段 * 固定周期有效时间段
*/ */

View File

@@ -19,7 +19,8 @@ package cn.felord.payment.wechat.v3.model.busifavor;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data; import lombok.Data;
import java.time.LocalDateTime; import java.time.OffsetDateTime;
/** /**
* 商家券核销规则-券可核销时间-无规律的有效时间段 * 商家券核销规则-券可核销时间-无规律的有效时间段
* *
@@ -32,11 +33,11 @@ public class IrregularyAvaliableTimeItem{
/** /**
* 开始时间 * 开始时间
*/ */
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssXXX", timezone = "GMT+8") @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssXXX")
private LocalDateTime beginTime; private OffsetDateTime beginTime;
/** /**
* 结束时间 * 结束时间
*/ */
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssXXX", timezone = "GMT+8") @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssXXX")
private LocalDateTime endTime; private OffsetDateTime endTime;
} }

View File

@@ -64,12 +64,12 @@ public class CombineH5PayParams {
/** /**
* 交易起始时间,选填 * 交易起始时间,选填
*/ */
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX", timezone = "GMT+8") @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssXXX")
private OffsetDateTime timeStart; private OffsetDateTime timeStart;
/** /**
* 交易结束时间,选填 * 交易结束时间,选填
*/ */
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX", timezone = "GMT+8") @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssXXX")
private OffsetDateTime timeExpire; private OffsetDateTime timeExpire;
} }

View File

@@ -64,12 +64,12 @@ public class CombinePayParams {
/** /**
* 交易起始时间,选填 * 交易起始时间,选填
*/ */
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX", timezone = "GMT+8") @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssXXX")
private OffsetDateTime timeStart; private OffsetDateTime timeStart;
/** /**
* 交易结束时间,选填 * 交易结束时间,选填
*/ */
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX", timezone = "GMT+8") @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssXXX")
private OffsetDateTime timeExpire; private OffsetDateTime timeExpire;
} }

View File

@@ -21,7 +21,7 @@ import cn.felord.payment.wechat.enumeration.PlateColor;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data; import lombok.Data;
import java.time.LocalDateTime; import java.time.OffsetDateTime;
/** /**
* 创建停车入场API参数 * 创建停车入场API参数
@@ -58,8 +58,8 @@ public class ParkingParams {
* <p> * <p>
* 格式为yyyy-MM-DDTHH:mm:ss+TIMEZONE * 格式为yyyy-MM-DDTHH:mm:ss+TIMEZONE
*/ */
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssXXX", timezone = "GMT+8") @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssXXX")
private LocalDateTime startTime; private OffsetDateTime startTime;
/** /**
* 停车场名称,必传 * 停车场名称,必传
*/ */

View File

@@ -19,7 +19,7 @@ package cn.felord.payment.wechat.v3.model.profitsharing;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data; import lombok.Data;
import java.time.LocalDateTime; import java.time.OffsetDateTime;
import java.util.List; import java.util.List;
/** /**
@@ -75,7 +75,7 @@ public class PartnerProfitsharingConsumeData {
* <p> * <p>
* Rfc3339标准 * Rfc3339标准
*/ */
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssXXX", timezone = "GMT+8") @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssXXX")
private LocalDateTime successTime; private OffsetDateTime successTime;
} }

View File

@@ -19,7 +19,7 @@ package cn.felord.payment.wechat.v3.model.profitsharing;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data; import lombok.Data;
import java.time.LocalDateTime; import java.time.OffsetDateTime;
import java.util.List; import java.util.List;
/** /**
@@ -69,7 +69,7 @@ public class ProfitsharingConsumeData {
* <p> * <p>
* Rfc3339标准 * Rfc3339标准
*/ */
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssXXX", timezone = "GMT+8") @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssXXX")
private LocalDateTime successTime; private OffsetDateTime successTime;
} }

View File

@@ -22,11 +22,11 @@
<parent> <parent>
<groupId>cn.felord</groupId> <groupId>cn.felord</groupId>
<artifactId>payment-spring-boot</artifactId> <artifactId>payment-spring-boot</artifactId>
<version>1.0.16.RELEASE</version> <version>1.0.17.RELEASE</version>
</parent> </parent>
<artifactId>payment-spring-boot-starter</artifactId> <artifactId>payment-spring-boot-starter</artifactId>
<version>1.0.16.RELEASE</version> <version>1.0.17.RELEASE</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@@ -21,7 +21,7 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<groupId>cn.felord</groupId> <groupId>cn.felord</groupId>
<artifactId>payment-spring-boot</artifactId> <artifactId>payment-spring-boot</artifactId>
<version>1.0.16.RELEASE</version> <version>1.0.17.RELEASE</version>
<packaging>pom</packaging> <packaging>pom</packaging>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>