diff --git a/README.md b/README.md index bf487ea..331c2af 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ [![Maven Central Repo Deployment](https://github.com/NotFound403/payment-spring-boot/actions/workflows/main.yml/badge.svg)](https://github.com/NotFound403/payment-spring-boot/actions/workflows/main.yml) -# 最好用的微信支付V3 Spring Boot 组件 +# 最好用的微信支付V3 Spring Boot 组件 为了满足业务中出现app支付、公众号支付、小程序支付等多appid并存的场景,对原有的进行了增强开发出了多租户版本。 @@ -13,13 +13,18 @@ cn.felord payment-spring-boot-starter - 1.0.14.RELEASE + 1.0.15.RELEASE ``` ## 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) + + ## 目前已经实现所有服务商和直连商户接口 - 实现微信支付多商户 @@ -32,12 +37,13 @@ - 实现微信支付V3 商家券 - 实现微信支付V3 批量转账到零钱 -更多参考[changelog](https://notfound403.github.io/payment-spring-boot/#/changelog) +更新日志参考[changelog](https://notfound403.github.io/payment-spring-boot/#/changelog) ## 核心API结构 ![](https://asset.felord.cn/blog/20220613092244.png) - `WechatPartnerProfitsharingApi` 微信支付服务商V3分账 +- `WechatBrandProfitsharingApi` 微信支付服务商V3连锁品牌分账 - `WechatPayCallback` 微信支付V3回调通知工具封装 - `WechatAllocationApi` 微信支付V2分账(未来会移除) - `WechatMarketingFavorApi` 微信支付代金券V3 @@ -51,11 +57,11 @@ - `WechatPayTransfersApi` 微信支付V2企业付款到零钱,目前不包括到银行卡 - `WechatDirectPayApi` 微信支付直连模式V3普通支付 - `WechatPayScoreParkingApi` 微信支付分V3停车服务 -- `WechatBatchTransferApi` 微信支付V3批量转账到零钱 -- `WechatPartnerSpecialMchApi` 微信支付V3服务商商户进件 -- `WechatMediaApi` 微信支付V3媒体上传 -- `WechatEcommerceApi` 电商收付通 -- `WechatSmartGuideApi` 服务商或者直连商户-经营能力-支付即服务 +- `WechatBatchTransferApi` 微信支付V3批量转账到零钱 +- `WechatPartnerSpecialMchApi` 微信支付V3服务商商户进件 +- `WechatMediaApi` 微信支付V3媒体上传 +- `WechatEcommerceApi` 电商收付通 +- `WechatSmartGuideApi` 服务商或者直连商户-经营能力-支付即服务 - `WechatGoldPlanApi` 服务商-经营能力-点金计划 > 随着版本迭代功能会增加。 @@ -67,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群,可通过扫码进入。 diff --git a/docs/README.md b/docs/README.md index b0e8261..5c6cc28 100644 --- a/docs/README.md +++ b/docs/README.md @@ -35,7 +35,7 @@ cn.felord payment-spring-boot-starter - 1.0.14.RELEASE + 1.0.15.RELEASE ``` ## 采用技术 diff --git a/docs/changelog.md b/docs/changelog.md index e02718d..dde910a 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -1,15 +1,26 @@ +## 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` + - 配置项增加`certAbsolutePath`字段用来定义证书的绝对路径,优先级高于`certPath`,当这两个路径都不配置时采用classpath路径`wechat/apiclient_cert.p12` [#73](https://github.com/NotFound403/payment-spring-boot/issues/73) #### 服务商 - feat: 实现服务商商户进件-特约商户进件相关API - feat: 实现点金计划,适用于服务商 - feat: 实现行业方案-电商收付通 - feat: 实现行业方案-智慧商圈 - feat: 实现其它能力-银行组件(服务商) +- feat: 实现其它能力-银行组件(服务商) - enhance: 服务商分账新增下载账单接口 - enhance: 新增服务商退款回调接口 #### 通用能力 diff --git a/docs/quick_start.md b/docs/quick_start.md index e3e18f3..a53bf3d 100644 --- a/docs/quick_start.md +++ b/docs/quick_start.md @@ -4,7 +4,7 @@ cn.felord payment-spring-boot-starter - 1.0.14.RELEASE + 1.0.15.RELEASE ``` > 基于 **Spring Boot 2.x** diff --git a/payment-spring-boot-autoconfigure/pom.xml b/payment-spring-boot-autoconfigure/pom.xml index 1c89273..ad8d5c7 100644 --- a/payment-spring-boot-autoconfigure/pom.xml +++ b/payment-spring-boot-autoconfigure/pom.xml @@ -5,11 +5,11 @@ cn.felord payment-spring-boot - 1.0.14.RELEASE + 1.0.15.RELEASE payment-spring-boot-autoconfigure - 1.0.14.RELEASE + 1.0.15.RELEASE jar 4.0.0 diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/ContactType.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/ContactType.java index 18e21ac..61e2cde 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/ContactType.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/ContactType.java @@ -20,7 +20,7 @@ package cn.felord.payment.wechat.enumeration; /** * 超级管理员类型 * - * @since + * @since 1.0.14.RELEASE */ public enum ContactType { /** @@ -31,7 +31,7 @@ public enum ContactType { LEGAL, /** * 经办人 - * + *

* 经商户授权办理微信支付业务的人员 */ SUPER diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/CouponBgColor.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/CouponBgColor.java index 3160457..8f2da80 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/CouponBgColor.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/CouponBgColor.java @@ -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 } diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/SubjectType.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/SubjectType.java index ee94993..2749b9e 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/SubjectType.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/SubjectType.java @@ -31,6 +31,10 @@ public enum SubjectType { * 营业执照上的主体类型一般为个体户、个体工商户、个体经营; */ SUBJECT_TYPE_INDIVIDUAL, + /** + * 小微商户 + */ + SUBJECT_TYPE_MICRO, /** * 企业 *

diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/WechatPayV3Type.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/WechatPayV3Type.java index f605562..9052c64 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/WechatPayV3Type.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/WechatPayV3Type.java @@ -460,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. * @@ -680,6 +680,62 @@ public enum WechatPayV3Type { * @since 1.0.13.RELEASE */ 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. @@ -830,7 +886,7 @@ public enum WechatPayV3Type { */ ECOMMERCE_PROFITSHARING_RECEIVERS_ADD(HttpMethod.POST, "%s/v3/ecommerce/profitsharing/receivers/add"), /** - * 行业方案-电商收付通-分账-添加分账接收方API. + * 行业方案-电商收付通-分账-删除分账接收方API. * * @since 1.0.14.RELEASE */ diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/AbstractApi.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/AbstractApi.java index 6914ffd..7a635da 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/AbstractApi.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/AbstractApi.java @@ -94,8 +94,7 @@ public abstract class AbstractApi { * @param mapper the mapper */ private void applyObjectMapper(ObjectMapper mapper) { - mapper.setPropertyNamingStrategy(PropertyNamingStrategy.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) diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/SignatureProvider.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/SignatureProvider.java index f4f84a1..10ad1b6 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/SignatureProvider.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/SignatureProvider.java @@ -58,12 +58,7 @@ import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.time.LocalDateTime; import java.time.ZoneOffset; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.concurrent.ConcurrentHashMap; +import java.util.*; import java.util.stream.Collectors; /** @@ -96,7 +91,7 @@ public class SignatureProvider { /** * 微信平台证书容器 key = 序列号 value = 证书对象 */ - private static final Map CERTIFICATE_MAP = new ConcurrentHashMap<>(); + private static final Set CERTIFICATE_SET = Collections.synchronizedSet(new HashSet<>()); /** * 加密算法提供方 - BouncyCastle */ @@ -186,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(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())); @@ -235,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"); @@ -253,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()); } @@ -296,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); } } @@ -336,10 +343,10 @@ public class SignatureProvider { 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); + cipher.init(Cipher.DECRYPT_MODE, privateKey); byte[] data = Base64Utils.decodeFromString(message); byte[] cipherData = cipher.doFinal(data); - return new String(cipherData,StandardCharsets.UTF_8); + return new String(cipherData, StandardCharsets.UTF_8); } catch (Exception e) { throw new PayException(e); @@ -353,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")); + }); } diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatApiProvider.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatApiProvider.java index 1667235..e08a5dd 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatApiProvider.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatApiProvider.java @@ -209,6 +209,16 @@ public class WechatApiProvider { 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服务商-商户进件-特约商户进件 * diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatBatchTransferApi.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatBatchTransferApi.java index 982d9ee..627cd6d 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatBatchTransferApi.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatBatchTransferApi.java @@ -82,7 +82,7 @@ public class WechatBatchTransferApi extends AbstractApi { List encrypted = transferDetailList.stream() .peek(transferDetailListItem -> { String userName = transferDetailListItem.getUserName(); - if(StringUtils.hasText(userName)){ + if (StringUtils.hasText(userName)) { String encryptedUserName = signatureProvider.encryptRequestMessage(userName, x509Certificate); transferDetailListItem.setUserName(encryptedUserName); } diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatBrandProfitsharingApi.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatBrandProfitsharingApi.java new file mode 100644 index 0000000..e18252b --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatBrandProfitsharingApi.java @@ -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 profitsharingOrders(BrandProfitsharingOrder brandProfitsharingOrder) { + WechatResponseEntity 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 + *

+ * 发起分账请求后,可调用此接口查询分账结果 + *

+ * 注意: + *

+ * + * @param queryOrderParams the query order params + * @return the wechat response entity + */ + public WechatResponseEntity queryProfitsharingOrder(PartnerQueryOrderParams queryOrderParams) { + WechatResponseEntity wechatResponseEntity = new WechatResponseEntity<>(); + this.client().withType(WechatPayV3Type.BRAND_PROFITSHARING_RESULT, queryOrderParams) + .function((wechatPayV3Type, params) -> { + MultiValueMap 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 + *

+ * 如果订单已经分账,在退款时,可以先调此接口,将已分账的资金从分账接收方的账户回退给分账方,再发起退款 + * + * @param returnOrdersParams the return orders params + * @return the wechat response entity + */ + public WechatResponseEntity returnOrders(PartnerReturnOrdersParams returnOrdersParams) { + WechatResponseEntity 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 + *

+ * 商户需要核实回退结果,可调用此接口查询回退结果 + *

+ * 注意: + *

    + *
  • 如果分账回退接口返回状态为处理中,可调用此接口查询回退结果
  • + *
+ * + * @param queryReturnOrderParams the query return order params + * @return the wechat response entity + */ + public WechatResponseEntity queryReturnOrders(EcommerceReturnOrderParams queryReturnOrderParams) { + WechatResponseEntity wechatResponseEntity = new WechatResponseEntity<>(); + this.client().withType(WechatPayV3Type.BRAND_PROFITSHARING_RETURN_ORDERS_RESULT, queryReturnOrderParams) + .function((wechatPayV3Type, params) -> { + MultiValueMap 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 + *

+ * 不需要进行分账的订单,可直接调用本接口将订单的金额全部解冻给二级商户。 + * + * @param finishOrder the finish order + * @return the wechat response entity + */ + public WechatResponseEntity finishOrder(EcommerceFinishOrder finishOrder) { + WechatResponseEntity 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 + *

+ * 可调用此接口查询订单剩余待分金额 + * + * @param transactionId the transaction id + * @return the wechat response entity + */ + public WechatResponseEntity queryOrderAmounts(String transactionId) { + WechatResponseEntity 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 brandConfigs(String brandMchid) { + WechatResponseEntity 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 + *

+ * 商户发起添加分账接收方请求,建立分账接收方列表。后续可通过发起分账请求,将分账方商户结算后的资金,分到该分账接收方 + * + * @param brandReceiver the brandReceiver + * @return wechat response entity + */ + public WechatResponseEntity addReceivers(BrandReceiver brandReceiver) { + WechatResponseEntity 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 + *

+ * 商户发起删除分账接收方请求。删除后,不支持将分账方商户结算后的资金,分到该分账接收方 + * + * @param delReceiversParams the del receivers params + * @return the wechat response entity + */ + public WechatResponseEntity deleteReceivers(BrandReceiverDeleteParams delReceiversParams) { + WechatResponseEntity 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 downloadMerchantBills(PartnerProfitsharingBillParams billParams) { + WechatResponseEntity wechatResponseEntity = new WechatResponseEntity<>(); + this.client().withType(WechatPayV3Type.PROFITSHARING_BILLS, billParams) + .function(((wechatPayV3Type, params) -> { + MultiValueMap 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); + } +} diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatMarketingBusiFavorApi.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatMarketingBusiFavorApi.java index 7a7fe0a..a78c29b 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatMarketingBusiFavorApi.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatMarketingBusiFavorApi.java @@ -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(); diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatPartnerPayApi.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatPartnerPayApi.java index 3b893bf..369c431 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatPartnerPayApi.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatPartnerPayApi.java @@ -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 refund(RefundParams refundParams) { + WechatResponseEntity 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 queryRefundInfo(RefundQueryParams params) { + WechatResponseEntity 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 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 * diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/ecommerce/ProfitsharingApi.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/ecommerce/ProfitsharingApi.java index 50e70c8..32b68b4 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/ecommerce/ProfitsharingApi.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/ecommerce/ProfitsharingApi.java @@ -178,7 +178,7 @@ public class ProfitsharingApi extends AbstractApi { queryParams.add("sub_mchid", params.getSubMchid()); String orderId = params.getOrderId(); if (orderId != null) { - queryParams.add("out_order_no", orderId); + queryParams.add("order_id", orderId); } String outOrderNo = params.getOutOrderNo(); if (outOrderNo != null) { diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/AbstractPayParams.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/AbstractPayParams.java index 936ead0..1f27334 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/AbstractPayParams.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/AbstractPayParams.java @@ -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和支付通知中原样返回,可作为自定义参数使用 */ diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/ProfitSharingConsumeData.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/ProfitSharingConsumeData.java index 81ebee4..868d714 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/ProfitSharingConsumeData.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/ProfitSharingConsumeData.java @@ -39,6 +39,14 @@ public class ProfitSharingConsumeData { * 直连模式分账发起和出资商户 */ private String mchid; + /** + * 服务商商户号 + */ + private String spMchid; + /** + * 子商户号 + */ + private String subMchid; /** * 微信订单号. diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/RefundParams.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/RefundParams.java index d8ba569..23dfee5 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/RefundParams.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/RefundParams.java @@ -30,6 +30,12 @@ import java.util.List; */ @Data public class RefundParams { + + /** + * 子商户的商户号,由微信支付生成并下发.(服务商退款使用) + */ + private String subMchid; + /** * 微信支付订单号,同{@link RefundParams#outTradeNo} 二选一 */ diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/RefundQueryParams.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/RefundQueryParams.java new file mode 100644 index 0000000..b4b0a2a --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/RefundQueryParams.java @@ -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; + +} diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/busifavor/BusiFavorUseParams.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/busifavor/BusiFavorUseParams.java index 75729ec..ab59f23 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/busifavor/BusiFavorUseParams.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/busifavor/BusiFavorUseParams.java @@ -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; /** * 核销请求单据号,商户侧保证唯一 */ diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/busifavor/CouponAvailableTime.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/busifavor/CouponAvailableTime.java index 5ba26c5..46e29a5 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/busifavor/CouponAvailableTime.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/busifavor/CouponAvailableTime.java @@ -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; /** * 固定周期有效时间段 */ diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/busifavor/IrregularyAvaliableTimeItem.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/busifavor/IrregularyAvaliableTimeItem.java index c9fdcc6..201ca9e 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/busifavor/IrregularyAvaliableTimeItem.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/busifavor/IrregularyAvaliableTimeItem.java @@ -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; } \ No newline at end of file diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/ecommerce/BrandReceiver.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/ecommerce/BrandReceiver.java new file mode 100644 index 0000000..0471efa --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/ecommerce/BrandReceiver.java @@ -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 + } +} diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/ecommerce/BrandReceiverDeleteParams.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/ecommerce/BrandReceiverDeleteParams.java new file mode 100644 index 0000000..f6f1f4d --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/ecommerce/BrandReceiverDeleteParams.java @@ -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; +} diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/parking/ParkingParams.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/parking/ParkingParams.java index a3276dc..081b206 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/parking/ParkingParams.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/parking/ParkingParams.java @@ -18,9 +18,10 @@ package cn.felord.payment.wechat.v3.model.payscore.parking; import cn.felord.payment.wechat.enumeration.PlateColor; +import com.fasterxml.jackson.annotation.JsonFormat; import lombok.Data; -import java.time.OffsetDateTime; +import java.time.LocalDateTime; /** * 创建停车入场API参数 @@ -57,7 +58,8 @@ public class ParkingParams { *

* 格式为yyyy-MM-DDTHH:mm:ss+TIMEZONE */ - private OffsetDateTime startTime; + @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssXXX", timezone = "GMT+8") + private LocalDateTime startTime; /** * 停车场名称,必传 */ diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/profitsharing/BrandProfitsharingOrder.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/profitsharing/BrandProfitsharingOrder.java new file mode 100644 index 0000000..32c5886 --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/profitsharing/BrandProfitsharingOrder.java @@ -0,0 +1,22 @@ +package cn.felord.payment.wechat.v3.model.profitsharing; + +import lombok.Data; + +import java.util.List; + +/** + * @author xiafang + * @since 2023/1/3 10:27 + */ +@Data +public class BrandProfitsharingOrder { + private final String brandMchid; + private final String subMchid; + private String appid; + private final String transactionId; + private final String outOrderNo; + private final List receivers; + private final Boolean finish; + private String subAppid; + +} diff --git a/payment-spring-boot-starter/pom.xml b/payment-spring-boot-starter/pom.xml index a9e02c7..56d079f 100644 --- a/payment-spring-boot-starter/pom.xml +++ b/payment-spring-boot-starter/pom.xml @@ -5,11 +5,11 @@ cn.felord payment-spring-boot - 1.0.14.RELEASE + 1.0.15.RELEASE payment-spring-boot-starter - 1.0.14.RELEASE + 1.0.15.RELEASE jar 4.0.0 diff --git a/pom.xml b/pom.xml index e9c5f60..31e60fd 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> cn.felord payment-spring-boot - 1.0.14.RELEASE + 1.0.15.RELEASE pom 4.0.0 @@ -71,7 +71,7 @@ UTF-8 UTF-8 1.8 - 2.7.0 + 2.7.7 4.31.7.ALL 1.67 @@ -157,7 +157,7 @@ org.apache.maven.plugins maven-gpg-plugin - 1.6 + 3.0.1 sign-artifacts