mirror of
https://github.com/dromara/payment-spring-boot.git
synced 2026-03-14 05:43:46 +08:00
Compare commits
51 Commits
1.0.13.REL
...
1.0.15.REL
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4dea6b0afe | ||
|
|
379d007bb4 | ||
|
|
de3cf3d2ae | ||
|
|
9d2f8a7d72 | ||
|
|
e1ec5f1b7c | ||
|
|
d8288cdd3a | ||
|
|
113e531eae | ||
|
|
d91b52ba2b | ||
|
|
1742437c2c | ||
|
|
2f391cc14c | ||
|
|
31bef5bfac | ||
|
|
5d1fd73f2b | ||
|
|
18b6615c44 | ||
|
|
0ebe58ae09 | ||
|
|
2f69023ffd | ||
|
|
a11aae69c3 | ||
|
|
2c28113ee7 | ||
|
|
05a3e83e3e | ||
|
|
2f7e6c6b22 | ||
|
|
9b4193a4f9 | ||
|
|
6e4bfd2192 | ||
|
|
e412760a8e | ||
|
|
02867baa2c | ||
|
|
4c21329ceb | ||
|
|
e1616c5606 | ||
|
|
34d0bed373 | ||
|
|
575bf6e8a2 | ||
|
|
f73be6452e | ||
|
|
a9ab004a96 | ||
|
|
24f270acd6 | ||
|
|
0145a343f9 | ||
|
|
0dd7ca97f7 | ||
|
|
5ef0ff0c85 | ||
|
|
af3ee97c33 | ||
|
|
796cb4c921 | ||
|
|
28b4c9c7a6 | ||
|
|
91597b90ac | ||
|
|
1acdf629d8 | ||
|
|
d8ec62c293 | ||
|
|
37fc29a02c | ||
|
|
8e9f704b89 | ||
|
|
d8ada58822 | ||
|
|
89f12df44a | ||
|
|
0027e6f934 | ||
|
|
565f27988d | ||
|
|
5e050ddbcb | ||
|
|
5a46bbc0a4 | ||
|
|
14553f9ba7 | ||
|
|
ebfc54d1db | ||
|
|
e59c8f4b16 | ||
|
|
a1071d2f86 |
81
.github/workflows/codesee-arch-diagram.yml
vendored
Normal file
81
.github/workflows/codesee-arch-diagram.yml
vendored
Normal file
@@ -0,0 +1,81 @@
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- release
|
||||
pull_request_target:
|
||||
types: [opened, synchronize, reopened]
|
||||
|
||||
name: CodeSee Map
|
||||
|
||||
jobs:
|
||||
test_map_action:
|
||||
runs-on: ubuntu-latest
|
||||
continue-on-error: true
|
||||
name: Run CodeSee Map Analysis
|
||||
steps:
|
||||
- name: checkout
|
||||
id: checkout
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
repository: ${{ github.event.pull_request.head.repo.full_name }}
|
||||
ref: ${{ github.event.pull_request.head.ref }}
|
||||
fetch-depth: 0
|
||||
|
||||
# codesee-detect-languages has an output with id languages.
|
||||
- name: Detect Languages
|
||||
id: detect-languages
|
||||
uses: Codesee-io/codesee-detect-languages-action@latest
|
||||
|
||||
- name: Configure JDK 16
|
||||
uses: actions/setup-java@v2
|
||||
if: ${{ fromJSON(steps.detect-languages.outputs.languages).java }}
|
||||
with:
|
||||
java-version: '16'
|
||||
distribution: 'zulu'
|
||||
|
||||
# CodeSee Maps Go support uses a static binary so there's no setup step required.
|
||||
|
||||
- name: Configure Node.js 14
|
||||
uses: actions/setup-node@v2
|
||||
if: ${{ fromJSON(steps.detect-languages.outputs.languages).javascript }}
|
||||
with:
|
||||
node-version: '14'
|
||||
|
||||
- name: Configure Python 3.x
|
||||
uses: actions/setup-python@v2
|
||||
if: ${{ fromJSON(steps.detect-languages.outputs.languages).python }}
|
||||
with:
|
||||
python-version: '3.10'
|
||||
architecture: 'x64'
|
||||
|
||||
- name: Configure Ruby '3.x'
|
||||
uses: ruby/setup-ruby@v1
|
||||
if: ${{ fromJSON(steps.detect-languages.outputs.languages).ruby }}
|
||||
with:
|
||||
ruby-version: '3.0'
|
||||
|
||||
# CodeSee Maps Rust support uses a static binary so there's no setup step required.
|
||||
|
||||
- name: Generate Map
|
||||
id: generate-map
|
||||
uses: Codesee-io/codesee-map-action@latest
|
||||
with:
|
||||
step: map
|
||||
github_ref: ${{ github.ref }}
|
||||
languages: ${{ steps.detect-languages.outputs.languages }}
|
||||
|
||||
- name: Upload Map
|
||||
id: upload-map
|
||||
uses: Codesee-io/codesee-map-action@latest
|
||||
with:
|
||||
step: mapUpload
|
||||
api_token: ${{ secrets.CODESEE_ARCH_DIAG_API_TOKEN }}
|
||||
github_ref: ${{ github.ref }}
|
||||
|
||||
- name: Insights
|
||||
id: insights
|
||||
uses: Codesee-io/codesee-map-action@latest
|
||||
with:
|
||||
step: insights
|
||||
api_token: ${{ secrets.CODESEE_ARCH_DIAG_API_TOKEN }}
|
||||
github_ref: ${{ github.ref }}
|
||||
31
README.md
31
README.md
@@ -1,4 +1,6 @@
|
||||
# 最好用的微信支付V3 Spring Boot 组件
|
||||
[](https://github.com/NotFound403/payment-spring-boot/actions/workflows/main.yml)
|
||||
|
||||
# 最好用的微信支付V3 Spring Boot 组件
|
||||
|
||||
为了满足业务中出现app支付、公众号支付、小程序支付等多appid并存的场景,对原有的进行了增强开发出了多租户版本。
|
||||
|
||||
@@ -11,11 +13,20 @@
|
||||
<dependency>
|
||||
<groupId>cn.felord</groupId>
|
||||
<artifactId>payment-spring-boot-starter</artifactId>
|
||||
<version>1.0.13.RELEASE</version>
|
||||
<version>1.0.15.RELEASE</version>
|
||||
</dependency>
|
||||
```
|
||||
## JDK问题
|
||||
|
||||
**推荐使用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 Gitee文档](https://felord.gitee.io/payment-spring-boot)
|
||||
|
||||
|
||||
## 目前已经实现所有服务商和直连商户接口
|
||||
|
||||
## 功能
|
||||
- 实现微信支付多商户
|
||||
- 集成支付宝SDK、快速接入Spring Boot
|
||||
- 实现微信支付V3 基础支付
|
||||
@@ -26,12 +37,13 @@
|
||||
- 实现微信支付V3 商家券
|
||||
- 实现微信支付V3 批量转账到零钱
|
||||
|
||||
更多参考[changelog](https://notfound403.github.io/payment-spring-boot/#/changelog)
|
||||
更新日志参考[changelog](https://notfound403.github.io/payment-spring-boot/#/changelog)
|
||||
|
||||
## 核心API结构
|
||||

|
||||
|
||||
- `WechatPartnerProfitsharingApi` 微信支付服务商V3分账
|
||||
- `WechatBrandProfitsharingApi` 微信支付服务商V3连锁品牌分账
|
||||
- `WechatPayCallback` 微信支付V3回调通知工具封装
|
||||
- `WechatAllocationApi` 微信支付V2分账(未来会移除)
|
||||
- `WechatMarketingFavorApi` 微信支付代金券V3
|
||||
@@ -45,7 +57,12 @@
|
||||
- `WechatPayTransfersApi` 微信支付V2企业付款到零钱,目前不包括到银行卡
|
||||
- `WechatDirectPayApi` 微信支付直连模式V3普通支付
|
||||
- `WechatPayScoreParkingApi` 微信支付分V3停车服务
|
||||
- `WechatBatchTransferApi` 微信支付V3批量转账到零钱
|
||||
- `WechatBatchTransferApi` 微信支付V3批量转账到零钱
|
||||
- `WechatPartnerSpecialMchApi` 微信支付V3服务商商户进件
|
||||
- `WechatMediaApi` 微信支付V3媒体上传
|
||||
- `WechatEcommerceApi` 电商收付通
|
||||
- `WechatSmartGuideApi` 服务商或者直连商户-经营能力-支付即服务
|
||||
- `WechatGoldPlanApi` 服务商-经营能力-点金计划
|
||||
|
||||
> 随着版本迭代功能会增加。
|
||||
|
||||
@@ -56,10 +73,6 @@
|
||||
- [GitHub](https://github.com/NotFound403/payment-spring-boot)
|
||||
- [Gitee](https://gitee.com/felord/payment-spring-boot)
|
||||
|
||||
## 文档地址
|
||||
- [payment-spring-boot GitHub文档](https://notfound403.github.io/payment-spring-boot)
|
||||
- [payment-spring-boot Gitee文档](https://felord.gitee.io/payment-spring-boot)
|
||||
|
||||
## QQ交流群
|
||||
为了交流解惑,新建QQ群,可通过扫码进入。
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
<dependency>
|
||||
<groupId>cn.felord</groupId>
|
||||
<artifactId>payment-spring-boot-starter</artifactId>
|
||||
<version>1.0.13.RELEASE</version>
|
||||
<version>1.0.15.RELEASE</version>
|
||||
</dependency>
|
||||
```
|
||||
## 采用技术
|
||||
|
||||
@@ -1,3 +1,32 @@
|
||||
## 1.0.15.RELEASE
|
||||
### 微信支付
|
||||
- feat: 增加服务商退款API
|
||||
- feat: 微信服务商分账-连锁品牌分账 [#82](https://github.com/NotFound403/payment-spring-boot/issues/82)
|
||||
- fix: 多租户证书无法复用的问题,刷新时正确移除证书 [#77](https://github.com/NotFound403/payment-spring-boot/issues/77)
|
||||
- fix: 批量转账到零钱API入参NPE问题修复 [#85](https://github.com/NotFound403/payment-spring-boot/issues/85)
|
||||
- fix: 商家券-修改批次预算API请求方法应该为Patch [#79](https://github.com/NotFound403/payment-spring-boot/issues/79)
|
||||
- enhance: 部分时间格式优化,更好地兼容Java Time API
|
||||
- enhance: 微信代金券样式的背景颜色枚举更新 [#84](https://github.com/NotFound403/payment-spring-boot/issues/84)
|
||||
- upgrade: Spring Boot 版本升级到2.7.7
|
||||
|
||||
## 1.0.14.RELEASE
|
||||
### 微信支付
|
||||
- fix: 批量转账到零钱查询BUG [#I5E2X7](https://gitee.com/felord/payment-spring-boot/issues/I5E2X7)
|
||||
- feat: 移除了被标记过期的API,包括基于微信支付V2版本的分账实现,使用相关接口的同学需要针对性的进行迁移
|
||||
- feat: 增加证书绝对路径实现
|
||||
- 配置项增加`certAbsolutePath`字段用来定义证书的绝对路径,优先级高于`certPath`,当这两个路径都不配置时采用classpath路径`wechat/apiclient_cert.p12` [#73](https://github.com/NotFound403/payment-spring-boot/issues/73)
|
||||
#### 服务商
|
||||
- feat: 实现服务商商户进件-特约商户进件相关API
|
||||
- feat: 实现点金计划,适用于服务商
|
||||
- feat: 实现行业方案-电商收付通
|
||||
- feat: 实现行业方案-智慧商圈
|
||||
- feat: 实现其它能力-银行组件(服务商)
|
||||
- enhance: 服务商分账新增下载账单接口
|
||||
- enhance: 新增服务商退款回调接口
|
||||
#### 通用能力
|
||||
- feat: 实现其它能力-图片、视频上传
|
||||
- feat: 支付即服务,适用于服务商和直连商户
|
||||
|
||||
## 1.0.13.RELEASE
|
||||
### 微信支付
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<dependency>
|
||||
<groupId>cn.felord</groupId>
|
||||
<artifactId>payment-spring-boot-starter</artifactId>
|
||||
<version>1.0.13.RELEASE</version>
|
||||
<version>1.0.15.RELEASE</version>
|
||||
</dependency>
|
||||
```
|
||||
> 基于 **Spring Boot 2.x**
|
||||
|
||||
@@ -5,11 +5,11 @@
|
||||
<parent>
|
||||
<groupId>cn.felord</groupId>
|
||||
<artifactId>payment-spring-boot</artifactId>
|
||||
<version>1.0.13.RELEASE</version>
|
||||
<version>1.0.15.RELEASE</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>payment-spring-boot-autoconfigure</artifactId>
|
||||
<version>1.0.13.RELEASE</version>
|
||||
<version>1.0.15.RELEASE</version>
|
||||
<packaging>jar</packaging>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -25,6 +25,9 @@ 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;
|
||||
|
||||
@@ -59,8 +62,11 @@ public class WechatPayConfiguration {
|
||||
v3Map.keySet().forEach(tenantId -> {
|
||||
WechatPayProperties.V3 v3 = v3Map.get(tenantId);
|
||||
String certPath = v3.getCertPath();
|
||||
String certAbsolutePath = v3.getCertAbsolutePath();
|
||||
String mchId = v3.getMchId();
|
||||
WechatMetaBean wechatMetaBean = keyPairFactory.initWechatMetaBean(certPath, CERT_ALIAS, mchId);
|
||||
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);
|
||||
|
||||
@@ -70,6 +70,10 @@ public class WechatPayProperties {
|
||||
* wechat pay certificate Path
|
||||
*/
|
||||
private String certPath;
|
||||
/**
|
||||
* wechat pay absolute certificate Path
|
||||
*/
|
||||
private String certAbsolutePath;
|
||||
/**
|
||||
* your pay server domain
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* 超级管理员类型
|
||||
*
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
public enum ContactType {
|
||||
/**
|
||||
* 经营者或者法人
|
||||
* <p>
|
||||
* 主体为个体工商户/企业/政府机关/事业单位/社会组织
|
||||
*/
|
||||
LEGAL,
|
||||
/**
|
||||
* 经办人
|
||||
* <p>
|
||||
* 经商户授权办理微信支付业务的人员
|
||||
*/
|
||||
SUPER
|
||||
}
|
||||
@@ -29,42 +29,41 @@ public enum CouponBgColor {
|
||||
/**
|
||||
* Color 010 coupon bg color.
|
||||
*/
|
||||
Color010,
|
||||
COLOR010,
|
||||
/**
|
||||
* Color 020 coupon bg color.
|
||||
* COLOR 020 coupon bg color.
|
||||
*/
|
||||
Color020,
|
||||
COLOR020,
|
||||
/**
|
||||
* Color 030 coupon bg color.
|
||||
* COLOR 030 coupon bg color.
|
||||
*/
|
||||
Color030,
|
||||
COLOR030,
|
||||
/**
|
||||
* Color 040 coupon bg color.
|
||||
* COLOR 040 coupon bg color.
|
||||
*/
|
||||
Color040,
|
||||
COLOR040,
|
||||
/**
|
||||
* Color 050 coupon bg color.
|
||||
* COLOR 050 coupon bg color.
|
||||
*/
|
||||
Color050,
|
||||
COLOR050,
|
||||
/**
|
||||
* Color 060 coupon bg color.
|
||||
* COLOR 060 coupon bg color.
|
||||
*/
|
||||
Color060,
|
||||
COLOR060,
|
||||
/**
|
||||
* Color 070 coupon bg color.
|
||||
* COLOR 070 coupon bg color.
|
||||
*/
|
||||
Color070,
|
||||
COLOR070,
|
||||
/**
|
||||
* Color 080 coupon bg color.
|
||||
* COLOR 080 coupon bg color.
|
||||
*/
|
||||
Color080,
|
||||
COLOR080,
|
||||
/**
|
||||
* Color 090 coupon bg color.
|
||||
* COLOR 090 coupon bg color.
|
||||
*/
|
||||
Color090,
|
||||
COLOR090,
|
||||
/**
|
||||
* Color 100 coupon bg color.
|
||||
* COLOR 100 coupon bg color.
|
||||
*/
|
||||
Color100
|
||||
|
||||
COLOR100
|
||||
}
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* 金融机构类型需与营业执照/登记证书上一致,可参考选择 <a href="https://kf.qq.com/faq/220215IrMRZ3220215n6buiU.html">金融机构指引</a>。
|
||||
*
|
||||
* @author felord.cn
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
public enum FinanceType {
|
||||
|
||||
/**
|
||||
* 银行业, 适用于商业银行、政策性银行、农村合作银行、村镇银行、开发性金融机构等
|
||||
*/
|
||||
BANK_AGENT,
|
||||
/**
|
||||
* 支付机构, 适用于非银行类支付机构
|
||||
*/
|
||||
PAYMENT_AGENT,
|
||||
/**
|
||||
* 保险业, 适用于保险、保险中介、保险代理、保险经纪等保险类业务
|
||||
*/
|
||||
INSURANCE,
|
||||
/**
|
||||
* 交易及结算类金融机构, 适用于交易所、登记结算类机构、银行卡清算机构、资金清算中心等
|
||||
*/
|
||||
TRADE_AND_SETTLE,
|
||||
/**
|
||||
* 其他金融机构, 适用于财务公司、信托公司、金融资产管理公司、金融租赁公司、汽车金融公司、贷款公司、货币经纪公司、消费金融公司、证券业、金融控股公司、股票、期货、货币兑换、小额贷款公司、金融资产管理、担保公司、商业保理公司、典当行、融资租赁公司、财经咨询等其他金融业务
|
||||
*/
|
||||
OTHER
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* 超级管理员证件类型
|
||||
* <p>
|
||||
* 当超级管理员类型是经办人时,请上传超级管理员证件类型。
|
||||
*
|
||||
* @author felord.cn
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
public enum IdDocType {
|
||||
/**
|
||||
* 中国大陆居民-身份证
|
||||
*/
|
||||
IDENTIFICATION_TYPE_IDCARD,
|
||||
/**
|
||||
* 其他国家或地区居民-护照
|
||||
*/
|
||||
IDENTIFICATION_TYPE_OVERSEA_PASSPORT,
|
||||
/**
|
||||
* 中国香港居民-来往内地通行证
|
||||
*/
|
||||
IDENTIFICATION_TYPE_HONGKONG_PASSPORT,
|
||||
/**
|
||||
* 中国澳门居民-来往内地通行证
|
||||
*/
|
||||
IDENTIFICATION_TYPE_MACAO_PASSPORT,
|
||||
/**
|
||||
* 中国台湾居民-来往大陆通行证
|
||||
*/
|
||||
IDENTIFICATION_TYPE_TAIWAN_PASSPORT,
|
||||
/**
|
||||
* 外国人居留证
|
||||
*/
|
||||
IDENTIFICATION_TYPE_FOREIGN_RESIDENT,
|
||||
/**
|
||||
* 港澳居民证
|
||||
*/
|
||||
IDENTIFICATION_TYPE_HONGKONG_MACAO_RESIDENT,
|
||||
/**
|
||||
* 台湾居民证
|
||||
*/
|
||||
IDENTIFICATION_TYPE_TAIWAN_RESIDENT
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2019-2021 felord.cn
|
||||
* 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.
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* 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
|
||||
* @see <a href="https://kf.qq.com/faq/180910IBZVnQ180910naQ77b.html">主体类型指引</a>
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
public enum SubjectType {
|
||||
/**
|
||||
* 个体户
|
||||
* <p>
|
||||
* 营业执照上的主体类型一般为个体户、个体工商户、个体经营;
|
||||
*/
|
||||
SUBJECT_TYPE_INDIVIDUAL,
|
||||
/**
|
||||
* 小微商户
|
||||
*/
|
||||
SUBJECT_TYPE_MICRO,
|
||||
/**
|
||||
* 企业
|
||||
* <p>
|
||||
* 营业执照上的主体类型一般为有限公司、有限责任公司;
|
||||
*/
|
||||
SUBJECT_TYPE_ENTERPRISE,
|
||||
/**
|
||||
* 政府机关
|
||||
* <p>
|
||||
* 包括各级、各类政府机关,如机关党委、税务、民政、人社、工商、商务、市监等;
|
||||
*/
|
||||
SUBJECT_TYPE_GOVERNMENT,
|
||||
/**
|
||||
* 事业单位
|
||||
* <p>
|
||||
* 包括国内各类事业单位,如:医疗、教育、学校等单位;
|
||||
*/
|
||||
SUBJECT_TYPE_INSTITUTIONS,
|
||||
/**
|
||||
* 社会组织
|
||||
* <p>
|
||||
* 包括社会团体、民办非企业、基金会、基层群众性自治组织、农村集体经济组织等组织
|
||||
*/
|
||||
SUBJECT_TYPE_OTHERS
|
||||
}
|
||||
@@ -54,7 +54,18 @@ public enum WechatPayV3Type {
|
||||
* @since 1.0.3.RELEASE
|
||||
*/
|
||||
FUND_FLOW_BILL(HttpMethod.GET, "%s/v3/bill/fundflowbill"),
|
||||
|
||||
/**
|
||||
* 图片上传API.
|
||||
*
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
MERCHANT_MEDIA_IMG(HttpMethod.POST, "%s/v3/merchant/media/upload"),
|
||||
/**
|
||||
* 视频上传API.
|
||||
*
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
MERCHANT_MEDIA_VIDEO(HttpMethod.POST, "%s/v3/merchant/media/video_upload"),
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
/**
|
||||
@@ -449,11 +460,11 @@ public enum WechatPayV3Type {
|
||||
*/
|
||||
MARKETING_BUSI_FAVOR_DISASSOCIATE(HttpMethod.POST, "%s/v3/marketing/busifavor/coupons/disassociate"),
|
||||
/**
|
||||
* 取消关联订单信息API.
|
||||
* 修改批次预算API.
|
||||
*
|
||||
* @since 1.0.4.RELEASES
|
||||
*/
|
||||
MARKETING_BUSI_FAVOR_BUDGET(HttpMethod.POST, "%s/v3/marketing/busifavor/stocks/{stock_id}/budget"),
|
||||
MARKETING_BUSI_FAVOR_BUDGET(HttpMethod.PATCH, "%s/v3/marketing/busifavor/stocks/{stock_id}/budget"),
|
||||
/**
|
||||
* 修改商家券基本信息API.
|
||||
*
|
||||
@@ -668,7 +679,413 @@ public enum WechatPayV3Type {
|
||||
*
|
||||
* @since 1.0.13.RELEASE
|
||||
*/
|
||||
PROFITSHARING_BILLS(HttpMethod.GET, "%s/v3/profitsharing/bills");
|
||||
PROFITSHARING_BILLS(HttpMethod.GET, "%s/v3/profitsharing/bills"),
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
/**
|
||||
* 请求品牌分账API.
|
||||
*
|
||||
* @since 1.0.15.RELEASE
|
||||
*/
|
||||
BRAND_PROFITSHARING_ORDERS(HttpMethod.POST, "%s/v3/brand/profitsharing/orders"),
|
||||
/**
|
||||
* 查询品牌分账结果API.
|
||||
*
|
||||
* @since 1.0.15.RELEASE
|
||||
*/
|
||||
BRAND_PROFITSHARING_RESULT(HttpMethod.GET, "%s/v3/brand/profitsharing/orders"),
|
||||
/**
|
||||
* 请求品牌分账回退API.
|
||||
*
|
||||
* @since 1.0.15.RELEASE
|
||||
*/
|
||||
BRAND_PROFITSHARING_RETURN_ORDERS(HttpMethod.POST, "%s/v3/brand/profitsharing/returnorders"),
|
||||
/**
|
||||
* 查询品牌分账回退结果API.
|
||||
*
|
||||
* @since 1.0.15.RELEASE
|
||||
*/
|
||||
BRAND_PROFITSHARING_RETURN_ORDERS_RESULT(HttpMethod.GET, "%s/v3/brand/profitsharing/returnorders"),
|
||||
/**
|
||||
* 完结品牌分账API.
|
||||
*
|
||||
* @since 1.0.15.RELEASE
|
||||
*/
|
||||
BRAND_PROFITSHARING_FINISH_ORDER(HttpMethod.POST, "%s/v3/brand/profitsharing/finish-order"),
|
||||
/**
|
||||
* 查询订单剩余待分金额API.
|
||||
*
|
||||
* @since 1.0.15.RELEASE
|
||||
*/
|
||||
BRAND_PROFITSHARING_ORDER_AMOUNTS(HttpMethod.GET, "%s/v3/brand/profitsharing/orders/{transaction_id}/amounts"),
|
||||
/**
|
||||
* 查询最大分账比例API.
|
||||
*
|
||||
* @since 1.0.15.RELEASE
|
||||
*/
|
||||
BRAND_CONFIGS(HttpMethod.GET, "%s/v3/brand/profitsharing/brand-configs/{brand_mchid}"),
|
||||
/**
|
||||
* 添加品牌分账接收方API.
|
||||
*
|
||||
* @since 1.0.15.RELEASE
|
||||
*/
|
||||
BRAND_PROFITSHARING_RECEIVERS_ADD(HttpMethod.POST, "%s/v3/brand/profitsharing/receivers/add"),
|
||||
/**
|
||||
* 删除分账接收方API.
|
||||
*
|
||||
* @since 1.0.15.RELEASE
|
||||
*/
|
||||
BRAND_PROFITSHARING_RECEIVERS_DELETE(HttpMethod.POST, "%s/v3/brand/profitsharing/receivers/delete"),
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
/**
|
||||
* 服务商-商户进件-特约商户进件-提交申请单API.
|
||||
*
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
SPEC_MCH_APPLY_PARTNER(HttpMethod.POST, "%s/v3/applyment4sub/applyment/"),
|
||||
/**
|
||||
* 服务商-商户进件-特约商户进件-通过业务申请编号查询申请状态API.
|
||||
*
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
SPEC_MCH_APPLY_QUERY_BUSINESS_CODE(HttpMethod.GET, "%s/v3/applyment4sub/applyment/business_code/{business_code}"),
|
||||
/**
|
||||
* 服务商-商户进件-特约商户进件-通过申请单号查询申请状态API.
|
||||
*
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
SPEC_MCH_APPLY_QUERY_APPLYMENT_ID(HttpMethod.GET, "%s/v3/applyment4sub/applyment/applyment_id/{applyment_id}"),
|
||||
/**
|
||||
* 服务商-商户进件-特约商户进件-修改结算账号API.
|
||||
*
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
SPEC_MCH_SUB_MODIFY(HttpMethod.POST, "%s/v3/apply4sub/sub_merchants/{sub_mchid}/modify-settlement"),
|
||||
/**
|
||||
* 服务商-商户进件-特约商户进件-查询结算账户API.
|
||||
*
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
SPEC_MCH_SUB_SETTLEMENT(HttpMethod.GET, "%s/v3/apply4sub/sub_merchants/{sub_mchid}/settlement"),
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
/**
|
||||
* 经营能力-支付即服务-服务人员注册API.
|
||||
*
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
SMART_GUIDES(HttpMethod.POST, "%s/v3/smartguide/guides"),
|
||||
/**
|
||||
* 经营能力-支付即服务-服务人员分配API.
|
||||
*
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
SMART_GUIDES_ASSIGN(HttpMethod.POST, "%s/v3/smartguide/guides/{guide_id}/assign"),
|
||||
/**
|
||||
* 经营能力-支付即服务-服务人员查询API.
|
||||
*
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
SMART_GUIDES_GET(HttpMethod.GET, "%s/v3/smartguide/guides"),
|
||||
/**
|
||||
* 经营能力-支付即服务-服务人员查询API.
|
||||
*
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
SMART_GUIDES_MODIFY(HttpMethod.PATCH, "%s/v3/smartguide/guides/{guide_id}"),
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
/**
|
||||
* 经营能力-点金计划-点金计划管理API.
|
||||
*
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
GOLD_PLAN_CHANGE(HttpMethod.POST, "%s/v3/goldplan/merchants/changegoldplanstatus"),
|
||||
/**
|
||||
* 经营能力-点金计划-商家小票管理API.
|
||||
*
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
GOLD_PLAN_CHANGE_CUSTOM(HttpMethod.POST, "%s/v3/goldplan/merchants/changecustompagestatus"),
|
||||
/**
|
||||
* 经营能力-点金计划-同业过滤标签管理API.
|
||||
*
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
GOLD_PLAN_FILTER(HttpMethod.POST, "%s/v3/goldplan/merchants/set-advertising-industry-filter"),
|
||||
/**
|
||||
* 经营能力-点金计划-开通广告展示API.
|
||||
*
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
GOLD_PLAN_ADV_OPEN(HttpMethod.POST, "%s/v3/goldplan/merchants/open-advertising-show"),
|
||||
/**
|
||||
* 经营能力-点金计划-关闭广告展示API.
|
||||
*
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
GOLD_PLAN_ADV_CLOSE(HttpMethod.POST, "%s/v3/goldplan/merchants/close-advertising-show"),
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
/**
|
||||
* 行业方案-电商收付通-商户进件-二级商户进件申请API.
|
||||
*
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
ECOMMERCE_APPLYMENT(HttpMethod.POST, "%s/v3/ecommerce/applyments/"),
|
||||
/**
|
||||
* 行业方案-电商收付通-商户进件-查询申请状态-通过申请单ID查询申请状态API.
|
||||
*
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
ECOMMERCE_APPLYMENT_ID(HttpMethod.GET, "%s/v3/ecommerce/applyments/{applyment_id}"),
|
||||
/**
|
||||
* 行业方案-电商收付通-商户进件-查询申请状态-通过业务申请编号查询申请状态API.
|
||||
*
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
ECOMMERCE_APPLYMENT_OUT_REQUEST_NO(HttpMethod.GET, "%s/v3/ecommerce/applyments/out-request-no/{out_request_no}"),
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
/**
|
||||
* 行业方案-电商收付通-分账-请求分账API.
|
||||
*
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
ECOMMERCE_PROFITSHARING_ORDERS(HttpMethod.POST, "%s/v3/ecommerce/profitsharing/orders"),
|
||||
/**
|
||||
* 行业方案-电商收付通-分账-查询分账结果API.
|
||||
*
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
ECOMMERCE_PROFITSHARING_RESULT(HttpMethod.GET, "%s/v3/ecommerce/profitsharing/orders"),
|
||||
/**
|
||||
* 行业方案-电商收付通-分账-请求分账回退API.
|
||||
*
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
ECOMMERCE_PROFITSHARING_RETURN_ORDERS(HttpMethod.POST, "%s/v3/ecommerce/profitsharing/returnorders"),
|
||||
/**
|
||||
* 行业方案-电商收付通-分账-查询分账回退结果API.
|
||||
*
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
ECOMMERCE_PROFITSHARING_RETURN_ORDERS_RESULT(HttpMethod.GET, "%s/v3/ecommerce/profitsharing/returnorders"),
|
||||
/**
|
||||
* 行业方案-电商收付通-分账-完结分账API.
|
||||
*
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
ECOMMERCE_PROFITSHARING_FINISH_ORDER(HttpMethod.POST, "%s/v3/ecommerce/profitsharing/finish-order"),
|
||||
/**
|
||||
* 行业方案-电商收付通-分账-查询订单剩余待分金额API.
|
||||
*
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
ECOMMERCE_PROFITSHARING_ORDER_AMOUNTS(HttpMethod.GET, "%s/v3/ecommerce/profitsharing/orders/{transaction_id}/amounts"),
|
||||
/**
|
||||
* 行业方案-电商收付通-分账-添加分账接收方API.
|
||||
*
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
ECOMMERCE_PROFITSHARING_RECEIVERS_ADD(HttpMethod.POST, "%s/v3/ecommerce/profitsharing/receivers/add"),
|
||||
/**
|
||||
* 行业方案-电商收付通-分账-删除分账接收方API.
|
||||
*
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
ECOMMERCE_PROFITSHARING_RECEIVERS_DELETE(HttpMethod.POST, "%s/v3/ecommerce/profitsharing/receivers/delete"),
|
||||
/**
|
||||
* 行业方案-电商收付通-补差-请求补差API.
|
||||
*
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
ECOMMERCE_SUBSIDIES_CREATE(HttpMethod.POST, "%s/v3/ecommerce/subsidies/create"),
|
||||
/**
|
||||
* 行业方案-电商收付通-补差-请求补差回退API.
|
||||
*
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
ECOMMERCE_SUBSIDIES_RETURN(HttpMethod.POST, "%s/v3/ecommerce/subsidies/return"),
|
||||
/**
|
||||
* 行业方案-电商收付通-补差-取消补差API.
|
||||
*
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
ECOMMERCE_SUBSIDIES_CANCEL(HttpMethod.POST, "%s/v3/ecommerce/subsidies/cancel"),
|
||||
/**
|
||||
* 行业方案-电商收付通-退款-申请退款API.
|
||||
*
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
ECOMMERCE_REFUNDS_APPLY(HttpMethod.POST, "%s/v3/ecommerce/refunds/apply"),
|
||||
/**
|
||||
* 行业方案-电商收付通-退款-查询退款API-通过微信支付退款单号查询退款.
|
||||
*
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
ECOMMERCE_REFUNDS_ID(HttpMethod.GET, "%s/v3/ecommerce/refunds/id/{refund_id}"),
|
||||
/**
|
||||
* 行业方案-电商收付通-退款-查询退款API-通过商户退款单号查询退款.
|
||||
*
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
ECOMMERCE_REFUNDS_OUT_REFUND_NO(HttpMethod.GET, "%s/v3/ecommerce/refunds/out-refund-no/{out_refund_no}"),
|
||||
/**
|
||||
* 行业方案-电商收付通-退款-垫付退款回补API.
|
||||
*
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
ECOMMERCE_REFUNDS_RETURN_ADVANCE(HttpMethod.POST, "%s/v3/ecommerce/refunds/{refund_id}/return-advance"),
|
||||
/**
|
||||
* 行业方案-电商收付通-退款-查询垫付回补结果API.
|
||||
*
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
ECOMMERCE_REFUNDS_RETURN_ADVANCE_RESULT(HttpMethod.GET, "%s/v3/ecommerce/refunds/{refund_id}/return-advance"),
|
||||
/**
|
||||
* 行业方案-电商收付通-余额查询-查询二级商户账户实时余额API.
|
||||
*
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
ECOMMERCE_FUND_BALANCE_REAL_TIME(HttpMethod.GET, "%s/v3/ecommerce/fund/balance/{sub_mchid}"),
|
||||
/**
|
||||
* 行业方案-电商收付通-余额查询-查询二级商户账户日终余额API.
|
||||
*
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
ECOMMERCE_FUND_BALANCE_END_DAY(HttpMethod.GET, "%s/v3/ecommerce/fund/enddaybalance/{sub_mchid}"),
|
||||
/**
|
||||
* 行业方案-电商收付通-余额查询-查询电商平台账户实时余额API.
|
||||
*
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
ECOMMERCE_FUND_BALANCE_TYPE_REAL_TIME(HttpMethod.GET, "%s/v3/merchant/fund/balance/{account_type}"),
|
||||
/**
|
||||
* 行业方案-电商收付通-余额查询-查询电商平台账户日终余额API.
|
||||
*
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
ECOMMERCE_FUND_BALANCE_TYPE_END_DAY(HttpMethod.GET, "%s/v3/merchant/fund/dayendbalance/{account_type}"),
|
||||
/**
|
||||
* 行业方案-电商收付通-商户提现-二级商户预约提现.
|
||||
*
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
ECOMMERCE_FUND_WITHDRAW(HttpMethod.POST, "%s/v3/ecommerce/fund/withdraw"),
|
||||
/**
|
||||
* 行业方案-电商收付通-商户提现-二级商户查询预约提现状态API-微信支付预约提现单号查询.
|
||||
*
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
ECOMMERCE_FUND_WITHDRAW_ID(HttpMethod.GET, "%s/v3/ecommerce/fund/withdraw/{withdraw_id}"),
|
||||
/**
|
||||
* 行业方案-电商收付通-商户提现-二级商户查询预约提现状态API-商户预约提现单号查询.
|
||||
*
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
ECOMMERCE_FUND_WITHDRAW_OUT_REQUEST_NO(HttpMethod.GET, "%s/v3/ecommerce/fund/withdraw/out-request-no/{out_request_no}"),
|
||||
/**
|
||||
* 行业方案-电商收付通-商户提现-电商平台预约提现API.
|
||||
*
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
ECOMMERCE_FUND_MERCHANT_WITHDRAW(HttpMethod.POST, "%s/v3/merchant/fund/withdraw"),
|
||||
/**
|
||||
* 行业方案-电商收付通-商户提现-电商平台查询预约提现状态API-微信支付预约提现单号查询.
|
||||
*
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
ECOMMERCE_FUND_MERCHANT_WITHDRAW_ID(HttpMethod.GET, "%s/v3/merchant/fund/withdraw/withdraw-id/{withdraw_id}"),
|
||||
/**
|
||||
* 行业方案-电商收付通-商户提现-电商平台查询预约提现状态API-商户预约提现单号查询.
|
||||
*
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
ECOMMERCE_FUND_WITHDRAW_MERCHANT_OUT_REQUEST_NO(HttpMethod.GET, "%s/v3/merchant/fund/withdraw/out-request-no/{out_request_no}"),
|
||||
/**
|
||||
* 行业方案-电商收付通-商户提现-按日下载提现异常文件API.
|
||||
*
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
ECOMMERCE_FUND_WITHDRAW_ERROR_BILL(HttpMethod.GET, "%s/v3/merchant/fund/withdraw/bill-type/{bill_type}"),
|
||||
/**
|
||||
* 行业方案-电商收付通-下载账单-申请二级商户资金账单API.
|
||||
*
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
ECOMMERCE_FUND_FLOW_BILL(HttpMethod.GET, "%s/v3/ecommerce/bill/fundflowbill"),
|
||||
/**
|
||||
* 行业方案-电商收付通-跨境付款-查询订单剩余可出境余额API.
|
||||
*
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
ECOMMERCE_FUND_OVERSEA_BALANCE(HttpMethod.GET, "%s/v3/funds-to-oversea/transactions/{transaction_id}/available_abroad_amounts"),
|
||||
/**
|
||||
* 行业方案-电商收付通-跨境付款-申请资金出境API.
|
||||
*
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
ECOMMERCE_FUND_OVERSEA_ORDERS(HttpMethod.POST, "%s/v3/funds-to-oversea/orders"),
|
||||
/**
|
||||
* 行业方案-电商收付通-跨境付款-查询出境结果API.
|
||||
*
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
ECOMMERCE_FUND_OVERSEA_ORDERS_RESULT(HttpMethod.GET, "%s/v3/funds-to-oversea/orders/{out_order_id}"),
|
||||
/**
|
||||
* 行业方案-电商收付通-跨境付款-获取购付汇账单文件下载链接API.
|
||||
*
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
ECOMMERCE_FUND_OVERSEA_BILLS(HttpMethod.GET, "%s/v3/funds-to-oversea/bill-download-url"),
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
/**
|
||||
* 智慧商圈-商圈积分同步API
|
||||
*
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
MALL_SCORE_SYNC(HttpMethod.POST, "%s/v3/businesscircle/points/notify"),
|
||||
/**
|
||||
* 智慧商圈-商圈积分同步API
|
||||
*
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
MALL_SCORE_RESULT(HttpMethod.GET, "%s/v3/businesscircle/user-authorizations/{openid}"),
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
/**
|
||||
* 获取对私银行卡号开户银行API
|
||||
*
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
CAPITAL_SEARCH(HttpMethod.GET, "%s/v3/capital/capitallhh/banks/search-banks-by-bank-account"),
|
||||
/**
|
||||
* 查询支持个人业务的银行列表API
|
||||
*
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
CAPITAL_PERSONAL(HttpMethod.GET, "%s/v3/capital/capitallhh/banks/personal-banking"),
|
||||
/**
|
||||
* 查询支持对公业务的银行列表API
|
||||
*
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
CAPITAL_CORPORATE(HttpMethod.GET, "%s/v3/capital/capitallhh/banks/corporate-banking"),
|
||||
/**
|
||||
* 查询省份列表API
|
||||
*
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
CAPITAL_PROVINCES(HttpMethod.GET, "%s/v3/capital/capitallhh/areas/provinces"),
|
||||
/**
|
||||
* 查询城市列表API
|
||||
*
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
CAPITAL_CITIES(HttpMethod.GET, "%s/v3/capital/capitallhh/areas/provinces/{province_code}/cities"),
|
||||
/**
|
||||
* 查询支行列表API
|
||||
*
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
CAPITAL_BRANCHES(HttpMethod.GET, "%s/v3/capital/capitallhh/banks/{bank_alias_code}/branches");
|
||||
|
||||
/**
|
||||
* The Pattern.
|
||||
*
|
||||
|
||||
@@ -1,249 +0,0 @@
|
||||
/*
|
||||
* 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.v2;
|
||||
|
||||
import cn.felord.payment.wechat.WechatPayProperties;
|
||||
import cn.felord.payment.wechat.v2.model.BaseModel;
|
||||
import cn.felord.payment.wechat.v2.model.allocation.*;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
|
||||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.http.HttpMethod;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 微信支付分账
|
||||
* <p>
|
||||
*
|
||||
* @author felord.cn
|
||||
* @since 1.0.10.RELEASE
|
||||
*/
|
||||
@Slf4j
|
||||
public class WechatAllocationApi {
|
||||
/**
|
||||
* The constant MAPPER.
|
||||
*/
|
||||
private static final ObjectMapper MAPPER = new ObjectMapper();
|
||||
|
||||
static {
|
||||
MAPPER.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE)
|
||||
.setSerializationInclusion(JsonInclude.Include.NON_NULL)
|
||||
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
|
||||
.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true)
|
||||
.registerModule(new JavaTimeModule());
|
||||
}
|
||||
|
||||
private final WechatV2Client wechatV2Client;
|
||||
|
||||
/**
|
||||
* Instantiates a new Wechat allocation api.
|
||||
*
|
||||
* @param wechatV2Client the wechat v 2 client
|
||||
*/
|
||||
public WechatAllocationApi(WechatV2Client wechatV2Client) {
|
||||
this.wechatV2Client = wechatV2Client;
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求单次分账
|
||||
*
|
||||
* @param profitSharingModel the profit sharing model
|
||||
* @return json node
|
||||
*/
|
||||
@SneakyThrows
|
||||
public JsonNode profitSharing(ProfitSharingModel profitSharingModel) {
|
||||
ProfitSharingSModel model = new ProfitSharingSModel();
|
||||
List<Receiver> receivers = profitSharingModel.getReceivers();
|
||||
model.setReceivers(MAPPER.writeValueAsString(receivers));
|
||||
|
||||
WechatPayProperties.V3 v3 = wechatV2Client.getWechatMetaBean().getV3();
|
||||
model.setAppid(v3.getAppId());
|
||||
model.setMchId(v3.getMchId());
|
||||
|
||||
model.setTransactionId(profitSharingModel.getTransactionId());
|
||||
model.setOutOrderNo(profitSharingModel.getOutOrderNo());
|
||||
|
||||
model.certPath(v3.getCertPath());
|
||||
model.signType(BaseModel.HMAC_SHA256);
|
||||
return wechatV2Client.wechatPayRequest(model,
|
||||
HttpMethod.POST,
|
||||
"https://api.mch.weixin.qq.com/secapi/pay/profitsharing");
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求单次分账
|
||||
*
|
||||
* @param multiProfitSharingModel the multi profit sharing model
|
||||
* @return json node
|
||||
*/
|
||||
@SneakyThrows
|
||||
public JsonNode multiProfitSharing(MultiProfitSharingModel multiProfitSharingModel) {
|
||||
MultiProfitSharingSModel multiProfitSharingSModel = new MultiProfitSharingSModel();
|
||||
List<Receiver> receivers = multiProfitSharingModel.getReceivers();
|
||||
multiProfitSharingSModel.setReceivers(MAPPER.writeValueAsString(receivers));
|
||||
|
||||
WechatPayProperties.V3 v3 = wechatV2Client.getWechatMetaBean().getV3();
|
||||
multiProfitSharingSModel.setAppid(v3.getAppId());
|
||||
multiProfitSharingSModel.setMchId(v3.getMchId());
|
||||
|
||||
multiProfitSharingSModel.setTransactionId(multiProfitSharingModel.getTransactionId());
|
||||
multiProfitSharingSModel.setOutOrderNo(multiProfitSharingModel.getOutOrderNo());
|
||||
|
||||
multiProfitSharingSModel.certPath(v3.getCertPath());
|
||||
multiProfitSharingSModel.signType(BaseModel.HMAC_SHA256);
|
||||
return wechatV2Client.wechatPayRequest(multiProfitSharingSModel,
|
||||
HttpMethod.POST,
|
||||
"https://api.mch.weixin.qq.com/secapi/pay/multiprofitsharing");
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询分账结果
|
||||
*
|
||||
* @param profitSharingQueryModel the profit sharing query model
|
||||
* @return json node
|
||||
*/
|
||||
public JsonNode profitSharingQuery(ProfitSharingQueryModel profitSharingQueryModel) {
|
||||
WechatPayProperties.V3 v3 = wechatV2Client.getWechatMetaBean().getV3();
|
||||
profitSharingQueryModel.setMchId(v3.getMchId());
|
||||
profitSharingQueryModel.certPath(v3.getCertPath());
|
||||
profitSharingQueryModel.signType(BaseModel.HMAC_SHA256);
|
||||
return wechatV2Client.wechatPayRequest(profitSharingQueryModel,
|
||||
HttpMethod.POST,
|
||||
"https://api.mch.weixin.qq.com/pay/profitsharingquery");
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加分账接收方
|
||||
*
|
||||
* @param profitSharingAddReceiverModel the profit sharing add receiver model
|
||||
* @return json node
|
||||
*/
|
||||
@SneakyThrows
|
||||
public JsonNode profitSharingAddReceiver(ProfitSharingAddReceiverModel profitSharingAddReceiverModel) {
|
||||
ProfitSharingAddReceiverSModel profitSharingAddReceiverSModel = new ProfitSharingAddReceiverSModel();
|
||||
ProfitSharingAddReceiverModel.Receiver receiver = profitSharingAddReceiverModel.getReceiver();
|
||||
profitSharingAddReceiverSModel.setReceiver(MAPPER.writeValueAsString(receiver));
|
||||
|
||||
WechatPayProperties.V3 v3 = wechatV2Client.getWechatMetaBean().getV3();
|
||||
profitSharingAddReceiverSModel.setAppid(v3.getAppId());
|
||||
profitSharingAddReceiverSModel.setMchId(v3.getMchId());
|
||||
|
||||
profitSharingAddReceiverSModel.certPath(v3.getCertPath());
|
||||
profitSharingAddReceiverSModel.signType(BaseModel.HMAC_SHA256);
|
||||
return wechatV2Client.wechatPayRequest(profitSharingAddReceiverSModel,
|
||||
HttpMethod.POST,
|
||||
"https://api.mch.weixin.qq.com/pay/profitsharingaddreceiver");
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除分账接收方
|
||||
*
|
||||
* @param profitSharingRemoveReceiverModel the profit sharing remove receiver model
|
||||
* @return json node
|
||||
*/
|
||||
@SneakyThrows
|
||||
public JsonNode profitSharingRemoveReceiver(ProfitSharingRemoveReceiverModel profitSharingRemoveReceiverModel) {
|
||||
ProfitSharingRemoveReceiverSModel profitSharingRemoveReceiverSModel = new ProfitSharingRemoveReceiverSModel();
|
||||
ProfitSharingRemoveReceiverModel.Receiver receiver = profitSharingRemoveReceiverModel.getReceiver();
|
||||
profitSharingRemoveReceiverSModel.setReceiver(MAPPER.writeValueAsString(receiver));
|
||||
|
||||
WechatPayProperties.V3 v3 = wechatV2Client.getWechatMetaBean().getV3();
|
||||
profitSharingRemoveReceiverSModel.setAppid(v3.getAppId());
|
||||
profitSharingRemoveReceiverSModel.setMchId(v3.getMchId());
|
||||
|
||||
profitSharingRemoveReceiverSModel.certPath(v3.getCertPath());
|
||||
profitSharingRemoveReceiverSModel.signType(BaseModel.HMAC_SHA256);
|
||||
return wechatV2Client.wechatPayRequest(profitSharingRemoveReceiverSModel,
|
||||
HttpMethod.POST,
|
||||
"https://api.mch.weixin.qq.com/pay/profitsharingremovereceiver");
|
||||
}
|
||||
|
||||
/**
|
||||
* 完结分账
|
||||
*
|
||||
* @param profitSharingFinishModel the profit sharing finish model
|
||||
* @return json node
|
||||
*/
|
||||
public JsonNode profitSharingFinish(ProfitSharingFinishModel profitSharingFinishModel) {
|
||||
WechatPayProperties.V3 v3 = wechatV2Client.getWechatMetaBean().getV3();
|
||||
profitSharingFinishModel.setAppid(v3.getAppId());
|
||||
profitSharingFinishModel.setMchId(v3.getMchId());
|
||||
profitSharingFinishModel.certPath(v3.getCertPath());
|
||||
profitSharingFinishModel.signType(BaseModel.HMAC_SHA256);
|
||||
return wechatV2Client.wechatPayRequest(profitSharingFinishModel,
|
||||
HttpMethod.POST,
|
||||
"https://api.mch.weixin.qq.com/secapi/pay/profitsharingfinish");
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询订单待分账金额
|
||||
*
|
||||
* @param profitSharingOrderAmountQueryModel the profit sharing order amount query model
|
||||
* @return json node
|
||||
*/
|
||||
public JsonNode profitSharingOrderAmountQuery(ProfitSharingOrderAmountQueryModel profitSharingOrderAmountQueryModel) {
|
||||
WechatPayProperties.V3 v3 = wechatV2Client.getWechatMetaBean().getV3();
|
||||
profitSharingOrderAmountQueryModel.setMchId(v3.getMchId());
|
||||
profitSharingOrderAmountQueryModel.certPath(v3.getCertPath());
|
||||
profitSharingOrderAmountQueryModel.signType(BaseModel.HMAC_SHA256);
|
||||
return wechatV2Client.wechatPayRequest(profitSharingOrderAmountQueryModel,
|
||||
HttpMethod.POST,
|
||||
"https://api.mch.weixin.qq.com/pay/profitsharingorderamountquery");
|
||||
}
|
||||
|
||||
/**
|
||||
* 分账回退
|
||||
*
|
||||
* @param profitSharingReturnModel the profit sharing return model
|
||||
* @return json node
|
||||
*/
|
||||
public JsonNode profitSharingReturn(ProfitSharingReturnModel profitSharingReturnModel) {
|
||||
WechatPayProperties.V3 v3 = wechatV2Client.getWechatMetaBean().getV3();
|
||||
profitSharingReturnModel.setAppid(v3.getAppId());
|
||||
profitSharingReturnModel.setMchId(v3.getMchId());
|
||||
profitSharingReturnModel.certPath(v3.getCertPath());
|
||||
profitSharingReturnModel.signType(BaseModel.HMAC_SHA256);
|
||||
return wechatV2Client.wechatPayRequest(profitSharingReturnModel,
|
||||
HttpMethod.POST,
|
||||
"https://api.mch.weixin.qq.com/secapi/pay/profitsharingreturn");
|
||||
}
|
||||
|
||||
/**
|
||||
* 回退结果查询
|
||||
*
|
||||
* @param profitSharingReturnQueryModel the profit sharing return query model
|
||||
* @return json node
|
||||
*/
|
||||
public JsonNode profitSharingReturnQuery(ProfitSharingReturnQueryModel profitSharingReturnQueryModel) {
|
||||
WechatPayProperties.V3 v3 = wechatV2Client.getWechatMetaBean().getV3();
|
||||
profitSharingReturnQueryModel.setAppid(v3.getAppId());
|
||||
profitSharingReturnQueryModel.setMchId(v3.getMchId());
|
||||
profitSharingReturnQueryModel.certPath(v3.getCertPath());
|
||||
profitSharingReturnQueryModel.signType(BaseModel.HMAC_SHA256);
|
||||
return wechatV2Client.wechatPayRequest(profitSharingReturnQueryModel,
|
||||
HttpMethod.POST,
|
||||
"https://api.mch.weixin.qq.com/pay/profitsharingreturnquery");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -42,6 +42,8 @@ public class WechatV2Client {
|
||||
WechatPayProperties.V3 v3 = wechatMetaBean.getV3();
|
||||
return model
|
||||
.appSecret(v3.getAppSecret())
|
||||
.certPath(v3.getCertPath())
|
||||
.certAbsolutePath(v3.getCertAbsolutePath())
|
||||
.request(v3.getMchId(), method, url);
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
|
||||
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
|
||||
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
|
||||
import lombok.Getter;
|
||||
import lombok.SneakyThrows;
|
||||
@@ -37,6 +37,8 @@ import org.bouncycastle.crypto.Digest;
|
||||
import org.bouncycastle.crypto.digests.MD5Digest;
|
||||
import org.bouncycastle.util.encoders.Hex;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.FileSystemResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.RequestEntity;
|
||||
@@ -79,11 +81,11 @@ public abstract class BaseModel {
|
||||
// 忽略null
|
||||
XML_MAPPER.setSerializationInclusion(JsonInclude.Include.NON_NULL)
|
||||
// 属性使用 驼峰首字母小写
|
||||
.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE);
|
||||
.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
|
||||
OBJECT_MAPPER
|
||||
// .configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, true)
|
||||
.setSerializationInclusion(JsonInclude.Include.NON_NULL)
|
||||
.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE);
|
||||
.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
|
||||
}
|
||||
|
||||
|
||||
@@ -97,6 +99,8 @@ public abstract class BaseModel {
|
||||
@JsonIgnore
|
||||
private String certPath;
|
||||
@JsonIgnore
|
||||
private String certAbsolutePath;
|
||||
@JsonIgnore
|
||||
private String signType;
|
||||
|
||||
public BaseModel appSecret(String appSecret) {
|
||||
@@ -109,6 +113,10 @@ public abstract class BaseModel {
|
||||
return this;
|
||||
}
|
||||
|
||||
public BaseModel certAbsolutePath(String certAbsolutePath) {
|
||||
this.certAbsolutePath = certAbsolutePath;
|
||||
return this;
|
||||
}
|
||||
|
||||
public BaseModel signType(String signType) {
|
||||
this.signType = signType;
|
||||
@@ -211,8 +219,9 @@ public abstract class BaseModel {
|
||||
private RestTemplate getRestTemplateClientAuthentication(String mchId)
|
||||
throws IOException, UnrecoverableKeyException, CertificateException, NoSuchAlgorithmException,
|
||||
KeyStoreException, KeyManagementException {
|
||||
ClassPathResource resource = new ClassPathResource(certPath == null ? "wechat/apiclient_cert.p12" : certPath);
|
||||
|
||||
Resource resource = certAbsolutePath != null ? new FileSystemResource(certAbsolutePath) :
|
||||
new ClassPathResource(certPath == null ? "wechat/apiclient_cert.p12" : certPath);
|
||||
char[] pem = mchId.toCharArray();
|
||||
|
||||
KeyStore store = KeyStore.getInstance("PKCS12");
|
||||
|
||||
@@ -1,95 +0,0 @@
|
||||
/*
|
||||
* 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.v2.model.allocation;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* The type Profit sharing add receiver model.
|
||||
*
|
||||
* @author wangzecheng
|
||||
* @since 1.0.10.RELEASE
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class ProfitSharingAddReceiverModel extends BaseProfitSharingReceiverModel {
|
||||
|
||||
private Receiver receiver;
|
||||
|
||||
/**
|
||||
* The type Receiver.
|
||||
*/
|
||||
@Data
|
||||
public static class Receiver {
|
||||
|
||||
/**
|
||||
* 分账接收方类型.
|
||||
* <p>
|
||||
* MERCHANT_ID:商户号(mch_id或者sub_mch_id)
|
||||
* PERSONAL_OPENID:个人openid
|
||||
*/
|
||||
private Type type;
|
||||
|
||||
/**
|
||||
* 分账接收方帐号.
|
||||
* <p>
|
||||
* 类型是MERCHANT_ID时,是商户号(mch_id或者sub_mch_id)
|
||||
* 类型是PERSONAL_OPENID时,是个人openid
|
||||
*/
|
||||
private String account;
|
||||
|
||||
/**
|
||||
* 分账接收方全称.
|
||||
* <p>
|
||||
* 分账接收方类型是MERCHANT_ID时,是商户全称(必传),当商户是小微商户或个体户时,是开户人姓名
|
||||
* 分账接收方类型是PERSONAL_OPENID时,是个人姓名(选传,传则校验)
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 与分账方的关系类型.
|
||||
* <p>
|
||||
* 子商户与接收方的关系。
|
||||
* 本字段值为枚举:
|
||||
* SERVICE_PROVIDER:服务商
|
||||
* STORE:门店
|
||||
* STAFF:员工
|
||||
* STORE_OWNER:店主
|
||||
* PARTNER:合作伙伴
|
||||
* HEADQUARTER:总部
|
||||
* BRAND:品牌方
|
||||
* DISTRIBUTOR:分销商
|
||||
* USER:用户
|
||||
* SUPPLIER:供应商
|
||||
* CUSTOM:自定义
|
||||
*/
|
||||
private RelationType relationType;
|
||||
|
||||
/**
|
||||
* 自定义的分账关系.
|
||||
* <p>
|
||||
* 子商户与接收方具体的关系,本字段最多10个字。
|
||||
* 当字段relation_type的值为CUSTOM时,本字段必填
|
||||
* 当字段relation_type的值不为CUSTOM时,本字段无需填写
|
||||
*/
|
||||
private String customRelation;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
/*
|
||||
* 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.v2.model.allocation;
|
||||
|
||||
import cn.felord.payment.wechat.v2.model.BaseModel;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* The type Profit sharing finish model.
|
||||
*
|
||||
* @author wangzecheng
|
||||
* @since 1.0.10.RELEASE
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class ProfitSharingFinishModel extends BaseModel {
|
||||
|
||||
/**
|
||||
* 商户号.
|
||||
* <p>
|
||||
* 微信支付分配的商户号
|
||||
*/
|
||||
private String mchId;
|
||||
|
||||
/**
|
||||
* 公众账号ID.
|
||||
* <p>
|
||||
* 微信分配的公众账号ID
|
||||
*/
|
||||
private String appid;
|
||||
|
||||
/**
|
||||
* 微信订单号.
|
||||
* <p>
|
||||
* 微信支付订单号
|
||||
*/
|
||||
private String transactionId;
|
||||
|
||||
/**
|
||||
* 商户分账单号.
|
||||
* <p>
|
||||
* 查询分账结果,输入申请分账时的商户分账单号; 查询分账完结执行的结果,输入发起分账完结时的商户分账单号
|
||||
*/
|
||||
private String outOrderNo;
|
||||
|
||||
/**
|
||||
* 分账完结描述.
|
||||
* <p>
|
||||
* 分账完结的原因描述
|
||||
*/
|
||||
private String description;
|
||||
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* 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.v2.model.allocation;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 单次分账请求按照传入的分账接收方账号和资金进行分账,同时会将订单剩余的待分账金额解冻给本商户。
|
||||
* 故操作成功后,订单不能再进行分账,也不能进行分账完结。
|
||||
*
|
||||
* @author wangzecheng
|
||||
* @since 1.0.10.RELEASE
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class ProfitSharingModel extends BaseProfitSharingModel {
|
||||
|
||||
/**
|
||||
* 分账接收方列表,不超过50个json对象,不能设置分账方作为分账接受方
|
||||
*/
|
||||
private List<Receiver> receivers;
|
||||
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
* 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.v2.model.allocation;
|
||||
|
||||
import cn.felord.payment.wechat.v2.model.BaseModel;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* The type Profit sharing query model.
|
||||
*
|
||||
* @author wangzecheng
|
||||
* @since 1.0.10.RELEASE
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class ProfitSharingQueryModel extends BaseModel {
|
||||
|
||||
/**
|
||||
* 商户号.
|
||||
* <p>
|
||||
* 微信支付分配的商户号
|
||||
*/
|
||||
private String mchId;
|
||||
|
||||
/**
|
||||
* 微信订单号.
|
||||
* <p>
|
||||
* 微信支付订单号
|
||||
*/
|
||||
private String transactionId;
|
||||
|
||||
/**
|
||||
* 商户分账单号.
|
||||
* <p>
|
||||
* 查询分账结果,输入申请分账时的商户分账单号; 查询分账完结执行的结果,输入发起分账完结时的商户分账单号
|
||||
*/
|
||||
private String outOrderNo;
|
||||
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
* 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.v2.model.allocation;
|
||||
|
||||
import cn.felord.payment.wechat.v2.model.BaseModel;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* The type Profit sharing return model.
|
||||
*
|
||||
* @author wangzecheng
|
||||
* @since 1.0.10.RELEASE
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class ProfitSharingReturnModel extends BaseModel {
|
||||
|
||||
/**
|
||||
* 商户号.
|
||||
* <p>
|
||||
* 微信支付分配的商户号
|
||||
*/
|
||||
private String mchId;
|
||||
|
||||
/**
|
||||
* 公众账号ID.
|
||||
* <p>
|
||||
* 微信分配的公众账号ID
|
||||
*/
|
||||
private String appid;
|
||||
private String orderId;
|
||||
private String outOrderNo;
|
||||
private String outReturnNo;
|
||||
private String returnAccountType;
|
||||
private String returnAccount;
|
||||
private String returnAmount;
|
||||
private String description;
|
||||
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
/*
|
||||
* 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.v2.model.allocation;
|
||||
|
||||
import cn.felord.payment.wechat.v2.model.BaseModel;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* The type Profit sharing return query model.
|
||||
*
|
||||
* @author wangzecheng
|
||||
* @since 1.0.10.RELEASE
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class ProfitSharingReturnQueryModel extends BaseModel {
|
||||
|
||||
/**
|
||||
* 商户号.
|
||||
* <p>
|
||||
* 微信支付分配的商户号
|
||||
*/
|
||||
private String mchId;
|
||||
|
||||
/**
|
||||
* 公众账号ID.
|
||||
* <p>
|
||||
* 微信分配的公众账号ID
|
||||
*/
|
||||
private String appid;
|
||||
|
||||
/**
|
||||
* 微信分账订单号.
|
||||
* <p>
|
||||
* 原发起分账请求时,微信返回的微信分账单号,与商户分账单号一一对应。
|
||||
* 微信分账单号与商户分账单号二选一填写
|
||||
*/
|
||||
private String orderId;
|
||||
|
||||
/**
|
||||
* 商户分账单号.
|
||||
* <p>
|
||||
* 原发起分账请求时使用的商户系统内部的分账单号。
|
||||
* 微信分账单号与商户分账单号二选一填写
|
||||
*/
|
||||
private String outOrderNo;
|
||||
|
||||
/**
|
||||
* 商户回退单号.
|
||||
* <p>
|
||||
* 调用回退接口提供的商户系统内部的回退单号
|
||||
*/
|
||||
private String outReturnNo;
|
||||
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
/*
|
||||
* 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.v2.model.allocation;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* The type Receiver.
|
||||
*
|
||||
* @author wangzecheng
|
||||
* @since 1.0.10.RELEASE
|
||||
*/
|
||||
@Data
|
||||
public class Receiver {
|
||||
|
||||
/**
|
||||
* 分账接收方类型.
|
||||
* <p>
|
||||
* MERCHANT_ID:商户号(mch_id或者sub_mch_id)
|
||||
* PERSONAL_OPENID:个人openid
|
||||
*/
|
||||
private Type type;
|
||||
|
||||
/**
|
||||
* 分账接收方帐号.
|
||||
* <p>
|
||||
* 类型是MERCHANT_ID时,是商户号(mch_id或者sub_mch_id)
|
||||
* 类型是PERSONAL_OPENID时,是个人openid
|
||||
*/
|
||||
private String account;
|
||||
|
||||
/**
|
||||
* 分账金额.
|
||||
* <p>
|
||||
* 单位为分,只能为整数,不能超过原订单支付金额及最大分账比例金额
|
||||
*/
|
||||
private Integer amount;
|
||||
|
||||
/**
|
||||
* 分账描述.
|
||||
* <p>
|
||||
* 分账的原因描述,分账账单中需要体现
|
||||
*/
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 分账个人接收方姓名.
|
||||
* <p>
|
||||
* 可选项,在接收方类型为个人的时可选填,若有值,会检查与 name 是否实名匹配,不匹配会拒绝分账请求.
|
||||
* 1、分账接收方类型是PERSONAL_OPENID时,是个人姓名(选传,传则校验)
|
||||
*/
|
||||
private String name;
|
||||
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
/*
|
||||
* 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.v2.model.allocation;
|
||||
|
||||
/**
|
||||
* The enum Relation type.
|
||||
* @author wangzecheng
|
||||
* @since 1.0.10.RELEASE
|
||||
*/
|
||||
public enum RelationType {
|
||||
|
||||
/**
|
||||
* Service provider relation type.
|
||||
*/
|
||||
SERVICE_PROVIDER,
|
||||
/**
|
||||
* Store relation type.
|
||||
*/
|
||||
STORE,
|
||||
/**
|
||||
* Staff relation type.
|
||||
*/
|
||||
STAFF,
|
||||
/**
|
||||
* Store owner relation type.
|
||||
*/
|
||||
STORE_OWNER,
|
||||
/**
|
||||
* Partner relation type.
|
||||
*/
|
||||
PARTNER,
|
||||
/**
|
||||
* Headquarter relation type.
|
||||
*/
|
||||
HEADQUARTER,
|
||||
/**
|
||||
* Brand relation type.
|
||||
*/
|
||||
BRAND,
|
||||
/**
|
||||
* Distributor relation type.
|
||||
*/
|
||||
DISTRIBUTOR,
|
||||
/**
|
||||
* User relation type.
|
||||
*/
|
||||
USER,
|
||||
/**
|
||||
* Supplier relation type.
|
||||
*/
|
||||
SUPPLIER,
|
||||
/**
|
||||
* Custom relation type.
|
||||
*/
|
||||
CUSTOM
|
||||
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
package cn.felord.payment.wechat.v2.model.allocation;
|
||||
|
||||
/**
|
||||
* The enum Type.
|
||||
*
|
||||
* @author wangzecheng
|
||||
* @since 1.0.10.RELEASE
|
||||
*/
|
||||
public enum Type {
|
||||
|
||||
/**
|
||||
* 商户号(mch_id或者sub_mch_id)
|
||||
*/
|
||||
MERCHANT_ID,
|
||||
|
||||
/**
|
||||
* 个人openid
|
||||
*/
|
||||
PERSONAL_OPENID
|
||||
}
|
||||
@@ -30,7 +30,7 @@ import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
|
||||
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||
import org.springframework.core.io.Resource;
|
||||
@@ -94,8 +94,7 @@ public abstract class AbstractApi {
|
||||
* @param mapper the mapper
|
||||
*/
|
||||
private void applyObjectMapper(ObjectMapper mapper) {
|
||||
mapper.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE
|
||||
)
|
||||
mapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE)
|
||||
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
|
||||
// empty string error
|
||||
.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true)
|
||||
@@ -158,7 +157,8 @@ public abstract class AbstractApi {
|
||||
*/
|
||||
protected RequestEntity<?> Post(URI uri, Object params) {
|
||||
try {
|
||||
return RequestEntity.post(uri).header("Pay-TenantId", tenantId)
|
||||
return RequestEntity.post(uri)
|
||||
.header("Pay-TenantId", tenantId)
|
||||
.body(mapper.writeValueAsString(params));
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new PayException("wechat app pay json failed");
|
||||
@@ -191,7 +191,8 @@ public abstract class AbstractApi {
|
||||
* @return the request entity
|
||||
*/
|
||||
protected RequestEntity<?> Get(URI uri) {
|
||||
return RequestEntity.get(uri).header("Pay-TenantId", tenantId)
|
||||
return RequestEntity.get(uri)
|
||||
.header("Pay-TenantId", tenantId)
|
||||
.build();
|
||||
}
|
||||
|
||||
@@ -210,7 +211,7 @@ public abstract class AbstractApi {
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建Post请求对象.
|
||||
* 构建Patch请求对象.
|
||||
*
|
||||
* @param uri the uri
|
||||
* @param params the params
|
||||
@@ -218,7 +219,27 @@ public abstract class AbstractApi {
|
||||
*/
|
||||
protected RequestEntity<?> Patch(URI uri, Object params) {
|
||||
try {
|
||||
return RequestEntity.patch(uri).header("Pay-TenantId", tenantId)
|
||||
return RequestEntity.patch(uri)
|
||||
.header("Pay-TenantId", tenantId)
|
||||
.body(mapper.writeValueAsString(params));
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new PayException("wechat app pay json failed");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建Patch请求对象.
|
||||
*
|
||||
* @param uri the uri
|
||||
* @param params the params
|
||||
* @param httpHeaders the http headers
|
||||
* @return the request entity
|
||||
*/
|
||||
protected RequestEntity<?> Patch(URI uri, Object params, HttpHeaders httpHeaders) {
|
||||
try {
|
||||
return RequestEntity.patch(uri)
|
||||
.header("Pay-TenantId", tenantId)
|
||||
.headers(httpHeaders)
|
||||
.body(mapper.writeValueAsString(params));
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new PayException("wechat app pay json failed");
|
||||
@@ -230,7 +251,7 @@ public abstract class AbstractApi {
|
||||
*
|
||||
* @param link the link
|
||||
* @return 对账单内容 ,有可能为空字符 “”
|
||||
* @see AbstractApi#billResource(String) AbstractApi#billResource(String)AbstractApi#billResource(String)AbstractApi#billResource(String)
|
||||
* @see AbstractApi#billResource(String) AbstractApi#billResource(String)AbstractApi#billResource(String)AbstractApi#billResource(String)AbstractApi#billResource(String)AbstractApi#billResource(String)
|
||||
*/
|
||||
protected String billCsvDownload(String link) {
|
||||
return this.client().withType(WechatPayV3Type.FILE_DOWNLOAD, link)
|
||||
@@ -349,7 +370,7 @@ public abstract class AbstractApi {
|
||||
/**
|
||||
* 调用{@code /v3/billdownload/file}直接下载为文件.
|
||||
*
|
||||
* @param downloadUrl 格式为 {@code https://api.mch.weixin.qq.com/v3/billdownload/file?token=xxx}
|
||||
* @param downloadUrl 格式为 {@code https://api.mch.weixin.qq.com/v3/billdownload/file?token=xxx}
|
||||
* @param filename 文件名称包含扩展名
|
||||
* @return the response entity
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
package cn.felord.payment.wechat.v3;
|
||||
|
||||
import cn.felord.payment.wechat.v3.model.PageParams;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* @author felord.cn
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class BranchBanksPageParams extends PageParams {
|
||||
private String bankAliasCode;
|
||||
private Integer cityCode;
|
||||
}
|
||||
@@ -21,6 +21,8 @@ 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.cert.X509Certificate;
|
||||
@@ -30,7 +32,7 @@ import java.security.cert.X509Certificate;
|
||||
*
|
||||
* @author felord.cn
|
||||
* @since 1.0.0.RELEASE
|
||||
**/
|
||||
*/
|
||||
public class KeyPairFactory {
|
||||
|
||||
private static final KeyStore PKCS12_KEY_STORE;
|
||||
@@ -47,13 +49,13 @@ public class KeyPairFactory {
|
||||
/**
|
||||
* 获取公私钥.
|
||||
*
|
||||
* @param keyPath the key path
|
||||
* @param resource the resource
|
||||
* @param keyAlias the key alias
|
||||
* @param keyPass password
|
||||
* @return the key pair
|
||||
*/
|
||||
public WechatMetaBean initWechatMetaBean(String keyPath, String keyAlias, String keyPass) {
|
||||
ClassPathResource resource = new ClassPathResource(keyPath);
|
||||
public WechatMetaBean initWechatMetaBean(Resource resource, String keyAlias, String keyPass) {
|
||||
|
||||
char[] pem = keyPass.toCharArray();
|
||||
try {
|
||||
PKCS12_KEY_STORE.load(resource.getInputStream(), pem);
|
||||
|
||||
@@ -29,7 +29,11 @@ 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.*;
|
||||
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.converter.HttpMessageConverter;
|
||||
import org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter;
|
||||
import org.springframework.util.AlternativeJdkIdGenerator;
|
||||
@@ -55,7 +59,6 @@ import java.security.cert.X509Certificate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneOffset;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
@@ -88,7 +91,7 @@ public class SignatureProvider {
|
||||
/**
|
||||
* 微信平台证书容器 key = 序列号 value = 证书对象
|
||||
*/
|
||||
private static final Map<String, X509WechatCertificateInfo> CERTIFICATE_MAP = new ConcurrentHashMap<>();
|
||||
private static final Set<X509WechatCertificateInfo> CERTIFICATE_SET = Collections.synchronizedSet(new HashSet<>());
|
||||
/**
|
||||
* 加密算法提供方 - BouncyCastle
|
||||
*/
|
||||
@@ -163,7 +166,7 @@ public class SignatureProvider {
|
||||
public String doRequestSign(PrivateKey privateKey, String... orderedComponents) {
|
||||
Signature signer = Signature.getInstance("SHA256withRSA", BC_PROVIDER);
|
||||
signer.initSign(privateKey);
|
||||
final String signatureStr = createSign(true, orderedComponents);
|
||||
final String signatureStr = createSign(orderedComponents);
|
||||
signer.update(signatureStr.getBytes(StandardCharsets.UTF_8));
|
||||
return Base64Utils.encodeToString(signer.sign());
|
||||
}
|
||||
@@ -178,14 +181,21 @@ public class SignatureProvider {
|
||||
public boolean responseSignVerify(ResponseSignVerifyParams params) {
|
||||
|
||||
String wechatpaySerial = params.getWechatpaySerial();
|
||||
if (CERTIFICATE_MAP.isEmpty() || !CERTIFICATE_MAP.containsKey(wechatpaySerial)) {
|
||||
wechatMetaContainer.getTenantIds().forEach(this::refreshCertificate);
|
||||
}
|
||||
Certificate certificate = CERTIFICATE_MAP.get(wechatpaySerial).getX509Certificate();
|
||||
X509WechatCertificateInfo certificate = CERTIFICATE_SET.stream()
|
||||
.filter(cert -> Objects.equals(wechatpaySerial, cert.getWechatPaySerial()))
|
||||
.findAny()
|
||||
.orElseGet(() -> {
|
||||
wechatMetaContainer.getTenantIds().forEach(this::refreshCertificate);
|
||||
return CERTIFICATE_SET.stream()
|
||||
.filter(cert -> Objects.equals(wechatpaySerial, cert.getWechatPaySerial()))
|
||||
.findAny()
|
||||
.orElseThrow(()->new PayException("cannot obtain the certificate"));
|
||||
});
|
||||
|
||||
final String signatureStr = createSign(true, params.getWechatpayTimestamp(), params.getWechatpayNonce(), params.getBody());
|
||||
|
||||
final String signatureStr = createSign(params.getWechatpayTimestamp(), params.getWechatpayNonce(), params.getBody());
|
||||
Signature signer = Signature.getInstance("SHA256withRSA", BC_PROVIDER);
|
||||
signer.initVerify(certificate);
|
||||
signer.initVerify(certificate.getX509Certificate());
|
||||
signer.update(signatureStr.getBytes(StandardCharsets.UTF_8));
|
||||
|
||||
return signer.verify(Base64Utils.decodeFromString(params.getWechatpaySignature()));
|
||||
@@ -227,7 +237,11 @@ public class SignatureProvider {
|
||||
}
|
||||
ArrayNode certificates = bodyObjectNode.withArray("data");
|
||||
if (certificates.isArray() && certificates.size() > 0) {
|
||||
CERTIFICATE_MAP.remove(tenantId);
|
||||
CERTIFICATE_SET.forEach( x509WechatCertificateInfo -> {
|
||||
if (Objects.equals(tenantId,x509WechatCertificateInfo.getTenantId())){
|
||||
CERTIFICATE_SET.remove(x509WechatCertificateInfo);
|
||||
}
|
||||
});
|
||||
final CertificateFactory certificateFactory = CertificateFactory.getInstance("X509", BC_PROVIDER);
|
||||
certificates.forEach(objectNode -> {
|
||||
JsonNode encryptCertificate = objectNode.get("encrypt_certificate");
|
||||
@@ -245,7 +259,7 @@ public class SignatureProvider {
|
||||
x509WechatCertificateInfo.setWechatPaySerial(responseSerialNo);
|
||||
x509WechatCertificateInfo.setTenantId(tenantId);
|
||||
x509WechatCertificateInfo.setX509Certificate((X509Certificate) certificate);
|
||||
CERTIFICATE_MAP.put(responseSerialNo, x509WechatCertificateInfo);
|
||||
CERTIFICATE_SET.add( x509WechatCertificateInfo);
|
||||
} catch (CertificateException e) {
|
||||
throw new PayException("An error occurred while generating the wechat v3 certificate, reason : " + e.getMessage());
|
||||
}
|
||||
@@ -288,7 +302,8 @@ public class SignatureProvider {
|
||||
throw new PayException(e);
|
||||
}
|
||||
return new String(bytes, StandardCharsets.UTF_8);
|
||||
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | InvalidAlgorithmParameterException | NoSuchProviderException e) {
|
||||
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException |
|
||||
InvalidAlgorithmParameterException | NoSuchProviderException e) {
|
||||
throw new PayException(e);
|
||||
}
|
||||
}
|
||||
@@ -315,6 +330,29 @@ public class SignatureProvider {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 对响应的敏感字段进行解密
|
||||
*
|
||||
* @param message the message
|
||||
* @param tenantId the tenant id
|
||||
* @return encrypt message
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
public String decryptResponseMessage(String message, String tenantId) {
|
||||
try {
|
||||
WechatMetaBean wechatMetaBean = wechatMetaContainer.getWechatMeta(tenantId);
|
||||
PrivateKey privateKey = wechatMetaBean.getKeyPair().getPrivate();
|
||||
Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding", BC_PROVIDER);
|
||||
cipher.init(Cipher.DECRYPT_MODE, privateKey);
|
||||
byte[] data = Base64Utils.decodeFromString(message);
|
||||
byte[] cipherData = cipher.doFinal(data);
|
||||
return new String(cipherData, StandardCharsets.UTF_8);
|
||||
|
||||
} catch (Exception e) {
|
||||
throw new PayException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get certificate x 509 wechat certificate info.
|
||||
*
|
||||
@@ -322,22 +360,17 @@ public class SignatureProvider {
|
||||
* @return the x 509 wechat certificate info
|
||||
*/
|
||||
public X509WechatCertificateInfo getCertificate(String tenantId) {
|
||||
for (String serial : CERTIFICATE_MAP.keySet()) {
|
||||
X509WechatCertificateInfo wechatCertificateInfo = CERTIFICATE_MAP.get(serial);
|
||||
X509Certificate x509Cert = wechatCertificateInfo.getX509Certificate();
|
||||
if (wechatCertificateInfo.getTenantId().equals(tenantId)){
|
||||
try {
|
||||
x509Cert.checkValidity();
|
||||
|
||||
return wechatCertificateInfo;
|
||||
} catch (Exception e) {
|
||||
log.warn("the wechat certificate is invalid , {}", e.getMessage());
|
||||
// Async?
|
||||
return CERTIFICATE_SET.stream()
|
||||
.filter(cert -> Objects.equals(tenantId, cert.getTenantId()))
|
||||
.findAny()
|
||||
.orElseGet(() -> {
|
||||
wechatMetaContainer.getTenantIds().forEach(this::refreshCertificate);
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new PayException("failed to obtain wechat pay x509Certificate ");
|
||||
return CERTIFICATE_SET.stream()
|
||||
.filter(cert -> Objects.equals(tenantId, cert.getTenantId()))
|
||||
.findAny()
|
||||
.orElseThrow(() -> new PayException("cannot obtain the certificate"));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -366,11 +399,9 @@ public class SignatureProvider {
|
||||
* @param components the components
|
||||
* @return string string
|
||||
*/
|
||||
private static String createSign(boolean newLine, String... components) {
|
||||
|
||||
String suffix = newLine ? "\n" : "";
|
||||
private static String createSign(String... components) {
|
||||
return Arrays.stream(components)
|
||||
.collect(Collectors.joining("\n", "", suffix));
|
||||
.collect(Collectors.joining("\n", "", "\n"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,10 +18,10 @@
|
||||
*/
|
||||
package cn.felord.payment.wechat.v3;
|
||||
|
||||
import cn.felord.payment.wechat.v2.WechatAllocationApi;
|
||||
import cn.felord.payment.wechat.v2.WechatPayRedpackApi;
|
||||
import cn.felord.payment.wechat.v2.WechatPayTransfersApi;
|
||||
import cn.felord.payment.wechat.v2.WechatV2Client;
|
||||
import cn.felord.payment.wechat.v3.ecommerce.WechatEcommerceApi;
|
||||
|
||||
/**
|
||||
* 微信支付工具.
|
||||
@@ -189,21 +189,6 @@ public class WechatApiProvider {
|
||||
return new WechatPayTransfersApi(wechatV2Client);
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信支付分账,基于V2
|
||||
*
|
||||
* @param tenantId the tenant id
|
||||
* @return wechat allocation api
|
||||
* @since 1.0.10.RELEASE
|
||||
*/
|
||||
public WechatAllocationApi allocationApi(String tenantId) {
|
||||
WechatMetaBean wechatMeta = wechatPayClient.signatureProvider()
|
||||
.wechatMetaContainer()
|
||||
.getWechatMeta(tenantId);
|
||||
WechatV2Client wechatV2Client = new WechatV2Client(wechatMeta);
|
||||
return new WechatAllocationApi(wechatV2Client);
|
||||
}
|
||||
|
||||
/**
|
||||
* 直连商户微信支付分账,基于V3
|
||||
*
|
||||
@@ -223,4 +208,103 @@ public class WechatApiProvider {
|
||||
public WechatPartnerProfitsharingApi partnerProfitsharingApi(String tenantId) {
|
||||
return new WechatPartnerProfitsharingApi(wechatPayClient, tenantId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 服务商品牌分账
|
||||
*
|
||||
* @param tenantId the tenant id
|
||||
* @return the wechat brand profitsharing api
|
||||
*/
|
||||
public WechatBrandProfitsharingApi brandProfitsharingApi(String tenantId) {
|
||||
return new WechatBrandProfitsharingApi(wechatPayClient, tenantId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信V3服务商-商户进件-特约商户进件
|
||||
*
|
||||
* @param tenantId the tenant id
|
||||
* @return wechat partner special mch api
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
public WechatPartnerSpecialMchApi partnerSpecialMchApi(String tenantId) {
|
||||
return new WechatPartnerSpecialMchApi(wechatPayClient, tenantId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 服务商或者直连商户-经营能力-支付即服务
|
||||
*
|
||||
* @param tenantId the tenant id
|
||||
* @return wechat smart guide api
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
public WechatSmartGuideApi smartGuideApi(String tenantId) {
|
||||
return new WechatSmartGuideApi(wechatPayClient, tenantId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 服务商-经营能力-点金计划
|
||||
*
|
||||
* @param tenantId the tenant id
|
||||
* @return the wechat gold plan api
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
public WechatGoldPlanApi goldPlanApi(String tenantId) {
|
||||
return new WechatGoldPlanApi(wechatPayClient, tenantId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 服务商-行业方案-电商收付通
|
||||
*
|
||||
* @param tenantId the tenant id
|
||||
* @return the wechat ecommerce api
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
public WechatEcommerceApi ecommerceApi(String tenantId) {
|
||||
return new WechatEcommerceApi(wechatPayClient, tenantId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 服务商智慧商圈
|
||||
*
|
||||
* @param tenantId the tenant id
|
||||
* @return the wechat business circle api
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
public WechatPartnerBusinessCircleApi partnerBusinessCircleApi(String tenantId) {
|
||||
return new WechatPartnerBusinessCircleApi(wechatPayClient, tenantId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 直连商户智慧商圈
|
||||
*
|
||||
* @param tenantId the tenant id
|
||||
* @return the wechat business circle api
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
public WechatBusinessCircleApi businessCircleApi(String tenantId) {
|
||||
return new WechatBusinessCircleApi(wechatPayClient, tenantId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 其它能力-媒体上传
|
||||
*
|
||||
* @param tenantId the tenant id
|
||||
* @return the wechat media api
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
public WechatMediaApi mediaApi(String tenantId) {
|
||||
return new WechatMediaApi(wechatPayClient, tenantId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 其它能力-银行组件(服务商)
|
||||
*
|
||||
* @param tenantId the tenant id
|
||||
* @return the wechat media api
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
public WechatCapitalApi capitalApi(String tenantId) {
|
||||
return new WechatCapitalApi(wechatPayClient, tenantId);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -82,8 +82,10 @@ public class WechatBatchTransferApi extends AbstractApi {
|
||||
List<CreateBatchTransferParams.TransferDetailListItem> encrypted = transferDetailList.stream()
|
||||
.peek(transferDetailListItem -> {
|
||||
String userName = transferDetailListItem.getUserName();
|
||||
String encryptedUserName = signatureProvider.encryptRequestMessage(userName, x509Certificate);
|
||||
transferDetailListItem.setUserName(encryptedUserName);
|
||||
if (StringUtils.hasText(userName)) {
|
||||
String encryptedUserName = signatureProvider.encryptRequestMessage(userName, x509Certificate);
|
||||
transferDetailListItem.setUserName(encryptedUserName);
|
||||
}
|
||||
String userIdCard = transferDetailListItem.getUserIdCard();
|
||||
if (StringUtils.hasText(userIdCard)) {
|
||||
String encryptedUserIdCard = signatureProvider.encryptRequestMessage(userIdCard, x509Certificate);
|
||||
@@ -196,8 +198,8 @@ public class WechatBatchTransferApi extends AbstractApi {
|
||||
this.client().withType(WechatPayV3Type.BATCH_TRANSFER_DETAIL_MCH, queryBatchTransferDetailParams)
|
||||
.function((type, params) -> {
|
||||
Map<String, String> pathParams = new HashMap<>(2);
|
||||
pathParams.put("batch_id", params.getBatchIdOrOutBatchNo());
|
||||
pathParams.put("detail_id", params.getDetailIdOrOutDetailNo());
|
||||
pathParams.put("out_batch_no", params.getBatchIdOrOutBatchNo());
|
||||
pathParams.put("out_detail_no", params.getDetailIdOrOutDetailNo());
|
||||
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
|
||||
@@ -0,0 +1,311 @@
|
||||
package cn.felord.payment.wechat.v3;
|
||||
|
||||
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.ecommerce.BrandReceiver;
|
||||
import cn.felord.payment.wechat.v3.model.ecommerce.BrandReceiverDeleteParams;
|
||||
import cn.felord.payment.wechat.v3.model.ecommerce.EcommerceFinishOrder;
|
||||
import cn.felord.payment.wechat.v3.model.ecommerce.EcommerceReturnOrderParams;
|
||||
import cn.felord.payment.wechat.v3.model.profitsharing.BrandProfitsharingOrder;
|
||||
import cn.felord.payment.wechat.v3.model.profitsharing.PartnerProfitsharingBillParams;
|
||||
import cn.felord.payment.wechat.v3.model.profitsharing.PartnerQueryOrderParams;
|
||||
import cn.felord.payment.wechat.v3.model.profitsharing.PartnerReturnOrdersParams;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
import java.net.URI;
|
||||
import java.time.LocalDate;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 服务商-资金应用-连锁品牌分账
|
||||
*
|
||||
* @author felord.cn
|
||||
* @since 1.0.15
|
||||
*/
|
||||
public class WechatBrandProfitsharingApi extends AbstractApi {
|
||||
|
||||
/**
|
||||
* Instantiates a new Abstract api.
|
||||
*
|
||||
* @param wechatPayClient the wechat pay client
|
||||
* @param tenantId the tenant id
|
||||
*/
|
||||
public WechatBrandProfitsharingApi(WechatPayClient wechatPayClient, String tenantId) {
|
||||
super(wechatPayClient, tenantId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求分账API
|
||||
*
|
||||
* @param brandProfitsharingOrder the brand profitsharing order
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> profitsharingOrders(BrandProfitsharingOrder brandProfitsharingOrder) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.BRAND_PROFITSHARING_ORDERS, brandProfitsharingOrder)
|
||||
.function((wechatPayV3Type, params) -> {
|
||||
params.setAppid(this.wechatMetaBean().getV3().getAppId());
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.toUri();
|
||||
return Post(uri, params);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询分账结果API
|
||||
* <p>
|
||||
* 发起分账请求后,可调用此接口查询分账结果
|
||||
* <p>
|
||||
* 注意:
|
||||
* <ul>
|
||||
* <li>发起解冻剩余资金请求后,可调用此接口查询解冻剩余资金的结果</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param queryOrderParams the query order params
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> queryProfitsharingOrder(PartnerQueryOrderParams queryOrderParams) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.BRAND_PROFITSHARING_RESULT, queryOrderParams)
|
||||
.function((wechatPayV3Type, params) -> {
|
||||
MultiValueMap<String, String> queryParams = new LinkedMultiValueMap<>();
|
||||
queryParams.add("sub_mchid", params.getSubMchid());
|
||||
queryParams.add("transaction_id", params.getTransactionId());
|
||||
queryParams.add("out_order_no", params.getOutOrderNo());
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA))
|
||||
.queryParams(queryParams)
|
||||
.build()
|
||||
.toUri();
|
||||
return Get(uri);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求分账回退API
|
||||
* <p>
|
||||
* 如果订单已经分账,在退款时,可以先调此接口,将已分账的资金从分账接收方的账户回退给分账方,再发起退款
|
||||
*
|
||||
* @param returnOrdersParams the return orders params
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> returnOrders(PartnerReturnOrdersParams returnOrdersParams) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.BRAND_PROFITSHARING_RETURN_ORDERS, returnOrdersParams)
|
||||
.function((wechatPayV3Type, params) -> {
|
||||
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.toUri();
|
||||
return Post(uri, params);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询分账回退结果API
|
||||
* <p>
|
||||
* 商户需要核实回退结果,可调用此接口查询回退结果
|
||||
* <p>
|
||||
* 注意:
|
||||
* <ul>
|
||||
* <li>如果分账回退接口返回状态为处理中,可调用此接口查询回退结果</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param queryReturnOrderParams the query return order params
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> queryReturnOrders(EcommerceReturnOrderParams queryReturnOrderParams) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.BRAND_PROFITSHARING_RETURN_ORDERS_RESULT, queryReturnOrderParams)
|
||||
.function((wechatPayV3Type, params) -> {
|
||||
MultiValueMap<String, String> queryParams = new LinkedMultiValueMap<>();
|
||||
queryParams.add("sub_mchid", params.getSubMchid());
|
||||
String orderId = params.getOrderId();
|
||||
if (orderId != null) {
|
||||
queryParams.add("order_id", orderId);
|
||||
}
|
||||
String outOrderNo = params.getOutOrderNo();
|
||||
if (outOrderNo != null) {
|
||||
queryParams.add("out_order_no", outOrderNo);
|
||||
}
|
||||
queryParams.add("out_return_no", params.getOutReturnNo());
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA))
|
||||
.queryParams(queryParams)
|
||||
.build()
|
||||
.toUri();
|
||||
return Get(uri);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 完结分账API
|
||||
* <p>
|
||||
* 不需要进行分账的订单,可直接调用本接口将订单的金额全部解冻给二级商户。
|
||||
*
|
||||
* @param finishOrder the finish order
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> finishOrder(EcommerceFinishOrder finishOrder) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.BRAND_PROFITSHARING_FINISH_ORDER, finishOrder)
|
||||
.function((wechatPayV3Type, params) -> {
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.toUri();
|
||||
return Post(uri, params);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询订单剩余待分金额API
|
||||
* <p>
|
||||
* 可调用此接口查询订单剩余待分金额
|
||||
*
|
||||
* @param transactionId the transaction id
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> queryOrderAmounts(String transactionId) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.BRAND_PROFITSHARING_ORDER_AMOUNTS, transactionId)
|
||||
.function((wechatPayV3Type, id) -> {
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.expand(id)
|
||||
.toUri();
|
||||
return Get(uri);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询最大分账比例API
|
||||
*
|
||||
* @param brandMchid the brandMchid
|
||||
* @return wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> brandConfigs(String brandMchid) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.BRAND_CONFIGS, brandMchid)
|
||||
.function((wechatPayV3Type, id) -> {
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.expand(id)
|
||||
.toUri();
|
||||
return Get(uri);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加分账接收方API
|
||||
* <p>
|
||||
* 商户发起添加分账接收方请求,建立分账接收方列表。后续可通过发起分账请求,将分账方商户结算后的资金,分到该分账接收方
|
||||
*
|
||||
* @param brandReceiver the brandReceiver
|
||||
* @return wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> addReceivers(BrandReceiver brandReceiver) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.BRAND_PROFITSHARING_RECEIVERS_ADD, brandReceiver)
|
||||
.function((wechatPayV3Type, params) -> {
|
||||
WechatPayProperties.V3 v3 = this.wechatMetaBean().getV3();
|
||||
params.setAppid(v3.getAppId());
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.toUri();
|
||||
return Post(uri, params);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除分账接收方API
|
||||
* <p>
|
||||
* 商户发起删除分账接收方请求。删除后,不支持将分账方商户结算后的资金,分到该分账接收方
|
||||
*
|
||||
* @param delReceiversParams the del receivers params
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> deleteReceivers(BrandReceiverDeleteParams delReceiversParams) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.BRAND_PROFITSHARING_RECEIVERS_DELETE, delReceiversParams)
|
||||
.function((wechatPayV3Type, params) -> {
|
||||
WechatPayProperties.V3 v3 = this.wechatMetaBean().getV3();
|
||||
params.setAppid(v3.getAppId());
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.toUri();
|
||||
return Post(uri, params);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 申请分账账单API
|
||||
*
|
||||
* @param billParams the bill params
|
||||
* @return the response entity
|
||||
*/
|
||||
public ResponseEntity<Resource> downloadMerchantBills(PartnerProfitsharingBillParams billParams) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.PROFITSHARING_BILLS, billParams)
|
||||
.function(((wechatPayV3Type, params) -> {
|
||||
MultiValueMap<String, String> queryParams = new LinkedMultiValueMap<>();
|
||||
String subMchid = params.getSubMchid();
|
||||
if (subMchid != null) {
|
||||
queryParams.add("sub_mchid", subMchid);
|
||||
}
|
||||
LocalDate billDate = params.getBillDate();
|
||||
queryParams.add("bill_date", billDate.format(DateTimeFormatter.ISO_DATE));
|
||||
TarType tarType = params.getTarType();
|
||||
if (Objects.nonNull(tarType)) {
|
||||
queryParams.add("tar_type", tarType.name());
|
||||
}
|
||||
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA))
|
||||
.queryParams(queryParams)
|
||||
.build()
|
||||
.toUri();
|
||||
return Get(uri);
|
||||
})).consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
String downloadUrl = Objects.requireNonNull(wechatResponseEntity.getBody())
|
||||
.get("download_url")
|
||||
.asText();
|
||||
|
||||
String ext = Objects.equals(TarType.GZIP, billParams.getTarType()) ? ".gzip" : ".txt";
|
||||
String filename = "profitsharingbill-" + billParams.getBillDate().toString() + ext;
|
||||
return this.downloadBillResponse(downloadUrl, filename);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* 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.busicircle.MallScoreParams;
|
||||
import cn.felord.payment.wechat.v3.model.busicircle.MallScoreSyncRequest;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
/**
|
||||
* 直连商户智慧商圈
|
||||
*
|
||||
* @author felord.cn
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
public class WechatBusinessCircleApi extends AbstractApi {
|
||||
/**
|
||||
* Instantiates a new Abstract api.
|
||||
*
|
||||
* @param wechatPayClient the wechat pay client
|
||||
* @param tenantId the tenant id
|
||||
*/
|
||||
public WechatBusinessCircleApi(WechatPayClient wechatPayClient, String tenantId) {
|
||||
super(wechatPayClient, tenantId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 商圈积分同步API
|
||||
*
|
||||
* @param request the request
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> apply(MallScoreSyncRequest request) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.MALL_SCORE_SYNC, request)
|
||||
.function((wechatPayV3Type, mallScoreSyncRequest) -> {
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.toUri();
|
||||
return Post(uri, mallScoreSyncRequest);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 商圈积分授权查询API
|
||||
*
|
||||
* @param params the params
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> queryAuthStatus(MallScoreParams params) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.MALL_SCORE_RESULT, params)
|
||||
.function((type, mallScoreParams) -> {
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA))
|
||||
.queryParam("appid", mallScoreParams.getAppid())
|
||||
.build()
|
||||
.expand(mallScoreParams.getOpenid())
|
||||
.toUri();
|
||||
return Get(uri);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
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.PageParams;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
import java.net.URI;
|
||||
import java.security.cert.X509Certificate;
|
||||
|
||||
/**
|
||||
* 其它能力-银行组件(服务商)
|
||||
* <p>
|
||||
* 具体参见 <a href="https://pay.weixin.qq.com/wiki/doc/apiv3_partner/Offline/apis/chapter11_2_1.shtml">银行组件</a>
|
||||
*
|
||||
* @author felord.cn
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
public class WechatCapitalApi extends AbstractApi{
|
||||
/**
|
||||
* Instantiates a new Abstract api.
|
||||
*
|
||||
* @param wechatPayClient the wechat pay client
|
||||
* @param tenantId the tenant id
|
||||
*/
|
||||
public WechatCapitalApi(WechatPayClient wechatPayClient, String tenantId) {
|
||||
super(wechatPayClient, tenantId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取对私银行卡号开户银行API
|
||||
*
|
||||
* @param accountNumber accountNumber
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> searchBanksByBankAccount(String accountNumber) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.CAPITAL_SEARCH, accountNumber)
|
||||
.function((type, param) -> {
|
||||
SignatureProvider signatureProvider = this.client().signatureProvider();
|
||||
X509WechatCertificateInfo certificate = signatureProvider.getCertificate(this.wechatMetaBean().getTenantId());
|
||||
final X509Certificate x509Certificate = certificate.getX509Certificate();
|
||||
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA))
|
||||
.queryParam("account_number", signatureProvider.encryptRequestMessage(param,x509Certificate))
|
||||
.build()
|
||||
.toUri();
|
||||
return Get(uri);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询支持个人业务的银行列表API
|
||||
*
|
||||
* @param params the params
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> queryPersonalBanks(PageParams params) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.CAPITAL_PERSONAL, params)
|
||||
.function((type, pageParams) -> {
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA))
|
||||
.queryParam("offset", pageParams.getOffset())
|
||||
.queryParam("limit", pageParams.getLimit())
|
||||
.build()
|
||||
.toUri();
|
||||
return Get(uri);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询支持对公业务的银行列表API
|
||||
*
|
||||
* @param params the params
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> queryCorporateBanks(PageParams params) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.CAPITAL_CORPORATE, params)
|
||||
.function((type, pageParams) -> {
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA))
|
||||
.queryParam("offset", pageParams.getOffset())
|
||||
.queryParam("limit", pageParams.getLimit())
|
||||
.build()
|
||||
.toUri();
|
||||
return Get(uri);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询省份列表API
|
||||
*
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> queryProvinces() {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.CAPITAL_PROVINCES, "")
|
||||
.function((type, pageParams) -> {
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.toUri();
|
||||
return Get(uri);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询城市列表API
|
||||
*
|
||||
* @param provinceCode provinceCode
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> queryCitiesByProvince(Integer provinceCode) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.CAPITAL_CITIES, provinceCode)
|
||||
.function((type, code) -> {
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.expand(code)
|
||||
.toUri();
|
||||
return Get(uri);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询支行列表API
|
||||
*
|
||||
* @param params branchBanksPageParams
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> queryBranchBanks(BranchBanksPageParams params) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.CAPITAL_BRANCHES, params)
|
||||
.function((type, pageParams) -> {
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA))
|
||||
.queryParam("city_code", pageParams.getCityCode())
|
||||
.queryParam("offset", pageParams.getOffset())
|
||||
.queryParam("limit", pageParams.getLimit())
|
||||
.build()
|
||||
.expand(pageParams.getBankAliasCode())
|
||||
.toUri();
|
||||
return Get(uri);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
* 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.goldplan.GoldPlanChangeParams;
|
||||
import cn.felord.payment.wechat.v3.model.goldplan.GoldPlanAdvertisingParams;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Collections;
|
||||
|
||||
/**
|
||||
* 经营能力-点金计划
|
||||
*
|
||||
* @author felord.cn
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
public class WechatGoldPlanApi extends AbstractApi {
|
||||
/**
|
||||
* Instantiates a new Abstract api.
|
||||
*
|
||||
* @param wechatPayClient the wechat pay client
|
||||
* @param tenantId the tenant id
|
||||
*/
|
||||
public WechatGoldPlanApi(WechatPayClient wechatPayClient, String tenantId) {
|
||||
super(wechatPayClient, tenantId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 点金计划管理API
|
||||
*
|
||||
* @param params the params
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> change(GoldPlanChangeParams params) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.GOLD_PLAN_CHANGE, params)
|
||||
.function((wechatPayV3Type, goldPlanChangeParams) -> {
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.toUri();
|
||||
return Post(uri, goldPlanChangeParams);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 商家小票管理API
|
||||
*
|
||||
* @param params the params
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> changeCustom(GoldPlanChangeParams params) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.GOLD_PLAN_CHANGE_CUSTOM, params)
|
||||
.function((wechatPayV3Type, goldPlanChangeParams) -> {
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.toUri();
|
||||
return Post(uri, goldPlanChangeParams);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 同业过滤标签管理API
|
||||
*
|
||||
* @param params the params
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> filter(GoldPlanAdvertisingParams params) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.GOLD_PLAN_CHANGE_CUSTOM, params)
|
||||
.function((wechatPayV3Type, goldPlanChangeParams) -> {
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.toUri();
|
||||
return Post(uri, goldPlanChangeParams);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 开通广告展示API
|
||||
*
|
||||
* @param params the params
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> openAdv(GoldPlanAdvertisingParams params) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.GOLD_PLAN_ADV_OPEN, params)
|
||||
.function((wechatPayV3Type, goldPlanChangeParams) -> {
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.toUri();
|
||||
return Post(uri, goldPlanChangeParams);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭广告展示API
|
||||
*
|
||||
* @param subMchid the sub mchid
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> closeAdv(String subMchid) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.GOLD_PLAN_ADV_CLOSE, subMchid)
|
||||
.function((wechatPayV3Type, id) -> {
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.toUri();
|
||||
return Post(uri, Collections.singletonMap("sub_mchid",id));
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
}
|
||||
@@ -360,7 +360,7 @@ public class WechatMarketingBusiFavorApi extends AbstractApi {
|
||||
.expand(budgetParams.getStockId())
|
||||
.toUri();
|
||||
budgetParams.setStockId(null);
|
||||
return Post(uri, budgetParams);
|
||||
return Patch(uri, budgetParams);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* 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 com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import lombok.SneakyThrows;
|
||||
import org.bouncycastle.jcajce.provider.digest.SHA256;
|
||||
import org.bouncycastle.util.encoders.Hex;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.RequestEntity;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 其它能力-媒体上传
|
||||
*
|
||||
* @author felord.cn
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
public class WechatMediaApi extends AbstractApi {
|
||||
|
||||
/**
|
||||
* Instantiates a new Abstract api.
|
||||
*
|
||||
* @param wechatPayClient the wechat pay client
|
||||
* @param tenantId the tenant id
|
||||
*/
|
||||
public WechatMediaApi(WechatPayClient wechatPayClient, String tenantId) {
|
||||
super(wechatPayClient, tenantId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 图片上传API
|
||||
*
|
||||
* @param file the file
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> mediaImageUpload(MultipartFile file) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.MERCHANT_MEDIA_IMG, file)
|
||||
.function(this::uploadFunction)
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 视频上传API
|
||||
*
|
||||
* @param file the file
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> mediaVideoUpload(MultipartFile file) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.MERCHANT_MEDIA_VIDEO, file)
|
||||
.function(this::uploadFunction)
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
@SneakyThrows
|
||||
private RequestEntity<?> uploadFunction(WechatPayV3Type type, MultipartFile file) {
|
||||
|
||||
Map<String, Object> meta = new LinkedHashMap<>(2);
|
||||
|
||||
String originalFilename = file.getOriginalFilename();
|
||||
String filename = StringUtils.hasText(originalFilename) ? originalFilename : file.getName();
|
||||
meta.put("filename", filename);
|
||||
|
||||
byte[] digest = SHA256.Digest.getInstance("SHA-256").digest(file.getBytes());
|
||||
meta.put("sha256", Hex.toHexString(digest));
|
||||
MultiValueMap<Object, Object> body = new LinkedMultiValueMap<>();
|
||||
body.add("meta", meta);
|
||||
body.add("file", file.getResource());
|
||||
// 签名
|
||||
String metaStr = this.getMapper().writeValueAsString(meta);
|
||||
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.toUri();
|
||||
return RequestEntity.post(uri)
|
||||
.header("Content-Type", MediaType.MULTIPART_FORM_DATA_VALUE)
|
||||
.header("Meta-Info", metaStr)
|
||||
.header("Pay-TenantId", tenantId())
|
||||
.body(body);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* 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.busicircle.PartnerMallScoreParams;
|
||||
import cn.felord.payment.wechat.v3.model.busicircle.PartnerMallScoreSyncRequest;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
/**
|
||||
* 服务商智慧商圈
|
||||
*
|
||||
* @author felord.cn
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
public class WechatPartnerBusinessCircleApi extends AbstractApi {
|
||||
/**
|
||||
* Instantiates a new Abstract api.
|
||||
*
|
||||
* @param wechatPayClient the wechat pay client
|
||||
* @param tenantId the tenant id
|
||||
*/
|
||||
public WechatPartnerBusinessCircleApi(WechatPayClient wechatPayClient, String tenantId) {
|
||||
super(wechatPayClient, tenantId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 商圈积分同步API
|
||||
*
|
||||
* @param request the request
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> apply(PartnerMallScoreSyncRequest request) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.MALL_SCORE_SYNC, request)
|
||||
.function((wechatPayV3Type, mallScoreSyncRequest) -> {
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.toUri();
|
||||
return Post(uri, mallScoreSyncRequest);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 商圈积分授权查询API
|
||||
*
|
||||
* @param params the params
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> queryAuthStatus(PartnerMallScoreParams params) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.MALL_SCORE_RESULT, params)
|
||||
.function((type, mallScoreParams) -> {
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA))
|
||||
.queryParam("sub_mchid", mallScoreParams.getSubMchid())
|
||||
.queryParam("appid", mallScoreParams.getAppid())
|
||||
.build()
|
||||
.expand(mallScoreParams.getOpenid())
|
||||
.toUri();
|
||||
return Get(uri);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,8 @@ import cn.felord.payment.PayException;
|
||||
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.RefundQueryParams;
|
||||
import cn.felord.payment.wechat.v3.model.TransactionQueryParams;
|
||||
import cn.felord.payment.wechat.v3.model.partner.CloseTransParams;
|
||||
import cn.felord.payment.wechat.v3.model.partner.PartnerPayParams;
|
||||
@@ -212,6 +214,61 @@ public class WechatPartnerPayApi extends AbstractApi {
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 申请退款API
|
||||
*
|
||||
* @param refundParams the refund params
|
||||
* @return the wechat response entity
|
||||
* @since 1.0.15-SNAPSHOT
|
||||
*/
|
||||
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();
|
||||
params.setNotifyUrl(v3.getDomain().concat(params.getNotifyUrl()));
|
||||
return Post(uri, params);
|
||||
}))
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 商户退款订单查询API
|
||||
*
|
||||
* @param params the params
|
||||
* @return the wechat response entity
|
||||
* @since 1.0.15-SNAPSHOT
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> queryRefundInfo(RefundQueryParams params) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.QUERY_REFUND, params)
|
||||
.function(this::queryRefundFunction)
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
private RequestEntity<?> queryRefundFunction(WechatPayV3Type type, RefundQueryParams params) {
|
||||
MultiValueMap<String, String> queryParams = new LinkedMultiValueMap<>();
|
||||
// queryParams.add("out_refund_no", params.getRefundOrderNo());
|
||||
queryParams.add("sub_mchid", params.getSubMchid());
|
||||
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA))
|
||||
.queryParams(queryParams)
|
||||
.build()
|
||||
.expand(params.getRefundOrderNo())
|
||||
.toUri();
|
||||
return Get(uri);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 商户订单号查询API
|
||||
*
|
||||
|
||||
@@ -17,11 +17,15 @@
|
||||
package cn.felord.payment.wechat.v3;
|
||||
|
||||
import cn.felord.payment.wechat.WechatPayProperties;
|
||||
import cn.felord.payment.wechat.enumeration.ReceiverType;
|
||||
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.profitsharing.*;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
@@ -30,7 +34,10 @@ import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
import java.net.URI;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.time.LocalDate;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -117,9 +124,8 @@ public class WechatPartnerProfitsharingApi extends AbstractApi {
|
||||
this.client().withType(WechatPayV3Type.PROFITSHARING_ORDERS_RESULT, queryOrderParams)
|
||||
.function((wechatPayV3Type, params) -> {
|
||||
MultiValueMap<String, String> queryParams = new LinkedMultiValueMap<>();
|
||||
queryParams.add("sub_mchid", params.getSubMchid());
|
||||
queryParams.add("transaction_id", params.getTransactionId());
|
||||
Optional.ofNullable(params.getSubMchid())
|
||||
.ifPresent(mchId -> queryParams.add("sub_mchid", params.getSubMchid()));
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA))
|
||||
.queryParams(queryParams)
|
||||
.build()
|
||||
@@ -291,9 +297,9 @@ public class WechatPartnerProfitsharingApi extends AbstractApi {
|
||||
X509WechatCertificateInfo certificate = signatureProvider.getCertificate(this.wechatMetaBean().getTenantId());
|
||||
final X509Certificate x509Certificate = certificate.getX509Certificate();
|
||||
params.setAppid(v3.getAppId());
|
||||
String name = params.getName();
|
||||
if (StringUtils.hasText(name)) {
|
||||
String encryptedName = signatureProvider.encryptRequestMessage(name, x509Certificate);
|
||||
|
||||
if (ReceiverType.MERCHANT_ID.equals(params.getType())) {
|
||||
String encryptedName = signatureProvider.encryptRequestMessage(params.getName(), x509Certificate);
|
||||
params.setName(encryptedName);
|
||||
}
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA))
|
||||
@@ -331,4 +337,42 @@ public class WechatPartnerProfitsharingApi extends AbstractApi {
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 申请分账账单API
|
||||
*
|
||||
* @param billParams the bill params
|
||||
* @return the response entity
|
||||
*/
|
||||
public ResponseEntity<Resource> downloadMerchantBills(PartnerProfitsharingBillParams billParams){
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.PROFITSHARING_BILLS,billParams)
|
||||
.function(((wechatPayV3Type, params) -> {
|
||||
MultiValueMap<String, String> queryParams = new LinkedMultiValueMap<>();
|
||||
String subMchid = params.getSubMchid();
|
||||
if (subMchid !=null){
|
||||
queryParams.add("sub_mchid",subMchid);
|
||||
}
|
||||
LocalDate billDate = params.getBillDate();
|
||||
queryParams.add("bill_date", billDate.format(DateTimeFormatter.ISO_DATE));
|
||||
TarType tarType = params.getTarType();
|
||||
if (Objects.nonNull(tarType)) {
|
||||
queryParams.add("tar_type", tarType.name());
|
||||
}
|
||||
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA))
|
||||
.queryParams(queryParams)
|
||||
.build()
|
||||
.toUri();
|
||||
return Get(uri);
|
||||
})).consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
String downloadUrl = Objects.requireNonNull(wechatResponseEntity.getBody())
|
||||
.get("download_url")
|
||||
.asText();
|
||||
|
||||
String ext = Objects.equals(TarType.GZIP, billParams.getTarType()) ? ".gzip" : ".txt";
|
||||
String filename = "profitsharingbill-" + billParams.getBillDate().toString() + ext;
|
||||
return this.downloadBillResponse(downloadUrl, filename);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,231 @@
|
||||
/*
|
||||
* 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.specmch.*;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
import java.net.URI;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 微信V3服务商-商户进件-特约商户进件
|
||||
* <p>
|
||||
* 参见<a href="https://pay.weixin.qq.com/wiki/doc/apiv3_partner/open/pay/chapter7_1_1.shtml">产品介绍</a>
|
||||
*
|
||||
* @author felord.cn
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
public class WechatPartnerSpecialMchApi extends AbstractApi {
|
||||
/**
|
||||
* Instantiates a new Abstract api.
|
||||
*
|
||||
* @param wechatPayClient the wechat pay client
|
||||
* @param tenantId the tenant id
|
||||
*/
|
||||
public WechatPartnerSpecialMchApi(WechatPayClient wechatPayClient, String tenantId) {
|
||||
super(wechatPayClient, tenantId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 提交申请单API
|
||||
* <p>
|
||||
* 服务商(银行、支付机构、电商平台不可用)使用该接口提交商家资料,帮助商家入驻成为微信支付的特约商户。
|
||||
* 流程指引请看 <a href="https://pay.weixin.qq.com/wiki/doc/apiv3_partner/open/pay/chapter7_1_2.shtml#part-6">特约商户进件流程</a>
|
||||
*
|
||||
* @param params the params
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> apply(ApplymentParams params) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.SPEC_MCH_APPLY_PARTNER, params)
|
||||
.function((wechatPayV3Type, applymentParams) -> {
|
||||
SignatureProvider signatureProvider = this.client().signatureProvider();
|
||||
X509WechatCertificateInfo certificate = signatureProvider.getCertificate(this.wechatMetaBean().getTenantId());
|
||||
final X509Certificate x509Certificate = certificate.getX509Certificate();
|
||||
ApplymentParams applyRequestParams = this.convert(applymentParams, signatureProvider, x509Certificate);
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.toUri();
|
||||
HttpHeaders httpHeaders = new HttpHeaders();
|
||||
httpHeaders.add("Wechatpay-Serial", certificate.getWechatPaySerial());
|
||||
return Post(uri, applyRequestParams, httpHeaders);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过业务申请编号查询申请状态
|
||||
*
|
||||
* @param businessCode the business code
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> queryByBusinessCode(String businessCode) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.SPEC_MCH_APPLY_QUERY_BUSINESS_CODE, businessCode)
|
||||
.function((type, id) -> {
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.expand(id)
|
||||
.toUri();
|
||||
return Get(uri);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过申请单号查询申请状态
|
||||
*
|
||||
* @param applymentId the applyment id
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> queryByApplymentId(String applymentId) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.SPEC_MCH_APPLY_QUERY_APPLYMENT_ID, applymentId)
|
||||
.function((type, id) -> {
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.expand(id)
|
||||
.toUri();
|
||||
return Get(uri);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改结算账号API
|
||||
* <p>
|
||||
* 服务商/电商平台(不包括支付机构、银行),可使用本接口,修改其进件且已签约特约商户/二级商户的结算银行账户。
|
||||
*
|
||||
* @param params the params
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> modify(SubMchModifyParams params) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.SPEC_MCH_SUB_MODIFY, params)
|
||||
.function((type, subMchModifyParams) -> {
|
||||
SignatureProvider signatureProvider = this.client().signatureProvider();
|
||||
X509WechatCertificateInfo certificate = signatureProvider.getCertificate(this.wechatMetaBean().getTenantId());
|
||||
final X509Certificate x509Certificate = certificate.getX509Certificate();
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.expand(subMchModifyParams.getSubMchid())
|
||||
.toUri();
|
||||
|
||||
subMchModifyParams.setSubMchid(null);
|
||||
subMchModifyParams.setAccountNumber(signatureProvider.encryptRequestMessage(subMchModifyParams.getAccountNumber(), x509Certificate));
|
||||
HttpHeaders httpHeaders = new HttpHeaders();
|
||||
httpHeaders.add("Wechatpay-Serial", certificate.getWechatPaySerial());
|
||||
return Post(uri, subMchModifyParams, httpHeaders);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询结算账户API
|
||||
* <p>
|
||||
* 服务商/电商平台(不包括支付机构、银行),可使用本接口,查询其进件且已签约特约商户/二级商户的结算账户信息(敏感信息掩码)。
|
||||
* 该接口可用于核实是否成功修改结算账户信息、及查询系统汇款验证结果。
|
||||
*
|
||||
* @param subMchid the sub mchid
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> querySettlement(String subMchid) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.SPEC_MCH_SUB_SETTLEMENT, subMchid)
|
||||
.function((type, id) -> {
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.expand(id)
|
||||
.toUri();
|
||||
return Get(uri);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
private ApplymentParams convert(ApplymentParams applymentParams, SignatureProvider signatureProvider, final X509Certificate x509Certificate) {
|
||||
|
||||
ContactInfo contactInfo = applymentParams.getContactInfo();
|
||||
contactInfo.setContactName(signatureProvider.encryptRequestMessage(contactInfo.getContactName(), x509Certificate));
|
||||
String contactIdNumber = contactInfo.getContactIdNumber();
|
||||
if (contactIdNumber != null) {
|
||||
contactInfo.setContactIdNumber(signatureProvider.encryptRequestMessage(contactIdNumber, x509Certificate));
|
||||
}
|
||||
String openid = contactInfo.getOpenid();
|
||||
if (openid != null) {
|
||||
contactInfo.setOpenid(signatureProvider.encryptRequestMessage(openid, x509Certificate));
|
||||
}
|
||||
contactInfo.setMobilePhone(signatureProvider.encryptRequestMessage(contactInfo.getMobilePhone(), x509Certificate));
|
||||
contactInfo.setContactEmail(signatureProvider.encryptRequestMessage(contactInfo.getContactEmail(), x509Certificate));
|
||||
|
||||
SubjectInfo subjectInfo = applymentParams.getSubjectInfo();
|
||||
IdentityInfo identityInfo = subjectInfo.getIdentityInfo();
|
||||
|
||||
IdCardInfo idCardInfo = identityInfo.getIdCardInfo();
|
||||
if (idCardInfo != null) {
|
||||
idCardInfo.setIdCardName(signatureProvider.encryptRequestMessage(idCardInfo.getIdCardName(), x509Certificate));
|
||||
idCardInfo.setIdCardNumber(signatureProvider.encryptRequestMessage(idCardInfo.getIdCardNumber(), x509Certificate));
|
||||
String idCardAddress = idCardInfo.getIdCardAddress();
|
||||
if (StringUtils.hasText(idCardAddress)){
|
||||
idCardInfo.setIdCardAddress(signatureProvider.encryptRequestMessage(idCardAddress, x509Certificate));
|
||||
}
|
||||
}
|
||||
IdDocInfo idDocInfo = identityInfo.getIdDocInfo();
|
||||
if (idDocInfo != null) {
|
||||
idDocInfo.setIdDocName(signatureProvider.encryptRequestMessage(idDocInfo.getIdDocName(), x509Certificate));
|
||||
idDocInfo.setIdDocNumber(signatureProvider.encryptRequestMessage(idDocInfo.getIdDocNumber(), x509Certificate));
|
||||
String idDocAddress = idDocInfo.getIdDocAddress();
|
||||
if (StringUtils.hasText(idDocAddress)){
|
||||
idDocInfo.setIdDocAddress(signatureProvider.encryptRequestMessage(idDocAddress, x509Certificate));
|
||||
}
|
||||
}
|
||||
List<UboInfoListItem> uboInfoList = subjectInfo.getUboInfoList();
|
||||
if (!CollectionUtils.isEmpty(uboInfoList)) {
|
||||
uboInfoList.forEach(uboInfoListItem -> {
|
||||
uboInfoListItem.setUboIdDocName(signatureProvider.encryptRequestMessage(uboInfoListItem.getUboIdDocName(), x509Certificate));
|
||||
uboInfoListItem.setUboIdDocNumber(signatureProvider.encryptRequestMessage(uboInfoListItem.getUboIdDocNumber(), x509Certificate));
|
||||
uboInfoListItem.setUboIdDocAddress(signatureProvider.encryptRequestMessage(uboInfoListItem.getUboIdDocAddress(), x509Certificate));
|
||||
});
|
||||
}
|
||||
|
||||
BankAccountInfo bankAccountInfo = applymentParams.getBankAccountInfo();
|
||||
|
||||
bankAccountInfo.setAccountName(signatureProvider.encryptRequestMessage(bankAccountInfo.getAccountName(), x509Certificate));
|
||||
bankAccountInfo.setAccountNumber(signatureProvider.encryptRequestMessage(bankAccountInfo.getAccountNumber(), x509Certificate));
|
||||
|
||||
return applymentParams;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -18,12 +18,9 @@
|
||||
package cn.felord.payment.wechat.v3;
|
||||
|
||||
import cn.felord.payment.PayException;
|
||||
import cn.felord.payment.wechat.v3.model.CallbackParams;
|
||||
import cn.felord.payment.wechat.v3.model.CouponConsumeData;
|
||||
import cn.felord.payment.wechat.v3.model.ProfitSharingConsumeData;
|
||||
import cn.felord.payment.wechat.v3.model.RefundConsumeData;
|
||||
import cn.felord.payment.wechat.v3.model.ResponseSignVerifyParams;
|
||||
import cn.felord.payment.wechat.v3.model.TransactionConsumeData;
|
||||
import cn.felord.payment.wechat.v3.model.*;
|
||||
import cn.felord.payment.wechat.v3.model.busicircle.MallRefundConsumeData;
|
||||
import cn.felord.payment.wechat.v3.model.busicircle.MallTransactionConsumeData;
|
||||
import cn.felord.payment.wechat.v3.model.busifavor.BusiFavorReceiveConsumeData;
|
||||
import cn.felord.payment.wechat.v3.model.combine.CombineTransactionConsumeData;
|
||||
import cn.felord.payment.wechat.v3.model.discountcard.DiscountCardAcceptedConsumeData;
|
||||
@@ -36,12 +33,13 @@ import cn.felord.payment.wechat.v3.model.payscore.PayScoreUserPaidConsumeData;
|
||||
import cn.felord.payment.wechat.v3.model.payscore.PayScoreUserPermissionConsumeData;
|
||||
import cn.felord.payment.wechat.v3.model.payscore.parking.ParkingCallback;
|
||||
import cn.felord.payment.wechat.v3.model.payscore.parking.TransParkingCallback;
|
||||
import cn.felord.payment.wechat.v3.model.profitsharing.PartnerProfitsharingConsumeData;
|
||||
import cn.felord.payment.wechat.v3.model.profitsharing.ProfitsharingConsumeData;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
|
||||
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
|
||||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -78,7 +76,7 @@ public class WechatPayCallback {
|
||||
private final String tenantId;
|
||||
|
||||
static {
|
||||
MAPPER.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE)
|
||||
MAPPER.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE)
|
||||
.setSerializationInclusion(JsonInclude.Include.NON_NULL)
|
||||
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
|
||||
.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true)
|
||||
@@ -243,7 +241,8 @@ public class WechatPayCallback {
|
||||
* <li>如果在所有通知频率后没有收到微信侧回调,商户应调用查询订单接口确认订单状态。</li>
|
||||
* </ul>
|
||||
* 特别提醒:商户系统对于支付成功通知的内容一定要做签名验证,并校验通知的信息是否与商户侧的信息一致,防止数据泄露导致出现“假通知”,造成资金损失。
|
||||
* @param params the params
|
||||
*
|
||||
* @param params the params
|
||||
* @param transParkingCallbackConsumer the transParkingCallbackConsumer
|
||||
* @return the map
|
||||
* @since 1.0.13.RELEASE
|
||||
@@ -388,7 +387,35 @@ public class WechatPayCallback {
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信支付分账V3动账通知
|
||||
* 服务商退款结果通知API,电商收付通复用
|
||||
* <p>
|
||||
* 退款状态改变后,微信会把相关退款结果发送给商户。
|
||||
*
|
||||
* @param params the params
|
||||
* @param consumeDataConsumer the consume data consumer
|
||||
* @return map map
|
||||
*/
|
||||
@SneakyThrows
|
||||
public Map<String, String> partnerRefundCallback(ResponseSignVerifyParams params, Consumer<PartnerRefundConsumeData> consumeDataConsumer) {
|
||||
CallbackParams callbackParams = resolve(params);
|
||||
String eventType = callbackParams.getEventType();
|
||||
|
||||
if (!(Objects.equals(eventType, EventType.REFUND_CLOSED.event) ||
|
||||
Objects.equals(eventType, EventType.REFUND_ABNORMAL.event) ||
|
||||
Objects.equals(eventType, EventType.REFUND_SUCCESS.event))) {
|
||||
log.error("wechat pay event type is not matched, callbackParams {}", callbackParams);
|
||||
throw new PayException(" wechat pay event type is not matched");
|
||||
}
|
||||
String data = this.decrypt(callbackParams);
|
||||
PartnerRefundConsumeData consumeData = MAPPER.readValue(data, PartnerRefundConsumeData.class);
|
||||
|
||||
consumeDataConsumer.accept(consumeData);
|
||||
return response();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 直连商户-微信支付分账V3动账通知
|
||||
*
|
||||
* @param params the params
|
||||
* @param profitsharingConsumeDataConsumer the profitsharing consume data consumer
|
||||
@@ -402,6 +429,55 @@ public class WechatPayCallback {
|
||||
return response();
|
||||
}
|
||||
|
||||
/**
|
||||
* 服务商-微信支付分账V3动账通知(电商收付通复用)
|
||||
*
|
||||
* @param params the params
|
||||
* @param profitsharingConsumeDataConsumer the profitsharing consume data consumer
|
||||
* @return map map
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
@SneakyThrows
|
||||
public Map<String, String> partnerProfitsharingCallback(ResponseSignVerifyParams params, Consumer<PartnerProfitsharingConsumeData> profitsharingConsumeDataConsumer) {
|
||||
String callback = this.callback(params, EventType.TRANSACTION_SUCCESS);
|
||||
PartnerProfitsharingConsumeData consumeData = MAPPER.readValue(callback, PartnerProfitsharingConsumeData.class);
|
||||
profitsharingConsumeDataConsumer.accept(consumeData);
|
||||
return response();
|
||||
}
|
||||
|
||||
/**
|
||||
* 服务商、直连商户 智慧商圈支付回调
|
||||
* <p>
|
||||
* 无需开发者判断,只有扣款成功微信才会回调此接口
|
||||
*
|
||||
* @param params the params
|
||||
* @param consumeDataConsumer the consume data consumer
|
||||
* @return the map
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
@SneakyThrows
|
||||
public Map<String, String> mallTransactionCallback(ResponseSignVerifyParams params, Consumer<MallTransactionConsumeData> consumeDataConsumer) {
|
||||
String data = this.callback(params, EventType.MALL_TRANSACTION_SUCCESS);
|
||||
MallTransactionConsumeData consumeData = MAPPER.readValue(data, MallTransactionConsumeData.class);
|
||||
consumeDataConsumer.accept(consumeData);
|
||||
return response();
|
||||
}
|
||||
|
||||
/**
|
||||
* 服务商、直连商户 智慧商圈退款回调
|
||||
*
|
||||
* @param params the params
|
||||
* @param consumeDataConsumer the consume data consumer
|
||||
* @return the map
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
@SneakyThrows
|
||||
public Map<String, String> mallRefundCallback(ResponseSignVerifyParams params, Consumer<MallRefundConsumeData> consumeDataConsumer) {
|
||||
String data = this.callback(params, EventType.MALL_REFUND_SUCCESS);
|
||||
MallRefundConsumeData consumeData = MAPPER.readValue(data, MallRefundConsumeData.class);
|
||||
consumeDataConsumer.accept(consumeData);
|
||||
return response();
|
||||
}
|
||||
/**
|
||||
* Callback.
|
||||
*
|
||||
@@ -552,6 +628,12 @@ public class WechatPayCallback {
|
||||
* @since 1.0.0.RELEASE
|
||||
*/
|
||||
TRANSACTION_SUCCESS("TRANSACTION.SUCCESS"),
|
||||
/**
|
||||
* 智慧商圈支付
|
||||
*
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
MALL_TRANSACTION_SUCCESS("MALL_TRANSACTION.SUCCESS"),
|
||||
/**
|
||||
* 支付分停车支付失败通知
|
||||
*/
|
||||
@@ -567,6 +649,12 @@ public class WechatPayCallback {
|
||||
* @since 1.0.6.RELEASE
|
||||
*/
|
||||
REFUND_SUCCESS("REFUND.SUCCESS"),
|
||||
/**
|
||||
* 智慧商圈退款成功事件.
|
||||
*
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
MALL_REFUND_SUCCESS("MALL_REFUND.SUCCESS"),
|
||||
|
||||
/**
|
||||
* 退款异常事件.
|
||||
|
||||
@@ -96,6 +96,7 @@ public class WechatPayClient {
|
||||
* The V3 pay type.
|
||||
*/
|
||||
private final WechatPayV3Type wechatPayV3Type;
|
||||
|
||||
/**
|
||||
* The Rest operations.
|
||||
*/
|
||||
@@ -216,7 +217,9 @@ public class WechatPayClient {
|
||||
HttpHeaders headers = requestEntity.getHeaders();
|
||||
|
||||
String body = requestEntity.hasBody() ? Objects.requireNonNull(requestEntity.getBody()).toString() : "";
|
||||
if (WechatPayV3Type.MARKETING_IMAGE_UPLOAD.pattern().contains(canonicalUrl)) {
|
||||
if (WechatPayV3Type.MARKETING_IMAGE_UPLOAD.pattern().contains(canonicalUrl) ||
|
||||
WechatPayV3Type.MERCHANT_MEDIA_IMG.pattern().contains(canonicalUrl) ||
|
||||
WechatPayV3Type.MERCHANT_MEDIA_VIDEO.pattern().contains(canonicalUrl)) {
|
||||
body = Objects.requireNonNull(headers.get("Meta-Info")).get(0);
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,9 @@ import cn.felord.payment.wechat.enumeration.WeChatServer;
|
||||
import cn.felord.payment.wechat.enumeration.WechatPayV3Type;
|
||||
import cn.felord.payment.wechat.v3.model.profitsharing.*;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
@@ -316,7 +318,7 @@ public class WechatProfitsharingApi extends AbstractApi {
|
||||
* @return the wechat response entity
|
||||
* @since 1.0.13.RELEASE
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> downloadMerchantBills(ProfitsharingBillParams billParams){
|
||||
public ResponseEntity<Resource> downloadMerchantBills(ProfitsharingBillParams billParams){
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.PROFITSHARING_BILLS,billParams)
|
||||
.function(((wechatPayV3Type, params) -> {
|
||||
@@ -335,7 +337,13 @@ public class WechatProfitsharingApi extends AbstractApi {
|
||||
return Get(uri);
|
||||
})).consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
String downloadUrl = Objects.requireNonNull(wechatResponseEntity.getBody())
|
||||
.get("download_url")
|
||||
.asText();
|
||||
|
||||
String ext = Objects.equals(TarType.GZIP, billParams.getTarType()) ? ".gzip" : ".txt";
|
||||
String filename = "profitsharingbill-" + billParams.getBillDate().toString() + ext;
|
||||
return this.downloadBillResponse(downloadUrl, filename);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* 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.smartguide.PartnerAssignParams;
|
||||
import cn.felord.payment.wechat.v3.model.smartguide.PartnerSmartGuidesParams;
|
||||
import cn.felord.payment.wechat.v3.model.smartguide.PartnerSmartGuidesQueryParams;
|
||||
import cn.felord.payment.wechat.v3.model.smartguide.SmartGuidesModifyParams;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.RequestEntity;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
import java.net.URI;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 微信V3服务商或者直连商户-经营能力-支付即服务
|
||||
*
|
||||
* @author felord.cn
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
public class WechatSmartGuideApi extends AbstractApi {
|
||||
/**
|
||||
* Instantiates a new Abstract api.
|
||||
*
|
||||
* @param wechatPayClient the wechat pay client
|
||||
* @param tenantId the tenant id
|
||||
*/
|
||||
public WechatSmartGuideApi(WechatPayClient wechatPayClient, String tenantId) {
|
||||
super(wechatPayClient, tenantId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 服务人员注册API
|
||||
* <p>
|
||||
* 用于开发者为商户注册服务人员使用。
|
||||
*
|
||||
* @param params the params
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> register(PartnerSmartGuidesParams params) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.SMART_GUIDES, params)
|
||||
.function((wechatPayV3Type, smartGuidesParams) -> {
|
||||
SignatureProvider signatureProvider = this.client().signatureProvider();
|
||||
X509WechatCertificateInfo certificate = signatureProvider.getCertificate(this.wechatMetaBean().getTenantId());
|
||||
final X509Certificate x509Certificate = certificate.getX509Certificate();
|
||||
smartGuidesParams.setName(signatureProvider.encryptRequestMessage(smartGuidesParams.getName(), x509Certificate));
|
||||
smartGuidesParams.setMobile(signatureProvider.encryptRequestMessage(smartGuidesParams.getMobile(), x509Certificate));
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.toUri();
|
||||
HttpHeaders httpHeaders = new HttpHeaders();
|
||||
httpHeaders.add("Wechatpay-Serial", certificate.getWechatPaySerial());
|
||||
return Post(uri, smartGuidesParams, httpHeaders);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 服务人员分配API
|
||||
* <p>
|
||||
* 用于开发者在顾客下单后为顾客分配服务人员使用。
|
||||
*
|
||||
* @param params the params
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> assign(PartnerAssignParams params) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.SMART_GUIDES_ASSIGN, params)
|
||||
.function((wechatPayV3Type, assignParams) -> {
|
||||
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.expand(assignParams.getGuideId())
|
||||
.toUri();
|
||||
Map<String, String> map = new HashMap<>(2);
|
||||
map.put("sub_mchid", assignParams.getSubMchid());
|
||||
map.put("out_trade_no", assignParams.getOutTradeNo());
|
||||
return Post(uri, map);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 服务人员分配API
|
||||
* <p>
|
||||
* 用于开发者在顾客下单后为顾客分配服务人员使用。
|
||||
* <p>
|
||||
* 成功返回后请自行使用{@link SignatureProvider#decryptResponseMessage(String, String)}解密敏感字段。
|
||||
*
|
||||
* @param params the params
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> query(PartnerSmartGuidesQueryParams params) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.SMART_GUIDES_GET, params)
|
||||
.function((wechatPayV3Type, smartGuidesQueryParams) -> {
|
||||
HttpHeaders httpHeaders = new HttpHeaders();
|
||||
httpHeaders.add("Pay-TenantId",this.tenantId());
|
||||
MultiValueMap<String, String> queryParams = new LinkedMultiValueMap<>();
|
||||
String subMchid = smartGuidesQueryParams.getSubMchid();
|
||||
if (subMchid != null) {
|
||||
queryParams.add("sub_mchid", subMchid);
|
||||
}
|
||||
queryParams.add("store_id", String.valueOf(smartGuidesQueryParams.getStoreId()));
|
||||
String userid = smartGuidesQueryParams.getUserid();
|
||||
if (userid != null) {
|
||||
queryParams.add("userid", userid);
|
||||
}
|
||||
String mobile = smartGuidesQueryParams.getMobile();
|
||||
if (mobile != null) {
|
||||
SignatureProvider signatureProvider = this.client().signatureProvider();
|
||||
X509WechatCertificateInfo certificate = signatureProvider.getCertificate(this.wechatMetaBean().getTenantId());
|
||||
final X509Certificate x509Certificate = certificate.getX509Certificate();
|
||||
queryParams.add("mobile", signatureProvider.encryptRequestMessage(mobile, x509Certificate));
|
||||
httpHeaders.add("Wechatpay-Serial", certificate.getWechatPaySerial());
|
||||
}
|
||||
String workId = smartGuidesQueryParams.getWorkId();
|
||||
if (workId != null) {
|
||||
queryParams.add("work_id", workId);
|
||||
}
|
||||
Integer offset = smartGuidesQueryParams.getOffset();
|
||||
if (offset != null) {
|
||||
queryParams.add("offset", String.valueOf(offset));
|
||||
}
|
||||
Integer limit = smartGuidesQueryParams.getLimit();
|
||||
if (limit != null) {
|
||||
queryParams.add("limit", String.valueOf(limit));
|
||||
}
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA))
|
||||
.queryParams(queryParams)
|
||||
.build()
|
||||
.toUri();
|
||||
return RequestEntity.get(uri).headers(httpHeaders)
|
||||
.build();
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 服务人员信息更新API
|
||||
*
|
||||
* @param params the params
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> modify(SmartGuidesModifyParams params) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.SMART_GUIDES_MODIFY, params)
|
||||
.function((wechatPayV3Type, smartGuidesParams) -> {
|
||||
SignatureProvider signatureProvider = this.client().signatureProvider();
|
||||
X509WechatCertificateInfo certificate = signatureProvider.getCertificate(this.wechatMetaBean().getTenantId());
|
||||
final X509Certificate x509Certificate = certificate.getX509Certificate();
|
||||
smartGuidesParams.setName(signatureProvider.encryptRequestMessage(smartGuidesParams.getName(), x509Certificate));
|
||||
smartGuidesParams.setMobile(signatureProvider.encryptRequestMessage(smartGuidesParams.getMobile(), x509Certificate));
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.toUri();
|
||||
HttpHeaders httpHeaders = new HttpHeaders();
|
||||
httpHeaders.add("Wechatpay-Serial", certificate.getWechatPaySerial());
|
||||
return Patch(uri, smartGuidesParams, httpHeaders);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,188 @@
|
||||
/*
|
||||
* 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.ecommerce;
|
||||
|
||||
import cn.felord.payment.wechat.enumeration.WeChatServer;
|
||||
import cn.felord.payment.wechat.enumeration.WechatPayV3Type;
|
||||
import cn.felord.payment.wechat.v3.AbstractApi;
|
||||
import cn.felord.payment.wechat.v3.SignatureProvider;
|
||||
import cn.felord.payment.wechat.v3.WechatPartnerSpecialMchApi;
|
||||
import cn.felord.payment.wechat.v3.WechatPayClient;
|
||||
import cn.felord.payment.wechat.v3.WechatResponseEntity;
|
||||
import cn.felord.payment.wechat.v3.X509WechatCertificateInfo;
|
||||
import cn.felord.payment.wechat.v3.model.ecommerce.EcommerceAccountInfo;
|
||||
import cn.felord.payment.wechat.v3.model.ecommerce.EcommerceApplymentParams;
|
||||
import cn.felord.payment.wechat.v3.model.ecommerce.EcommerceContactInfo;
|
||||
import cn.felord.payment.wechat.v3.model.ecommerce.EcommerceIdCardInfo;
|
||||
import cn.felord.payment.wechat.v3.model.ecommerce.EcommerceIdDocInfo;
|
||||
import cn.felord.payment.wechat.v3.model.ecommerce.UboInfo;
|
||||
import cn.felord.payment.wechat.v3.model.specmch.SubMchModifyParams;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
import java.net.URI;
|
||||
import java.security.cert.X509Certificate;
|
||||
|
||||
/**
|
||||
* 电商收付通-商户进件
|
||||
*
|
||||
* @author felord.cn
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
public class ApplymentApi extends AbstractApi {
|
||||
|
||||
private final WechatPartnerSpecialMchApi wechatPartnerSpecialMchApi;
|
||||
|
||||
/**
|
||||
* Instantiates a new Abstract api.
|
||||
*
|
||||
* @param wechatPayClient the wechat pay client
|
||||
* @param tenantId the tenant id
|
||||
*/
|
||||
ApplymentApi(WechatPayClient wechatPayClient, String tenantId) {
|
||||
super(wechatPayClient, tenantId);
|
||||
this.wechatPartnerSpecialMchApi = new WechatPartnerSpecialMchApi(wechatPayClient, tenantId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 二级商户进件申请API
|
||||
*
|
||||
* @param params the params
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> apply(EcommerceApplymentParams params) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.ECOMMERCE_APPLYMENT, params).function((wechatPayV3Type, applymentParams) -> {
|
||||
SignatureProvider signatureProvider = this.client().signatureProvider();
|
||||
X509WechatCertificateInfo certificate = signatureProvider.getCertificate(this.wechatMetaBean().getTenantId());
|
||||
final X509Certificate x509Certificate = certificate.getX509Certificate();
|
||||
EcommerceApplymentParams applyRequestParams = this.convert(applymentParams, signatureProvider, x509Certificate);
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA)).build().toUri();
|
||||
HttpHeaders httpHeaders = new HttpHeaders();
|
||||
httpHeaders.add("Wechatpay-Serial", certificate.getWechatPaySerial());
|
||||
return Post(uri, applyRequestParams, httpHeaders);
|
||||
}).consumer(wechatResponseEntity::convert).request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过申请单ID查询申请状态API
|
||||
*
|
||||
* @param applymentId the applyment id
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> queryByApplymentId(String applymentId) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.ECOMMERCE_APPLYMENT_ID, applymentId).function((type, id) -> {
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA)).build().expand(id).toUri();
|
||||
return Get(uri);
|
||||
}).consumer(wechatResponseEntity::convert).request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过业务申请编号查询申请状态API
|
||||
*
|
||||
* @param outRequestNo the outRequestNo
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> queryByBusinessCode(String outRequestNo) {
|
||||
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.ECOMMERCE_APPLYMENT_OUT_REQUEST_NO, outRequestNo).function((type, id) -> {
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA)).build().expand(id).toUri();
|
||||
return Get(uri);
|
||||
}).consumer(wechatResponseEntity::convert).request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改结算账号API
|
||||
*
|
||||
* @param params the params
|
||||
* @return wechat response entity
|
||||
* @see WechatPartnerSpecialMchApi#modify(SubMchModifyParams)
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> modify(SubMchModifyParams params) {
|
||||
return this.wechatPartnerSpecialMchApi.modify(params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询结算账户API
|
||||
* <p>
|
||||
* 服务商/电商平台(不包括支付机构、银行),可使用本接口,查询其进件且已签约特约商户/二级商户的结算账户信息(敏感信息掩码)。
|
||||
* 该接口可用于核实是否成功修改结算账户信息、及查询系统汇款验证结果。
|
||||
*
|
||||
* @param subMchid the sub mchid
|
||||
* @return the wechat response entity
|
||||
* @see WechatPartnerSpecialMchApi#querySettlement(String)
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> querySettlement(String subMchid) {
|
||||
return this.wechatPartnerSpecialMchApi.querySettlement(subMchid);
|
||||
}
|
||||
|
||||
private EcommerceApplymentParams convert(EcommerceApplymentParams applymentParams, SignatureProvider signatureProvider, X509Certificate x509Certificate) {
|
||||
EcommerceIdCardInfo idCardInfo = applymentParams.getIdCardInfo();
|
||||
if (idCardInfo != null) {
|
||||
idCardInfo.setIdCardName(signatureProvider.encryptRequestMessage(idCardInfo.getIdCardName(), x509Certificate));
|
||||
idCardInfo.setIdCardNumber(signatureProvider.encryptRequestMessage(idCardInfo.getIdCardNumber(), x509Certificate));
|
||||
String idCardAddress = idCardInfo.getIdCardAddress();
|
||||
if (StringUtils.hasText(idCardAddress)) {
|
||||
idCardInfo.setIdCardAddress(signatureProvider.encryptRequestMessage(idCardAddress, x509Certificate));
|
||||
}
|
||||
}
|
||||
EcommerceIdDocInfo idDocInfo = applymentParams.getIdDocInfo();
|
||||
if (idDocInfo != null) {
|
||||
idDocInfo.setIdDocName(signatureProvider.encryptRequestMessage(idDocInfo.getIdDocName(), x509Certificate));
|
||||
idDocInfo.setIdDocNumber(signatureProvider.encryptRequestMessage(idDocInfo.getIdDocNumber(), x509Certificate));
|
||||
String idDocAddress = idDocInfo.getIdDocAddress();
|
||||
if (StringUtils.hasText(idDocAddress)) {
|
||||
idDocInfo.setIdDocAddress(signatureProvider.encryptRequestMessage(idDocAddress, x509Certificate));
|
||||
}
|
||||
}
|
||||
UboInfo uboInfo = applymentParams.getUboInfo();
|
||||
if (uboInfo != null) {
|
||||
UboInfo.IdCardInfo cardInfo = uboInfo.getIdCardInfo();
|
||||
if (cardInfo != null) {
|
||||
cardInfo.setIdCardName(signatureProvider.encryptRequestMessage(cardInfo.getIdCardName(), x509Certificate));
|
||||
cardInfo.setIdCardNumber(signatureProvider.encryptRequestMessage(cardInfo.getIdCardNumber(), x509Certificate));
|
||||
}
|
||||
UboInfo.IdDocInfo docInfo = uboInfo.getIdDocInfo();
|
||||
if (docInfo != null) {
|
||||
docInfo.setIdDocName(signatureProvider.encryptRequestMessage(docInfo.getIdDocName(), x509Certificate));
|
||||
docInfo.setIdDocNumber(signatureProvider.encryptRequestMessage(docInfo.getIdDocNumber(), x509Certificate));
|
||||
}
|
||||
}
|
||||
EcommerceAccountInfo accountInfo = applymentParams.getAccountInfo();
|
||||
if (accountInfo != null) {
|
||||
accountInfo.setAccountName(signatureProvider.encryptRequestMessage(accountInfo.getAccountName(), x509Certificate));
|
||||
accountInfo.setAccountNumber(signatureProvider.encryptRequestMessage(accountInfo.getAccountNumber(), x509Certificate));
|
||||
}
|
||||
EcommerceContactInfo contactInfo = applymentParams.getContactInfo();
|
||||
contactInfo.setContactName(signatureProvider.encryptRequestMessage(contactInfo.getContactName(), x509Certificate));
|
||||
contactInfo.setContactIdCardNumber(signatureProvider.encryptRequestMessage(contactInfo.getContactIdCardNumber(), x509Certificate));
|
||||
String contactEmail = contactInfo.getContactEmail();
|
||||
if (contactEmail != null) {
|
||||
contactInfo.setContactEmail(signatureProvider.encryptRequestMessage(contactEmail, x509Certificate));
|
||||
}
|
||||
return applymentParams;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* 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.ecommerce;
|
||||
|
||||
import cn.felord.payment.wechat.enumeration.FundFlowAccountType;
|
||||
import cn.felord.payment.wechat.enumeration.WeChatServer;
|
||||
import cn.felord.payment.wechat.enumeration.WechatPayV3Type;
|
||||
import cn.felord.payment.wechat.v3.AbstractApi;
|
||||
import cn.felord.payment.wechat.v3.WechatPayClient;
|
||||
import cn.felord.payment.wechat.v3.WechatResponseEntity;
|
||||
import cn.felord.payment.wechat.v3.model.ecommerce.EcommerceFundEndDay;
|
||||
import cn.felord.payment.wechat.v3.model.ecommerce.EcommerceFundSubMch;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
import java.net.URI;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
/**
|
||||
* 电商收付通余额查询
|
||||
*
|
||||
* @author felord.cn
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
public class BalanceApi extends AbstractApi {
|
||||
/**
|
||||
* Instantiates a new Abstract api.
|
||||
*
|
||||
* @param wechatPayClient the wechat pay client
|
||||
* @param tenantId the tenant id
|
||||
*/
|
||||
BalanceApi(WechatPayClient wechatPayClient, String tenantId) {
|
||||
super(wechatPayClient, tenantId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询二级商户账户实时余额API
|
||||
*
|
||||
* @param params the params
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> queryBySubMchid(EcommerceFundSubMch params) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.ECOMMERCE_FUND_BALANCE_REAL_TIME, params)
|
||||
.function((type, fundSubMch) -> {
|
||||
UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA));
|
||||
if (params.getAccountType() != null) {
|
||||
builder.queryParam("account_type", fundSubMch.getAccountType().name());
|
||||
}
|
||||
URI uri = builder
|
||||
.build()
|
||||
.expand(fundSubMch.getSubMchid())
|
||||
.toUri();
|
||||
return Get(uri);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询二级商户账户日终余额API
|
||||
*
|
||||
* @param params the params
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> queryAtEndDay(EcommerceFundEndDay params) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.ECOMMERCE_FUND_BALANCE_END_DAY, params)
|
||||
.function((type, fundEndDay) -> {
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA))
|
||||
.queryParam("account_type", fundEndDay.getDate().format(DateTimeFormatter.ISO_DATE))
|
||||
.build()
|
||||
.expand(fundEndDay.getSubMchid())
|
||||
.toUri();
|
||||
return Get(uri);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询电商平台账户实时余额API
|
||||
*
|
||||
* @param type the type
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> queryBalanceAtRealTime(FundFlowAccountType type) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.ECOMMERCE_FUND_BALANCE_TYPE_REAL_TIME, type)
|
||||
.function((wechatPayV3Type, accountType) -> {
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.expand(accountType.name())
|
||||
.toUri();
|
||||
return Get(uri);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询电商平台账户实时余额API
|
||||
*
|
||||
* @param type the type
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> queryBalanceAtEndDay(FundFlowAccountType type) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.ECOMMERCE_FUND_BALANCE_TYPE_END_DAY, type)
|
||||
.function((wechatPayV3Type, accountType) -> {
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.expand(accountType.name())
|
||||
.toUri();
|
||||
return Get(uri);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* 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.ecommerce;
|
||||
|
||||
import cn.felord.payment.wechat.enumeration.FundFlowAccountType;
|
||||
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.AbstractApi;
|
||||
import cn.felord.payment.wechat.v3.WechatPartnerProfitsharingApi;
|
||||
import cn.felord.payment.wechat.v3.WechatPayClient;
|
||||
import cn.felord.payment.wechat.v3.WechatResponseEntity;
|
||||
import cn.felord.payment.wechat.v3.model.FundFlowBillParams;
|
||||
import cn.felord.payment.wechat.v3.model.profitsharing.PartnerProfitsharingBillParams;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
import java.net.URI;
|
||||
import java.time.LocalDate;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* 电商收付通下载账单
|
||||
*
|
||||
* @author felord.cn
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
public class DownloadApi extends AbstractApi {
|
||||
private final WechatPartnerProfitsharingApi wechatPartnerProfitsharingApi;
|
||||
|
||||
/**
|
||||
* Instantiates a new Abstract api.
|
||||
*
|
||||
* @param wechatPayClient the wechat pay client
|
||||
* @param tenantId the tenant id
|
||||
*/
|
||||
DownloadApi(WechatPayClient wechatPayClient, String tenantId) {
|
||||
super(wechatPayClient, tenantId);
|
||||
this.wechatPartnerProfitsharingApi = new WechatPartnerProfitsharingApi(wechatPayClient, tenantId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 申请分账账单API
|
||||
*
|
||||
* @param params the params
|
||||
* @return the response entity
|
||||
*/
|
||||
public ResponseEntity<Resource> downloadProfitsharingBills(PartnerProfitsharingBillParams params) {
|
||||
return this.wechatPartnerProfitsharingApi.downloadMerchantBills(params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 申请二级商户资金账单API
|
||||
* <p>
|
||||
* 过于复杂,需要合并文件并自行解密
|
||||
*
|
||||
* @param fundFlowBillParams the fund flow bill params
|
||||
* @return response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> downloadMchFundFlowBill(FundFlowBillParams fundFlowBillParams) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.ECOMMERCE_FUND_FLOW_BILL, fundFlowBillParams)
|
||||
.function((wechatPayV3Type, params) -> {
|
||||
MultiValueMap<String, String> queryParams = new LinkedMultiValueMap<>();
|
||||
LocalDate billDate = params.getBillDate();
|
||||
queryParams.add("bill_date", billDate.format(DateTimeFormatter.ISO_DATE));
|
||||
|
||||
FundFlowAccountType accountType = Optional.ofNullable(params.getAccountType())
|
||||
.orElse(FundFlowAccountType.BASIC);
|
||||
queryParams.add("account_type", accountType.name());
|
||||
TarType tarType = params.getTarType();
|
||||
if (Objects.nonNull(tarType)) {
|
||||
queryParams.add("tar_type", tarType.name());
|
||||
}
|
||||
queryParams.add("algorithm", "AEAD_AES_256_GCM");
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA))
|
||||
.queryParams(queryParams)
|
||||
.build().toUri();
|
||||
return Get(uri);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
* 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.ecommerce;
|
||||
|
||||
import cn.felord.payment.wechat.enumeration.WeChatServer;
|
||||
import cn.felord.payment.wechat.enumeration.WechatPayV3Type;
|
||||
import cn.felord.payment.wechat.v3.AbstractApi;
|
||||
import cn.felord.payment.wechat.v3.WechatPayClient;
|
||||
import cn.felord.payment.wechat.v3.WechatResponseEntity;
|
||||
import cn.felord.payment.wechat.v3.model.ecommerce.EcommerceFundOverseaOrder;
|
||||
import cn.felord.payment.wechat.v3.model.ecommerce.EcommerceFundOverseaParams;
|
||||
import cn.felord.payment.wechat.v3.model.ecommerce.EcommerceFundOverseaResultParams;
|
||||
import cn.felord.payment.wechat.v3.model.profitsharing.PartnerProfitsharingBillParams;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
import java.net.URI;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 电商收付通跨境付款
|
||||
*
|
||||
* @author felord.cn
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
public class FundOverseaApi extends AbstractApi {
|
||||
/**
|
||||
* Instantiates a new Abstract api.
|
||||
*
|
||||
* @param wechatPayClient the wechat pay client
|
||||
* @param tenantId the tenant id
|
||||
*/
|
||||
FundOverseaApi(WechatPayClient wechatPayClient, String tenantId) {
|
||||
super(wechatPayClient, tenantId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询订单剩余可出境余额API
|
||||
*
|
||||
* @param params the params
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> queryBalance(EcommerceFundOverseaParams params) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.ECOMMERCE_FUND_OVERSEA_BALANCE, params)
|
||||
.function((type, fundOverseaParams) -> {
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA))
|
||||
.queryParam("sub_mchid", fundOverseaParams.getSubMchid())
|
||||
.build()
|
||||
.expand(fundOverseaParams.getTransactionId())
|
||||
.toUri();
|
||||
return Get(uri);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 申请资金出境API
|
||||
*
|
||||
* @param order the order
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> apply(EcommerceFundOverseaOrder order) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.ECOMMERCE_FUND_OVERSEA_ORDERS, order)
|
||||
.function((wechatPayV3Type, overseaOrder) -> {
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.toUri();
|
||||
return Post(uri, overseaOrder);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询出境结果API
|
||||
*
|
||||
* @param params the params
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> queryOrder(EcommerceFundOverseaResultParams params) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.ECOMMERCE_FUND_OVERSEA_ORDERS_RESULT, params)
|
||||
.function((type, overseaResultParams) -> {
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA))
|
||||
.queryParam("sub_mchid", overseaResultParams.getSubMchid())
|
||||
.queryParam("transaction_id", overseaResultParams.getTransactionId())
|
||||
.build()
|
||||
.expand(overseaResultParams.getOutOrderId())
|
||||
.toUri();
|
||||
return Get(uri);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取购付汇账单文件下载链接API
|
||||
*
|
||||
* @param billParams the bill params
|
||||
* @return the response entity
|
||||
*/
|
||||
public ResponseEntity<Resource> downloadMerchantBills(PartnerProfitsharingBillParams billParams) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.ECOMMERCE_FUND_OVERSEA_BILLS, billParams)
|
||||
.function(((wechatPayV3Type, params) -> {
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA))
|
||||
.queryParam("bill_date", params.getBillDate().format(DateTimeFormatter.ISO_DATE))
|
||||
.queryParam("sub_mchid", params.getSubMchid())
|
||||
.build()
|
||||
.toUri();
|
||||
return Get(uri);
|
||||
})).consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
String downloadUrl = Objects.requireNonNull(wechatResponseEntity.getBody())
|
||||
.get("download_url")
|
||||
.asText();
|
||||
|
||||
String ext = ".gzip";
|
||||
String filename = "fundoverseabill-" + billParams.getBillDate().toString() + ext;
|
||||
return this.downloadBillResponse(downloadUrl, filename);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,303 @@
|
||||
/*
|
||||
* 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.ecommerce;
|
||||
|
||||
import cn.felord.payment.wechat.WechatPayProperties;
|
||||
import cn.felord.payment.wechat.enumeration.ReceiverType;
|
||||
import cn.felord.payment.wechat.enumeration.WeChatServer;
|
||||
import cn.felord.payment.wechat.enumeration.WechatPayV3Type;
|
||||
import cn.felord.payment.wechat.v3.AbstractApi;
|
||||
import cn.felord.payment.wechat.v3.SignatureProvider;
|
||||
import cn.felord.payment.wechat.v3.WechatPayClient;
|
||||
import cn.felord.payment.wechat.v3.WechatResponseEntity;
|
||||
import cn.felord.payment.wechat.v3.X509WechatCertificateInfo;
|
||||
import cn.felord.payment.wechat.v3.model.ecommerce.EcommerceFinishOrder;
|
||||
import cn.felord.payment.wechat.v3.model.ecommerce.EcommerceProfitsharingOrder;
|
||||
import cn.felord.payment.wechat.v3.model.ecommerce.EcommerceReceiver;
|
||||
import cn.felord.payment.wechat.v3.model.ecommerce.EcommerceReceiverDeleteParams;
|
||||
import cn.felord.payment.wechat.v3.model.ecommerce.EcommerceReturnOrderParams;
|
||||
import cn.felord.payment.wechat.v3.model.ecommerce.Receiver;
|
||||
import cn.felord.payment.wechat.v3.model.profitsharing.PartnerQueryOrderParams;
|
||||
import cn.felord.payment.wechat.v3.model.profitsharing.PartnerReturnOrdersParams;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
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;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 电商收付通分账
|
||||
*
|
||||
* @author felord.cn
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
public class ProfitsharingApi extends AbstractApi {
|
||||
/**
|
||||
* Instantiates a new Abstract api.
|
||||
*
|
||||
* @param wechatPayClient the wechat pay client
|
||||
* @param tenantId the tenant id
|
||||
*/
|
||||
ProfitsharingApi(WechatPayClient wechatPayClient, String tenantId) {
|
||||
super(wechatPayClient, tenantId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求分账API
|
||||
* <p>
|
||||
* 微信订单支付成功后,商户发起分账请求,将结算后的资金分到分账接收方
|
||||
*
|
||||
* @param profitSharingOrder the profit sharing order
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> profitsharingOrders(EcommerceProfitsharingOrder profitSharingOrder) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.ECOMMERCE_PROFITSHARING_ORDERS, profitSharingOrder)
|
||||
.function((wechatPayV3Type, params) -> {
|
||||
WechatPayProperties.V3 v3 = this.wechatMetaBean().getV3();
|
||||
SignatureProvider signatureProvider = this.client().signatureProvider();
|
||||
X509WechatCertificateInfo certificate = signatureProvider.getCertificate(this.wechatMetaBean().getTenantId());
|
||||
final X509Certificate x509Certificate = certificate.getX509Certificate();
|
||||
params.setAppid(v3.getAppId());
|
||||
List<Receiver> receivers = params.getReceivers();
|
||||
if (!CollectionUtils.isEmpty(receivers)) {
|
||||
receivers.forEach(receiversItem -> {
|
||||
String name = receiversItem.getReceiverName();
|
||||
if (StringUtils.hasText(name)) {
|
||||
String encryptedName = signatureProvider.encryptRequestMessage(name, x509Certificate);
|
||||
receiversItem.setReceiverName(encryptedName);
|
||||
}
|
||||
});
|
||||
}
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.toUri();
|
||||
HttpHeaders httpHeaders = new HttpHeaders();
|
||||
httpHeaders.add("Wechatpay-Serial", certificate.getWechatPaySerial());
|
||||
return Post(uri, params, httpHeaders);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询分账结果API
|
||||
* <p>
|
||||
* 发起分账请求后,可调用此接口查询分账结果
|
||||
* <p>
|
||||
* 注意:
|
||||
* <ul>
|
||||
* <li>发起解冻剩余资金请求后,可调用此接口查询解冻剩余资金的结果</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param queryOrderParams the query order params
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> queryProfitsharingOrder(PartnerQueryOrderParams queryOrderParams) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.ECOMMERCE_PROFITSHARING_RESULT, queryOrderParams)
|
||||
.function((wechatPayV3Type, params) -> {
|
||||
MultiValueMap<String, String> queryParams = new LinkedMultiValueMap<>();
|
||||
queryParams.add("sub_mchid", params.getSubMchid());
|
||||
queryParams.add("transaction_id", params.getTransactionId());
|
||||
queryParams.add("out_order_no", params.getOutOrderNo());
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA))
|
||||
.queryParams(queryParams)
|
||||
.build()
|
||||
.toUri();
|
||||
return Get(uri);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求分账回退API
|
||||
* <p>
|
||||
* 如果订单已经分账,在退款时,可以先调此接口,将已分账的资金从分账接收方的账户回退给分账方,再发起退款
|
||||
*
|
||||
* @param returnOrdersParams the return orders params
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> returnOrders(PartnerReturnOrdersParams returnOrdersParams) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.ECOMMERCE_PROFITSHARING_RETURN_ORDERS, returnOrdersParams)
|
||||
.function((wechatPayV3Type, params) -> {
|
||||
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.toUri();
|
||||
return Post(uri, params);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询分账回退结果API
|
||||
* <p>
|
||||
* 商户需要核实回退结果,可调用此接口查询回退结果
|
||||
* <p>
|
||||
* 注意:
|
||||
* <ul>
|
||||
* <li>如果分账回退接口返回状态为处理中,可调用此接口查询回退结果</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param queryReturnOrderParams the query return order params
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> queryReturnOrders(EcommerceReturnOrderParams queryReturnOrderParams) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.ECOMMERCE_PROFITSHARING_RETURN_ORDERS_RESULT, queryReturnOrderParams)
|
||||
.function((wechatPayV3Type, params) -> {
|
||||
MultiValueMap<String, String> queryParams = new LinkedMultiValueMap<>();
|
||||
queryParams.add("sub_mchid", params.getSubMchid());
|
||||
String orderId = params.getOrderId();
|
||||
if (orderId != null) {
|
||||
queryParams.add("order_id", orderId);
|
||||
}
|
||||
String outOrderNo = params.getOutOrderNo();
|
||||
if (outOrderNo != null) {
|
||||
queryParams.add("out_order_no", outOrderNo);
|
||||
}
|
||||
queryParams.add("out_return_no", params.getOutReturnNo());
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA))
|
||||
.queryParams(queryParams)
|
||||
.build()
|
||||
.toUri();
|
||||
return Get(uri);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 完结分账API
|
||||
* <p>
|
||||
* 不需要进行分账的订单,可直接调用本接口将订单的金额全部解冻给二级商户。
|
||||
*
|
||||
* @param finishOrder the finish order
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> finishOrder(EcommerceFinishOrder finishOrder) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.ECOMMERCE_PROFITSHARING_FINISH_ORDER, finishOrder)
|
||||
.function((wechatPayV3Type, params) -> {
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.toUri();
|
||||
return Post(uri, params);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询订单剩余待分金额API
|
||||
* <p>
|
||||
* 可调用此接口查询订单剩余待分金额
|
||||
*
|
||||
* @param transactionId the transaction id
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> queryOrderAmounts(String transactionId) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.ECOMMERCE_PROFITSHARING_ORDER_AMOUNTS, transactionId)
|
||||
.function((wechatPayV3Type, id) -> {
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.expand(id)
|
||||
.toUri();
|
||||
return Get(uri);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加分账接收方API
|
||||
* <p>
|
||||
* 商户发起添加分账接收方请求,建立分账接收方列表。后续可通过发起分账请求,将分账方商户结算后的资金,分到该分账接收方
|
||||
*
|
||||
* @param ecommerceReceiver the ecommerce receiver
|
||||
* @return wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> addReceivers(EcommerceReceiver ecommerceReceiver) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.ECOMMERCE_PROFITSHARING_RECEIVERS_ADD, ecommerceReceiver)
|
||||
.function((wechatPayV3Type, params) -> {
|
||||
WechatPayProperties.V3 v3 = this.wechatMetaBean().getV3();
|
||||
params.setAppid(v3.getAppId());
|
||||
SignatureProvider signatureProvider = this.client().signatureProvider();
|
||||
X509WechatCertificateInfo certificate = signatureProvider.getCertificate(this.wechatMetaBean().getTenantId());
|
||||
final X509Certificate x509Certificate = certificate.getX509Certificate();
|
||||
|
||||
String name = params.getName();
|
||||
if (ReceiverType.PERSONAL_OPENID.equals(params.getType()) && StringUtils.hasText(name)) {
|
||||
// 个人应该必传
|
||||
String encryptedName = signatureProvider.encryptRequestMessage(name, x509Certificate);
|
||||
params.setEncryptedName(encryptedName);
|
||||
}
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.toUri();
|
||||
HttpHeaders httpHeaders = new HttpHeaders();
|
||||
httpHeaders.add("Wechatpay-Serial", certificate.getWechatPaySerial());
|
||||
return Post(uri, params, httpHeaders);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除分账接收方API
|
||||
* <p>
|
||||
* 商户发起删除分账接收方请求。删除后,不支持将分账方商户结算后的资金,分到该分账接收方
|
||||
*
|
||||
* @param delReceiversParams the del receivers params
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> deleteReceivers(EcommerceReceiverDeleteParams delReceiversParams) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.ECOMMERCE_PROFITSHARING_RECEIVERS_DELETE, delReceiversParams)
|
||||
.function((wechatPayV3Type, params) -> {
|
||||
WechatPayProperties.V3 v3 = this.wechatMetaBean().getV3();
|
||||
params.setAppid(v3.getAppId());
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.toUri();
|
||||
return Post(uri, params);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* 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.ecommerce;
|
||||
|
||||
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.AbstractApi;
|
||||
import cn.felord.payment.wechat.v3.WechatPayClient;
|
||||
import cn.felord.payment.wechat.v3.WechatResponseEntity;
|
||||
import cn.felord.payment.wechat.v3.model.ecommerce.EcommerceRefundParams;
|
||||
import cn.felord.payment.wechat.v3.model.ecommerce.EcommerceReturnAdvance;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Collections;
|
||||
|
||||
/**
|
||||
* 电商收付通退款
|
||||
*
|
||||
* @author felord.cn
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
public class RefundsApi extends AbstractApi {
|
||||
/**
|
||||
* Instantiates a new Abstract api.
|
||||
*
|
||||
* @param wechatPayClient the wechat pay client
|
||||
* @param tenantId the tenant id
|
||||
*/
|
||||
RefundsApi(WechatPayClient wechatPayClient, String tenantId) {
|
||||
super(wechatPayClient, tenantId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 申请退款API
|
||||
*
|
||||
* @param params the params
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> apply(EcommerceRefundParams params) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.ECOMMERCE_REFUNDS_APPLY, params)
|
||||
.function((wechatPayV3Type, refundParams) -> {
|
||||
WechatPayProperties.V3 v3 = this.wechatMetaBean().getV3();
|
||||
refundParams.setSpAppid(v3.getAppId());
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.toUri();
|
||||
return Post(uri, refundParams);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询退款API-通过微信支付退款单号查询退款
|
||||
*
|
||||
* @param refundId the refund id
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> queryByRefundId(String refundId) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.ECOMMERCE_REFUNDS_ID, refundId)
|
||||
.function((type, id) -> {
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.expand(id)
|
||||
.toUri();
|
||||
return Get(uri);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询退款API-通过商户退款单号查询退款
|
||||
*
|
||||
* @param outRefundNo the out refund no
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> queryByOutRefundNo(String outRefundNo) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.ECOMMERCE_REFUNDS_OUT_REFUND_NO, outRefundNo)
|
||||
.function((type, no) -> {
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.expand(no)
|
||||
.toUri();
|
||||
return Get(uri);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 垫付退款回补API
|
||||
* <p>
|
||||
* 提交垫付退款后,发起退款方可通过该接口发起垫付退款资金回补,把退款垫付的资金从二级商户回补到电商平台账户。
|
||||
*
|
||||
* @param params the params
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> returnAdvance(EcommerceReturnAdvance params) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.ECOMMERCE_REFUNDS_RETURN_ADVANCE, params)
|
||||
.function((wechatPayV3Type, advanceParams) -> {
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.expand(advanceParams.getRefundId())
|
||||
.toUri();
|
||||
return Post(uri, Collections.singletonMap("sub_mchid", advanceParams.getSubMchid()));
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询垫付回补结果API
|
||||
* <p>
|
||||
* 提交垫付退款回补后,通过调用该接口查询垫付回补结果。
|
||||
*
|
||||
* @param params the params
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> queryAdvanceResult(EcommerceReturnAdvance params) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.ECOMMERCE_REFUNDS_RETURN_ADVANCE_RESULT, params)
|
||||
.function((type, returnAdvance) -> {
|
||||
LinkedMultiValueMap<String, String> queryParams = new LinkedMultiValueMap<>();
|
||||
queryParams.add("refund_id",returnAdvance.getRefundId());
|
||||
queryParams.add("sub_mchid",returnAdvance.getSubMchid());
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA))
|
||||
.queryParams(queryParams)
|
||||
.build()
|
||||
.toUri();
|
||||
return Get(uri);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* 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.ecommerce;
|
||||
|
||||
import cn.felord.payment.wechat.enumeration.WeChatServer;
|
||||
import cn.felord.payment.wechat.enumeration.WechatPayV3Type;
|
||||
import cn.felord.payment.wechat.v3.AbstractApi;
|
||||
import cn.felord.payment.wechat.v3.WechatPayClient;
|
||||
import cn.felord.payment.wechat.v3.WechatResponseEntity;
|
||||
import cn.felord.payment.wechat.v3.model.ecommerce.EcommerceSubsidiesCancelParams;
|
||||
import cn.felord.payment.wechat.v3.model.ecommerce.EcommerceSubsidiesCreateParams;
|
||||
import cn.felord.payment.wechat.v3.model.ecommerce.EcommerceSubsidiesReturnParams;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
/**
|
||||
* 电商收付通-补差
|
||||
*
|
||||
* @author felord.cn
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
public class SubsidiesApi extends AbstractApi {
|
||||
/**
|
||||
* Instantiates a new Abstract api.
|
||||
*
|
||||
* @param wechatPayClient the wechat pay client
|
||||
* @param tenantId the tenant id
|
||||
*/
|
||||
SubsidiesApi(WechatPayClient wechatPayClient, String tenantId) {
|
||||
super(wechatPayClient, tenantId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求补差API
|
||||
* <p>
|
||||
* 服务商下单的时候带上补差标识,微信订单支付成功并结算完成后,发起分账前,调用该口进行补差。
|
||||
*
|
||||
* @param params the params
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> create(EcommerceSubsidiesCreateParams params) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.ECOMMERCE_SUBSIDIES_CREATE, params)
|
||||
.function((wechatPayV3Type, createParams) -> {
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.toUri();
|
||||
return Post(uri, createParams);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求补差回退API
|
||||
* <p>
|
||||
* 订单发送退款的时候,可以对补贴成功的补差单发起回退。
|
||||
*
|
||||
* @param params the params
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> spreadBack(EcommerceSubsidiesReturnParams params) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.ECOMMERCE_SUBSIDIES_RETURN, params)
|
||||
.function((wechatPayV3Type, returnParams) -> {
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.toUri();
|
||||
return Post(uri, returnParams);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消补差API
|
||||
* <p>
|
||||
* 对带有补差标识的订单,如果不需要补差,可在发起分账前,可调用这个接口进行取消补差。
|
||||
*
|
||||
* @param params the params
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> cancel(EcommerceSubsidiesCancelParams params) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.ECOMMERCE_SUBSIDIES_CANCEL, params)
|
||||
.function((wechatPayV3Type, returnParams) -> {
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.toUri();
|
||||
return Post(uri, returnParams);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* 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.ecommerce;
|
||||
|
||||
import cn.felord.payment.wechat.v3.WechatCombinePayApi;
|
||||
import cn.felord.payment.wechat.v3.WechatPartnerPayApi;
|
||||
import cn.felord.payment.wechat.v3.WechatPayClient;
|
||||
|
||||
/**
|
||||
* 电商收付通.
|
||||
*
|
||||
* @author felord.cn
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
public class WechatEcommerceApi {
|
||||
private final WechatPayClient wechatPayClient;
|
||||
private final String tenantId;
|
||||
|
||||
/**
|
||||
* Instantiates a new Wechat ecommerce api.
|
||||
*
|
||||
* @param wechatPayClient the wechat pay client
|
||||
* @param tenantId the tenant id
|
||||
*/
|
||||
public WechatEcommerceApi(WechatPayClient wechatPayClient, String tenantId) {
|
||||
this.wechatPayClient = wechatPayClient;
|
||||
this.tenantId = tenantId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 商户进件
|
||||
*
|
||||
* @return the applyment api
|
||||
*/
|
||||
public ApplymentApi applyment() {
|
||||
return new ApplymentApi(this.wechatPayClient, this.tenantId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 普通支付
|
||||
*
|
||||
* @return the wechat partner pay api
|
||||
*/
|
||||
public WechatPartnerPayApi partnerPay() {
|
||||
return new WechatPartnerPayApi(this.wechatPayClient, this.tenantId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 合单支付
|
||||
*
|
||||
* @return the WechatCombinePayApi
|
||||
*/
|
||||
public WechatCombinePayApi combinePay() {
|
||||
return new WechatCombinePayApi(this.wechatPayClient, this.tenantId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 分账
|
||||
*
|
||||
* @return the profitsharing api
|
||||
*/
|
||||
public ProfitsharingApi profitsharing() {
|
||||
return new ProfitsharingApi(this.wechatPayClient, this.tenantId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 补差
|
||||
*
|
||||
* @return the subsidies api
|
||||
*/
|
||||
public SubsidiesApi subsidies() {
|
||||
return new SubsidiesApi(this.wechatPayClient, this.tenantId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 退款
|
||||
*
|
||||
* @return the refunds api
|
||||
*/
|
||||
public RefundsApi refunds() {
|
||||
return new RefundsApi(this.wechatPayClient, this.tenantId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 余额查询
|
||||
*
|
||||
* @return the balance api
|
||||
*/
|
||||
public BalanceApi balance() {
|
||||
return new BalanceApi(this.wechatPayClient, this.tenantId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 商户提现
|
||||
*
|
||||
* @return the withdraw api
|
||||
*/
|
||||
public WithDrawApi withDraw() {
|
||||
return new WithDrawApi(this.wechatPayClient, this.tenantId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 跨境付款
|
||||
*
|
||||
* @return the oversea api
|
||||
*/
|
||||
public FundOverseaApi overseaApi() {
|
||||
return new FundOverseaApi(this.wechatPayClient, this.tenantId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载账单
|
||||
*
|
||||
* @return the withdraw api
|
||||
*/
|
||||
public DownloadApi download() {
|
||||
return new DownloadApi(this.wechatPayClient, this.tenantId);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,223 @@
|
||||
/*
|
||||
* 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.ecommerce;
|
||||
|
||||
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.AbstractApi;
|
||||
import cn.felord.payment.wechat.v3.WechatPayClient;
|
||||
import cn.felord.payment.wechat.v3.WechatResponseEntity;
|
||||
import cn.felord.payment.wechat.v3.model.ecommerce.EcommerceErrorBillParams;
|
||||
import cn.felord.payment.wechat.v3.model.ecommerce.EcommerceMchReserveParams;
|
||||
import cn.felord.payment.wechat.v3.model.ecommerce.EcommerceOutRequestNo;
|
||||
import cn.felord.payment.wechat.v3.model.ecommerce.EcommerceReserveParams;
|
||||
import cn.felord.payment.wechat.v3.model.ecommerce.EcommerceWithdraw;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
import java.net.URI;
|
||||
import java.time.LocalDate;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 电商收付通-商户提现
|
||||
*
|
||||
* @author felord.cn
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
public class WithDrawApi extends AbstractApi {
|
||||
/**
|
||||
* Instantiates a new Abstract api.
|
||||
*
|
||||
* @param wechatPayClient the wechat pay client
|
||||
* @param tenantId the tenant id
|
||||
*/
|
||||
WithDrawApi(WechatPayClient wechatPayClient, String tenantId) {
|
||||
super(wechatPayClient, tenantId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 二级商户预约提现API
|
||||
*
|
||||
* @param params the params
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> ecommerceReserve(EcommerceReserveParams params) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.ECOMMERCE_FUND_WITHDRAW, params)
|
||||
.function((wechatPayV3Type, refundParams) -> {
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.toUri();
|
||||
return Post(uri, refundParams);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 二级商户查询预约提现状态API-微信支付预约提现单号查询
|
||||
*
|
||||
* @param params the params
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> queryByWithdrawId(EcommerceWithdraw params) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.ECOMMERCE_FUND_WITHDRAW_ID, params)
|
||||
.function((type, ecommerceWithdraw) -> {
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA))
|
||||
.queryParam("sub_mchid", ecommerceWithdraw.getSubMchid())
|
||||
.build()
|
||||
.expand(ecommerceWithdraw.getWithdrawId())
|
||||
.toUri();
|
||||
return Get(uri);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 二级商户查询预约提现状态API-商户预约提现单号查询
|
||||
*
|
||||
* @param params the params
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> queryByOutRequestNo(EcommerceOutRequestNo params) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.ECOMMERCE_FUND_WITHDRAW_OUT_REQUEST_NO, params)
|
||||
.function((type, ecommerceWithdraw) -> {
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA))
|
||||
.queryParam("sub_mchid", ecommerceWithdraw.getSubMchid())
|
||||
.build()
|
||||
.expand(ecommerceWithdraw.getOutRequestNo())
|
||||
.toUri();
|
||||
return Get(uri);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 电商平台预约提现API
|
||||
*
|
||||
* @param params the params
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> ecommerceMchReserve(EcommerceMchReserveParams params) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.ECOMMERCE_FUND_MERCHANT_WITHDRAW, params)
|
||||
.function((wechatPayV3Type, refundParams) -> {
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.toUri();
|
||||
return Post(uri, refundParams);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 电商平台查询预约提现状态API-微信支付预约提现单号查询
|
||||
*
|
||||
* @param withdrawId the withdraw id
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> queryMchByWithdrawId(String withdrawId) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.ECOMMERCE_FUND_MERCHANT_WITHDRAW_ID, withdrawId)
|
||||
.function((type, id) -> {
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.expand(withdrawId)
|
||||
.toUri();
|
||||
return Get(uri);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 电商平台查询预约提现状态API-商户预约提现单号查询
|
||||
*
|
||||
* @param outRequestNo the out request no
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> queryMchByOutRequestNo(String outRequestNo) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.ECOMMERCE_FUND_WITHDRAW_MERCHANT_OUT_REQUEST_NO, outRequestNo)
|
||||
.function((type, no) -> {
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.expand(no)
|
||||
.toUri();
|
||||
return Get(uri);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 按日下载提现异常文件API
|
||||
* <p>
|
||||
* 电商服务商按日查询并下载提现状态为异常的提现单,提现异常包括提现失败和银行退票。
|
||||
*
|
||||
* @param params the params
|
||||
* @return the response entity
|
||||
*/
|
||||
public ResponseEntity<Resource> downloadErrorBill(EcommerceErrorBillParams params) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
|
||||
this.client().withType(WechatPayV3Type.ECOMMERCE_FUND_WITHDRAW_ERROR_BILL, params)
|
||||
.function((wechatPayV3Type, errorBillParams) -> {
|
||||
MultiValueMap<String, String> queryParams = new LinkedMultiValueMap<>();
|
||||
LocalDate billDate = params.getBillDate();
|
||||
queryParams.add("bill_date", billDate.format(DateTimeFormatter.ISO_DATE));
|
||||
TarType tarType = params.getTarType();
|
||||
if (Objects.nonNull(tarType)) {
|
||||
queryParams.add("tar_type", tarType.name());
|
||||
}
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA))
|
||||
.queryParams(queryParams)
|
||||
.build()
|
||||
.expand("NO_SUCC")
|
||||
.toUri();
|
||||
return Get(uri);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
String downloadUrl = Objects.requireNonNull(wechatResponseEntity.getBody())
|
||||
.get("download_url")
|
||||
.asText();
|
||||
|
||||
String ext = Objects.equals(TarType.GZIP, params.getTarType()) ? ".gzip" : ".txt";
|
||||
String filename = "errorbill-" + params.getBillDate().toString() + ext;
|
||||
return downloadBillResponse(downloadUrl, filename);
|
||||
}
|
||||
}
|
||||
@@ -17,8 +17,11 @@
|
||||
|
||||
package cn.felord.payment.wechat.v3.model;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* @author felord.cn
|
||||
* @since 1.0.8.RELEASE
|
||||
@@ -37,9 +40,10 @@ public abstract class AbstractPayParams {
|
||||
*/
|
||||
private String outTradeNo;
|
||||
/**
|
||||
* 订单失效时间 YYYY-MM-DDTHH:mm:ss+TIMEZONE
|
||||
* 订单失效时间 rfc 3339 YYYY-MM-DDTHH:mm:ss+TIMEZONE
|
||||
*/
|
||||
private String timeExpire;
|
||||
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssXXX", timezone = "GMT+8")
|
||||
private LocalDateTime timeExpire;
|
||||
/**
|
||||
* 附加数据,在查询API和支付通知中原样返回,可作为自定义参数使用
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package cn.felord.payment.wechat.v3.model;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author felord.cn
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
@Data
|
||||
public class PageParams {
|
||||
private Integer offset;
|
||||
private Integer limit;
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* 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.model;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author felord.cn
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
@Data
|
||||
public class PartnerRefundConsumeData {
|
||||
private String transactionId;
|
||||
private Amount amount;
|
||||
private String outTradeNo;
|
||||
private String refundStatus;
|
||||
private String outRefundNo;
|
||||
private String refundAccount;
|
||||
private String spMchid;
|
||||
private String subMchid;
|
||||
private String successTime;
|
||||
private String userReceivedAccount;
|
||||
private String refundId;
|
||||
|
||||
/**
|
||||
* 微信支付退款金额信息
|
||||
*
|
||||
* @author felord.cn
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
@Data
|
||||
public static class Amount {
|
||||
/**
|
||||
* 订单金额,单位为分
|
||||
*/
|
||||
private Integer total;
|
||||
/**
|
||||
* 退款金额,单位为分
|
||||
*/
|
||||
private Integer refund;
|
||||
/**
|
||||
* 用户实际支付金额,单位为分
|
||||
*/
|
||||
private Integer payerTotal;
|
||||
/**
|
||||
* 退款给用户的金额,单位为分,不包含所有优惠券金额
|
||||
*/
|
||||
private Integer payerRefund;
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,7 @@
|
||||
*/
|
||||
package cn.felord.payment.wechat.v3.model;
|
||||
|
||||
import cn.felord.payment.wechat.v2.model.allocation.Receiver;
|
||||
import cn.felord.payment.wechat.v3.model.profitsharing.Receiver;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import lombok.Data;
|
||||
|
||||
@@ -39,6 +39,14 @@ public class ProfitSharingConsumeData {
|
||||
* 直连模式分账发起和出资商户
|
||||
*/
|
||||
private String mchid;
|
||||
/**
|
||||
* 服务商商户号
|
||||
*/
|
||||
private String spMchid;
|
||||
/**
|
||||
* 子商户号
|
||||
*/
|
||||
private String subMchid;
|
||||
|
||||
/**
|
||||
* 微信订单号.
|
||||
|
||||
@@ -30,6 +30,12 @@ import java.util.List;
|
||||
*/
|
||||
@Data
|
||||
public class RefundParams {
|
||||
|
||||
/**
|
||||
* 子商户的商户号,由微信支付生成并下发.(服务商退款使用)
|
||||
*/
|
||||
private String subMchid;
|
||||
|
||||
/**
|
||||
* 微信支付订单号,同{@link RefundParams#outTradeNo} 二选一
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package cn.felord.payment.wechat.v3.model;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 微信支付服务商退款查询API请求参数.
|
||||
*
|
||||
* @author zhongying
|
||||
* @since 1.0.15-SNAPSHOT
|
||||
*/
|
||||
@Data
|
||||
public class RefundQueryParams {
|
||||
|
||||
/**
|
||||
* 子商户id
|
||||
*/
|
||||
private String subMchid;
|
||||
|
||||
/**
|
||||
* 退款单号
|
||||
*/
|
||||
private String refundOrderNo;
|
||||
|
||||
}
|
||||
@@ -128,6 +128,14 @@ public class TransactionConsumeData {
|
||||
* 用户在直连商户appid下的唯一标识。
|
||||
*/
|
||||
private String openid;
|
||||
/**
|
||||
* 用户在服务商appid下的唯一标识。
|
||||
*/
|
||||
private String spOpenid;
|
||||
/**
|
||||
* 用户在子商户appid下的唯一标识。
|
||||
*/
|
||||
private String subOpenid;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -15,31 +15,28 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package cn.felord.payment.wechat.v2.model.allocation;
|
||||
package cn.felord.payment.wechat.v3.model.busicircle;
|
||||
|
||||
import cn.felord.payment.wechat.v2.model.BaseModel;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.time.OffsetDateTime;
|
||||
|
||||
/**
|
||||
* The type Base profit sharing model.
|
||||
*
|
||||
* @author wangzecheng
|
||||
* @since 1.0.10.RELEASE
|
||||
* @author felord.cn
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class BaseProfitSharingModel extends BaseModel {
|
||||
|
||||
|
||||
/**
|
||||
* 商户号.
|
||||
* <p>
|
||||
* 微信支付分配的商户号
|
||||
*/
|
||||
private String mchId;
|
||||
public class MallRefundConsumeData {
|
||||
private String mchid;
|
||||
private String merchantName;
|
||||
private String shopName;
|
||||
private String shopNumber;
|
||||
private String appid;
|
||||
private String openid;
|
||||
private OffsetDateTime refundTime;
|
||||
private Integer payAmount;
|
||||
private Integer refundAmount;
|
||||
private String transactionId;
|
||||
private String outOrderNo;
|
||||
private String refundId;
|
||||
|
||||
}
|
||||
@@ -15,14 +15,16 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package cn.felord.payment.wechat.v2.model.allocation;
|
||||
package cn.felord.payment.wechat.v3.model.busicircle;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* The type Multi profit sharing model.
|
||||
*
|
||||
* @author wangzecheng
|
||||
* @since 1.0.10.RELEASE
|
||||
* @author felord.cn
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
public class MultiProfitSharingModel extends ProfitSharingModel {
|
||||
|
||||
@Data
|
||||
public class MallScoreParams {
|
||||
private String appid;
|
||||
private String openid;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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.model.busicircle;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.OffsetDateTime;
|
||||
|
||||
/**
|
||||
* @author felord.cn
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
@Data
|
||||
public class MallScoreSyncRequest {
|
||||
private String transactionId;
|
||||
private String appid;
|
||||
private String openid;
|
||||
private Boolean earnPoints;
|
||||
private Integer increasedPoints;
|
||||
private OffsetDateTime pointsUpdateTime;
|
||||
private Integer totalPoints;
|
||||
private String noPointsRemarks;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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.model.busicircle;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author felord.cn
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
@Data
|
||||
public class MallTransactionConsumeData {
|
||||
private String mchid;
|
||||
private String merchantName;
|
||||
private String shopName;
|
||||
private String shopNumber;
|
||||
private String appid;
|
||||
private String openid;
|
||||
private Integer amount;
|
||||
private String timeEnd;
|
||||
private String transactionId;
|
||||
private String commitTag;
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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.model.busicircle;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* @author felord.cn
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class PartnerMallScoreParams extends MallScoreParams {
|
||||
private String subMchid;
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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.model.busicircle;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* @author felord.cn
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class PartnerMallScoreSyncRequest extends MallScoreSyncRequest{
|
||||
private String subMchid;
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2019-2021 felord.cn
|
||||
* 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.
|
||||
|
||||
@@ -19,7 +19,7 @@ package cn.felord.payment.wechat.v3.model.busifavor;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.OffsetDateTime;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 核销用户券请求参数
|
||||
@@ -45,7 +45,7 @@ public class BusiFavorUseParams {
|
||||
* 请求核销时间
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssXXX", timezone = "GMT+8")
|
||||
private OffsetDateTime useTime;
|
||||
private LocalDateTime useTime;
|
||||
/**
|
||||
* 核销请求单据号,商户侧保证唯一
|
||||
*/
|
||||
|
||||
@@ -19,7 +19,7 @@ package cn.felord.payment.wechat.v3.model.busifavor;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.OffsetDateTime;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -55,12 +55,12 @@ public class CouponAvailableTime {
|
||||
* 批次开始时间 rfc 3339 yyyy-MM-ddTHH:mm:ss+TIMEZONE
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssXXX", timezone = "GMT+8")
|
||||
private OffsetDateTime availableBeginTime;
|
||||
private LocalDateTime availableBeginTime;
|
||||
/**
|
||||
* 批次结束时间 rfc 3339 yyyy-MM-ddTHH:mm:ss+TIMEZONE
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssXXX", timezone = "GMT+8")
|
||||
private OffsetDateTime availableEndTime;
|
||||
private LocalDateTime availableEndTime;
|
||||
/**
|
||||
* 固定周期有效时间段
|
||||
*/
|
||||
|
||||
@@ -19,7 +19,7 @@ package cn.felord.payment.wechat.v3.model.busifavor;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.OffsetDateTime;
|
||||
import java.time.LocalDateTime;
|
||||
/**
|
||||
* 商家券核销规则-券可核销时间-无规律的有效时间段
|
||||
*
|
||||
@@ -33,10 +33,10 @@ public class IrregularyAvaliableTimeItem{
|
||||
* 开始时间
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssXXX", timezone = "GMT+8")
|
||||
private OffsetDateTime beginTime;
|
||||
private LocalDateTime beginTime;
|
||||
/**
|
||||
* 结束时间
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssXXX", timezone = "GMT+8")
|
||||
private OffsetDateTime endTime;
|
||||
private LocalDateTime endTime;
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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.model.ecommerce;
|
||||
|
||||
import cn.felord.payment.wechat.enumeration.ReceiverType;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* The type Ecommerce receiver.
|
||||
*
|
||||
* @author felord.cn
|
||||
* @since 1.0.15.RELEASE
|
||||
*/
|
||||
@Data
|
||||
public class BrandReceiver {
|
||||
private String brandMchid;
|
||||
private String appid;
|
||||
private String subAppid;
|
||||
private ReceiverType type;
|
||||
private String account;
|
||||
private String name;
|
||||
private RelationType relationType;
|
||||
|
||||
/**
|
||||
* The enum Relation type.
|
||||
*/
|
||||
public enum RelationType {
|
||||
/**
|
||||
* 供应商
|
||||
*/
|
||||
SUPPLIER,
|
||||
/**
|
||||
* 分销商
|
||||
*/
|
||||
DISTRIBUTOR,
|
||||
/**
|
||||
* 服务商
|
||||
*/
|
||||
SERVICE_PROVIDER,
|
||||
/**
|
||||
* 平台
|
||||
*/
|
||||
PLATFORM,
|
||||
/**
|
||||
* 员工
|
||||
*/
|
||||
STAFF,
|
||||
/**
|
||||
* 其它
|
||||
*/
|
||||
OTHERS
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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.model.ecommerce;
|
||||
|
||||
import cn.felord.payment.wechat.enumeration.ReceiverType;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author felord.cn
|
||||
* @since 1.0.15.RELEASE
|
||||
*/
|
||||
@Data
|
||||
public class BrandReceiverDeleteParams {
|
||||
private final String brandMchid;
|
||||
private final ReceiverType type;
|
||||
private final String account;
|
||||
private String appid;
|
||||
private String subAppid;
|
||||
}
|
||||
@@ -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.v3.model.ecommerce;
|
||||
|
||||
import cn.felord.payment.wechat.v3.model.specmch.AccountCertInfo;
|
||||
import lombok.Data;
|
||||
/**
|
||||
*
|
||||
* @author felord.cn
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
@Data
|
||||
public class EcommerceAccountInfo {
|
||||
private String bankAccountType;
|
||||
private String accountBank;
|
||||
private String accountName;
|
||||
private String bankAddressCode;
|
||||
private String bankBranchId;
|
||||
private String bankName;
|
||||
private String accountNumber;
|
||||
private AccountCertInfo accountCertInfo;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* 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.model.ecommerce;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class EcommerceAmount {
|
||||
private Integer total;
|
||||
private String currency;
|
||||
private Integer refund;
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* 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.model.ecommerce;
|
||||
|
||||
import cn.felord.payment.wechat.enumeration.ContactType;
|
||||
import cn.felord.payment.wechat.enumeration.IdDocType;
|
||||
import cn.felord.payment.wechat.v3.model.specmch.FinanceInstitutionInfo;
|
||||
import lombok.Data;
|
||||
/**
|
||||
* 二级商户进件申请API请求参数
|
||||
*
|
||||
* @author felord.cn
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
@Data
|
||||
public class EcommerceApplymentParams{
|
||||
private String outRequestNo;
|
||||
private String organizationType;
|
||||
private Boolean financeInstitution;
|
||||
private EcommerceBusinessLicenseInfo businessLicenseInfo;
|
||||
private FinanceInstitutionInfo financeInstitutionInfo;
|
||||
private ContactType idHolderType;
|
||||
private IdDocType idDocType;
|
||||
private String authorizeLetterCopy;
|
||||
private EcommerceIdCardInfo idCardInfo;
|
||||
private EcommerceIdDocInfo idDocInfo;
|
||||
private Boolean owner;
|
||||
private UboInfo uboInfo;
|
||||
private Boolean needAccountInfo;
|
||||
private EcommerceAccountInfo accountInfo;
|
||||
private EcommerceContactInfo contactInfo;
|
||||
private SalesSceneInfo salesSceneInfo;
|
||||
private EcommerceSettlementInfo settlementInfo;
|
||||
private String merchantShortname;
|
||||
private String qualifications;
|
||||
private String businessAdditionPics;
|
||||
private String businessAdditionDesc;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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.model.ecommerce;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author felord.cn
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
@Data
|
||||
public class EcommerceBusinessLicenseInfo {
|
||||
private String businessLicenseCopy;
|
||||
private String businessLicenseNumber;
|
||||
private String merchantName;
|
||||
private String legalPerson;
|
||||
private String companyAddress;
|
||||
private String businessTime;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* 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.model.ecommerce;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class EcommerceContactInfo {
|
||||
private String contactType;
|
||||
private String contactName;
|
||||
private String contactIdCardNumber;
|
||||
private String mobilePhone;
|
||||
private String contactEmail;
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -14,34 +15,31 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package cn.felord.payment.wechat.v3.model.ecommerce;
|
||||
|
||||
package cn.felord.payment.wechat.v2.model.allocation;
|
||||
|
||||
import cn.felord.payment.wechat.v2.model.BaseModel;
|
||||
import cn.felord.payment.wechat.enumeration.TarType;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.time.LocalDate;
|
||||
|
||||
/**
|
||||
* The type Base profit sharing receiver model.
|
||||
* 按日下载提现异常文件API
|
||||
*
|
||||
* @author wangzecheng
|
||||
* @since 1.0.10.RELEASE
|
||||
* @author felord.cn
|
||||
* @since 1.0.3.RELEASE
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class BaseProfitSharingReceiverModel extends BaseModel {
|
||||
public class EcommerceErrorBillParams {
|
||||
/**
|
||||
* 商户号.
|
||||
* 账单日期,必传。
|
||||
* <p>
|
||||
* 微信支付分配的商户号
|
||||
* 格式yyyy-MM-DD,仅支持三个月内的账单下载申请。
|
||||
*/
|
||||
private String mchId;
|
||||
|
||||
private LocalDate billDate;
|
||||
/**
|
||||
* 公众账号ID.
|
||||
* <p>
|
||||
* 微信分配的公众账号ID
|
||||
* 压缩类型,不填默认值为数据流
|
||||
*
|
||||
* @see TarType
|
||||
*/
|
||||
private String appid;
|
||||
|
||||
private TarType tarType;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package cn.felord.payment.wechat.v3.model.ecommerce;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class EcommerceFinishOrder{
|
||||
private String subMchid;
|
||||
private String transactionId;
|
||||
private String outOrderNo;
|
||||
private String description;
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* 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.model.ecommerce;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDate;
|
||||
|
||||
/**
|
||||
* @author felord.cn
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
@Data
|
||||
public class EcommerceFundEndDay {
|
||||
private String subMchid;
|
||||
private LocalDate date;
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* 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.model.ecommerce;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* The type Ecommerce fun oversea order.
|
||||
*
|
||||
* @author felord.cn
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
@Data
|
||||
public class EcommerceFundOverseaOrder {
|
||||
private String outOrderId;
|
||||
private String subMchid;
|
||||
private String transactionId;
|
||||
private Integer amount;
|
||||
private String foreignCurrency;
|
||||
private List<GoodsInfo> goodsInfo;
|
||||
private SellerInfo sellerInfo;
|
||||
private ExpressInfo expressInfo;
|
||||
private PayeeInfo payeeInfo;
|
||||
|
||||
|
||||
/**
|
||||
* The type Goods info.
|
||||
*/
|
||||
@Data
|
||||
public static class GoodsInfo {
|
||||
private String goodsName;
|
||||
private String goodsCategory;
|
||||
private Integer goodsUnitPrice;
|
||||
private Integer goodsQuantity;
|
||||
}
|
||||
|
||||
/**
|
||||
* The type Seller info.
|
||||
*/
|
||||
@Data
|
||||
public static class SellerInfo {
|
||||
private String overseaBusinessName;
|
||||
private String overseaShopName;
|
||||
private String sellerId;
|
||||
}
|
||||
|
||||
/**
|
||||
* The type Express info.
|
||||
*/
|
||||
@Data
|
||||
public static class ExpressInfo {
|
||||
private String courierNumber;
|
||||
private String expressCompanyName;
|
||||
}
|
||||
|
||||
/**
|
||||
* The type Payee info.
|
||||
*/
|
||||
@Data
|
||||
public static class PayeeInfo {
|
||||
private String payeeId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* 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.model.ecommerce;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author felord.cn
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
@Data
|
||||
public class EcommerceFundOverseaParams {
|
||||
private String subMchid;
|
||||
private String transactionId;
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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.model.ecommerce;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author felord.cn
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
@Data
|
||||
public class EcommerceFundOverseaResultParams {
|
||||
private String outOrderId;
|
||||
private String subMchid;
|
||||
private String transactionId;
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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.model.ecommerce;
|
||||
|
||||
import cn.felord.payment.wechat.enumeration.FundFlowAccountType;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author felord.cn
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
@Data
|
||||
public class EcommerceFundSubMch {
|
||||
private String subMchid;
|
||||
private FundFlowAccountType accountType;
|
||||
}
|
||||
@@ -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.v3.model.ecommerce;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDate;
|
||||
|
||||
/**
|
||||
* @author felord.cn
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
@Data
|
||||
public class EcommerceIdCardInfo {
|
||||
private String idCardCopy;
|
||||
private String idCardNational;
|
||||
private String idCardName;
|
||||
private String idCardNumber;
|
||||
private String idCardAddress;
|
||||
private LocalDate idCardValidTimeBegin;
|
||||
private String idCardValidTime;
|
||||
}
|
||||
@@ -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.v3.model.ecommerce;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDate;
|
||||
|
||||
/**
|
||||
* @author felord.cn
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
@Data
|
||||
public class EcommerceIdDocInfo {
|
||||
private String idDocCopy;
|
||||
private String idDocCopyBack;
|
||||
private String idDocName;
|
||||
private String idDocNumber;
|
||||
private String idDocAddress;
|
||||
private LocalDate docPeriodBegin;
|
||||
private String docPeriodEnd;
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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.model.ecommerce;
|
||||
|
||||
import cn.felord.payment.wechat.enumeration.FundFlowAccountType;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author felord.cn
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
@Data
|
||||
public class EcommerceMchReserveParams {
|
||||
private String outRequestNo;
|
||||
private Integer amount;
|
||||
private String remark;
|
||||
private String bankMemo;
|
||||
private FundFlowAccountType accountType;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* 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.model.ecommerce;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author felord.cn
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
@Data
|
||||
public class EcommerceOutRequestNo {
|
||||
private String subMchid;
|
||||
private String outRequestNo;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package cn.felord.payment.wechat.v3.model.ecommerce;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class EcommerceProfitsharingOrder {
|
||||
private String appid;
|
||||
private String subMchid;
|
||||
private String transactionId;
|
||||
private String outOrderNo;
|
||||
private List<Receiver> receivers;
|
||||
private Boolean finish;
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* 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.model.ecommerce;
|
||||
|
||||
import cn.felord.payment.wechat.enumeration.ReceiverType;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* The type Ecommerce receiver.
|
||||
*
|
||||
* @author felord.cn
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
@Data
|
||||
public class EcommerceReceiver {
|
||||
private String appid;
|
||||
private ReceiverType type;
|
||||
private String account;
|
||||
private String name;
|
||||
private String encryptedName;
|
||||
private RelationType relationType;
|
||||
|
||||
/**
|
||||
* The enum Relation type.
|
||||
*/
|
||||
public enum RelationType {
|
||||
/**
|
||||
* 供应商
|
||||
*/
|
||||
SUPPLIER,
|
||||
/**
|
||||
* 分销商
|
||||
*/
|
||||
DISTRIBUTOR,
|
||||
/**
|
||||
* 服务商
|
||||
*/
|
||||
SERVICE_PROVIDER,
|
||||
/**
|
||||
* 平台
|
||||
*/
|
||||
PLATFORM,
|
||||
/**
|
||||
* 其它
|
||||
*/
|
||||
OTHERS, }
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* 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.model.ecommerce;
|
||||
|
||||
import cn.felord.payment.wechat.enumeration.ReceiverType;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author felord.cn
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
@Data
|
||||
public class EcommerceReceiverDeleteParams {
|
||||
private String appid;
|
||||
private ReceiverType type;
|
||||
private String account;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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.model.ecommerce;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author felord.cn
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
@Data
|
||||
public class EcommerceRefundParams {
|
||||
private String subMchid;
|
||||
private String spAppid;
|
||||
private String subAppid;
|
||||
private String transactionId;
|
||||
private String outTradeNo;
|
||||
private String outRefundNo;
|
||||
private String reason;
|
||||
private EcommerceAmount amount;
|
||||
private String notifyUrl;
|
||||
private String refundAccount;
|
||||
private String fundsAccount;
|
||||
}
|
||||
@@ -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.v3.model.ecommerce;
|
||||
|
||||
import cn.felord.payment.wechat.enumeration.FundFlowAccountType;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author felord.cn
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
@Data
|
||||
public class EcommerceReserveParams {
|
||||
private String subMchid;
|
||||
private String outRequestNo;
|
||||
private Integer amount;
|
||||
private String remark;
|
||||
private String bankMemo;
|
||||
private FundFlowAccountType accountType;
|
||||
}
|
||||
@@ -15,14 +15,16 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package cn.felord.payment.wechat.v2.model.allocation;
|
||||
package cn.felord.payment.wechat.v3.model.ecommerce;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* The type Multi profit sharing s model.
|
||||
*
|
||||
* @author wangzecheng
|
||||
* @since 1.0.10.RELEASE
|
||||
* @author felord.cn
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
public class MultiProfitSharingSModel extends ProfitSharingSModel {
|
||||
|
||||
@Data
|
||||
public class EcommerceReturnAdvance {
|
||||
private String refundId;
|
||||
private String subMchid;
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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.model.ecommerce;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author felord.cn
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
@Data
|
||||
public class EcommerceReturnOrderParams {
|
||||
/**
|
||||
* 子商户号,选填
|
||||
*/
|
||||
private String subMchid;
|
||||
/**
|
||||
* 微信分账单号,同{@link #outOrderNo} 二选一
|
||||
*/
|
||||
private String orderId;
|
||||
/**
|
||||
* 商户分账单号,同{@link #orderId} 二选一
|
||||
*/
|
||||
private String outOrderNo;
|
||||
/**
|
||||
* 商户回退单号,必填
|
||||
*/
|
||||
private String outReturnNo;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* 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.model.ecommerce;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class EcommerceSettlementInfo {
|
||||
private String settlementId;
|
||||
private String qualificationType;
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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.model.ecommerce;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author felord.cn
|
||||
* @since 1.0.14.RELEASE
|
||||
*/
|
||||
@Data
|
||||
public class EcommerceSubsidiesCancelParams {
|
||||
private String subMchid;
|
||||
private String transactionId;
|
||||
private String description;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user