From 24f270acd623cdc7f105c56bee54847b762e71b6 Mon Sep 17 00:00:00 2001 From: xiafang Date: Thu, 15 Sep 2022 18:25:55 +0800 Subject: [PATCH 01/19] changelog --- docs/changelog.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/changelog.md b/docs/changelog.md index e02718d..688df4f 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -3,13 +3,13 @@ - 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: 新增服务商退款回调接口 #### 通用能力 From a9ab004a96244192604b5a3c30cbecf5ff37e8d1 Mon Sep 17 00:00:00 2001 From: xiafang Date: Thu, 22 Sep 2022 15:28:32 +0800 Subject: [PATCH 02/19] =?UTF-8?q?fix:=20=E5=A4=9A=E7=A7=9F=E6=88=B7?= =?UTF-8?q?=E8=AF=81=E4=B9=A6=E6=97=A0=E6=B3=95=E5=A4=8D=E7=94=A8=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes #77 --- .../payment/wechat/v3/SignatureProvider.java | 60 +++++++++---------- 1 file changed, 29 insertions(+), 31 deletions(-) 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..51b6b04 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,7 @@ public class SignatureProvider { } ArrayNode certificates = bodyObjectNode.withArray("data"); if (certificates.isArray() && certificates.size() > 0) { - CERTIFICATE_MAP.remove(tenantId); + CERTIFICATE_SET.remove(tenantId); final CertificateFactory certificateFactory = CertificateFactory.getInstance("X509", BC_PROVIDER); certificates.forEach(objectNode -> { JsonNode encryptCertificate = objectNode.get("encrypt_certificate"); @@ -253,7 +255,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 +298,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 +339,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 +356,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")); + }); } From f73be6452e55f17c87be77af0972ea74b64f3cc0 Mon Sep 17 00:00:00 2001 From: xiafang Date: Thu, 22 Sep 2022 15:34:51 +0800 Subject: [PATCH 03/19] =?UTF-8?q?fix:=20=E5=A4=9A=E7=A7=9F=E6=88=B7?= =?UTF-8?q?=E8=AF=81=E4=B9=A6=E6=97=A0=E6=B3=95=E5=A4=8D=E7=94=A8=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98=EF=BC=8C=E5=88=B7=E6=96=B0=E6=97=B6=E6=AD=A3?= =?UTF-8?q?=E7=A1=AE=E7=A7=BB=E9=99=A4=E8=AF=81=E4=B9=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes #77 --- .../java/cn/felord/payment/wechat/v3/SignatureProvider.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) 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 51b6b04..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 @@ -237,7 +237,11 @@ public class SignatureProvider { } ArrayNode certificates = bodyObjectNode.withArray("data"); if (certificates.isArray() && certificates.size() > 0) { - CERTIFICATE_SET.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"); From 575bf6e8a215dd390324e324678b5bc972b4610b Mon Sep 17 00:00:00 2001 From: hellozhongying Date: Thu, 22 Sep 2022 17:54:04 +0800 Subject: [PATCH 04/19] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E5=95=86=E9=80=80=E6=AC=BEapi?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wechat/enumeration/WechatPayV3Type.java | 6 ++ .../wechat/v3/WechatPartnerPayApi.java | 57 +++++++++++++++++++ .../payment/wechat/v3/model/RefundParams.java | 6 ++ .../wechat/v3/model/RefundQueryParams.java | 24 ++++++++ 4 files changed, 93 insertions(+) create mode 100644 payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/RefundQueryParams.java 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..da882c2 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 @@ -600,6 +600,12 @@ public enum WechatPayV3Type { */ MWEB_PARTNER(HttpMethod.POST, "%s/v3/pay/partner/transactions/h5"), + /** + * 服务商退款 + * @since 1.0.15 + */ + REFUND_PARTNER(HttpMethod.POST, "%s/v3/refund/domestic/refunds"), + /** * 关闭订单. * 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..876ace7 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_PARTNER, 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/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; + +} From 34d0bed373e600fee91ac77253aba0e0e11b3cbb Mon Sep 17 00:00:00 2001 From: hellozhongying Date: Thu, 22 Sep 2022 18:31:35 +0800 Subject: [PATCH 05/19] =?UTF-8?q?=E5=8E=BB=E6=8E=89=E5=A4=9A=E4=BD=99?= =?UTF-8?q?=E7=9A=84=E9=80=80=E6=AC=BE=E6=9E=9A=E4=B8=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../felord/payment/wechat/enumeration/WechatPayV3Type.java | 6 ------ .../cn/felord/payment/wechat/v3/WechatPartnerPayApi.java | 2 +- 2 files changed, 1 insertion(+), 7 deletions(-) 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 da882c2..f605562 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 @@ -600,12 +600,6 @@ public enum WechatPayV3Type { */ MWEB_PARTNER(HttpMethod.POST, "%s/v3/pay/partner/transactions/h5"), - /** - * 服务商退款 - * @since 1.0.15 - */ - REFUND_PARTNER(HttpMethod.POST, "%s/v3/refund/domestic/refunds"), - /** * 关闭订单. * 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 876ace7..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 @@ -223,7 +223,7 @@ public class WechatPartnerPayApi extends AbstractApi { */ public WechatResponseEntity refund(RefundParams refundParams) { WechatResponseEntity wechatResponseEntity = new WechatResponseEntity<>(); - this.client().withType(WechatPayV3Type.REFUND_PARTNER, refundParams) + this.client().withType(WechatPayV3Type.REFUND, refundParams) .function(((type, params) -> { URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA)) .build() From e1616c5606929ffe3e1fe68b5cb2adf13cf31269 Mon Sep 17 00:00:00 2001 From: xiafang Date: Wed, 28 Sep 2022 08:35:20 +0800 Subject: [PATCH 06/19] =?UTF-8?q?fix:=20=E5=95=86=E5=AE=B6=E5=8D=B7-?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=89=B9=E6=AC=A1=E9=A2=84=E7=AE=97API?= =?UTF-8?q?=E8=AF=B7=E6=B1=82=E6=96=B9=E6=B3=95=E5=BA=94=E8=AF=A5=E4=B8=BA?= =?UTF-8?q?Patch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes #79 --- .../cn/felord/payment/wechat/enumeration/WechatPayV3Type.java | 2 +- .../felord/payment/wechat/v3/WechatMarketingBusiFavorApi.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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..9ecc667 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,7 +460,7 @@ public enum WechatPayV3Type { */ MARKETING_BUSI_FAVOR_DISASSOCIATE(HttpMethod.POST, "%s/v3/marketing/busifavor/coupons/disassociate"), /** - * 取消关联订单信息API. + * 修改批次预算API. * * @since 1.0.4.RELEASES */ 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(); From 02867baa2c803bffe4aa36731aaebbbe0e28273a Mon Sep 17 00:00:00 2001 From: xiafang Date: Wed, 28 Sep 2022 08:39:17 +0800 Subject: [PATCH 07/19] =?UTF-8?q?fix:=20=E5=95=86=E5=AE=B6=E5=8D=B7-?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=89=B9=E6=AC=A1=E9=A2=84=E7=AE=97API?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E4=BF=AE=E6=94=B9=E4=B8=BAPatch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes #79 --- .../cn/felord/payment/wechat/enumeration/WechatPayV3Type.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 9ecc667..9537048 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 @@ -464,7 +464,7 @@ public enum WechatPayV3Type { * * @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. * From 6e4bfd219231d77b2aad74d0c6688952cd31d268 Mon Sep 17 00:00:00 2001 From: Fang Date: Wed, 5 Oct 2022 12:13:52 +0800 Subject: [PATCH 08/19] =?UTF-8?q?enhance:=20rfc=203339=20=E6=A0=BC?= =?UTF-8?q?=E5=BC=8F=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wechat/v3/model/busifavor/BusiFavorUseParams.java | 4 ++-- .../wechat/v3/model/busifavor/CouponAvailableTime.java | 6 +++--- .../v3/model/busifavor/IrregularyAvaliableTimeItem.java | 6 +++--- .../wechat/v3/model/payscore/parking/ParkingParams.java | 6 ++++-- 4 files changed, 12 insertions(+), 10 deletions(-) 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/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; /** * 停车场名称,必传 */ From 9b4193a4f97ceb52c26a809fb7684b9c7aa9bd99 Mon Sep 17 00:00:00 2001 From: Fang Date: Wed, 5 Oct 2022 12:25:38 +0800 Subject: [PATCH 09/19] =?UTF-8?q?upgrade:=20spring=20boot=20=E7=89=88?= =?UTF-8?q?=E6=9C=AC=E5=8D=87=E7=BA=A7=E5=88=B02.7.4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e9c5f60..86f1602 100644 --- a/pom.xml +++ b/pom.xml @@ -71,7 +71,7 @@ UTF-8 UTF-8 1.8 - 2.7.0 + 2.7.4 4.31.7.ALL 1.67 From 2f7e6c6b22948f5d9ab3c2d13ecd03bb20bfad08 Mon Sep 17 00:00:00 2001 From: Fang Date: Wed, 5 Oct 2022 13:17:06 +0800 Subject: [PATCH 10/19] =?UTF-8?q?enhance:=20=E8=AE=A2=E5=8D=95=E5=A4=B1?= =?UTF-8?q?=E6=95=88=E6=97=B6=E9=97=B4=E7=8E=B0=E5=9C=A8=E9=9C=80=E8=A6=81?= =?UTF-8?q?=E4=BB=A5java=E6=97=B6=E9=97=B4=E6=A0=BC=E5=BC=8FLocalDateTime?= =?UTF-8?q?=E4=BC=A0=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/felord/payment/wechat/enumeration/ContactType.java | 4 ++-- .../java/cn/felord/payment/wechat/v3/AbstractApi.java | 3 +-- .../felord/payment/wechat/v3/model/AbstractPayParams.java | 8 ++++++-- 3 files changed, 9 insertions(+), 6 deletions(-) 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/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/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和支付通知中原样返回,可作为自定义参数使用 */ From 05a3e83e3ef4f76cda47568c493ee7f1667e4f30 Mon Sep 17 00:00:00 2001 From: Fang Date: Wed, 5 Oct 2022 13:17:06 +0800 Subject: [PATCH 11/19] =?UTF-8?q?enhance:=20=E8=AE=A2=E5=8D=95=E5=A4=B1?= =?UTF-8?q?=E6=95=88=E6=97=B6=E9=97=B4=E7=8E=B0=E5=9C=A8=E9=9C=80=E8=A6=81?= =?UTF-8?q?=E4=BB=A5java=E6=97=B6=E9=97=B4=E6=A0=BC=E5=BC=8FLocalDateTime?= =?UTF-8?q?=E4=BC=A0=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #66 --- .../cn/felord/payment/wechat/enumeration/ContactType.java | 4 ++-- .../java/cn/felord/payment/wechat/v3/AbstractApi.java | 3 +-- .../felord/payment/wechat/v3/model/AbstractPayParams.java | 8 ++++++-- 3 files changed, 9 insertions(+), 6 deletions(-) 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/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/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和支付通知中原样返回,可作为自定义参数使用 */ From 2f69023ffd99ba0dd17e3c1257ee438ce60caa0e Mon Sep 17 00:00:00 2001 From: xiafang Date: Tue, 11 Oct 2022 11:12:26 +0800 Subject: [PATCH 12/19] upgrade: gpg upgrade to 3.0.1 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e9c5f60..7e056c0 100644 --- a/pom.xml +++ b/pom.xml @@ -157,7 +157,7 @@ org.apache.maven.plugins maven-gpg-plugin - 1.6 + 3.0.1 sign-artifacts From 5d1fd73f2b775486241d1402642779a7dbb94332 Mon Sep 17 00:00:00 2001 From: Fang Date: Wed, 2 Nov 2022 18:41:51 +0800 Subject: [PATCH 13/19] =?UTF-8?q?enhance:=20=E5=A2=9E=E5=8A=A0=E5=B0=8F?= =?UTF-8?q?=E5=BE=AE=E5=95=86=E6=88=B7=E8=BF=9B=E4=BB=B6=E4=B8=BB=E4=BD=93?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/felord/payment/wechat/enumeration/SubjectType.java | 4 ++++ 1 file changed, 4 insertions(+) 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, /** * 企业 *

