diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 01e4abe..27941aa 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,13 +1,21 @@ +# 相当于脚本用途的一个声明 name: Maven Central Repo Deployment +# 触发脚本的事件 这里为发布release之后触发 on: release: types: [released] +# 定义一个发行任务 jobs: publish: +# 任务运行的环境 runs-on: ubuntu-latest +# 任务的步骤 steps: - - name: Checkout +# 1. 声明 checkout 仓库代码到工作区 + - name: Checkout Git Repo uses: actions/checkout@v2 +# 2. 安装Java 环境 这里会用到的参数就是 Git Action secrets中配置的, +# 取值要在key前面加 secrets. - name: Set up Maven Central Repo uses: actions/setup-java@v1 with: @@ -16,7 +24,9 @@ jobs: server-username: ${{ secrets.OSSRH_USER }} server-password: ${{ secrets.OSSRH_PASSWORD }} gpg-passphrase: ${{ secrets.GPG_PASSWORD }} +# 3. 发布到Maven中央仓库 - name: Publish to Maven Central Repo +# 这里用到了其他人写的action脚本,详细可以去看他的文档。 uses: samuelmeuli/action-maven-publish@v1 with: gpg_private_key: ${{ secrets.GPG_SECRET }} diff --git a/README.md b/README.md index dd9fc9c..6212053 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ cn.felord payment-spring-boot-starter - 1.0.9.RELEASE + 1.0.10.RELEASE ``` diff --git a/docs/README.md b/docs/README.md index ad75c9b..302d83f 100644 --- a/docs/README.md +++ b/docs/README.md @@ -35,7 +35,7 @@ cn.felord payment-spring-boot-starter - 1.0.9.RELEASE + 1.0.10.RELEASE ``` ## 采用技术 diff --git a/docs/changelog.md b/docs/changelog.md index 8c78cdf..9e3695f 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -1,9 +1,20 @@ +## 1.0.10.RELEASE + +- 微信支付 + - feat: 微信支付V2分账接口实现,感谢**zacone**同学贡献的PR + - factor: 优化证书加载方式 + - factor: 商家券修改API的请求方式变更为`Patch` + - fix: 修复微信支付V3中native支付通知回调`successTime`字段无时区信息的问题([#I3ED43](https://gitee.com/felord/payment-spring-boot/issues/I3ED43)) +- 支付宝 + - fix: 修复支付宝Maven打包无法读取证书的问题([#24](https://github.com/NotFound403/payment-spring-boot/issues/24)) + ## 1.0.9.RELEASE - 微信支付 - - refactor: 服务商支付 WechatPartnerPayApi 加入Spring IOC + - refactor: `WechatPartnerPayApi` 加入**Spring IOC** - fix: 支付分支付成功回调反序列化异常 ([#21](https://github.com/NotFound403/payment-spring-boot/issues/21)) - fix: 修复枚举空指针问题 ([#22](https://github.com/NotFound403/payment-spring-boot/issues/22)) + ## 1.0.8.RELEASE - 微信支付 diff --git a/docs/quick_start.md b/docs/quick_start.md index 3683091..c251fb0 100644 --- a/docs/quick_start.md +++ b/docs/quick_start.md @@ -4,7 +4,7 @@ cn.felord payment-spring-boot-starter - 1.0.9.RELEASE + 1.0.10.RELEASE ``` > 基于 **Spring Boot 2.x** diff --git a/payment-spring-boot-autoconfigure/pom.xml b/payment-spring-boot-autoconfigure/pom.xml index fd9ca57..da2fb9b 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.9.RELEASE + 1.0.10.RELEASE payment-spring-boot-autoconfigure - 1.0.9.RELEASE + 1.0.10.RELEASE jar 4.0.0 diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/alipay/AliPayConfiguration.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/alipay/AliPayConfiguration.java index 564089c..bfc50c5 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/alipay/AliPayConfiguration.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/alipay/AliPayConfiguration.java @@ -19,11 +19,12 @@ package cn.felord.payment.alipay; +import cn.felord.payment.PayException; import com.alipay.api.AlipayApiException; import com.alipay.api.AlipayClient; import com.alipay.api.CertAlipayRequest; import com.alipay.api.DefaultAlipayClient; -import cn.felord.payment.PayException; +import com.alipay.api.internal.util.file.IOUtils; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; @@ -32,7 +33,9 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ClassPathResource; -import java.io.*; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; /** * @author felord.cn @@ -57,28 +60,28 @@ public class AliPayConfiguration { propertyMapper.from(v1::getFormat).to(certAlipayRequest::setFormat); propertyMapper.from(v1::getCharset).to(certAlipayRequest::setCharset); propertyMapper.from(v1::getSignType).to(certAlipayRequest::setSignType); - propertyMapper.from(v1::getAppCertPublicKeyPath).as(this::getFileAbsolutePath).to(certAlipayRequest::setCertPath); - propertyMapper.from(v1::getAlipayPublicCertPath).as(this::getFileAbsolutePath).to(certAlipayRequest::setAlipayPublicCertPath); - propertyMapper.from(v1::getAlipayRootCertPath).as(this::getFileAbsolutePath).to(certAlipayRequest::setRootCertPath); + propertyMapper.from(v1::getAppCertPublicKeyPath).as(this::getContentFromClassPath).to(certAlipayRequest::setCertContent); + propertyMapper.from(v1::getAlipayPublicCertPath).as(this::getContentFromClassPath).to(certAlipayRequest::setAlipayPublicCertContent); + propertyMapper.from(v1::getAlipayRootCertPath).as(this::getContentFromClassPath).to(certAlipayRequest::setRootCertContent); return new DefaultAlipayClient(certAlipayRequest); } - private String getFileAbsolutePath(String classPath) { - try { - return new ClassPathResource(classPath).getFile().getAbsolutePath(); - } catch (IOException e) { - log.error("ali pay cert path is not exist ,{}", e.getMessage()); - throw new PayException("ali pay cert path is not exist"); - } + private String getContentFromClassPath(String classPath) { + ClassPathResource resource = new ClassPathResource(classPath); + try (InputStreamReader in = new InputStreamReader(resource.getInputStream())) { + return IOUtils.toString(in); + } catch (IOException e) { + log.error("ali pay root cert is invalid ,{}", e.getMessage()); + throw new PayException("ali pay root cert path is invalid"); + } } private String appRSAPrivateKey(String classPath) { ClassPathResource resource = new ClassPathResource(classPath); - try { - FileReader in = new FileReader(resource.getFile()); - try(BufferedReader bufferedReader = new BufferedReader(in)){ + try (InputStreamReader inputStreamReader = new InputStreamReader(resource.getInputStream())) { + try (BufferedReader bufferedReader = new BufferedReader(inputStreamReader)) { return bufferedReader.readLine(); } } catch (IOException e) { @@ -87,5 +90,4 @@ public class AliPayConfiguration { } } - } diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/WechatPayConfiguration.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/WechatPayConfiguration.java index c65b521..2413710 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/WechatPayConfiguration.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/WechatPayConfiguration.java @@ -60,7 +60,7 @@ public class WechatPayConfiguration { WechatPayProperties.V3 v3 = v3Map.get(tenantId); String certPath = v3.getCertPath(); String mchId = v3.getMchId(); - WechatMetaBean wechatMetaBean = keyPairFactory.createPKCS12(certPath, CERT_ALIAS, mchId); + WechatMetaBean wechatMetaBean = keyPairFactory.initWechatMetaBean(certPath, CERT_ALIAS, mchId); wechatMetaBean.setV3(v3); wechatMetaBean.setTenantId(tenantId); container.addWechatMeta(tenantId, wechatMetaBean); 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 2b1500f..3bcbca3 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 @@ -431,7 +431,7 @@ public enum WechatPayV3Type { * * @since 1.0.4.RELEASES */ - MARKETING_BUSI_FAVOR_UPDATE(HttpMethod.POST, "%s/v3/marketing/busifavor/stocks/{stock_id}"), + MARKETING_BUSI_FAVOR_UPDATE(HttpMethod.PATCH, "%s/v3/marketing/busifavor/stocks/{stock_id}"), /** * 申请退券API. * diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v2/WechatAllocationApi.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v2/WechatAllocationApi.java new file mode 100644 index 0000000..6c815ca --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v2/WechatAllocationApi.java @@ -0,0 +1,248 @@ +/* + * Copyright 2019-2021 felord.cn + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * Website: + * https://felord.cn + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.felord.payment.wechat.v2; + +import cn.felord.payment.wechat.WechatPayProperties; +import cn.felord.payment.wechat.v2.model.BaseModel; +import cn.felord.payment.wechat.v2.model.allocation.*; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.PropertyNamingStrategy; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpMethod; + +import java.util.List; + +/** + * 微信支付分账 + *