From 1742437c2c0b0a48e9f62cca51a8bdbfeac1120a Mon Sep 17 00:00:00 2001 From: xiafang Date: Tue, 3 Jan 2023 09:25:10 +0800 Subject: [PATCH 14/19] =?UTF-8?q?fix:=20=E6=89=B9=E9=87=8F=E8=BD=AC?= =?UTF-8?q?=E8=B4=A6=E5=88=B0=E9=9B=B6=E9=92=B1=E9=87=91=E9=A2=9D=E5=B0=8F?= =?UTF-8?q?=E4=BA=8E2000=20userName=E6=98=AF=E5=8F=AF=E4=BB=A5=E9=9D=9E?= =?UTF-8?q?=E5=BF=85=E5=A1=AB=E7=9A=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes #85 --- .../wechat/v3/WechatBatchTransferApi.java | 36 ++++++++++--------- 1 file changed, 20 insertions(+), 16 deletions(-) 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 886c165..b0d15aa 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,8 +82,10 @@ public class WechatBatchTransferApi extends AbstractApi { List 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); @@ -110,20 +112,7 @@ public class WechatBatchTransferApi extends AbstractApi { public WechatResponseEntity queryBatchByBatchId(QueryBatchTransferParams queryBatchTransferParams) { WechatResponseEntity wechatResponseEntity = new WechatResponseEntity<>(); this.client().withType(WechatPayV3Type.BATCH_TRANSFER_BATCH_ID, queryBatchTransferParams) - .function((type, params) -> { - MultiValueMap queryParams = new LinkedMultiValueMap<>(); - queryParams.add("need_query_detail", params.getNeedQueryDetail().toString()); - queryParams.add("offset", params.getOffset().toString()); - queryParams.add("limit", params.getLimit().toString()); - queryParams.add("detail_status", params.getDetailStatus().name()); - - URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA)) - .queryParams(queryParams) - .build() - .expand(params.getCode()) - .toUri(); - return Get(uri); - }) + .function(this::apply) .consumer(wechatResponseEntity::convert) .request(); return wechatResponseEntity; @@ -402,4 +391,19 @@ public class WechatBatchTransferApi extends AbstractApi { .request(); return wechatResponseEntity; } + + private RequestEntity apply(WechatPayV3Type type, QueryBatchTransferParams params) { + MultiValueMap queryParams = new LinkedMultiValueMap<>(); + queryParams.add("need_query_detail", params.getNeedQueryDetail().toString()); + queryParams.add("offset", params.getOffset().toString()); + queryParams.add("limit", params.getLimit().toString()); + queryParams.add("detail_status", params.getDetailStatus().name()); + + URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA)) + .queryParams(queryParams) + .build() + .expand(params.getCode()) + .toUri(); + return Get(uri); + } } From d91b52ba2b4d63d27e1c50c29e66b7c05b5e2bca Mon Sep 17 00:00:00 2001 From: xiafang Date: Tue, 3 Jan 2023 09:28:08 +0800 Subject: [PATCH 15/19] =?UTF-8?q?fix:=20=E5=BE=AE=E4=BF=A1=E4=BB=A3?= =?UTF-8?q?=E9=87=91=E5=88=B8=E6=A0=B7=E5=BC=8F=E7=9A=84=E8=83=8C=E6=99=AF?= =?UTF-8?q?=E9=A2=9C=E8=89=B2=E6=9E=9A=E4=B8=BE=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes #84 --- .../wechat/enumeration/CouponBgColor.java | 39 +++++++++---------- 1 file changed, 19 insertions(+), 20 deletions(-) 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 } From d8288cdd3ae495e8677601f3268c361df2329cdd Mon Sep 17 00:00:00 2001 From: xiafang Date: Tue, 3 Jan 2023 15:09:13 +0800 Subject: [PATCH 16/19] =?UTF-8?q?feat:=20=E5=BE=AE=E4=BF=A1=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1=E5=95=86=E5=88=86=E8=B4=A6-=E8=BF=9E=E9=94=81?= =?UTF-8?q?=E5=93=81=E7=89=8C=E5=88=86=E8=B4=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes #82 --- .../wechat/enumeration/WechatPayV3Type.java | 58 +++- .../payment/wechat/v3/WechatApiProvider.java | 10 + .../v3/WechatBrandProfitsharingApi.java | 315 ++++++++++++++++++ .../wechat/v3/ecommerce/ProfitsharingApi.java | 2 +- .../v3/model/ProfitSharingConsumeData.java | 8 + .../v3/model/ecommerce/BrandReceiver.java | 68 ++++ .../ecommerce/BrandReceiverDeleteParams.java | 34 ++ .../BrandProfitsharingOrder.java | 22 ++ 8 files changed, 515 insertions(+), 2 deletions(-) create mode 100644 payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatBrandProfitsharingApi.java create mode 100644 payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/ecommerce/BrandReceiver.java create mode 100644 payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/ecommerce/BrandReceiverDeleteParams.java create mode 100644 payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/profitsharing/BrandProfitsharingOrder.java 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 9537048..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 @@ -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/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/WechatBrandProfitsharingApi.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatBrandProfitsharingApi.java new file mode 100644 index 0000000..b25ee73 --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatBrandProfitsharingApi.java @@ -0,0 +1,315 @@ +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.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.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.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.HttpHeaders; +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/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/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/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/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; + +} From e1ec5f1b7cf7206390a9986c9feedc5a2881a7bb Mon Sep 17 00:00:00 2001 From: xiafang Date: Tue, 3 Jan 2023 15:32:50 +0800 Subject: [PATCH 17/19] =?UTF-8?q?upgrade:=20spring=20boot=20=E7=89=88?= =?UTF-8?q?=E6=9C=AC=E5=8D=87=E7=BA=A7=E5=88=B02.7.7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 18 ++++++++++++------ docs/README.md | 2 +- docs/changelog.md | 11 +++++++++++ docs/quick_start.md | 2 +- payment-spring-boot-autoconfigure/pom.xml | 4 ++-- .../wechat/v3/WechatBrandProfitsharingApi.java | 4 ---- payment-spring-boot-starter/pom.xml | 4 ++-- pom.xml | 4 ++-- 8 files changed, 31 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 5f2256e..9a5b36f 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +[![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 组件 为了满足业务中出现app支付、公众号支付、小程序支付等多appid并存的场景,对原有的进行了增强开发出了多租户版本。 @@ -11,9 +13,16 @@ 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) ## 目前已经实现所有服务商和直连商户接口 @@ -27,12 +36,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 @@ -61,10 +71,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 688df4f..d646be1 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -1,3 +1,14 @@ +## 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.4 + ## 1.0.14.RELEASE ### 微信支付 - fix: 批量转账到零钱查询BUG [#I5E2X7](https://gitee.com/felord/payment-spring-boot/issues/I5E2X7) 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/v3/WechatBrandProfitsharingApi.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatBrandProfitsharingApi.java index b25ee73..e18252b 100644 --- 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 @@ -1,15 +1,12 @@ 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.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.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.profitsharing.BrandProfitsharingOrder; import cn.felord.payment.wechat.v3.model.profitsharing.PartnerProfitsharingBillParams; @@ -17,7 +14,6 @@ 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.HttpHeaders; import org.springframework.http.ResponseEntity; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; 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 71595b3..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.4 + 2.7.7 4.31.7.ALL 1.67 From 9d2f8a7d72be93ca1a3711928050598558425f65 Mon Sep 17 00:00:00 2001 From: xiafang Date: Tue, 3 Jan 2023 15:38:03 +0800 Subject: [PATCH 18/19] =?UTF-8?q?upgrade:=20spring=20boot=20=E7=89=88?= =?UTF-8?q?=E6=9C=AC=E5=8D=87=E7=BA=A7=E5=88=B02.7.7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/changelog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/changelog.md b/docs/changelog.md index d646be1..dde910a 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -7,7 +7,7 @@ - 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.4 +- upgrade: Spring Boot 版本升级到2.7.7 ## 1.0.14.RELEASE ### 微信支付 From de3cf3d2ae1b81be6a0436fa8d1f85ffbf8f897d Mon Sep 17 00:00:00 2001 From: xiafang Date: Tue, 3 Jan 2023 16:06:06 +0800 Subject: [PATCH 19/19] =?UTF-8?q?=E8=A7=A3=E5=86=B3=E5=86=B2=E7=AA=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 15 +++++---- .../wechat/v3/WechatBatchTransferApi.java | 32 +++++++++---------- 2 files changed, 23 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 9a5b36f..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并存的场景,对原有的进行了增强开发出了多租户版本。 @@ -24,6 +24,7 @@ - [payment-spring-boot GitHub文档](https://notfound403.github.io/payment-spring-boot) - [payment-spring-boot Gitee文档](https://felord.gitee.io/payment-spring-boot) + ## 目前已经实现所有服务商和直连商户接口 - 实现微信支付多商户 @@ -56,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` 服务商-经营能力-点金计划 > 随着版本迭代功能会增加。 @@ -71,7 +72,7 @@ ## 仓库地址 - [GitHub](https://github.com/NotFound403/payment-spring-boot) - [Gitee](https://gitee.com/felord/payment-spring-boot) - + ## QQ交流群 为了交流解惑,新建QQ群,可通过扫码进入。 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 b0d15aa..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); } @@ -112,7 +112,20 @@ public class WechatBatchTransferApi extends AbstractApi { public WechatResponseEntity queryBatchByBatchId(QueryBatchTransferParams queryBatchTransferParams) { WechatResponseEntity wechatResponseEntity = new WechatResponseEntity<>(); this.client().withType(WechatPayV3Type.BATCH_TRANSFER_BATCH_ID, queryBatchTransferParams) - .function(this::apply) + .function((type, params) -> { + MultiValueMap queryParams = new LinkedMultiValueMap<>(); + queryParams.add("need_query_detail", params.getNeedQueryDetail().toString()); + queryParams.add("offset", params.getOffset().toString()); + queryParams.add("limit", params.getLimit().toString()); + queryParams.add("detail_status", params.getDetailStatus().name()); + + URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA)) + .queryParams(queryParams) + .build() + .expand(params.getCode()) + .toUri(); + return Get(uri); + }) .consumer(wechatResponseEntity::convert) .request(); return wechatResponseEntity; @@ -391,19 +404,4 @@ public class WechatBatchTransferApi extends AbstractApi { .request(); return wechatResponseEntity; } - - private RequestEntity apply(WechatPayV3Type type, QueryBatchTransferParams params) { - MultiValueMap queryParams = new LinkedMultiValueMap<>(); - queryParams.add("need_query_detail", params.getNeedQueryDetail().toString()); - queryParams.add("offset", params.getOffset().toString()); - queryParams.add("limit", params.getLimit().toString()); - queryParams.add("detail_status", params.getDetailStatus().name()); - - URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA)) - .queryParams(queryParams) - .build() - .expand(params.getCode()) - .toUri(); - return Get(uri); - } }