+ * + * @since 1.0.10.RELEASE + */ +@Slf4j +public class WechatAllocationApi { + /** + * The constant MAPPER. + */ + private static final ObjectMapper MAPPER = new ObjectMapper(); + + static { + MAPPER.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE) + .setSerializationInclusion(JsonInclude.Include.NON_NULL) + .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) + .configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true) + .registerModule(new JavaTimeModule()); + } + + private final WechatV2Client wechatV2Client; + + /** + * Instantiates a new Wechat allocation api. + * + * @param wechatV2Client the wechat v 2 client + */ + public WechatAllocationApi(WechatV2Client wechatV2Client) { + this.wechatV2Client = wechatV2Client; + } + + /** + * 请求单次分账 + * + * @param profitSharingModel the profit sharing model + * @return json node + */ + @SneakyThrows + public JsonNode profitSharing(ProfitSharingModel profitSharingModel) { + ProfitSharingSModel profitSharingSModel = new ProfitSharingSModel(); + List receivers = profitSharingModel.getReceivers(); + profitSharingSModel.setReceivers(MAPPER.writeValueAsString(receivers)); + + WechatPayProperties.V3 v3 = wechatV2Client.getWechatMetaBean().getV3(); + profitSharingSModel.setAppid(v3.getAppId()); + profitSharingSModel.setMchId(v3.getMchId()); + + profitSharingSModel.setTransactionId(profitSharingModel.getTransactionId()); + profitSharingSModel.setOutOrderNo(profitSharingModel.getOutOrderNo()); + + profitSharingSModel.certPath(v3.getCertPath()); + profitSharingSModel.signType(BaseModel.HMAC_SHA256); + return wechatV2Client.wechatPayRequest(profitSharingSModel, + HttpMethod.POST, + "https://api.mch.weixin.qq.com/secapi/pay/profitsharing"); + } + + /** + * 请求单次分账 + * + * @param multiProfitSharingModel the multi profit sharing model + * @return json node + */ + @SneakyThrows + public JsonNode multiProfitSharing(MultiProfitSharingModel multiProfitSharingModel) { + MultiProfitSharingSModel multiProfitSharingSModel = new MultiProfitSharingSModel(); + List receivers = multiProfitSharingModel.getReceivers(); + multiProfitSharingSModel.setReceivers(MAPPER.writeValueAsString(receivers)); + + WechatPayProperties.V3 v3 = wechatV2Client.getWechatMetaBean().getV3(); + multiProfitSharingSModel.setAppid(v3.getAppId()); + multiProfitSharingSModel.setMchId(v3.getMchId()); + + multiProfitSharingSModel.setTransactionId(multiProfitSharingModel.getTransactionId()); + multiProfitSharingSModel.setOutOrderNo(multiProfitSharingModel.getOutOrderNo()); + + multiProfitSharingSModel.certPath(v3.getCertPath()); + multiProfitSharingSModel.signType(BaseModel.HMAC_SHA256); + return wechatV2Client.wechatPayRequest(multiProfitSharingSModel, + HttpMethod.POST, + "https://api.mch.weixin.qq.com/secapi/pay/multiprofitsharing"); + } + + /** + * 查询分账结果 + * + * @param profitSharingQueryModel the profit sharing query model + * @return json node + */ + public JsonNode profitSharingQuery(ProfitSharingQueryModel profitSharingQueryModel) { + WechatPayProperties.V3 v3 = wechatV2Client.getWechatMetaBean().getV3(); + profitSharingQueryModel.setMchId(v3.getMchId()); + profitSharingQueryModel.certPath(v3.getCertPath()); + profitSharingQueryModel.signType(BaseModel.HMAC_SHA256); + return wechatV2Client.wechatPayRequest(profitSharingQueryModel, + HttpMethod.POST, + "https://api.mch.weixin.qq.com/pay/profitsharingquery"); + } + + /** + * 添加分账接收方 + * + * @param profitSharingAddReceiverModel the profit sharing add receiver model + * @return json node + */ + @SneakyThrows + public JsonNode profitSharingAddReceiver(ProfitSharingAddReceiverModel profitSharingAddReceiverModel) { + ProfitSharingAddReceiverSModel profitSharingAddReceiverSModel = new ProfitSharingAddReceiverSModel(); + ProfitSharingAddReceiverModel.Receiver receiver = profitSharingAddReceiverModel.getReceiver(); + profitSharingAddReceiverSModel.setReceiver(MAPPER.writeValueAsString(receiver)); + + WechatPayProperties.V3 v3 = wechatV2Client.getWechatMetaBean().getV3(); + profitSharingAddReceiverSModel.setAppid(v3.getAppId()); + profitSharingAddReceiverSModel.setMchId(v3.getMchId()); + + profitSharingAddReceiverSModel.certPath(v3.getCertPath()); + profitSharingAddReceiverSModel.signType(BaseModel.HMAC_SHA256); + return wechatV2Client.wechatPayRequest(profitSharingAddReceiverSModel, + HttpMethod.POST, + "https://api.mch.weixin.qq.com/pay/profitsharingaddreceiver"); + } + + /** + * 删除分账接收方 + * + * @param profitSharingRemoveReceiverModel the profit sharing remove receiver model + * @return json node + */ + @SneakyThrows + public JsonNode profitSharingRemoveReceiver(ProfitSharingRemoveReceiverModel profitSharingRemoveReceiverModel) { + ProfitSharingRemoveReceiverSModel profitSharingRemoveReceiverSModel = new ProfitSharingRemoveReceiverSModel(); + ProfitSharingRemoveReceiverModel.Receiver receiver = profitSharingRemoveReceiverModel.getReceiver(); + profitSharingRemoveReceiverSModel.setReceiver(MAPPER.writeValueAsString(receiver)); + + WechatPayProperties.V3 v3 = wechatV2Client.getWechatMetaBean().getV3(); + profitSharingRemoveReceiverSModel.setAppid(v3.getAppId()); + profitSharingRemoveReceiverSModel.setMchId(v3.getMchId()); + + profitSharingRemoveReceiverSModel.certPath(v3.getCertPath()); + profitSharingRemoveReceiverSModel.signType(BaseModel.HMAC_SHA256); + return wechatV2Client.wechatPayRequest(profitSharingRemoveReceiverSModel, + HttpMethod.POST, + "https://api.mch.weixin.qq.com/pay/profitsharingremovereceiver"); + } + + /** + * 完结分账 + * + * @param profitSharingFinishModel the profit sharing finish model + * @return json node + */ + public JsonNode profitSharingFinish(ProfitSharingFinishModel profitSharingFinishModel) { + WechatPayProperties.V3 v3 = wechatV2Client.getWechatMetaBean().getV3(); + profitSharingFinishModel.setAppid(v3.getAppId()); + profitSharingFinishModel.setMchId(v3.getMchId()); + profitSharingFinishModel.certPath(v3.getCertPath()); + profitSharingFinishModel.signType(BaseModel.HMAC_SHA256); + return wechatV2Client.wechatPayRequest(profitSharingFinishModel, + HttpMethod.POST, + "https://api.mch.weixin.qq.com/secapi/pay/profitsharingfinish"); + } + + /** + * 查询订单待分账金额 + * + * @param profitSharingOrderAmountQueryModel the profit sharing order amount query model + * @return json node + */ + public JsonNode profitSharingOrderAmountQuery(ProfitSharingOrderAmountQueryModel profitSharingOrderAmountQueryModel) { + WechatPayProperties.V3 v3 = wechatV2Client.getWechatMetaBean().getV3(); + profitSharingOrderAmountQueryModel.setMchId(v3.getMchId()); + profitSharingOrderAmountQueryModel.certPath(v3.getCertPath()); + profitSharingOrderAmountQueryModel.signType(BaseModel.HMAC_SHA256); + return wechatV2Client.wechatPayRequest(profitSharingOrderAmountQueryModel, + HttpMethod.POST, + "https://api.mch.weixin.qq.com/pay/profitsharingorderamountquery"); + } + + /** + * 分账回退 + * + * @param profitSharingReturnModel the profit sharing return model + * @return json node + */ + public JsonNode profitSharingReturn(ProfitSharingReturnModel profitSharingReturnModel) { + WechatPayProperties.V3 v3 = wechatV2Client.getWechatMetaBean().getV3(); + profitSharingReturnModel.setAppid(v3.getAppId()); + profitSharingReturnModel.setMchId(v3.getMchId()); + profitSharingReturnModel.certPath(v3.getCertPath()); + profitSharingReturnModel.signType(BaseModel.HMAC_SHA256); + return wechatV2Client.wechatPayRequest(profitSharingReturnModel, + HttpMethod.POST, + "https://api.mch.weixin.qq.com/secapi/pay/profitsharingreturn"); + } + + /** + * 回退结果查询 + * + * @param profitSharingReturnQueryModel the profit sharing return query model + * @return json node + */ + public JsonNode profitSharingReturnQuery(ProfitSharingReturnQueryModel profitSharingReturnQueryModel) { + WechatPayProperties.V3 v3 = wechatV2Client.getWechatMetaBean().getV3(); + profitSharingReturnQueryModel.setAppid(v3.getAppId()); + profitSharingReturnQueryModel.setMchId(v3.getMchId()); + profitSharingReturnQueryModel.certPath(v3.getCertPath()); + profitSharingReturnQueryModel.signType(BaseModel.HMAC_SHA256); + return wechatV2Client.wechatPayRequest(profitSharingReturnQueryModel, + HttpMethod.POST, + "https://api.mch.weixin.qq.com/pay/profitsharingreturnquery"); + } + +} diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v2/model/BaseModel.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v2/model/BaseModel.java index f1d5fe8..1f6380f 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v2/model/BaseModel.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v2/model/BaseModel.java @@ -48,6 +48,8 @@ import org.springframework.util.IdGenerator; import org.springframework.web.client.RestTemplate; import org.springframework.web.util.UriComponentsBuilder; +import javax.crypto.Mac; +import javax.crypto.spec.SecretKeySpec; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLContext; import java.io.IOException; @@ -63,6 +65,7 @@ import java.security.cert.CertificateException; */ @Getter public abstract class BaseModel { + public static final String HMAC_SHA256="HMAC-SHA256"; private static final XmlMapper XML_MAPPER = new XmlMapper(); private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); @@ -84,13 +87,27 @@ public abstract class BaseModel { private String sign; @JsonIgnore private String appSecret; - + @JsonIgnore + private String certPath; + @JsonIgnore + private String signType; public BaseModel appSecret(String appSecret) { this.appSecret = appSecret; return this; } + public BaseModel certPath(String certPath) { + this.certPath = certPath; + return this; + } + + + public BaseModel signType(String signType) { + this.signType = signType; + return this; + } + /** * Xml string. * @@ -99,7 +116,11 @@ public abstract class BaseModel { @SneakyThrows private String xml() { String link = link(this); - this.sign = this.md5(link); + if (HMAC_SHA256.equals(signType)) { + this.sign = this.hmacSha256(link); + } else { + this.sign = this.md5(link); + } return XML_MAPPER.writer() .withRootName("xml") .writeValueAsString(this); @@ -120,6 +141,21 @@ public abstract class BaseModel { return Hex.toHexString(md5Bytes).toUpperCase(); } + /** + * hmacSha256. + * + * @param src the src + * @return the string + */ + @SneakyThrows + private String hmacSha256(String src) { + Mac sha256_HMAC = Mac.getInstance("HmacSHA256"); + SecretKeySpec secret_key = new SecretKeySpec(appSecret.getBytes(),"HmacSHA256"); + sha256_HMAC.init(secret_key); + byte[] bytes = sha256_HMAC.doFinal(src.getBytes(StandardCharsets.UTF_8)); + return Hex.toHexString(bytes).toUpperCase(); + } + /** * 按照格式拼接参数以生成签名 * @@ -130,14 +166,13 @@ public abstract class BaseModel { @SneakyThrows private String link(T t) { Assert.hasText(appSecret, "wechat pay appSecret is required"); - return OBJECT_MAPPER + String link = OBJECT_MAPPER .writer() .writeValueAsString(t) .replaceAll("\":\"", "=") .replaceAll("\",\"", "&") - .replaceAll("\\{\"", "") - .replaceAll("\"}", "") - .concat("&key=").concat(this.appSecret); + .replaceAll("\\\\\"", "\""); + return link.substring(2, link.length() - 2).concat("&key=").concat(this.appSecret); } @@ -164,7 +199,7 @@ public abstract class BaseModel { private RestTemplate getRestTemplateClientAuthentication(String mchId) throws IOException, UnrecoverableKeyException, CertificateException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException { - ClassPathResource resource = new ClassPathResource("wechat/apiclient_cert.p12"); + ClassPathResource resource = new ClassPathResource(certPath == null ? "wechat/apiclient_cert.p12" : certPath); char[] pem = mchId.toCharArray(); diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v2/model/allocation/BaseProfitSharingModel.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v2/model/allocation/BaseProfitSharingModel.java new file mode 100644 index 0000000..b526ad2 --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v2/model/allocation/BaseProfitSharingModel.java @@ -0,0 +1,45 @@ +/* + * Copyright 2019-2021 felord.cn + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * Website: + * https://felord.cn + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.felord.payment.wechat.v2.model.allocation; + +import cn.felord.payment.wechat.v2.model.BaseModel; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * The type Base profit sharing model. + * + * @author wangzecheng + * @since 1.0.10.RELEASE + */ +@EqualsAndHashCode(callSuper = true) +@Data +public class BaseProfitSharingModel extends BaseModel { + + + /** + * 商户号. + *

+ * 微信支付分配的商户号 + */ + private String mchId; + private String appid; + private String transactionId; + private String outOrderNo; + +} diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v2/model/allocation/BaseProfitSharingReceiverModel.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v2/model/allocation/BaseProfitSharingReceiverModel.java new file mode 100644 index 0000000..7a235f3 --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v2/model/allocation/BaseProfitSharingReceiverModel.java @@ -0,0 +1,47 @@ +/* + * Copyright 2019-2021 felord.cn + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * Website: + * https://felord.cn + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.felord.payment.wechat.v2.model.allocation; + +import cn.felord.payment.wechat.v2.model.BaseModel; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * The type Base profit sharing receiver model. + * + * @author wangzecheng + * @since 1.0.10.RELEASE + */ +@EqualsAndHashCode(callSuper = true) +@Data +public class BaseProfitSharingReceiverModel extends BaseModel { + /** + * 商户号. + *

+ * 微信支付分配的商户号 + */ + private String mchId; + + /** + * 公众账号ID. + *

+ * 微信分配的公众账号ID + */ + private String appid; + +} diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v2/model/allocation/MultiProfitSharingModel.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v2/model/allocation/MultiProfitSharingModel.java new file mode 100644 index 0000000..8718017 --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v2/model/allocation/MultiProfitSharingModel.java @@ -0,0 +1,28 @@ +/* + * Copyright 2019-2021 felord.cn + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * Website: + * https://felord.cn + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.felord.payment.wechat.v2.model.allocation; + +/** + * The type Multi profit sharing model. + * + * @author wangzecheng + * @since 1.0.10.RELEASE + */ +public class MultiProfitSharingModel extends ProfitSharingModel { + +} diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v2/model/allocation/MultiProfitSharingSModel.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v2/model/allocation/MultiProfitSharingSModel.java new file mode 100644 index 0000000..af5f404 --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v2/model/allocation/MultiProfitSharingSModel.java @@ -0,0 +1,28 @@ +/* + * Copyright 2019-2021 felord.cn + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * Website: + * https://felord.cn + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.felord.payment.wechat.v2.model.allocation; + +/** + * The type Multi profit sharing s model. + * + * @author wangzecheng + * @since 1.0.10.RELEASE + */ +public class MultiProfitSharingSModel extends ProfitSharingSModel { + +} diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v2/model/allocation/ProfitSharingAddReceiverModel.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v2/model/allocation/ProfitSharingAddReceiverModel.java new file mode 100644 index 0000000..34d31d4 --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v2/model/allocation/ProfitSharingAddReceiverModel.java @@ -0,0 +1,95 @@ +/* + * Copyright 2019-2021 felord.cn + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * Website: + * https://felord.cn + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.felord.payment.wechat.v2.model.allocation; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * The type Profit sharing add receiver model. + * + * @author wangzecheng + * @since 1.0.10.RELEASE + */ +@EqualsAndHashCode(callSuper = true) +@Data +public class ProfitSharingAddReceiverModel extends BaseProfitSharingReceiverModel { + + private Receiver receiver; + + /** + * The type Receiver. + */ + @Data + public static class Receiver { + + /** + * 分账接收方类型. + *

+ * MERCHANT_ID:商户号(mch_id或者sub_mch_id) + * PERSONAL_OPENID:个人openid + */ + private Type type; + + /** + * 分账接收方帐号. + *

+ * 类型是MERCHANT_ID时,是商户号(mch_id或者sub_mch_id) + * 类型是PERSONAL_OPENID时,是个人openid + */ + private String account; + + /** + * 分账接收方全称. + *

+ * 分账接收方类型是MERCHANT_ID时,是商户全称(必传),当商户是小微商户或个体户时,是开户人姓名 + * 分账接收方类型是PERSONAL_OPENID时,是个人姓名(选传,传则校验) + */ + private String name; + + /** + * 与分账方的关系类型. + *

+ * 子商户与接收方的关系。 + * 本字段值为枚举: + * SERVICE_PROVIDER:服务商 + * STORE:门店 + * STAFF:员工 + * STORE_OWNER:店主 + * PARTNER:合作伙伴 + * HEADQUARTER:总部 + * BRAND:品牌方 + * DISTRIBUTOR:分销商 + * USER:用户 + * SUPPLIER:供应商 + * CUSTOM:自定义 + */ + private RelationType relationType; + + /** + * 自定义的分账关系. + *

+ * 子商户与接收方具体的关系,本字段最多10个字。 + * 当字段relation_type的值为CUSTOM时,本字段必填 + * 当字段relation_type的值不为CUSTOM时,本字段无需填写 + */ + private String customRelation; + + } + +} diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v2/model/allocation/ProfitSharingAddReceiverSModel.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v2/model/allocation/ProfitSharingAddReceiverSModel.java new file mode 100644 index 0000000..ba8ef1b --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v2/model/allocation/ProfitSharingAddReceiverSModel.java @@ -0,0 +1,35 @@ +/* + * Copyright 2019-2021 felord.cn + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * Website: + * https://felord.cn + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.felord.payment.wechat.v2.model.allocation; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * The type Profit sharing add receiver s model. + * + * @author wangzecheng + * @since 1.0.10.RELEASE + */ +@EqualsAndHashCode(callSuper = true) +@Data +public class ProfitSharingAddReceiverSModel extends BaseProfitSharingReceiverModel { + + private String receiver; + +} diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v2/model/allocation/ProfitSharingFinishModel.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v2/model/allocation/ProfitSharingFinishModel.java new file mode 100644 index 0000000..4d046f3 --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v2/model/allocation/ProfitSharingFinishModel.java @@ -0,0 +1,69 @@ +/* + * Copyright 2019-2021 felord.cn + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * Website: + * https://felord.cn + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.felord.payment.wechat.v2.model.allocation; + +import cn.felord.payment.wechat.v2.model.BaseModel; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * The type Profit sharing finish model. + * + * @author wangzecheng + * @since 1.0.10.RELEASE + */ +@EqualsAndHashCode(callSuper = true) +@Data +public class ProfitSharingFinishModel extends BaseModel { + + /** + * 商户号. + *

+ * 微信支付分配的商户号 + */ + private String mchId; + + /** + * 公众账号ID. + *

+ * 微信分配的公众账号ID + */ + private String appid; + + /** + * 微信订单号. + *

+ * 微信支付订单号 + */ + private String transactionId; + + /** + * 商户分账单号. + *

+ * 查询分账结果,输入申请分账时的商户分账单号; 查询分账完结执行的结果,输入发起分账完结时的商户分账单号 + */ + private String outOrderNo; + + /** + * 分账完结描述. + *

+ * 分账完结的原因描述 + */ + private String description; + +} diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v2/model/allocation/ProfitSharingModel.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v2/model/allocation/ProfitSharingModel.java new file mode 100644 index 0000000..638ff68 --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v2/model/allocation/ProfitSharingModel.java @@ -0,0 +1,41 @@ +/* + * Copyright 2019-2021 felord.cn + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * Website: + * https://felord.cn + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.felord.payment.wechat.v2.model.allocation; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.List; + +/** + * 单次分账请求按照传入的分账接收方账号和资金进行分账,同时会将订单剩余的待分账金额解冻给本商户。 + * 故操作成功后,订单不能再进行分账,也不能进行分账完结。 + * + * @author wangzecheng + * @since 1.0.10.RELEASE + */ +@EqualsAndHashCode(callSuper = true) +@Data +public class ProfitSharingModel extends BaseProfitSharingModel { + + /** + * 分账接收方列表,不超过50个json对象,不能设置分账方作为分账接受方 + */ + private List receivers; + +} diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v2/model/allocation/ProfitSharingOrderAmountQueryModel.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v2/model/allocation/ProfitSharingOrderAmountQueryModel.java new file mode 100644 index 0000000..02b9ab2 --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v2/model/allocation/ProfitSharingOrderAmountQueryModel.java @@ -0,0 +1,48 @@ +/* + * Copyright 2019-2021 felord.cn + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * Website: + * https://felord.cn + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.felord.payment.wechat.v2.model.allocation; + +import cn.felord.payment.wechat.v2.model.BaseModel; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * The type Profit sharing order amount query model. + * + * @author wangzecheng + * @since 1.0.10.RELEASE + */ +@EqualsAndHashCode(callSuper = true) +@Data +public class ProfitSharingOrderAmountQueryModel extends BaseModel { + + /** + * 商户号. + *

+ * 微信支付分配的商户号 + */ + private String mchId; + + /** + * 微信订单号. + *

+ * 微信支付订单号 + */ + private String transactionId; + +} diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v2/model/allocation/ProfitSharingQueryModel.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v2/model/allocation/ProfitSharingQueryModel.java new file mode 100644 index 0000000..1f7584d --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v2/model/allocation/ProfitSharingQueryModel.java @@ -0,0 +1,55 @@ +/* + * Copyright 2019-2021 felord.cn + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * Website: + * https://felord.cn + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.felord.payment.wechat.v2.model.allocation; + +import cn.felord.payment.wechat.v2.model.BaseModel; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * The type Profit sharing query model. + * + * @author wangzecheng + * @since 1.0.10.RELEASE + */ +@EqualsAndHashCode(callSuper = true) +@Data +public class ProfitSharingQueryModel extends BaseModel { + + /** + * 商户号. + *

+ * 微信支付分配的商户号 + */ + private String mchId; + + /** + * 微信订单号. + *

+ * 微信支付订单号 + */ + private String transactionId; + + /** + * 商户分账单号. + *

+ * 查询分账结果,输入申请分账时的商户分账单号; 查询分账完结执行的结果,输入发起分账完结时的商户分账单号 + */ + private String outOrderNo; + +} diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v2/model/allocation/ProfitSharingRemoveReceiverModel.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v2/model/allocation/ProfitSharingRemoveReceiverModel.java new file mode 100644 index 0000000..b97c49e --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v2/model/allocation/ProfitSharingRemoveReceiverModel.java @@ -0,0 +1,46 @@ +/* + * Copyright 2019-2021 felord.cn + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * Website: + * https://felord.cn + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.felord.payment.wechat.v2.model.allocation; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * The type Profit sharing remove receiver model. + * + * @author wangzecheng + * @since 1.0.10.RELEASE + */ +@EqualsAndHashCode(callSuper = true) +@Data +public class ProfitSharingRemoveReceiverModel extends BaseProfitSharingReceiverModel { + + private Receiver receiver; + + /** + * The type Receiver. + */ + @Data + public static class Receiver { + + private Type type; + private String account; + + } + +} diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v2/model/allocation/ProfitSharingRemoveReceiverSModel.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v2/model/allocation/ProfitSharingRemoveReceiverSModel.java new file mode 100644 index 0000000..39ef4d3 --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v2/model/allocation/ProfitSharingRemoveReceiverSModel.java @@ -0,0 +1,35 @@ +/* + * Copyright 2019-2021 felord.cn + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * Website: + * https://felord.cn + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.felord.payment.wechat.v2.model.allocation; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * The type Profit sharing remove receiver s model. + * + * @author wangzecheng + * @since 1.0.10.RELEASE + */ +@EqualsAndHashCode(callSuper = true) +@Data +public class ProfitSharingRemoveReceiverSModel extends BaseProfitSharingReceiverModel { + + private String receiver; + +} diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v2/model/allocation/ProfitSharingReturnModel.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v2/model/allocation/ProfitSharingReturnModel.java new file mode 100644 index 0000000..6a7f021 --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v2/model/allocation/ProfitSharingReturnModel.java @@ -0,0 +1,55 @@ +/* + * Copyright 2019-2021 felord.cn + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * Website: + * https://felord.cn + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.felord.payment.wechat.v2.model.allocation; + +import cn.felord.payment.wechat.v2.model.BaseModel; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * The type Profit sharing return model. + * + * @author wangzecheng + * @since 1.0.10.RELEASE + */ +@EqualsAndHashCode(callSuper = true) +@Data +public class ProfitSharingReturnModel extends BaseModel { + + /** + * 商户号. + *

+ * 微信支付分配的商户号 + */ + private String mchId; + + /** + * 公众账号ID. + *

+ * 微信分配的公众账号ID + */ + private String appid; + private String orderId; + private String outOrderNo; + private String outReturnNo; + private String returnAccountType; + private String returnAccount; + private String returnAmount; + private String description; + +} diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v2/model/allocation/ProfitSharingReturnQueryModel.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v2/model/allocation/ProfitSharingReturnQueryModel.java new file mode 100644 index 0000000..40669db --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v2/model/allocation/ProfitSharingReturnQueryModel.java @@ -0,0 +1,71 @@ +/* + * Copyright 2019-2021 felord.cn + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * Website: + * https://felord.cn + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.felord.payment.wechat.v2.model.allocation; + +import cn.felord.payment.wechat.v2.model.BaseModel; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * The type Profit sharing return query model. + * + * @author wangzecheng + * @since 1.0.10.RELEASE + */ +@EqualsAndHashCode(callSuper = true) +@Data +public class ProfitSharingReturnQueryModel extends BaseModel { + + /** + * 商户号. + *

+ * 微信支付分配的商户号 + */ + private String mchId; + + /** + * 公众账号ID. + *

+ * 微信分配的公众账号ID + */ + private String appid; + + /** + * 微信分账订单号. + *

+ * 原发起分账请求时,微信返回的微信分账单号,与商户分账单号一一对应。 + * 微信分账单号与商户分账单号二选一填写 + */ + private String orderId; + + /** + * 商户分账单号. + *

+ * 原发起分账请求时使用的商户系统内部的分账单号。 + * 微信分账单号与商户分账单号二选一填写 + */ + private String outOrderNo; + + /** + * 商户回退单号. + *

+ * 调用回退接口提供的商户系统内部的回退单号 + */ + private String outReturnNo; + +} diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v2/model/allocation/ProfitSharingSModel.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v2/model/allocation/ProfitSharingSModel.java new file mode 100644 index 0000000..99df912 --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v2/model/allocation/ProfitSharingSModel.java @@ -0,0 +1,37 @@ +/* + * Copyright 2019-2021 felord.cn + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * Website: + * https://felord.cn + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package cn.felord.payment.wechat.v2.model.allocation; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * The type Profit sharing s model. + * + * @author wangzecheng + * @since 1.0.10.RELEASE + */ +@EqualsAndHashCode(callSuper = true) +@Data +public class ProfitSharingSModel extends BaseProfitSharingModel { + + /** + * 分账接收方列表,不超过50个json对象,不能设置分账方作为分账接受方。 + */ + private String receivers; + +} diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v2/model/allocation/Receiver.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v2/model/allocation/Receiver.java new file mode 100644 index 0000000..352b822 --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v2/model/allocation/Receiver.java @@ -0,0 +1,69 @@ +/* + * Copyright 2019-2021 felord.cn + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * Website: + * https://felord.cn + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.felord.payment.wechat.v2.model.allocation; + +import lombok.Data; + +/** + * The type Receiver. + * + * @author wangzecheng + * @since 1.0.10.RELEASE + */ +@Data +public class Receiver { + + /** + * 分账接收方类型. + *

+ * MERCHANT_ID:商户号(mch_id或者sub_mch_id) + * PERSONAL_OPENID:个人openid + */ + private Type type; + + /** + * 分账接收方帐号. + *

+ * 类型是MERCHANT_ID时,是商户号(mch_id或者sub_mch_id) + * 类型是PERSONAL_OPENID时,是个人openid + */ + private String account; + + /** + * 分账金额. + *

+ * 单位为分,只能为整数,不能超过原订单支付金额及最大分账比例金额 + */ + private Integer amount; + + /** + * 分账描述. + *

+ * 分账的原因描述,分账账单中需要体现 + */ + private String description; + + /** + * 分账个人接收方姓名. + *

+ * 可选项,在接收方类型为个人的时可选填,若有值,会检查与 name 是否实名匹配,不匹配会拒绝分账请求. + * 1、分账接收方类型是PERSONAL_OPENID时,是个人姓名(选传,传则校验) + */ + private String name; + +} diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v2/model/allocation/RelationType.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v2/model/allocation/RelationType.java new file mode 100644 index 0000000..319abc1 --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v2/model/allocation/RelationType.java @@ -0,0 +1,72 @@ +/* + * Copyright 2019-2021 felord.cn + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * Website: + * https://felord.cn + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.felord.payment.wechat.v2.model.allocation; + +/** + * The enum Relation type. + * @author wangzecheng + * @since 1.0.10.RELEASE + */ +public enum RelationType { + + /** + * Service provider relation type. + */ + SERVICE_PROVIDER, + /** + * Store relation type. + */ + STORE, + /** + * Staff relation type. + */ + STAFF, + /** + * Store owner relation type. + */ + STORE_OWNER, + /** + * Partner relation type. + */ + PARTNER, + /** + * Headquarter relation type. + */ + HEADQUARTER, + /** + * Brand relation type. + */ + BRAND, + /** + * Distributor relation type. + */ + DISTRIBUTOR, + /** + * User relation type. + */ + USER, + /** + * Supplier relation type. + */ + SUPPLIER, + /** + * Custom relation type. + */ + CUSTOM + +} diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v2/model/allocation/Type.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v2/model/allocation/Type.java new file mode 100644 index 0000000..1a0b7be --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v2/model/allocation/Type.java @@ -0,0 +1,20 @@ +package cn.felord.payment.wechat.v2.model.allocation; + +/** + * The enum Type. + * + * @author wangzecheng + * @since 1.0.10.RELEASE + */ +public enum Type { + + /** + * 商户号(mch_id或者sub_mch_id) + */ + MERCHANT_ID, + + /** + * 个人openid + */ + PERSONAL_OPENID +} 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 546c453..50615ec 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 @@ -202,6 +202,21 @@ public abstract class AbstractApi { .build(); } + /** + * 构建Post请求对象. + * + * @param uri the uri + * @param params the params + * @return the request entity + */ + protected RequestEntity Patch(URI uri, Object params) { + try { + return RequestEntity.patch(uri).header("Pay-TenantId", tenantId) + .body(mapper.writeValueAsString(params)); + } catch (JsonProcessingException e) { + throw new PayException("wechat app pay json failed"); + } + } /** * 对账单内容下载,非流文件。 * diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/KeyPairFactory.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/KeyPairFactory.java index 839245f..c6a3547 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/KeyPairFactory.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/KeyPairFactory.java @@ -22,10 +22,7 @@ package cn.felord.payment.wechat.v3; import cn.felord.payment.PayException; import org.springframework.core.io.ClassPathResource; -import java.security.KeyPair; -import java.security.KeyStore; -import java.security.PrivateKey; -import java.security.PublicKey; +import java.security.*; import java.security.cert.X509Certificate; /** @@ -36,9 +33,16 @@ import java.security.cert.X509Certificate; **/ public class KeyPairFactory { - private KeyStore store; + private static final KeyStore PKCS12_KEY_STORE; + + static { + try { + PKCS12_KEY_STORE = KeyStore.getInstance("PKCS12"); + } catch (KeyStoreException e) { + throw new PayException(" wechat pay keystore initialization failed"); + } + } - private final Object lock = new Object(); /** * 获取公私钥. @@ -48,23 +52,16 @@ public class KeyPairFactory { * @param keyPass password * @return the key pair */ - public WechatMetaBean createPKCS12(String keyPath, String keyAlias, String keyPass) { + public WechatMetaBean initWechatMetaBean(String keyPath, String keyAlias, String keyPass) { ClassPathResource resource = new ClassPathResource(keyPath); char[] pem = keyPass.toCharArray(); try { - synchronized (lock) { - if (store == null) { - synchronized (lock) { - store = KeyStore.getInstance("PKCS12"); - store.load(resource.getInputStream(), pem); - } - } - } - X509Certificate certificate = (X509Certificate) store.getCertificate(keyAlias); + PKCS12_KEY_STORE.load(resource.getInputStream(), pem); + X509Certificate certificate = (X509Certificate) PKCS12_KEY_STORE.getCertificate(keyAlias); certificate.checkValidity(); String serialNumber = certificate.getSerialNumber().toString(16).toUpperCase(); PublicKey publicKey = certificate.getPublicKey(); - PrivateKey storeKey = (PrivateKey) store.getKey(keyAlias, pem); + PrivateKey storeKey = (PrivateKey) PKCS12_KEY_STORE.getKey(keyAlias, pem); WechatMetaBean wechatMetaBean = new WechatMetaBean(); wechatMetaBean.setKeyPair(new KeyPair(publicKey, storeKey)); wechatMetaBean.setSerialNumber(serialNumber); 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 bab8d0e..b7c9778 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 @@ -18,6 +18,7 @@ */ package cn.felord.payment.wechat.v3; +import cn.felord.payment.wechat.v2.WechatAllocationApi; import cn.felord.payment.wechat.v2.WechatPayRedpackApi; import cn.felord.payment.wechat.v2.WechatPayTransfersApi; import cn.felord.payment.wechat.v2.WechatV2Client; @@ -177,4 +178,19 @@ public class WechatApiProvider { return new WechatPayTransfersApi(wechatV2Client); } + /** + * 微信支付分账,基于V2 + * + * @param tenantId the tenant id + * @return wechat allocation api + * @since 1.0.10.RELEASE + */ + public WechatAllocationApi allocationApi(String tenantId) { + WechatMetaBean wechatMeta = wechatPayClient.signatureProvider() + .wechatMetaContainer() + .getWechatMeta(tenantId); + WechatV2Client wechatV2Client = new WechatV2Client(wechatMeta); + return new WechatAllocationApi(wechatV2Client); + } + } 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 9fd4018..b29e50f 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 @@ -384,7 +384,7 @@ public class WechatMarketingBusiFavorApi extends AbstractApi { .expand(updateParams.getStockId()) .toUri(); updateParams.setStockId(null); - return Post(uri, updateParams); + return Patch(uri, updateParams); }) .consumer(wechatResponseEntity::convert) .request(); diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatPayCallback.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatPayCallback.java index 77d41df..f6789a8 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatPayCallback.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatPayCallback.java @@ -91,6 +91,27 @@ public class WechatPayCallback { } + /** + * 微信支付分账回调. + * + * @param params the params + * @param consumeDataConsumer the consume data consumer + * @return the map + * @since 1.0.10.RELEASE + */ + @SneakyThrows + public Map profitSharingCallback(ResponseSignVerifyParams params, Consumer consumeDataConsumer) { + String data = this.callback(params, EventType.TRANSACTION); + ProfitSharingConsumeData consumeData = MAPPER.readValue(data, ProfitSharingConsumeData.class); + consumeDataConsumer.accept(consumeData); + Map responseBody = new HashMap<>(2); + responseBody.put("code", 200); + responseBody.put("message", "SUCCESS"); + return responseBody; + + } + + /** * 微信支付代金券核销回调. * 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 new file mode 100644 index 0000000..d0edeb3 --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/ProfitSharingConsumeData.java @@ -0,0 +1,77 @@ +/* + * + * Copyright 2019-2020 felord.cn + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * Website: + * https://felord.cn + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package cn.felord.payment.wechat.v3.model; + +import cn.felord.payment.wechat.v2.model.allocation.Receiver; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 微信支付分账通知参数 + * + * @author wangzecheng + * @since 1.0.10.RELEASE + */ +@Data +public class ProfitSharingConsumeData { + + /** + * 直连商户号. + *

+ * 直连模式分账发起和出资商户 + */ + private String mchid; + + /** + * 微信订单号. + *

+ * 微信支付订单号 + */ + private String transactionId; + + /** + * 微信分账/回退单号. + */ + private String orderId; + + /** + * 商户分账/回退单号. + *

+ * 分账方系统内部的分账/回退单号 + */ + private String outOrderNo; + + /** + * 分账接收方. + *

+ * 分账接收方对象 + */ + private Receiver receiver; + + /** + * 成功时间. + *

+ * Rfc3339标准 + */ + @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssXXX", timezone = "GMT+8") + private LocalDateTime successTime; + +} diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/RefundConsumeData.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/RefundConsumeData.java index a9a942f..f983733 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/RefundConsumeData.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/RefundConsumeData.java @@ -22,7 +22,7 @@ import cn.felord.payment.wechat.enumeration.RefundStatus; import com.fasterxml.jackson.annotation.JsonFormat; import lombok.Data; -import java.time.OffsetDateTime; +import java.time.LocalDateTime; /** * 微信支付退款结果通知解密 @@ -60,7 +60,7 @@ public class RefundConsumeData { * 退款成功时间 */ @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssXXX", timezone = "GMT+8") - private OffsetDateTime successTime; + private LocalDateTime successTime; /** * 退款入账账户 */ diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/TransactionConsumeData.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/TransactionConsumeData.java index a9fe1f7..8d070a9 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/TransactionConsumeData.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/TransactionConsumeData.java @@ -23,7 +23,7 @@ import cn.felord.payment.wechat.enumeration.TradeType; import com.fasterxml.jackson.annotation.JsonFormat; import lombok.Data; -import java.time.OffsetDateTime; +import java.time.LocalDateTime; import java.util.List; /** @@ -91,7 +91,7 @@ public class TransactionConsumeData { * 支付完成时间 YYYY-MM-DDTHH:mm:ss+TIMEZONE */ @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssXXX", timezone = "GMT+8") - private OffsetDateTime successTime; + private LocalDateTime successTime; /** * 在 1.0.0.RELEASE 直接返回了枚举字符串,1.0.2.RELEASE 中变更为枚举 * diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/busifavor/BusiFavorReceiveConsumeData.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/busifavor/BusiFavorReceiveConsumeData.java index 2560165..bdd250b 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/busifavor/BusiFavorReceiveConsumeData.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/busifavor/BusiFavorReceiveConsumeData.java @@ -20,7 +20,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; /** * 商家券领券事件回调通知解密 @@ -50,7 +50,7 @@ public class BusiFavorReceiveConsumeData { * 发放时间 rfc 3339 yyyy-MM-ddTHH:mm:ss+TIMEZONE */ @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssXXX", timezone = "GMT+8") - private OffsetDateTime sendTime; + private LocalDateTime sendTime; /** * 微信用户在appid下的唯一标识。 */ diff --git a/payment-spring-boot-starter/pom.xml b/payment-spring-boot-starter/pom.xml index 2a817cd..dd4975d 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.9.RELEASE + 1.0.10.RELEASE payment-spring-boot-starter - 1.0.9.RELEASE + 1.0.10.RELEASE jar 4.0.0 diff --git a/pom.xml b/pom.xml index 2fc0f08..5d1a7c8 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.9.RELEASE + 1.0.10.RELEASE pom 4.0.0