From 303db8bc49b62101cfe2d373d58f6b23e0db45fb Mon Sep 17 00:00:00 2001 From: gong <1157756119@qq.com> Date: Fri, 26 Dec 2025 11:38:48 +0800 Subject: [PATCH 01/19] =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E6=94=AF=E4=BB=98-?= =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E5=9B=BE=E7=89=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cash-dependencies/pom.xml | 7 + cash-sdk/aggregation-pay/pom.xml | 30 ++++ .../java/com/czg/wechat/WechatConfig.java | 47 ++++++ .../java/com/czg/wechat/WechatEncrypt.java | 47 ++++++ .../com/czg/wechat/WechatEntryManager.java | 157 ++++++++++++++++++ .../java/com/czg/wechat/WechatPayManager.java | 11 ++ .../wechat/dto/config/WechatPayConfigDto.java | 49 ++++++ cash-sdk/pom.xml | 1 + 8 files changed, 349 insertions(+) create mode 100644 cash-sdk/aggregation-pay/pom.xml create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatConfig.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatEncrypt.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatEntryManager.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatPayManager.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/config/WechatPayConfigDto.java diff --git a/cash-dependencies/pom.xml b/cash-dependencies/pom.xml index b5163a004..cbbd275f7 100644 --- a/cash-dependencies/pom.xml +++ b/cash-dependencies/pom.xml @@ -42,6 +42,7 @@ 2.5.1 2.9.10 4.1.128.Final + 0.2.17 @@ -268,6 +269,12 @@ netty-codec-mqtt ${netty.version} + + + com.github.wechatpay-apiv3 + wechatpay-java + ${wechatpay.version} + diff --git a/cash-sdk/aggregation-pay/pom.xml b/cash-sdk/aggregation-pay/pom.xml new file mode 100644 index 000000000..3df1fb396 --- /dev/null +++ b/cash-sdk/aggregation-pay/pom.xml @@ -0,0 +1,30 @@ + + + 4.0.0 + + com.czg + cash-sdk + 1.0.0 + + + aggregation-pay + jar + 聚合支付 + + + + 21 + 21 + UTF-8 + + + + + com.github.wechatpay-apiv3 + wechatpay-java + + + + \ No newline at end of file diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatConfig.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatConfig.java new file mode 100644 index 000000000..ace7aaab8 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatConfig.java @@ -0,0 +1,47 @@ +package com.czg.wechat; + +import com.czg.wechat.dto.config.WechatPayConfigDto; +import com.wechat.pay.java.core.Config; +import com.wechat.pay.java.core.RSAPublicKeyConfig; +import com.wechat.pay.java.service.file.FileUploadService; + +/** + * 微信支付 配置 + * + * @author yjjie + * @date 2025/12/26 09:33 + */ +public class WechatConfig { + + /** + * 获取微信支付配置 + * @param dto 微信支付配置 + * @return 微信支付配置 + */ + public static Config getConfig(WechatPayConfigDto dto) { + return new RSAPublicKeyConfig.Builder() + .merchantId(dto.getMerchantId()) + .privateKey(dto.getPrivateKey()) + .publicKey(dto.getPublicKey()) + .publicKeyId(dto.getPublicKeyId()) + .merchantSerialNumber(dto.getSerialNumber()) + .apiV3Key(dto.getApiV3Key()) + .build(); + } + + public static FileUploadService getFileUploadService(Config config) { + return new FileUploadService.Builder() + .config(config) + .build(); + } + + /** + * 获取文件上传服务 + * @param dto 微信支付配置 + * @return 文件上传服务 + */ + public static FileUploadService getFileUploadService(WechatPayConfigDto dto) { + return getFileUploadService(getConfig(dto)); + } + +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatEncrypt.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatEncrypt.java new file mode 100644 index 000000000..82c2cd179 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatEncrypt.java @@ -0,0 +1,47 @@ +package com.czg.wechat; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +/** + * 微信支付加解密 + * @author yjjie + * @date 2025/12/26 10:58 + */ +public class WechatEncrypt { + + public static String getFileBytesSha256(byte[] input) throws NoSuchAlgorithmException { + return bytesToHex(calculateSha256(input)); + } + + /** + * 核心方法:计算字节数组的 SHA-256 哈希值 + * @param input 待计算的字节数组 + * @return SHA-256 哈希值(32 字节的字节数组) + */ + private static byte[] calculateSha256(byte[] input) throws NoSuchAlgorithmException { + // 获取 SHA-256 消息摘要实例(Java 21 完全兼容) + MessageDigest digest = MessageDigest.getInstance("SHA-256"); + // 计算哈希值 + return digest.digest(input); + } + + /** + * 辅助方法:将字节数组转换为十六进制字符串(SHA-256 结果常用格式) + * @param bytes 待转换的字节数组 + * @return 十六进制字符串(SHA-256 对应 64 位字符串) + */ + private static String bytesToHex(byte[] bytes) { + StringBuilder hexString = new StringBuilder(); + // Java 21 可使用 var 简化声明 + for (var b : bytes) { + // 将字节转换为两位十六进制数,不足补 0 + String hex = Integer.toHexString(0xff & b); + if (hex.length() == 1) { + hexString.append('0'); + } + hexString.append(hex); + } + return hexString.toString(); + } +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatEntryManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatEntryManager.java new file mode 100644 index 000000000..162a2ba72 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatEntryManager.java @@ -0,0 +1,157 @@ +package com.czg.wechat; + +import com.alibaba.fastjson2.JSONObject; +import com.czg.wechat.dto.config.WechatPayConfigDto; +import com.wechat.pay.java.service.file.FileUploadService; +import com.wechat.pay.java.service.file.model.FileUploadResponse; +import lombok.extern.slf4j.Slf4j; + +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; + +/** + * 微信支付进件 管理 + * + * @author yjjie + * @date 2025/12/26 10:57 + */ +@Slf4j +public class WechatEntryManager { + + public static String uploadImage(WechatPayConfigDto configDto, String url) { + // 校验入参 + if (configDto == null || url == null || url.trim().isEmpty()) { + log.error("上传图片失败:配置或URL参数为空"); + return ""; + } + + FileUploadService service = WechatConfig.getFileUploadService(configDto); + + try { + // 获取图片字节数组 + byte[] bytes = downloadImage(url); + if (bytes.length == 0) { + log.error("下载的图片内容为空,URL:{}", url); + return ""; + } + + // 2. 计算SHA256 + String sha256Hex = WechatEncrypt.getFileBytesSha256(bytes); + + // 3. 构造元数据(从URL提取文件名,或自定义) + JSONObject meta = new JSONObject(); + meta.put("sha256", sha256Hex); + // 从URL提取文件名,若提取失败则使用默认名 + String fileName = extractFileNameFromUrl(url); + meta.put("filename", fileName); + + // 4. 上传图片到微信接口 + FileUploadResponse uploadResponse = service.uploadImage( + configDto.getDomain() + "/v3/merchant/media/upload", + meta.toJSONString(), + fileName, + bytes + ); + + return uploadResponse.getMediaId(); + } catch (Exception e) { + log.error("微信上传图片报错,URL:{},错误信息:{}", url, e.getMessage(), e); + } + return ""; + } + + public static byte[] downloadImage(String url) throws Exception { + HttpClient client = HttpClient.newHttpClient(); + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(url)) + .GET() + .build(); + + HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofByteArray()); + + if (response.statusCode() != 200) { + throw new RuntimeException("Failed to download image, status code: " + response.statusCode()); + } + + return response.body(); + } + + /** + * 从URL中提取文件名 + * + * @param url 图片URL + * @return 提取的文件名,失败则返回默认名 + */ + private static String extractFileNameFromUrl(String url) { + try { + if (url.contains("/")) { + String fileName = url.substring(url.lastIndexOf("/") + 1); + // 如果文件名包含参数,截取?之前的部分 + if (fileName.contains("?")) { + fileName = fileName.substring(0, fileName.indexOf("?")); + } + // 如果提取的文件名有效,直接返回 + if (fileName.contains(".")) { + return fileName; + } + } + } catch (Exception e) { + log.warn("提取文件名失败,使用默认文件名", e); + } + // 默认文件名 + return "upload_" + System.currentTimeMillis() + ".png"; + } + + public static void main(String[] args) { + WechatPayConfigDto dto = new WechatPayConfigDto() + .setMerchantId("1643779408") + .setApiV3Key("a92baac5eb7a36ed8ec198113e769a03") + .setSerialNumber("4DE9BAC2EA584C3F274F694C9753CA814C4E9BF4") + .setPublicKey(""" + -----BEGIN PUBLIC KEY----- + MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtbeWXEEjBaYtw2OyM+SC + aCEMbryRXi4duKxx3vYG4rUVix+d5/Jz7Khev4Upml9zC+Xxvv/G9bHWAUyolzqD + wefahGurIxr43r4GJVnQ4i5G6BbBVw5d4Vuz0y/9Zd14zmc/EmBpT0Ml26H7tOZl + n1LSbQ4xNFkrRKrNEcExBLxkCd+K5K2TREZznywIi0izbHImvuzM8IneuR51FiqK + pdFnAjTwb126EIj6ECkL6KLCl8RWqpfiX8SFiolSQLs1/w79O0sIUk96X2zWpnoW + rTDFatPif/VEKl3y2dTlxxDxoZtVi48yTDW00OMzVl5D67oX3FVK0KsjHJSCfGlZ + 6wIDAQAB + -----END PUBLIC KEY-----""") + .setPrivateKey(""" + -----BEGIN PRIVATE KEY----- + MIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQDqnAZhTxT572fo + 6wvSr8Rt0vRXg+EFKC6UvUiNE24oocQU5fjedX9KL/+fmoqay/xqIxvxvCNFTs4J + zlMqavSl6bMWCpjvf/Ry82JmN1v2kJEO4lgP8BsEiqlUpObCH8BMAVUOn1j+9q4Q + uZJJcbtRvec2fNweDM8EJp4B7RlUdDbHm86lfcDVp8iini7VjDp6D7aHT+C8A8OT + ugxQIquDec778wVd9r2Sv3+t6rAzFs+n+Zu++2xtFEPhO5N0wjrLHaukl+9crU+1 + lktjDzcPd07SwGZ+A+3BTmW3UCramI3506e/3MWBECB7ge+gM4URAV0nJJCLH/Im + WgEvPMr5AgMBAAECggEBAKv+wraoMWqiVv1tA/froAgbtcJLDranJK8qrXuvmPz0 + yzm+91qvrSgIVFEADUk67swo/R2Vng37nhWWS2Y3jy/rSr2H+2Lp3Z5ATA0/3I3A + onfU/FaC4mvL9CP32KzMdj/CYkccDzSsSCQ+x75MQNXGcTGDDCSDo2kZnpEu73j3 + aqvO1jbqTGWigRfjOIaIhStjQIT8nEm/3mJ4f5dM9M6FMz33mhax8EahSgvdahYB + t45iaGOWw81OJhmry47EvpwjXBl7jtO2HX3LiLbq5Ebcwu1zqDz5NM7ttnnGAqWC + 6y7JN5Vt4wPYrCydiUDe7dj0looffr2yw6MkNfYjLGECgYEA+FAvbEInQEi9YguS + CQtLHngqvYeai66tvyykog9o38KHnPGx2Myf+rn/Hcp7KNRfjd5G34CCNg7KLnrx + YIYh6+2bY3jirzdYUxuNKGbvM4gky/6M/P9zHF/uALKOE02yArdqemf4UxUvrYCc + JdXsAMqvbpdvW1aGgNRB32YCkG0CgYEA8d89vawsCjNCEUh0VWTMoBLFoex3qBMZ + rfzYQeBo6bDCRlAlUVzl+ouBUxSYxP/U8rzeNaRzGUwRLmlGMjyIr58FBlHsg2cR + DlsX3HVCUjpS6sgPXOqakdiLfhMcHZAspislSyVfeS3TbUWiA45+5PuNUq+EZYwl + ESsB1+yfRT0CgYEA0Ct49ksnWM8iZbXJgeeD3FFlk2rBd2TDqEem5W4Bv8T3p+0/ + 6b7yR2HyrGj5gys3yFmWFP1JLESN3xWWkhMhEQcrg+LuN3Iwi8vHNR3GXu892f7W + 96q4OAt8Hf2S+j/igkB99YyANDbIt63gOh/zMF67X/14j5wkOpC3gK+maqkCgYEA + s7nIrPoUt3ejLiiCmTmPe5q3VDzcJP4cZNau8zSHgK6hjZHcSPsYwPWMoWl6o1fe + qoiBLacHB9MoKS58xLOKdcVZ/Ho/ntylJd+2eVCAeY1xM5h5IfgJ5znbXVFh4O3S + 357L1Wzt5qOQqW/GlZH65LevKbPWU4axvHISqpnfN5kCgYEAqiqLuAPu84VSsqsE + GFh25t+1f0JY1sNfilE3/t9AdQeeCFv/5z9KB1kMt3a5ZFeVonsFIvCyaOJjhSkj + 4HCB94vWS7NuN5G9r874lMaPbZYQGwrcVaf265tN7cYYr3gUx1qB6+u+fh/kcft1 + BBmTzhb0zp5k8ngwAkA1g/LK204= + -----END PRIVATE KEY-----""") + .setPublicKeyId("PUB_KEY_ID_0116437794082025111000382377001000") + .setDomain("https://api.mch.weixin.qq.com"); + + String string = uploadImage(dto, "https://czg-qr-order.oss-cn-beijing.aliyuncs.com/indexs/shuangbackground.png"); + log.info("图片上传成功:{}", string); + } +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatPayManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatPayManager.java new file mode 100644 index 000000000..897ad8fc3 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatPayManager.java @@ -0,0 +1,11 @@ +package com.czg.wechat; + +/** + * @author yjjie + * @date 2025/12/26 09:15 + */ +public class WechatPayManager { + + public static void main(String[] args) { + } +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/config/WechatPayConfigDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/config/WechatPayConfigDto.java new file mode 100644 index 000000000..a0cb78bc4 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/config/WechatPayConfigDto.java @@ -0,0 +1,49 @@ +package com.czg.wechat.dto.config; + +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * @author yjjie + * @date 2025/12/26 09:21 + */ +@Data +@Accessors(chain = true) +public class WechatPayConfigDto { + + /** + * 商户号 + */ + private String merchantId; + + /** + * Api V3密钥 + */ + private String apiV3Key; + + /** + * 商户证书序列号 + */ + private String serialNumber; + + /** + * 商户私钥 + */ + private String privateKey; + + /** + * 商户公钥 + */ + private String publicKey; + + /** + * 商户公钥 ID + */ + private String publicKeyId; + + /** + * 微信支付域名 + * + */ + private String domain; +} diff --git a/cash-sdk/pom.xml b/cash-sdk/pom.xml index 55ee0e62b..b92f22d79 100644 --- a/cash-sdk/pom.xml +++ b/cash-sdk/pom.xml @@ -13,6 +13,7 @@ 第三方内容 czg-pay + aggregation-pay cash-sdk From 6b5c451f92f28c6c8e0273d343a6478a9448c0eb Mon Sep 17 00:00:00 2001 From: gong <1157756119@qq.com> Date: Fri, 26 Dec 2025 15:08:21 +0800 Subject: [PATCH 02/19] =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E6=94=AF=E4=BB=98-=20d?= =?UTF-8?q?to?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../req/entry/WechatEntryAdditionReqDto.java | 49 ++++++++++ .../entry/WechatEntryBankAccountReqDto.java | 73 +++++++++++++++ .../req/entry/WechatEntryContactReqDto.java | 13 +++ .../dto/req/entry/WechatEntryReqDto.java | 64 +++++++++++++ .../req/entry/WechatEntrySettleReqDto.java | 89 +++++++++++++++++++ .../req/entry/WechatEntrySubjectReqDto.java | 55 ++++++++++++ .../business/WechatEntryBusinessReqDto.java | 48 ++++++++++ .../WechatEntryCertificateReqDto.java | 12 +++ .../business/WechatEntryLicenseReqDto.java | 88 ++++++++++++++++++ .../sales/WechatEntryAppInfoReqDto.java | 43 +++++++++ .../sales/WechatEntryMiniProgramReqDto.java | 45 ++++++++++ .../sales/WechatEntryMpInfoReqDto.java | 43 +++++++++ .../sales/WechatEntrySalesInfoReqDto.java | 85 ++++++++++++++++++ .../sales/WechatEntryStoreInfoReqDto.java | 76 ++++++++++++++++ .../sales/WechatEntryWebInfoReqDto.java | 42 +++++++++ .../sales/WechatEntryWeworkInfoReqDto.java | 31 +++++++ 16 files changed, 856 insertions(+) create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryAdditionReqDto.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryBankAccountReqDto.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryContactReqDto.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryReqDto.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntrySettleReqDto.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntrySubjectReqDto.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryBusinessReqDto.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryCertificateReqDto.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryLicenseReqDto.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryAppInfoReqDto.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryMiniProgramReqDto.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryMpInfoReqDto.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntrySalesInfoReqDto.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryStoreInfoReqDto.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryWebInfoReqDto.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryWeworkInfoReqDto.java diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryAdditionReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryAdditionReqDto.java new file mode 100644 index 000000000..a656d8303 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryAdditionReqDto.java @@ -0,0 +1,49 @@ +package com.czg.wechat.dto.req.entry; + +import com.alibaba.fastjson2.annotation.JSONField; +import lombok.Data; + +import java.util.List; + +/** + * 微信进件-补充信息 + * + * @author yjjie + * @date 2025/12/26 13:43 + */ +@Data +public class WechatEntryAdditionReqDto { + + /** + * 选填 + * 法定代表人开户承诺函 + * 模板下载地址 ... + * 通过图片上传完成后 MediaID + */ + @JSONField(name = "legal_person_commitment") + private String legalPersonCommitment; + + /** + * 选填 + * 法定代表人开户意愿视频 + * 通过视频上传完成后 MediaID + */ + @JSONField(name = "legal_person_video") + private String legalPersonVideo; + + /** + * 选填 + * 补充材料 + * 最多可上传5张照片 + * 通过图片上传完成后 MediaID + */ + @JSONField(name = "business_addition_pics") + private List businessAdditionPics; + + /** + * 选填 + * 补充说明 512字以内 + */ + @JSONField(name = "business_addition_msg") + private String businessAdditionMsg; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryBankAccountReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryBankAccountReqDto.java new file mode 100644 index 000000000..35d0cacdf --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryBankAccountReqDto.java @@ -0,0 +1,73 @@ +package com.czg.wechat.dto.req.entry; + +import com.alibaba.fastjson2.annotation.JSONField; +import lombok.Data; + +/** + * 微信进件-银行账号 + * + * @author yjjie + * @date 2025/12/26 13:42 + */ +@Data +public class WechatEntryBankAccountReqDto { + + /** + * 必填 + * 账户类型 + * 1、若主体为企业/政府机关/事业单位/社会组织,可填写:对公银行账户; + * 2、若主体为个体户,可选择填写:对公银行账户或经营者个人银行卡 + * 可选取值 BANK_ACCOUNT_TYPE_CORPORATE: 对公银行账户 BANK_ACCOUNT_TYPE_PERSONAL: 经营者个人银行卡 + */ + @JSONField(name = "bank_account_type") + private String bankAccountType; + + /** + * 必填 + * 开户名称 + * 1、选择“经营者个人银行卡”时,开户名称必须与“经营者证件姓名”一致; + * 2、选择“对公银行账户”时,开户名称必须与营业执照上的“商户名称”一致; + * 3、该字段需要使用微信支付公钥加密(推荐),请参考获取微信支付公钥ID说明以及微信支付公钥加密敏感信息指引,也可以使用微信支付平台证书公钥加密,参考获取平台证书序列号、平台证书加密敏感信息指引。 + * ... + */ + @JSONField(name = "account_name") + private String accountName; + + /** + * 必填 + * 开户银行 + * 对私银行调用:查询支持个人业务的银行列表API + * 对公银行调用:查询支持对公业务的银行列表API + */ + @JSONField(name = "account_bank") + private String accountBank; + + /** + * 选填 + * 开户银行银行号 + * 1、根据开户银行查询接口中的“是否需要填写支行”判断是否需要填写。如为其他银行,开户银行全称(含支行)和开户银行联行号二选一; + * 2、详细需调用查询支行列表API查看查询结果。 ... + */ + @JSONField(name = "bank_branch_id") + private String bankBranchId; + + /** + * 选填 + * 开户银行全称(含支行) + * 1、根据开户银行查询接口中的“是否需要填写支行”判断是否需要填写。如为其他银行,开户银行全称(含支行)和开户银行联行号二选一; + * 2、详细需调用查询支行列表API查看查询结果。 ... + */ + @JSONField(name = "bank_name") + private String bankName; + + /** + * 必填 + * 开户银行账号 + * 1、选择“经营者个人银行卡”时,开户账号为经营者个人银行卡号; + * 2、选择“对公银行账户”时,开户账号为对公银行账号; + * 3、该字段需要使用微信支付公钥加密(推荐),请参考获取微信支付公钥ID说明以及微信支付公钥加密敏感信息指引,也可以使用微信支付平台证书公钥加密,参考获取平台证书序列号、平台证书加密敏感信息指引。 + * ... + */ + @JSONField(name = "account_number") + private String accountNumber; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryContactReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryContactReqDto.java new file mode 100644 index 000000000..a7990dbd0 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryContactReqDto.java @@ -0,0 +1,13 @@ +package com.czg.wechat.dto.req.entry; + +import lombok.Data; + +/** + * 进件 联系人信息 + * + * @author yjjie + * @date 2025/12/26 13:38 + */ +@Data +public class WechatEntryContactReqDto { +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryReqDto.java new file mode 100644 index 000000000..c0793e703 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryReqDto.java @@ -0,0 +1,64 @@ +package com.czg.wechat.dto.req.entry; + +import com.alibaba.fastjson2.annotation.JSONField; +import com.czg.wechat.dto.req.entry.business.WechatEntryBusinessReqDto; +import lombok.Data; + +/** + * 微信进件请求参数 + * 参考地址 ... + * @author yjjie + * @date 2025/12/26 13:36 + */ +@Data +public class WechatEntryReqDto { + + /** + * 业务申请编号 + */ + @JSONField(name = "business_code") + private String businessCode; + + /** + * 超级管理员信息 + */ + @JSONField(name = "contact_info") + private WechatEntryContactReqDto contactInfo; + + /** + * 主体资料 + */ + @JSONField(name = "subject_info") + private WechatEntrySubjectReqDto subjectInfo; + + /** + * 必填 + * 经营资料 + * 商家的经营业务信息、售卖商品/提供服务场景信息 + */ + @JSONField(name = "business_info") + private WechatEntryBusinessReqDto businessInfo; + + /** + * 必填 + * 结算规则 + * 请填写商家的结算费率规则、特殊资质等信息 + */ + @JSONField(name = "settlement_info") + private WechatEntrySettleReqDto settlementInfo; + + /** + * 必填 + * 结算银行账户 + */ + @JSONField(name = "bank_account_info") + private WechatEntryBankAccountReqDto bankAccountInfo; + + /** + * 选填 + * 补充材料 + * 根据实际审核情况,会额外要求商家提供指定的补充资料 + */ + @JSONField(name = "addition_info") + private WechatEntryAdditionReqDto additionInfo; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntrySettleReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntrySettleReqDto.java new file mode 100644 index 000000000..55f434741 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntrySettleReqDto.java @@ -0,0 +1,89 @@ +package com.czg.wechat.dto.req.entry; + +import com.alibaba.fastjson2.annotation.JSONField; +import lombok.Data; + +import java.util.List; + +/** + * 进件 结算信息 + * @author yjjie + * @date 2025/12/26 13:38 + */ +@Data +public class WechatEntrySettleReqDto { + + /** + * 必填 + * 入驻结算规则ID + * 请选择结算规则ID,详细参见费率结算规则对照表 + * ... + */ + @JSONField(name = "settlement_id") + private String settlementId; + + /** + * 必填 + * 所属行业 + * ... + */ + @JSONField(name = "qualification_type") + private String qualificationType; + + /** + * 选填 + * 特殊资质图片 + * 1、仅当商户选择了必需提交特殊资质的行业时,需要提供该项资料;若商户选择了无需特殊资质的行业,或未选择行业时,无需提交该项资料,详情查看《费率结算规则对照表》; + * 2、最多可上传5张照片,请填写通过图片上传API预先上传图片生成好的MediaID。 + */ + @JSONField(name = "qualifications") + private List qualifications; + + /** + * 选填 + * 优惠费率活动ID + * 如果商户有意向报名优惠费率活动,该字段必填。详细参见《优惠费率活动对照表》 + * ... + */ + @JSONField(name = "activities_id") + private String activitiesId; + + /** + * 选填 + * 优惠费率活动值 + * 根据优惠费率活动规则,由合作伙伴自定义填写,支持两个小数点,需在优惠费率活动ID指定费率范围内 + * (1)2023年7月17日-9月17日,各合作伙伴平台可选择只传入“活动费率值”,或分别传入“信用卡优惠活动费率值” 与 “非信用卡优惠活动费率值”,只传入“活动费率值”的情况下,平台将协助将申请单中的 “优惠活动费率值” 回填入新增的 “信用卡优惠活动费率值” 与 “非信用卡优惠活动费率值”中 ; + * (2)2023年9月18日起,平台将不再提供如上兼容能力,届时仅能分别传入“信用卡优惠活动费率值” 与 “非信用卡优惠活动费率值”,否则接口将会报错。为避免影响正常进件,请在兼容期间完成相关调整。 + */ + @JSONField(name = "activities_rate") + private String activitiesRate; + + /** + * 选填 + * 优惠费率活动补充材料 + * 1、根据所选优惠费率活动,提供相关材料,详细参见《优惠费率活动对照表》;... + * 2、最多可上传5张照片,请填写通过图片上传API预先上传图片生成好的MediaID。 + */ + @JSONField(name = "activities_additions") + private List activitiesAdditions; + + /** + * 选填 + * 非信用卡活动费率值 + * 用户支付方式为借记卡时收取的手续费费率: + * 1、若填写了优惠费率活动ID,则该字段必填; + * 2、仅能填入2位以内小数,且在优惠费率活动ID指定费率范围内。 + */ + @JSONField(name = "debit_activities_rate") + private String debitActivitiesRate; + + /** + * 选填 + * 信用卡活动费率值 + * 用户支付方式为信用卡时收取的手续费费率: + * 1、若填写了优惠费率活动ID,则该字段必填; + * 2、仅能填入2位以内小数,且在优惠费率活动ID指定费率范围内。 + */ + @JSONField(name = "credit_activities_rate") + private String creditActivitiesRate; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntrySubjectReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntrySubjectReqDto.java new file mode 100644 index 000000000..a445b6a5f --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntrySubjectReqDto.java @@ -0,0 +1,55 @@ +package com.czg.wechat.dto.req.entry; + +import com.alibaba.fastjson2.annotation.JSONField; +import com.czg.wechat.dto.req.entry.business.WechatEntryCertificateReqDto; +import com.czg.wechat.dto.req.entry.business.WechatEntryLicenseReqDto; +import lombok.Data; + +/** + * 进件 主体资料 + * @author yjjie + * @date 2025/12/26 13:40 + */ +@Data +public class WechatEntrySubjectReqDto { + + /** + * 必填 + * 主体类型 主体类型需与营业执照/登记证书上一致,可参考选择主体指引。... + * 可选取值 + * SUBJECT_TYPE_INDIVIDUAL: (个体户)营业执照上的主体类型一般为个体户、个体工商户、个体经营 + * SUBJECT_TYPE_ENTERPRISE: (企业)营业执照上的主体类型一般为有限公司、有限责任公司 + * SUBJECT_TYPE_GOVERNMENT: (政府机关)包括各级、各类政府机关,如机关党委、税务、民政、人社、工商、商务、市监等 + * SUBJECT_TYPE_INSTITUTIONS: (事业单位)包括国内各类事业单位,如:医疗、教育、学校等单位 + * SUBJECT_TYPE_OTHERS:(社会组织) 包括社会团体、民办非企业、基金会、基层群众性自治组织、农村集体经济组织等组织 + */ + @JSONField(name = "subject_type") + private String subjectType; + + /** + * 选填 + * 是否是金融机构 + * 【是否是金融机构】 选填,请根据申请主体的实际情况填写,可参考选择金融机构指引: + * 1、若商户主体是金融机构,则填写:true; + * 2、若商户主体不是金融机构,则填写:false。 + * 若未传入将默认填写:false。 + */ + @JSONField(name = "finance_institution") + private Boolean financeInstitution; + + /** + * 必填 + * 营业执照 当前不允许小微注册,所以必填 + * 1、主体为个体户/企业,必填; + * 2、请上传“营业执照”,需年检章齐全,当年注册除外; + */ + @JSONField(name = "business_license_info") + private WechatEntryLicenseReqDto businessLicenseInfo; + + /** + * 选填 + * 登记证书 主体为政府机关/事业单位/其他组织时,必填。 + */ + @JSONField(name = "certificate_info") + private WechatEntryCertificateReqDto certificateInfo; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryBusinessReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryBusinessReqDto.java new file mode 100644 index 000000000..94dcd1d39 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryBusinessReqDto.java @@ -0,0 +1,48 @@ +package com.czg.wechat.dto.req.entry.business; + +import com.alibaba.fastjson2.annotation.JSONField; +import com.czg.wechat.dto.req.entry.business.sales.WechatEntrySalesInfoReqDto; +import lombok.Data; + +/** + * 微信进件 商户信息 经营资料 + * + * @author yjjie + * @date 2025/12/26 13:41 + */ +@Data +public class WechatEntryBusinessReqDto { + + /** + * 必填 + * 商户简称 在支付完成页向买家展示,需与微信经营类目相关 + * 1、请输入1-64个字符; + * 2、前后不能有空格、制表符、换行符; + * 3、不能仅含特殊字符; + * 4、仅能填写数字、英文字母、汉字及特殊字符; + * 5、仅支持utf-8格式; + * 6、简称要求 + * (1)不支持单纯以人名来命名,若为个体户经营,可用“个体户+经营者名称”或“经营者名称+业务”命名,如“个体户张三”或“张三餐饮店”; + * (2)不支持无实际意义的文案,如“XX特约商户”、“800”、“XX客服电话XXX”。 + */ + @JSONField(name = "merchant_shortname") + private String merchantShortname; + + /** + * 必填 + * 客服电话 将在交易记录中向买家展示,请确保电话畅通以便平台回拨确认 + * 1、前后不能有空格、制表符、换行符; + * 2、需满足以下任一条件; + * 11位数字的手机号码; + * 5-20位数字、连字符“-”、加号“+”。 + */ + @JSONField(name = "service_phone") + private String servicePhone; + + /** + * 必填 + * 经营场景 + */ + @JSONField(name = "sales_info") + private WechatEntrySalesInfoReqDto salesInfo; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryCertificateReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryCertificateReqDto.java new file mode 100644 index 000000000..df2090102 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryCertificateReqDto.java @@ -0,0 +1,12 @@ +package com.czg.wechat.dto.req.entry.business; + +import lombok.Data; + +/** + * 登记证书 + * @author yjjie + * @date 2025/12/26 15:07 + */ +@Data +public class WechatEntryCertificateReqDto { +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryLicenseReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryLicenseReqDto.java new file mode 100644 index 000000000..c13401254 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryLicenseReqDto.java @@ -0,0 +1,88 @@ +package com.czg.wechat.dto.req.entry.business; + +import com.alibaba.fastjson2.annotation.JSONField; +import lombok.Data; + +/** + * 营业执照信息 + * @author yjjie + * @date 2025/12/26 14:59 + */ +@Data +public class WechatEntryLicenseReqDto { + + /** + * 必填 + * 营业执照照片 + * 1、照片应正面拍摄、清晰、四角完整、无反光或遮挡;不得翻拍、截图、镜像、PS; + * 2、上传彩色照片、彩色扫描件,复印件需加盖公章鲜章; + * 3、水印仅限于微信支付业务相关; + * 4、指引与示例可参考【指引文档】; + * 5、可上传1张图片,请填写通过图片上传API预先上传图片生成好的MediaID。 + */ + @JSONField(name = "license_copy") + private String licenseCopy; + + /** + * 必填 + * 注册号/统一社会信用代码 + */ + @JSONField(name = "license_number") + private String licenseNumber; + + /** + * 必填 + * 商户名称 + * 1、长度为2-128个字符; + * 2、前后不能有空格、制表符、换行符; + * 3、不能仅含数字、特殊字符; + * 4、仅能填写数字、英文字母、汉字及特殊字符; + * 5、仅支持utf-8格式; + * 6、个体户证件为以下情况时,按照个体户XXX命名(XXX是营业执照经营人姓名):营业执照登记名称为空、仅含数字、仅含特殊字符、“无”、“无字号”; + * 7、个体户不能使用“企业”“公司”或“农民专业合作社”结尾。 + */ + @JSONField(name = "merchant_name") + private String merchantName; + + /** + * 必填 + * 个体户经营者/法定代表人姓名 请填写营业执照的经营者/法定代表人姓名 + * 1、长度为2-100个字符; + * 2、前后不能有空格、制表符、换行符; + * 3、不能仅含特殊字符; + * 4、仅能填写数字、英文字母、汉字及特殊字符。 + */ + @JSONField(name = "legal_person") + private String legalPerson; + + /** + * 选填 + * 注册地址 建议填写营业执照的注册地址,若该字段未填写,系统将会查询国家工商信息填入。需注意若工商信息查询不到,则会被审核驳回。 + * 1、长度为4-128个字符; + * 2、前后不能有空格、制表符、换行符; + * 3、不能仅含数字、特殊字符; + * 4、仅能填写数字、英文字母、汉字及特殊字符; + * 5、仅支持utf-8格式。 + */ + @JSONField(name = "license_address") + private String licenseAddress; + + /** + * 选填 + * 有效期限开始日期 建议填写营业执照的有效期限开始时间,若该字段未填写,系统将会查询国家工商信息填入。需注意若工商信息查询不到,则会被审核驳回。 + * 1、日期格式应满足合法的YYYY-MM-DD格式; + * 2、开始时间不能小于1900-01-01; + * 3、开始时间不能大于等于当前日期。 + */ + @JSONField(name = "period_begin") + private String periodBegin; + + /** + * 选填 + * 营业期限结束日期 建议填写营业执照的有效期限结束时间,若该字段未填写,系统将会查询国家工商信息填入。需注意若工商信息查询不到,则会被审核驳回。 + * 1、日期格式应满足合法的YYYY-MM-DD格式或长期; + * 2、结束时间需大于开始时间。 + */ + @JSONField(name = "period_end") + private String periodEnd; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryAppInfoReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryAppInfoReqDto.java new file mode 100644 index 000000000..c14b829be --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryAppInfoReqDto.java @@ -0,0 +1,43 @@ +package com.czg.wechat.dto.req.entry.business.sales; + +import com.alibaba.fastjson2.annotation.JSONField; +import lombok.Data; + +import java.util.List; + +/** + * 进件-经营资料-经营场景-App场景 + * @author yjjie + * @date 2025/12/26 14:26 + */ +@Data +public class WechatEntryAppInfoReqDto { + + /** + * 必填 + * App截图 + * 1、请提供APP首页截图、尾页截图、应用内截图、支付页截图各1张; + * 2、请填写通过图片上传API预先上传图片生成好的MediaID。 + */ + @JSONField(name = "app_pics") + private List appPics; + + /** + * 选填 + * 商家应用AppID + * 1、服务商应用AppID与商家应用AppID,二选一必填; + * 2、可填写与商家主体一致且已认证的应用AppID,需是已认证的App; + * 3、审核通过后,系统将发起特约商家商户号与该AppID的绑定(即配置为sub_appid),服务商随后可在发起支付时选择传入该AppID,以完成支付,并获取sub_openid用于数据统计,营销等业务场景。 + */ + @JSONField(name = "app_sub_appid") + private String appSubAppid; + + /** + * 选填 + * 服务商应用AppID + * 1、服务商应用AppID与商家应用AppID,二选一必填; + * 2、可填写当前服务商商户号已绑定的应用AppID。 + */ + @JSONField(name = "app_appid") + private String appAppid; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryMiniProgramReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryMiniProgramReqDto.java new file mode 100644 index 000000000..124199c42 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryMiniProgramReqDto.java @@ -0,0 +1,45 @@ +package com.czg.wechat.dto.req.entry.business.sales; + +import com.alibaba.fastjson2.annotation.JSONField; +import lombok.Data; + +import java.util.List; + +/** + * 进件-经营资料-经营场景-小程序场景 + * @author yjjie + * @date 2025/12/26 14:23 + */ +@Data +public class WechatEntryMiniProgramReqDto { + + /** + * 选填 + * 服务商小程序AppID + * 1、服务商小程序AppID与商家小程序AppID,二选一必填; + * 2、可填写当前服务商商户号已绑定的小程序AppID。 + */ + @JSONField(name = "mini_program_appid") + private String miniProgramAppid; + + /** + * 选填 + * 商家小程序AppID + * 1、服务商小程序AppID与商家小程序AppID,二选一必填; + * 2、请填写已认证的小程序AppID; + * 3、完成进件后,系统发起特约商户号与该AppID的绑定(即配置为sub_appid可在发起支付时传入) + * (1)若AppID主体与商家主体/服务商主体一致,则直接完成绑定; + * (2)若AppID主体与商家主体/服务商主体不一致,则商户签约时显示《联合营运承诺函》,并且AppID的管理员需登录公众平台确认绑定意愿。 + */ + @JSONField(name = "mini_program_sub_appid") + private String miniProgramSubAppid; + + /** + * 选填 + * 小程序截图 + * 1、请提供展示商品/服务的页面截图/设计稿(最多5张),若小程序未建设完善或未上线 请务必提供; + * 2、请填写通过图片上传API预先上传图片生成好的MediaID。 + */ + @JSONField(name = "mini_program_pics") + private List miniProgramPics; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryMpInfoReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryMpInfoReqDto.java new file mode 100644 index 000000000..aa419e063 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryMpInfoReqDto.java @@ -0,0 +1,43 @@ +package com.czg.wechat.dto.req.entry.business.sales; + +import com.alibaba.fastjson2.annotation.JSONField; +import lombok.Data; + +import java.util.List; + +/** + * 进件-经营资料-经营场景-服务号或公众号景 + * @author yjjie + * @date 2025/12/26 14:20 + */ +@Data +public class WechatEntryMpInfoReqDto { + + /** + * 必填 + * 服务号或公众号页面截图 + * 1、请提供展示商品/服务的页面截图/设计稿(最多5张),若服务号或公众号未建设完善或未上线请务必提供; + * 2、请填写通过图片上传API预先上传图片生成好的MediaID。 + */ + @JSONField(name = "mp_pics") + private List mpPics; + + /** + * 选填 + * 商家服务号或公众号AppID + * 1、服务商服务号或公众号AppID、商家服务号或公众号AppID,二选一必填; + * 2、可填写与商家主体一致且已认证的服务号或公众号AppID,需是已认证的服务号、政府或媒体类型的公众号; + * 3、审核通过后,系统将发起特约商家商户号与该AppID的绑定(即配置为sub_appid),服务商随后可在发起支付时选择传入该appid,以完成支付,并获取sub_openid用于数据统计,营销等业务场景。 + */ + @JSONField(name = "mp_sub_appid") + private String mpSubAppid; + + /** + * 选填 + * 服务商服务号或公众号AppID + * 1、服务商服务号或公众号AppID、商家服务号或公众号AppID,二选一必填; + * 2、可填写当前服务商商户号已绑定的服务号或公众号AppID。 + */ + @JSONField(name = "mp_appid") + private String mpAppid; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntrySalesInfoReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntrySalesInfoReqDto.java new file mode 100644 index 000000000..00143fd84 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntrySalesInfoReqDto.java @@ -0,0 +1,85 @@ +package com.czg.wechat.dto.req.entry.business.sales; + +import com.alibaba.fastjson2.annotation.JSONField; +import lombok.Data; + +import java.util.List; + +/** + * 进件-经营场景 + * @author yjjie + * @date 2025/12/26 14:07 + */ +@Data +public class WechatEntrySalesInfoReqDto { + + /** + * 必填 + * 经营场景类型 + * 1、请勾选实际售卖商品/提供服务场景(至少一项),以便为你开通需要的支付权限; + * 2、建议只勾选目前必须的场景,以便尽快通过入驻审核,其他支付权限可在入驻后再根据实际需要发起申请 + * 可选取值 + * SALES_SCENES_STORE: 线下场所 + * SALES_SCENES_MP: 服务号与公众号 + * SALES_SCENES_MINI_PROGRAM: 小程序 + * SALES_SCENES_WEB: 互联网网站 + * SALES_SCENES_APP: App + * SALES_SCENES_WEWORK: 企业微信 + */ + @JSONField(name = "sales_scenes_type") + private List salesScenesType; + + /** + * 选填 + * 线下场所场景 + * 1、审核通过后,服务商可帮商户发起付款码支付、JSAPI支付; + * 2、当"经营场景类型"选择"SALES_SCENES_STORE",该场景资料必填。 + */ + @JSONField(name = "biz_store_info") + private WechatEntryStoreInfoReqDto bizStoreInfo; + + /** + * 选填 + * 服务号或公众号场景 + * 1、审核通过后,服务商可帮商家发起JSAPI支付; + * 2、当"经营场景类型"选择"SALES_SCENES_MP",该场景资料必填。 + */ + @JSONField(name = "mp_info") + private WechatEntryMpInfoReqDto mpInfo; + + /** + * 选填 + * 小程序场景 + * 1、审核通过后,服务商可帮商家发起JSAPI支付; + * 2、当"经营场景类型"选择"SALES_SCENES_MINI_PROGRAM",该场景资料必填。 + */ + @JSONField(name = "mini_program_info") + private WechatEntryMiniProgramReqDto miniProgramInfo; + + /** + * 选填 + * App场景 + * 1、审核通过后,服务商可帮商家发起App支付; + * 2、当"经营场景类型"选择"SALES_SCENES_APP",该场景资料必填。 + */ + @JSONField(name = "app_info") + private WechatEntryAppInfoReqDto appInfo; + + /** + * 选填 + * 互联网网站场景 + * 1、审核通过后,服务商可帮商家发起JSAPI支付; + * 2、当"经营场景类型"选择"SALES_SCENES_WEB",该场景资料必填。 + */ + @JSONField(name = "web_info") + private WechatEntryWebInfoReqDto webInfo; + + /** + * 选填 + * 企业微信场景 + * 1、审核通过后,服务商可帮商家发起JSAPI支付; + * 2、当"经营场景类型"选择"SALES_SCENES_WEWORK",该场景资料必填。 + */ + @JSONField(name = "wework_info") + private WechatEntryWeworkInfoReqDto weworkInfo; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryStoreInfoReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryStoreInfoReqDto.java new file mode 100644 index 000000000..e4c202a52 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryStoreInfoReqDto.java @@ -0,0 +1,76 @@ +package com.czg.wechat.dto.req.entry.business.sales; + +import com.alibaba.fastjson2.annotation.JSONField; +import lombok.Data; + +import java.util.List; + +/** + * 进件-经营资料-经营场景-线下场所场景 + * @author yjjie + * @date 2025/12/26 14:10 + */ +@Data +public class WechatEntryStoreInfoReqDto { + + /** + * 必填 + * 线下场所名称 请填写门店名称 + * 1、长度为1-50个字符; + * 2、前后不能有空格、制表符、换行符; + * 3、不能仅含数字、特殊字符; + * 4、仅能填写数字、英文字母、汉字及特殊字符; + * 5、仅支持utf-8格式。 + */ + @JSONField(name = "biz_store_name") + private String bizStoreName; + + /** + * 必填 + * 线下场所省市编码 + * 1、只能由数字组成; + * 2、详细参见微信支付提供的省市对照表。 ... + */ + @JSONField(name = "biz_address_code") + private String bizAddressCode; + + /** + * 必填 + * 线下场所地址 请填写详细的经营场所信息,如有多个场所,选择一个主要场所填写即可。 + * 1、长度为4-512个字符; + * 2、前后不能有空格、制表符、换行符; + * 3、不能仅含数字、特殊字符; + * 4、仅能填写数字、英文字母、汉字及特殊字符; + * 5、仅支持utf-8格式 + */ + @JSONField(name = "biz_store_address") + private String bizStoreAddress; + + /** + * 必填 + * 线下场所门头照片 + * 1、请上传门头正面照片(要求门店招牌、门框完整、清晰、可辨识);若为停车场等无固定门头照片的经营场所,可上传岗亭/出入闸口。具体参考【指引文档】; + * 2、请填写通过图片上传API预先上传图片生成好的MediaID。 + */ + @JSONField(name = "store_entrance_pic") + private List storeEntrancePic; + + /** + * 必填 + * 线下场所内部照片 + * 1、请上传门店内部环境照片(可辨识经营内容)。若为停车场等无固定门头的经营场所,可上传停车场内部照片。具体参考【指引文档】; + * 2、请填写通过图片上传API预先上传图片生成好的MediaID。 + */ + @JSONField(name = "indoor_pic") + private List indoorPic; + + /** + * 选填 + * 线下场所对应的商家AppID + * 1、可填写与商家主体一致且已认证的服务号或公众号、小程序、APP的AppID,其中服务号或公众号AppID需是已认证的服务号、政府或媒体类型的公众号; + * 2、审核通过后,系统将额外为商家开通付款码支付、JSAPI支付的自有交易权限,并完成商家商户号与该AppID的绑定。 + */ + @JSONField(name = "biz_sub_appid") + private String bizSubAppid; + +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryWebInfoReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryWebInfoReqDto.java new file mode 100644 index 000000000..b213f88de --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryWebInfoReqDto.java @@ -0,0 +1,42 @@ +package com.czg.wechat.dto.req.entry.business.sales; + +import com.alibaba.fastjson2.annotation.JSONField; +import lombok.Data; + +/** + * 进件-经营资料-经营场景-互联网网站场景 + * @author yjjie + * @date 2025/12/26 14:29 + */ +@Data +public class WechatEntryWebInfoReqDto { + + /** + * 必填 + * 互联网网站域名 + * 1、如为PC端商城、智能终端等场景,可上传官网链接; + * 2、网站域名需ICP备案,若备案主体与申请主体不同,请上传加盖公章的网站授权函。 + */ + @JSONField(name = "domain") + private String domain; + + /** + * 必填 + * 网站授权函 + * 1、若备案主体与申请主体不同,请务必上传加盖公章的网站授权函.doc; ... + * 2、请填写通过图片上传API预先上传图片生成好的MediaID。 + */ + @JSONField(name = "web_authorisation") + private String webAuthorisation; + + /** + * 选填 + * 互联网网站对应的商家AppID + * 1、可填写已认证的服务号或公众号、小程序、APP的AppID,其中服务号或公众号AppID需是已认证的服务号、政府或媒体类型的公众号; + * 2、完成进件后,系统发起特约商户号与该AppID的绑定(即配置为sub_appid,可在发起支付时传入) + * (1)若APPID主体与商家主体一致,则直接完成绑定; + * (2)若APPID主体与商家主体不一致,则商户签约时显示《联合营运承诺函》,并且 AppID的管理员需登录公众平台确认绑定意愿;( 暂不支持绑定异主体的应用APPID)。 + */ + @JSONField(name = "web_appid") + private String webAppid; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryWeworkInfoReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryWeworkInfoReqDto.java new file mode 100644 index 000000000..544e08d2e --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryWeworkInfoReqDto.java @@ -0,0 +1,31 @@ +package com.czg.wechat.dto.req.entry.business.sales; + +import com.alibaba.fastjson2.annotation.JSONField; +import lombok.Data; + +/** + * 进件-经营资料-经营场景-企业微信场景 + * @author yjjie + * @date 2025/12/26 14:32 + */ +@Data +public class WechatEntryWeworkInfoReqDto { + + /** + * 必填 + * 商家企业微信CorpID + * 1、可填写与商家主体一致且已认证的企业微信CorpID; + * 2、审核通过后,系统将为商家开通企业微信专区的自有交易权限,并完成商家商户号与该AppID的绑定,商家可自行发起交易。 + */ + @JSONField(name = "sub_corp_id") + private String subCorpId; + + /** + * 必填 + * 企业微信页面截图 + * 1、最多可上传5张照片; + * 2、请填写通过图片上传API预先上传图片生成好的MediaID。 + */ + @JSONField(name = "wework_pics") + private String[] weworkPics; +} From e179a910ba556af1e4d32894edba3e4e0ba2ef0b Mon Sep 17 00:00:00 2001 From: gong <1157756119@qq.com> Date: Fri, 26 Dec 2025 15:13:11 +0800 Subject: [PATCH 03/19] =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E6=94=AF=E4=BB=98-=20d?= =?UTF-8?q?to1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/req/entry/business/WechatEntryCertificateReqDto.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryCertificateReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryCertificateReqDto.java index df2090102..910f94b58 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryCertificateReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryCertificateReqDto.java @@ -9,4 +9,9 @@ import lombok.Data; */ @Data public class WechatEntryCertificateReqDto { + + /** + * 必填 + * 登记证书照片 + */ } From 0cdad226ea75bc6bf8736014f222138860fdc19d Mon Sep 17 00:00:00 2001 From: gong <1157756119@qq.com> Date: Fri, 26 Dec 2025 16:23:46 +0800 Subject: [PATCH 04/19] =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E6=94=AF=E4=BB=98-=20d?= =?UTF-8?q?to222?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../req/entry/WechatEntryContactReqDto.java | 124 ++++++++++++++++++ .../req/entry/WechatEntrySubjectReqDto.java | 50 ++++++- .../WechatEntryCertificateReqDto.java | 92 +++++++++++++ .../WechatEntryFinanceInstitutionReqDto.java | 40 ++++++ .../business/WechatEntryIdentityReqDto.java | 70 ++++++++++ .../business/WechatEntryUboInfoReqDto.java | 111 ++++++++++++++++ .../req/entry/id/WechatEntryIdCardReqDto.java | 94 +++++++++++++ .../entry/id/WechatEntryIdDocInfoReqDto.java | 98 ++++++++++++++ 8 files changed, 677 insertions(+), 2 deletions(-) create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryFinanceInstitutionReqDto.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryIdentityReqDto.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryUboInfoReqDto.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/id/WechatEntryIdCardReqDto.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/id/WechatEntryIdDocInfoReqDto.java diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryContactReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryContactReqDto.java index a7990dbd0..82c91ed49 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryContactReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryContactReqDto.java @@ -1,5 +1,6 @@ package com.czg.wechat.dto.req.entry; +import com.alibaba.fastjson2.annotation.JSONField; import lombok.Data; /** @@ -10,4 +11,127 @@ import lombok.Data; */ @Data public class WechatEntryContactReqDto { + + /** + * 必填 + * 超级管理员类型 + * 主体为“个体工商户/企业/政府机关/事业单位/社会组织”,可选择:LEGAL:经营者/法定代表人,SUPER:经办人 。(经办人:经商户授权办理微信支付业务的人员)。 + * 可选取值 + * LEGAL: 经营者/法定代表人 + * SUPER: 经办人 + */ + @JSONField(name = "contact_type") + private String contactType; + + /** + * 必填 + * 超级管理员姓名 + * 1、长度为2-100个字符; + * 2、前后不能有空格、制表符、换行符; + * 3、不能仅含数字、特殊字符; + * 4、仅能填写数字、英文字母、汉字及特殊字符。 + * 该字段需要使用微信支付公钥加密(推荐),请参考获取微信支付公钥ID说明以及微信支付公钥加密敏感信息指引,也可以使用微信支付平台证书公钥加密,参考获取平台证书序列号、平台证书加密敏感信息指引。 + */ + @JSONField(name = "contact_name") + private String contactName; + + /** + * 选填 + * 超级管理员证件类型 当超级管理员类型是经办人时,请上传超级管理员证件类型。 + * 可选取值 + * IDENTIFICATION_TYPE_IDCARD: 中国大陆居民-身份证 + * IDENTIFICATION_TYPE_OVERSEA_PASSPORT: 其他国家或地区居民-护照 + * IDENTIFICATION_TYPE_HONGKONG_PASSPORT: 中国香港居民-来往内地通行证 + * IDENTIFICATION_TYPE_MACAO_PASSPORT: 中国澳门居民-来往内地通行证 + * IDENTIFICATION_TYPE_TAIWAN_PASSPORT: 中国台湾居民-来往大陆通行证 + * IDENTIFICATION_TYPE_FOREIGN_RESIDENT: 外国人居留证 + * IDENTIFICATION_TYPE_HONGKONG_MACAO_RESIDENT: 港澳居民居住证 + * IDENTIFICATION_TYPE_TAIWAN_RESIDENT: 台湾居民居住证 + */ + @JSONField(name = "contact_id_type") + private String contactIdType; + + /** + * 选填 + * 超级管理员身份证件号码 + * 1、当超级管理员类型是经办人时,请上传超级管理员证件号码; + * 2、可传身份证、来往内地通行证、来往大陆通行证、护照等证件号码,号码规范如下: + * 身份证(限中国大陆居民):17位数字+1位数字|X; + * 护照(限境外人士):4-15位 数字|字母|连字符; + * 中国香港居民--来往内地通行证:H/h开头+8或10位数字/字母; + * 中国澳门居民--来往内地通行证:M/m开头+8或10位数字/字母; + * 中国台湾居民--来往大陆通行证:8位数字或10位数字; + * 外国人居留证:15位 数字|字母; + * 台湾居民居住证/港澳居民居住证:17位数字+1位数字|X; + * 3、超级管理员签约时,校验微信号绑定的银行卡实名信息,是否与该证件号码一致; + * 4、该字段需要使用微信支付公钥加密(推荐),请参考获取微信支付公钥ID说明以及微信支付公钥加密敏感信息指引,也可以使用微信支付平台证书公钥加密,参考获取平台证书序列号、平台证书加密敏感信息指引。 + */ + @JSONField(name = "contact_id_number") + private String contactIdNumber; + + /** + * 选填 + * 超级管理员证件正面照片 + * 1、当超级管理员类型是经办人时,请上传超级管理员证件的正面照片; + * 2、若证件类型为身份证,请上传人像面照片; + * 3、正面拍摄、清晰、四角完整、无反光或遮挡;不得翻拍、截图、镜像、PS; + * 4、请上传彩色照片或彩色扫描件或复印件(需加盖公章鲜章),可添加“微信支付”相关水印(如微信支付认证),见【指引文档】; + * 5、可上传1张图片,请填写通过图片上传API预先上传图片生成好的MediaID。 + */ + @JSONField(name = "contact_id_doc_copy") + private String contactIdDocCopy; + + /** + * 选填 + * 超级管理员证件反面照片 + * 1、当超级管理员类型是经办人时,请上传超级管理员证件的反面照片; + * 2、若证件类型为护照,无需上传反面照片; + * 3、正面拍摄、清晰、四角完整、无反光或遮挡;不得翻拍、截图、镜像、PS; + * 4、请上传彩色照片或彩色扫描件,复印件需加盖公章鲜章,可添加“微信支付”相关水印(如微信支付认证),见【指引文档】; + * 5、可上传1张图片,请填写通过图片上传API预先上传图片生成好的MediaID。 + */ + @JSONField(name = "contact_id_doc_copy_back") + private String contactIdDocCopyBack; + + /** + * 选填 + * 超级管理员证件有效期开始时间 + * 1、当超级管理员类型是经办人时,请上传证件有效期开始时间; + * 2、请按照示例值填写,日期格式应满足合法的YYYY-MM-DD格式; + * 3、开始时间不能小于1900-01-01,开始时间不能大于等于当前日期。 + */ + @JSONField(name = "contact_period_begin") + private String contactPeriodBegin; + + /** + * 选填 + * 超级管理员证件有效期截止时间 + * 1、当超级管理员类型是经办人时,请上传证件有效期结束时间; + * 2、请按照示例值填写,日期格式应满足合法的YYYY-MM-DD格式,若证件有效期为长期,请填写:长期; + * 3、结束时间大于开始时间。 + */ + @JSONField(name = "contact_period_end") + private String contactPeriodEnd; + + /** + * 必填 + * 联系手机 + * 1、前后不能有空格、制表符、换行符; + * 2、需满足以下任一条件: + * 11位数字的手机号码; + * 5-20位数字、连字符“-”、加号“+”; + * 3、用于接收微信支付的重要管理信息及日常操作验证码; + * 4、该字段需要使用微信支付公钥加密(推荐),请参考获取微信支付公钥ID说明以及微信支付公钥加密敏感信息指引,也可以使用微信支付平台证书公钥加密,参考获取平台证书序列号、平台证书加密敏感信息指引。 + */ + @JSONField(name = "mobile_phone") + private String mobilePhone; + + /** + * 必填 + * 联系邮箱 + * 1、用于接收微信支付的开户邮件及日常业务通知; + * 2、需要带@,遵循邮箱格式校验 ,该字段需要使用微信支付公钥加密(推荐),请参考获取微信支付公钥ID说明以及微信支付公钥加密敏感信息指引,也可以使用微信支付平台证书公钥加密,参考获取平台证书序列号、平台证书加密敏感信息指引。 + */ + @JSONField(name = "contact_email") + private String contactEmail; } diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntrySubjectReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntrySubjectReqDto.java index a445b6a5f..d8cabd000 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntrySubjectReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntrySubjectReqDto.java @@ -1,10 +1,11 @@ package com.czg.wechat.dto.req.entry; import com.alibaba.fastjson2.annotation.JSONField; -import com.czg.wechat.dto.req.entry.business.WechatEntryCertificateReqDto; -import com.czg.wechat.dto.req.entry.business.WechatEntryLicenseReqDto; +import com.czg.wechat.dto.req.entry.business.*; import lombok.Data; +import java.util.List; + /** * 进件 主体资料 * @author yjjie @@ -52,4 +53,49 @@ public class WechatEntrySubjectReqDto { */ @JSONField(name = "certificate_info") private WechatEntryCertificateReqDto certificateInfo; + + /** + * 选填 + * 单位证明函照片 + * 1、主体类型为政府机关、事业单位选传: + * (1)若上传,则审核通过后即可签约,无需汇款验证; + * (2)若未上传,则审核通过后,需汇款验证。 + * 2、主体为个体户、企业、其他组织等,不需要上传本字段; + * 3、请参照示例图打印单位证明函,全部信息需打印,不支持手写商户信息,并加盖公章; ... + * 4、可上传1张图片,请填写通过图片上传API预先上传图片生成好的MediaID。 + */ + @JSONField(name = "certificate_letter_copy") + private String certificateLetterCopy; + + /** + * 选填 + * 金融机构许可证信息 当主体是金融机构时,必填。 + */ + @JSONField(name = "finance_institution_info") + private WechatEntryFinanceInstitutionReqDto financeInstitutionInfo; + + /** + * 必填 + * 经营者/法定代表人身份证件 + * 1、个体户:请上传经营者的身份证件; + * 2、企业/社会组织:请上传法定代表人的身份证件; + * 3、政府机关/事业单位:请上传法定代表人/经办人的身份证件。 + */ + @JSONField(name = "identity_info") + private WechatEntryIdentityReqDto identityInfo; + + /** + * 选填 + * 最终受益人信息列表(UBO) + * 1、主体类型个体户/社会组织/政府机关/事业单位时,无需填写 + * 2、主体类型为企业时,按照下述要求填写 + * 1)若经营者/法定代表人不是最终受益所有人,则需提填写受益所有人信息,最多上传4个。 + * 2)若经营者/法定代表人是最终受益所有人之一,可在此填写其他受益所有人信息,最多上传3个。 + * 根据国家相关法律法规,需要提供公司受益所有人信息,受益所有人需符合至少以下条件之一: + * ▪️直接或者间接拥有超过25%公司股权或者表决权的自然人。 + * ▪️通过人事、财务等其他方式对公司进行控制的自然人。 + * ▪️公司的高级管理人员,包括公司的经理、副经理、财务负责人、上市公司董事会秘书和公司章程规定的其他人员。 + */ + @JSONField(name = "ubo_info_list") + private List uboInfoList; } diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryCertificateReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryCertificateReqDto.java index 910f94b58..ce09795f3 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryCertificateReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryCertificateReqDto.java @@ -1,5 +1,6 @@ package com.czg.wechat.dto.req.entry.business; +import com.alibaba.fastjson2.annotation.JSONField; import lombok.Data; /** @@ -13,5 +14,96 @@ public class WechatEntryCertificateReqDto { /** * 必填 * 登记证书照片 + * 1、照片应正面拍摄、清晰、四角完整、无反光或遮挡;不得翻拍、截图、镜像、PS; + * 2、上传彩色照片、彩色扫描件,复印件需加盖公章鲜章; + * 3、水印仅限于微信支付业务相关; + * 4、指引与示例可参考【指引文档】; + * 5、请填写通过图片上传API预先上传图片生成好的MediaID。 */ + @JSONField(name = "cert_copy") + private String certCopy; + + /** + * 必填 + * 登记证书类型 + * 1、主体为“政府机关/事业单位/社会组织”时,请上传登记证书类型; + * 2、主体为“个体工商户/企业”时,不填; + * 当主体为事业单位时,选择此枚举值: + * CERTIFICATE_TYPE_2388:事业单位法人证书 + * 当主体为政府机关,选择此枚举值: + * CERTIFICATE_TYPE_2389:统一社会信用代码证书 + * 当主体为社会组织,选择以下枚举值之一: + * CERTIFICATE_TYPE_2389:统一社会信用代码证书 + * CERTIFICATE_TYPE_2394:社会团体法人登记证书 + * CERTIFICATE_TYPE_2395:民办非企业单位登记证书 + * CERTIFICATE_TYPE_2396:基金会法人登记证书 + * CERTIFICATE_TYPE_2520:执业许可证/执业证 + * CERTIFICATE_TYPE_2521:基层群众性自治组织特别法人统一社会信用代码证 + * CERTIFICATE_TYPE_2522:农村集体经济组织登记证 + * CERTIFICATE_TYPE_2399:宗教活动场所登记证 + * CERTIFICATE_TYPE_2400:政府部门下发的其他有效证明文件 + */ + @JSONField(name = "cert_type") + private String certType; + + /** + * 必填 + * 证书号 请输入与所选证书类型相匹配且符合国家标准规范的证书号,其中除政府证明文件外,需满足18位阿拉伯数字或大写英文字母(不得包含英文字母I/O/Z/S/V) + */ + @JSONField(name = "cert_number") + private String certNumber; + + /** + * 必填 + * 商户名称 请填写登记证书上的商户名称 + * 1、长度为2-128个字符; + * 2、前后不能有空格、制表符、换行符; + * 3、不能仅含数字、特殊字符; + * 4、仅能填写数字、英文字母、汉字及特殊字符; + * 5、仅支持utf-8格式。 + */ + @JSONField(name = "merchant_name") + private String merchantName; + + /** + * 必填 + * 注册地址 请填写登记证书的注册地址 + * 1、长度为4-128个字符; + * 2、前后不能有空格、制表符、换行符; + * 3、不能仅含数字、特殊字符; + * 4、仅能填写数字、英文字母、汉字及特殊字符; + * 5、仅支持utf-8格式。 + */ + @JSONField(name = "company_address") + private String companyAddress; + + /** + * 必填 + * 法定代表人 请填写登记证书上的法定代表人姓名 + * 1、长度为2-100个字符; + * 2、前后不能有空格、制表符、换行符; + * 3、不能仅含特殊字符; + * 4、仅能填写数字、英文字母、汉字及特殊字符。 + */ + @JSONField(name = "legal_person") + private String legalPerson; + + /** + * 选填 + * 有效期限开始日期 建议填写营业执照的有效期限开始时间,若该字段未填写,系统将会查询国家工商信息填入。需注意若工商信息查询不到,则会被审核驳回。 + * 1、日期格式应满足合法的YYYY-MM-DD格式; + * 2、开始时间不能小于1900-01-01; + * 3、开始时间不能大于等于当前日期。 + */ + @JSONField(name = "period_begin") + private String periodBegin; + + /** + * 选填 + * 营业期限结束日期 建议填写营业执照的有效期限结束时间,若该字段未填写,系统将会查询国家工商信息填入。需注意若工商信息查询不到,则会被审核驳回。 + * 1、日期格式应满足合法的YYYY-MM-DD格式或长期; + * 2、结束时间需大于开始时间。 + */ + @JSONField(name = "period_end") + private String periodEnd; } diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryFinanceInstitutionReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryFinanceInstitutionReqDto.java new file mode 100644 index 000000000..61a450018 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryFinanceInstitutionReqDto.java @@ -0,0 +1,40 @@ +package com.czg.wechat.dto.req.entry.business; + +import com.alibaba.fastjson2.annotation.JSONField; +import lombok.Data; + +import java.util.List; + +/** + * 金融机构许可证信息 + * @author yjjie + * @date 2025/12/26 15:21 + */ +@Data +public class WechatEntryFinanceInstitutionReqDto { + + /** + * 必填 + * 金融机构类型 金融机构类型需与营业执照/登记证书上一致,可参考选择金融机构指引。 + * BANK_AGENT:银行业, 适用于商业银行、政策性银行、农村合作银行、村镇银行、开发性金融机构等 + * PAYMENT_AGENT:支付机构, 适用于非银行类支付机构 + * INSURANCE:保险业, 适用于保险、保险中介、保险代理、保险经纪等保险类业务 + * TRADE_AND_SETTLE:交易及结算类金融机构, 适用于交易所、登记结算类机构、银行卡清算机构、资金清算中心等 + * OTHER:其他金融机构, 适用于财务公司、信托公司、金融资产管理公司、金融租赁公司、汽车金融公司、贷款公司、货币经纪公司、消费金融公司、证券业、金融控股公司、股票、期货、货币兑换、小额贷款公司、金融资产管理、担保公司、商业保理公司、典当行、融资租赁公司、财经咨询等其他金融业务 + */ + @JSONField(name = "finance_type") + private String financeType; + + /** + * 必填 + * 金融机构许可证图片 + * 1、照片应正面拍摄、清晰、四角完整、无反光或遮挡;不得翻拍、截图、镜像、PS; + * 2、上传彩色照片、彩色扫描件,复印件需加盖公章鲜章; + * 3、水印仅限于微信支付业务相关; + * 4、根据所属金融机构类型的许可证要求提供,详情查看金融机构指引; ... + * 5、请提供为“申请商家主体”所属的许可证,可授权使用总公司/分公司的特殊资质; + * 6、最多可上传5张照片,请填写通过图片上传API预先上传图片生成好的MediaID。 + */ + @JSONField(name = "finance_license_pics") + private List financeLicensePics; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryIdentityReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryIdentityReqDto.java new file mode 100644 index 000000000..539c71e96 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryIdentityReqDto.java @@ -0,0 +1,70 @@ +package com.czg.wechat.dto.req.entry.business; + +import com.alibaba.fastjson2.annotation.JSONField; +import com.czg.wechat.dto.req.entry.id.WechatEntryIdCardReqDto; +import com.czg.wechat.dto.req.entry.id.WechatEntryIdDocInfoReqDto; +import lombok.Data; + +/** + * 经营者/法定代表人身份证件 + * @author yjjie + * @date 2025/12/26 15:24 + */ +@Data +public class WechatEntryIdentityReqDto { + + /** + * 选填 + * 证件持有人类型 + * 1、主体类型为政府机关/事业单位时选传: + * (1)若上传的是法定代表人证件,则不需要上传该字段。 + * (2)若因政策保密等原因,无法提供法定代表人证件时,可上传经办人。 (经办人:经商户授权办理微信支付业务的人员,授权范围包括但不限于签约,入驻过程需完成账户验证)。 + * 2、主体类型为小微/个人卖家/企业/个体户/社会组织时,默认为经营者/法定代表人,不需要上传该字段。 + * LEGAL: 经营者/法定代表人 + * SUPER: 经办人 + */ + @JSONField(name = "id_holder_type") + private String idHolderType; + + /** + * 选填 + * 证件类型 + * 1、当证件持有人类型为法定代表人时,填写。其他情况,无需上传; + * 2、个体户/企业/事业单位/社会组织:可选择任一证件类型,政府机关仅支持中国大陆居民-身份证类型。 + * 可选取值 + * IDENTIFICATION_TYPE_IDCARD: 中国大陆居民-身份证 + * IDENTIFICATION_TYPE_OVERSEA_PASSPORT: 其他国家或地区居民-护照 + * IDENTIFICATION_TYPE_HONGKONG_PASSPORT: 中国香港居民-来往内地通行证 + * IDENTIFICATION_TYPE_MACAO_PASSPORT: 中国澳门居民-来往内地通行证 + * IDENTIFICATION_TYPE_TAIWAN_PASSPORT: 中国台湾居民-来往大陆通行证 + * IDENTIFICATION_TYPE_FOREIGN_RESIDENT: 外国人居留证 + * IDENTIFICATION_TYPE_HONGKONG_MACAO_RESIDENT: 港澳居民居住证 + * IDENTIFICATION_TYPE_TAIWAN_RESIDENT: 台湾居民居住证 + */ + @JSONField(name = "id_doc_type") + private String idDocType; + + /** + * 选填 + * 法定代表人说明函 + * 1、当证件持有人类型为经办人时,必须上传。其他情况,无需上传; + * 2、若因特殊情况,无法提供法定代表人证件时,请参照示例图打印法定代表人说明函,全部信息需打印,不支持手写商户信息,并加盖公章; ... + * 3、可上传1张图片,请填写通过图片上传API预先上传图片生成好的MediaID。 + */ + @JSONField(name = "authorize_letter_copy") + private String authorizeLetterCopy; + + /** + * 选填 + * 身份证信息 当证件持有人类型为经营者/法定代表人且证件类型为“身份证”时填写。 + */ + @JSONField(name = "id_card_info") + private WechatEntryIdCardReqDto idCardInfo; + + /** + * 选填 + * 其他类型证件信息 当证件持有人类型为经营者/法定代表人且证件类型不为“身份证”时填写。 + */ + @JSONField(name = "id_doc_info") + private WechatEntryIdDocInfoReqDto idDocInfo; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryUboInfoReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryUboInfoReqDto.java new file mode 100644 index 000000000..3e01e0970 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryUboInfoReqDto.java @@ -0,0 +1,111 @@ +package com.czg.wechat.dto.req.entry.business; + +import com.alibaba.fastjson2.annotation.JSONField; +import lombok.Data; + +/** + * 最终受益人信息 + * @author yjjie + * @date 2025/12/26 15:50 + */ +@Data +public class WechatEntryUboInfoReqDto { + + /** + * 必填 + * 证件类型 请填写受益人的证件类型。枚举值: + * 可选取值 + * IDENTIFICATION_TYPE_IDCARD: 中国大陆居民-身份证 + * IDENTIFICATION_TYPE_OVERSEA_PASSPORT: 其他国家或地区居民-护照 + * IDENTIFICATION_TYPE_HONGKONG_PASSPORT: 中国香港居民-来往内地通行证 + * IDENTIFICATION_TYPE_MACAO_PASSPORT: 中国澳门居民-来往内地通行证 + * IDENTIFICATION_TYPE_TAIWAN_PASSPORT: 中国台湾居民-来往大陆通行证 + * IDENTIFICATION_TYPE_FOREIGN_RESIDENT: 外国人居留证 + * IDENTIFICATION_TYPE_HONGKONG_MACAO_RESIDENT: 港澳居民居住证 + * IDENTIFICATION_TYPE_TAIWAN_RESIDENT: 台湾居民居住证 + */ + @JSONField(name = "ubo_id_doc_type") + private String uboIdDocType; + + /** + * 必填 + * 证件正面照片 + * 1、请上传受益人证件的正面照片; + * 2、若证件类型为身份证,请上传人像面照片; + * 3、正面拍摄、清晰、四角完整、无反光或遮挡;不得翻拍、截图、镜像、PS; + * 4、请上传彩色照片or彩色扫描件,复印件需加盖公章鲜章,可添加“微信支付”相关水印(如微信支付认证),见【指引文档】; + * 5、可上传1张图片,请填写通过图片上传API预先上传图片生成好的MediaID。 + */ + @JSONField(name = "ubo_id_doc_copy") + private String uboIdDocCopy; + + /** + * 选填 + * 证件反面照片 + * 1、请上传受益人证件的反面照片; + * 2、若证件类型为身份证,请上传国徽面照片; + * 3、若证件类型为护照,无需上传反面照片; + * 4、正面拍摄、清晰、四角完整、无反光或遮挡;不得翻拍、截图、镜像、PS; + * 5、请上传彩色照片or彩色扫描件,复印件需加盖公章鲜章,可添加“微信支付”相关水印(如微信支付认证),见【指引文档】; + * 6、可上传1张图片,请填写通过图片上传API预先上传图片生成好的MediaID。 + */ + @JSONField(name = "ubo_id_doc_copy_back") + private String uboIdDocCopyBack; + + /** + * 必填 + * 证件姓名 + * 1、长度为2-100个字符; + * 2、前后不能有空格、制表符、换行符; + * 3、不能仅含数字、特殊字符; + * 4、仅能填写数字、英文字母、汉字及特殊字符; + * 5、该字段需要使用微信支付公钥加密(推荐),请参考获取微信支付公钥ID说明以及微信支付公钥加密敏感信息指引,也可以使用微信支付平台证书公钥加密,参考获取平台证书序列号、平台证书加密敏感信息指引。 + */ + @JSONField(name = "ubo_id_doc_name") + private String uboIdDocName; + + /** + * 必填 + * 证件号码 + * 1、证件号码为证件正反面中一致的号码; + * 2、证件号码为18位或15位,或港澳居民来往内地通行证为9位; + * 3、证件号码为英文字母X或x,或港澳居民来往内地通行证为英文字母X或x; + * 4、证件号码为英文字母x或X,或港澳居民来往内地通行证为英文字母x或X; + * 5、该字段需要使用微信支付公钥加密(推荐),请参考获取微信支付公钥 + */ + @JSONField(name = "ubo_id_doc_number") + private String uboIdDocNumber; + + /** + * 必填 + * 证件居住地址 + * 1、请按照身份证住址填写,如广东省深圳市南山区xx路xx号xx室; + * 2、长度为4-128个字符; + * 3、前后不能有空格、制表符、换行符; + * 4、不能仅含数字、特殊字符; + * 5、仅能填写数字、英文字母、汉字及特殊字符; + * 6、仅支持utf-8格式; + * 7、 该字段需要使用微信支付公钥加密(推荐),请参考获取微信支付公钥ID说明以及微信支付公钥加密敏感信息指引,也可以使用微信支付平台证书公钥加密,参考获取平台证书序列号、平台证书加密敏感信息指引。 + */ + @JSONField(name = "ubo_id_doc_address") + private String uboIdDocAddress; + + /** + * 必填 + * 证件有效期开始时间 + * 1、日期格式应满足合法的YYYY-MM-DD格式; + * 2、开始时间不能小于1900-01-01; + * 3、开始时间不能大于等于当前日期。 + */ + @JSONField(name = "ubo_period_begin") + private String uboPeriodBegin; + + /** + * 必填 + * 证件有效期结束时间 + * 1、日期格式应满足合法的YYYY-MM-DD格式或长期; + * 2、结束时间需大于开始时间。 + */ + @JSONField(name = "ubo_period_end") + private String uboPeriodEnd; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/id/WechatEntryIdCardReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/id/WechatEntryIdCardReqDto.java new file mode 100644 index 000000000..7e18cc07d --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/id/WechatEntryIdCardReqDto.java @@ -0,0 +1,94 @@ +package com.czg.wechat.dto.req.entry.id; + +import com.alibaba.fastjson2.annotation.JSONField; +import lombok.Data; + +/** + * 身份证信息 + * @author yjjie + * @date 2025/12/26 15:29 + */ +@Data +public class WechatEntryIdCardReqDto { + + /** + * 必填 + * 身份证人像面照片 + * 1、请上传个体户经营者/法定代表人的身份证人像面照片; + * 2、正面拍摄、清晰、四角完整、无反光或遮挡;不得翻拍、截图、镜像、PS; + * 3、请上传彩色照片or彩色扫描件,复印件需加盖公章鲜章,可添加“微信支付”相关水印(如微信支付认证),见【指引文档】; + * 4、可上传1张图片,请填写通过图片上传API预先上传图片生成好的MediaID。 + */ + @JSONField(name = "id_card_copy") + private String idCardCopy; + + /** + * 必填 + * 身份证国徽面照片 + * 、请上传个体户经营者/法定代表人的身份证国徽面照片; + * 2、正面拍摄、清晰、四角完整、无反光或遮挡;不得翻拍、截图、镜像、PS; + * 3、请上传彩色照片or彩色扫描件,复印件需加盖公章鲜章,可添加“微信支付”相关水印(如微信支付认证),见【指引文档】; + * 4、可上传1张图片,请填写通过图片上传API预先上传图片生成好的MediaID。 + */ + @JSONField(name = "id_card_national") + private String idCardNational; + + /** + * 必填 + * 身份证姓名 + * 1、请填写个体户经营者/法定代表人对应身份证的姓名; + * 2、长度为2-100个字符; + * 3、前后不能有空格、制表符、换行符; + * 4、不能仅含数字、特殊字符; + * 5、仅能填写数字、英文字母、汉字及特殊字符; + * 6、该字段需要使用微信支付公钥加密(推荐),请参考获取微信支付公钥ID说明以及微信支付公钥加密敏感信息指引,也可以使用微信支付平台证书公钥加密,参考获取平台证书序列号、平台证书加密敏感信息指引。 + * 加密 + */ + @JSONField(name = "id_card_name") + private String idCardName; + + /** + * 必填 + * 身份证号码 + * 1、请填写个体户经营者/法定代表人对应身份证的号码; + * 2、17位数字+1位数字|X ,该字段需要使用微信支付公钥加密(推荐),请参考获取微信支付公钥ID说明以及微信支付公钥加密敏感信息指引,也可以使用微信支付平台证书公钥加密,参考获取平台证书序列号、平台证书加密敏感信息指引。 + * 加密 + */ + @JSONField(name = "id_card_number") + private String idCardNumber; + + /** + * 选填 + * 身份证居住地址 + * 1、主体类型为企业时,需要填写。其他主体类型,无需上传; + * 2、请按照身份证住址填写,如广东省深圳市南山区xx路xx号xx室; + * 3、长度为4-128个字符; + * 4、前后不能有空格、制表符、换行符; + * 5、不能仅含数字、特殊字符; + * 6、仅能填写数字、英文字母、汉字及特殊字符; + * 7、仅支持utf-8格式; + * 8、 该字段需要使用微信支付公钥加密(推荐),请参考获取微信支付公钥ID说明以及微信支付公钥加密敏感信息指引,也可以使用微信支付平台证书公钥加密,参考获取平台证书序列号、平台证书加密敏感信息指引。 + * 加密 + */ + @JSONField(name = "id_card_address") + private String idCardAddress; + + /** + * 必填 + * 身份证有效期开始时间 + * 1、请填写身份证有效期开始时间,格式为yyyy-MM-dd; + * 2、开始时间不能小于1900-01-01; + * 3、开始时间不能大于等于当前日期。 + */ + @JSONField(name = "card_period_begin") + private String cardPeriodBegin; + + /** + * 必填 + * 身份证有效期截止时间 + * 1、日期格式应满足合法的YYYY-MM-DD格式或长期; + * 2、结束时间需大于开始时间。 + */ + @JSONField(name = "card_period_end") + private String cardPeriodEnd; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/id/WechatEntryIdDocInfoReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/id/WechatEntryIdDocInfoReqDto.java new file mode 100644 index 000000000..47e3029b7 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/id/WechatEntryIdDocInfoReqDto.java @@ -0,0 +1,98 @@ +package com.czg.wechat.dto.req.entry.id; + +import com.alibaba.fastjson2.annotation.JSONField; +import lombok.Data; + +/** + * 其他类型证件信息 + * @author yjjie + * @date 2025/12/26 15:42 + */ +@Data +public class WechatEntryIdDocInfoReqDto { + + /** + * 必填 + * 证件正面照片 + * 1、证件类型不为“身份证”时,上传证件正面照片; + * 2、正面拍摄、清晰、四角完整、无反光或遮挡;不得翻拍、截图、镜像、PS; + * 3、请上传彩色照片or彩色扫描件,复印件需加盖公章鲜章,可添加“微信支付”相关水印(如微信支付认证),见【指引文档】; + * 4、可上传1张图片,请填写通过图片上传API预先上传图片生成好的MediaID。 + */ + @JSONField(name = "id_doc_copy") + private String idDocCopy; + + /** + * 选填 + * 证件反面照片 + * 1、若证件类型为往来通行证、外国人居留证、港澳居民居住证、台湾居民居住证时,上传证件反面照片; + * 2、若证件类型为护照,无需上传反面照片; + * 3、正面拍摄、清晰、四角完整、无反光或遮挡;不得翻拍、截图、镜像、PS; + * 4、请上传彩色照片or彩色扫描件,复印件需加盖公章鲜章,可添加“微信支付”相关水印(如微信支付认证),见【指引文档】; + * 5、可上传1张图片,请填写通过图片上传API预先上传图片生成好的MediaID。 + */ + @JSONField(name = "id_doc_copy_back") + private String idDocCopyBack; + + /** + * 必填 + * 证件姓名 + * 1、请填写经营者/法定代表人的证件姓名; + * 2、长度为2-100个字符; + * 3、前后不能有空格、制表符、换行符; + * 4、不能仅含数字、特殊字符; + * 5、仅能填写数字、英文字母、汉字及特殊字符; + * 6、该字段需要使用微信支付公钥加密(推荐),请参考获取微信支付公钥ID说明以及微信支付公钥加密敏感信息指引,也可以使用微信支付平台证书公钥加密,参考获取平台证书序列号、平台证书加密敏感信息指引。 + */ + @JSONField(name = "id_doc_name") + private String idDocName; + + /** + * 必填 + * 证件号码 + * 1、请填写经营者/法定代表人的证件号码: + * 护照(限境外人士):4-15位 数字|字母|连字符; + * 中国香港居民--来往内地通行证:H/h开头+8或10位数字/字母; + * 中国澳门居民--来往内地通行证:M/m开头+8或10位数字/字母; + * 中国台湾居民--来往大陆通行证:8位数字或10位数字; + * 外国人居留证:15位 数字|字母; + * 台湾居民居住证/港澳居民居住证:17位数字+1位数字|X; + * 2、该字段需要使用微信支付公钥加密(推荐),请参考获取微信支付公钥ID说明以及微信支付公钥加密敏感信息指引,也可以使用微信支付平台证书公钥加密,参考获取平台证书序列号、平台证书加密敏感信息指引。 + */ + @JSONField(name = "id_doc_number") + private String idDocNumber; + + /** + * 选填 + * 证件居住地址 + * 1、主体类型为企业时,需要填写。其他主体类型,无需上传; + * 2、请按照身份证住址填写,如广东省深圳市南山区xx路xx号xx室; + * 3、长度为4-128个字符; + * 4、前后不能有空格、制表符、换行符; + * 5、不能仅含数字、特殊字符; + * 6、仅能填写数字、英文字母、汉字及特殊字符; + * 7、仅支持utf-8格式; + * 8、 该字段需要使用微信支付公钥加密(推荐),请参考获取微信支付公钥ID说明以及微信支付公钥加密敏感信息指引,也可以使用微信支付平台证书公钥加密,参考获取平台证书序列号、平台证书加密敏感信息指引。 + */ + @JSONField(name = "id_doc_address") + private String idDocAddress; + + /** + * 必填 + * 证件有效期开始时间 + * 1、日期格式应满足合法的YYYY-MM-DD格式; + * 2、开始时间不能小于1900-01-01; + * 3、开始时间不能大于等于当前日期。 + */ + @JSONField(name = "doc_period_begin") + private String docPeriodBegin; + + /** + * 必填 + * 证件有效期结束时间 + * 1、日期格式应满足合法的YYYY-MM-DD格式或长期; + * 2、结束时间需大于开始时间。 + */ + @JSONField(name = "doc_period_end") + private String docPeriodEnd; +} From 2046ad2486c0501f443bb9ca68663994b2ba5723 Mon Sep 17 00:00:00 2001 From: gong <1157756119@qq.com> Date: Fri, 26 Dec 2025 16:53:57 +0800 Subject: [PATCH 05/19] =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E6=94=AF=E4=BB=98-=20d?= =?UTF-8?q?to=20=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/czg/wechat/WechatEntryManager.java | 9 ++++-- .../req/entry/WechatEntryAdditionReqDto.java | 10 ++++--- .../entry/WechatEntryBankAccountReqDto.java | 14 ++++++---- .../req/entry/WechatEntryContactReqDto.java | 22 ++++++++------- .../dto/req/entry/WechatEntryReqDto.java | 13 ++++++--- .../req/entry/WechatEntrySettleReqDto.java | 24 ++++++++-------- .../req/entry/WechatEntrySubjectReqDto.java | 28 ++++++++++--------- .../business/WechatEntryBusinessReqDto.java | 8 ++++-- .../WechatEntryCertificateReqDto.java | 18 ++++++------ .../WechatEntryFinanceInstitutionReqDto.java | 4 ++- .../business/WechatEntryIdentityReqDto.java | 12 ++++---- .../business/WechatEntryLicenseReqDto.java | 16 ++++++----- .../business/WechatEntryUboInfoReqDto.java | 6 ++-- .../sales/WechatEntryAppInfoReqDto.java | 12 ++++---- .../sales/WechatEntryMiniProgramReqDto.java | 8 ++++-- .../sales/WechatEntryMpInfoReqDto.java | 12 ++++---- .../sales/WechatEntrySalesInfoReqDto.java | 20 +++++++------ .../sales/WechatEntryStoreInfoReqDto.java | 14 ++++++---- .../sales/WechatEntryWebInfoReqDto.java | 8 ++++-- .../sales/WechatEntryWeworkInfoReqDto.java | 4 ++- .../req/entry/id/WechatEntryIdCardReqDto.java | 10 ++++--- .../entry/id/WechatEntryIdDocInfoReqDto.java | 12 ++++---- 22 files changed, 167 insertions(+), 117 deletions(-) diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatEntryManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatEntryManager.java index 162a2ba72..85e9e7c84 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatEntryManager.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatEntryManager.java @@ -1,7 +1,9 @@ package com.czg.wechat; import com.alibaba.fastjson2.JSONObject; +import com.alibaba.fastjson2.JSONWriter; import com.czg.wechat.dto.config.WechatPayConfigDto; +import com.czg.wechat.dto.req.entry.WechatEntryReqDto; import com.wechat.pay.java.service.file.FileUploadService; import com.wechat.pay.java.service.file.model.FileUploadResponse; import lombok.extern.slf4j.Slf4j; @@ -151,7 +153,10 @@ public class WechatEntryManager { .setPublicKeyId("PUB_KEY_ID_0116437794082025111000382377001000") .setDomain("https://api.mch.weixin.qq.com"); - String string = uploadImage(dto, "https://czg-qr-order.oss-cn-beijing.aliyuncs.com/indexs/shuangbackground.png"); - log.info("图片上传成功:{}", string); +// String string = uploadImage(dto, "https://czg-qr-order.oss-cn-beijing.aliyuncs.com/indexs/shuangbackground.png"); +// log.info("图片上传成功:{}", string); + + WechatEntryReqDto reqDto = new WechatEntryReqDto(); + System.out.println(JSONObject.toJSONString(reqDto, JSONWriter.Feature.IgnoreEmpty)); } } diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryAdditionReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryAdditionReqDto.java index a656d8303..af0d5ed7d 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryAdditionReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryAdditionReqDto.java @@ -2,6 +2,7 @@ package com.czg.wechat.dto.req.entry; import com.alibaba.fastjson2.annotation.JSONField; import lombok.Data; +import lombok.experimental.Accessors; import java.util.List; @@ -12,10 +13,11 @@ import java.util.List; * @date 2025/12/26 13:43 */ @Data +@Accessors(chain = true) public class WechatEntryAdditionReqDto { /** - * 选填 + * 【选填】 * 法定代表人开户承诺函 * 模板下载地址 ... * 通过图片上传完成后 MediaID @@ -24,7 +26,7 @@ public class WechatEntryAdditionReqDto { private String legalPersonCommitment; /** - * 选填 + * 【选填】 * 法定代表人开户意愿视频 * 通过视频上传完成后 MediaID */ @@ -32,7 +34,7 @@ public class WechatEntryAdditionReqDto { private String legalPersonVideo; /** - * 选填 + * 【选填】 * 补充材料 * 最多可上传5张照片 * 通过图片上传完成后 MediaID @@ -41,7 +43,7 @@ public class WechatEntryAdditionReqDto { private List businessAdditionPics; /** - * 选填 + * 【选填】 * 补充说明 512字以内 */ @JSONField(name = "business_addition_msg") diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryBankAccountReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryBankAccountReqDto.java index 35d0cacdf..8908d1511 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryBankAccountReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryBankAccountReqDto.java @@ -2,6 +2,7 @@ package com.czg.wechat.dto.req.entry; import com.alibaba.fastjson2.annotation.JSONField; import lombok.Data; +import lombok.experimental.Accessors; /** * 微信进件-银行账号 @@ -10,10 +11,11 @@ import lombok.Data; * @date 2025/12/26 13:42 */ @Data +@Accessors(chain = true) public class WechatEntryBankAccountReqDto { /** - * 必填 + * 【必填】 * 账户类型 * 1、若主体为企业/政府机关/事业单位/社会组织,可填写:对公银行账户; * 2、若主体为个体户,可选择填写:对公银行账户或经营者个人银行卡 @@ -23,7 +25,7 @@ public class WechatEntryBankAccountReqDto { private String bankAccountType; /** - * 必填 + * 【必填】 * 开户名称 * 1、选择“经营者个人银行卡”时,开户名称必须与“经营者证件姓名”一致; * 2、选择“对公银行账户”时,开户名称必须与营业执照上的“商户名称”一致; @@ -34,7 +36,7 @@ public class WechatEntryBankAccountReqDto { private String accountName; /** - * 必填 + * 【必填】 * 开户银行 * 对私银行调用:查询支持个人业务的银行列表API * 对公银行调用:查询支持对公业务的银行列表API @@ -43,7 +45,7 @@ public class WechatEntryBankAccountReqDto { private String accountBank; /** - * 选填 + * 【选填】 * 开户银行银行号 * 1、根据开户银行查询接口中的“是否需要填写支行”判断是否需要填写。如为其他银行,开户银行全称(含支行)和开户银行联行号二选一; * 2、详细需调用查询支行列表API查看查询结果。 ... @@ -52,7 +54,7 @@ public class WechatEntryBankAccountReqDto { private String bankBranchId; /** - * 选填 + * 【选填】 * 开户银行全称(含支行) * 1、根据开户银行查询接口中的“是否需要填写支行”判断是否需要填写。如为其他银行,开户银行全称(含支行)和开户银行联行号二选一; * 2、详细需调用查询支行列表API查看查询结果。 ... @@ -61,7 +63,7 @@ public class WechatEntryBankAccountReqDto { private String bankName; /** - * 必填 + * 【必填】 * 开户银行账号 * 1、选择“经营者个人银行卡”时,开户账号为经营者个人银行卡号; * 2、选择“对公银行账户”时,开户账号为对公银行账号; diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryContactReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryContactReqDto.java index 82c91ed49..635a3ff64 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryContactReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryContactReqDto.java @@ -2,6 +2,7 @@ package com.czg.wechat.dto.req.entry; import com.alibaba.fastjson2.annotation.JSONField; import lombok.Data; +import lombok.experimental.Accessors; /** * 进件 联系人信息 @@ -10,10 +11,11 @@ import lombok.Data; * @date 2025/12/26 13:38 */ @Data +@Accessors(chain = true) public class WechatEntryContactReqDto { /** - * 必填 + * 【必填】 * 超级管理员类型 * 主体为“个体工商户/企业/政府机关/事业单位/社会组织”,可选择:LEGAL:经营者/法定代表人,SUPER:经办人 。(经办人:经商户授权办理微信支付业务的人员)。 * 可选取值 @@ -24,7 +26,7 @@ public class WechatEntryContactReqDto { private String contactType; /** - * 必填 + * 【必填】 * 超级管理员姓名 * 1、长度为2-100个字符; * 2、前后不能有空格、制表符、换行符; @@ -36,7 +38,7 @@ public class WechatEntryContactReqDto { private String contactName; /** - * 选填 + * 【选填】 * 超级管理员证件类型 当超级管理员类型是经办人时,请上传超级管理员证件类型。 * 可选取值 * IDENTIFICATION_TYPE_IDCARD: 中国大陆居民-身份证 @@ -52,7 +54,7 @@ public class WechatEntryContactReqDto { private String contactIdType; /** - * 选填 + * 【选填】 * 超级管理员身份证件号码 * 1、当超级管理员类型是经办人时,请上传超级管理员证件号码; * 2、可传身份证、来往内地通行证、来往大陆通行证、护照等证件号码,号码规范如下: @@ -70,7 +72,7 @@ public class WechatEntryContactReqDto { private String contactIdNumber; /** - * 选填 + * 【选填】 * 超级管理员证件正面照片 * 1、当超级管理员类型是经办人时,请上传超级管理员证件的正面照片; * 2、若证件类型为身份证,请上传人像面照片; @@ -82,7 +84,7 @@ public class WechatEntryContactReqDto { private String contactIdDocCopy; /** - * 选填 + * 【选填】 * 超级管理员证件反面照片 * 1、当超级管理员类型是经办人时,请上传超级管理员证件的反面照片; * 2、若证件类型为护照,无需上传反面照片; @@ -94,7 +96,7 @@ public class WechatEntryContactReqDto { private String contactIdDocCopyBack; /** - * 选填 + * 【选填】 * 超级管理员证件有效期开始时间 * 1、当超级管理员类型是经办人时,请上传证件有效期开始时间; * 2、请按照示例值填写,日期格式应满足合法的YYYY-MM-DD格式; @@ -104,7 +106,7 @@ public class WechatEntryContactReqDto { private String contactPeriodBegin; /** - * 选填 + * 【选填】 * 超级管理员证件有效期截止时间 * 1、当超级管理员类型是经办人时,请上传证件有效期结束时间; * 2、请按照示例值填写,日期格式应满足合法的YYYY-MM-DD格式,若证件有效期为长期,请填写:长期; @@ -114,7 +116,7 @@ public class WechatEntryContactReqDto { private String contactPeriodEnd; /** - * 必填 + * 【必填】 * 联系手机 * 1、前后不能有空格、制表符、换行符; * 2、需满足以下任一条件: @@ -127,7 +129,7 @@ public class WechatEntryContactReqDto { private String mobilePhone; /** - * 必填 + * 【必填】 * 联系邮箱 * 1、用于接收微信支付的开户邮件及日常业务通知; * 2、需要带@,遵循邮箱格式校验 ,该字段需要使用微信支付公钥加密(推荐),请参考获取微信支付公钥ID说明以及微信支付公钥加密敏感信息指引,也可以使用微信支付平台证书公钥加密,参考获取平台证书序列号、平台证书加密敏感信息指引。 diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryReqDto.java index c0793e703..41432c01e 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryReqDto.java @@ -3,6 +3,7 @@ package com.czg.wechat.dto.req.entry; import com.alibaba.fastjson2.annotation.JSONField; import com.czg.wechat.dto.req.entry.business.WechatEntryBusinessReqDto; import lombok.Data; +import lombok.experimental.Accessors; /** * 微信进件请求参数 @@ -11,28 +12,32 @@ import lombok.Data; * @date 2025/12/26 13:36 */ @Data +@Accessors(chain = true) public class WechatEntryReqDto { /** + * 【必填】 * 业务申请编号 */ @JSONField(name = "business_code") private String businessCode; /** + * 【必填】 * 超级管理员信息 */ @JSONField(name = "contact_info") private WechatEntryContactReqDto contactInfo; /** + * 【必填】 * 主体资料 */ @JSONField(name = "subject_info") private WechatEntrySubjectReqDto subjectInfo; /** - * 必填 + * 【必填】 * 经营资料 * 商家的经营业务信息、售卖商品/提供服务场景信息 */ @@ -40,7 +45,7 @@ public class WechatEntryReqDto { private WechatEntryBusinessReqDto businessInfo; /** - * 必填 + * 【必填】 * 结算规则 * 请填写商家的结算费率规则、特殊资质等信息 */ @@ -48,14 +53,14 @@ public class WechatEntryReqDto { private WechatEntrySettleReqDto settlementInfo; /** - * 必填 + * 【必填】 * 结算银行账户 */ @JSONField(name = "bank_account_info") private WechatEntryBankAccountReqDto bankAccountInfo; /** - * 选填 + * 【选填】 * 补充材料 * 根据实际审核情况,会额外要求商家提供指定的补充资料 */ diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntrySettleReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntrySettleReqDto.java index 55f434741..3bcdf6594 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntrySettleReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntrySettleReqDto.java @@ -2,6 +2,7 @@ package com.czg.wechat.dto.req.entry; import com.alibaba.fastjson2.annotation.JSONField; import lombok.Data; +import lombok.experimental.Accessors; import java.util.List; @@ -11,10 +12,11 @@ import java.util.List; * @date 2025/12/26 13:38 */ @Data +@Accessors(chain = true) public class WechatEntrySettleReqDto { /** - * 必填 + * 【必填】 * 入驻结算规则ID * 请选择结算规则ID,详细参见费率结算规则对照表 * ... @@ -23,7 +25,7 @@ public class WechatEntrySettleReqDto { private String settlementId; /** - * 必填 + * 【必填】 * 所属行业 * ... */ @@ -31,7 +33,7 @@ public class WechatEntrySettleReqDto { private String qualificationType; /** - * 选填 + * 【选填】 * 特殊资质图片 * 1、仅当商户选择了必需提交特殊资质的行业时,需要提供该项资料;若商户选择了无需特殊资质的行业,或未选择行业时,无需提交该项资料,详情查看《费率结算规则对照表》; * 2、最多可上传5张照片,请填写通过图片上传API预先上传图片生成好的MediaID。 @@ -40,16 +42,16 @@ public class WechatEntrySettleReqDto { private List qualifications; /** - * 选填 + * 【选填】 * 优惠费率活动ID - * 如果商户有意向报名优惠费率活动,该字段必填。详细参见《优惠费率活动对照表》 + * 如果商户有意向报名优惠费率活动,该字段【必填】。详细参见《优惠费率活动对照表》 * ... */ @JSONField(name = "activities_id") private String activitiesId; /** - * 选填 + * 【选填】 * 优惠费率活动值 * 根据优惠费率活动规则,由合作伙伴自定义填写,支持两个小数点,需在优惠费率活动ID指定费率范围内 * (1)2023年7月17日-9月17日,各合作伙伴平台可选择只传入“活动费率值”,或分别传入“信用卡优惠活动费率值” 与 “非信用卡优惠活动费率值”,只传入“活动费率值”的情况下,平台将协助将申请单中的 “优惠活动费率值” 回填入新增的 “信用卡优惠活动费率值” 与 “非信用卡优惠活动费率值”中 ; @@ -59,7 +61,7 @@ public class WechatEntrySettleReqDto { private String activitiesRate; /** - * 选填 + * 【选填】 * 优惠费率活动补充材料 * 1、根据所选优惠费率活动,提供相关材料,详细参见《优惠费率活动对照表》;... * 2、最多可上传5张照片,请填写通过图片上传API预先上传图片生成好的MediaID。 @@ -68,20 +70,20 @@ public class WechatEntrySettleReqDto { private List activitiesAdditions; /** - * 选填 + * 【选填】 * 非信用卡活动费率值 * 用户支付方式为借记卡时收取的手续费费率: - * 1、若填写了优惠费率活动ID,则该字段必填; + * 1、若填写了优惠费率活动ID,则该字段【必填】; * 2、仅能填入2位以内小数,且在优惠费率活动ID指定费率范围内。 */ @JSONField(name = "debit_activities_rate") private String debitActivitiesRate; /** - * 选填 + * 【选填】 * 信用卡活动费率值 * 用户支付方式为信用卡时收取的手续费费率: - * 1、若填写了优惠费率活动ID,则该字段必填; + * 1、若填写了优惠费率活动ID,则该字段【必填】; * 2、仅能填入2位以内小数,且在优惠费率活动ID指定费率范围内。 */ @JSONField(name = "credit_activities_rate") diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntrySubjectReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntrySubjectReqDto.java index d8cabd000..b0c693823 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntrySubjectReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntrySubjectReqDto.java @@ -3,6 +3,7 @@ package com.czg.wechat.dto.req.entry; import com.alibaba.fastjson2.annotation.JSONField; import com.czg.wechat.dto.req.entry.business.*; import lombok.Data; +import lombok.experimental.Accessors; import java.util.List; @@ -12,10 +13,11 @@ import java.util.List; * @date 2025/12/26 13:40 */ @Data +@Accessors(chain = true) public class WechatEntrySubjectReqDto { /** - * 必填 + * 【必填】 * 主体类型 主体类型需与营业执照/登记证书上一致,可参考选择主体指引。... * 可选取值 * SUBJECT_TYPE_INDIVIDUAL: (个体户)营业执照上的主体类型一般为个体户、个体工商户、个体经营 @@ -28,9 +30,9 @@ public class WechatEntrySubjectReqDto { private String subjectType; /** - * 选填 + * 【选填】 * 是否是金融机构 - * 【是否是金融机构】 选填,请根据申请主体的实际情况填写,可参考选择金融机构指引: + * 【是否是金融机构】 【选填】,请根据申请主体的实际情况填写,可参考选择金融机构指引: * 1、若商户主体是金融机构,则填写:true; * 2、若商户主体不是金融机构,则填写:false。 * 若未传入将默认填写:false。 @@ -39,23 +41,23 @@ public class WechatEntrySubjectReqDto { private Boolean financeInstitution; /** - * 必填 - * 营业执照 当前不允许小微注册,所以必填 - * 1、主体为个体户/企业,必填; + * 【必填】 + * 营业执照 当前不允许小微注册,所以【必填】 + * 1、主体为个体户/企业,【必填】; * 2、请上传“营业执照”,需年检章齐全,当年注册除外; */ @JSONField(name = "business_license_info") private WechatEntryLicenseReqDto businessLicenseInfo; /** - * 选填 - * 登记证书 主体为政府机关/事业单位/其他组织时,必填。 + * 【选填】 + * 登记证书 主体为政府机关/事业单位/其他组织时,【必填】。 */ @JSONField(name = "certificate_info") private WechatEntryCertificateReqDto certificateInfo; /** - * 选填 + * 【选填】 * 单位证明函照片 * 1、主体类型为政府机关、事业单位选传: * (1)若上传,则审核通过后即可签约,无需汇款验证; @@ -68,14 +70,14 @@ public class WechatEntrySubjectReqDto { private String certificateLetterCopy; /** - * 选填 - * 金融机构许可证信息 当主体是金融机构时,必填。 + * 【选填】 + * 金融机构许可证信息 当主体是金融机构时,【必填】。 */ @JSONField(name = "finance_institution_info") private WechatEntryFinanceInstitutionReqDto financeInstitutionInfo; /** - * 必填 + * 【必填】 * 经营者/法定代表人身份证件 * 1、个体户:请上传经营者的身份证件; * 2、企业/社会组织:请上传法定代表人的身份证件; @@ -85,7 +87,7 @@ public class WechatEntrySubjectReqDto { private WechatEntryIdentityReqDto identityInfo; /** - * 选填 + * 【选填】 * 最终受益人信息列表(UBO) * 1、主体类型个体户/社会组织/政府机关/事业单位时,无需填写 * 2、主体类型为企业时,按照下述要求填写 diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryBusinessReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryBusinessReqDto.java index 94dcd1d39..e6d9b66a4 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryBusinessReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryBusinessReqDto.java @@ -3,6 +3,7 @@ package com.czg.wechat.dto.req.entry.business; import com.alibaba.fastjson2.annotation.JSONField; import com.czg.wechat.dto.req.entry.business.sales.WechatEntrySalesInfoReqDto; import lombok.Data; +import lombok.experimental.Accessors; /** * 微信进件 商户信息 经营资料 @@ -11,10 +12,11 @@ import lombok.Data; * @date 2025/12/26 13:41 */ @Data +@Accessors(chain = true) public class WechatEntryBusinessReqDto { /** - * 必填 + * 【必填】 * 商户简称 在支付完成页向买家展示,需与微信经营类目相关 * 1、请输入1-64个字符; * 2、前后不能有空格、制表符、换行符; @@ -29,7 +31,7 @@ public class WechatEntryBusinessReqDto { private String merchantShortname; /** - * 必填 + * 【必填】 * 客服电话 将在交易记录中向买家展示,请确保电话畅通以便平台回拨确认 * 1、前后不能有空格、制表符、换行符; * 2、需满足以下任一条件; @@ -40,7 +42,7 @@ public class WechatEntryBusinessReqDto { private String servicePhone; /** - * 必填 + * 【必填】 * 经营场景 */ @JSONField(name = "sales_info") diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryCertificateReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryCertificateReqDto.java index ce09795f3..5885b1327 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryCertificateReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryCertificateReqDto.java @@ -2,6 +2,7 @@ package com.czg.wechat.dto.req.entry.business; import com.alibaba.fastjson2.annotation.JSONField; import lombok.Data; +import lombok.experimental.Accessors; /** * 登记证书 @@ -9,10 +10,11 @@ import lombok.Data; * @date 2025/12/26 15:07 */ @Data +@Accessors(chain = true) public class WechatEntryCertificateReqDto { /** - * 必填 + * 【必填】 * 登记证书照片 * 1、照片应正面拍摄、清晰、四角完整、无反光或遮挡;不得翻拍、截图、镜像、PS; * 2、上传彩色照片、彩色扫描件,复印件需加盖公章鲜章; @@ -24,7 +26,7 @@ public class WechatEntryCertificateReqDto { private String certCopy; /** - * 必填 + * 【必填】 * 登记证书类型 * 1、主体为“政府机关/事业单位/社会组织”时,请上传登记证书类型; * 2、主体为“个体工商户/企业”时,不填; @@ -47,14 +49,14 @@ public class WechatEntryCertificateReqDto { private String certType; /** - * 必填 + * 【必填】 * 证书号 请输入与所选证书类型相匹配且符合国家标准规范的证书号,其中除政府证明文件外,需满足18位阿拉伯数字或大写英文字母(不得包含英文字母I/O/Z/S/V) */ @JSONField(name = "cert_number") private String certNumber; /** - * 必填 + * 【必填】 * 商户名称 请填写登记证书上的商户名称 * 1、长度为2-128个字符; * 2、前后不能有空格、制表符、换行符; @@ -66,7 +68,7 @@ public class WechatEntryCertificateReqDto { private String merchantName; /** - * 必填 + * 【必填】 * 注册地址 请填写登记证书的注册地址 * 1、长度为4-128个字符; * 2、前后不能有空格、制表符、换行符; @@ -78,7 +80,7 @@ public class WechatEntryCertificateReqDto { private String companyAddress; /** - * 必填 + * 【必填】 * 法定代表人 请填写登记证书上的法定代表人姓名 * 1、长度为2-100个字符; * 2、前后不能有空格、制表符、换行符; @@ -89,7 +91,7 @@ public class WechatEntryCertificateReqDto { private String legalPerson; /** - * 选填 + * 【选填】 * 有效期限开始日期 建议填写营业执照的有效期限开始时间,若该字段未填写,系统将会查询国家工商信息填入。需注意若工商信息查询不到,则会被审核驳回。 * 1、日期格式应满足合法的YYYY-MM-DD格式; * 2、开始时间不能小于1900-01-01; @@ -99,7 +101,7 @@ public class WechatEntryCertificateReqDto { private String periodBegin; /** - * 选填 + * 【选填】 * 营业期限结束日期 建议填写营业执照的有效期限结束时间,若该字段未填写,系统将会查询国家工商信息填入。需注意若工商信息查询不到,则会被审核驳回。 * 1、日期格式应满足合法的YYYY-MM-DD格式或长期; * 2、结束时间需大于开始时间。 diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryFinanceInstitutionReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryFinanceInstitutionReqDto.java index 61a450018..6e5c6849b 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryFinanceInstitutionReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryFinanceInstitutionReqDto.java @@ -2,6 +2,7 @@ package com.czg.wechat.dto.req.entry.business; import com.alibaba.fastjson2.annotation.JSONField; import lombok.Data; +import lombok.experimental.Accessors; import java.util.List; @@ -11,10 +12,11 @@ import java.util.List; * @date 2025/12/26 15:21 */ @Data +@Accessors(chain = true) public class WechatEntryFinanceInstitutionReqDto { /** - * 必填 + * 【必填】 * 金融机构类型 金融机构类型需与营业执照/登记证书上一致,可参考选择金融机构指引。 * BANK_AGENT:银行业, 适用于商业银行、政策性银行、农村合作银行、村镇银行、开发性金融机构等 * PAYMENT_AGENT:支付机构, 适用于非银行类支付机构 diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryIdentityReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryIdentityReqDto.java index 539c71e96..fbe4dedb7 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryIdentityReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryIdentityReqDto.java @@ -4,6 +4,7 @@ import com.alibaba.fastjson2.annotation.JSONField; import com.czg.wechat.dto.req.entry.id.WechatEntryIdCardReqDto; import com.czg.wechat.dto.req.entry.id.WechatEntryIdDocInfoReqDto; import lombok.Data; +import lombok.experimental.Accessors; /** * 经营者/法定代表人身份证件 @@ -11,10 +12,11 @@ import lombok.Data; * @date 2025/12/26 15:24 */ @Data +@Accessors(chain = true) public class WechatEntryIdentityReqDto { /** - * 选填 + * 【选填】 * 证件持有人类型 * 1、主体类型为政府机关/事业单位时选传: * (1)若上传的是法定代表人证件,则不需要上传该字段。 @@ -27,7 +29,7 @@ public class WechatEntryIdentityReqDto { private String idHolderType; /** - * 选填 + * 【选填】 * 证件类型 * 1、当证件持有人类型为法定代表人时,填写。其他情况,无需上传; * 2、个体户/企业/事业单位/社会组织:可选择任一证件类型,政府机关仅支持中国大陆居民-身份证类型。 @@ -45,7 +47,7 @@ public class WechatEntryIdentityReqDto { private String idDocType; /** - * 选填 + * 【选填】 * 法定代表人说明函 * 1、当证件持有人类型为经办人时,必须上传。其他情况,无需上传; * 2、若因特殊情况,无法提供法定代表人证件时,请参照示例图打印法定代表人说明函,全部信息需打印,不支持手写商户信息,并加盖公章; ... @@ -55,14 +57,14 @@ public class WechatEntryIdentityReqDto { private String authorizeLetterCopy; /** - * 选填 + * 【选填】 * 身份证信息 当证件持有人类型为经营者/法定代表人且证件类型为“身份证”时填写。 */ @JSONField(name = "id_card_info") private WechatEntryIdCardReqDto idCardInfo; /** - * 选填 + * 【选填】 * 其他类型证件信息 当证件持有人类型为经营者/法定代表人且证件类型不为“身份证”时填写。 */ @JSONField(name = "id_doc_info") diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryLicenseReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryLicenseReqDto.java index c13401254..c98a00d6c 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryLicenseReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryLicenseReqDto.java @@ -2,6 +2,7 @@ package com.czg.wechat.dto.req.entry.business; import com.alibaba.fastjson2.annotation.JSONField; import lombok.Data; +import lombok.experimental.Accessors; /** * 营业执照信息 @@ -9,10 +10,11 @@ import lombok.Data; * @date 2025/12/26 14:59 */ @Data +@Accessors(chain = true) public class WechatEntryLicenseReqDto { /** - * 必填 + * 【必填】 * 营业执照照片 * 1、照片应正面拍摄、清晰、四角完整、无反光或遮挡;不得翻拍、截图、镜像、PS; * 2、上传彩色照片、彩色扫描件,复印件需加盖公章鲜章; @@ -24,14 +26,14 @@ public class WechatEntryLicenseReqDto { private String licenseCopy; /** - * 必填 + * 【必填】 * 注册号/统一社会信用代码 */ @JSONField(name = "license_number") private String licenseNumber; /** - * 必填 + * 【必填】 * 商户名称 * 1、长度为2-128个字符; * 2、前后不能有空格、制表符、换行符; @@ -45,7 +47,7 @@ public class WechatEntryLicenseReqDto { private String merchantName; /** - * 必填 + * 【必填】 * 个体户经营者/法定代表人姓名 请填写营业执照的经营者/法定代表人姓名 * 1、长度为2-100个字符; * 2、前后不能有空格、制表符、换行符; @@ -56,7 +58,7 @@ public class WechatEntryLicenseReqDto { private String legalPerson; /** - * 选填 + * 【选填】 * 注册地址 建议填写营业执照的注册地址,若该字段未填写,系统将会查询国家工商信息填入。需注意若工商信息查询不到,则会被审核驳回。 * 1、长度为4-128个字符; * 2、前后不能有空格、制表符、换行符; @@ -68,7 +70,7 @@ public class WechatEntryLicenseReqDto { private String licenseAddress; /** - * 选填 + * 【选填】 * 有效期限开始日期 建议填写营业执照的有效期限开始时间,若该字段未填写,系统将会查询国家工商信息填入。需注意若工商信息查询不到,则会被审核驳回。 * 1、日期格式应满足合法的YYYY-MM-DD格式; * 2、开始时间不能小于1900-01-01; @@ -78,7 +80,7 @@ public class WechatEntryLicenseReqDto { private String periodBegin; /** - * 选填 + * 【选填】 * 营业期限结束日期 建议填写营业执照的有效期限结束时间,若该字段未填写,系统将会查询国家工商信息填入。需注意若工商信息查询不到,则会被审核驳回。 * 1、日期格式应满足合法的YYYY-MM-DD格式或长期; * 2、结束时间需大于开始时间。 diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryUboInfoReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryUboInfoReqDto.java index 3e01e0970..961fbd723 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryUboInfoReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryUboInfoReqDto.java @@ -2,6 +2,7 @@ package com.czg.wechat.dto.req.entry.business; import com.alibaba.fastjson2.annotation.JSONField; import lombok.Data; +import lombok.experimental.Accessors; /** * 最终受益人信息 @@ -9,10 +10,11 @@ import lombok.Data; * @date 2025/12/26 15:50 */ @Data +@Accessors(chain = true) public class WechatEntryUboInfoReqDto { /** - * 必填 + * 【必填】 * 证件类型 请填写受益人的证件类型。枚举值: * 可选取值 * IDENTIFICATION_TYPE_IDCARD: 中国大陆居民-身份证 @@ -40,7 +42,7 @@ public class WechatEntryUboInfoReqDto { private String uboIdDocCopy; /** - * 选填 + * 【选填】 * 证件反面照片 * 1、请上传受益人证件的反面照片; * 2、若证件类型为身份证,请上传国徽面照片; diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryAppInfoReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryAppInfoReqDto.java index c14b829be..3c2a53b6f 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryAppInfoReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryAppInfoReqDto.java @@ -2,6 +2,7 @@ package com.czg.wechat.dto.req.entry.business.sales; import com.alibaba.fastjson2.annotation.JSONField; import lombok.Data; +import lombok.experimental.Accessors; import java.util.List; @@ -11,10 +12,11 @@ import java.util.List; * @date 2025/12/26 14:26 */ @Data +@Accessors(chain = true) public class WechatEntryAppInfoReqDto { /** - * 必填 + * 【必填】 * App截图 * 1、请提供APP首页截图、尾页截图、应用内截图、支付页截图各1张; * 2、请填写通过图片上传API预先上传图片生成好的MediaID。 @@ -23,9 +25,9 @@ public class WechatEntryAppInfoReqDto { private List appPics; /** - * 选填 + * 【选填】 * 商家应用AppID - * 1、服务商应用AppID与商家应用AppID,二选一必填; + * 1、服务商应用AppID与商家应用AppID,二选一【必填】; * 2、可填写与商家主体一致且已认证的应用AppID,需是已认证的App; * 3、审核通过后,系统将发起特约商家商户号与该AppID的绑定(即配置为sub_appid),服务商随后可在发起支付时选择传入该AppID,以完成支付,并获取sub_openid用于数据统计,营销等业务场景。 */ @@ -33,9 +35,9 @@ public class WechatEntryAppInfoReqDto { private String appSubAppid; /** - * 选填 + * 【选填】 * 服务商应用AppID - * 1、服务商应用AppID与商家应用AppID,二选一必填; + * 1、服务商应用AppID与商家应用AppID,二选一【必填】; * 2、可填写当前服务商商户号已绑定的应用AppID。 */ @JSONField(name = "app_appid") diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryMiniProgramReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryMiniProgramReqDto.java index 124199c42..259d3ff9d 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryMiniProgramReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryMiniProgramReqDto.java @@ -2,6 +2,7 @@ package com.czg.wechat.dto.req.entry.business.sales; import com.alibaba.fastjson2.annotation.JSONField; import lombok.Data; +import lombok.experimental.Accessors; import java.util.List; @@ -11,10 +12,11 @@ import java.util.List; * @date 2025/12/26 14:23 */ @Data +@Accessors(chain = true) public class WechatEntryMiniProgramReqDto { /** - * 选填 + * 【选填】 * 服务商小程序AppID * 1、服务商小程序AppID与商家小程序AppID,二选一必填; * 2、可填写当前服务商商户号已绑定的小程序AppID。 @@ -23,7 +25,7 @@ public class WechatEntryMiniProgramReqDto { private String miniProgramAppid; /** - * 选填 + * 【选填】 * 商家小程序AppID * 1、服务商小程序AppID与商家小程序AppID,二选一必填; * 2、请填写已认证的小程序AppID; @@ -35,7 +37,7 @@ public class WechatEntryMiniProgramReqDto { private String miniProgramSubAppid; /** - * 选填 + * 【选填】 * 小程序截图 * 1、请提供展示商品/服务的页面截图/设计稿(最多5张),若小程序未建设完善或未上线 请务必提供; * 2、请填写通过图片上传API预先上传图片生成好的MediaID。 diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryMpInfoReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryMpInfoReqDto.java index aa419e063..e90bd0292 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryMpInfoReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryMpInfoReqDto.java @@ -2,6 +2,7 @@ package com.czg.wechat.dto.req.entry.business.sales; import com.alibaba.fastjson2.annotation.JSONField; import lombok.Data; +import lombok.experimental.Accessors; import java.util.List; @@ -11,10 +12,11 @@ import java.util.List; * @date 2025/12/26 14:20 */ @Data +@Accessors(chain = true) public class WechatEntryMpInfoReqDto { /** - * 必填 + * 【必填】 * 服务号或公众号页面截图 * 1、请提供展示商品/服务的页面截图/设计稿(最多5张),若服务号或公众号未建设完善或未上线请务必提供; * 2、请填写通过图片上传API预先上传图片生成好的MediaID。 @@ -23,9 +25,9 @@ public class WechatEntryMpInfoReqDto { private List mpPics; /** - * 选填 + * 【选填】 * 商家服务号或公众号AppID - * 1、服务商服务号或公众号AppID、商家服务号或公众号AppID,二选一必填; + * 1、服务商服务号或公众号AppID、商家服务号或公众号AppID,二选一【必填】; * 2、可填写与商家主体一致且已认证的服务号或公众号AppID,需是已认证的服务号、政府或媒体类型的公众号; * 3、审核通过后,系统将发起特约商家商户号与该AppID的绑定(即配置为sub_appid),服务商随后可在发起支付时选择传入该appid,以完成支付,并获取sub_openid用于数据统计,营销等业务场景。 */ @@ -33,9 +35,9 @@ public class WechatEntryMpInfoReqDto { private String mpSubAppid; /** - * 选填 + * 【选填】 * 服务商服务号或公众号AppID - * 1、服务商服务号或公众号AppID、商家服务号或公众号AppID,二选一必填; + * 1、服务商服务号或公众号AppID、商家服务号或公众号AppID,二选一【必填】; * 2、可填写当前服务商商户号已绑定的服务号或公众号AppID。 */ @JSONField(name = "mp_appid") diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntrySalesInfoReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntrySalesInfoReqDto.java index 00143fd84..e1547c633 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntrySalesInfoReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntrySalesInfoReqDto.java @@ -2,6 +2,7 @@ package com.czg.wechat.dto.req.entry.business.sales; import com.alibaba.fastjson2.annotation.JSONField; import lombok.Data; +import lombok.experimental.Accessors; import java.util.List; @@ -11,10 +12,11 @@ import java.util.List; * @date 2025/12/26 14:07 */ @Data +@Accessors(chain = true) public class WechatEntrySalesInfoReqDto { /** - * 必填 + * 【必填】 * 经营场景类型 * 1、请勾选实际售卖商品/提供服务场景(至少一项),以便为你开通需要的支付权限; * 2、建议只勾选目前必须的场景,以便尽快通过入驻审核,其他支付权限可在入驻后再根据实际需要发起申请 @@ -30,25 +32,25 @@ public class WechatEntrySalesInfoReqDto { private List salesScenesType; /** - * 选填 + * 【选填】 * 线下场所场景 * 1、审核通过后,服务商可帮商户发起付款码支付、JSAPI支付; - * 2、当"经营场景类型"选择"SALES_SCENES_STORE",该场景资料必填。 + * 2、当"经营场景类型"选择"SALES_SCENES_STORE",该场景资料【必填】。 */ @JSONField(name = "biz_store_info") private WechatEntryStoreInfoReqDto bizStoreInfo; /** - * 选填 + * 【选填】 * 服务号或公众号场景 * 1、审核通过后,服务商可帮商家发起JSAPI支付; - * 2、当"经营场景类型"选择"SALES_SCENES_MP",该场景资料必填。 + * 2、当"经营场景类型"选择"SALES_SCENES_MP",该场景资料【必填】。 */ @JSONField(name = "mp_info") private WechatEntryMpInfoReqDto mpInfo; /** - * 选填 + * 【选填】 * 小程序场景 * 1、审核通过后,服务商可帮商家发起JSAPI支付; * 2、当"经营场景类型"选择"SALES_SCENES_MINI_PROGRAM",该场景资料必填。 @@ -57,7 +59,7 @@ public class WechatEntrySalesInfoReqDto { private WechatEntryMiniProgramReqDto miniProgramInfo; /** - * 选填 + * 【选填】 * App场景 * 1、审核通过后,服务商可帮商家发起App支付; * 2、当"经营场景类型"选择"SALES_SCENES_APP",该场景资料必填。 @@ -66,7 +68,7 @@ public class WechatEntrySalesInfoReqDto { private WechatEntryAppInfoReqDto appInfo; /** - * 选填 + * 【选填】 * 互联网网站场景 * 1、审核通过后,服务商可帮商家发起JSAPI支付; * 2、当"经营场景类型"选择"SALES_SCENES_WEB",该场景资料必填。 @@ -75,7 +77,7 @@ public class WechatEntrySalesInfoReqDto { private WechatEntryWebInfoReqDto webInfo; /** - * 选填 + * 【选填】 * 企业微信场景 * 1、审核通过后,服务商可帮商家发起JSAPI支付; * 2、当"经营场景类型"选择"SALES_SCENES_WEWORK",该场景资料必填。 diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryStoreInfoReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryStoreInfoReqDto.java index e4c202a52..7b661eeb7 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryStoreInfoReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryStoreInfoReqDto.java @@ -2,6 +2,7 @@ package com.czg.wechat.dto.req.entry.business.sales; import com.alibaba.fastjson2.annotation.JSONField; import lombok.Data; +import lombok.experimental.Accessors; import java.util.List; @@ -11,10 +12,11 @@ import java.util.List; * @date 2025/12/26 14:10 */ @Data +@Accessors(chain = true) public class WechatEntryStoreInfoReqDto { /** - * 必填 + * 【必填】 * 线下场所名称 请填写门店名称 * 1、长度为1-50个字符; * 2、前后不能有空格、制表符、换行符; @@ -26,7 +28,7 @@ public class WechatEntryStoreInfoReqDto { private String bizStoreName; /** - * 必填 + * 【必填】 * 线下场所省市编码 * 1、只能由数字组成; * 2、详细参见微信支付提供的省市对照表。 ... @@ -35,7 +37,7 @@ public class WechatEntryStoreInfoReqDto { private String bizAddressCode; /** - * 必填 + * 【必填】 * 线下场所地址 请填写详细的经营场所信息,如有多个场所,选择一个主要场所填写即可。 * 1、长度为4-512个字符; * 2、前后不能有空格、制表符、换行符; @@ -47,7 +49,7 @@ public class WechatEntryStoreInfoReqDto { private String bizStoreAddress; /** - * 必填 + * 【必填】 * 线下场所门头照片 * 1、请上传门头正面照片(要求门店招牌、门框完整、清晰、可辨识);若为停车场等无固定门头照片的经营场所,可上传岗亭/出入闸口。具体参考【指引文档】; * 2、请填写通过图片上传API预先上传图片生成好的MediaID。 @@ -56,7 +58,7 @@ public class WechatEntryStoreInfoReqDto { private List storeEntrancePic; /** - * 必填 + * 【必填】 * 线下场所内部照片 * 1、请上传门店内部环境照片(可辨识经营内容)。若为停车场等无固定门头的经营场所,可上传停车场内部照片。具体参考【指引文档】; * 2、请填写通过图片上传API预先上传图片生成好的MediaID。 @@ -65,7 +67,7 @@ public class WechatEntryStoreInfoReqDto { private List indoorPic; /** - * 选填 + * 【选填】 * 线下场所对应的商家AppID * 1、可填写与商家主体一致且已认证的服务号或公众号、小程序、APP的AppID,其中服务号或公众号AppID需是已认证的服务号、政府或媒体类型的公众号; * 2、审核通过后,系统将额外为商家开通付款码支付、JSAPI支付的自有交易权限,并完成商家商户号与该AppID的绑定。 diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryWebInfoReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryWebInfoReqDto.java index b213f88de..6dc446d61 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryWebInfoReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryWebInfoReqDto.java @@ -2,6 +2,7 @@ package com.czg.wechat.dto.req.entry.business.sales; import com.alibaba.fastjson2.annotation.JSONField; import lombok.Data; +import lombok.experimental.Accessors; /** * 进件-经营资料-经营场景-互联网网站场景 @@ -9,10 +10,11 @@ import lombok.Data; * @date 2025/12/26 14:29 */ @Data +@Accessors(chain = true) public class WechatEntryWebInfoReqDto { /** - * 必填 + * 【必填】 * 互联网网站域名 * 1、如为PC端商城、智能终端等场景,可上传官网链接; * 2、网站域名需ICP备案,若备案主体与申请主体不同,请上传加盖公章的网站授权函。 @@ -21,7 +23,7 @@ public class WechatEntryWebInfoReqDto { private String domain; /** - * 必填 + * 【必填】 * 网站授权函 * 1、若备案主体与申请主体不同,请务必上传加盖公章的网站授权函.doc; ... * 2、请填写通过图片上传API预先上传图片生成好的MediaID。 @@ -30,7 +32,7 @@ public class WechatEntryWebInfoReqDto { private String webAuthorisation; /** - * 选填 + * 【选填】 * 互联网网站对应的商家AppID * 1、可填写已认证的服务号或公众号、小程序、APP的AppID,其中服务号或公众号AppID需是已认证的服务号、政府或媒体类型的公众号; * 2、完成进件后,系统发起特约商户号与该AppID的绑定(即配置为sub_appid,可在发起支付时传入) diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryWeworkInfoReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryWeworkInfoReqDto.java index 544e08d2e..1c4530022 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryWeworkInfoReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryWeworkInfoReqDto.java @@ -2,6 +2,7 @@ package com.czg.wechat.dto.req.entry.business.sales; import com.alibaba.fastjson2.annotation.JSONField; import lombok.Data; +import lombok.experimental.Accessors; /** * 进件-经营资料-经营场景-企业微信场景 @@ -9,10 +10,11 @@ import lombok.Data; * @date 2025/12/26 14:32 */ @Data +@Accessors(chain = true) public class WechatEntryWeworkInfoReqDto { /** - * 必填 + * 【必填】 * 商家企业微信CorpID * 1、可填写与商家主体一致且已认证的企业微信CorpID; * 2、审核通过后,系统将为商家开通企业微信专区的自有交易权限,并完成商家商户号与该AppID的绑定,商家可自行发起交易。 diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/id/WechatEntryIdCardReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/id/WechatEntryIdCardReqDto.java index 7e18cc07d..fdc203cb9 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/id/WechatEntryIdCardReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/id/WechatEntryIdCardReqDto.java @@ -2,6 +2,7 @@ package com.czg.wechat.dto.req.entry.id; import com.alibaba.fastjson2.annotation.JSONField; import lombok.Data; +import lombok.experimental.Accessors; /** * 身份证信息 @@ -9,10 +10,11 @@ import lombok.Data; * @date 2025/12/26 15:29 */ @Data +@Accessors(chain = true) public class WechatEntryIdCardReqDto { /** - * 必填 + * 【必填】 * 身份证人像面照片 * 1、请上传个体户经营者/法定代表人的身份证人像面照片; * 2、正面拍摄、清晰、四角完整、无反光或遮挡;不得翻拍、截图、镜像、PS; @@ -23,7 +25,7 @@ public class WechatEntryIdCardReqDto { private String idCardCopy; /** - * 必填 + * 【必填】 * 身份证国徽面照片 * 、请上传个体户经营者/法定代表人的身份证国徽面照片; * 2、正面拍摄、清晰、四角完整、无反光或遮挡;不得翻拍、截图、镜像、PS; @@ -34,7 +36,7 @@ public class WechatEntryIdCardReqDto { private String idCardNational; /** - * 必填 + * 【必填】 * 身份证姓名 * 1、请填写个体户经营者/法定代表人对应身份证的姓名; * 2、长度为2-100个字符; @@ -58,7 +60,7 @@ public class WechatEntryIdCardReqDto { private String idCardNumber; /** - * 选填 + * 【选填】 * 身份证居住地址 * 1、主体类型为企业时,需要填写。其他主体类型,无需上传; * 2、请按照身份证住址填写,如广东省深圳市南山区xx路xx号xx室; diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/id/WechatEntryIdDocInfoReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/id/WechatEntryIdDocInfoReqDto.java index 47e3029b7..9a959e844 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/id/WechatEntryIdDocInfoReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/id/WechatEntryIdDocInfoReqDto.java @@ -2,6 +2,7 @@ package com.czg.wechat.dto.req.entry.id; import com.alibaba.fastjson2.annotation.JSONField; import lombok.Data; +import lombok.experimental.Accessors; /** * 其他类型证件信息 @@ -9,10 +10,11 @@ import lombok.Data; * @date 2025/12/26 15:42 */ @Data +@Accessors(chain = true) public class WechatEntryIdDocInfoReqDto { /** - * 必填 + * 【必填】 * 证件正面照片 * 1、证件类型不为“身份证”时,上传证件正面照片; * 2、正面拍摄、清晰、四角完整、无反光或遮挡;不得翻拍、截图、镜像、PS; @@ -23,7 +25,7 @@ public class WechatEntryIdDocInfoReqDto { private String idDocCopy; /** - * 选填 + * 【选填】 * 证件反面照片 * 1、若证件类型为往来通行证、外国人居留证、港澳居民居住证、台湾居民居住证时,上传证件反面照片; * 2、若证件类型为护照,无需上传反面照片; @@ -35,7 +37,7 @@ public class WechatEntryIdDocInfoReqDto { private String idDocCopyBack; /** - * 必填 + * 【必填】 * 证件姓名 * 1、请填写经营者/法定代表人的证件姓名; * 2、长度为2-100个字符; @@ -48,7 +50,7 @@ public class WechatEntryIdDocInfoReqDto { private String idDocName; /** - * 必填 + * 【必填】 * 证件号码 * 1、请填写经营者/法定代表人的证件号码: * 护照(限境外人士):4-15位 数字|字母|连字符; @@ -63,7 +65,7 @@ public class WechatEntryIdDocInfoReqDto { private String idDocNumber; /** - * 选填 + * 【选填】 * 证件居住地址 * 1、主体类型为企业时,需要填写。其他主体类型,无需上传; * 2、请按照身份证住址填写,如广东省深圳市南山区xx路xx号xx室; From 38ea1478cb38a733af1d1877f8250d5da20add98 Mon Sep 17 00:00:00 2001 From: gong <1157756119@qq.com> Date: Mon, 29 Dec 2025 11:42:20 +0800 Subject: [PATCH 06/19] =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E8=AF=B7=E6=B1=82?= =?UTF-8?q?=E5=8A=A0=E5=AF=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/czg/wechat/WechatConfig.java | 4 +- .../java/com/czg/wechat/WechatEncrypt.java | 30 ++++++ .../com/czg/wechat/WechatEntryManager.java | 102 +++++++++++++++++- .../java/com/czg/wechat/WechatReqUtils.java | 87 +++++++++++++++ 4 files changed, 218 insertions(+), 5 deletions(-) create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatReqUtils.java diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatConfig.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatConfig.java index ace7aaab8..8be29a6e0 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatConfig.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatConfig.java @@ -18,7 +18,7 @@ public class WechatConfig { * @param dto 微信支付配置 * @return 微信支付配置 */ - public static Config getConfig(WechatPayConfigDto dto) { + public static Config getRsaConfig(WechatPayConfigDto dto) { return new RSAPublicKeyConfig.Builder() .merchantId(dto.getMerchantId()) .privateKey(dto.getPrivateKey()) @@ -41,7 +41,7 @@ public class WechatConfig { * @return 文件上传服务 */ public static FileUploadService getFileUploadService(WechatPayConfigDto dto) { - return getFileUploadService(getConfig(dto)); + return getFileUploadService(getRsaConfig(dto)); } } diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatEncrypt.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatEncrypt.java index 82c2cd179..edca7803b 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatEncrypt.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatEncrypt.java @@ -1,15 +1,45 @@ package com.czg.wechat; +import lombok.extern.slf4j.Slf4j; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.security.InvalidKeyException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.cert.X509Certificate; +import java.util.Base64; /** * 微信支付加解密 * @author yjjie * @date 2025/12/26 10:58 */ +@Slf4j public class WechatEncrypt { + public static String rsaEncryptOaep(String message, PublicKey publicKey) { + try { + Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding"); + cipher.init(Cipher.ENCRYPT_MODE, publicKey); + byte[] data = message.getBytes(StandardCharsets.UTF_8); + byte[] cipherData = cipher.doFinal(data); + return Base64.getEncoder().encodeToString(cipherData); + } catch (NoSuchAlgorithmException | NoSuchPaddingException e) { + log.error("当前Java环境不支持RSA v1.5/OAEP"); + } catch (InvalidKeyException e) { + log.error("无效的证书"); + } catch (IllegalBlockSizeException | BadPaddingException e) { + log.error("加密原串的长度不能超过214字节"); + } + return ""; + } + public static String getFileBytesSha256(byte[] input) throws NoSuchAlgorithmException { return bytesToHex(calculateSha256(input)); } diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatEntryManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatEntryManager.java index 85e9e7c84..7524b156c 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatEntryManager.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatEntryManager.java @@ -3,7 +3,15 @@ package com.czg.wechat; import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONWriter; import com.czg.wechat.dto.config.WechatPayConfigDto; -import com.czg.wechat.dto.req.entry.WechatEntryReqDto; +import com.czg.wechat.dto.req.entry.*; +import com.czg.wechat.dto.req.entry.business.WechatEntryBusinessReqDto; +import com.czg.wechat.dto.req.entry.business.WechatEntryIdentityReqDto; +import com.czg.wechat.dto.req.entry.business.WechatEntryLicenseReqDto; +import com.czg.wechat.dto.req.entry.business.sales.WechatEntrySalesInfoReqDto; +import com.czg.wechat.dto.req.entry.business.sales.WechatEntryStoreInfoReqDto; +import com.wechat.pay.java.core.Config; +import com.wechat.pay.java.core.cipher.PrivacyEncryptor; +import com.wechat.pay.java.core.cipher.Signer; import com.wechat.pay.java.service.file.FileUploadService; import com.wechat.pay.java.service.file.model.FileUploadResponse; import lombok.extern.slf4j.Slf4j; @@ -12,6 +20,8 @@ import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; +import java.util.Arrays; +import java.util.List; /** * 微信支付进件 管理 @@ -22,6 +32,21 @@ import java.net.http.HttpResponse; @Slf4j public class WechatEntryManager { + public static void entryMerchant(WechatPayConfigDto configDto, WechatEntryReqDto reqDto) { + String params = JSONObject.toJSONString(reqDto, JSONWriter.Feature.IgnoreEmpty); + +// String string = WechatReqUtils.encryptReqParam(configDto, "POST", "/v3/applyment4sub/applyment/", params); + + WechatReqUtils.postReq(configDto, "POST", "/v3/applyment4sub/applyment/", params); + } + + /** + * 上传图片 + * + * @param configDto 配置 + * @param url 图片URL + * @return 图片ID + */ public static String uploadImage(WechatPayConfigDto configDto, String url) { // 校验入参 if (configDto == null || url == null || url.trim().isEmpty()) { @@ -156,7 +181,78 @@ public class WechatEntryManager { // String string = uploadImage(dto, "https://czg-qr-order.oss-cn-beijing.aliyuncs.com/indexs/shuangbackground.png"); // log.info("图片上传成功:{}", string); - WechatEntryReqDto reqDto = new WechatEntryReqDto(); - System.out.println(JSONObject.toJSONString(reqDto, JSONWriter.Feature.IgnoreEmpty)); + Config config = WechatConfig.getRsaConfig(dto); + PrivacyEncryptor encryptor = config.createEncryptor(); + + WechatEntryReqDto reqDto = new WechatEntryReqDto() + .setBusinessCode("MER_20231025110010000010000000000001"); + + WechatEntryContactReqDto contactInfo = new WechatEntryContactReqDto() + .setContactType("LEGAL") + .setContactName(encryptor.encrypt("张三")) + .setContactIdType("IDCARD") + .setContactIdNumber(encryptor.encrypt("110101199001011234")) + .setContactIdDocCopy("https://czg-qr-order.oss-cn-beijing.aliyuncs.com/indexs/shuangbackground.png") + .setContactIdDocCopyBack("https://czg-qr-order.oss-cn-beijing.aliyuncs.com/indexs/shuangbackground.png") + .setContactPeriodBegin("2023-10-25") + .setContactPeriodEnd("2024-10-25") + .setMobilePhone(encryptor.encrypt("13888888888")) + .setContactEmail(encryptor.encrypt("123456@qq.com")); + + reqDto.setContactInfo(contactInfo); + + WechatEntrySubjectReqDto subjectInfo = new WechatEntrySubjectReqDto() + .setSubjectType("SUBJECT_TYPE_INDIVIDUAL"); + + WechatEntryLicenseReqDto licenseInfo = new WechatEntryLicenseReqDto() + .setLicenseCopy("https://czg-qr-order.oss-cn-beijing.aliyuncs.com/indexs/shuangbackground.png") + .setLicenseNumber("110101199001011234") + .setMerchantName("张三商行") + .setLegalPerson(encryptor.encrypt("张三")) + .setLicenseAddress("北京") + .setPeriodBegin("2023-10-25") + .setPeriodEnd("2024-10-25"); + subjectInfo.setBusinessLicenseInfo(licenseInfo); + + WechatEntryIdentityReqDto identityInfo = new WechatEntryIdentityReqDto() + .setIdHolderType("LEGAL"); + subjectInfo.setIdentityInfo(identityInfo); + + reqDto.setSubjectInfo(subjectInfo); + + WechatEntryBusinessReqDto businessInfo = new WechatEntryBusinessReqDto() + .setMerchantShortname("张三商行") + .setServicePhone("13888888888"); + WechatEntrySalesInfoReqDto salesInfo = new WechatEntrySalesInfoReqDto() + .setSalesScenesType(List.of("SALES_SCENES_STORE")); + WechatEntryStoreInfoReqDto storeInfo = new WechatEntryStoreInfoReqDto() + .setBizStoreName("张三商行") + .setBizAddressCode("110101") + .setBizStoreAddress("北京") + .setStoreEntrancePic(List.of("https://czg-qr-order.oss-cn-beijing.aliyuncs.com/indexs/shuangbackground.png")) + .setIndoorPic(List.of("https://czg-qr-order.oss-cn-beijing.aliyuncs.com/indexs/shuangbackground.png")); + salesInfo.setBizStoreInfo(storeInfo); + businessInfo.setSalesInfo(salesInfo); + + reqDto.setBusinessInfo(businessInfo); + + WechatEntrySettleReqDto settleInfo = new WechatEntrySettleReqDto() + .setSettlementId("719") + .setQualificationType("IDCARD") + .setQualifications(List.of("110101199001011234")) + .setActivitiesId("20191030111cff5b5e"); + + reqDto.setSettlementInfo(settleInfo); + + WechatEntryBankAccountReqDto bankAccountInfo = new WechatEntryBankAccountReqDto() + .setBankAccountType("BANK_ACCOUNT_TYPE_CORPORATE") + .setAccountBank("ICBC") + .setBankName("中国工商银行") + .setAccountName(encryptor.encrypt("张三")) + .setAccountNumber(encryptor.encrypt("110101199001011234")); + + reqDto.setBankAccountInfo(bankAccountInfo); + + entryMerchant(dto, reqDto); } } diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatReqUtils.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatReqUtils.java new file mode 100644 index 000000000..b92fb54fc --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatReqUtils.java @@ -0,0 +1,87 @@ +package com.czg.wechat; + +import cn.hutool.http.HttpRequest; +import cn.hutool.http.HttpUtil; +import com.czg.wechat.dto.config.WechatPayConfigDto; +import com.wechat.pay.java.core.Config; +import com.wechat.pay.java.core.RSAPublicKeyConfig; +import com.wechat.pay.java.core.cipher.PrivacyEncryptor; +import com.wechat.pay.java.core.cipher.Signer; +import lombok.extern.slf4j.Slf4j; + +import java.util.UUID; + +/** + * 微信请求工具类 + * + * @author yjjie + * @date 2025/12/29 10:02 + */ +@Slf4j +public class WechatReqUtils { + + public static String postReq(WechatPayConfigDto configDto, String method, String url, String body) { + long timestamp = getTimestamp(); + String nonce = getNonceStr(); + + String signature = encryptReqParam(configDto, method, url, body, timestamp, nonce); + + String authorization = String.format("WECHATPAY2-SHA256-RSA2048 mchid=\"%s\",nonce_str=\"%s\",signature=\"%s\",timestamp=\"%d\",serial_no=\"%s\"", + configDto.getMerchantId(), nonce, signature, timestamp, "4DE9BAC2EA584C3F274F694C9753CA814C4E9BF4"); + + log.info("authorization = {}", authorization); + + HttpRequest request = HttpUtil.createPost(configDto.getDomain() + url) + .header("Authorization", authorization) + .header("Content-Type", "application/json") + .header("Wechatpay-Serial", configDto.getPublicKeyId()) +// .header("Wechatpay-Serial", "4DE9BAC2EA584C3F274F694C9753CA814C4E9BF4") + .body(body); + + String s = request.execute().body(); + log.info("s = {}", s); + + return ""; + } + + /** + * 加密请求参数 + * @param configDto 配置 + * @param method 请求方法 + * @param url 请求地址 + * @param body 请求报文主体 + * @return 加密后的报文 + * + * 签名方法 + * HTTP请求方法\n + * URL\n + * 请求时间戳\n + * 请求随机串\n + * 请求报文主体\n + */ + public static String encryptReqParam(WechatPayConfigDto configDto, String method, String url, String body, long timestamp, String nonce) { + String encryptStr = String.format("%s\n%s\n%d\n%s\n%s\n", + method, url, timestamp, nonce, body); + System.out.println("encryptStr = \n" + encryptStr); + + Config config = WechatConfig.getRsaConfig(configDto); + Signer signer = config.createSigner(); + String signature = signer.sign(encryptStr).getSign(); + System.out.println("signature = " + signature); + return signature; + } + + /** + * 获取随机串 + */ + private static String getNonceStr() { + return UUID.randomUUID().toString().replaceAll("-", "").toUpperCase(); + } + + /** + * 获取时间戳 + */ + private static long getTimestamp() { + return System.currentTimeMillis()/1000; + } +} From 8a8cef3005abc882e1ff92be2083a67b331eaa8d Mon Sep 17 00:00:00 2001 From: gong <1157756119@qq.com> Date: Mon, 29 Dec 2025 15:30:35 +0800 Subject: [PATCH 07/19] =?UTF-8?q?=E9=83=A8=E5=88=86=E6=94=AF=E4=BB=98?= =?UTF-8?q?=E5=AE=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cash-dependencies/pom.xml | 7 +++ cash-sdk/aggregation-pay/pom.xml | 5 ++ .../com/czg/alipay/AlipayEntryManager.java | 49 +++++++++++++++++++ .../dto/AlipayCreateContactInfoDto.java | 34 +++++++++++++ .../com/czg/alipay/dto/AlipayCreateDto.java | 37 ++++++++++++++ 5 files changed, 132 insertions(+) create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/AlipayEntryManager.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/AlipayCreateContactInfoDto.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/AlipayCreateDto.java diff --git a/cash-dependencies/pom.xml b/cash-dependencies/pom.xml index cbbd275f7..a598172c8 100644 --- a/cash-dependencies/pom.xml +++ b/cash-dependencies/pom.xml @@ -43,6 +43,7 @@ 2.9.10 4.1.128.Final 0.2.17 + 3.1.65.ALL @@ -275,6 +276,12 @@ wechatpay-java ${wechatpay.version} + + + com.alipay.sdk + alipay-sdk-java-v3 + ${apipay-v3.version} + diff --git a/cash-sdk/aggregation-pay/pom.xml b/cash-sdk/aggregation-pay/pom.xml index 3df1fb396..1955b7850 100644 --- a/cash-sdk/aggregation-pay/pom.xml +++ b/cash-sdk/aggregation-pay/pom.xml @@ -25,6 +25,11 @@ com.github.wechatpay-apiv3 wechatpay-java + + + com.alipay.sdk + alipay-sdk-java-v3 + \ No newline at end of file diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/AlipayEntryManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/AlipayEntryManager.java new file mode 100644 index 000000000..db63e8645 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/AlipayEntryManager.java @@ -0,0 +1,49 @@ +package com.czg.alipay; + +import com.alipay.v3.ApiClient; +import com.alipay.v3.ApiException; +import com.alipay.v3.Configuration; +import com.alipay.v3.api.AlipayOpenAgentApi; +import com.alipay.v3.model.AlipayOpenAgentCreateDefaultResponse; +import com.alipay.v3.model.AlipayOpenAgentCreateModel; +import com.alipay.v3.model.AlipayOpenAgentCreateResponseModel; +import com.alipay.v3.model.ContactModel; +import com.alipay.v3.util.model.AlipayConfig; + +/** + * 支付宝进件管理 + * + * ... + * @author yjjie + * @date 2025/12/29 14:11 + */ +public class AlipayEntryManager { + + public static void main(String[] args) throws ApiException { + ApiClient defaultClient = Configuration.getDefaultApiClient(); + // 初始化alipay参数(全局设置一次) + AlipayConfig alipayConfig = new AlipayConfig(); + alipayConfig.setServerUrl("https://openapi.alipay.com"); + alipayConfig.setAppId("2021004174605036"); + alipayConfig.setAlipayPublicKey("MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAiQkrz+emAuS1mB3KKDOMmAZRd/BlPbh7fAIHAqAj1+QCZNcV3o2BTLIIqnuKpSlFXDG3uDzp2VsBxcizXuBbFyPGylnD9CgCj5abyh3+FIHPAZ2IM3TtpqImZ0TSPGXrMli4Nir7MvZktgccCqQKCC4o6iaDGz+UwWwJUIPna8fm2tiTZ+KH150CZbKVj4ZGNpBh5XSV/1dRgyQIV9D/EwSbkZ0n6VgKQLJBi0C2UE3QB17aL1Ir6+gDXIDbknN8O7GUD3aMGdThYdSRUb5wp9CZ5qfV7vCS/CgaRo38nhH3NOzkTL+7v0m1ZDHPmqEkn9VzZN6sCQdL7PoAOjHOCwIDAQAB"); + alipayConfig.setPrivateKey("MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQD48HaUoV7OH7os+9L01kHgxzwIhJick4OkFq4aHsntsXEJ J3gedhuEZtV8oHKZ30DPW12IJ4S8NXtpr8OWaqrAPFonf4wVaRY1d0yIAea57kfLEn9oOEEy4FzARgMNDkyxC+/3OUdGbLHpTjfVX3gusXsEhUDy1/WewihAkoNYF37+W3W/uVLzeWoPq0EcUbRv/G/t/p6gL69ltsMAiVFG4Q/Yk24YAN6lYgBPNLXUEwQ1Q+T+1omjfavHgvarKOp33z3JOUH+aGOmDsJ5Y9gyGtJzOCipAd8Zcv+T1ygsEzZYO1/gzcbPnfO1ShqStCHzssuw8FBVx2JdfQKXKMMNAgMBAAECggEAVTrO/pg5Q00titU1Jspsh67u6OOs9H605Ws2dI7yB8VmtAGlaJh7V1t14FN2qSP8poHbhhAxq9aLyGV7C3a9u09udnN+3J28EtYjh7VO732bavWMVXxdJjQWzWWrCb9JlpxFrlkYBA6W4w/6ob0sAqCVQ7jzwbEa0R4cde8ztOa5nysKSfr4YTSs0gqvoiC6fmg8eiRJraEQBoYz9VkKFtOhhh/4w5FhVcYQ2gQvZ3kK3QVuD1eJIQKlCtz8qaox9lXKDiZT4SCmnKshdUL0u5TYIcYeBjZmhJz0Q50KHcpZrCs5y7I0+vRBH3hU+TKSQt7ureymwhbwWMHScLV2gQKBgQD+58SHXhr5M8NGagAmTdsgmCnNv2kOYMd4STyPMY10SVwCv1Bk808ZuP+7e558J1b5/OuDLI5dLq6xrZ/1wLv1G++XqxI00hlFuWS5mUGJVcXotT1mw20rVeUILc7Qe3mLvbMGgfyKf4A7Qa5SSZ4bDeDTJYaFxyiQ281hMzDuPQKBgQD6AiL/Na2/uPH4CG6juwpjYvYVUcjK+7gbRwf3wWsWMpk90Z4ju2iUiP5c1J/oK9P+1T3PIr6M4Xjza8JJj+r9KC/PVB0gBv6vVM96cDpKUEy/UMpcn/T81vqj/Z+WEOODU8Ms6NiTTm+u9ldvpCjbu0u8M+9c0JeIyadJvSTFEQKBgQCsxmFyM3nq8YfpgU2qqNjfBeRH3faSVUy+nj1a/YZYjKS+A/i1BCnYUImeBVNN6chNV342ggvY4xxruDiU9Vcw8wd58O09Oi8BEIFSP6upL6cebUI6Fjo3xlegLJRiwV6INkNTJOYM5hD/mSxUACwXQFfkJipBINXBIgraWD1RLQKBgQCj49axWq0F6+WjZVOyPaD3uh37p9trRUxRhWTxw3fB23WdktaKMgbCqHOmwzP4bRLSEVQtf2dOz1gMqu14b8HqJvgAf/F/11YJ9hz09LEhmjZVjE68HZfqT7uK2W5OX8/lfXmK7TFcj6SjG5YB96lZMhTZ0WnufEd6QkdKDZYXIQKBgQD9GDTcIMbFwbEaKHnfZaTD3f876EGRgsgrCxwdEk7LBCRPwWo7yI929M4psIlpNwNeiyjBkBunWIVkpznp6qPtJqagIPUYesU4f5v6/okq5wcpaNKSkWbIvWVLaLGOiA1aeGJtbpMpyClbSr52puHpRRdvAiIEQ74yYh0JX8q96g=="); + defaultClient.setAlipayConfig(alipayConfig); + AlipayOpenAgentApi api = new AlipayOpenAgentApi(); + AlipayOpenAgentCreateModel data = new AlipayOpenAgentCreateModel(); + ContactModel contactInfo = new ContactModel(); + contactInfo.setContactEmail("zhangsan@alipy.com"); + contactInfo.setContactName("张三"); + contactInfo.setContactMobile("18866668888"); + data.setContactInfo(contactInfo); + data.setOrderTicket("00ee2d475f374ad097ee0f1ac223fX00"); + data.setAccount("test@alipay.com"); + try { + AlipayOpenAgentCreateResponseModel response = api.create(data); + System.out.println(response); + } catch (ApiException e) { + AlipayOpenAgentCreateDefaultResponse errorObject = (AlipayOpenAgentCreateDefaultResponse) e.getErrorObject(); + System.out.println("调用失败:" + errorObject); + System.out.println("调用失败:" + e.getMessage()); + } + } +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/AlipayCreateContactInfoDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/AlipayCreateContactInfoDto.java new file mode 100644 index 000000000..313506dcd --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/AlipayCreateContactInfoDto.java @@ -0,0 +1,34 @@ +package com.czg.alipay.dto; + +import com.alibaba.fastjson2.annotation.JSONField; +import lombok.Data; + +/** + * 联系人信息 + * @author yjjie + * @date 2025/12/29 14:21 + */ +@Data +public class AlipayCreateContactInfoDto { + + /** + * 【必填】 + * 联系人名称 + */ + @JSONField(name = "contact_name") + private String contactName; + + /** + * 【必填】 + * 联系人手机号 + */ + @JSONField(name = "contact_mobile") + private String contactMobile; + + /** + * 【选填】 + * 联系人邮箱 + */ + @JSONField(name = "contact_email") + private String contactEmail; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/AlipayCreateDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/AlipayCreateDto.java new file mode 100644 index 000000000..a9f9edd76 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/AlipayCreateDto.java @@ -0,0 +1,37 @@ +package com.czg.alipay.dto; + +import com.alibaba.fastjson2.annotation.JSONField; +import lombok.Data; + +/** + * 开启代商户签约、创建应用事务 + * 在 ISV 代商户进行应用创建、产品签约时,用于开启一个操作事务,必须是第一个调用的接口。 + * 场景1:ISV 代商户进行应用创建、产品签约,最后提交事务后需要商户确认才能完成流程; + * 场景2:服务市场订购及授权,使用订单授权凭证order_ticket开启预授权模式,该模式下提交事务后无需商户确认。 + * @author yjjie + * @date 2025/12/29 14:19 + */ +@Data +public class AlipayCreateDto { + + /** + * 【必填】 + * isv代操作的商户账号,可以是支付宝账号,也可以是pid(2088开头) + */ + @JSONField(name = "account") + private String account; + + /** + * 【必填】 + * 商户联系人信息,包含联系人名称、手机、邮箱信息。联系人信息将用于接受签约后的重要通知,如确认协议、到期提醒等。 + */ + @JSONField(name = "contact_info") + private AlipayCreateContactInfoDto contactInfo; + + /** + * 【选填】 + * 订单授权凭证。若传入本参数,则对应事务提交后进入预授权模式。 + */ + @JSONField(name = "order_ticket") + private String orderTicket; +} From 484c40cdb5c641498c87b689ad66a1295483831b Mon Sep 17 00:00:00 2001 From: gong <1157756119@qq.com> Date: Tue, 30 Dec 2025 10:38:45 +0800 Subject: [PATCH 08/19] =?UTF-8?q?=E8=8E=B7=E5=8F=96=E5=BE=AE=E4=BF=A1?= =?UTF-8?q?=E6=94=AF=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/czg/alipay/AlipayEntryManager.java | 6 +- .../com/czg/wechat/WechatEntryManager.java | 23 +++++-- .../java/com/czg/wechat/WechatReqUtils.java | 69 ++++++++++++------- 3 files changed, 64 insertions(+), 34 deletions(-) diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/AlipayEntryManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/AlipayEntryManager.java index db63e8645..d33793279 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/AlipayEntryManager.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/AlipayEntryManager.java @@ -13,7 +13,7 @@ import com.alipay.v3.util.model.AlipayConfig; /** * 支付宝进件管理 * - * ... + * ... * @author yjjie * @date 2025/12/29 14:11 */ @@ -24,9 +24,9 @@ public class AlipayEntryManager { // 初始化alipay参数(全局设置一次) AlipayConfig alipayConfig = new AlipayConfig(); alipayConfig.setServerUrl("https://openapi.alipay.com"); - alipayConfig.setAppId("2021004174605036"); + alipayConfig.setAppId("2021006121646825"); alipayConfig.setAlipayPublicKey("MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAiQkrz+emAuS1mB3KKDOMmAZRd/BlPbh7fAIHAqAj1+QCZNcV3o2BTLIIqnuKpSlFXDG3uDzp2VsBxcizXuBbFyPGylnD9CgCj5abyh3+FIHPAZ2IM3TtpqImZ0TSPGXrMli4Nir7MvZktgccCqQKCC4o6iaDGz+UwWwJUIPna8fm2tiTZ+KH150CZbKVj4ZGNpBh5XSV/1dRgyQIV9D/EwSbkZ0n6VgKQLJBi0C2UE3QB17aL1Ir6+gDXIDbknN8O7GUD3aMGdThYdSRUb5wp9CZ5qfV7vCS/CgaRo38nhH3NOzkTL+7v0m1ZDHPmqEkn9VzZN6sCQdL7PoAOjHOCwIDAQAB"); - alipayConfig.setPrivateKey("MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQD48HaUoV7OH7os+9L01kHgxzwIhJick4OkFq4aHsntsXEJ J3gedhuEZtV8oHKZ30DPW12IJ4S8NXtpr8OWaqrAPFonf4wVaRY1d0yIAea57kfLEn9oOEEy4FzARgMNDkyxC+/3OUdGbLHpTjfVX3gusXsEhUDy1/WewihAkoNYF37+W3W/uVLzeWoPq0EcUbRv/G/t/p6gL69ltsMAiVFG4Q/Yk24YAN6lYgBPNLXUEwQ1Q+T+1omjfavHgvarKOp33z3JOUH+aGOmDsJ5Y9gyGtJzOCipAd8Zcv+T1ygsEzZYO1/gzcbPnfO1ShqStCHzssuw8FBVx2JdfQKXKMMNAgMBAAECggEAVTrO/pg5Q00titU1Jspsh67u6OOs9H605Ws2dI7yB8VmtAGlaJh7V1t14FN2qSP8poHbhhAxq9aLyGV7C3a9u09udnN+3J28EtYjh7VO732bavWMVXxdJjQWzWWrCb9JlpxFrlkYBA6W4w/6ob0sAqCVQ7jzwbEa0R4cde8ztOa5nysKSfr4YTSs0gqvoiC6fmg8eiRJraEQBoYz9VkKFtOhhh/4w5FhVcYQ2gQvZ3kK3QVuD1eJIQKlCtz8qaox9lXKDiZT4SCmnKshdUL0u5TYIcYeBjZmhJz0Q50KHcpZrCs5y7I0+vRBH3hU+TKSQt7ureymwhbwWMHScLV2gQKBgQD+58SHXhr5M8NGagAmTdsgmCnNv2kOYMd4STyPMY10SVwCv1Bk808ZuP+7e558J1b5/OuDLI5dLq6xrZ/1wLv1G++XqxI00hlFuWS5mUGJVcXotT1mw20rVeUILc7Qe3mLvbMGgfyKf4A7Qa5SSZ4bDeDTJYaFxyiQ281hMzDuPQKBgQD6AiL/Na2/uPH4CG6juwpjYvYVUcjK+7gbRwf3wWsWMpk90Z4ju2iUiP5c1J/oK9P+1T3PIr6M4Xjza8JJj+r9KC/PVB0gBv6vVM96cDpKUEy/UMpcn/T81vqj/Z+WEOODU8Ms6NiTTm+u9ldvpCjbu0u8M+9c0JeIyadJvSTFEQKBgQCsxmFyM3nq8YfpgU2qqNjfBeRH3faSVUy+nj1a/YZYjKS+A/i1BCnYUImeBVNN6chNV342ggvY4xxruDiU9Vcw8wd58O09Oi8BEIFSP6upL6cebUI6Fjo3xlegLJRiwV6INkNTJOYM5hD/mSxUACwXQFfkJipBINXBIgraWD1RLQKBgQCj49axWq0F6+WjZVOyPaD3uh37p9trRUxRhWTxw3fB23WdktaKMgbCqHOmwzP4bRLSEVQtf2dOz1gMqu14b8HqJvgAf/F/11YJ9hz09LEhmjZVjE68HZfqT7uK2W5OX8/lfXmK7TFcj6SjG5YB96lZMhTZ0WnufEd6QkdKDZYXIQKBgQD9GDTcIMbFwbEaKHnfZaTD3f876EGRgsgrCxwdEk7LBCRPwWo7yI929M4psIlpNwNeiyjBkBunWIVkpznp6qPtJqagIPUYesU4f5v6/okq5wcpaNKSkWbIvWVLaLGOiA1aeGJtbpMpyClbSr52puHpRRdvAiIEQ74yYh0JX8q96g=="); + alipayConfig.setPrivateKey("MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCz3FkdffxZibdwis9W7eOW1dEjGAbSvRDL2ikfeCIW5KZNoIjUqxI0mIoUlLRRKO71QLHZS1Vb2aJp8jeOAqIPa8e76HTneQEzk3FGA8gpraSGvbadHWzvxnmYKsts1TBiEZQL82ySJXhQTJvZ6jyDM7s6wHHUnrH+Qi29QpppQ1sxsoJeCtajUgRg3btD6XbBcyFAX3pzM56Kw9eaIjZoD8WToZOM/Y3sqNL2uo8lLqcIpTrI7Pq5ZOspmBQ+t8v3rS9IdDZZMvd0trzS67AXwHz8rKPBT/lL1A4iHnXCHUvktusX1fPs3/RGY/a7PIddaBLnfY0GcueE16K7QcrXAgMBAAECggEAbSdT2eckp75BWoaTcGEs1tRqeM7TDT/6moyKmnOQ1K3tE31SrSYpBUxxuC3LBNo/sw2RIZtrcTOyMnPyLTgB3DP/4lUf5X51MTTQ8LnI1ypvh+pIki9Sdm3QS33lOOZk149tdpdDk6ozyx/DEcvq74EMpoo2SuAIi5LkKVDrXuehvGA/WeXtpmuPgqRFdIA+JBlA3knHk5XEQY/k2Y31gq5oCwNL9iT9OAZqVkukE6EnvCXE9t2rAV4/snYilaf/UaO+ktgEwSbPBQ8YKlovDAarMBbGtgr6E174A9djlPyR+W/fgx8rlTwSWtieb9MkO8LN3KSxgVs0kY5U8OHg8QKBgQDljJq9kTFHare+W/fAXdUy3tJprfNQCAii6s+GuDfTQiviVQDtWmdtHAN+xU3to7MepvVhwHsqtQnZXKTtZuwwxn82FNl7A5RYD3GVFW+wG6AsGLIdESrWxySoL6Kx8QmNpMEVg8acT/ywzW/RnUXS5vU7GIi8GA0vtyBo24R9KQKBgQDIlf/R9+iNk9oXlbB/k4um9eVvBBS7l5cx4E5Id5Dpp4kGZfPZEa7oDsEUstZZM9mgQLJK/noNWbcf0+BohCR5ux7SC12qIoxwN3k4BzTDqrS8BzFuVVp5PELUsf/uCbRn05iMzpiDUhj3Vde04wvjHYIobfKlZO2HeSWXCpUH/wKBgQC8wSuU6ck90pEY5QMKmZ3wYK1g3PsQOirv3Gmde+nbu7PePsuuYQJfBAQTwCZeXJezgtKP+PjOm2Nn6vhrhpB9YxvD2s0ijET1TG23i5L1myHQYNZFdJJnXgXUjqcX7v5ODMYA7QTqEBPXRnbGRK7fx66rU3dMQ/LD46+wyaFeUQKBgA4QTk53dkuu6SSsLyLSwoDjTsHY5Gc+urAZjQORtoxbXcUgEtfOYJgOqMT9wP+iHgkZYCbX7tDO0IMfxOUvFqueTgvmFhwergAUM6CVCMMLTf689l9JBr3nVrw4+rvC3G5HLLP6rEDQ2cVFtIkPPj8fS4fwJYopKGpOOS9843QbAoGBAMoHH8LqoZ50FLsospx/hJe24Cd8wCgQTXSa/hMqNZ1999JDhftMt7R0ZdB1he2LReACe0K9ntBU4H4u225zZ3wZlyOfoyerAHuLK/ysNlgIIzblZlOxbBJ64Kul8leXzlYy3tOZuZ997KqBcWPCE3LUBBNvM6E3blJUnlmJAVoi"); defaultClient.setAlipayConfig(alipayConfig); AlipayOpenAgentApi api = new AlipayOpenAgentApi(); AlipayOpenAgentCreateModel data = new AlipayOpenAgentCreateModel(); diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatEntryManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatEntryManager.java index 7524b156c..676da7552 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatEntryManager.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatEntryManager.java @@ -11,7 +11,6 @@ import com.czg.wechat.dto.req.entry.business.sales.WechatEntrySalesInfoReqDto; import com.czg.wechat.dto.req.entry.business.sales.WechatEntryStoreInfoReqDto; import com.wechat.pay.java.core.Config; import com.wechat.pay.java.core.cipher.PrivacyEncryptor; -import com.wechat.pay.java.core.cipher.Signer; import com.wechat.pay.java.service.file.FileUploadService; import com.wechat.pay.java.service.file.model.FileUploadResponse; import lombok.extern.slf4j.Slf4j; @@ -20,24 +19,34 @@ import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; -import java.util.Arrays; import java.util.List; +import java.util.Map; /** * 微信支付进件 管理 - * + * 参考地址 ... * @author yjjie * @date 2025/12/26 10:57 */ @Slf4j public class WechatEntryManager { + public static void queryBankList(WechatPayConfigDto configDto, Integer offset, Integer limit) { + WechatReqUtils.getReq(configDto, "/v3/capital/capitallhh/banks/personal-banking", Map.of("offset", offset, "limit", limit)); + } + + /** + * 商户进件 + * + * @param configDto 配置 + * @param reqDto 请求参数 + */ public static void entryMerchant(WechatPayConfigDto configDto, WechatEntryReqDto reqDto) { String params = JSONObject.toJSONString(reqDto, JSONWriter.Feature.IgnoreEmpty); -// String string = WechatReqUtils.encryptReqParam(configDto, "POST", "/v3/applyment4sub/applyment/", params); +// String string = WechatReqUtils.encryptReqParam(configDto, "/v3/applyment4sub/applyment/", params); - WechatReqUtils.postReq(configDto, "POST", "/v3/applyment4sub/applyment/", params); + WechatReqUtils.postReq(configDto, "/v3/applyment4sub/applyment/", params); } /** @@ -178,6 +187,8 @@ public class WechatEntryManager { .setPublicKeyId("PUB_KEY_ID_0116437794082025111000382377001000") .setDomain("https://api.mch.weixin.qq.com"); + queryBankList(dto, 0, 10); + // String string = uploadImage(dto, "https://czg-qr-order.oss-cn-beijing.aliyuncs.com/indexs/shuangbackground.png"); // log.info("图片上传成功:{}", string); @@ -253,6 +264,6 @@ public class WechatEntryManager { reqDto.setBankAccountInfo(bankAccountInfo); - entryMerchant(dto, reqDto); +// entryMerchant(dto, reqDto); } } diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatReqUtils.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatReqUtils.java index b92fb54fc..7a3a3c7ad 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatReqUtils.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatReqUtils.java @@ -1,15 +1,21 @@ package com.czg.wechat; +import cn.hutool.core.util.StrUtil; import cn.hutool.http.HttpRequest; import cn.hutool.http.HttpUtil; +import com.czg.exception.CzgException; import com.czg.wechat.dto.config.WechatPayConfigDto; import com.wechat.pay.java.core.Config; -import com.wechat.pay.java.core.RSAPublicKeyConfig; -import com.wechat.pay.java.core.cipher.PrivacyEncryptor; import com.wechat.pay.java.core.cipher.Signer; import lombok.extern.slf4j.Slf4j; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.Map; +import java.util.Objects; import java.util.UUID; +import java.util.stream.Collectors; /** * 微信请求工具类 @@ -20,38 +26,51 @@ import java.util.UUID; @Slf4j public class WechatReqUtils { - public static String postReq(WechatPayConfigDto configDto, String method, String url, String body) { + public static String postReq(WechatPayConfigDto configDto, String url, String body) { + return req(configDto, url, "POST", body); + } + + public static String getReq(WechatPayConfigDto configDto, String url, Map params) { + url = Arrays.stream(params.entrySet().toArray(new Map.Entry[0])) + .map(entry -> entry.getKey() + "=" + URLEncoder.encode(entry.getValue().toString(), StandardCharsets.UTF_8)) + .collect(Collectors.joining("&", url + "?", "")); + return req(configDto, url, "GET", ""); + } + + private static String req(WechatPayConfigDto configDto, String url, String method, String body) { long timestamp = getTimestamp(); String nonce = getNonceStr(); - String signature = encryptReqParam(configDto, method, url, body, timestamp, nonce); - String authorization = String.format("WECHATPAY2-SHA256-RSA2048 mchid=\"%s\",nonce_str=\"%s\",signature=\"%s\",timestamp=\"%d\",serial_no=\"%s\"", - configDto.getMerchantId(), nonce, signature, timestamp, "4DE9BAC2EA584C3F274F694C9753CA814C4E9BF4"); + configDto.getMerchantId(), nonce, signature, timestamp, configDto.getSerialNumber()); - log.info("authorization = {}", authorization); - - HttpRequest request = HttpUtil.createPost(configDto.getDomain() + url) - .header("Authorization", authorization) - .header("Content-Type", "application/json") - .header("Wechatpay-Serial", configDto.getPublicKeyId()) -// .header("Wechatpay-Serial", "4DE9BAC2EA584C3F274F694C9753CA814C4E9BF4") - .body(body); + HttpRequest request = switch (method) { + case "POST" -> HttpUtil.createPost(configDto.getDomain() + url) + .header("Authorization", authorization) + .header("Content-Type", "application/json") + .header("Wechatpay-Serial", configDto.getPublicKeyId()) + .body(body); + case "GET" -> HttpUtil.createGet(configDto.getDomain() + url) + .header("Authorization", authorization) + .header("Content-Type", "application/json") + .header("Wechatpay-Serial", configDto.getPublicKeyId()); + default -> throw new CzgException("不支持的请求方法"); + }; String s = request.execute().body(); - log.info("s = {}", s); - - return ""; + log.info("微信支付请求:url = {}, method: {}, body: {}, resp: {}", url, method, body, s); + return s; } /** * 加密请求参数 - * @param configDto 配置 - * @param method 请求方法 - * @param url 请求地址 - * @param body 请求报文主体 - * @return 加密后的报文 * + * @param configDto 配置 + * @param method 请求方法 + * @param url 请求地址 + * @param body 请求报文主体 + * @return 加密后的报文 + *

* 签名方法 * HTTP请求方法\n * URL\n @@ -62,12 +81,12 @@ public class WechatReqUtils { public static String encryptReqParam(WechatPayConfigDto configDto, String method, String url, String body, long timestamp, String nonce) { String encryptStr = String.format("%s\n%s\n%d\n%s\n%s\n", method, url, timestamp, nonce, body); - System.out.println("encryptStr = \n" + encryptStr); + log.info("encryptStr = {}", encryptStr); Config config = WechatConfig.getRsaConfig(configDto); Signer signer = config.createSigner(); String signature = signer.sign(encryptStr).getSign(); - System.out.println("signature = " + signature); + log.info("签名 signature:{}", signature); return signature; } @@ -82,6 +101,6 @@ public class WechatReqUtils { * 获取时间戳 */ private static long getTimestamp() { - return System.currentTimeMillis()/1000; + return System.currentTimeMillis() / 1000; } } From 9a1b5b5cae49baaac28abf36b4f69f92ea29287f Mon Sep 17 00:00:00 2001 From: gong <1157756119@qq.com> Date: Sun, 4 Jan 2026 10:24:35 +0800 Subject: [PATCH 09/19] =?UTF-8?q?=E6=94=AF=E4=BB=98=E5=AE=9D=E5=85=A5?= =?UTF-8?q?=E7=BD=91=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/czg/alipay/AlipayEntryManager.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/AlipayEntryManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/AlipayEntryManager.java index d33793279..74fc03406 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/AlipayEntryManager.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/AlipayEntryManager.java @@ -13,12 +13,13 @@ import com.alipay.v3.util.model.AlipayConfig; /** * 支付宝进件管理 * - * ... + * ... * @author yjjie * @date 2025/12/29 14:11 */ public class AlipayEntryManager { + // https://opendocs.alipay.com/solution/0dec7x?pathHash=caec4753 直付通 public static void main(String[] args) throws ApiException { ApiClient defaultClient = Configuration.getDefaultApiClient(); // 初始化alipay参数(全局设置一次) @@ -35,8 +36,8 @@ public class AlipayEntryManager { contactInfo.setContactName("张三"); contactInfo.setContactMobile("18866668888"); data.setContactInfo(contactInfo); - data.setOrderTicket("00ee2d475f374ad097ee0f1ac223fX00"); - data.setAccount("test@alipay.com"); +// data.setOrderTicket("00ee2d475f374ad097ee0f1ac223fX00"); + data.setAccount("1157756119@qq.com"); try { AlipayOpenAgentCreateResponseModel response = api.create(data); System.out.println(response); From 8d9878a316ed26c23306581ab629bd9f9101fc5a Mon Sep 17 00:00:00 2001 From: gong <1157756119@qq.com> Date: Sun, 4 Jan 2026 14:20:24 +0800 Subject: [PATCH 10/19] =?UTF-8?q?=E6=94=AF=E4=BB=98=E5=AE=9D=20=E5=9B=BE?= =?UTF-8?q?=E7=89=87=E4=B8=8A=E4=BC=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/czg/CommonUtil.java | 41 +++ .../java/com/czg/alipay/AlipayClient.java | 31 +++ .../com/czg/alipay/AlipayEntryManager.java | 47 +++- .../dto/AlipayCreateContactInfoDto.java | 34 --- .../com/czg/alipay/dto/AlipayCreateDto.java | 37 --- .../alipay/dto/config/AlipayConfigDto.java | 34 +++ .../alipay/dto/entry/AlipayAddressReqDto.java | 43 +++ .../dto/entry/AlipayBizCardsReqDto.java | 89 +++++++ .../dto/entry/AlipayContactInfoReqDto.java | 50 ++++ .../alipay/dto/entry/AlipayEntryReqDto.java | 249 ++++++++++++++++++ .../dto/entry/AlipayImageUploadReqDto.java | 31 +++ .../dto/entry/AlipayQualificationsReqDto.java | 30 +++ .../dto/entry/AlipaySettleRuleReqDto.java | 29 ++ .../alipay/dto/entry/AlipaySitesReqDto.java | 148 +++++++++++ .../com/czg/wechat/WechatEntryManager.java | 167 ++++++------ 15 files changed, 893 insertions(+), 167 deletions(-) create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/CommonUtil.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/AlipayClient.java delete mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/AlipayCreateContactInfoDto.java delete mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/AlipayCreateDto.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/config/AlipayConfigDto.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayAddressReqDto.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayBizCardsReqDto.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayContactInfoReqDto.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayEntryReqDto.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayImageUploadReqDto.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayQualificationsReqDto.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipaySettleRuleReqDto.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipaySitesReqDto.java diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/CommonUtil.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/CommonUtil.java new file mode 100644 index 000000000..19ab6599b --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/CommonUtil.java @@ -0,0 +1,41 @@ +package com.czg; + +import lombok.extern.slf4j.Slf4j; + +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; + +/** + * @author yjjie + * @date 2026/1/4 13:58 + */ +@Slf4j +public class CommonUtil { + /** + * 下载图片 + * @param url 图片地址 + * @return 图片字节数组 + */ + public static byte[] downloadImage(String url) { + HttpClient client = HttpClient.newHttpClient(); + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(url)) + .GET() + .build(); + + try { + HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofByteArray()); + + if (response.statusCode() != 200) { + throw new RuntimeException("Failed to download image, status code: " + response.statusCode()); + } + + return response.body(); + } catch (Exception e) { + log.error("Failed to download image: {}", e.getMessage()); + return new byte[0]; + } + } +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/AlipayClient.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/AlipayClient.java new file mode 100644 index 000000000..44991f37e --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/AlipayClient.java @@ -0,0 +1,31 @@ +package com.czg.alipay; + +import com.alipay.v3.ApiClient; +import com.alipay.v3.Configuration; +import com.alipay.v3.util.model.AlipayConfig; +import com.czg.alipay.dto.config.AlipayConfigDto; +import lombok.extern.slf4j.Slf4j; + +/** + * @author yjjie + * @date 2026/1/4 13:48 + */ +@Slf4j +public class AlipayClient { + + public static void setupAlipayConfig(AlipayConfigDto configDto) { + try { + ApiClient defaultClient = Configuration.getDefaultApiClient(); + // 初始化alipay参数(全局设置一次) + AlipayConfig alipayConfig = new AlipayConfig(); + alipayConfig.setServerUrl(configDto.getDomain()); + alipayConfig.setAppId(configDto.getAppId()); + alipayConfig.setAlipayPublicKey(configDto.getAlipayPublicKey()); + alipayConfig.setPrivateKey(configDto.getPrivateKey()); + defaultClient.setAlipayConfig(alipayConfig); + } catch (Exception e) { + log.error("初始化alipay参数异常", e); + } + + } +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/AlipayEntryManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/AlipayEntryManager.java index 74fc03406..ddce4f17a 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/AlipayEntryManager.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/AlipayEntryManager.java @@ -3,24 +3,61 @@ package com.czg.alipay; import com.alipay.v3.ApiClient; import com.alipay.v3.ApiException; import com.alipay.v3.Configuration; +import com.alipay.v3.api.AlipayMerchantImageApi; import com.alipay.v3.api.AlipayOpenAgentApi; -import com.alipay.v3.model.AlipayOpenAgentCreateDefaultResponse; -import com.alipay.v3.model.AlipayOpenAgentCreateModel; -import com.alipay.v3.model.AlipayOpenAgentCreateResponseModel; -import com.alipay.v3.model.ContactModel; +import com.alipay.v3.model.*; import com.alipay.v3.util.model.AlipayConfig; +import com.czg.CommonUtil; +import com.czg.alipay.dto.config.AlipayConfigDto; +import com.czg.alipay.dto.entry.AlipayImageUploadReqDto; +import lombok.extern.slf4j.Slf4j; + +import java.io.File; /** * 支付宝进件管理 * * ... + * * @author yjjie * @date 2025/12/29 14:11 */ +@Slf4j public class AlipayEntryManager { + public static String uploadImage() { + + byte[] bytes = CommonUtil.downloadImage("https://czg-qr-order.oss-cn-beijing.aliyuncs.com/indexs/shuangbackground.png"); + + File file = new File("/Users/yjjie/Desktop/111222.jpg"); + + AlipayMerchantImageApi api = new AlipayMerchantImageApi(); + + AlipayMerchantImageUploadModel model = new AlipayMerchantImageUploadModel(); + model.setImageType("jpg"); + try { + AlipayMerchantImageUploadResponseModel upload = api.upload(model, file); + return upload.getImageId(); + } catch (ApiException e) { + log.error("支付宝上传图片报错,URL:{},错误信息:{}", "url", e.getMessage(), e); + return ""; + } + } + + public static void main(String[] args) { + AlipayConfigDto configDto = new AlipayConfigDto() + .setDomain("https://openapi.alipay.com") + .setAppId("2021004174605036") + .setPrivateKey("MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQD48HaUoV7OH7os+9L01kHgxzwIhJick4OkFq4aHsntsXEJ J3gedhuEZtV8oHKZ30DPW12IJ4S8NXtpr8OWaqrAPFonf4wVaRY1d0yIAea57kfLEn9oOEEy4FzARgMNDkyxC+/3OUdGbLHpTjfVX3gusXsEhUDy1/WewihAkoNYF37+W3W/uVLzeWoPq0EcUbRv/G/t/p6gL69ltsMAiVFG4Q/Yk24YAN6lYgBPNLXUEwQ1Q+T+1omjfavHgvarKOp33z3JOUH+aGOmDsJ5Y9gyGtJzOCipAd8Zcv+T1ygsEzZYO1/gzcbPnfO1ShqStCHzssuw8FBVx2JdfQKXKMMNAgMBAAECggEAVTrO/pg5Q00titU1Jspsh67u6OOs9H605Ws2dI7yB8VmtAGlaJh7V1t14FN2qSP8poHbhhAxq9aLyGV7C3a9u09udnN+3J28EtYjh7VO732bavWMVXxdJjQWzWWrCb9JlpxFrlkYBA6W4w/6ob0sAqCVQ7jzwbEa0R4cde8ztOa5nysKSfr4YTSs0gqvoiC6fmg8eiRJraEQBoYz9VkKFtOhhh/4w5FhVcYQ2gQvZ3kK3QVuD1eJIQKlCtz8qaox9lXKDiZT4SCmnKshdUL0u5TYIcYeBjZmhJz0Q50KHcpZrCs5y7I0+vRBH3hU+TKSQt7ureymwhbwWMHScLV2gQKBgQD+58SHXhr5M8NGagAmTdsgmCnNv2kOYMd4STyPMY10SVwCv1Bk808ZuP+7e558J1b5/OuDLI5dLq6xrZ/1wLv1G++XqxI00hlFuWS5mUGJVcXotT1mw20rVeUILc7Qe3mLvbMGgfyKf4A7Qa5SSZ4bDeDTJYaFxyiQ281hMzDuPQKBgQD6AiL/Na2/uPH4CG6juwpjYvYVUcjK+7gbRwf3wWsWMpk90Z4ju2iUiP5c1J/oK9P+1T3PIr6M4Xjza8JJj+r9KC/PVB0gBv6vVM96cDpKUEy/UMpcn/T81vqj/Z+WEOODU8Ms6NiTTm+u9ldvpCjbu0u8M+9c0JeIyadJvSTFEQKBgQCsxmFyM3nq8YfpgU2qqNjfBeRH3faSVUy+nj1a/YZYjKS+A/i1BCnYUImeBVNN6chNV342ggvY4xxruDiU9Vcw8wd58O09Oi8BEIFSP6upL6cebUI6Fjo3xlegLJRiwV6INkNTJOYM5hD/mSxUACwXQFfkJipBINXBIgraWD1RLQKBgQCj49axWq0F6+WjZVOyPaD3uh37p9trRUxRhWTxw3fB23WdktaKMgbCqHOmwzP4bRLSEVQtf2dOz1gMqu14b8HqJvgAf/F/11YJ9hz09LEhmjZVjE68HZfqT7uK2W5OX8/lfXmK7TFcj6SjG5YB96lZMhTZ0WnufEd6QkdKDZYXIQKBgQD9GDTcIMbFwbEaKHnfZaTD3f876EGRgsgrCxwdEk7LBCRPwWo7yI929M4psIlpNwNeiyjBkBunWIVkpznp6qPtJqagIPUYesU4f5v6/okq5wcpaNKSkWbIvWVLaLGOiA1aeGJtbpMpyClbSr52puHpRRdvAiIEQ74yYh0JX8q96g==") + .setAlipayPublicKey("MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAiQkrz+emAuS1mB3KKDOMmAZRd/BlPbh7fAIHAqAj1+QCZNcV3o2BTLIIqnuKpSlFXDG3uDzp2VsBxcizXuBbFyPGylnD9CgCj5abyh3+FIHPAZ2IM3TtpqImZ0TSPGXrMli4Nir7MvZktgccCqQKCC4o6iaDGz+UwWwJUIPna8fm2tiTZ+KH150CZbKVj4ZGNpBh5XSV/1dRgyQIV9D/EwSbkZ0n6VgKQLJBi0C2UE3QB17aL1Ir6+gDXIDbknN8O7GUD3aMGdThYdSRUb5wp9CZ5qfV7vCS/CgaRo38nhH3NOzkTL+7v0m1ZDHPmqEkn9VzZN6sCQdL7PoAOjHOCwIDAQAB"); + AlipayClient.setupAlipayConfig(configDto); + + String image = uploadImage(); + System.out.println("image id = " + image); + } + // https://opendocs.alipay.com/solution/0dec7x?pathHash=caec4753 直付通 - public static void main(String[] args) throws ApiException { + public static void test() throws ApiException { ApiClient defaultClient = Configuration.getDefaultApiClient(); // 初始化alipay参数(全局设置一次) AlipayConfig alipayConfig = new AlipayConfig(); diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/AlipayCreateContactInfoDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/AlipayCreateContactInfoDto.java deleted file mode 100644 index 313506dcd..000000000 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/AlipayCreateContactInfoDto.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.czg.alipay.dto; - -import com.alibaba.fastjson2.annotation.JSONField; -import lombok.Data; - -/** - * 联系人信息 - * @author yjjie - * @date 2025/12/29 14:21 - */ -@Data -public class AlipayCreateContactInfoDto { - - /** - * 【必填】 - * 联系人名称 - */ - @JSONField(name = "contact_name") - private String contactName; - - /** - * 【必填】 - * 联系人手机号 - */ - @JSONField(name = "contact_mobile") - private String contactMobile; - - /** - * 【选填】 - * 联系人邮箱 - */ - @JSONField(name = "contact_email") - private String contactEmail; -} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/AlipayCreateDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/AlipayCreateDto.java deleted file mode 100644 index a9f9edd76..000000000 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/AlipayCreateDto.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.czg.alipay.dto; - -import com.alibaba.fastjson2.annotation.JSONField; -import lombok.Data; - -/** - * 开启代商户签约、创建应用事务 - * 在 ISV 代商户进行应用创建、产品签约时,用于开启一个操作事务,必须是第一个调用的接口。 - * 场景1:ISV 代商户进行应用创建、产品签约,最后提交事务后需要商户确认才能完成流程; - * 场景2:服务市场订购及授权,使用订单授权凭证order_ticket开启预授权模式,该模式下提交事务后无需商户确认。 - * @author yjjie - * @date 2025/12/29 14:19 - */ -@Data -public class AlipayCreateDto { - - /** - * 【必填】 - * isv代操作的商户账号,可以是支付宝账号,也可以是pid(2088开头) - */ - @JSONField(name = "account") - private String account; - - /** - * 【必填】 - * 商户联系人信息,包含联系人名称、手机、邮箱信息。联系人信息将用于接受签约后的重要通知,如确认协议、到期提醒等。 - */ - @JSONField(name = "contact_info") - private AlipayCreateContactInfoDto contactInfo; - - /** - * 【选填】 - * 订单授权凭证。若传入本参数,则对应事务提交后进入预授权模式。 - */ - @JSONField(name = "order_ticket") - private String orderTicket; -} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/config/AlipayConfigDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/config/AlipayConfigDto.java new file mode 100644 index 000000000..a39bd5478 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/config/AlipayConfigDto.java @@ -0,0 +1,34 @@ +package com.czg.alipay.dto.config; + +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * @author yjjie + * @date 2026/1/4 13:49 + */ +@Data +@Accessors(chain = true) +public class AlipayConfigDto { + + /** + * 支付宝 AppId + */ + private String appId; + + /** + * 商户私钥 + */ + private String privateKey; + + /** + * 支付宝公钥 + */ + private String alipayPublicKey; + + /** + * 支付宝支付域名 + * + */ + private String domain; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayAddressReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayAddressReqDto.java new file mode 100644 index 000000000..349d690eb --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayAddressReqDto.java @@ -0,0 +1,43 @@ +package com.czg.alipay.dto.entry; + +import com.alibaba.fastjson2.annotation.JSONField; +import lombok.Data; + +/** + * 经营地址 + * @author yjjie + * @date 2026/1/4 11:20 + */ +@Data +public class AlipayAddressReqDto { + + /** + * 【必填】 + * 城市编码 + * 蚂蚁店铺请按照蚂蚁店铺地区码 表格中填写。 + * 直付通商户请按照直付通商户地区码 表格中内容填写。 + */ + @JSONField(name = "city_code") + private String cityCode; + + /** + * 【必填】 + * 区县编码 + */ + @JSONField(name = "district_code") + private String districtCode; + + /** + * 【必填】 + * 详细地址 + */ + @JSONField(name = "address") + private String address; + + /** + * 【必填】 + * 省份编码 + */ + @JSONField(name = "province_code") + private String provinceCode; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayBizCardsReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayBizCardsReqDto.java new file mode 100644 index 000000000..319fbdb2a --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayBizCardsReqDto.java @@ -0,0 +1,89 @@ +package com.czg.alipay.dto.entry; + +import com.alibaba.fastjson2.annotation.JSONField; +import lombok.Data; + +/** + * 结算银行卡信息 + * @author yjjie + * @date 2026/1/4 11:14 + */ +@Data +public class AlipayBizCardsReqDto { + + /** + * 【必填】 + * 开户支行名 + */ + @JSONField(name = "account_branch_name") + private String accountBranchName; + + /** + * 【必填】 + * 卡户名 + */ + @JSONField(name = "account_holder_name") + private String accountHolderName; + + /** + * 【必填】 + * 开户行所在地-省 + */ + @JSONField(name = "account_inst_province") + private String accountInstProvince; + + /** + * 【必填】 + * 开户行所在地-市 + */ + @JSONField(name = "account_inst_city") + private String accountInstCity; + + /** + * 【必填】 + * 开户行简称缩写 + */ + @JSONField(name = "account_inst_id") + private String accountInstId; + + /** + * 【必填】 + * 银行名称 + */ + @JSONField(name = "account_inst_name") + private String accountInstName; + + /** + * 【必填】 + * 银行卡号 + */ + @JSONField(name = "account_no") + private String accountNo; + + /** + * 【必填】 + * 银行卡类型 + * 【枚举值】 + * 借记卡: DC + * 信用卡: CC + */ + @JSONField(name = "account_type") + private String accountType; + + /** + * 【必填】 + * 账号使用类型 + * 【枚举值】 + * 对公: 01 + * 对私: 02 + */ + @JSONField(name = "usage_type") + private String usageType; + + /** + * 【选填】 + * 联行号 + */ + @JSONField(name = "bank_code") + private String bankCode; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayContactInfoReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayContactInfoReqDto.java new file mode 100644 index 000000000..c29dc6ff0 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayContactInfoReqDto.java @@ -0,0 +1,50 @@ +package com.czg.alipay.dto.entry; + +import com.alibaba.fastjson2.annotation.JSONField; +import lombok.Data; + +/** + * 商户联系人信息 + * @author yjjie + * @date 2026/1/4 11:02 + */ +@Data +public class AlipayContactInfoReqDto { + /** + * 【必填】 + * 联系人名字 + */ + @JSONField(name = "name") + private String name; + + /** + * 【必填】 + * email | mobile | phone 三选一 + * 电子邮箱 + */ + @JSONField(name = "email") + private String email; + + /** + * 【必填】 + * email | mobile | phone 三选一 + * 手机号码 + */ + @JSONField(name = "mobile") + private String mobile; + + /** + * 【必填】 + * email | mobile | phone 三选一 + * 电话 + */ + @JSONField(name = "phone") + private String phone; + + /** + * 【必填】 + * 身份证号 + */ + @JSONField(name = "id_card_no") + private String idCardNo; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayEntryReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayEntryReqDto.java new file mode 100644 index 000000000..46fded03d --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayEntryReqDto.java @@ -0,0 +1,249 @@ +package com.czg.alipay.dto.entry; + +import com.alibaba.fastjson2.annotation.JSONField; +import lombok.Data; + +import java.util.List; + +/** + * 平台商提交二级商户资料进行进件,完成二级商户入驻 + * ... + * @author yjjie + * @date 2025/12/29 14:19 + */ +@Data +public class AlipayEntryReqDto { + + /** + * 【必填】 + * 商户编号,由一级商户定义,保证在一级商户下唯一即可 + */ + @JSONField(name = "external_id") + private String externalId; + + /** + * 【必填】 + * 商户别名。支付宝收银台及账单中的商户名称会展示此处设置的别名。如果涉及支付宝APP内的支付,支付结果页也会展示该别名;如果涉及线下当面付场景,请填写线下店铺名称 + */ + @JSONField(name = "alias_name") + private String aliasName; + + /** + * 【必填】 + * 商户联系人信息。在本业务中,ContactInfo对象中联系人姓名、手机号必填,其他选填 + */ + @JSONField(name = "contact_infos") + private AlipayContactInfoReqDto contactInfo; + + /** + * 【必填】 + * 默认结算规则。当调用收单接口,settle_info中设置默认结算规则(defaultSettle)时,交易资金将结算至此处设置的默认结算目标账户中。其详细描述及收单接口传参示例参考功能包文档 + */ + @JSONField(name = "default_settle_rule") + private AlipaySettleRuleReqDto defaultSettleRule; + + /** + * 【必填】 + * 商户使用服务 + * 可选值有:当面付、jsapi支付、app支付、wap支付、电脑支付、预授权支付、商户代扣、小程序支付、订单码支付。其值会影响其他字段必填性,详见其他字段描述 + * 当面付: 当面付 + * jsapi支付: jsapi支付 + * app支付: app支付 + * wap支付: wap支付 + * 电脑支付: 电脑支付 + * 预授权支付: 预授权支付 + * 商户代扣: 商户代扣 + * 小程序支付: 小程序支付 + * 订单码支付: 订单码支付 + */ + @JSONField(name = "service") + private List service; + + /** + * 【必填】 + * 商户证件编号 + * 按商户类型merchant_type的说明提供对应的证件编号 + */ + @JSONField(name = "cert_no") + private String certNo; + + /** + * 【必填】 + * 商户类别码 mcc + * ... + * 可查看 进件MCC与资质要求 202212.xlsx,特殊行业要按照MCC说明中的资质一栏上传辅助资质,辅助资质要在 qualifications 中上传,会有人工审核。 + * 【示例值】B0007 + */ + @JSONField(name = "mcc") + private String mcc; + + /** + * 【选填】 + * 结算支付宝账号 + * 结算账号使用支付宝账号时必填,本字段指定交易资金结算的具体支付宝账号,与binding_alipay_logon_id同主体的支付宝账号即可 + */ + @JSONField(name = "alipay_logon_id") + private String alipayLogonId; + + /** + * 【选填】 + * 法人名称 + * 非个人商户类型必填 + */ + @JSONField(name = "legal_name") + private String legalName; + + /** + * 【选填】 + * 法人证件编号 + * 法人证件编号,非个人商户类型必填 + */ + @JSONField(name = "legal_cert_no") + private String legalCertNo; + + /** + * 【选填】 + * 商户证件图 + * 目前只有当商户类型是个人商户且使用当面付服务时才需填写 + */ + @JSONField(name = "cert_image_back") + private String certImageBack; + + /** + * 【选填】 + * 商户证件图片 + * 本业务接口中,如果是特殊行业必填;使用当面付服务时,非个人必填,个人结算到卡时必填。其值为使用ant.merchant.expand.indirect.image.upload上传图片得到的一串oss key。 + */ + @JSONField(name = "cert_image") + private String certImage; + + /** + * 【选填】 + * 进件的二级商户名称 + * 一般情况下要与证件的名称相同。个体工商户类型可以放宽到法人名称 + */ + @JSONField(name = "name") + private String name; + + /** + * 【选填】 + * 法人证件类型 + * 默认可不填,认为legal_cert_no是大陆身份证。类型包括:100 大陆身份证;105 港澳居民往来内地通行证;106 台湾同胞往来大陆通行证;108 外国人居留证 + * 【枚举值】 + * 大陆身份证: 100 + * 港澳居民往来内地通行证: 105 + * 台湾同胞往来大陆通行证: 106 + * 外国人居留证: 108 + */ + @JSONField(name = "legal_cert_type") + private String legalCertType; + + /** + * 【选填】 + * 商户类型 + * 01:企业;cert_type填写201(营业执照);cert_no填写营业执照号; + * 02:事业单位:cert_type填写218(事业单位法人证书);cert_no填写事业单位法人证书编号; + * 03:民办非企业组织:cert_type填写204(民办非企业登记证书);cert_no填写民办非企业登记证书编号; + * 04:社会团体:cert_type填写206(社会团体法人登记证书);cert_no填写社会团体法人登记证书编号; + * 05:党政及国家机关:cert_type填写219(党政机关批准设立文件/行政执法主体资格证);cert_no填写党政机关批准设立文件/行政执法主体资格证编号; + * 06:个人商户:cert_type填写100(个人身份证);cert_no填写个人身份证号码; + * 07:个体工商户:cert_type填写201(营业执照);cert_no填写营业执照编号; + */ + @JSONField(name = "merchant_type") + private String merchantType; + + /** + * 【选填】 + * 商户证件类型 + * 按商户类型merchant_type的说明提供对应的证件类型。 + * 营业执照: 201 + * 事业单位法人证书: 218 + * 民办非企业登记证书: 204 + * 社会团体法人登记证书: 206 + * 党政机关批准设立文件/行政执法主体资格证: 219 + * 个人身份证: 100 + */ + @JSONField(name = "cert_type") + private String certType; + + /** + * 【选填】 + * 证件名称 + * 目前只有个体工商户商户类型要求填入本字段,填写值为个体工商户营业执照上的名称 + */ + @JSONField(name = "cert_name") + private String certName; + + /** + * 【选填】 + * 结算银行卡信息 + * 结算银行卡信息,结算账号使用银行卡时必填。本业务当前只允许传入一张结算卡。个人类型商户不允许结算到银行卡 + * 【必选条件】结算银行卡信息,结算账号使用银行卡时必填。本业务当前只允许传入一张结算卡。个人类型商户不允许结算到银行卡 + */ + @JSONField(name = "biz_cards") + private AlipayBizCardsReqDto bizCards; + + /** + * 【选填】 + * 经营地址 + * 使用当面付服务时必填。地址对象中省、市、区、地址必填,其余选填 + */ + @JSONField(name = "business_address") + private AlipayAddressReqDto businessAddress; + + /** + * 【选填】 + * 门头照 + * 使用当面付服务时必填。其值为使用ant.merchant.expand.indirect.image.upload上传图片得到的一串oss key + */ + @JSONField(name = "out_door_images") + private String outDoorImages; + + /** + * 【选填】 + * 内景照 + * 使用当面付服务时必填。其值为使用ant.merchant.expand.indirect.image.upload上传图片得到的一串oss key + */ + @JSONField(name = "in_door_images") + private String inDoorImages; + + /** + * 【选填】 + * 授权函 + * 《说明函》模板参考 + * 当商户名与结算卡户名不一致。《说明函》模板参考。涉及外籍法人(这种情况上传任意能证明身份的图片)时必填, + * 其值为使用ant.merchant.expand.indirect.image.upload上传图片得到的一串oss key。(商户类型为个体工商户时,本字段仅需上传营业执照非授权函) + */ + @JSONField(name = "license_auth_letter_image") + private String licenseAuthLetterImage; + + /** + * 【选填】 + * 商户站点信息 + * 包括网站、app、小程序。商户使用服务包含电脑支付、wap支付时,必须填充一个类型为01(网站)的SiteInfo对象,site_type/site_url/site_name必填; + * 当包含app支付时,必须至少填充类型为02(APP)或06(支付宝小程序)中一种类型的SiteInfo对象,site_type/site_name必填;当包含jsapi支付时,必须填充一个类型为06(支付宝小程序)的SiteInfo对象; + */ + @JSONField(name = "sites") + private AlipaySitesReqDto sites; + + /** + * 【选填】 + * 商户行业资质图片 + * 当商户的经营类目选择了特殊行业时该字段必填,需要特殊行业资质文件。每项行业资质信息中,industry_qualification_type和industry_qualification_image均必填。 + */ + @JSONField(name = "qualifications") + private List qualifications; + + /** + * 【选填】 + * 交易场景 + * 【枚举值】 + * 小程序支付场景: TINY_APP + * H5场景: WAP + * 线下当面付场景: OFFLINE + * APP支付场景: APP + * 网站支付场景: PC + */ + @JSONField(name = "trade_scene") + private List tradeScene; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayImageUploadReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayImageUploadReqDto.java new file mode 100644 index 000000000..a2abcc34e --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayImageUploadReqDto.java @@ -0,0 +1,31 @@ +package com.czg.alipay.dto.entry; + +import com.alibaba.fastjson2.annotation.JSONField; +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * 图片上传 + * @author yjjie + * @date 2026/1/4 13:46 + */ +@Data +@Accessors(chain = true) +public class AlipayImageUploadReqDto { + + /** + * 【必填】 + * 图片格式 + * 支持格式:bmp、jpg、jpeg、png、gif. + */ + @JSONField(name = "image_type") + private String imageType; + + /** + * 【必填】 + * 图片二进制字节流 + * 最大为10M + */ + @JSONField(name = "image_content") + private byte[] imageContent; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayQualificationsReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayQualificationsReqDto.java new file mode 100644 index 000000000..6e4190027 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayQualificationsReqDto.java @@ -0,0 +1,30 @@ +package com.czg.alipay.dto.entry; + +import com.alibaba.fastjson2.annotation.JSONField; +import lombok.Data; + +/** + * 商户行业资质 + * @author yjjie + * @date 2026/1/4 11:40 + */ +@Data +public class AlipayQualificationsReqDto { + + /** + * 【必填】 + * 商户行业资质类型 具体选值参见 文档 + * 【枚举值】 + * 金融许可证: 323 + * 【示例值】323 + */ + @JSONField(name = "industry_qualification_type") + private String industryQualificationType; + + /** + * 【必填】 + * 商户行业资质图片 + */ + @JSONField(name = "industry_qualification_image") + private String industryQualificationImage; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipaySettleRuleReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipaySettleRuleReqDto.java new file mode 100644 index 000000000..75881a854 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipaySettleRuleReqDto.java @@ -0,0 +1,29 @@ +package com.czg.alipay.dto.entry; + +import com.alibaba.fastjson2.annotation.JSONField; +import lombok.Data; + +/** + * 结算规则 + * @author yjjie + * @date 2026/1/4 11:06 + */ +@Data +public class AlipaySettleRuleReqDto { + + /** + * 【必填】 + * 默认结算类型 + * 可选值有bankCard/alipayAccount。bankCard表示结算到银行卡;alipayAccount表示结算到支付宝账号 + */ + @JSONField(name = "default_settle_type") + private String defaultSettleType; + + /** + * 【必填】 + * 默认结算目标 + * 当默认结算类型为bankCard时填写银行卡卡号,其值需在进件填写的结算银行卡范围内;当默认结算类型为alipayAccount时填写支付宝账号登录号,其值需在进件填写的结算支付宝账号范围内。 + */ + @JSONField(name = "default_settle_target") + private String defaultSettleTarget; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipaySitesReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipaySitesReqDto.java new file mode 100644 index 000000000..0e88ad25d --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipaySitesReqDto.java @@ -0,0 +1,148 @@ +package com.czg.alipay.dto.entry; + +import com.alibaba.fastjson2.annotation.JSONField; +import lombok.Data; + +/** + * @author yjjie + * @date 2026/1/4 11:31 + */ +@Data +public class AlipaySitesReqDto { + + /** + * 【必填】 + * 网站类型 + * 【枚举值】 + * 网站: 01 + * APP: 02 + * 服务窗: 03 + * 公众号: 04 + * 其他: 05 + * 支付宝小程序: 06 + * 手机网站/H5: 07 + */ + @JSONField(name = "site_type") + private String siteType; + + /** + * 【选填】 + * 站点地址 + * 当传入service,且包含jsapi支付时,sites的site_type=06, site_url必填 + */ + @JSONField(name = "site_url") + private String siteUrl; + + /** + * 【选填】 + * 站点名称 + * 当传入service,且包含jsapi支付、小程序支付时,sites的site_type=06, site_name必填 + */ + @JSONField(name = "site_name") + private String siteName; + + /** + * 【选填】 + * 截图照片 + * 当传入交易场景trade_scene,且当传入trade_scene=WAP、trade_scene=APP、trade_scene=PC时该参数必传 + */ + @JSONField(name = "screenshot_image") + private String screenshotImage; + + /** + * 【选填】 + * 小程序appId + * 当传入service,且包含jsapi支付时,sites的site_type=06, tiny_app_id必填。 + */ + @JSONField(name = "tiny_app_id") + private String tinyAppId; + + /** + * 【选填】 + * 测试账号 + */ + @JSONField(name = "account") + private String account; + + /** + * 【选填】 + * 测试账号密码 + */ + @JSONField(name = "password") + private String password; + + /** + * 【选填】 + * 上架状态 + * 【枚举值】 + * 已上线: ONLINE + * 已上线-内部: ONLINE_INNER + * 未上线: OFFLINE + */ + @JSONField(name = "status") + private String status; + + /** + * 【选填】 + * 授权函照片 + */ + @JSONField(name = "auth_letter_image") + private String authLetterImage; + + /** + * 【选填】 + * 备注说明 + */ + @JSONField(name = "remark") + private String remark; + + /** + * 【选填】 + * 备注说明图片 + */ + @JSONField(name = "remark_image") + private String remarkImage; + + /** + * 【选填】 + * 网站域名 + */ + @JSONField(name = "site_domain") + private String siteDomain; + + /** + * 【选填】 + * ICP备案主体信息服务名称 + */ + @JSONField(name = "icp_service_name") + private String icpServiceName; + + /** + * 【选填】 + * ICP备案/许可证号 + */ + @JSONField(name = "icp_no") + private String icpNo; + + /** + * 【选填】 + * ICP备案主体主办单位名称 + */ + @JSONField(name = "icp_org_name") + private String icpOrgName; + + /** + * 【选填】 + * 下载地址 + */ + @JSONField(name = "download") + private String download; + + /** + * 【选填】 + * 应用市场 + * 【示例值】豌豆荚 + */ + @JSONField(name = "market") + private String market; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatEntryManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatEntryManager.java index 676da7552..43dc5f8f3 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatEntryManager.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatEntryManager.java @@ -2,6 +2,7 @@ package com.czg.wechat; import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONWriter; +import com.czg.CommonUtil; import com.czg.wechat.dto.config.WechatPayConfigDto; import com.czg.wechat.dto.req.entry.*; import com.czg.wechat.dto.req.entry.business.WechatEntryBusinessReqDto; @@ -67,7 +68,7 @@ public class WechatEntryManager { try { // 获取图片字节数组 - byte[] bytes = downloadImage(url); + byte[] bytes = CommonUtil.downloadImage(url); if (bytes.length == 0) { log.error("下载的图片内容为空,URL:{}", url); return ""; @@ -98,22 +99,6 @@ public class WechatEntryManager { return ""; } - public static byte[] downloadImage(String url) throws Exception { - HttpClient client = HttpClient.newHttpClient(); - HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create(url)) - .GET() - .build(); - - HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofByteArray()); - - if (response.statusCode() != 200) { - throw new RuntimeException("Failed to download image, status code: " + response.statusCode()); - } - - return response.body(); - } - /** * 从URL中提取文件名 * @@ -187,82 +172,82 @@ public class WechatEntryManager { .setPublicKeyId("PUB_KEY_ID_0116437794082025111000382377001000") .setDomain("https://api.mch.weixin.qq.com"); - queryBankList(dto, 0, 10); +// queryBankList(dto, 0, 10); -// String string = uploadImage(dto, "https://czg-qr-order.oss-cn-beijing.aliyuncs.com/indexs/shuangbackground.png"); -// log.info("图片上传成功:{}", string); + String string = uploadImage(dto, "https://czg-qr-order.oss-cn-beijing.aliyuncs.com/indexs/shuangbackground.png"); + log.info("图片上传成功:{}", string); - Config config = WechatConfig.getRsaConfig(dto); - PrivacyEncryptor encryptor = config.createEncryptor(); - - WechatEntryReqDto reqDto = new WechatEntryReqDto() - .setBusinessCode("MER_20231025110010000010000000000001"); - - WechatEntryContactReqDto contactInfo = new WechatEntryContactReqDto() - .setContactType("LEGAL") - .setContactName(encryptor.encrypt("张三")) - .setContactIdType("IDCARD") - .setContactIdNumber(encryptor.encrypt("110101199001011234")) - .setContactIdDocCopy("https://czg-qr-order.oss-cn-beijing.aliyuncs.com/indexs/shuangbackground.png") - .setContactIdDocCopyBack("https://czg-qr-order.oss-cn-beijing.aliyuncs.com/indexs/shuangbackground.png") - .setContactPeriodBegin("2023-10-25") - .setContactPeriodEnd("2024-10-25") - .setMobilePhone(encryptor.encrypt("13888888888")) - .setContactEmail(encryptor.encrypt("123456@qq.com")); - - reqDto.setContactInfo(contactInfo); - - WechatEntrySubjectReqDto subjectInfo = new WechatEntrySubjectReqDto() - .setSubjectType("SUBJECT_TYPE_INDIVIDUAL"); - - WechatEntryLicenseReqDto licenseInfo = new WechatEntryLicenseReqDto() - .setLicenseCopy("https://czg-qr-order.oss-cn-beijing.aliyuncs.com/indexs/shuangbackground.png") - .setLicenseNumber("110101199001011234") - .setMerchantName("张三商行") - .setLegalPerson(encryptor.encrypt("张三")) - .setLicenseAddress("北京") - .setPeriodBegin("2023-10-25") - .setPeriodEnd("2024-10-25"); - subjectInfo.setBusinessLicenseInfo(licenseInfo); - - WechatEntryIdentityReqDto identityInfo = new WechatEntryIdentityReqDto() - .setIdHolderType("LEGAL"); - subjectInfo.setIdentityInfo(identityInfo); - - reqDto.setSubjectInfo(subjectInfo); - - WechatEntryBusinessReqDto businessInfo = new WechatEntryBusinessReqDto() - .setMerchantShortname("张三商行") - .setServicePhone("13888888888"); - WechatEntrySalesInfoReqDto salesInfo = new WechatEntrySalesInfoReqDto() - .setSalesScenesType(List.of("SALES_SCENES_STORE")); - WechatEntryStoreInfoReqDto storeInfo = new WechatEntryStoreInfoReqDto() - .setBizStoreName("张三商行") - .setBizAddressCode("110101") - .setBizStoreAddress("北京") - .setStoreEntrancePic(List.of("https://czg-qr-order.oss-cn-beijing.aliyuncs.com/indexs/shuangbackground.png")) - .setIndoorPic(List.of("https://czg-qr-order.oss-cn-beijing.aliyuncs.com/indexs/shuangbackground.png")); - salesInfo.setBizStoreInfo(storeInfo); - businessInfo.setSalesInfo(salesInfo); - - reqDto.setBusinessInfo(businessInfo); - - WechatEntrySettleReqDto settleInfo = new WechatEntrySettleReqDto() - .setSettlementId("719") - .setQualificationType("IDCARD") - .setQualifications(List.of("110101199001011234")) - .setActivitiesId("20191030111cff5b5e"); - - reqDto.setSettlementInfo(settleInfo); - - WechatEntryBankAccountReqDto bankAccountInfo = new WechatEntryBankAccountReqDto() - .setBankAccountType("BANK_ACCOUNT_TYPE_CORPORATE") - .setAccountBank("ICBC") - .setBankName("中国工商银行") - .setAccountName(encryptor.encrypt("张三")) - .setAccountNumber(encryptor.encrypt("110101199001011234")); - - reqDto.setBankAccountInfo(bankAccountInfo); +// Config config = WechatConfig.getRsaConfig(dto); +// PrivacyEncryptor encryptor = config.createEncryptor(); +// +// WechatEntryReqDto reqDto = new WechatEntryReqDto() +// .setBusinessCode("MER_20231025110010000010000000000001"); +// +// WechatEntryContactReqDto contactInfo = new WechatEntryContactReqDto() +// .setContactType("LEGAL") +// .setContactName(encryptor.encrypt("张三")) +// .setContactIdType("IDCARD") +// .setContactIdNumber(encryptor.encrypt("110101199001011234")) +// .setContactIdDocCopy("https://czg-qr-order.oss-cn-beijing.aliyuncs.com/indexs/shuangbackground.png") +// .setContactIdDocCopyBack("https://czg-qr-order.oss-cn-beijing.aliyuncs.com/indexs/shuangbackground.png") +// .setContactPeriodBegin("2023-10-25") +// .setContactPeriodEnd("2024-10-25") +// .setMobilePhone(encryptor.encrypt("13888888888")) +// .setContactEmail(encryptor.encrypt("123456@qq.com")); +// +// reqDto.setContactInfo(contactInfo); +// +// WechatEntrySubjectReqDto subjectInfo = new WechatEntrySubjectReqDto() +// .setSubjectType("SUBJECT_TYPE_INDIVIDUAL"); +// +// WechatEntryLicenseReqDto licenseInfo = new WechatEntryLicenseReqDto() +// .setLicenseCopy("https://czg-qr-order.oss-cn-beijing.aliyuncs.com/indexs/shuangbackground.png") +// .setLicenseNumber("110101199001011234") +// .setMerchantName("张三商行") +// .setLegalPerson(encryptor.encrypt("张三")) +// .setLicenseAddress("北京") +// .setPeriodBegin("2023-10-25") +// .setPeriodEnd("2024-10-25"); +// subjectInfo.setBusinessLicenseInfo(licenseInfo); +// +// WechatEntryIdentityReqDto identityInfo = new WechatEntryIdentityReqDto() +// .setIdHolderType("LEGAL"); +// subjectInfo.setIdentityInfo(identityInfo); +// +// reqDto.setSubjectInfo(subjectInfo); +// +// WechatEntryBusinessReqDto businessInfo = new WechatEntryBusinessReqDto() +// .setMerchantShortname("张三商行") +// .setServicePhone("13888888888"); +// WechatEntrySalesInfoReqDto salesInfo = new WechatEntrySalesInfoReqDto() +// .setSalesScenesType(List.of("SALES_SCENES_STORE")); +// WechatEntryStoreInfoReqDto storeInfo = new WechatEntryStoreInfoReqDto() +// .setBizStoreName("张三商行") +// .setBizAddressCode("110101") +// .setBizStoreAddress("北京") +// .setStoreEntrancePic(List.of("https://czg-qr-order.oss-cn-beijing.aliyuncs.com/indexs/shuangbackground.png")) +// .setIndoorPic(List.of("https://czg-qr-order.oss-cn-beijing.aliyuncs.com/indexs/shuangbackground.png")); +// salesInfo.setBizStoreInfo(storeInfo); +// businessInfo.setSalesInfo(salesInfo); +// +// reqDto.setBusinessInfo(businessInfo); +// +// WechatEntrySettleReqDto settleInfo = new WechatEntrySettleReqDto() +// .setSettlementId("719") +// .setQualificationType("IDCARD") +// .setQualifications(List.of("110101199001011234")) +// .setActivitiesId("20191030111cff5b5e"); +// +// reqDto.setSettlementInfo(settleInfo); +// +// WechatEntryBankAccountReqDto bankAccountInfo = new WechatEntryBankAccountReqDto() +// .setBankAccountType("BANK_ACCOUNT_TYPE_CORPORATE") +// .setAccountBank("ICBC") +// .setBankName("中国工商银行") +// .setAccountName(encryptor.encrypt("张三")) +// .setAccountNumber(encryptor.encrypt("110101199001011234")); +// +// reqDto.setBankAccountInfo(bankAccountInfo); // entryMerchant(dto, reqDto); } From 7efc46126cb3a02c4ff7b0daf4295465359fb603 Mon Sep 17 00:00:00 2001 From: gong <1157756119@qq.com> Date: Tue, 6 Jan 2026 10:29:34 +0800 Subject: [PATCH 11/19] =?UTF-8?q?=E5=B0=81=E8=A3=85=E5=85=A5=E7=BD=91dto?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/czg/dto/AggregateMerchantDto.java | 49 ++++ .../com/czg/dto/BusinessLicenceInfoDto.java | 42 ++++ .../java/com/czg/dto/LegalPersonInfoDto.java | 68 ++++++ .../java/com/czg/dto/MerchantBaseInfoDto.java | 75 ++++++ .../java/com/czg/dto/SettlementInfoDto.java | 132 +++++++++++ .../main/java/com/czg/dto/StoreInfoDto.java | 66 ++++++ .../czg/{ => third}/alipay/AlipayClient.java | 4 +- .../alipay/AlipayEntryManager.java | 92 ++++++-- .../com/czg/third/alipay/AlipayReqUtils.java | 223 ++++++++++++++++++ .../alipay/dto/config/AlipayConfigDto.java | 2 +- .../alipay/dto/entry/AlipayAddressReqDto.java | 2 +- .../dto/entry/AlipayBizCardsReqDto.java | 2 +- .../dto/entry/AlipayContactInfoReqDto.java | 2 +- .../alipay/dto/entry/AlipayEntryReqDto.java | 2 +- .../dto/entry/AlipayImageUploadReqDto.java | 2 +- .../dto/entry/AlipayQualificationsReqDto.java | 2 +- .../dto/entry/AlipaySettleRuleReqDto.java | 2 +- .../alipay/dto/entry/AlipaySitesReqDto.java | 2 +- .../czg/{ => third}/wechat/WechatConfig.java | 4 +- .../czg/{ => third}/wechat/WechatEncrypt.java | 2 +- .../wechat/WechatEntryManager.java | 20 +- .../{ => third}/wechat/WechatPayManager.java | 2 +- .../{ => third}/wechat/WechatReqUtils.java | 6 +- .../wechat/dto/config/WechatPayConfigDto.java | 2 +- .../req/entry/WechatEntryAdditionReqDto.java | 2 +- .../entry/WechatEntryBankAccountReqDto.java | 2 +- .../req/entry/WechatEntryContactReqDto.java | 2 +- .../dto/req/entry/WechatEntryReqDto.java | 4 +- .../req/entry/WechatEntrySettleReqDto.java | 2 +- .../req/entry/WechatEntrySubjectReqDto.java | 4 +- .../business/WechatEntryBusinessReqDto.java | 4 +- .../WechatEntryCertificateReqDto.java | 2 +- .../WechatEntryFinanceInstitutionReqDto.java | 2 +- .../business/WechatEntryIdentityReqDto.java | 6 +- .../business/WechatEntryLicenseReqDto.java | 2 +- .../business/WechatEntryUboInfoReqDto.java | 2 +- .../sales/WechatEntryAppInfoReqDto.java | 2 +- .../sales/WechatEntryMiniProgramReqDto.java | 2 +- .../sales/WechatEntryMpInfoReqDto.java | 2 +- .../sales/WechatEntrySalesInfoReqDto.java | 2 +- .../sales/WechatEntryStoreInfoReqDto.java | 2 +- .../sales/WechatEntryWebInfoReqDto.java | 2 +- .../sales/WechatEntryWeworkInfoReqDto.java | 2 +- .../req/entry/id/WechatEntryIdCardReqDto.java | 2 +- .../entry/id/WechatEntryIdDocInfoReqDto.java | 2 +- .../java/com/czg/{ => utils}/CommonUtil.java | 2 +- 46 files changed, 776 insertions(+), 83 deletions(-) create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/dto/AggregateMerchantDto.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/dto/BusinessLicenceInfoDto.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/dto/LegalPersonInfoDto.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/dto/MerchantBaseInfoDto.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/dto/SettlementInfoDto.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/dto/StoreInfoDto.java rename cash-sdk/aggregation-pay/src/main/java/com/czg/{ => third}/alipay/AlipayClient.java (91%) rename cash-sdk/aggregation-pay/src/main/java/com/czg/{ => third}/alipay/AlipayEntryManager.java (66%) create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayReqUtils.java rename cash-sdk/aggregation-pay/src/main/java/com/czg/{ => third}/alipay/dto/config/AlipayConfigDto.java (92%) rename cash-sdk/aggregation-pay/src/main/java/com/czg/{ => third}/alipay/dto/entry/AlipayAddressReqDto.java (95%) rename cash-sdk/aggregation-pay/src/main/java/com/czg/{ => third}/alipay/dto/entry/AlipayBizCardsReqDto.java (97%) rename cash-sdk/aggregation-pay/src/main/java/com/czg/{ => third}/alipay/dto/entry/AlipayContactInfoReqDto.java (95%) rename cash-sdk/aggregation-pay/src/main/java/com/czg/{ => third}/alipay/dto/entry/AlipayEntryReqDto.java (99%) rename cash-sdk/aggregation-pay/src/main/java/com/czg/{ => third}/alipay/dto/entry/AlipayImageUploadReqDto.java (93%) rename cash-sdk/aggregation-pay/src/main/java/com/czg/{ => third}/alipay/dto/entry/AlipayQualificationsReqDto.java (94%) rename cash-sdk/aggregation-pay/src/main/java/com/czg/{ => third}/alipay/dto/entry/AlipaySettleRuleReqDto.java (95%) rename cash-sdk/aggregation-pay/src/main/java/com/czg/{ => third}/alipay/dto/entry/AlipaySitesReqDto.java (98%) rename cash-sdk/aggregation-pay/src/main/java/com/czg/{ => third}/wechat/WechatConfig.java (93%) rename cash-sdk/aggregation-pay/src/main/java/com/czg/{ => third}/wechat/WechatEncrypt.java (98%) rename cash-sdk/aggregation-pay/src/main/java/com/czg/{ => third}/wechat/WechatEntryManager.java (93%) rename cash-sdk/aggregation-pay/src/main/java/com/czg/{ => third}/wechat/WechatPayManager.java (82%) rename cash-sdk/aggregation-pay/src/main/java/com/czg/{ => third}/wechat/WechatReqUtils.java (96%) rename cash-sdk/aggregation-pay/src/main/java/com/czg/{ => third}/wechat/dto/config/WechatPayConfigDto.java (94%) rename cash-sdk/aggregation-pay/src/main/java/com/czg/{ => third}/wechat/dto/req/entry/WechatEntryAdditionReqDto.java (96%) rename cash-sdk/aggregation-pay/src/main/java/com/czg/{ => third}/wechat/dto/req/entry/WechatEntryBankAccountReqDto.java (98%) rename cash-sdk/aggregation-pay/src/main/java/com/czg/{ => third}/wechat/dto/req/entry/WechatEntryContactReqDto.java (99%) rename cash-sdk/aggregation-pay/src/main/java/com/czg/{ => third}/wechat/dto/req/entry/WechatEntryReqDto.java (92%) rename cash-sdk/aggregation-pay/src/main/java/com/czg/{ => third}/wechat/dto/req/entry/WechatEntrySettleReqDto.java (98%) rename cash-sdk/aggregation-pay/src/main/java/com/czg/{ => third}/wechat/dto/req/entry/WechatEntrySubjectReqDto.java (97%) rename cash-sdk/aggregation-pay/src/main/java/com/czg/{ => third}/wechat/dto/req/entry/business/WechatEntryBusinessReqDto.java (92%) rename cash-sdk/aggregation-pay/src/main/java/com/czg/{ => third}/wechat/dto/req/entry/business/WechatEntryCertificateReqDto.java (98%) rename cash-sdk/aggregation-pay/src/main/java/com/czg/{ => third}/wechat/dto/req/entry/business/WechatEntryFinanceInstitutionReqDto.java (97%) rename cash-sdk/aggregation-pay/src/main/java/com/czg/{ => third}/wechat/dto/req/entry/business/WechatEntryIdentityReqDto.java (94%) rename cash-sdk/aggregation-pay/src/main/java/com/czg/{ => third}/wechat/dto/req/entry/business/WechatEntryLicenseReqDto.java (98%) rename cash-sdk/aggregation-pay/src/main/java/com/czg/{ => third}/wechat/dto/req/entry/business/WechatEntryUboInfoReqDto.java (98%) rename cash-sdk/aggregation-pay/src/main/java/com/czg/{ => third}/wechat/dto/req/entry/business/sales/WechatEntryAppInfoReqDto.java (96%) rename cash-sdk/aggregation-pay/src/main/java/com/czg/{ => third}/wechat/dto/req/entry/business/sales/WechatEntryMiniProgramReqDto.java (96%) rename cash-sdk/aggregation-pay/src/main/java/com/czg/{ => third}/wechat/dto/req/entry/business/sales/WechatEntryMpInfoReqDto.java (96%) rename cash-sdk/aggregation-pay/src/main/java/com/czg/{ => third}/wechat/dto/req/entry/business/sales/WechatEntrySalesInfoReqDto.java (97%) rename cash-sdk/aggregation-pay/src/main/java/com/czg/{ => third}/wechat/dto/req/entry/business/sales/WechatEntryStoreInfoReqDto.java (98%) rename cash-sdk/aggregation-pay/src/main/java/com/czg/{ => third}/wechat/dto/req/entry/business/sales/WechatEntryWebInfoReqDto.java (96%) rename cash-sdk/aggregation-pay/src/main/java/com/czg/{ => third}/wechat/dto/req/entry/business/sales/WechatEntryWeworkInfoReqDto.java (94%) rename cash-sdk/aggregation-pay/src/main/java/com/czg/{ => third}/wechat/dto/req/entry/id/WechatEntryIdCardReqDto.java (98%) rename cash-sdk/aggregation-pay/src/main/java/com/czg/{ => third}/wechat/dto/req/entry/id/WechatEntryIdDocInfoReqDto.java (99%) rename cash-sdk/aggregation-pay/src/main/java/com/czg/{ => utils}/CommonUtil.java (97%) diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/AggregateMerchantDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/AggregateMerchantDto.java new file mode 100644 index 000000000..1131c3cd8 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/AggregateMerchantDto.java @@ -0,0 +1,49 @@ +package com.czg.dto; + +import lombok.Data; + +/** + * 统一进件 + * + * @author yjjie + * @date 2026/1/6 10:02 + */ +@Data +public class AggregateMerchantDto { + + /** + * 【必填】 + * 商户编号(在当前系统唯一) + */ + private String merchantCode; + + /** + * 【必填】 + * 商户基础信息 + */ + private MerchantBaseInfoDto merchantBaseInfo; + + /** + * 【必填】 + * 法人信息 + */ + private LegalPersonInfoDto legalPersonInfo; + + /** + * 【必填】 + * 营业执照信息 + */ + private BusinessLicenceInfoDto businessLicenceInfo; + + /** + * 【必填】 + * 门店信息 + */ + private StoreInfoDto storeInfo; + + /** + * 【必填】 + * 结算信息 + */ + private SettlementInfoDto settlementInfo; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/BusinessLicenceInfoDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/BusinessLicenceInfoDto.java new file mode 100644 index 000000000..860175856 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/BusinessLicenceInfoDto.java @@ -0,0 +1,42 @@ +package com.czg.dto; + +import lombok.Data; + +/** + * 营业执照信息 + * @author yjjie + * @date 2026/1/6 10:17 + */ +@Data +public class BusinessLicenceInfoDto { + + /** + * 营业执照全称--非小微必填 + */ + private String licenceName; + + /** + * 营业执照号码--非小微必填 + */ + private String licenceNo; + + /** + * 营业执照开始日期--非小微必填 + */ + private String licenceStartDate; + + /** + * 营业执照结束日期--非小微必填 + */ + private String licenceEndDate; + + /** + * 营业执照注册地址--非小微必填 + */ + private String registeredAddress; + + /** + * 营业执照 + */ + private String licensePic; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/LegalPersonInfoDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/LegalPersonInfoDto.java new file mode 100644 index 000000000..f6d2c101e --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/LegalPersonInfoDto.java @@ -0,0 +1,68 @@ +package com.czg.dto; + +import lombok.Data; + +/** + * 法人信息 + * @author yjjie + * @date 2026/1/6 10:13 + */ +@Data +public class LegalPersonInfoDto { + + /** + * 【必填】 + * 法人姓名 + */ + private String legalPersonName; + + /** + * 【必填】 + * 法人身份证号 + */ + private String legalPersonId; + + /** + * 【必填】 + * 法人身份证开始日期 + */ + private String legalIdStartDate; + + /** + * 【必填】 + * 法人身份证到期日期 + */ + private String legalPersonIdEndDate; + + /** + * 【必填】 + * 法人电话 + */ + private String legalPersonPhone; + + /** + * 法人性别(0男 1女) + */ + private String legalGender; + + /** + * 【必填】 + * 法人地址 + */ + private String legalAddress; + + /** + * 身份证手持 图片 + */ + private String idCardHandPic; + + /** + * 身份证正面 + */ + private String idCardFrontPic; + + /** + * 身份证反面 + */ + private String idCardBackPic; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/MerchantBaseInfoDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/MerchantBaseInfoDto.java new file mode 100644 index 000000000..ca57d4e04 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/MerchantBaseInfoDto.java @@ -0,0 +1,75 @@ +package com.czg.dto; + +import lombok.Data; + +/** + * 商户基础信息 + * + * @author yjjie + * @date 2026/1/6 10:09 + */ +@Data +public class MerchantBaseInfoDto { + + /** + * 【必填】 + * 商户类型 + * 0: 个体商户; + * 1: 企业商户; + * 3: 小微商户 + */ + private String userType; + + /** + * 【必填】 + * 商户简称--企业、个体必填 + */ + private String shortName; + + /** + * 证件类型 + * 目前只支持身份证 传值:0 + */ + private String certType = "0"; + + /** + * 【必填】 + * 行业编码 + */ + private String mccCode; + + /** + * 【必填】 + * 联系人姓名 + */ + private String contactName; + + /** + * 【必填】 + * 联系人身份证号 + */ + private String contactPersonId; + + /** + * 【必填】 + * 联系人电话 + */ + private String contactPhone; + + /** + * 【必填】 + * 联系人通讯地址 + */ + private String contactAddr; + + /** + * 【必填】 + * 联系人邮箱 + */ + private String contactEmail; + + /** + * 企业类型,1:普通企业,2:事业单位,3:其他组织 + */ + private String companyChildType = "1"; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/SettlementInfoDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/SettlementInfoDto.java new file mode 100644 index 000000000..152492d9d --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/SettlementInfoDto.java @@ -0,0 +1,132 @@ +package com.czg.dto; + +import lombok.Data; + +/** + * 结算信息 + * @author yjjie + * @date 2026/1/6 10:22 + */ +@Data +public class SettlementInfoDto { + + /** + * 法人结算 0:非法人结算, 1:法人结算 + */ + private String codeLegalPersonAcc; + + /** + * 非法人姓名 + */ + private String unincorporatedName; + + /** + * 非法人身份证号码 + */ + private String unincorporatedId; + + /** + * 结算卡类型 必填 11 对私借记卡(结算卡正面照、结算卡反面照图片必传) 21 对公借记卡(只须结算卡正面照片) + */ + private String settlementCardType; + + /** + * 结算账户卡号 + */ + private String settlementCardNo; + + /** + * 结算账户户名 + */ + private String settlementName; + + /** + * 结算银行预留手机号 + */ + private String bankMobile; + + /** + * 开户行省ID + */ + private String openAccProvinceId; + + /** + * 开户行市ID + */ + private String openAccCityId; + + /** + * 开户行区ID + */ + private String openAccAreaId; + + /** + * 开户行省 + */ + private String openAccProvince; + + /** + * 开户行市 + */ + private String openAccCity; + + /** + * 开户行区 + */ + private String openAccArea; + + /** + * 开户行行别名称 + */ + private String bankName; + + /** + * 开户行编号 + */ + private String bankType; + + /** + * 支行开户行行别名称 + */ + private String bankBranchName; + + /** + * 支行开户行编号 + */ + private String bankBranchCode; + + /** + * 银行卡正面 + */ + private String bankCardFrontPic; + + /** + * 银行卡反面 + */ + private String bankCardBackPic; + + /** + * 开户许可证 + */ + private String openAccountLicence; + + /** + * 非法人手持结算授权书 + */ + private String nonLegHandSettleAuthPic; + + /** + * 非法人结算授权书 + */ + private String nonLegSettleAuthPic; + + /** + * 非法人身份证正面 + */ + private String nonLegIdCardFrontPic; + + /** + * 非法人身份证反面 + */ + private String nonLegIdCardBackPic; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/StoreInfoDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/StoreInfoDto.java new file mode 100644 index 000000000..8e5e765cb --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/StoreInfoDto.java @@ -0,0 +1,66 @@ +package com.czg.dto; + +import lombok.Data; + +/** + * 门店信息 + * @author yjjie + * @date 2026/1/6 10:19 + */ +@Data +public class StoreInfoDto { + + /** + * 【必填】 + * 商户归属省id + */ + private String mercProvId; + + /** + * 【必填】 + * 商户归属市id + */ + private String mercCityId; + + /** + * 【必填】 + * 商户归属区id + */ + private String mercAreaId; + + /** + * 商户归属省 + */ + private String mercProv; + + /** + * 商户归属市 + */ + private String mercCity; + + /** + * 商户归属区 + */ + private String mercArea; + + /** + * 【必填】 + * 营业地址 + */ + private String businessAddress; + + /** + * 经营场所内设照片 + */ + private String insidePic; + + /** + * 门头照 + */ + private String doorPic; + + /** + * 收银台照片 + */ + private String cashierDeskPic; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/AlipayClient.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayClient.java similarity index 91% rename from cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/AlipayClient.java rename to cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayClient.java index 44991f37e..a247b64e6 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/AlipayClient.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayClient.java @@ -1,9 +1,9 @@ -package com.czg.alipay; +package com.czg.third.alipay; import com.alipay.v3.ApiClient; import com.alipay.v3.Configuration; import com.alipay.v3.util.model.AlipayConfig; -import com.czg.alipay.dto.config.AlipayConfigDto; +import com.czg.third.alipay.dto.config.AlipayConfigDto; import lombok.extern.slf4j.Slf4j; /** diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/AlipayEntryManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayEntryManager.java similarity index 66% rename from cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/AlipayEntryManager.java rename to cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayEntryManager.java index ddce4f17a..551d01a2d 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/AlipayEntryManager.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayEntryManager.java @@ -1,18 +1,25 @@ -package com.czg.alipay; +package com.czg.third.alipay; +import com.alipay.api.AlipayApiException; +import com.alipay.api.DefaultAlipayClient; +import com.alipay.api.domain.AntMerchantExpandIndirectZftSimplecreateModel; +import com.alipay.api.request.AntMerchantExpandIndirectZftSimplecreateRequest; +import com.alipay.api.response.AntMerchantExpandIndirectZftSimplecreateResponse; import com.alipay.v3.ApiClient; import com.alipay.v3.ApiException; import com.alipay.v3.Configuration; -import com.alipay.v3.api.AlipayMerchantImageApi; import com.alipay.v3.api.AlipayOpenAgentApi; +import com.alipay.v3.api.AntMerchantExpandIndirectImageApi; import com.alipay.v3.model.*; import com.alipay.v3.util.model.AlipayConfig; -import com.czg.CommonUtil; -import com.czg.alipay.dto.config.AlipayConfigDto; -import com.czg.alipay.dto.entry.AlipayImageUploadReqDto; +import com.czg.utils.CommonUtil; +import com.czg.third.alipay.dto.config.AlipayConfigDto; +import java.util.regex.Pattern; import lombok.extern.slf4j.Slf4j; import java.io.File; +import java.nio.file.Files; +import java.nio.file.Path; /** * 支付宝进件管理 @@ -24,27 +31,49 @@ import java.io.File; */ @Slf4j public class AlipayEntryManager { + // 匹配常见的图片扩展名 + private static final Pattern PATTERN = Pattern.compile("\\.(jpg|jpeg|png|gif|bmp|webp|svg|ico)(?:[\\?#]|$)", Pattern.CASE_INSENSITIVE); - public static String uploadImage() { - - byte[] bytes = CommonUtil.downloadImage("https://czg-qr-order.oss-cn-beijing.aliyuncs.com/indexs/shuangbackground.png"); - - File file = new File("/Users/yjjie/Desktop/111222.jpg"); - - AlipayMerchantImageApi api = new AlipayMerchantImageApi(); - - AlipayMerchantImageUploadModel model = new AlipayMerchantImageUploadModel(); - model.setImageType("jpg"); + public static String uploadImage(String url) { try { - AlipayMerchantImageUploadResponseModel upload = api.upload(model, file); + byte[] bytes = CommonUtil.downloadImage(url); + + Path tempFile = Files.createTempFile("image_", ".png"); + + // 写入数据 + Files.write(tempFile, bytes); + + File file = tempFile.toFile(); + + AntMerchantExpandIndirectImageApi imageApi = new AntMerchantExpandIndirectImageApi(); + + AntMerchantExpandIndirectImageUploadModel model = new AntMerchantExpandIndirectImageUploadModel(); + // 从 url 中获取图片 后缀 + model.setImageType(extractImageExtension(url)); + AntMerchantExpandIndirectImageUploadResponseModel upload = imageApi.upload(model, file); return upload.getImageId(); - } catch (ApiException e) { + } catch (Exception e) { log.error("支付宝上传图片报错,URL:{},错误信息:{}", "url", e.getMessage(), e); return ""; } } - public static void main(String[] args) { + /** + * 使用正则表达式提取图片后缀 + */ + public static String extractImageExtension(String imageUrl) { + java.util.regex.Matcher matcher = PATTERN.matcher(imageUrl); + + if (matcher.find()) { + String extension = matcher.group(1).toLowerCase(); + // 处理jpeg的情况 + return "jpeg".equals(extension) ? "jpg" : extension; + } + // 默认后缀 + return "png"; + } + + public static void main(String[] args) throws AlipayApiException { AlipayConfigDto configDto = new AlipayConfigDto() .setDomain("https://openapi.alipay.com") .setAppId("2021004174605036") @@ -52,8 +81,31 @@ public class AlipayEntryManager { .setAlipayPublicKey("MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAiQkrz+emAuS1mB3KKDOMmAZRd/BlPbh7fAIHAqAj1+QCZNcV3o2BTLIIqnuKpSlFXDG3uDzp2VsBxcizXuBbFyPGylnD9CgCj5abyh3+FIHPAZ2IM3TtpqImZ0TSPGXrMli4Nir7MvZktgccCqQKCC4o6iaDGz+UwWwJUIPna8fm2tiTZ+KH150CZbKVj4ZGNpBh5XSV/1dRgyQIV9D/EwSbkZ0n6VgKQLJBi0C2UE3QB17aL1Ir6+gDXIDbknN8O7GUD3aMGdThYdSRUb5wp9CZ5qfV7vCS/CgaRo38nhH3NOzkTL+7v0m1ZDHPmqEkn9VzZN6sCQdL7PoAOjHOCwIDAQAB"); AlipayClient.setupAlipayConfig(configDto); - String image = uploadImage(); - System.out.println("image id = " + image); +// AlipayOpenAgentCreateModel data = new AlipayOpenAgentCreateModel(); +// +// AlipayOpenAgentFacetofaceApi api = new AlipayOpenAgentFacetofaceApi(); + +// String imageId = uploadImage("https://czg-qr-order.oss-cn-beijing.aliyuncs.com/indexs/shuangbackground.png"); +// System.out.println("支付宝图片 ID = " + imageId); + + AntMerchantExpandIndirectZftSimplecreateRequest request = new AntMerchantExpandIndirectZftSimplecreateRequest(); + AntMerchantExpandIndirectZftSimplecreateModel model = new AntMerchantExpandIndirectZftSimplecreateModel(); + + // 设置商户编号 + model.setExternalId("105290059990194"); + + request.setBizModel(model); + + com.alipay.api.AlipayConfig alipayConfig = new com.alipay.api.AlipayConfig(); + alipayConfig.setServerUrl(configDto.getDomain()); + alipayConfig.setAppId(configDto.getAppId()); + alipayConfig.setAlipayPublicKey(configDto.getAlipayPublicKey()); + alipayConfig.setPrivateKey(configDto.getPrivateKey()); + // 初始化SDK + DefaultAlipayClient defaultAlipayClient = new DefaultAlipayClient(alipayConfig); +// AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig); + AntMerchantExpandIndirectZftSimplecreateResponse response = defaultAlipayClient.execute(request); + System.out.println(response.getBody()); } // https://opendocs.alipay.com/solution/0dec7x?pathHash=caec4753 直付通 diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayReqUtils.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayReqUtils.java new file mode 100644 index 000000000..733c48c49 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayReqUtils.java @@ -0,0 +1,223 @@ +package com.czg.third.alipay; + + +import com.alipay.api.AlipayApiException; +import com.alipay.api.AlipayConfig; +import com.alipay.api.DefaultAlipayClient; +import com.alipay.api.domain.*; +import com.alipay.api.request.AntMerchantExpandIndirectZftSimplecreateRequest; +import com.alipay.api.response.AntMerchantExpandIndirectZftSimplecreateResponse; +import java.util.ArrayList; +import java.util.List; + +/** + * @author yjjie + * @date 2026/1/5 13:46 + */ +public class AlipayReqUtils { + public static void main(String[] args) throws AlipayApiException { + DefaultAlipayClient defaultAlipayClient = new DefaultAlipayClient(getAlipayConfig()); + // 初始化SDK +// AlipayClient alipayClient = new DefaultAlipayClient(getAlipayConfig()); + + // 构造请求参数以调用接口 + AntMerchantExpandIndirectZftSimplecreateRequest request = new AntMerchantExpandIndirectZftSimplecreateRequest(); + AntMerchantExpandIndirectZftSimplecreateModel model = new AntMerchantExpandIndirectZftSimplecreateModel(); + + // 设置商户编号 + model.setExternalId("1052900599901941"); + + // 设置签约支付宝账户 + model.setBindingAlipayLogonId("18434286340"); + + // 设置商户别名 + model.setAliasName("一点点"); + + // 设置商户客服电话 +// model.setServicePhone("0571-85022088"); + + // 设置商户联系人信息 + ContactInfo contactInfos = new ContactInfo(); + contactInfos.setIdCardNo("142725199902176419"); +// contactInfos.setPhone("0571-85022088"); + contactInfos.setName("王伟"); + contactInfos.setMobile("18434286340"); + contactInfos.setEmail("18434286340"); + model.setContactInfos(contactInfos); + + // 设置进件的二级商户名称 + model.setName("王伟"); + + // 设置默认结算规则 + DefaultSettleRule defaultSettleRule = new DefaultSettleRule(); + defaultSettleRule.setDefaultSettleType("alipayAccount"); + defaultSettleRule.setDefaultSettleTarget("18434286340"); + model.setDefaultSettleRule(defaultSettleRule); + + // 设置结算支付宝账号 + model.setAlipayLogonId("18434286340"); + + // 设置结算银行卡信息 + SettleCardInfo bizCards = new SettleCardInfo(); + bizCards.setAccountInstName("招商银行"); + bizCards.setBankCode("103290003044"); + bizCards.setAccountType("DC"); + bizCards.setUsageType("01"); + bizCards.setAccountHolderName("王伟"); + bizCards.setAccountInstCity("杭州市"); + bizCards.setAccountInstId("CMB"); + bizCards.setAccountNo("6214831259609102"); + bizCards.setAccountBranchName("招商银行杭州高新支行"); + bizCards.setAccountInstProvince("浙江省"); + model.setBizCards(bizCards); + + // 设置授权函 + model.setLicenseAuthLetterImage("c6c0c7a1-b9d5-4e5d-b9d4-9eed39f00e65.jpg"); + + // 设置开票资料信息 +// MerchantInvoiceInfo invoiceInfo = new MerchantInvoiceInfo(); +// invoiceInfo.setMailTelephone("057162288888"); +// invoiceInfo.setTaxPayerQualification("01"); +// invoiceInfo.setAddress("浙江省杭州市西湖区西溪路蚂蚁金服"); +// invoiceInfo.setAcceptElectronic(false); +// invoiceInfo.setTelephone("057162288888"); +// invoiceInfo.setTitle("蚂蚁金服(杭州)信息技术有限公司"); +// invoiceInfo.setMailName("张三"); +// invoiceInfo.setAutoInvoice(true); +// invoiceInfo.setTaxPayerValid("19981011"); +// invoiceInfo.setTaxNo("51010482542598631219"); +// invoiceInfo.setBankName("中国银行"); +// AddressInfo mailAddress = new AddressInfo(); +// mailAddress.setAddress("万塘路18号黄龙时代广场B座"); +// mailAddress.setDistrictCode("371002"); +// mailAddress.setLatitude("60.270001"); +// mailAddress.setCityCode("371000"); +// mailAddress.setPoiid("B0FFIVU189"); +// mailAddress.setProvinceCode("370000"); +// mailAddress.setLongitude("120.760001"); +// invoiceInfo.setMailAddress(mailAddress); +// invoiceInfo.setBankAccount("1234567812345678123"); +// model.setInvoiceInfo(invoiceInfo); + + // 设置商户使用服务 + List service = new ArrayList(); + service.add("当面付"); + model.setService(service); + + // 设置经营地址 + AddressInfo businessAddress = new AddressInfo(); + businessAddress.setAddress("万塘路18号黄龙时代广场B座"); + businessAddress.setDistrictCode("371002"); + businessAddress.setLatitude("60.270001"); + businessAddress.setCityCode("371000"); + businessAddress.setPoiid("B0FFIVU189"); + businessAddress.setProvinceCode("370000"); + businessAddress.setType("BUSINESS_ADDRESS"); + businessAddress.setLongitude("120.760001"); + model.setBusinessAddress(businessAddress); + + // 设置门头照 + model.setOutDoorImages("c6c0c7a1-b9d5-4e5d-b9d4-9eed39f00e65.jpg"); + + // 设置内景照 + model.setInDoorImages("c6c0c7a1-b9d5-4e5d-b9d4-9eed39f00e65.jpg"); + + // 设置商户站点信息 +// SiteInfo sites = new SiteInfo(); +// sites.setIcpOrgName("支付宝(中国)网络技术有限公司"); +// sites.setSiteType("01"); +// sites.setSiteDomain("www.alipay.com"); +// sites.setScreenshotImage("c6c0c7a1-b9d5-4e5d-b9d4-9eed39f00e65.jpg"); +// sites.setRemark("备注说明"); +// sites.setAuthLetterImage("c6c0c7a1-b9d5-4e5d-b9d4-9eed39f00e65.jpg"); +// sites.setSiteName("XXX网站"); +// sites.setMarket("豌豆荚"); +// sites.setPassword("测试密码"); +// sites.setDownload("https://itunes.apple.com/cn/app/id333206289?mt=8"); +// sites.setTinyAppId("2021004105652035"); +// sites.setSiteUrl("https://open.alipay.com"); +// sites.setIcpServiceName("支付宝"); +// sites.setRemarkImage("c6c0c7a1-b9d5-4e5d-b9d4-9eed39f00e65.jpg"); +// sites.setAccount("测试账号"); +// sites.setIcpNo("沪ICP备15027489号-2"); +// sites.setStatus("ONLINE"); +// model.setSites(sites); + + // 设置商户类别码 mcc + model.setMcc("B0007"); + + // 设置商户行业资质图片 + List qualifications = new ArrayList(); + IndustryQualificationInfo qualifications0 = new IndustryQualificationInfo(); + qualifications0.setIndustryQualificationImage("c6c0c7a1-b9d5-4e5d-b9d4-9eed39f00e65.jpg"); + qualifications0.setIndustryQualificationType("323"); + qualifications.add(qualifications0); + model.setQualifications(qualifications); + + // 设置补充证件号 + model.setAdditionalCertNo("9133010608210550XR"); + + // 设置补充证件类型 + model.setAdditionalCertType("201"); + + // 设置补充证件图片 + model.setAdditionalCertImage("c6c0c7a1-b9d5-4e5d-b9d4-9eed39f00e65.jpg"); + + // uid参数未来计划废弃,存量商户可继续使用,新商户请使用openid。请根据应用-开发配置-openid配置选择支持的字段。 + // model.setInfoSourceUid("2088111122223333"); + + // 设置(平替原来的info_source_uid字段 +// model.setInfoSourceOpenId("074a1CcTG1LelxKe4xQC0zgNdId0nxi95b5lsNpazWYoCo5"); + + // uid参数未来计划废弃,存量商户可继续使用,新商户请使用openid。请根据应用-开发配置-openid配置选择支持的字段。 + // model.setOverseaSettleAccount("2088111122223333"); + + // 设置(平替原来的oversea_settle_open_id字段 +// model.setOverseaSettleOpenId("074a1CcTG1LelxKe4xQC0zgNdId0nxi95b5lsNpazWYoCo5"); + + // 设置二级商户与服务商的签约时间 + model.setSignTimeWithIsv("2015-04-15"); + + // 设置代扣产品信息 + ZFTWithholdingInfo zftWithholdingInfo = new ZFTWithholdingInfo(); + zftWithholdingInfo.setWithholdingServiceFeatureName("GENERAL_WITHHOLDING_P"); + zftWithholdingInfo.setSignScene("DEFAULT"); + model.setZftWithholdingInfo(zftWithholdingInfo); + + // 设置交易场景 + List tradeScene = new ArrayList(); + tradeScene.add("TINY_APP"); + model.setTradeScene(tradeScene); + + request.setBizModel(model); + // 第三方代调用模式下请设置app_auth_token + // request.putOtherTextParam("app_auth_token", "<-- 请填写应用授权令牌 -->"); + + AntMerchantExpandIndirectZftSimplecreateResponse response = defaultAlipayClient.execute(request); + System.out.println(response.getBody()); + + if (response.isSuccess()) { + System.out.println("调用成功"); + } else { + System.out.println("调用失败"); + // sdk版本是"4.38.0.ALL"及以上,可以参考下面的示例获取诊断链接 + // String diagnosisUrl = DiagnosisUtils.getDiagnosisUrl(response); + // System.out.println(diagnosisUrl); + } + } + + private static AlipayConfig getAlipayConfig() { + String privateKey = "MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQD48HaUoV7OH7os+9L01kHgxzwIhJick4OkFq4aHsntsXEJ J3gedhuEZtV8oHKZ30DPW12IJ4S8NXtpr8OWaqrAPFonf4wVaRY1d0yIAea57kfLEn9oOEEy4FzARgMNDkyxC+/3OUdGbLHpTjfVX3gusXsEhUDy1/WewihAkoNYF37+W3W/uVLzeWoPq0EcUbRv/G/t/p6gL69ltsMAiVFG4Q/Yk24YAN6lYgBPNLXUEwQ1Q+T+1omjfavHgvarKOp33z3JOUH+aGOmDsJ5Y9gyGtJzOCipAd8Zcv+T1ygsEzZYO1/gzcbPnfO1ShqStCHzssuw8FBVx2JdfQKXKMMNAgMBAAECggEAVTrO/pg5Q00titU1Jspsh67u6OOs9H605Ws2dI7yB8VmtAGlaJh7V1t14FN2qSP8poHbhhAxq9aLyGV7C3a9u09udnN+3J28EtYjh7VO732bavWMVXxdJjQWzWWrCb9JlpxFrlkYBA6W4w/6ob0sAqCVQ7jzwbEa0R4cde8ztOa5nysKSfr4YTSs0gqvoiC6fmg8eiRJraEQBoYz9VkKFtOhhh/4w5FhVcYQ2gQvZ3kK3QVuD1eJIQKlCtz8qaox9lXKDiZT4SCmnKshdUL0u5TYIcYeBjZmhJz0Q50KHcpZrCs5y7I0+vRBH3hU+TKSQt7ureymwhbwWMHScLV2gQKBgQD+58SHXhr5M8NGagAmTdsgmCnNv2kOYMd4STyPMY10SVwCv1Bk808ZuP+7e558J1b5/OuDLI5dLq6xrZ/1wLv1G++XqxI00hlFuWS5mUGJVcXotT1mw20rVeUILc7Qe3mLvbMGgfyKf4A7Qa5SSZ4bDeDTJYaFxyiQ281hMzDuPQKBgQD6AiL/Na2/uPH4CG6juwpjYvYVUcjK+7gbRwf3wWsWMpk90Z4ju2iUiP5c1J/oK9P+1T3PIr6M4Xjza8JJj+r9KC/PVB0gBv6vVM96cDpKUEy/UMpcn/T81vqj/Z+WEOODU8Ms6NiTTm+u9ldvpCjbu0u8M+9c0JeIyadJvSTFEQKBgQCsxmFyM3nq8YfpgU2qqNjfBeRH3faSVUy+nj1a/YZYjKS+A/i1BCnYUImeBVNN6chNV342ggvY4xxruDiU9Vcw8wd58O09Oi8BEIFSP6upL6cebUI6Fjo3xlegLJRiwV6INkNTJOYM5hD/mSxUACwXQFfkJipBINXBIgraWD1RLQKBgQCj49axWq0F6+WjZVOyPaD3uh37p9trRUxRhWTxw3fB23WdktaKMgbCqHOmwzP4bRLSEVQtf2dOz1gMqu14b8HqJvgAf/F/11YJ9hz09LEhmjZVjE68HZfqT7uK2W5OX8/lfXmK7TFcj6SjG5YB96lZMhTZ0WnufEd6QkdKDZYXIQKBgQD9GDTcIMbFwbEaKHnfZaTD3f876EGRgsgrCxwdEk7LBCRPwWo7yI929M4psIlpNwNeiyjBkBunWIVkpznp6qPtJqagIPUYesU4f5v6/okq5wcpaNKSkWbIvWVLaLGOiA1aeGJtbpMpyClbSr52puHpRRdvAiIEQ74yYh0JX8q96g=="; + String alipayPublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAiQkrz+emAuS1mB3KKDOMmAZRd/BlPbh7fAIHAqAj1+QCZNcV3o2BTLIIqnuKpSlFXDG3uDzp2VsBxcizXuBbFyPGylnD9CgCj5abyh3+FIHPAZ2IM3TtpqImZ0TSPGXrMli4Nir7MvZktgccCqQKCC4o6iaDGz+UwWwJUIPna8fm2tiTZ+KH150CZbKVj4ZGNpBh5XSV/1dRgyQIV9D/EwSbkZ0n6VgKQLJBi0C2UE3QB17aL1Ir6+gDXIDbknN8O7GUD3aMGdThYdSRUb5wp9CZ5qfV7vCS/CgaRo38nhH3NOzkTL+7v0m1ZDHPmqEkn9VzZN6sCQdL7PoAOjHOCwIDAQAB"; + AlipayConfig alipayConfig = new AlipayConfig(); + alipayConfig.setServerUrl("https://openapi.alipay.com/gateway.do"); + alipayConfig.setAppId("2021004174605036"); + alipayConfig.setPrivateKey(privateKey); + alipayConfig.setFormat("json"); + alipayConfig.setAlipayPublicKey(alipayPublicKey); + alipayConfig.setCharset("UTF-8"); + alipayConfig.setSignType("RSA2"); + return alipayConfig; + } + +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/config/AlipayConfigDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/dto/config/AlipayConfigDto.java similarity index 92% rename from cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/config/AlipayConfigDto.java rename to cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/dto/config/AlipayConfigDto.java index a39bd5478..b23fa57e1 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/config/AlipayConfigDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/dto/config/AlipayConfigDto.java @@ -1,4 +1,4 @@ -package com.czg.alipay.dto.config; +package com.czg.third.alipay.dto.config; import lombok.Data; import lombok.experimental.Accessors; diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayAddressReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/dto/entry/AlipayAddressReqDto.java similarity index 95% rename from cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayAddressReqDto.java rename to cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/dto/entry/AlipayAddressReqDto.java index 349d690eb..71bb9e137 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayAddressReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/dto/entry/AlipayAddressReqDto.java @@ -1,4 +1,4 @@ -package com.czg.alipay.dto.entry; +package com.czg.third.alipay.dto.entry; import com.alibaba.fastjson2.annotation.JSONField; import lombok.Data; diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayBizCardsReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/dto/entry/AlipayBizCardsReqDto.java similarity index 97% rename from cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayBizCardsReqDto.java rename to cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/dto/entry/AlipayBizCardsReqDto.java index 319fbdb2a..06cb1fe0a 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayBizCardsReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/dto/entry/AlipayBizCardsReqDto.java @@ -1,4 +1,4 @@ -package com.czg.alipay.dto.entry; +package com.czg.third.alipay.dto.entry; import com.alibaba.fastjson2.annotation.JSONField; import lombok.Data; diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayContactInfoReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/dto/entry/AlipayContactInfoReqDto.java similarity index 95% rename from cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayContactInfoReqDto.java rename to cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/dto/entry/AlipayContactInfoReqDto.java index c29dc6ff0..c243994ef 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayContactInfoReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/dto/entry/AlipayContactInfoReqDto.java @@ -1,4 +1,4 @@ -package com.czg.alipay.dto.entry; +package com.czg.third.alipay.dto.entry; import com.alibaba.fastjson2.annotation.JSONField; import lombok.Data; diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayEntryReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/dto/entry/AlipayEntryReqDto.java similarity index 99% rename from cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayEntryReqDto.java rename to cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/dto/entry/AlipayEntryReqDto.java index 46fded03d..cbc0a52f5 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayEntryReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/dto/entry/AlipayEntryReqDto.java @@ -1,4 +1,4 @@ -package com.czg.alipay.dto.entry; +package com.czg.third.alipay.dto.entry; import com.alibaba.fastjson2.annotation.JSONField; import lombok.Data; diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayImageUploadReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/dto/entry/AlipayImageUploadReqDto.java similarity index 93% rename from cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayImageUploadReqDto.java rename to cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/dto/entry/AlipayImageUploadReqDto.java index a2abcc34e..666759afe 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayImageUploadReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/dto/entry/AlipayImageUploadReqDto.java @@ -1,4 +1,4 @@ -package com.czg.alipay.dto.entry; +package com.czg.third.alipay.dto.entry; import com.alibaba.fastjson2.annotation.JSONField; import lombok.Data; diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayQualificationsReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/dto/entry/AlipayQualificationsReqDto.java similarity index 94% rename from cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayQualificationsReqDto.java rename to cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/dto/entry/AlipayQualificationsReqDto.java index 6e4190027..81e66a598 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipayQualificationsReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/dto/entry/AlipayQualificationsReqDto.java @@ -1,4 +1,4 @@ -package com.czg.alipay.dto.entry; +package com.czg.third.alipay.dto.entry; import com.alibaba.fastjson2.annotation.JSONField; import lombok.Data; diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipaySettleRuleReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/dto/entry/AlipaySettleRuleReqDto.java similarity index 95% rename from cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipaySettleRuleReqDto.java rename to cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/dto/entry/AlipaySettleRuleReqDto.java index 75881a854..307a0425c 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipaySettleRuleReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/dto/entry/AlipaySettleRuleReqDto.java @@ -1,4 +1,4 @@ -package com.czg.alipay.dto.entry; +package com.czg.third.alipay.dto.entry; import com.alibaba.fastjson2.annotation.JSONField; import lombok.Data; diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipaySitesReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/dto/entry/AlipaySitesReqDto.java similarity index 98% rename from cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipaySitesReqDto.java rename to cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/dto/entry/AlipaySitesReqDto.java index 0e88ad25d..4ce85c3c7 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/alipay/dto/entry/AlipaySitesReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/dto/entry/AlipaySitesReqDto.java @@ -1,4 +1,4 @@ -package com.czg.alipay.dto.entry; +package com.czg.third.alipay.dto.entry; import com.alibaba.fastjson2.annotation.JSONField; import lombok.Data; diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatConfig.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatConfig.java similarity index 93% rename from cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatConfig.java rename to cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatConfig.java index 8be29a6e0..8842485f8 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatConfig.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatConfig.java @@ -1,6 +1,6 @@ -package com.czg.wechat; +package com.czg.third.wechat; -import com.czg.wechat.dto.config.WechatPayConfigDto; +import com.czg.third.wechat.dto.config.WechatPayConfigDto; import com.wechat.pay.java.core.Config; import com.wechat.pay.java.core.RSAPublicKeyConfig; import com.wechat.pay.java.service.file.FileUploadService; diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatEncrypt.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEncrypt.java similarity index 98% rename from cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatEncrypt.java rename to cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEncrypt.java index edca7803b..24ca2a939 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatEncrypt.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEncrypt.java @@ -1,4 +1,4 @@ -package com.czg.wechat; +package com.czg.third.wechat; import lombok.extern.slf4j.Slf4j; diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatEntryManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java similarity index 93% rename from cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatEntryManager.java rename to cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java index 43dc5f8f3..625d2bbe3 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatEntryManager.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java @@ -1,26 +1,14 @@ -package com.czg.wechat; +package com.czg.third.wechat; import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONWriter; -import com.czg.CommonUtil; -import com.czg.wechat.dto.config.WechatPayConfigDto; -import com.czg.wechat.dto.req.entry.*; -import com.czg.wechat.dto.req.entry.business.WechatEntryBusinessReqDto; -import com.czg.wechat.dto.req.entry.business.WechatEntryIdentityReqDto; -import com.czg.wechat.dto.req.entry.business.WechatEntryLicenseReqDto; -import com.czg.wechat.dto.req.entry.business.sales.WechatEntrySalesInfoReqDto; -import com.czg.wechat.dto.req.entry.business.sales.WechatEntryStoreInfoReqDto; -import com.wechat.pay.java.core.Config; -import com.wechat.pay.java.core.cipher.PrivacyEncryptor; +import com.czg.third.wechat.dto.req.entry.WechatEntryReqDto; +import com.czg.utils.CommonUtil; +import com.czg.third.wechat.dto.config.WechatPayConfigDto; import com.wechat.pay.java.service.file.FileUploadService; import com.wechat.pay.java.service.file.model.FileUploadResponse; import lombok.extern.slf4j.Slf4j; -import java.net.URI; -import java.net.http.HttpClient; -import java.net.http.HttpRequest; -import java.net.http.HttpResponse; -import java.util.List; import java.util.Map; /** diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatPayManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatPayManager.java similarity index 82% rename from cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatPayManager.java rename to cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatPayManager.java index 897ad8fc3..1b1d914ad 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatPayManager.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatPayManager.java @@ -1,4 +1,4 @@ -package com.czg.wechat; +package com.czg.third.wechat; /** * @author yjjie diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatReqUtils.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatReqUtils.java similarity index 96% rename from cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatReqUtils.java rename to cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatReqUtils.java index 7a3a3c7ad..f15522400 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/WechatReqUtils.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatReqUtils.java @@ -1,10 +1,9 @@ -package com.czg.wechat; +package com.czg.third.wechat; -import cn.hutool.core.util.StrUtil; import cn.hutool.http.HttpRequest; import cn.hutool.http.HttpUtil; import com.czg.exception.CzgException; -import com.czg.wechat.dto.config.WechatPayConfigDto; +import com.czg.third.wechat.dto.config.WechatPayConfigDto; import com.wechat.pay.java.core.Config; import com.wechat.pay.java.core.cipher.Signer; import lombok.extern.slf4j.Slf4j; @@ -13,7 +12,6 @@ import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.Map; -import java.util.Objects; import java.util.UUID; import java.util.stream.Collectors; diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/config/WechatPayConfigDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/config/WechatPayConfigDto.java similarity index 94% rename from cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/config/WechatPayConfigDto.java rename to cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/config/WechatPayConfigDto.java index a0cb78bc4..262d32fbd 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/config/WechatPayConfigDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/config/WechatPayConfigDto.java @@ -1,4 +1,4 @@ -package com.czg.wechat.dto.config; +package com.czg.third.wechat.dto.config; import lombok.Data; import lombok.experimental.Accessors; diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryAdditionReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/WechatEntryAdditionReqDto.java similarity index 96% rename from cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryAdditionReqDto.java rename to cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/WechatEntryAdditionReqDto.java index af0d5ed7d..c7c7865e7 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryAdditionReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/WechatEntryAdditionReqDto.java @@ -1,4 +1,4 @@ -package com.czg.wechat.dto.req.entry; +package com.czg.third.wechat.dto.req.entry; import com.alibaba.fastjson2.annotation.JSONField; import lombok.Data; diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryBankAccountReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/WechatEntryBankAccountReqDto.java similarity index 98% rename from cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryBankAccountReqDto.java rename to cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/WechatEntryBankAccountReqDto.java index 8908d1511..948400189 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryBankAccountReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/WechatEntryBankAccountReqDto.java @@ -1,4 +1,4 @@ -package com.czg.wechat.dto.req.entry; +package com.czg.third.wechat.dto.req.entry; import com.alibaba.fastjson2.annotation.JSONField; import lombok.Data; diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryContactReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/WechatEntryContactReqDto.java similarity index 99% rename from cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryContactReqDto.java rename to cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/WechatEntryContactReqDto.java index 635a3ff64..b7327dfe8 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryContactReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/WechatEntryContactReqDto.java @@ -1,4 +1,4 @@ -package com.czg.wechat.dto.req.entry; +package com.czg.third.wechat.dto.req.entry; import com.alibaba.fastjson2.annotation.JSONField; import lombok.Data; diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/WechatEntryReqDto.java similarity index 92% rename from cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryReqDto.java rename to cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/WechatEntryReqDto.java index 41432c01e..0555fdda3 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntryReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/WechatEntryReqDto.java @@ -1,7 +1,7 @@ -package com.czg.wechat.dto.req.entry; +package com.czg.third.wechat.dto.req.entry; import com.alibaba.fastjson2.annotation.JSONField; -import com.czg.wechat.dto.req.entry.business.WechatEntryBusinessReqDto; +import com.czg.third.wechat.dto.req.entry.business.WechatEntryBusinessReqDto; import lombok.Data; import lombok.experimental.Accessors; diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntrySettleReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/WechatEntrySettleReqDto.java similarity index 98% rename from cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntrySettleReqDto.java rename to cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/WechatEntrySettleReqDto.java index 3bcdf6594..637cdfd00 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntrySettleReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/WechatEntrySettleReqDto.java @@ -1,4 +1,4 @@ -package com.czg.wechat.dto.req.entry; +package com.czg.third.wechat.dto.req.entry; import com.alibaba.fastjson2.annotation.JSONField; import lombok.Data; diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntrySubjectReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/WechatEntrySubjectReqDto.java similarity index 97% rename from cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntrySubjectReqDto.java rename to cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/WechatEntrySubjectReqDto.java index b0c693823..1010b4969 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/WechatEntrySubjectReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/WechatEntrySubjectReqDto.java @@ -1,7 +1,7 @@ -package com.czg.wechat.dto.req.entry; +package com.czg.third.wechat.dto.req.entry; import com.alibaba.fastjson2.annotation.JSONField; -import com.czg.wechat.dto.req.entry.business.*; +import com.czg.third.wechat.dto.req.entry.business.*; import lombok.Data; import lombok.experimental.Accessors; diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryBusinessReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/business/WechatEntryBusinessReqDto.java similarity index 92% rename from cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryBusinessReqDto.java rename to cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/business/WechatEntryBusinessReqDto.java index e6d9b66a4..d2b5f773b 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryBusinessReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/business/WechatEntryBusinessReqDto.java @@ -1,7 +1,7 @@ -package com.czg.wechat.dto.req.entry.business; +package com.czg.third.wechat.dto.req.entry.business; import com.alibaba.fastjson2.annotation.JSONField; -import com.czg.wechat.dto.req.entry.business.sales.WechatEntrySalesInfoReqDto; +import com.czg.third.wechat.dto.req.entry.business.sales.WechatEntrySalesInfoReqDto; import lombok.Data; import lombok.experimental.Accessors; diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryCertificateReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/business/WechatEntryCertificateReqDto.java similarity index 98% rename from cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryCertificateReqDto.java rename to cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/business/WechatEntryCertificateReqDto.java index 5885b1327..cd422bf05 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryCertificateReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/business/WechatEntryCertificateReqDto.java @@ -1,4 +1,4 @@ -package com.czg.wechat.dto.req.entry.business; +package com.czg.third.wechat.dto.req.entry.business; import com.alibaba.fastjson2.annotation.JSONField; import lombok.Data; diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryFinanceInstitutionReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/business/WechatEntryFinanceInstitutionReqDto.java similarity index 97% rename from cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryFinanceInstitutionReqDto.java rename to cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/business/WechatEntryFinanceInstitutionReqDto.java index 6e5c6849b..b300cd666 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryFinanceInstitutionReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/business/WechatEntryFinanceInstitutionReqDto.java @@ -1,4 +1,4 @@ -package com.czg.wechat.dto.req.entry.business; +package com.czg.third.wechat.dto.req.entry.business; import com.alibaba.fastjson2.annotation.JSONField; import lombok.Data; diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryIdentityReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/business/WechatEntryIdentityReqDto.java similarity index 94% rename from cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryIdentityReqDto.java rename to cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/business/WechatEntryIdentityReqDto.java index fbe4dedb7..3d694aeb6 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryIdentityReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/business/WechatEntryIdentityReqDto.java @@ -1,8 +1,8 @@ -package com.czg.wechat.dto.req.entry.business; +package com.czg.third.wechat.dto.req.entry.business; import com.alibaba.fastjson2.annotation.JSONField; -import com.czg.wechat.dto.req.entry.id.WechatEntryIdCardReqDto; -import com.czg.wechat.dto.req.entry.id.WechatEntryIdDocInfoReqDto; +import com.czg.third.wechat.dto.req.entry.id.WechatEntryIdCardReqDto; +import com.czg.third.wechat.dto.req.entry.id.WechatEntryIdDocInfoReqDto; import lombok.Data; import lombok.experimental.Accessors; diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryLicenseReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/business/WechatEntryLicenseReqDto.java similarity index 98% rename from cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryLicenseReqDto.java rename to cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/business/WechatEntryLicenseReqDto.java index c98a00d6c..0e76f06c5 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryLicenseReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/business/WechatEntryLicenseReqDto.java @@ -1,4 +1,4 @@ -package com.czg.wechat.dto.req.entry.business; +package com.czg.third.wechat.dto.req.entry.business; import com.alibaba.fastjson2.annotation.JSONField; import lombok.Data; diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryUboInfoReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/business/WechatEntryUboInfoReqDto.java similarity index 98% rename from cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryUboInfoReqDto.java rename to cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/business/WechatEntryUboInfoReqDto.java index 961fbd723..8f7014e2c 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/WechatEntryUboInfoReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/business/WechatEntryUboInfoReqDto.java @@ -1,4 +1,4 @@ -package com.czg.wechat.dto.req.entry.business; +package com.czg.third.wechat.dto.req.entry.business; import com.alibaba.fastjson2.annotation.JSONField; import lombok.Data; diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryAppInfoReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/business/sales/WechatEntryAppInfoReqDto.java similarity index 96% rename from cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryAppInfoReqDto.java rename to cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/business/sales/WechatEntryAppInfoReqDto.java index 3c2a53b6f..bfb652f7e 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryAppInfoReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/business/sales/WechatEntryAppInfoReqDto.java @@ -1,4 +1,4 @@ -package com.czg.wechat.dto.req.entry.business.sales; +package com.czg.third.wechat.dto.req.entry.business.sales; import com.alibaba.fastjson2.annotation.JSONField; import lombok.Data; diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryMiniProgramReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/business/sales/WechatEntryMiniProgramReqDto.java similarity index 96% rename from cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryMiniProgramReqDto.java rename to cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/business/sales/WechatEntryMiniProgramReqDto.java index 259d3ff9d..fbf428a46 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryMiniProgramReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/business/sales/WechatEntryMiniProgramReqDto.java @@ -1,4 +1,4 @@ -package com.czg.wechat.dto.req.entry.business.sales; +package com.czg.third.wechat.dto.req.entry.business.sales; import com.alibaba.fastjson2.annotation.JSONField; import lombok.Data; diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryMpInfoReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/business/sales/WechatEntryMpInfoReqDto.java similarity index 96% rename from cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryMpInfoReqDto.java rename to cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/business/sales/WechatEntryMpInfoReqDto.java index e90bd0292..e6a1bebfb 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryMpInfoReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/business/sales/WechatEntryMpInfoReqDto.java @@ -1,4 +1,4 @@ -package com.czg.wechat.dto.req.entry.business.sales; +package com.czg.third.wechat.dto.req.entry.business.sales; import com.alibaba.fastjson2.annotation.JSONField; import lombok.Data; diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntrySalesInfoReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/business/sales/WechatEntrySalesInfoReqDto.java similarity index 97% rename from cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntrySalesInfoReqDto.java rename to cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/business/sales/WechatEntrySalesInfoReqDto.java index e1547c633..b1d6979de 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntrySalesInfoReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/business/sales/WechatEntrySalesInfoReqDto.java @@ -1,4 +1,4 @@ -package com.czg.wechat.dto.req.entry.business.sales; +package com.czg.third.wechat.dto.req.entry.business.sales; import com.alibaba.fastjson2.annotation.JSONField; import lombok.Data; diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryStoreInfoReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/business/sales/WechatEntryStoreInfoReqDto.java similarity index 98% rename from cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryStoreInfoReqDto.java rename to cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/business/sales/WechatEntryStoreInfoReqDto.java index 7b661eeb7..2347f01ea 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryStoreInfoReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/business/sales/WechatEntryStoreInfoReqDto.java @@ -1,4 +1,4 @@ -package com.czg.wechat.dto.req.entry.business.sales; +package com.czg.third.wechat.dto.req.entry.business.sales; import com.alibaba.fastjson2.annotation.JSONField; import lombok.Data; diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryWebInfoReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/business/sales/WechatEntryWebInfoReqDto.java similarity index 96% rename from cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryWebInfoReqDto.java rename to cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/business/sales/WechatEntryWebInfoReqDto.java index 6dc446d61..bc087205a 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryWebInfoReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/business/sales/WechatEntryWebInfoReqDto.java @@ -1,4 +1,4 @@ -package com.czg.wechat.dto.req.entry.business.sales; +package com.czg.third.wechat.dto.req.entry.business.sales; import com.alibaba.fastjson2.annotation.JSONField; import lombok.Data; diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryWeworkInfoReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/business/sales/WechatEntryWeworkInfoReqDto.java similarity index 94% rename from cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryWeworkInfoReqDto.java rename to cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/business/sales/WechatEntryWeworkInfoReqDto.java index 1c4530022..4706b9d46 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/business/sales/WechatEntryWeworkInfoReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/business/sales/WechatEntryWeworkInfoReqDto.java @@ -1,4 +1,4 @@ -package com.czg.wechat.dto.req.entry.business.sales; +package com.czg.third.wechat.dto.req.entry.business.sales; import com.alibaba.fastjson2.annotation.JSONField; import lombok.Data; diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/id/WechatEntryIdCardReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/id/WechatEntryIdCardReqDto.java similarity index 98% rename from cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/id/WechatEntryIdCardReqDto.java rename to cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/id/WechatEntryIdCardReqDto.java index fdc203cb9..02c1e3c18 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/id/WechatEntryIdCardReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/id/WechatEntryIdCardReqDto.java @@ -1,4 +1,4 @@ -package com.czg.wechat.dto.req.entry.id; +package com.czg.third.wechat.dto.req.entry.id; import com.alibaba.fastjson2.annotation.JSONField; import lombok.Data; diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/id/WechatEntryIdDocInfoReqDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/id/WechatEntryIdDocInfoReqDto.java similarity index 99% rename from cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/id/WechatEntryIdDocInfoReqDto.java rename to cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/id/WechatEntryIdDocInfoReqDto.java index 9a959e844..b5cae26ba 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/wechat/dto/req/entry/id/WechatEntryIdDocInfoReqDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/req/entry/id/WechatEntryIdDocInfoReqDto.java @@ -1,4 +1,4 @@ -package com.czg.wechat.dto.req.entry.id; +package com.czg.third.wechat.dto.req.entry.id; import com.alibaba.fastjson2.annotation.JSONField; import lombok.Data; diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/CommonUtil.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/utils/CommonUtil.java similarity index 97% rename from cash-sdk/aggregation-pay/src/main/java/com/czg/CommonUtil.java rename to cash-sdk/aggregation-pay/src/main/java/com/czg/utils/CommonUtil.java index 19ab6599b..ab7becdb8 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/CommonUtil.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/utils/CommonUtil.java @@ -1,4 +1,4 @@ -package com.czg; +package com.czg.utils; import lombok.extern.slf4j.Slf4j; From 6ec6fafc9834108e5c61621b69cbe2ee47908284 Mon Sep 17 00:00:00 2001 From: gong <1157756119@qq.com> Date: Tue, 6 Jan 2026 15:45:39 +0800 Subject: [PATCH 12/19] =?UTF-8?q?=E8=B5=84=E6=96=99=E5=87=86=E5=A4=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/czg/EntryManager.java | 31 ++++++++ .../dto/{ => req}/AggregateMerchantDto.java | 2 +- .../dto/{ => req}/BusinessLicenceInfoDto.java | 2 +- .../czg/dto/{ => req}/LegalPersonInfoDto.java | 2 +- .../dto/{ => req}/MerchantBaseInfoDto.java | 2 +- .../czg/dto/{ => req}/SettlementInfoDto.java | 2 +- .../com/czg/dto/{ => req}/StoreInfoDto.java | 2 +- .../java/com/czg/dto/resp/BankBranchDto.java | 58 +++++++++++++++ .../com/czg/third/alipay/AlipayClient.java | 38 ++++++---- .../czg/third/alipay/AlipayEntryManager.java | 71 +++++++++++-------- .../com/czg/third/alipay/AlipayReqUtils.java | 19 +---- .../alipay/dto/config/AlipayConfigDto.java | 10 ++- .../czg/third/wechat/WechatEntryManager.java | 44 ++++++++++-- .../com/czg/third/wechat/WechatReqUtils.java | 4 ++ .../wechat/dto/config/WechatPayConfigDto.java | 48 +++++++++++++ 15 files changed, 260 insertions(+), 75 deletions(-) create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/EntryManager.java rename cash-sdk/aggregation-pay/src/main/java/com/czg/dto/{ => req}/AggregateMerchantDto.java (96%) rename cash-sdk/aggregation-pay/src/main/java/com/czg/dto/{ => req}/BusinessLicenceInfoDto.java (96%) rename cash-sdk/aggregation-pay/src/main/java/com/czg/dto/{ => req}/LegalPersonInfoDto.java (97%) rename cash-sdk/aggregation-pay/src/main/java/com/czg/dto/{ => req}/MerchantBaseInfoDto.java (97%) rename cash-sdk/aggregation-pay/src/main/java/com/czg/dto/{ => req}/SettlementInfoDto.java (98%) rename cash-sdk/aggregation-pay/src/main/java/com/czg/dto/{ => req}/StoreInfoDto.java (97%) create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/dto/resp/BankBranchDto.java diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/EntryManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/EntryManager.java new file mode 100644 index 000000000..d57762c28 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/EntryManager.java @@ -0,0 +1,31 @@ +package com.czg; + +import com.czg.dto.resp.BankBranchDto; +import com.czg.third.alipay.AlipayEntryManager; + +import java.util.List; + +/** + * 进件管理 + * + * @author yjjie + * @date 2026/1/6 13:56 + */ +public class EntryManager { + + /** + * 查询银行支行列表 + * + * @param province 省份 陕西省 + * @param city 城市 西安市 + * @param instId 顶级机构ID CMB + */ + public static List queryBankBranchList(String province, String city, String instId) { + return AlipayEntryManager.queryBankBranchList(instId, province, city); + } + + public static void main(String[] args) { + List dtoList = queryBankBranchList("陕西省", "西安市", "CMB"); + System.out.println(dtoList); + } +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/AggregateMerchantDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/AggregateMerchantDto.java similarity index 96% rename from cash-sdk/aggregation-pay/src/main/java/com/czg/dto/AggregateMerchantDto.java rename to cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/AggregateMerchantDto.java index 1131c3cd8..bdc521828 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/AggregateMerchantDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/AggregateMerchantDto.java @@ -1,4 +1,4 @@ -package com.czg.dto; +package com.czg.dto.req; import lombok.Data; diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/BusinessLicenceInfoDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/BusinessLicenceInfoDto.java similarity index 96% rename from cash-sdk/aggregation-pay/src/main/java/com/czg/dto/BusinessLicenceInfoDto.java rename to cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/BusinessLicenceInfoDto.java index 860175856..a4ac1c96c 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/BusinessLicenceInfoDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/BusinessLicenceInfoDto.java @@ -1,4 +1,4 @@ -package com.czg.dto; +package com.czg.dto.req; import lombok.Data; diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/LegalPersonInfoDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/LegalPersonInfoDto.java similarity index 97% rename from cash-sdk/aggregation-pay/src/main/java/com/czg/dto/LegalPersonInfoDto.java rename to cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/LegalPersonInfoDto.java index f6d2c101e..5f152b459 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/LegalPersonInfoDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/LegalPersonInfoDto.java @@ -1,4 +1,4 @@ -package com.czg.dto; +package com.czg.dto.req; import lombok.Data; diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/MerchantBaseInfoDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/MerchantBaseInfoDto.java similarity index 97% rename from cash-sdk/aggregation-pay/src/main/java/com/czg/dto/MerchantBaseInfoDto.java rename to cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/MerchantBaseInfoDto.java index ca57d4e04..9de2b790f 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/MerchantBaseInfoDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/MerchantBaseInfoDto.java @@ -1,4 +1,4 @@ -package com.czg.dto; +package com.czg.dto.req; import lombok.Data; diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/SettlementInfoDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/SettlementInfoDto.java similarity index 98% rename from cash-sdk/aggregation-pay/src/main/java/com/czg/dto/SettlementInfoDto.java rename to cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/SettlementInfoDto.java index 152492d9d..7df35f646 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/SettlementInfoDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/SettlementInfoDto.java @@ -1,4 +1,4 @@ -package com.czg.dto; +package com.czg.dto.req; import lombok.Data; diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/StoreInfoDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/StoreInfoDto.java similarity index 97% rename from cash-sdk/aggregation-pay/src/main/java/com/czg/dto/StoreInfoDto.java rename to cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/StoreInfoDto.java index 8e5e765cb..4d6111873 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/StoreInfoDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/StoreInfoDto.java @@ -1,4 +1,4 @@ -package com.czg.dto; +package com.czg.dto.req; import lombok.Data; diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/resp/BankBranchDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/resp/BankBranchDto.java new file mode 100644 index 000000000..f3c473090 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/resp/BankBranchDto.java @@ -0,0 +1,58 @@ +package com.czg.dto.resp; + +import com.alibaba.fastjson2.annotation.JSONField; +import lombok.Data; + +/** + * 银行支行信息 + * @author yjjie + * @date 2026/1/6 15:37 + */ +@Data +public class BankBranchDto { + /** + * 机构ID + */ + private String instId; + + /** + * 银行代码 + */ + private String bankCode; + + /** + * 城市 + */ + private String city; + + /** + * 银行简称 + */ + private String simpleName; + + /** + * 省份 + */ + @JSONField(name = "provice") + private String province; + + /** + * IBPS代码 + */ + private String ibpsCode; + + /** + * 承担机构 + */ + private String undertakeInst; + + /** + * 分支机构名称 + */ + private String branchName; + + /** + * 机构全称 + */ + private String instName; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayClient.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayClient.java index a247b64e6..c8a71033c 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayClient.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayClient.java @@ -1,8 +1,8 @@ package com.czg.third.alipay; -import com.alipay.v3.ApiClient; -import com.alipay.v3.Configuration; -import com.alipay.v3.util.model.AlipayConfig; +import com.alipay.api.AlipayApiException; +import com.alipay.api.AlipayConfig; +import com.alipay.api.DefaultAlipayClient; import com.czg.third.alipay.dto.config.AlipayConfigDto; import lombok.extern.slf4j.Slf4j; @@ -13,19 +13,29 @@ import lombok.extern.slf4j.Slf4j; @Slf4j public class AlipayClient { - public static void setupAlipayConfig(AlipayConfigDto configDto) { + public static DefaultAlipayClient getDefaultClient(AlipayConfigDto configDto) { try { - ApiClient defaultClient = Configuration.getDefaultApiClient(); - // 初始化alipay参数(全局设置一次) - AlipayConfig alipayConfig = new AlipayConfig(); - alipayConfig.setServerUrl(configDto.getDomain()); - alipayConfig.setAppId(configDto.getAppId()); - alipayConfig.setAlipayPublicKey(configDto.getAlipayPublicKey()); - alipayConfig.setPrivateKey(configDto.getPrivateKey()); - defaultClient.setAlipayConfig(alipayConfig); - } catch (Exception e) { - log.error("初始化alipay参数异常", e); + return new DefaultAlipayClient(getAlipayConfig(configDto)); + } catch (AlipayApiException e) { + log.error("创建支付宝客户端失败", e); + return null; + } + } + + public static AlipayConfig getAlipayConfig(AlipayConfigDto configDto) { + if (configDto == null) { + configDto = AlipayConfigDto.getDefaultConfig(); } + AlipayConfig alipayConfig = new AlipayConfig(); + alipayConfig.setServerUrl(configDto.getDomain()); + alipayConfig.setAppId(configDto.getAppId()); + alipayConfig.setPrivateKey(configDto.getPrivateKey()); + alipayConfig.setFormat("json"); + alipayConfig.setAlipayPublicKey(configDto.getAlipayPublicKey()); + alipayConfig.setCharset("UTF-8"); + alipayConfig.setSignType("RSA2"); + + return alipayConfig; } } diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayEntryManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayEntryManager.java index 551d01a2d..190f777e9 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayEntryManager.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayEntryManager.java @@ -1,9 +1,14 @@ package com.czg.third.alipay; +import com.alibaba.fastjson2.JSONArray; +import com.alibaba.fastjson2.JSONObject; import com.alipay.api.AlipayApiException; import com.alipay.api.DefaultAlipayClient; +import com.alipay.api.domain.AlipayFinancialnetAuthPbcnameQueryModel; import com.alipay.api.domain.AntMerchantExpandIndirectZftSimplecreateModel; +import com.alipay.api.request.AlipayFinancialnetAuthPbcnameQueryRequest; import com.alipay.api.request.AntMerchantExpandIndirectZftSimplecreateRequest; +import com.alipay.api.response.AlipayFinancialnetAuthPbcnameQueryResponse; import com.alipay.api.response.AntMerchantExpandIndirectZftSimplecreateResponse; import com.alipay.v3.ApiClient; import com.alipay.v3.ApiException; @@ -12,9 +17,14 @@ import com.alipay.v3.api.AlipayOpenAgentApi; import com.alipay.v3.api.AntMerchantExpandIndirectImageApi; import com.alipay.v3.model.*; import com.alipay.v3.util.model.AlipayConfig; +import com.czg.dto.resp.BankBranchDto; import com.czg.utils.CommonUtil; import com.czg.third.alipay.dto.config.AlipayConfigDto; + +import java.util.ArrayList; +import java.util.List; import java.util.regex.Pattern; + import lombok.extern.slf4j.Slf4j; import java.io.File; @@ -58,6 +68,34 @@ public class AlipayEntryManager { } } + /** + * 查询支行 + * + * @param instId 顶级机构ID CMB + * @param province 省份 陕西省 + * @param city 城市 西安市 + */ + public static List queryBankBranchList(String instId, String province, String city) { + try { + AlipayFinancialnetAuthPbcnameQueryRequest request = new AlipayFinancialnetAuthPbcnameQueryRequest(); + + AlipayFinancialnetAuthPbcnameQueryModel model = new AlipayFinancialnetAuthPbcnameQueryModel(); + model.setInstId(instId); + model.setProvice(province); + model.setCity(city); + + request.setBizModel(model); + DefaultAlipayClient defaultAlipayClient = AlipayClient.getDefaultClient(null); + AlipayFinancialnetAuthPbcnameQueryResponse response = defaultAlipayClient.execute(request); + + String data = response.getPbcQueryResult(); + return JSONArray.parseArray(data, BankBranchDto.class); + } catch (Exception e) { + log.error("支付宝查询支行报错,错误信息:{}", e.getMessage(), e); + return new ArrayList<>(); + } + } + /** * 使用正则表达式提取图片后缀 */ @@ -73,39 +111,10 @@ public class AlipayEntryManager { return "png"; } - public static void main(String[] args) throws AlipayApiException { - AlipayConfigDto configDto = new AlipayConfigDto() - .setDomain("https://openapi.alipay.com") - .setAppId("2021004174605036") - .setPrivateKey("MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQD48HaUoV7OH7os+9L01kHgxzwIhJick4OkFq4aHsntsXEJ J3gedhuEZtV8oHKZ30DPW12IJ4S8NXtpr8OWaqrAPFonf4wVaRY1d0yIAea57kfLEn9oOEEy4FzARgMNDkyxC+/3OUdGbLHpTjfVX3gusXsEhUDy1/WewihAkoNYF37+W3W/uVLzeWoPq0EcUbRv/G/t/p6gL69ltsMAiVFG4Q/Yk24YAN6lYgBPNLXUEwQ1Q+T+1omjfavHgvarKOp33z3JOUH+aGOmDsJ5Y9gyGtJzOCipAd8Zcv+T1ygsEzZYO1/gzcbPnfO1ShqStCHzssuw8FBVx2JdfQKXKMMNAgMBAAECggEAVTrO/pg5Q00titU1Jspsh67u6OOs9H605Ws2dI7yB8VmtAGlaJh7V1t14FN2qSP8poHbhhAxq9aLyGV7C3a9u09udnN+3J28EtYjh7VO732bavWMVXxdJjQWzWWrCb9JlpxFrlkYBA6W4w/6ob0sAqCVQ7jzwbEa0R4cde8ztOa5nysKSfr4YTSs0gqvoiC6fmg8eiRJraEQBoYz9VkKFtOhhh/4w5FhVcYQ2gQvZ3kK3QVuD1eJIQKlCtz8qaox9lXKDiZT4SCmnKshdUL0u5TYIcYeBjZmhJz0Q50KHcpZrCs5y7I0+vRBH3hU+TKSQt7ureymwhbwWMHScLV2gQKBgQD+58SHXhr5M8NGagAmTdsgmCnNv2kOYMd4STyPMY10SVwCv1Bk808ZuP+7e558J1b5/OuDLI5dLq6xrZ/1wLv1G++XqxI00hlFuWS5mUGJVcXotT1mw20rVeUILc7Qe3mLvbMGgfyKf4A7Qa5SSZ4bDeDTJYaFxyiQ281hMzDuPQKBgQD6AiL/Na2/uPH4CG6juwpjYvYVUcjK+7gbRwf3wWsWMpk90Z4ju2iUiP5c1J/oK9P+1T3PIr6M4Xjza8JJj+r9KC/PVB0gBv6vVM96cDpKUEy/UMpcn/T81vqj/Z+WEOODU8Ms6NiTTm+u9ldvpCjbu0u8M+9c0JeIyadJvSTFEQKBgQCsxmFyM3nq8YfpgU2qqNjfBeRH3faSVUy+nj1a/YZYjKS+A/i1BCnYUImeBVNN6chNV342ggvY4xxruDiU9Vcw8wd58O09Oi8BEIFSP6upL6cebUI6Fjo3xlegLJRiwV6INkNTJOYM5hD/mSxUACwXQFfkJipBINXBIgraWD1RLQKBgQCj49axWq0F6+WjZVOyPaD3uh37p9trRUxRhWTxw3fB23WdktaKMgbCqHOmwzP4bRLSEVQtf2dOz1gMqu14b8HqJvgAf/F/11YJ9hz09LEhmjZVjE68HZfqT7uK2W5OX8/lfXmK7TFcj6SjG5YB96lZMhTZ0WnufEd6QkdKDZYXIQKBgQD9GDTcIMbFwbEaKHnfZaTD3f876EGRgsgrCxwdEk7LBCRPwWo7yI929M4psIlpNwNeiyjBkBunWIVkpznp6qPtJqagIPUYesU4f5v6/okq5wcpaNKSkWbIvWVLaLGOiA1aeGJtbpMpyClbSr52puHpRRdvAiIEQ74yYh0JX8q96g==") - .setAlipayPublicKey("MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAiQkrz+emAuS1mB3KKDOMmAZRd/BlPbh7fAIHAqAj1+QCZNcV3o2BTLIIqnuKpSlFXDG3uDzp2VsBxcizXuBbFyPGylnD9CgCj5abyh3+FIHPAZ2IM3TtpqImZ0TSPGXrMli4Nir7MvZktgccCqQKCC4o6iaDGz+UwWwJUIPna8fm2tiTZ+KH150CZbKVj4ZGNpBh5XSV/1dRgyQIV9D/EwSbkZ0n6VgKQLJBi0C2UE3QB17aL1Ir6+gDXIDbknN8O7GUD3aMGdThYdSRUb5wp9CZ5qfV7vCS/CgaRo38nhH3NOzkTL+7v0m1ZDHPmqEkn9VzZN6sCQdL7PoAOjHOCwIDAQAB"); - AlipayClient.setupAlipayConfig(configDto); + public static void main(String[] args) { -// AlipayOpenAgentCreateModel data = new AlipayOpenAgentCreateModel(); -// -// AlipayOpenAgentFacetofaceApi api = new AlipayOpenAgentFacetofaceApi(); + queryBankBranchList("CMB", "西安市", "陕西省"); -// String imageId = uploadImage("https://czg-qr-order.oss-cn-beijing.aliyuncs.com/indexs/shuangbackground.png"); -// System.out.println("支付宝图片 ID = " + imageId); - - AntMerchantExpandIndirectZftSimplecreateRequest request = new AntMerchantExpandIndirectZftSimplecreateRequest(); - AntMerchantExpandIndirectZftSimplecreateModel model = new AntMerchantExpandIndirectZftSimplecreateModel(); - - // 设置商户编号 - model.setExternalId("105290059990194"); - - request.setBizModel(model); - - com.alipay.api.AlipayConfig alipayConfig = new com.alipay.api.AlipayConfig(); - alipayConfig.setServerUrl(configDto.getDomain()); - alipayConfig.setAppId(configDto.getAppId()); - alipayConfig.setAlipayPublicKey(configDto.getAlipayPublicKey()); - alipayConfig.setPrivateKey(configDto.getPrivateKey()); - // 初始化SDK - DefaultAlipayClient defaultAlipayClient = new DefaultAlipayClient(alipayConfig); -// AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig); - AntMerchantExpandIndirectZftSimplecreateResponse response = defaultAlipayClient.execute(request); - System.out.println(response.getBody()); } // https://opendocs.alipay.com/solution/0dec7x?pathHash=caec4753 直付通 diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayReqUtils.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayReqUtils.java index 733c48c49..0ab504b1e 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayReqUtils.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayReqUtils.java @@ -7,6 +7,7 @@ import com.alipay.api.DefaultAlipayClient; import com.alipay.api.domain.*; import com.alipay.api.request.AntMerchantExpandIndirectZftSimplecreateRequest; import com.alipay.api.response.AntMerchantExpandIndirectZftSimplecreateResponse; + import java.util.ArrayList; import java.util.List; @@ -16,9 +17,7 @@ import java.util.List; */ public class AlipayReqUtils { public static void main(String[] args) throws AlipayApiException { - DefaultAlipayClient defaultAlipayClient = new DefaultAlipayClient(getAlipayConfig()); - // 初始化SDK -// AlipayClient alipayClient = new DefaultAlipayClient(getAlipayConfig()); + DefaultAlipayClient defaultAlipayClient = AlipayClient.getDefaultClient(null); // 构造请求参数以调用接口 AntMerchantExpandIndirectZftSimplecreateRequest request = new AntMerchantExpandIndirectZftSimplecreateRequest(); @@ -206,18 +205,4 @@ public class AlipayReqUtils { } } - private static AlipayConfig getAlipayConfig() { - String privateKey = "MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQD48HaUoV7OH7os+9L01kHgxzwIhJick4OkFq4aHsntsXEJ J3gedhuEZtV8oHKZ30DPW12IJ4S8NXtpr8OWaqrAPFonf4wVaRY1d0yIAea57kfLEn9oOEEy4FzARgMNDkyxC+/3OUdGbLHpTjfVX3gusXsEhUDy1/WewihAkoNYF37+W3W/uVLzeWoPq0EcUbRv/G/t/p6gL69ltsMAiVFG4Q/Yk24YAN6lYgBPNLXUEwQ1Q+T+1omjfavHgvarKOp33z3JOUH+aGOmDsJ5Y9gyGtJzOCipAd8Zcv+T1ygsEzZYO1/gzcbPnfO1ShqStCHzssuw8FBVx2JdfQKXKMMNAgMBAAECggEAVTrO/pg5Q00titU1Jspsh67u6OOs9H605Ws2dI7yB8VmtAGlaJh7V1t14FN2qSP8poHbhhAxq9aLyGV7C3a9u09udnN+3J28EtYjh7VO732bavWMVXxdJjQWzWWrCb9JlpxFrlkYBA6W4w/6ob0sAqCVQ7jzwbEa0R4cde8ztOa5nysKSfr4YTSs0gqvoiC6fmg8eiRJraEQBoYz9VkKFtOhhh/4w5FhVcYQ2gQvZ3kK3QVuD1eJIQKlCtz8qaox9lXKDiZT4SCmnKshdUL0u5TYIcYeBjZmhJz0Q50KHcpZrCs5y7I0+vRBH3hU+TKSQt7ureymwhbwWMHScLV2gQKBgQD+58SHXhr5M8NGagAmTdsgmCnNv2kOYMd4STyPMY10SVwCv1Bk808ZuP+7e558J1b5/OuDLI5dLq6xrZ/1wLv1G++XqxI00hlFuWS5mUGJVcXotT1mw20rVeUILc7Qe3mLvbMGgfyKf4A7Qa5SSZ4bDeDTJYaFxyiQ281hMzDuPQKBgQD6AiL/Na2/uPH4CG6juwpjYvYVUcjK+7gbRwf3wWsWMpk90Z4ju2iUiP5c1J/oK9P+1T3PIr6M4Xjza8JJj+r9KC/PVB0gBv6vVM96cDpKUEy/UMpcn/T81vqj/Z+WEOODU8Ms6NiTTm+u9ldvpCjbu0u8M+9c0JeIyadJvSTFEQKBgQCsxmFyM3nq8YfpgU2qqNjfBeRH3faSVUy+nj1a/YZYjKS+A/i1BCnYUImeBVNN6chNV342ggvY4xxruDiU9Vcw8wd58O09Oi8BEIFSP6upL6cebUI6Fjo3xlegLJRiwV6INkNTJOYM5hD/mSxUACwXQFfkJipBINXBIgraWD1RLQKBgQCj49axWq0F6+WjZVOyPaD3uh37p9trRUxRhWTxw3fB23WdktaKMgbCqHOmwzP4bRLSEVQtf2dOz1gMqu14b8HqJvgAf/F/11YJ9hz09LEhmjZVjE68HZfqT7uK2W5OX8/lfXmK7TFcj6SjG5YB96lZMhTZ0WnufEd6QkdKDZYXIQKBgQD9GDTcIMbFwbEaKHnfZaTD3f876EGRgsgrCxwdEk7LBCRPwWo7yI929M4psIlpNwNeiyjBkBunWIVkpznp6qPtJqagIPUYesU4f5v6/okq5wcpaNKSkWbIvWVLaLGOiA1aeGJtbpMpyClbSr52puHpRRdvAiIEQ74yYh0JX8q96g=="; - String alipayPublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAiQkrz+emAuS1mB3KKDOMmAZRd/BlPbh7fAIHAqAj1+QCZNcV3o2BTLIIqnuKpSlFXDG3uDzp2VsBxcizXuBbFyPGylnD9CgCj5abyh3+FIHPAZ2IM3TtpqImZ0TSPGXrMli4Nir7MvZktgccCqQKCC4o6iaDGz+UwWwJUIPna8fm2tiTZ+KH150CZbKVj4ZGNpBh5XSV/1dRgyQIV9D/EwSbkZ0n6VgKQLJBi0C2UE3QB17aL1Ir6+gDXIDbknN8O7GUD3aMGdThYdSRUb5wp9CZ5qfV7vCS/CgaRo38nhH3NOzkTL+7v0m1ZDHPmqEkn9VzZN6sCQdL7PoAOjHOCwIDAQAB"; - AlipayConfig alipayConfig = new AlipayConfig(); - alipayConfig.setServerUrl("https://openapi.alipay.com/gateway.do"); - alipayConfig.setAppId("2021004174605036"); - alipayConfig.setPrivateKey(privateKey); - alipayConfig.setFormat("json"); - alipayConfig.setAlipayPublicKey(alipayPublicKey); - alipayConfig.setCharset("UTF-8"); - alipayConfig.setSignType("RSA2"); - return alipayConfig; - } - } diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/dto/config/AlipayConfigDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/dto/config/AlipayConfigDto.java index b23fa57e1..f2838086f 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/dto/config/AlipayConfigDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/dto/config/AlipayConfigDto.java @@ -28,7 +28,15 @@ public class AlipayConfigDto { /** * 支付宝支付域名 - * + * */ private String domain; + + public static AlipayConfigDto getDefaultConfig() { + return new AlipayConfigDto() + .setAppId("2021004174605036") + .setPrivateKey("MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQD48HaUoV7OH7os+9L01kHgxzwIhJick4OkFq4aHsntsXEJ J3gedhuEZtV8oHKZ30DPW12IJ4S8NXtpr8OWaqrAPFonf4wVaRY1d0yIAea57kfLEn9oOEEy4FzARgMNDkyxC+/3OUdGbLHpTjfVX3gusXsEhUDy1/WewihAkoNYF37+W3W/uVLzeWoPq0EcUbRv/G/t/p6gL69ltsMAiVFG4Q/Yk24YAN6lYgBPNLXUEwQ1Q+T+1omjfavHgvarKOp33z3JOUH+aGOmDsJ5Y9gyGtJzOCipAd8Zcv+T1ygsEzZYO1/gzcbPnfO1ShqStCHzssuw8FBVx2JdfQKXKMMNAgMBAAECggEAVTrO/pg5Q00titU1Jspsh67u6OOs9H605Ws2dI7yB8VmtAGlaJh7V1t14FN2qSP8poHbhhAxq9aLyGV7C3a9u09udnN+3J28EtYjh7VO732bavWMVXxdJjQWzWWrCb9JlpxFrlkYBA6W4w/6ob0sAqCVQ7jzwbEa0R4cde8ztOa5nysKSfr4YTSs0gqvoiC6fmg8eiRJraEQBoYz9VkKFtOhhh/4w5FhVcYQ2gQvZ3kK3QVuD1eJIQKlCtz8qaox9lXKDiZT4SCmnKshdUL0u5TYIcYeBjZmhJz0Q50KHcpZrCs5y7I0+vRBH3hU+TKSQt7ureymwhbwWMHScLV2gQKBgQD+58SHXhr5M8NGagAmTdsgmCnNv2kOYMd4STyPMY10SVwCv1Bk808ZuP+7e558J1b5/OuDLI5dLq6xrZ/1wLv1G++XqxI00hlFuWS5mUGJVcXotT1mw20rVeUILc7Qe3mLvbMGgfyKf4A7Qa5SSZ4bDeDTJYaFxyiQ281hMzDuPQKBgQD6AiL/Na2/uPH4CG6juwpjYvYVUcjK+7gbRwf3wWsWMpk90Z4ju2iUiP5c1J/oK9P+1T3PIr6M4Xjza8JJj+r9KC/PVB0gBv6vVM96cDpKUEy/UMpcn/T81vqj/Z+WEOODU8Ms6NiTTm+u9ldvpCjbu0u8M+9c0JeIyadJvSTFEQKBgQCsxmFyM3nq8YfpgU2qqNjfBeRH3faSVUy+nj1a/YZYjKS+A/i1BCnYUImeBVNN6chNV342ggvY4xxruDiU9Vcw8wd58O09Oi8BEIFSP6upL6cebUI6Fjo3xlegLJRiwV6INkNTJOYM5hD/mSxUACwXQFfkJipBINXBIgraWD1RLQKBgQCj49axWq0F6+WjZVOyPaD3uh37p9trRUxRhWTxw3fB23WdktaKMgbCqHOmwzP4bRLSEVQtf2dOz1gMqu14b8HqJvgAf/F/11YJ9hz09LEhmjZVjE68HZfqT7uK2W5OX8/lfXmK7TFcj6SjG5YB96lZMhTZ0WnufEd6QkdKDZYXIQKBgQD9GDTcIMbFwbEaKHnfZaTD3f876EGRgsgrCxwdEk7LBCRPwWo7yI929M4psIlpNwNeiyjBkBunWIVkpznp6qPtJqagIPUYesU4f5v6/okq5wcpaNKSkWbIvWVLaLGOiA1aeGJtbpMpyClbSr52puHpRRdvAiIEQ74yYh0JX8q96g==") + .setAlipayPublicKey("MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAiQkrz+emAuS1mB3KKDOMmAZRd/BlPbh7fAIHAqAj1+QCZNcV3o2BTLIIqnuKpSlFXDG3uDzp2VsBxcizXuBbFyPGylnD9CgCj5abyh3+FIHPAZ2IM3TtpqImZ0TSPGXrMli4Nir7MvZktgccCqQKCC4o6iaDGz+UwWwJUIPna8fm2tiTZ+KH150CZbKVj4ZGNpBh5XSV/1dRgyQIV9D/EwSbkZ0n6VgKQLJBi0C2UE3QB17aL1Ir6+gDXIDbknN8O7GUD3aMGdThYdSRUb5wp9CZ5qfV7vCS/CgaRo38nhH3NOzkTL+7v0m1ZDHPmqEkn9VzZN6sCQdL7PoAOjHOCwIDAQAB") + .setDomain("https://openapi.alipay.com/gateway.do"); + } } diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java index 625d2bbe3..a2ce8a410 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java @@ -1,5 +1,6 @@ package com.czg.third.wechat; +import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONWriter; import com.czg.third.wechat.dto.req.entry.WechatEntryReqDto; @@ -9,6 +10,11 @@ import com.wechat.pay.java.service.file.FileUploadService; import com.wechat.pay.java.service.file.model.FileUploadResponse; import lombok.extern.slf4j.Slf4j; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; import java.util.Map; /** @@ -20,8 +26,25 @@ import java.util.Map; @Slf4j public class WechatEntryManager { - public static void queryBankList(WechatPayConfigDto configDto, Integer offset, Integer limit) { - WechatReqUtils.getReq(configDto, "/v3/capital/capitallhh/banks/personal-banking", Map.of("offset", offset, "limit", limit)); + public static JSONObject queryBankList(WechatPayConfigDto configDto, Integer offset, Integer limit) { + String resp = WechatReqUtils.getReq(configDto, "/v3/capital/capitallhh/banks/corporate-banking", Map.of("offset", offset, "limit", limit)); + log.info("查询银行列表:{}", resp); + return JSONObject.parseObject(resp); + } + + public static JSONObject queryBankBranchList(WechatPayConfigDto configDto, String bankAliceCode, String cityCode, Integer offset, Integer limit) { + String resp = WechatReqUtils.getReq(configDto, "/v3/capital/capitallhh/banks/" + bankAliceCode + "/branches", Map.of("city_code", cityCode, "offset", offset, "limit", limit)); + return JSONObject.parseObject(resp); + } + + public static JSONObject queryProvinceList(WechatPayConfigDto configDto) { + String resp = WechatReqUtils.getReq(configDto, "/v3/capital/capitallhh/areas/provinces", Map.of()); + return JSONObject.parseObject(resp); + } + + public static JSONObject queryCityList(WechatPayConfigDto configDto, String provinceCode) { + String resp = WechatReqUtils.getReq(configDto, "/v3/capital/capitallhh/areas/provinces/" + provinceCode + "/cities", Map.of()); + return JSONObject.parseObject(resp); } /** @@ -113,7 +136,7 @@ public class WechatEntryManager { return "upload_" + System.currentTimeMillis() + ".png"; } - public static void main(String[] args) { + public static void main(String[] args) throws IOException { WechatPayConfigDto dto = new WechatPayConfigDto() .setMerchantId("1643779408") .setApiV3Key("a92baac5eb7a36ed8ec198113e769a03") @@ -160,10 +183,19 @@ public class WechatEntryManager { .setPublicKeyId("PUB_KEY_ID_0116437794082025111000382377001000") .setDomain("https://api.mch.weixin.qq.com"); -// queryBankList(dto, 0, 10); + int offset = 0; + Integer limit = 100; +// JSONObject resp = queryBankList(dto, offset, limit); - String string = uploadImage(dto, "https://czg-qr-order.oss-cn-beijing.aliyuncs.com/indexs/shuangbackground.png"); - log.info("图片上传成功:{}", string); +// queryBankBranchList(dto, "1000009561", "110000", offset, limit); + queryBankBranchList(dto, "1000009561", "29", offset, limit); + +// queryProvinceList(dto); +// queryCityList(dto, "28"); + + +// String string = uploadImage(dto, "https://czg-qr-order.oss-cn-beijing.aliyuncs.com/indexs/shuangbackground.png"); +// log.info("图片上传成功:{}", string); // Config config = WechatConfig.getRsaConfig(dto); // PrivacyEncryptor encryptor = config.createEncryptor(); diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatReqUtils.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatReqUtils.java index f15522400..57a831c80 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatReqUtils.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatReqUtils.java @@ -32,6 +32,10 @@ public class WechatReqUtils { url = Arrays.stream(params.entrySet().toArray(new Map.Entry[0])) .map(entry -> entry.getKey() + "=" + URLEncoder.encode(entry.getValue().toString(), StandardCharsets.UTF_8)) .collect(Collectors.joining("&", url + "?", "")); + + // 如果最后没有参数,则去掉多余的 "?" + url = url.endsWith("?") ? url.substring(0, url.length() - 1) : url; + return req(configDto, url, "GET", ""); } diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/config/WechatPayConfigDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/config/WechatPayConfigDto.java index 262d32fbd..78e544e8b 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/config/WechatPayConfigDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/config/WechatPayConfigDto.java @@ -46,4 +46,52 @@ public class WechatPayConfigDto { * */ private String domain; + + public static WechatPayConfigDto getDefaultConfig() { + return new WechatPayConfigDto() + .setMerchantId("1643779408") + .setApiV3Key("a92baac5eb7a36ed8ec198113e769a03") + .setSerialNumber("4DE9BAC2EA584C3F274F694C9753CA814C4E9BF4") + .setPublicKey(""" + -----BEGIN PUBLIC KEY----- + MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtbeWXEEjBaYtw2OyM+SC + aCEMbryRXi4duKxx3vYG4rUVix+d5/Jz7Khev4Upml9zC+Xxvv/G9bHWAUyolzqD + wefahGurIxr43r4GJVnQ4i5G6BbBVw5d4Vuz0y/9Zd14zmc/EmBpT0Ml26H7tOZl + n1LSbQ4xNFkrRKrNEcExBLxkCd+K5K2TREZznywIi0izbHImvuzM8IneuR51FiqK + pdFnAjTwb126EIj6ECkL6KLCl8RWqpfiX8SFiolSQLs1/w79O0sIUk96X2zWpnoW + rTDFatPif/VEKl3y2dTlxxDxoZtVi48yTDW00OMzVl5D67oX3FVK0KsjHJSCfGlZ + 6wIDAQAB + -----END PUBLIC KEY-----""") + .setPrivateKey(""" + -----BEGIN PRIVATE KEY----- + MIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQDqnAZhTxT572fo + 6wvSr8Rt0vRXg+EFKC6UvUiNE24oocQU5fjedX9KL/+fmoqay/xqIxvxvCNFTs4J + zlMqavSl6bMWCpjvf/Ry82JmN1v2kJEO4lgP8BsEiqlUpObCH8BMAVUOn1j+9q4Q + uZJJcbtRvec2fNweDM8EJp4B7RlUdDbHm86lfcDVp8iini7VjDp6D7aHT+C8A8OT + ugxQIquDec778wVd9r2Sv3+t6rAzFs+n+Zu++2xtFEPhO5N0wjrLHaukl+9crU+1 + lktjDzcPd07SwGZ+A+3BTmW3UCramI3506e/3MWBECB7ge+gM4URAV0nJJCLH/Im + WgEvPMr5AgMBAAECggEBAKv+wraoMWqiVv1tA/froAgbtcJLDranJK8qrXuvmPz0 + yzm+91qvrSgIVFEADUk67swo/R2Vng37nhWWS2Y3jy/rSr2H+2Lp3Z5ATA0/3I3A + onfU/FaC4mvL9CP32KzMdj/CYkccDzSsSCQ+x75MQNXGcTGDDCSDo2kZnpEu73j3 + aqvO1jbqTGWigRfjOIaIhStjQIT8nEm/3mJ4f5dM9M6FMz33mhax8EahSgvdahYB + t45iaGOWw81OJhmry47EvpwjXBl7jtO2HX3LiLbq5Ebcwu1zqDz5NM7ttnnGAqWC + 6y7JN5Vt4wPYrCydiUDe7dj0looffr2yw6MkNfYjLGECgYEA+FAvbEInQEi9YguS + CQtLHngqvYeai66tvyykog9o38KHnPGx2Myf+rn/Hcp7KNRfjd5G34CCNg7KLnrx + YIYh6+2bY3jirzdYUxuNKGbvM4gky/6M/P9zHF/uALKOE02yArdqemf4UxUvrYCc + JdXsAMqvbpdvW1aGgNRB32YCkG0CgYEA8d89vawsCjNCEUh0VWTMoBLFoex3qBMZ + rfzYQeBo6bDCRlAlUVzl+ouBUxSYxP/U8rzeNaRzGUwRLmlGMjyIr58FBlHsg2cR + DlsX3HVCUjpS6sgPXOqakdiLfhMcHZAspislSyVfeS3TbUWiA45+5PuNUq+EZYwl + ESsB1+yfRT0CgYEA0Ct49ksnWM8iZbXJgeeD3FFlk2rBd2TDqEem5W4Bv8T3p+0/ + 6b7yR2HyrGj5gys3yFmWFP1JLESN3xWWkhMhEQcrg+LuN3Iwi8vHNR3GXu892f7W + 96q4OAt8Hf2S+j/igkB99YyANDbIt63gOh/zMF67X/14j5wkOpC3gK+maqkCgYEA + s7nIrPoUt3ejLiiCmTmPe5q3VDzcJP4cZNau8zSHgK6hjZHcSPsYwPWMoWl6o1fe + qoiBLacHB9MoKS58xLOKdcVZ/Ho/ntylJd+2eVCAeY1xM5h5IfgJ5znbXVFh4O3S + 357L1Wzt5qOQqW/GlZH65LevKbPWU4axvHISqpnfN5kCgYEAqiqLuAPu84VSsqsE + GFh25t+1f0JY1sNfilE3/t9AdQeeCFv/5z9KB1kMt3a5ZFeVonsFIvCyaOJjhSkj + 4HCB94vWS7NuN5G9r874lMaPbZYQGwrcVaf265tN7cYYr3gUx1qB6+u+fh/kcft1 + BBmTzhb0zp5k8ngwAkA1g/LK204= + -----END PRIVATE KEY-----""") + .setPublicKeyId("PUB_KEY_ID_0116437794082025111000382377001000") + .setDomain("https://api.mch.weixin.qq.com"); + } } From 8501e21cf4de51a340ed1b692b06aefcf809979d Mon Sep 17 00:00:00 2001 From: gong <1157756119@qq.com> Date: Tue, 6 Jan 2026 17:45:56 +0800 Subject: [PATCH 13/19] =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E5=9B=BE=E7=89=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/czg/mq/OrderMqListener.java | 3 - .../src/main/java/com/czg/EntryManager.java | 251 +++++++++++++++++- .../czg/dto/req/BusinessLicenceInfoDto.java | 2 +- .../main/java/com/czg/dto/req/ImageDto.java | 26 ++ .../com/czg/dto/req/LegalPersonInfoDto.java | 8 +- .../com/czg/dto/req/MerchantBaseInfoDto.java | 31 +++ .../com/czg/dto/req/SettlementInfoDto.java | 23 +- .../java/com/czg/dto/req/StoreInfoDto.java | 6 +- .../czg/third/alipay/AlipayEntryManager.java | 32 +-- .../com/czg/third/wechat/WechatConfig.java | 7 +- .../czg/third/wechat/WechatEntryManager.java | 10 +- .../main/java/com/czg/utils/CommonUtil.java | 20 ++ 12 files changed, 357 insertions(+), 62 deletions(-) create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/ImageDto.java diff --git a/cash-api/order-server/src/main/java/com/czg/mq/OrderMqListener.java b/cash-api/order-server/src/main/java/com/czg/mq/OrderMqListener.java index e8054e747..5d917ce97 100644 --- a/cash-api/order-server/src/main/java/com/czg/mq/OrderMqListener.java +++ b/cash-api/order-server/src/main/java/com/czg/mq/OrderMqListener.java @@ -48,9 +48,6 @@ public class OrderMqListener { orderInfoCustomService.updateOrderDetailStatus(Long.valueOf(finalInfo)); }); - info = info.replace("UP_ORDER_DETAIL:", ""); - System.out.println(info); - } @RabbitListener(queues = {"${spring.profiles.active}-" + RabbitConstants.Queue.ORDER_STOCK_QUEUE}) diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/EntryManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/EntryManager.java index d57762c28..b988f1abb 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/EntryManager.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/EntryManager.java @@ -1,7 +1,12 @@ package com.czg; +import cn.hutool.core.util.StrUtil; +import com.czg.dto.req.*; import com.czg.dto.resp.BankBranchDto; +import com.czg.exception.CzgException; import com.czg.third.alipay.AlipayEntryManager; +import com.czg.third.wechat.WechatEntryManager; +import com.czg.utils.AssertUtil; import java.util.List; @@ -16,16 +21,252 @@ public class EntryManager { /** * 查询银行支行列表 * - * @param province 省份 陕西省 - * @param city 城市 西安市 - * @param instId 顶级机构ID CMB + * @param province 省份 陕西省 + * @param city 城市 西安市 + * @param instId 顶级机构ID CMB */ public static List queryBankBranchList(String province, String city, String instId) { return AlipayEntryManager.queryBankBranchList(instId, province, city); } + /** + * 进件 + * 请先执行: + * 1. {@link com.czg.EntryManager#verifyEntryParam(AggregateMerchantDto)} 验证进件参数 + * 2. {@link com.czg.EntryManager#uploadParamImage(AggregateMerchantDto)} 上传图片至第三方 + * @param reqDto 进件参数 + */ + public static void entryMerchant(AggregateMerchantDto reqDto) { + + } + + /** + * 上传图片至第三方 + * 请先执行 {@link com.czg.EntryManager#verifyEntryParam(AggregateMerchantDto)} 验证进件参数 + * @param reqDto 进件参数 + */ + public static void uploadParamImage(AggregateMerchantDto reqDto) { + MerchantBaseInfoDto baseInfo = reqDto.getMerchantBaseInfo(); + // 联系人身份证反面 + if (baseInfo.getContactIdCardBackPic() != null) { + uploadImageToThird(baseInfo.getContactIdCardBackPic()); + } + // 联系人身份证正面 + if (baseInfo.getContactIdCardFrontPic() != null) { + uploadImageToThird(baseInfo.getContactIdCardFrontPic()); + } + + LegalPersonInfoDto legalPersonInfo = reqDto.getLegalPersonInfo(); + // 法人身份证反面 + if (legalPersonInfo.getIdCardBackPic() != null) { + uploadImageToThird(legalPersonInfo.getIdCardBackPic()); + } + // 法人身份证正面 + if (legalPersonInfo.getIdCardFrontPic() != null) { + uploadImageToThird(legalPersonInfo.getIdCardFrontPic()); + } + // 法人手持身份证 + if (legalPersonInfo.getIdCardHandPic() != null) { + uploadImageToThird(legalPersonInfo.getIdCardHandPic()); + } + + BusinessLicenceInfoDto businessLicenceInfo = reqDto.getBusinessLicenceInfo(); + // 营业执照 + if (businessLicenceInfo.getLicensePic() != null) { + uploadImageToThird(businessLicenceInfo.getLicensePic()); + } + + SettlementInfoDto settlementInfo = reqDto.getSettlementInfo(); + // 银行卡背面 + if (settlementInfo.getBankCardBackPic() != null) { + uploadImageToThird(settlementInfo.getBankCardBackPic()); + } + // 银行卡正面 + if (settlementInfo.getBankCardFrontPic() != null) { + uploadImageToThird(settlementInfo.getBankCardFrontPic()); + } + // 开户许可证 + if (settlementInfo.getOpenAccountLicencePic() != null) { + uploadImageToThird(settlementInfo.getOpenAccountLicencePic()); + } + // 非法人手持授权函 + if (settlementInfo.getNoLegalHandSettleAuthPic() != null) { + uploadImageToThird(settlementInfo.getNoLegalHandSettleAuthPic()); + } + // 非法人授权函 + if (settlementInfo.getNoLegalSettleAuthPic() != null) { + uploadImageToThird(settlementInfo.getNoLegalSettleAuthPic()); + } + // 非法人身份证反面 + if (settlementInfo.getNoLegalIdCardBackPic() != null) { + uploadImageToThird(settlementInfo.getNoLegalIdCardBackPic()); + } + // 非法人身份证正面 + if (settlementInfo.getNoLegalIdCardFrontPic() != null) { + uploadImageToThird(settlementInfo.getNoLegalIdCardFrontPic()); + } + + StoreInfoDto storeInfo = reqDto.getStoreInfo(); + // 店内图片 + if (storeInfo.getInsidePic() != null) { + uploadImageToThird(storeInfo.getInsidePic()); + } + // 门店门头图片 + if (storeInfo.getDoorPic() != null) { + uploadImageToThird(storeInfo.getDoorPic()); + } + // 收银台图片 + if (storeInfo.getCashierDeskPic() != null) { + uploadImageToThird(storeInfo.getCashierDeskPic()); + } + } + + private static void uploadImageToThird(ImageDto dto) { + if (StrUtil.isBlank(dto.getWechatId())) { + String image = WechatEntryManager.uploadImage(dto.getUrl()); + dto.setWechatId(image); + } + if (StrUtil.isBlank(dto.getAlipayId())) { + String image = AlipayEntryManager.uploadImage(dto.getUrl()); + dto.setAlipayId(image); + } + } + + /** + * 验证进件参数 + * + * @param reqDto 进件参数 + */ + public static void verifyEntryParam(AggregateMerchantDto reqDto) { + AssertUtil.isBlank(reqDto.getMerchantCode(), "商户编号不能为空"); + + AssertUtil.isNull(reqDto.getMerchantBaseInfo(), "商户基础信息不能为空"); + + MerchantBaseInfoDto baseInfo = reqDto.getMerchantBaseInfo(); + AssertUtil.isBlank(baseInfo.getUserType(), "商户类型不能为空"); + AssertUtil.isBlank(baseInfo.getShortName(), "商户简称不能为空"); + AssertUtil.isBlank(baseInfo.getCertType(), "证件类型不能为空"); + if (!"0".equals(baseInfo.getCertType())) { + throw new CzgException("证件类型错误"); + } + AssertUtil.isBlank(baseInfo.getMccCode(), "商户行业编码不能为空"); + if ("SUPER".equals(baseInfo.getContactPersonType())) { + AssertUtil.isBlank(baseInfo.getContactName(), "联系人姓名不能为空"); + AssertUtil.isBlank(baseInfo.getContactPersonId(), "联系人身份证号不能为空"); + AssertUtil.isBlank(baseInfo.getContactPhone(), "联系人电话不能为空"); + AssertUtil.isBlank(baseInfo.getContactAddr(), "联系人地址不能为空"); + AssertUtil.isBlank(baseInfo.getContactEmail(), "联系人邮箱不能为空"); + AssertUtil.isBlank(baseInfo.getContactIdStartDate(), "联系人身份证开始日期不能为空"); + AssertUtil.isBlank(baseInfo.getContactPersonIdEndDate(), "联系人身份证到期日期不能为空"); + AssertUtil.isNull(baseInfo.getContactIdCardBackPic(), "联系人身份证反面不能为空"); + AssertUtil.isBlank(baseInfo.getContactIdCardBackPic().getUrl(), "联系人身份证反面不能为空"); + AssertUtil.isNull(baseInfo.getContactIdCardFrontPic(), "联系人身份证正面不能为空"); + AssertUtil.isBlank(baseInfo.getContactIdCardFrontPic().getUrl(), "联系人身份证正面不能为空"); + } + AssertUtil.isBlank(baseInfo.getCompanyChildType(), "商户类型不能为空"); + if ("0".equals(baseInfo.getUserType())) { + // 个体商户, 暂无其他校验 + } else if ("1".equals(baseInfo.getUserType())) { + if (!"1".equals(baseInfo.getCompanyChildType()) && !"2".equals(baseInfo.getCompanyChildType()) && !"3".equals(baseInfo.getCompanyChildType())) { + throw new CzgException("商户类型错误"); + } + } else { + throw new CzgException("商户类型错误"); + } + + AssertUtil.isNull(reqDto.getBusinessLicenceInfo(), "营业执照信息不能为空"); + BusinessLicenceInfoDto businessLicenceInfo = reqDto.getBusinessLicenceInfo(); + AssertUtil.isBlank(businessLicenceInfo.getLicenceNo(), "营业执照编号不能为空"); + AssertUtil.isBlank(businessLicenceInfo.getLicenceName(), "营业执照名称不能为空"); + AssertUtil.isBlank(businessLicenceInfo.getRegisteredAddress(), "营业执照注册地址不能为空"); + AssertUtil.isBlank(businessLicenceInfo.getLicenceStartDate(), "营业执照开始日期不能为空"); + AssertUtil.isBlank(businessLicenceInfo.getLicenceEndDate(), "营业执照到期日期不能为空"); + AssertUtil.isNull(businessLicenceInfo.getLicensePic(), "营业执照名称不能为空"); + AssertUtil.isBlank(businessLicenceInfo.getLicensePic().getUrl(), "营业执照名称不能为空"); + + + AssertUtil.isNull(reqDto.getLegalPersonInfo(), "法人信息不能为空"); + LegalPersonInfoDto legalPersonInfo = reqDto.getLegalPersonInfo(); + AssertUtil.isBlank(legalPersonInfo.getLegalPersonName(), "法人姓名不能为空"); + AssertUtil.isBlank(legalPersonInfo.getLegalPersonId(), "法人身份证号不能为空"); + AssertUtil.isBlank(legalPersonInfo.getLegalIdStartDate(), "法人身份证开始日期不能为空"); + AssertUtil.isBlank(legalPersonInfo.getLegalPersonIdEndDate(), "法人身份证到期日期不能为空"); + AssertUtil.isBlank(legalPersonInfo.getLegalPersonPhone(), "法人电话不能为空"); + AssertUtil.isBlank(legalPersonInfo.getLegalGender(), "法人性别不能为空"); + AssertUtil.isBlank(legalPersonInfo.getLegalAddress(), "法人地址不能为空"); + AssertUtil.isNull(legalPersonInfo.getIdCardHandPic(), "法人身份证手持不能为空"); + AssertUtil.isBlank(legalPersonInfo.getIdCardHandPic().getUrl(), "法人身份证手持不能为空"); + AssertUtil.isNull(legalPersonInfo.getIdCardFrontPic(), "法人身份证正面不能为空"); + AssertUtil.isBlank(legalPersonInfo.getIdCardFrontPic().getUrl(), "法人身份证正面不能为空"); + AssertUtil.isNull(legalPersonInfo.getIdCardBackPic(), "法人身份证反面不能为空"); + AssertUtil.isBlank(legalPersonInfo.getIdCardBackPic().getUrl(), "法人身份证反面不能为空"); + + AssertUtil.isNull(reqDto.getStoreInfo(), "门店信息不能为空"); + StoreInfoDto storeInfo = reqDto.getStoreInfo(); + AssertUtil.isBlank(storeInfo.getMercProvId(), "门店省ID不能为空"); + AssertUtil.isBlank(storeInfo.getMercCityId(), "门店市ID不能为空"); + AssertUtil.isBlank(storeInfo.getMercAreaId(), "门店区ID不能为空"); + AssertUtil.isBlank(storeInfo.getMercProv(), "门店省不能为空"); + AssertUtil.isBlank(storeInfo.getMercCity(), "门店市不能为空"); + AssertUtil.isBlank(storeInfo.getMercArea(), "门店区不能为空"); + AssertUtil.isBlank(storeInfo.getBusinessAddress(), "门店营业地址不能为空"); + AssertUtil.isNull(storeInfo.getInsidePic(), "门店营业地址不能为空"); + AssertUtil.isBlank(storeInfo.getInsidePic().getUrl(), "门店营业地址不能为空"); + AssertUtil.isNull(storeInfo.getDoorPic(), "门店门头照不能为空"); + AssertUtil.isBlank(storeInfo.getDoorPic().getUrl(), "门店门头照不能为空"); + AssertUtil.isNull(storeInfo.getCashierDeskPic(), "门店收银台照不能为空"); + AssertUtil.isBlank(storeInfo.getCashierDeskPic().getUrl(), "门店收银台照不能为空"); + + + AssertUtil.isNull(reqDto.getSettlementInfo(), "结算信息不能为空"); + SettlementInfoDto settlementInfo = reqDto.getSettlementInfo(); + AssertUtil.isBlank(settlementInfo.getSettlementCardNo(), "结算卡号不能为空"); + AssertUtil.isBlank(settlementInfo.getSettlementName(), "结算账户户名不能为空"); + AssertUtil.isBlank(settlementInfo.getBankMobile(), "结算银行预留手机号不能为空"); + AssertUtil.isBlank(settlementInfo.getSettlementCardType(), "结算卡类型不能为空"); + AssertUtil.isBlank(settlementInfo.getOpenAccProvinceId(), "结算开户行省ID不能为空"); + AssertUtil.isBlank(settlementInfo.getOpenAccCityId(), "结算开户行市ID不能为空"); + AssertUtil.isBlank(settlementInfo.getOpenAccAreaId(), "结算开户行区ID不能为空"); + AssertUtil.isBlank(settlementInfo.getOpenAccProvince(), "结算开户行省不能为空"); + AssertUtil.isBlank(settlementInfo.getOpenAccCity(), "结算开户行市不能为空"); + AssertUtil.isBlank(settlementInfo.getOpenAccArea(), "结算开户行区不能为空"); + if ("11".equals(settlementInfo.getSettlementCardType())) { + // 11 对私借记卡(结算卡正面照、结算卡反面照图片必传) + AssertUtil.isNull(settlementInfo.getBankCardFrontPic(), "结算卡正面照不能为空"); + AssertUtil.isBlank(settlementInfo.getBankCardFrontPic().getUrl(), "结算卡正面照不能为空"); + AssertUtil.isNull(settlementInfo.getBankCardBackPic(), "结算卡反面照不能为空"); + AssertUtil.isBlank(settlementInfo.getBankCardBackPic().getUrl(), "结算卡反面照不能为空"); + AssertUtil.isBlank(settlementInfo.getSettlementType(), "结算类型不能为空"); + if ("0".equals(settlementInfo.getSettlementType())) { + // 非法人结算 + AssertUtil.isBlank(settlementInfo.getNoLegalName(), "非法人姓名不能为空"); + AssertUtil.isBlank(settlementInfo.getNoLegalId(), "非法人身份证号不能为空"); + AssertUtil.isNull(settlementInfo.getNoLegalIdCardFrontPic(), "非法人身份证正面不能为空"); + AssertUtil.isBlank(settlementInfo.getNoLegalIdCardFrontPic().getUrl(), "非法人身份证正面不能为空"); + AssertUtil.isNull(settlementInfo.getNoLegalIdCardBackPic(), "非法人身份证反面不能为空"); + AssertUtil.isBlank(settlementInfo.getNoLegalIdCardBackPic().getUrl(), "非法人身份证反面不能为空"); + AssertUtil.isNull(settlementInfo.getNoLegalSettleAuthPic(), "非法人结算授权书不能为空"); + AssertUtil.isBlank(settlementInfo.getNoLegalSettleAuthPic().getUrl(), "非法人结算授权书不能为空"); + } else if ("1".equals(settlementInfo.getSettlementType())) { + // 法人结算 暂无处理 + } else { + throw new CzgException("结算类型错误"); + } + } else if ("21".equals(settlementInfo.getSettlementCardType())) { + // 21 对公借记卡(只须结算卡正面照片) + AssertUtil.isNull(settlementInfo.getOpenAccountLicencePic(), "开户许可证不能为空"); + AssertUtil.isBlank(settlementInfo.getOpenAccountLicencePic().getUrl(), "开户许可证不能为空"); + } else { + throw new CzgException("结算卡类型错误"); + } + + } + public static void main(String[] args) { - List dtoList = queryBankBranchList("陕西省", "西安市", "CMB"); - System.out.println(dtoList); + + AggregateMerchantDto merchantDto = new AggregateMerchantDto(); + merchantDto.setMerchantCode("20220106000000000001"); + + verifyEntryParam(merchantDto); } } diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/BusinessLicenceInfoDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/BusinessLicenceInfoDto.java index a4ac1c96c..bd6380ca2 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/BusinessLicenceInfoDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/BusinessLicenceInfoDto.java @@ -38,5 +38,5 @@ public class BusinessLicenceInfoDto { /** * 营业执照 */ - private String licensePic; + private ImageDto licensePic; } diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/ImageDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/ImageDto.java new file mode 100644 index 000000000..5784464d7 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/ImageDto.java @@ -0,0 +1,26 @@ +package com.czg.dto.req; + +import lombok.Data; + +/** + * @author yjjie + * @date 2026/1/6 16:53 + */ +@Data +public class ImageDto { + + /** + * 图片 url + */ + private String url; + + /** + * 微信 图片 mediaId + */ + private String wechatId; + + /** + * 支付宝 图片 mediaId + */ + private String alipayId; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/LegalPersonInfoDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/LegalPersonInfoDto.java index 5f152b459..203cbfdc4 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/LegalPersonInfoDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/LegalPersonInfoDto.java @@ -54,15 +54,17 @@ public class LegalPersonInfoDto { /** * 身份证手持 图片 */ - private String idCardHandPic; + private ImageDto idCardHandPic; /** + * 【必填】 * 身份证正面 */ - private String idCardFrontPic; + private ImageDto idCardFrontPic; /** + * 【必填】 * 身份证反面 */ - private String idCardBackPic; + private ImageDto idCardBackPic; } diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/MerchantBaseInfoDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/MerchantBaseInfoDto.java index 9de2b790f..3515e8dc0 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/MerchantBaseInfoDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/MerchantBaseInfoDto.java @@ -38,6 +38,13 @@ public class MerchantBaseInfoDto { */ private String mccCode; + /** + * 联系人类型 + * LEGAL: 经营者/法定代表人 + * SUPER: 经办人 + */ + private String contactPersonType = "LEGAL"; + /** * 【必填】 * 联系人姓名 @@ -50,6 +57,30 @@ public class MerchantBaseInfoDto { */ private String contactPersonId; + /** + * 【必填】 + * 联系人身份证开始日期 + */ + private String contactIdStartDate; + + /** + * 【必填】 + * 联系人身份证到期日期 + */ + private String contactPersonIdEndDate; + + /** + * 【必填】 + * 联系人身份证背面 + */ + private ImageDto contactIdCardBackPic; + + /** + * 【必填】 + * 联系人身份证正面 + */ + private ImageDto contactIdCardFrontPic; + /** * 【必填】 * 联系人电话 diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/SettlementInfoDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/SettlementInfoDto.java index 7df35f646..b58705cea 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/SettlementInfoDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/SettlementInfoDto.java @@ -4,6 +4,7 @@ import lombok.Data; /** * 结算信息 + * * @author yjjie * @date 2026/1/6 10:22 */ @@ -11,19 +12,19 @@ import lombok.Data; public class SettlementInfoDto { /** - * 法人结算 0:非法人结算, 1:法人结算 + * 结算类型 0:非法人结算, 1:法人结算 */ - private String codeLegalPersonAcc; + private String settlementType; /** * 非法人姓名 */ - private String unincorporatedName; + private String noLegalName; /** * 非法人身份证号码 */ - private String unincorporatedId; + private String noLegalId; /** * 结算卡类型 必填 11 对私借记卡(结算卡正面照、结算卡反面照图片必传) 21 对公借记卡(只须结算卡正面照片) @@ -98,35 +99,35 @@ public class SettlementInfoDto { /** * 银行卡正面 */ - private String bankCardFrontPic; + private ImageDto bankCardFrontPic; /** * 银行卡反面 */ - private String bankCardBackPic; + private ImageDto bankCardBackPic; /** * 开户许可证 */ - private String openAccountLicence; + private ImageDto openAccountLicencePic; /** * 非法人手持结算授权书 */ - private String nonLegHandSettleAuthPic; + private ImageDto noLegalHandSettleAuthPic; /** * 非法人结算授权书 */ - private String nonLegSettleAuthPic; + private ImageDto noLegalSettleAuthPic; /** * 非法人身份证正面 */ - private String nonLegIdCardFrontPic; + private ImageDto noLegalIdCardFrontPic; /** * 非法人身份证反面 */ - private String nonLegIdCardBackPic; + private ImageDto noLegalIdCardBackPic; } diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/StoreInfoDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/StoreInfoDto.java index 4d6111873..ee4c32613 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/StoreInfoDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/StoreInfoDto.java @@ -52,15 +52,15 @@ public class StoreInfoDto { /** * 经营场所内设照片 */ - private String insidePic; + private ImageDto insidePic; /** * 门头照 */ - private String doorPic; + private ImageDto doorPic; /** * 收银台照片 */ - private String cashierDeskPic; + private ImageDto cashierDeskPic; } diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayEntryManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayEntryManager.java index 190f777e9..03b9ef58d 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayEntryManager.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayEntryManager.java @@ -1,15 +1,10 @@ package com.czg.third.alipay; import com.alibaba.fastjson2.JSONArray; -import com.alibaba.fastjson2.JSONObject; -import com.alipay.api.AlipayApiException; import com.alipay.api.DefaultAlipayClient; import com.alipay.api.domain.AlipayFinancialnetAuthPbcnameQueryModel; -import com.alipay.api.domain.AntMerchantExpandIndirectZftSimplecreateModel; import com.alipay.api.request.AlipayFinancialnetAuthPbcnameQueryRequest; -import com.alipay.api.request.AntMerchantExpandIndirectZftSimplecreateRequest; import com.alipay.api.response.AlipayFinancialnetAuthPbcnameQueryResponse; -import com.alipay.api.response.AntMerchantExpandIndirectZftSimplecreateResponse; import com.alipay.v3.ApiClient; import com.alipay.v3.ApiException; import com.alipay.v3.Configuration; @@ -19,17 +14,13 @@ import com.alipay.v3.model.*; import com.alipay.v3.util.model.AlipayConfig; import com.czg.dto.resp.BankBranchDto; import com.czg.utils.CommonUtil; -import com.czg.third.alipay.dto.config.AlipayConfigDto; - -import java.util.ArrayList; -import java.util.List; -import java.util.regex.Pattern; - import lombok.extern.slf4j.Slf4j; import java.io.File; import java.nio.file.Files; import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; /** * 支付宝进件管理 @@ -41,8 +32,6 @@ import java.nio.file.Path; */ @Slf4j public class AlipayEntryManager { - // 匹配常见的图片扩展名 - private static final Pattern PATTERN = Pattern.compile("\\.(jpg|jpeg|png|gif|bmp|webp|svg|ico)(?:[\\?#]|$)", Pattern.CASE_INSENSITIVE); public static String uploadImage(String url) { try { @@ -59,7 +48,7 @@ public class AlipayEntryManager { AntMerchantExpandIndirectImageUploadModel model = new AntMerchantExpandIndirectImageUploadModel(); // 从 url 中获取图片 后缀 - model.setImageType(extractImageExtension(url)); + model.setImageType(CommonUtil.extractImageExtension(url)); AntMerchantExpandIndirectImageUploadResponseModel upload = imageApi.upload(model, file); return upload.getImageId(); } catch (Exception e) { @@ -96,21 +85,6 @@ public class AlipayEntryManager { } } - /** - * 使用正则表达式提取图片后缀 - */ - public static String extractImageExtension(String imageUrl) { - java.util.regex.Matcher matcher = PATTERN.matcher(imageUrl); - - if (matcher.find()) { - String extension = matcher.group(1).toLowerCase(); - // 处理jpeg的情况 - return "jpeg".equals(extension) ? "jpg" : extension; - } - // 默认后缀 - return "png"; - } - public static void main(String[] args) { queryBankBranchList("CMB", "西安市", "陕西省"); diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatConfig.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatConfig.java index 8842485f8..9dc172994 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatConfig.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatConfig.java @@ -19,6 +19,9 @@ public class WechatConfig { * @return 微信支付配置 */ public static Config getRsaConfig(WechatPayConfigDto dto) { + if (dto == null) { + dto = WechatPayConfigDto.getDefaultConfig(); + } return new RSAPublicKeyConfig.Builder() .merchantId(dto.getMerchantId()) .privateKey(dto.getPrivateKey()) @@ -29,7 +32,7 @@ public class WechatConfig { .build(); } - public static FileUploadService getFileUploadService(Config config) { + public static FileUploadService getFileUploadServiceByConfig(Config config) { return new FileUploadService.Builder() .config(config) .build(); @@ -41,7 +44,7 @@ public class WechatConfig { * @return 文件上传服务 */ public static FileUploadService getFileUploadService(WechatPayConfigDto dto) { - return getFileUploadService(getRsaConfig(dto)); + return getFileUploadServiceByConfig(getRsaConfig(dto)); } } diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java index a2ce8a410..6fee949ea 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java @@ -43,7 +43,7 @@ public class WechatEntryManager { } public static JSONObject queryCityList(WechatPayConfigDto configDto, String provinceCode) { - String resp = WechatReqUtils.getReq(configDto, "/v3/capital/capitallhh/areas/provinces/" + provinceCode + "/cities", Map.of()); + String resp = WechatReqUtils.getReq(configDto, "/v3/capital/capitallhh/areas/provinces/" + provinceCode + "/cities", Map.of()); return JSONObject.parseObject(resp); } @@ -64,14 +64,14 @@ public class WechatEntryManager { /** * 上传图片 * - * @param configDto 配置 * @param url 图片URL * @return 图片ID */ - public static String uploadImage(WechatPayConfigDto configDto, String url) { + public static String uploadImage(String url) { + WechatPayConfigDto configDto = WechatPayConfigDto.getDefaultConfig(); // 校验入参 - if (configDto == null || url == null || url.trim().isEmpty()) { - log.error("上传图片失败:配置或URL参数为空"); + if (url == null || url.trim().isEmpty()) { + log.error("上传图片失败:URL参数为空"); return ""; } diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/utils/CommonUtil.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/utils/CommonUtil.java index ab7becdb8..b46e3cc5e 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/utils/CommonUtil.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/utils/CommonUtil.java @@ -6,6 +6,7 @@ import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; +import java.util.regex.Pattern; /** * @author yjjie @@ -13,6 +14,25 @@ import java.net.http.HttpResponse; */ @Slf4j public class CommonUtil { + + // 匹配常见的图片扩展名 + private static final Pattern PATTERN = Pattern.compile("\\.(jpg|jpeg|png|gif|bmp|webp|svg|ico)(?:[\\?#]|$)", Pattern.CASE_INSENSITIVE); + + /** + * 使用正则表达式提取图片后缀 + */ + public static String extractImageExtension(String imageUrl) { + java.util.regex.Matcher matcher = PATTERN.matcher(imageUrl); + + if (matcher.find()) { + String extension = matcher.group(1).toLowerCase(); + // 处理jpeg的情况 + return "jpeg".equals(extension) ? "jpg" : extension; + } + // 默认后缀 + return "png"; + } + /** * 下载图片 * @param url 图片地址 From 193f4d016a83bcfe3bbab1267fe97070e4a546a9 Mon Sep 17 00:00:00 2001 From: gong <1157756119@qq.com> Date: Tue, 6 Jan 2026 18:36:11 +0800 Subject: [PATCH 14/19] =?UTF-8?q?=E5=B0=81=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/czg/EntryManager.java | 122 +++++++++----- .../java/com/czg/dto/resp/EntryRespDto.java | 34 ++++ .../com/czg/third/alipay/AlipayClient.java | 19 +++ .../czg/third/alipay/AlipayEntryManager.java | 33 +++- .../czg/third/wechat/WechatEntryManager.java | 57 +++---- .../java/com/czg/utils/AsyncTaskExecutor.java | 157 ++++++++++++++++++ .../{CommonUtil.java => UploadFileUtil.java} | 28 +++- 7 files changed, 366 insertions(+), 84 deletions(-) create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/dto/resp/EntryRespDto.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/utils/AsyncTaskExecutor.java rename cash-sdk/aggregation-pay/src/main/java/com/czg/utils/{CommonUtil.java => UploadFileUtil.java} (64%) diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/EntryManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/EntryManager.java index b988f1abb..b8bb1dc50 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/EntryManager.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/EntryManager.java @@ -3,12 +3,16 @@ package com.czg; import cn.hutool.core.util.StrUtil; import com.czg.dto.req.*; import com.czg.dto.resp.BankBranchDto; +import com.czg.dto.resp.EntryRespDto; import com.czg.exception.CzgException; import com.czg.third.alipay.AlipayEntryManager; import com.czg.third.wechat.WechatEntryManager; import com.czg.utils.AssertUtil; +import com.czg.utils.AsyncTaskExecutor; +import java.util.ArrayList; import java.util.List; +import java.util.function.Supplier; /** * 进件管理 @@ -34,101 +38,136 @@ public class EntryManager { * 请先执行: * 1. {@link com.czg.EntryManager#verifyEntryParam(AggregateMerchantDto)} 验证进件参数 * 2. {@link com.czg.EntryManager#uploadParamImage(AggregateMerchantDto)} 上传图片至第三方 + * * @param reqDto 进件参数 */ - public static void entryMerchant(AggregateMerchantDto reqDto) { + public static EntryRespDto entryMerchant(AggregateMerchantDto reqDto) { + List> tasks = new ArrayList<>(); + tasks.add(() -> WechatEntryManager.entryMerchant(null, reqDto)); + tasks.add(() -> AlipayEntryManager.entryMerchant(null, reqDto)); + // 执行所有任务 + List> results = AsyncTaskExecutor.executeAll(tasks); + for (AsyncTaskExecutor.TaskResult result : results) { + // 合并两个进件结果 + } + + return new EntryRespDto(); } /** * 上传图片至第三方 * 请先执行 {@link com.czg.EntryManager#verifyEntryParam(AggregateMerchantDto)} 验证进件参数 + * * @param reqDto 进件参数 */ public static void uploadParamImage(AggregateMerchantDto reqDto) { + List> tasks = new ArrayList<>(); + MerchantBaseInfoDto baseInfo = reqDto.getMerchantBaseInfo(); // 联系人身份证反面 - if (baseInfo.getContactIdCardBackPic() != null) { + tasks.add(() -> { uploadImageToThird(baseInfo.getContactIdCardBackPic()); - } + return null; + }); // 联系人身份证正面 - if (baseInfo.getContactIdCardFrontPic() != null) { + tasks.add(() -> { uploadImageToThird(baseInfo.getContactIdCardFrontPic()); - } + return null; + }); LegalPersonInfoDto legalPersonInfo = reqDto.getLegalPersonInfo(); // 法人身份证反面 - if (legalPersonInfo.getIdCardBackPic() != null) { + tasks.add(() -> { uploadImageToThird(legalPersonInfo.getIdCardBackPic()); - } + return null; + }); // 法人身份证正面 - if (legalPersonInfo.getIdCardFrontPic() != null) { + tasks.add(() -> { uploadImageToThird(legalPersonInfo.getIdCardFrontPic()); - } + return null; + }); // 法人手持身份证 - if (legalPersonInfo.getIdCardHandPic() != null) { + tasks.add(() -> { uploadImageToThird(legalPersonInfo.getIdCardHandPic()); - } + return null; + }); BusinessLicenceInfoDto businessLicenceInfo = reqDto.getBusinessLicenceInfo(); // 营业执照 - if (businessLicenceInfo.getLicensePic() != null) { + tasks.add(() -> { uploadImageToThird(businessLicenceInfo.getLicensePic()); - } + return null; + }); SettlementInfoDto settlementInfo = reqDto.getSettlementInfo(); // 银行卡背面 - if (settlementInfo.getBankCardBackPic() != null) { + tasks.add(() -> { uploadImageToThird(settlementInfo.getBankCardBackPic()); - } + return null; + }); // 银行卡正面 - if (settlementInfo.getBankCardFrontPic() != null) { + tasks.add(() -> { uploadImageToThird(settlementInfo.getBankCardFrontPic()); - } + return null; + }); // 开户许可证 - if (settlementInfo.getOpenAccountLicencePic() != null) { + tasks.add(() -> { uploadImageToThird(settlementInfo.getOpenAccountLicencePic()); - } + return null; + }); // 非法人手持授权函 - if (settlementInfo.getNoLegalHandSettleAuthPic() != null) { + tasks.add(() -> { uploadImageToThird(settlementInfo.getNoLegalHandSettleAuthPic()); - } + return null; + }); // 非法人授权函 - if (settlementInfo.getNoLegalSettleAuthPic() != null) { + tasks.add(() -> { uploadImageToThird(settlementInfo.getNoLegalSettleAuthPic()); - } + return null; + }); // 非法人身份证反面 - if (settlementInfo.getNoLegalIdCardBackPic() != null) { + tasks.add(() -> { uploadImageToThird(settlementInfo.getNoLegalIdCardBackPic()); - } + return null; + }); // 非法人身份证正面 - if (settlementInfo.getNoLegalIdCardFrontPic() != null) { + tasks.add(() -> { uploadImageToThird(settlementInfo.getNoLegalIdCardFrontPic()); - } + return null; + }); StoreInfoDto storeInfo = reqDto.getStoreInfo(); // 店内图片 - if (storeInfo.getInsidePic() != null) { + tasks.add(() -> { uploadImageToThird(storeInfo.getInsidePic()); - } + return null; + }); // 门店门头图片 - if (storeInfo.getDoorPic() != null) { + tasks.add(() -> { uploadImageToThird(storeInfo.getDoorPic()); - } + return null; + }); // 收银台图片 - if (storeInfo.getCashierDeskPic() != null) { + tasks.add(() -> { uploadImageToThird(storeInfo.getCashierDeskPic()); - } + return null; + }); + + // 执行所有任务 + AsyncTaskExecutor.executeAll(tasks); } private static void uploadImageToThird(ImageDto dto) { - if (StrUtil.isBlank(dto.getWechatId())) { - String image = WechatEntryManager.uploadImage(dto.getUrl()); - dto.setWechatId(image); - } - if (StrUtil.isBlank(dto.getAlipayId())) { - String image = AlipayEntryManager.uploadImage(dto.getUrl()); - dto.setAlipayId(image); + if (dto != null && StrUtil.isNotBlank(dto.getUrl())) { + if (StrUtil.isBlank(dto.getWechatId())) { + String image = WechatEntryManager.uploadImage(null, dto.getUrl()); + dto.setWechatId(image); + } + if (StrUtil.isBlank(dto.getAlipayId())) { + String image = AlipayEntryManager.uploadImage(null, dto.getUrl()); + dto.setAlipayId(image); + } } } @@ -267,6 +306,7 @@ public class EntryManager { AggregateMerchantDto merchantDto = new AggregateMerchantDto(); merchantDto.setMerchantCode("20220106000000000001"); - verifyEntryParam(merchantDto); +// verifyEntryParam(merchantDto); + uploadParamImage(merchantDto); } } diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/resp/EntryRespDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/resp/EntryRespDto.java new file mode 100644 index 000000000..1780c699e --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/resp/EntryRespDto.java @@ -0,0 +1,34 @@ +package com.czg.dto.resp; + +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * 进件相应结果 + * @author yjjie + * @date 2026/1/6 18:15 + */ +@Data +@Accessors(chain = true) +public class EntryRespDto { + + /** + * 微信申请 Id + */ + private String wechatApplyId; + + /** + * 微信状态 + */ + private String wechatStatus; + + /** + * 支付宝订单 Id + */ + private String alipayOrderId; + + /** + * 支付宝状态 + */ + private String alipayStatus; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayClient.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayClient.java index c8a71033c..7af9a1578 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayClient.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayClient.java @@ -3,6 +3,8 @@ package com.czg.third.alipay; import com.alipay.api.AlipayApiException; import com.alipay.api.AlipayConfig; import com.alipay.api.DefaultAlipayClient; +import com.alipay.v3.ApiClient; +import com.alipay.v3.Configuration; import com.czg.third.alipay.dto.config.AlipayConfigDto; import lombok.extern.slf4j.Slf4j; @@ -22,6 +24,23 @@ public class AlipayClient { } } + public static ApiClient getApiClient(AlipayConfigDto configDto) { + try { + ApiClient defaultClient = Configuration.getDefaultApiClient(); + // 初始化alipay参数(全局设置一次) + com.alipay.v3.util.model.AlipayConfig alipayConfig = new com.alipay.v3.util.model.AlipayConfig(); + alipayConfig.setServerUrl(configDto.getDomain()); + alipayConfig.setAppId(configDto.getAppId()); + alipayConfig.setAlipayPublicKey(configDto.getAlipayPublicKey()); + alipayConfig.setPrivateKey(configDto.getPrivateKey()); + defaultClient.setAlipayConfig(alipayConfig); + return defaultClient; + } catch (Exception e) { + log.error("创建支付宝客户端失败", e); + return null; + } + } + public static AlipayConfig getAlipayConfig(AlipayConfigDto configDto) { if (configDto == null) { configDto = AlipayConfigDto.getDefaultConfig(); diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayEntryManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayEntryManager.java index 03b9ef58d..909b7cb7b 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayEntryManager.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayEntryManager.java @@ -12,8 +12,11 @@ import com.alipay.v3.api.AlipayOpenAgentApi; import com.alipay.v3.api.AntMerchantExpandIndirectImageApi; import com.alipay.v3.model.*; import com.alipay.v3.util.model.AlipayConfig; +import com.czg.dto.req.AggregateMerchantDto; import com.czg.dto.resp.BankBranchDto; -import com.czg.utils.CommonUtil; +import com.czg.dto.resp.EntryRespDto; +import com.czg.third.alipay.dto.config.AlipayConfigDto; +import com.czg.utils.UploadFileUtil; import lombok.extern.slf4j.Slf4j; import java.io.File; @@ -33,9 +36,29 @@ import java.util.List; @Slf4j public class AlipayEntryManager { - public static String uploadImage(String url) { + /** + * 进件商户 + * + * @param configDto 配置信息 + * @param reqDto 请求信息 + */ + public static EntryRespDto entryMerchant(AlipayConfigDto configDto, AggregateMerchantDto reqDto) { + return new EntryRespDto(); + } + + /** + * 上传图片 + * + * @param configDto 配置信息 + * @param url 图片地址 + * @return 图片ID + */ + public static String uploadImage(AlipayConfigDto configDto, String url) { + if (configDto == null) { + configDto = AlipayConfigDto.getDefaultConfig(); + } try { - byte[] bytes = CommonUtil.downloadImage(url); + byte[] bytes = UploadFileUtil.downloadImage(url); Path tempFile = Files.createTempFile("image_", ".png"); @@ -45,10 +68,10 @@ public class AlipayEntryManager { File file = tempFile.toFile(); AntMerchantExpandIndirectImageApi imageApi = new AntMerchantExpandIndirectImageApi(); - + imageApi.setApiClient(AlipayClient.getApiClient(configDto)); AntMerchantExpandIndirectImageUploadModel model = new AntMerchantExpandIndirectImageUploadModel(); // 从 url 中获取图片 后缀 - model.setImageType(CommonUtil.extractImageExtension(url)); + model.setImageType(UploadFileUtil.extractImageExtension(url)); AntMerchantExpandIndirectImageUploadResponseModel upload = imageApi.upload(model, file); return upload.getImageId(); } catch (Exception e) { diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java index 6fee949ea..64a5d5d90 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java @@ -1,20 +1,17 @@ package com.czg.third.wechat; -import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONWriter; -import com.czg.third.wechat.dto.req.entry.WechatEntryReqDto; -import com.czg.utils.CommonUtil; +import com.czg.dto.req.AggregateMerchantDto; +import com.czg.dto.resp.EntryRespDto; import com.czg.third.wechat.dto.config.WechatPayConfigDto; +import com.czg.third.wechat.dto.req.entry.WechatEntryReqDto; +import com.czg.utils.UploadFileUtil; import com.wechat.pay.java.service.file.FileUploadService; import com.wechat.pay.java.service.file.model.FileUploadResponse; import lombok.extern.slf4j.Slf4j; -import java.io.File; import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.List; import java.util.Map; /** @@ -26,6 +23,16 @@ import java.util.Map; @Slf4j public class WechatEntryManager { + /** + * 进件商户 + * + * @param configDto 配置信息 + * @param reqDto 请求信息 + */ + public static EntryRespDto entryMerchant(WechatPayConfigDto configDto, AggregateMerchantDto reqDto) { + return new EntryRespDto(); + } + public static JSONObject queryBankList(WechatPayConfigDto configDto, Integer offset, Integer limit) { String resp = WechatReqUtils.getReq(configDto, "/v3/capital/capitallhh/banks/corporate-banking", Map.of("offset", offset, "limit", limit)); log.info("查询银行列表:{}", resp); @@ -67,8 +74,10 @@ public class WechatEntryManager { * @param url 图片URL * @return 图片ID */ - public static String uploadImage(String url) { - WechatPayConfigDto configDto = WechatPayConfigDto.getDefaultConfig(); + public static String uploadImage(WechatPayConfigDto configDto, String url) { + if (configDto == null) { + configDto = WechatPayConfigDto.getDefaultConfig(); + } // 校验入参 if (url == null || url.trim().isEmpty()) { log.error("上传图片失败:URL参数为空"); @@ -79,7 +88,7 @@ public class WechatEntryManager { try { // 获取图片字节数组 - byte[] bytes = CommonUtil.downloadImage(url); + byte[] bytes = UploadFileUtil.downloadImage(url); if (bytes.length == 0) { log.error("下载的图片内容为空,URL:{}", url); return ""; @@ -92,7 +101,7 @@ public class WechatEntryManager { JSONObject meta = new JSONObject(); meta.put("sha256", sha256Hex); // 从URL提取文件名,若提取失败则使用默认名 - String fileName = extractFileNameFromUrl(url); + String fileName = UploadFileUtil.extractFileNameFromUrl(url); meta.put("filename", fileName); // 4. 上传图片到微信接口 @@ -110,32 +119,6 @@ public class WechatEntryManager { return ""; } - /** - * 从URL中提取文件名 - * - * @param url 图片URL - * @return 提取的文件名,失败则返回默认名 - */ - private static String extractFileNameFromUrl(String url) { - try { - if (url.contains("/")) { - String fileName = url.substring(url.lastIndexOf("/") + 1); - // 如果文件名包含参数,截取?之前的部分 - if (fileName.contains("?")) { - fileName = fileName.substring(0, fileName.indexOf("?")); - } - // 如果提取的文件名有效,直接返回 - if (fileName.contains(".")) { - return fileName; - } - } - } catch (Exception e) { - log.warn("提取文件名失败,使用默认文件名", e); - } - // 默认文件名 - return "upload_" + System.currentTimeMillis() + ".png"; - } - public static void main(String[] args) throws IOException { WechatPayConfigDto dto = new WechatPayConfigDto() .setMerchantId("1643779408") diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/utils/AsyncTaskExecutor.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/utils/AsyncTaskExecutor.java new file mode 100644 index 000000000..619acdf11 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/utils/AsyncTaskExecutor.java @@ -0,0 +1,157 @@ +package com.czg.utils; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.function.Supplier; +import java.util.stream.Collectors; + +/** + * Java 21 异步多任务执行工具类 + * 功能:异步执行多个任务,等待所有任务完成后统一返回结果(包含成功/失败信息) + * 特性:基于虚拟线程、支持泛型、完善的异常处理、可自定义线程池 + * + * @author yjjie + * @date 2026/1/6 18:21 + */ +public class AsyncTaskExecutor { + + // 默认线程池:Java 21 虚拟线程池(轻量级、高并发) + private static final ExecutorService DEFAULT_EXECUTOR = Executors.newVirtualThreadPerTaskExecutor(); + + /** + * 执行多个异步任务,等待所有任务完成后统一返回结果 + * + * @param tasks 任务列表(每个任务是一个 Supplier 函数式接口,封装具体业务逻辑) + * @param 任务返回值类型 + * @return 所有任务的执行结果(包含成功/失败信息) + */ + public static List> executeAll(List> tasks) { + return executeAll(tasks, DEFAULT_EXECUTOR); + } + + /** + * 执行多个异步任务(自定义线程池),等待所有任务完成后统一返回结果 + * + * @param tasks 任务列表 + * @param executor 自定义线程池(如需要使用传统线程池可传入) + * @param 任务返回值类型 + * @return 所有任务的执行结果 + */ + public static List> executeAll(List> tasks, ExecutorService executor) { + // 校验入参 + if (tasks == null || tasks.isEmpty()) { + return List.of(); + } + if (executor == null) { + throw new IllegalArgumentException("线程池不能为null"); + } + + // 1. 提交所有异步任务,获取CompletableFuture列表 + List>> futureList = tasks.stream() + .map(task -> CompletableFuture.supplyAsync( + () -> executeSingleTask(task), + executor + )) + .collect(Collectors.toList()); + + // 2. 等待所有任务完成(无超时) + CompletableFuture allFutures = CompletableFuture.allOf( + futureList.toArray(new CompletableFuture[0]) + ); + + try { + // 阻塞等待所有任务完成(可根据业务需求添加超时,如 allFutures.get(10, TimeUnit.SECONDS)) + allFutures.get(); + } catch (Exception e) { + // 全局等待异常(如超时、中断),标记所有未完成的任务为失败 + handleGlobalException(futureList, e); + } + + // 3. 收集所有任务结果 + return futureList.stream() + // 显式指定泛型类型,让编译器明确知道map的返回类型是TaskResult + .>map(future -> { + try { + // 这里强制指定泛型,避免类型推断模糊 + return future.get(); + } catch (Exception e) { + // 理论上不会走到这里,因为singleTask已捕获异常,allOf已等待完成 + return new TaskResult<>(null, false, "结果收集异常:" + e.getMessage()); + } + }) + .collect(Collectors.toList()); + } + + /** + * 执行单个任务,捕获任务执行过程中的异常 + */ + private static TaskResult executeSingleTask(Supplier task) { + try { + T result = task.get(); + return new TaskResult<>(result, true, null); + } catch (Exception e) { + // 捕获单个任务的所有异常,封装为失败结果 + return new TaskResult<>(null, false, "任务执行失败:" + e.getMessage()); + } + } + + /** + * 处理全局等待过程中的异常(如超时、中断),标记未完成任务为失败 + */ + private static void handleGlobalException(List>> futureList, Exception e) { + String errorMsg = "全局等待异常:" + e.getMessage(); + futureList.forEach(future -> { + if (!future.isDone()) { + // 取消未完成的任务,并标记为失败 + future.complete(new TaskResult<>(null, false, errorMsg)); + } + }); + // 恢复线程中断状态(如果是中断异常) + if (e instanceof InterruptedException) { + Thread.currentThread().interrupt(); + } + } + + /** + * 任务结果封装类 + * 包含:返回值、是否成功、失败信息 + * + * @param 结果类型 + * @param result Getter 方法 任务返回值(成功时非null) + * @param success 是否执行成功 + * @param errorMsg 失败信息(失败时非null) + */ + public record TaskResult(T result, boolean success, String errorMsg) { + + // 重写toString,方便打印结果 + @NotNull + @Override + public String toString() { + if (success) { + return "TaskResult{success=true, result=" + result + "}"; + } else { + return "TaskResult{success=false, errorMsg='" + errorMsg + "'}"; + } + } + } + + /** + * 关闭默认线程池(可选,如应用退出时调用) + */ + public static void shutdownDefaultExecutor() { + DEFAULT_EXECUTOR.shutdown(); + try { + if (!DEFAULT_EXECUTOR.awaitTermination(5, TimeUnit.SECONDS)) { + DEFAULT_EXECUTOR.shutdownNow(); + } + } catch (InterruptedException e) { + DEFAULT_EXECUTOR.shutdownNow(); + Thread.currentThread().interrupt(); + } + } +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/utils/CommonUtil.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/utils/UploadFileUtil.java similarity index 64% rename from cash-sdk/aggregation-pay/src/main/java/com/czg/utils/CommonUtil.java rename to cash-sdk/aggregation-pay/src/main/java/com/czg/utils/UploadFileUtil.java index b46e3cc5e..b8b61121d 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/utils/CommonUtil.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/utils/UploadFileUtil.java @@ -13,7 +13,7 @@ import java.util.regex.Pattern; * @date 2026/1/4 13:58 */ @Slf4j -public class CommonUtil { +public class UploadFileUtil { // 匹配常见的图片扩展名 private static final Pattern PATTERN = Pattern.compile("\\.(jpg|jpeg|png|gif|bmp|webp|svg|ico)(?:[\\?#]|$)", Pattern.CASE_INSENSITIVE); @@ -58,4 +58,30 @@ public class CommonUtil { return new byte[0]; } } + + /** + * 从URL中提取文件名 + * + * @param url 图片URL + * @return 提取的文件名,失败则返回默认名 + */ + public static String extractFileNameFromUrl(String url) { + try { + if (url.contains("/")) { + String fileName = url.substring(url.lastIndexOf("/") + 1); + // 如果文件名包含参数,截取?之前的部分 + if (fileName.contains("?")) { + fileName = fileName.substring(0, fileName.indexOf("?")); + } + // 如果提取的文件名有效,直接返回 + if (fileName.contains(".")) { + return fileName; + } + } + } catch (Exception e) { + log.warn("提取文件名失败,使用默认文件名", e); + } + // 默认文件名 + return "upload_" + System.currentTimeMillis() + ".png"; + } } From 74122fae45c632542bf588a30ab79f39cc5bdbc5 Mon Sep 17 00:00:00 2001 From: gong <1157756119@qq.com> Date: Wed, 7 Jan 2026 13:54:35 +0800 Subject: [PATCH 15/19] =?UTF-8?q?=E6=9E=84=E5=BB=BA=E5=BE=AE=E4=BF=A1?= =?UTF-8?q?=E8=BF=9B=E4=BB=B6=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/czg/EntryManager.java | 165 ++++++++++++++--- .../src/main/java/com/czg/PayCst.java | 53 ++++++ .../main/java/com/czg/dto/req/ImageDto.java | 8 + .../com/czg/dto/req/LegalPersonInfoDto.java | 8 +- .../com/czg/dto/req/MerchantBaseInfoDto.java | 25 +-- .../java/com/czg/dto/req/StoreInfoDto.java | 12 +- .../java/com/czg/dto/resp/EntryRespDto.java | 12 ++ .../com/czg/dto/resp/EntryThirdRespDto.java | 34 ++++ .../com/czg/third/alipay/AlipayClient.java | 7 +- .../czg/third/alipay/AlipayEntryManager.java | 61 +++++-- .../com/czg/third/alipay/AlipayReqUtils.java | 18 +- .../alipay/dto/config/AlipayConfigDto.java | 5 + .../czg/third/wechat/WechatEntryManager.java | 168 +++++++++++++++--- .../com/czg/third/wechat/WechatReqUtils.java | 6 +- 14 files changed, 497 insertions(+), 85 deletions(-) create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/PayCst.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/dto/resp/EntryThirdRespDto.java diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/EntryManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/EntryManager.java index b8bb1dc50..a90b242da 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/EntryManager.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/EntryManager.java @@ -1,14 +1,17 @@ package com.czg; +import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.StrUtil; import com.czg.dto.req.*; import com.czg.dto.resp.BankBranchDto; import com.czg.dto.resp.EntryRespDto; +import com.czg.dto.resp.EntryThirdRespDto; import com.czg.exception.CzgException; import com.czg.third.alipay.AlipayEntryManager; import com.czg.third.wechat.WechatEntryManager; import com.czg.utils.AssertUtil; import com.czg.utils.AsyncTaskExecutor; +import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.List; @@ -39,20 +42,46 @@ public class EntryManager { * 1. {@link com.czg.EntryManager#verifyEntryParam(AggregateMerchantDto)} 验证进件参数 * 2. {@link com.czg.EntryManager#uploadParamImage(AggregateMerchantDto)} 上传图片至第三方 * - * @param reqDto 进件参数 + * @param reqDto 进件参数 + * @param platform 平台 {@link com.czg.PayCst.Platform} */ - public static EntryRespDto entryMerchant(AggregateMerchantDto reqDto) { - List> tasks = new ArrayList<>(); - tasks.add(() -> WechatEntryManager.entryMerchant(null, reqDto)); - tasks.add(() -> AlipayEntryManager.entryMerchant(null, reqDto)); + public static EntryRespDto entryMerchant(AggregateMerchantDto reqDto, String... platform) { + List> tasks = new ArrayList<>(); - // 执行所有任务 - List> results = AsyncTaskExecutor.executeAll(tasks); - for (AsyncTaskExecutor.TaskResult result : results) { - // 合并两个进件结果 + if (platform == null || platform.length == 0) { + platform = new String[]{PayCst.Platform.WECHAT, PayCst.Platform.ALIPAY}; } - return new EntryRespDto(); + if (ArrayUtil.contains(platform, PayCst.Platform.WECHAT)) { + tasks.add(() -> WechatEntryManager.entryMerchant(null, reqDto)); + } + if (ArrayUtil.contains(platform, PayCst.Platform.ALIPAY)) { + tasks.add(() -> AlipayEntryManager.entryMerchant(null, reqDto)); + } + + // 执行所有任务 + List> results = AsyncTaskExecutor.executeAll(tasks); + + return getEntryRespDto(results); + } + + @NotNull + private static EntryRespDto getEntryRespDto(List> results) { + EntryRespDto entryRespDto = new EntryRespDto(); + for (AsyncTaskExecutor.TaskResult result : results) { + // 合并两个进件结果 + EntryThirdRespDto respDto = result.result(); + if (PayCst.Platform.WECHAT.equals(respDto.getPlatform())) { + entryRespDto.setWechatApplyId(respDto.getEntryId()); + entryRespDto.setWechatStatus(respDto.getStatus()); + entryRespDto.setWechatErrorMsg(respDto.getErrorMsg()); + } else if (PayCst.Platform.ALIPAY.equals(respDto.getPlatform())) { + entryRespDto.setAlipayOrderId(respDto.getEntryId()); + entryRespDto.setAlipayStatus(respDto.getStatus()); + entryRespDto.setAlipayErrorMsg(respDto.getErrorMsg()); + } + } + return entryRespDto; } /** @@ -184,18 +213,22 @@ public class EntryManager { MerchantBaseInfoDto baseInfo = reqDto.getMerchantBaseInfo(); AssertUtil.isBlank(baseInfo.getUserType(), "商户类型不能为空"); AssertUtil.isBlank(baseInfo.getShortName(), "商户简称不能为空"); - AssertUtil.isBlank(baseInfo.getCertType(), "证件类型不能为空"); - if (!"0".equals(baseInfo.getCertType())) { - throw new CzgException("证件类型错误"); - } AssertUtil.isBlank(baseInfo.getMccCode(), "商户行业编码不能为空"); - if ("SUPER".equals(baseInfo.getContactPersonType())) { + AssertUtil.isBlank(baseInfo.getContactPersonType(), "联系人类型不能为空"); + if (!PayCst.ContactPersonType.SUPER.equals(baseInfo.getContactPersonType()) && !PayCst.ContactPersonType.LEGAL.equals(baseInfo.getContactPersonType())) { + throw new CzgException("联系人类型错误"); + } + if (PayCst.ContactPersonType.SUPER.equals(baseInfo.getContactPersonType())) { + AssertUtil.isBlank(baseInfo.getCertType(), "证件类型不能为空"); + if (!"0".equals(baseInfo.getCertType())) { + throw new CzgException("证件类型错误"); + } AssertUtil.isBlank(baseInfo.getContactName(), "联系人姓名不能为空"); AssertUtil.isBlank(baseInfo.getContactPersonId(), "联系人身份证号不能为空"); AssertUtil.isBlank(baseInfo.getContactPhone(), "联系人电话不能为空"); AssertUtil.isBlank(baseInfo.getContactAddr(), "联系人地址不能为空"); AssertUtil.isBlank(baseInfo.getContactEmail(), "联系人邮箱不能为空"); - AssertUtil.isBlank(baseInfo.getContactIdStartDate(), "联系人身份证开始日期不能为空"); + AssertUtil.isBlank(baseInfo.getContactPersonIdStartDate(), "联系人身份证开始日期不能为空"); AssertUtil.isBlank(baseInfo.getContactPersonIdEndDate(), "联系人身份证到期日期不能为空"); AssertUtil.isNull(baseInfo.getContactIdCardBackPic(), "联系人身份证反面不能为空"); AssertUtil.isBlank(baseInfo.getContactIdCardBackPic().getUrl(), "联系人身份证反面不能为空"); @@ -228,9 +261,10 @@ public class EntryManager { LegalPersonInfoDto legalPersonInfo = reqDto.getLegalPersonInfo(); AssertUtil.isBlank(legalPersonInfo.getLegalPersonName(), "法人姓名不能为空"); AssertUtil.isBlank(legalPersonInfo.getLegalPersonId(), "法人身份证号不能为空"); - AssertUtil.isBlank(legalPersonInfo.getLegalIdStartDate(), "法人身份证开始日期不能为空"); + AssertUtil.isBlank(legalPersonInfo.getLegalIdPersonStartDate(), "法人身份证开始日期不能为空"); AssertUtil.isBlank(legalPersonInfo.getLegalPersonIdEndDate(), "法人身份证到期日期不能为空"); AssertUtil.isBlank(legalPersonInfo.getLegalPersonPhone(), "法人电话不能为空"); + AssertUtil.isBlank(legalPersonInfo.getLegalPersonEmail(), "法人邮箱不能为空"); AssertUtil.isBlank(legalPersonInfo.getLegalGender(), "法人性别不能为空"); AssertUtil.isBlank(legalPersonInfo.getLegalAddress(), "法人地址不能为空"); AssertUtil.isNull(legalPersonInfo.getIdCardHandPic(), "法人身份证手持不能为空"); @@ -242,9 +276,9 @@ public class EntryManager { AssertUtil.isNull(reqDto.getStoreInfo(), "门店信息不能为空"); StoreInfoDto storeInfo = reqDto.getStoreInfo(); - AssertUtil.isBlank(storeInfo.getMercProvId(), "门店省ID不能为空"); - AssertUtil.isBlank(storeInfo.getMercCityId(), "门店市ID不能为空"); - AssertUtil.isBlank(storeInfo.getMercAreaId(), "门店区ID不能为空"); + AssertUtil.isBlank(storeInfo.getMercProvCode(), "门店省ID不能为空"); + AssertUtil.isBlank(storeInfo.getMercCityCode(), "门店市ID不能为空"); + AssertUtil.isBlank(storeInfo.getMercAreaCode(), "门店区ID不能为空"); AssertUtil.isBlank(storeInfo.getMercProv(), "门店省不能为空"); AssertUtil.isBlank(storeInfo.getMercCity(), "门店市不能为空"); AssertUtil.isBlank(storeInfo.getMercArea(), "门店区不能为空"); @@ -303,10 +337,97 @@ public class EntryManager { public static void main(String[] args) { + + AggregateMerchantDto merchantDto = getTestMerchantEntryData(); + +// verifyEntryParam(merchantDto); +// uploadParamImage(merchantDto); + + verifyEntryParam(merchantDto); + uploadParamImage(merchantDto); + System.out.println(merchantDto); + entryMerchant(merchantDto, PayCst.Platform.WECHAT); +// entryMerchant(merchantDto, PayCst.Platform.WECHAT, PayCst.Platform.ALIPAY); + } + + private static AggregateMerchantDto getTestMerchantEntryData() { AggregateMerchantDto merchantDto = new AggregateMerchantDto(); merchantDto.setMerchantCode("20220106000000000001"); -// verifyEntryParam(merchantDto); - uploadParamImage(merchantDto); + MerchantBaseInfoDto baseInfoDto = new MerchantBaseInfoDto(); + baseInfoDto.setUserType("1"); + baseInfoDto.setCompanyChildType("1"); + baseInfoDto.setShortName("测试商户"); + baseInfoDto.setMccCode("0741"); + baseInfoDto.setContactPersonType(PayCst.ContactPersonType.SUPER); + baseInfoDto.setContactName("张三"); + baseInfoDto.setContactPersonId("110101199001011234"); + baseInfoDto.setContactPersonIdStartDate("2021-01-01"); + baseInfoDto.setContactPersonIdEndDate("2025-01-01"); + baseInfoDto.setContactPhone("13800000000"); + baseInfoDto.setContactEmail("1157756119@qq.com"); + baseInfoDto.setContactAddr("广东省深圳市南山区"); + baseInfoDto.setContactIdCardFrontPic(new ImageDto("https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/20240312/31476c871c224389aea0ac4e17c964a3.jpg")); + baseInfoDto.setContactIdCardBackPic(new ImageDto("https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/20240312/31476c871c224389aea0ac4e17c964a3.jpg")); + merchantDto.setMerchantBaseInfo(baseInfoDto); + + BusinessLicenceInfoDto businessLicenceInfoDto = new BusinessLicenceInfoDto(); + businessLicenceInfoDto.setLicenceName("测试商户"); + businessLicenceInfoDto.setLicenceNo("110101199001011234"); + businessLicenceInfoDto.setLicenceStartDate("2021-01-01"); + businessLicenceInfoDto.setLicenceEndDate("2052-01-01"); + businessLicenceInfoDto.setRegisteredAddress("广东省深圳市南山区"); + businessLicenceInfoDto.setLicensePic(new ImageDto("https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/20240312/31476c871c224389aea0ac4e17c964a3.jpg")); + merchantDto.setBusinessLicenceInfo(businessLicenceInfoDto); + + LegalPersonInfoDto legalPersonInfoDto = new LegalPersonInfoDto(); + legalPersonInfoDto.setLegalPersonName("张三"); + legalPersonInfoDto.setLegalPersonId("110101199001011234"); + legalPersonInfoDto.setLegalIdPersonStartDate("2021-01-01"); + legalPersonInfoDto.setLegalPersonIdEndDate("2055-01-01"); + legalPersonInfoDto.setLegalPersonPhone("13800000000"); + legalPersonInfoDto.setLegalPersonEmail("1157756119@qq.com"); + legalPersonInfoDto.setLegalGender("1"); + legalPersonInfoDto.setLegalAddress("广东省深圳市南山区"); + legalPersonInfoDto.setIdCardHandPic(new ImageDto("https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/20240312/31476c871c224389aea0ac4e17c964a3.jpg")); + legalPersonInfoDto.setIdCardFrontPic(new ImageDto("https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/20240312/31476c871c224389aea0ac4e17c964a3.jpg")); + legalPersonInfoDto.setIdCardBackPic(new ImageDto("https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/20240312/31476c871c224389aea0ac4e17c964a3.jpg")); + merchantDto.setLegalPersonInfo(legalPersonInfoDto); + + StoreInfoDto storeInfoDto = new StoreInfoDto(); + storeInfoDto.setMercProvCode("440000"); + storeInfoDto.setMercCityCode("440300"); + storeInfoDto.setMercAreaCode("440303"); + storeInfoDto.setMercProv("广东省"); + storeInfoDto.setMercCity("深圳市"); + storeInfoDto.setMercArea("南山区"); + storeInfoDto.setBusinessAddress("广东省深圳市南山区"); + storeInfoDto.setInsidePic(new ImageDto("https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/20240312/31476c871c224389aea0ac4e17c964a3.jpg")); + storeInfoDto.setDoorPic(new ImageDto("https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/20240312/31476c871c224389aea0ac4e17c964a3.jpg")); + storeInfoDto.setCashierDeskPic(new ImageDto("https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/20240312/31476c871c224389aea0ac4e17c964a3.jpg")); + merchantDto.setStoreInfo(storeInfoDto); + + SettlementInfoDto settlementInfoDto = new SettlementInfoDto(); + settlementInfoDto.setSettlementType("1"); + settlementInfoDto.setSettlementCardType("21"); + settlementInfoDto.setSettlementName("张三"); + settlementInfoDto.setSettlementCardNo("110101199001011234"); + settlementInfoDto.setBankMobile("13800000000"); + settlementInfoDto.setOpenAccProvinceId("440000"); + settlementInfoDto.setOpenAccCityId("440300"); + settlementInfoDto.setOpenAccAreaId("440303"); + settlementInfoDto.setOpenAccProvince("广东省"); + settlementInfoDto.setOpenAccCity("深圳市"); + settlementInfoDto.setOpenAccArea("南山区"); + settlementInfoDto.setBankName("中国工商银行"); + settlementInfoDto.setBankType("1"); + settlementInfoDto.setBankBranchName("广东省深圳市南山区"); + settlementInfoDto.setBankBranchCode("440300"); + settlementInfoDto.setBankCardFrontPic(new ImageDto("https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/20240312/31476c871c224389aea0ac4e17c964a3.jpg")); + settlementInfoDto.setBankCardBackPic(new ImageDto("https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/20240312/31476c871c224389aea0ac4e17c964a3.jpg")); + settlementInfoDto.setOpenAccountLicencePic(new ImageDto("https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/20240312/31476c871c224389aea0ac4e17c964a3.jpg")); + merchantDto.setSettlementInfo(settlementInfoDto); + + return merchantDto; } } diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/PayCst.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/PayCst.java new file mode 100644 index 000000000..5000c63ac --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/PayCst.java @@ -0,0 +1,53 @@ +package com.czg; + +/** + * 支付相关常量 + * @author yjjie + * @date 2026/1/7 09:20 + */ +public interface PayCst { + + /** + * 平台 + */ + class Platform { + /** + * 微信 + */ + public static final String WECHAT = "wechat"; + /** + * 支付宝 + */ + public static final String ALIPAY = "alipay"; + } + + /** + * 进件状态 + */ + class EntryStatus { + /** + * 待处理 + */ + public static final String INIT = "INIT"; + + /** + * 失败 + */ + public static final String FAIL = "FAIL"; + } + + /** + * 联系人类型 + */ + class ContactPersonType { + /** + * 法人 + */ + public static final String LEGAL = "LEGAL"; + + /** + * 经办人 + */ + public static final String SUPER = "SUPER"; + } +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/ImageDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/ImageDto.java index 5784464d7..b46a6c05a 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/ImageDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/ImageDto.java @@ -1,12 +1,14 @@ package com.czg.dto.req; import lombok.Data; +import lombok.experimental.Accessors; /** * @author yjjie * @date 2026/1/6 16:53 */ @Data +@Accessors(chain = true) public class ImageDto { /** @@ -23,4 +25,10 @@ public class ImageDto { * 支付宝 图片 mediaId */ private String alipayId; + + public ImageDto() {} + + public ImageDto(String url) { + this.url = url; + } } diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/LegalPersonInfoDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/LegalPersonInfoDto.java index 203cbfdc4..8f631d00e 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/LegalPersonInfoDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/LegalPersonInfoDto.java @@ -26,7 +26,7 @@ public class LegalPersonInfoDto { * 【必填】 * 法人身份证开始日期 */ - private String legalIdStartDate; + private String legalIdPersonStartDate; /** * 【必填】 @@ -40,6 +40,12 @@ public class LegalPersonInfoDto { */ private String legalPersonPhone; + /** + * 【必填】 + * 法人邮箱 + */ + private String legalPersonEmail; + /** * 法人性别(0男 1女) */ diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/MerchantBaseInfoDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/MerchantBaseInfoDto.java index 3515e8dc0..ae8384f60 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/MerchantBaseInfoDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/MerchantBaseInfoDto.java @@ -26,12 +26,6 @@ public class MerchantBaseInfoDto { */ private String shortName; - /** - * 证件类型 - * 目前只支持身份证 传值:0 - */ - private String certType = "0"; - /** * 【必填】 * 行业编码 @@ -46,61 +40,58 @@ public class MerchantBaseInfoDto { private String contactPersonType = "LEGAL"; /** - * 【必填】 * 联系人姓名 */ private String contactName; /** - * 【必填】 + * 证件类型 + * 目前只支持身份证 传值:0 + */ + private String certType = "0"; + + /** * 联系人身份证号 */ private String contactPersonId; /** - * 【必填】 * 联系人身份证开始日期 */ - private String contactIdStartDate; + private String contactPersonIdStartDate; /** - * 【必填】 * 联系人身份证到期日期 */ private String contactPersonIdEndDate; /** - * 【必填】 * 联系人身份证背面 */ private ImageDto contactIdCardBackPic; /** - * 【必填】 * 联系人身份证正面 */ private ImageDto contactIdCardFrontPic; /** - * 【必填】 * 联系人电话 */ private String contactPhone; /** - * 【必填】 * 联系人通讯地址 */ private String contactAddr; /** - * 【必填】 * 联系人邮箱 */ private String contactEmail; /** - * 企业类型,1:普通企业,2:事业单位,3:其他组织 + * 企业类型,1:普通企业,2:事业单位,3:政府机关,4:社会组织 */ private String companyChildType = "1"; } diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/StoreInfoDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/StoreInfoDto.java index ee4c32613..09b4f18e8 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/StoreInfoDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/StoreInfoDto.java @@ -12,21 +12,21 @@ public class StoreInfoDto { /** * 【必填】 - * 商户归属省id + * 商户归属省Code */ - private String mercProvId; + private String mercProvCode; /** * 【必填】 - * 商户归属市id + * 商户归属市Code */ - private String mercCityId; + private String mercCityCode; /** * 【必填】 - * 商户归属区id + * 商户归属区Code */ - private String mercAreaId; + private String mercAreaCode; /** * 商户归属省 diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/resp/EntryRespDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/resp/EntryRespDto.java index 1780c699e..f6abe75e4 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/resp/EntryRespDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/resp/EntryRespDto.java @@ -19,9 +19,15 @@ public class EntryRespDto { /** * 微信状态 + * {@link com.czg.PayCst.EntryStatus} */ private String wechatStatus; + /** + * 微信进件错误信息 + */ + private String wechatErrorMsg; + /** * 支付宝订单 Id */ @@ -29,6 +35,12 @@ public class EntryRespDto { /** * 支付宝状态 + * {@link com.czg.PayCst.EntryStatus} */ private String alipayStatus; + + /** + * 支付宝进件错误信息 + */ + private String alipayErrorMsg; } diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/resp/EntryThirdRespDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/resp/EntryThirdRespDto.java new file mode 100644 index 000000000..449b56f46 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/resp/EntryThirdRespDto.java @@ -0,0 +1,34 @@ +package com.czg.dto.resp; + +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * @author yjjie + * @date 2026/1/7 09:07 + */ +@Data +@Accessors(chain = true) +public class EntryThirdRespDto { + + /** + * 录入id + */ + private String entryId; + + /** + * 平台 + */ + private String platform; + + /** + * 状态 + * {@link com.czg.PayCst.EntryStatus} + */ + private String status; + + /** + * 错误信息 + */ + private String errorMsg; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayClient.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayClient.java index 7af9a1578..93c6527c4 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayClient.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayClient.java @@ -24,7 +24,10 @@ public class AlipayClient { } } - public static ApiClient getApiClient(AlipayConfigDto configDto) { + public static void setApiClient(AlipayConfigDto configDto) { + if (configDto == null) { + configDto = AlipayConfigDto.getDefaultConfig(); + } try { ApiClient defaultClient = Configuration.getDefaultApiClient(); // 初始化alipay参数(全局设置一次) @@ -34,10 +37,8 @@ public class AlipayClient { alipayConfig.setAlipayPublicKey(configDto.getAlipayPublicKey()); alipayConfig.setPrivateKey(configDto.getPrivateKey()); defaultClient.setAlipayConfig(alipayConfig); - return defaultClient; } catch (Exception e) { log.error("创建支付宝客户端失败", e); - return null; } } diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayEntryManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayEntryManager.java index 909b7cb7b..de32ddd66 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayEntryManager.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayEntryManager.java @@ -2,9 +2,13 @@ package com.czg.third.alipay; import com.alibaba.fastjson2.JSONArray; import com.alipay.api.DefaultAlipayClient; +import com.alipay.api.FileItem; import com.alipay.api.domain.AlipayFinancialnetAuthPbcnameQueryModel; +import com.alipay.api.domain.AntMerchantExpandIndirectZftSimplecreateModel; import com.alipay.api.request.AlipayFinancialnetAuthPbcnameQueryRequest; +import com.alipay.api.request.AntMerchantExpandIndirectImageUploadRequest; import com.alipay.api.response.AlipayFinancialnetAuthPbcnameQueryResponse; +import com.alipay.api.response.AntMerchantExpandIndirectImageUploadResponse; import com.alipay.v3.ApiClient; import com.alipay.v3.ApiException; import com.alipay.v3.Configuration; @@ -12,10 +16,13 @@ import com.alipay.v3.api.AlipayOpenAgentApi; import com.alipay.v3.api.AntMerchantExpandIndirectImageApi; import com.alipay.v3.model.*; import com.alipay.v3.util.model.AlipayConfig; +import com.czg.PayCst; import com.czg.dto.req.AggregateMerchantDto; import com.czg.dto.resp.BankBranchDto; import com.czg.dto.resp.EntryRespDto; +import com.czg.dto.resp.EntryThirdRespDto; import com.czg.third.alipay.dto.config.AlipayConfigDto; +import com.czg.third.wechat.dto.req.entry.WechatEntryReqDto; import com.czg.utils.UploadFileUtil; import lombok.extern.slf4j.Slf4j; @@ -42,8 +49,21 @@ public class AlipayEntryManager { * @param configDto 配置信息 * @param reqDto 请求信息 */ - public static EntryRespDto entryMerchant(AlipayConfigDto configDto, AggregateMerchantDto reqDto) { - return new EntryRespDto(); + public static EntryThirdRespDto entryMerchant(AlipayConfigDto configDto, AggregateMerchantDto reqDto) { + AntMerchantExpandIndirectZftSimplecreateModel entryReqDto = buildEntryParams(reqDto); + EntryThirdRespDto respDto = new EntryThirdRespDto() + .setPlatform(PayCst.Platform.ALIPAY); + + try { +// entry(configDto, entryReqDto); + } catch (Exception e) { + log.error("支付宝进件报错:{}", e.getMessage(), e); + respDto.setStatus(PayCst.EntryStatus.FAIL); + respDto.setEntryId(""); + respDto.setErrorMsg(e.getMessage()); + } + + return respDto; } /** @@ -54,9 +74,6 @@ public class AlipayEntryManager { * @return 图片ID */ public static String uploadImage(AlipayConfigDto configDto, String url) { - if (configDto == null) { - configDto = AlipayConfigDto.getDefaultConfig(); - } try { byte[] bytes = UploadFileUtil.downloadImage(url); @@ -67,13 +84,17 @@ public class AlipayEntryManager { File file = tempFile.toFile(); - AntMerchantExpandIndirectImageApi imageApi = new AntMerchantExpandIndirectImageApi(); - imageApi.setApiClient(AlipayClient.getApiClient(configDto)); - AntMerchantExpandIndirectImageUploadModel model = new AntMerchantExpandIndirectImageUploadModel(); - // 从 url 中获取图片 后缀 - model.setImageType(UploadFileUtil.extractImageExtension(url)); - AntMerchantExpandIndirectImageUploadResponseModel upload = imageApi.upload(model, file); - return upload.getImageId(); + AntMerchantExpandIndirectImageUploadRequest request = new AntMerchantExpandIndirectImageUploadRequest(); + request.setImageType(UploadFileUtil.extractImageExtension(url)); + + // 设置图片内容 + FileItem imageContent = new FileItem(file); + request.setImageContent(imageContent); + + DefaultAlipayClient defaultAlipayClient = AlipayClient.getDefaultClient(configDto); + AntMerchantExpandIndirectImageUploadResponse response = defaultAlipayClient.execute(request); + + return response.getImageId(); } catch (Exception e) { log.error("支付宝上传图片报错,URL:{},错误信息:{}", "url", e.getMessage(), e); return ""; @@ -108,9 +129,23 @@ public class AlipayEntryManager { } } + /** + * 构建进件参数 + * + * @param reqDto 请求参数 + * @return 进件参数 + */ + private static AntMerchantExpandIndirectZftSimplecreateModel buildEntryParams(AggregateMerchantDto reqDto) { + AntMerchantExpandIndirectZftSimplecreateModel entryParams = new AntMerchantExpandIndirectZftSimplecreateModel(); + + + return entryParams; + } + public static void main(String[] args) { - queryBankBranchList("CMB", "西安市", "陕西省"); +// queryBankBranchList("CMB", "陕西省", "西安市"); + uploadImage(null, "https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/20240312/31476c871c224389aea0ac4e17c964a3.jpg"); } diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayReqUtils.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayReqUtils.java index 0ab504b1e..c81f50ed6 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayReqUtils.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayReqUtils.java @@ -17,7 +17,9 @@ import java.util.List; */ public class AlipayReqUtils { public static void main(String[] args) throws AlipayApiException { - DefaultAlipayClient defaultAlipayClient = AlipayClient.getDefaultClient(null); +// DefaultAlipayClient defaultAlipayClient = AlipayClient.getDefaultClient(null); +// AlipayClient alipayClient = new DefaultAlipayClient(getAlipayConfig()); + DefaultAlipayClient defaultAlipayClient = new DefaultAlipayClient(getAlipayConfig()); // 构造请求参数以调用接口 AntMerchantExpandIndirectZftSimplecreateRequest request = new AntMerchantExpandIndirectZftSimplecreateRequest(); @@ -205,4 +207,18 @@ public class AlipayReqUtils { } } + private static AlipayConfig getAlipayConfig() { + String privateKey = "MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQD48HaUoV7OH7os+9L01kHgxzwIhJick4OkFq4aHsntsXEJ J3gedhuEZtV8oHKZ30DPW12IJ4S8NXtpr8OWaqrAPFonf4wVaRY1d0yIAea57kfLEn9oOEEy4FzARgMNDkyxC+/3OUdGbLHpTjfVX3gusXsEhUDy1/WewihAkoNYF37+W3W/uVLzeWoPq0EcUbRv/G/t/p6gL69ltsMAiVFG4Q/Yk24YAN6lYgBPNLXUEwQ1Q+T+1omjfavHgvarKOp33z3JOUH+aGOmDsJ5Y9gyGtJzOCipAd8Zcv+T1ygsEzZYO1/gzcbPnfO1ShqStCHzssuw8FBVx2JdfQKXKMMNAgMBAAECggEAVTrO/pg5Q00titU1Jspsh67u6OOs9H605Ws2dI7yB8VmtAGlaJh7V1t14FN2qSP8poHbhhAxq9aLyGV7C3a9u09udnN+3J28EtYjh7VO732bavWMVXxdJjQWzWWrCb9JlpxFrlkYBA6W4w/6ob0sAqCVQ7jzwbEa0R4cde8ztOa5nysKSfr4YTSs0gqvoiC6fmg8eiRJraEQBoYz9VkKFtOhhh/4w5FhVcYQ2gQvZ3kK3QVuD1eJIQKlCtz8qaox9lXKDiZT4SCmnKshdUL0u5TYIcYeBjZmhJz0Q50KHcpZrCs5y7I0+vRBH3hU+TKSQt7ureymwhbwWMHScLV2gQKBgQD+58SHXhr5M8NGagAmTdsgmCnNv2kOYMd4STyPMY10SVwCv1Bk808ZuP+7e558J1b5/OuDLI5dLq6xrZ/1wLv1G++XqxI00hlFuWS5mUGJVcXotT1mw20rVeUILc7Qe3mLvbMGgfyKf4A7Qa5SSZ4bDeDTJYaFxyiQ281hMzDuPQKBgQD6AiL/Na2/uPH4CG6juwpjYvYVUcjK+7gbRwf3wWsWMpk90Z4ju2iUiP5c1J/oK9P+1T3PIr6M4Xjza8JJj+r9KC/PVB0gBv6vVM96cDpKUEy/UMpcn/T81vqj/Z+WEOODU8Ms6NiTTm+u9ldvpCjbu0u8M+9c0JeIyadJvSTFEQKBgQCsxmFyM3nq8YfpgU2qqNjfBeRH3faSVUy+nj1a/YZYjKS+A/i1BCnYUImeBVNN6chNV342ggvY4xxruDiU9Vcw8wd58O09Oi8BEIFSP6upL6cebUI6Fjo3xlegLJRiwV6INkNTJOYM5hD/mSxUACwXQFfkJipBINXBIgraWD1RLQKBgQCj49axWq0F6+WjZVOyPaD3uh37p9trRUxRhWTxw3fB23WdktaKMgbCqHOmwzP4bRLSEVQtf2dOz1gMqu14b8HqJvgAf/F/11YJ9hz09LEhmjZVjE68HZfqT7uK2W5OX8/lfXmK7TFcj6SjG5YB96lZMhTZ0WnufEd6QkdKDZYXIQKBgQD9GDTcIMbFwbEaKHnfZaTD3f876EGRgsgrCxwdEk7LBCRPwWo7yI929M4psIlpNwNeiyjBkBunWIVkpznp6qPtJqagIPUYesU4f5v6/okq5wcpaNKSkWbIvWVLaLGOiA1aeGJtbpMpyClbSr52puHpRRdvAiIEQ74yYh0JX8q96g=="; + String alipayPublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAiQkrz+emAuS1mB3KKDOMmAZRd/BlPbh7fAIHAqAj1+QCZNcV3o2BTLIIqnuKpSlFXDG3uDzp2VsBxcizXuBbFyPGylnD9CgCj5abyh3+FIHPAZ2IM3TtpqImZ0TSPGXrMli4Nir7MvZktgccCqQKCC4o6iaDGz+UwWwJUIPna8fm2tiTZ+KH150CZbKVj4ZGNpBh5XSV/1dRgyQIV9D/EwSbkZ0n6VgKQLJBi0C2UE3QB17aL1Ir6+gDXIDbknN8O7GUD3aMGdThYdSRUb5wp9CZ5qfV7vCS/CgaRo38nhH3NOzkTL+7v0m1ZDHPmqEkn9VzZN6sCQdL7PoAOjHOCwIDAQAB"; + AlipayConfig alipayConfig = new AlipayConfig(); + alipayConfig.setServerUrl("https://openapi.alipay.com/gateway.do"); + alipayConfig.setAppId("2021004174605036"); + alipayConfig.setPrivateKey(privateKey); + alipayConfig.setFormat("json"); + alipayConfig.setAlipayPublicKey(alipayPublicKey); + alipayConfig.setCharset("UTF-8"); + alipayConfig.setSignType("RSA2"); + return alipayConfig; + } + } diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/dto/config/AlipayConfigDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/dto/config/AlipayConfigDto.java index f2838086f..d1ce39399 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/dto/config/AlipayConfigDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/dto/config/AlipayConfigDto.java @@ -38,5 +38,10 @@ public class AlipayConfigDto { .setPrivateKey("MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQD48HaUoV7OH7os+9L01kHgxzwIhJick4OkFq4aHsntsXEJ J3gedhuEZtV8oHKZ30DPW12IJ4S8NXtpr8OWaqrAPFonf4wVaRY1d0yIAea57kfLEn9oOEEy4FzARgMNDkyxC+/3OUdGbLHpTjfVX3gusXsEhUDy1/WewihAkoNYF37+W3W/uVLzeWoPq0EcUbRv/G/t/p6gL69ltsMAiVFG4Q/Yk24YAN6lYgBPNLXUEwQ1Q+T+1omjfavHgvarKOp33z3JOUH+aGOmDsJ5Y9gyGtJzOCipAd8Zcv+T1ygsEzZYO1/gzcbPnfO1ShqStCHzssuw8FBVx2JdfQKXKMMNAgMBAAECggEAVTrO/pg5Q00titU1Jspsh67u6OOs9H605Ws2dI7yB8VmtAGlaJh7V1t14FN2qSP8poHbhhAxq9aLyGV7C3a9u09udnN+3J28EtYjh7VO732bavWMVXxdJjQWzWWrCb9JlpxFrlkYBA6W4w/6ob0sAqCVQ7jzwbEa0R4cde8ztOa5nysKSfr4YTSs0gqvoiC6fmg8eiRJraEQBoYz9VkKFtOhhh/4w5FhVcYQ2gQvZ3kK3QVuD1eJIQKlCtz8qaox9lXKDiZT4SCmnKshdUL0u5TYIcYeBjZmhJz0Q50KHcpZrCs5y7I0+vRBH3hU+TKSQt7ureymwhbwWMHScLV2gQKBgQD+58SHXhr5M8NGagAmTdsgmCnNv2kOYMd4STyPMY10SVwCv1Bk808ZuP+7e558J1b5/OuDLI5dLq6xrZ/1wLv1G++XqxI00hlFuWS5mUGJVcXotT1mw20rVeUILc7Qe3mLvbMGgfyKf4A7Qa5SSZ4bDeDTJYaFxyiQ281hMzDuPQKBgQD6AiL/Na2/uPH4CG6juwpjYvYVUcjK+7gbRwf3wWsWMpk90Z4ju2iUiP5c1J/oK9P+1T3PIr6M4Xjza8JJj+r9KC/PVB0gBv6vVM96cDpKUEy/UMpcn/T81vqj/Z+WEOODU8Ms6NiTTm+u9ldvpCjbu0u8M+9c0JeIyadJvSTFEQKBgQCsxmFyM3nq8YfpgU2qqNjfBeRH3faSVUy+nj1a/YZYjKS+A/i1BCnYUImeBVNN6chNV342ggvY4xxruDiU9Vcw8wd58O09Oi8BEIFSP6upL6cebUI6Fjo3xlegLJRiwV6INkNTJOYM5hD/mSxUACwXQFfkJipBINXBIgraWD1RLQKBgQCj49axWq0F6+WjZVOyPaD3uh37p9trRUxRhWTxw3fB23WdktaKMgbCqHOmwzP4bRLSEVQtf2dOz1gMqu14b8HqJvgAf/F/11YJ9hz09LEhmjZVjE68HZfqT7uK2W5OX8/lfXmK7TFcj6SjG5YB96lZMhTZ0WnufEd6QkdKDZYXIQKBgQD9GDTcIMbFwbEaKHnfZaTD3f876EGRgsgrCxwdEk7LBCRPwWo7yI929M4psIlpNwNeiyjBkBunWIVkpznp6qPtJqagIPUYesU4f5v6/okq5wcpaNKSkWbIvWVLaLGOiA1aeGJtbpMpyClbSr52puHpRRdvAiIEQ74yYh0JX8q96g==") .setAlipayPublicKey("MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAiQkrz+emAuS1mB3KKDOMmAZRd/BlPbh7fAIHAqAj1+QCZNcV3o2BTLIIqnuKpSlFXDG3uDzp2VsBxcizXuBbFyPGylnD9CgCj5abyh3+FIHPAZ2IM3TtpqImZ0TSPGXrMli4Nir7MvZktgccCqQKCC4o6iaDGz+UwWwJUIPna8fm2tiTZ+KH150CZbKVj4ZGNpBh5XSV/1dRgyQIV9D/EwSbkZ0n6VgKQLJBi0C2UE3QB17aL1Ir6+gDXIDbknN8O7GUD3aMGdThYdSRUb5wp9CZ5qfV7vCS/CgaRo38nhH3NOzkTL+7v0m1ZDHPmqEkn9VzZN6sCQdL7PoAOjHOCwIDAQAB") .setDomain("https://openapi.alipay.com/gateway.do"); +// return new AlipayConfigDto() +// .setAppId("2021004145625815") +// .setPrivateKey("MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCAjDBuS8K/IJb9ui+KuNm/sTUdEiaji4BNpZ92avO1N5JpNlGmac6ec4p3tNFT950sBLcQkClcUpQxUHQzAT6DYNNXOKyvfI/EmcqwCw6PaMNLs/8cV//J2WWZBUhLaOsjKurpm9/3W5MnTh4BGxIfBoeBMA8f8K3BgKdmyKtvIEV2h2cyjsMskdn+g6oNZcmWcms0pvpPHyH46mRaGFhpp0v19wX3WsamGldh1L2VntmaDN3C2XbSrXv90XYp5bEUqwTbLwXpMAlzTibF56d/iqv9oYi8cpAKougUFLOymnbutLNs2tLrEDSFwHcmG2/wbZHybZyYcIgFgv4arf+tAgMBAAECggEAf7hKKlw1y6Z6vvAtalxNZUuRZSfyog3p1bwYWxTavZPQcZ7Zs0lvVDmiO1u5m/7q96BbryY9IhCeUv0H5uF2lhwu/3s9AEL3qTPQkeb6eXxyhhX6A9RfPdM1Qbtg4CQHdHKg4qjP9znSVHwmDZ0y/QaEvdPdQzPjv92u9c2tn4N4x6XyBYcU5gzxiJNnIugCmBgcJo/3H2fgV+XXEhORPvy5of9b4oATHEaLS/8dAS2wuOjhzaGS4MXp3VkXn3XaYjwSzaL03qYWA+xm+aO5sJv8bmqZW7sNVck5o3sPo7cQ4VkBFVzyrRdmJcxcSRJ9MsB9JsrhoKI8pgaXrVie4QKBgQDU2vai0lpBIK/0jzRpPNoqdT8lnafnnWni8nU4kfAh+gCLi+HBPhQRT0kv4unQc2q2/gALE7sgZVO00JGY5a3R0orsojPoUSZlpypGW7GGqKy576NHn0nw4o/PdfysT92VWgt1hlfTf6qfCDhfE9APU+RGvlSWXcT8nxVel3iUaQKBgQCamoJN6+4v+chJvL2nqV8NVVRLp0vDIHxs1QOtKwUodx8Qp1D6CJYtavCXn8aNUFVNQJPJ7TQPpJjXP2rI4SN01weDwx+I+wh8PBGHV6/234R+6TvFgY1PrYgCdfNP4i/E7B4uyEhAxdU73PB8qkqRAeJGok05p7oG71KCOBiYpQKBgEZfGflcuDAeAW5GRhqg3rP4zWa/R7qgZVh9tll8jjp9b96y4XFE99d9MgId8BVVgyt6sEL5Q/2C4ni+F9TH4n6jMADp42VkJuCmsqhOOlP9whU67+2G8Sgtj0QUivPg964f9ffl8XVgGOW5DwIIB9p5btggptCLscufQK5kP545AoGADBvf6tR4wl8w9b2HqTMV08iEIqzGvVC1Dh0c/Zop/EJgN4CzUfIMOSBwGaAVAApzs+pD6QPgGP2OTwWTioo/qa4R05sbxDHNN1XJFa2jhZV6HiqMWOrNs5jm1zJ/zRjtHuJTdtyO9CvKiLbESy9XScY4/8lEfSiK5HIoJzTXkFUCgYAkYkvkW6psJpWj05XWq44UN0n6QOU/Igl35Um/iuOMVhsTmIt09STQVTuzJzfH82+sCqoRsD1blE5unKNUC1DK77aNKTv3Z0dxN9R7FAyfZRiYQXTrbBPBqWjay6FCNxn8e8UsJN4Z6FIV2LGlQI114krSap1MALKLVvnld0NaUQ==") +// .setAlipayPublicKey("MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAiQkrz+emAuS1mB3KKDOMmAZRd/BlPbh7fAIHAqAj1+QCZNcV3o2BTLIIqnuKpSlFXDG3uDzp2VsBxcizXuBbFyPGylnD9CgCj5abyh3+FIHPAZ2IM3TtpqImZ0TSPGXrMli4Nir7MvZktgccCqQKCC4o6iaDGz+UwWwJUIPna8fm2tiTZ+KH150CZbKVj4ZGNpBh5XSV/1dRgyQIV9D/EwSbkZ0n6VgKQLJBi0C2UE3QB17aL1Ir6+gDXIDbknN8O7GUD3aMGdThYdSRUb5wp9CZ5qfV7vCS/CgaRo38nhH3NOzkTL+7v0m1ZDHPmqEkn9VzZN6sCQdL7PoAOjHOCwIDAQAB") +// .setDomain("https://openapi.alipay.com/gateway.do"); } } diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java index 64a5d5d90..c9904ccaa 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java @@ -2,21 +2,33 @@ package com.czg.third.wechat; import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONWriter; -import com.czg.dto.req.AggregateMerchantDto; -import com.czg.dto.resp.EntryRespDto; +import com.czg.PayCst; +import com.czg.dto.req.*; +import com.czg.dto.resp.EntryThirdRespDto; +import com.czg.exception.CzgException; import com.czg.third.wechat.dto.config.WechatPayConfigDto; -import com.czg.third.wechat.dto.req.entry.WechatEntryReqDto; +import com.czg.third.wechat.dto.req.entry.*; +import com.czg.third.wechat.dto.req.entry.business.WechatEntryBusinessReqDto; +import com.czg.third.wechat.dto.req.entry.business.WechatEntryIdentityReqDto; +import com.czg.third.wechat.dto.req.entry.business.WechatEntryLicenseReqDto; +import com.czg.third.wechat.dto.req.entry.business.sales.WechatEntryMiniProgramReqDto; +import com.czg.third.wechat.dto.req.entry.business.sales.WechatEntrySalesInfoReqDto; +import com.czg.third.wechat.dto.req.entry.business.sales.WechatEntryStoreInfoReqDto; import com.czg.utils.UploadFileUtil; +import com.wechat.pay.java.core.Config; +import com.wechat.pay.java.core.cipher.PrivacyEncryptor; import com.wechat.pay.java.service.file.FileUploadService; import com.wechat.pay.java.service.file.model.FileUploadResponse; import lombok.extern.slf4j.Slf4j; import java.io.IOException; +import java.util.List; import java.util.Map; /** * 微信支付进件 管理 * 参考地址 ... + * * @author yjjie * @date 2025/12/26 10:57 */ @@ -29,8 +41,23 @@ public class WechatEntryManager { * @param configDto 配置信息 * @param reqDto 请求信息 */ - public static EntryRespDto entryMerchant(WechatPayConfigDto configDto, AggregateMerchantDto reqDto) { - return new EntryRespDto(); + public static EntryThirdRespDto entryMerchant(WechatPayConfigDto configDto, AggregateMerchantDto reqDto) { + WechatEntryReqDto entryReqDto = buildEntryParams(configDto, reqDto); + EntryThirdRespDto respDto = new EntryThirdRespDto() + .setPlatform(PayCst.Platform.WECHAT); + + try { + String params = JSONObject.toJSONString(entryReqDto, JSONWriter.Feature.IgnoreEmpty); + String respBody = WechatReqUtils.postReq(configDto, "/v3/applyment4sub/applyment/", params); + System.out.println("调用成功:" + respBody); + } catch (Exception e) { + log.error("微信进件报错:{}", e.getMessage(), e); + respDto.setStatus(PayCst.EntryStatus.FAIL); + respDto.setEntryId(""); + respDto.setErrorMsg(e.getMessage()); + } + + return respDto; } public static JSONObject queryBankList(WechatPayConfigDto configDto, Integer offset, Integer limit) { @@ -50,28 +77,15 @@ public class WechatEntryManager { } public static JSONObject queryCityList(WechatPayConfigDto configDto, String provinceCode) { - String resp = WechatReqUtils.getReq(configDto, "/v3/capital/capitallhh/areas/provinces/" + provinceCode + "/cities", Map.of()); + String resp = WechatReqUtils.getReq(configDto, "/v3/capital/capitallhh/areas/provinces/" + provinceCode + "/cities", Map.of()); return JSONObject.parseObject(resp); } - /** - * 商户进件 - * - * @param configDto 配置 - * @param reqDto 请求参数 - */ - public static void entryMerchant(WechatPayConfigDto configDto, WechatEntryReqDto reqDto) { - String params = JSONObject.toJSONString(reqDto, JSONWriter.Feature.IgnoreEmpty); - -// String string = WechatReqUtils.encryptReqParam(configDto, "/v3/applyment4sub/applyment/", params); - - WechatReqUtils.postReq(configDto, "/v3/applyment4sub/applyment/", params); - } /** * 上传图片 * - * @param url 图片URL + * @param url 图片URL * @return 图片ID */ public static String uploadImage(WechatPayConfigDto configDto, String url) { @@ -119,6 +133,120 @@ public class WechatEntryManager { return ""; } + /** + * 构建进件参数 + * + * @param reqDto 请求参数 + * @return 进件参数 + */ + private static WechatEntryReqDto buildEntryParams(WechatPayConfigDto configDto, AggregateMerchantDto reqDto) { + WechatEntryReqDto entryParams = new WechatEntryReqDto(); + + Config config = WechatConfig.getRsaConfig(configDto); + PrivacyEncryptor encryptor = config.createEncryptor(); + + entryParams.setBusinessCode(reqDto.getMerchantCode()); + + MerchantBaseInfoDto baseInfo = reqDto.getMerchantBaseInfo(); + LegalPersonInfoDto legalPersonInfo = reqDto.getLegalPersonInfo(); + BusinessLicenceInfoDto businessLicenceInfo = reqDto.getBusinessLicenceInfo(); + StoreInfoDto storeInfo = reqDto.getStoreInfo(); + SettlementInfoDto settlementInfo = reqDto.getSettlementInfo(); + + WechatEntryContactReqDto contactInfo = new WechatEntryContactReqDto(); + contactInfo.setContactType(baseInfo.getContactPersonType()); + // 默认都使用身份证 暂不支持其他证件 + contactInfo.setContactIdDocCopy("IDENTIFICATION_TYPE_IDCARD"); + if (PayCst.ContactPersonType.SUPER.equals(baseInfo.getContactPersonType())) { + contactInfo.setContactName(encryptor.encrypt(baseInfo.getContactName())); + contactInfo.setContactIdNumber(encryptor.encrypt(baseInfo.getContactPersonId())); + contactInfo.setContactIdDocCopy(baseInfo.getContactIdCardFrontPic().getWechatId()); + contactInfo.setContactIdDocCopyBack(baseInfo.getContactIdCardBackPic().getWechatId()); + contactInfo.setContactPeriodBegin(baseInfo.getContactPersonIdStartDate()); + contactInfo.setContactPeriodEnd(baseInfo.getContactPersonIdEndDate()); + contactInfo.setMobilePhone(encryptor.encrypt(baseInfo.getContactPhone())); + contactInfo.setContactEmail(encryptor.encrypt(baseInfo.getContactEmail())); + } else if (PayCst.ContactPersonType.LEGAL.equals(baseInfo.getContactPersonType())) { + contactInfo.setContactName(encryptor.encrypt(legalPersonInfo.getLegalPersonName())); + contactInfo.setContactIdNumber(encryptor.encrypt(legalPersonInfo.getLegalPersonId())); + contactInfo.setContactIdDocCopy(legalPersonInfo.getIdCardFrontPic().getWechatId()); + contactInfo.setContactIdDocCopyBack(legalPersonInfo.getIdCardBackPic().getWechatId()); + contactInfo.setContactPeriodBegin(legalPersonInfo.getLegalIdPersonStartDate()); + contactInfo.setContactPeriodEnd(legalPersonInfo.getLegalPersonIdEndDate()); + contactInfo.setMobilePhone(encryptor.encrypt(legalPersonInfo.getLegalPersonPhone())); + contactInfo.setContactEmail(encryptor.encrypt(legalPersonInfo.getLegalPersonEmail())); + } else { + throw new CzgException("联系人类型错误"); + } + entryParams.setContactInfo(contactInfo); + + WechatEntrySubjectReqDto subjectInfo = new WechatEntrySubjectReqDto(); + if ("0".equals(baseInfo.getUserType())) { + subjectInfo.setSubjectType("SUBJECT_TYPE_INDIVIDUAL"); + } else if ("1".equals(baseInfo.getUserType())) { + switch (baseInfo.getCompanyChildType()) { + case "1" -> subjectInfo.setSubjectType("SUBJECT_TYPE_ENTERPRISE"); + case "2" -> subjectInfo.setSubjectType("SUBJECT_TYPE_INSTITUTIONS"); + case "3" -> subjectInfo.setSubjectType("SUBJECT_TYPE_GOVERNMENT"); + case "4" -> subjectInfo.setSubjectType("SUBJECT_TYPE_OTHERS"); + default -> throw new CzgException("主体类型错误"); + } + } else { + throw new CzgException("用户类型错误"); + } + subjectInfo.setFinanceInstitution(false); + + WechatEntryLicenseReqDto licenseReqDto = new WechatEntryLicenseReqDto(); + licenseReqDto.setLicenseCopy(businessLicenceInfo.getLicensePic().getWechatId()); + licenseReqDto.setLicenseNumber(businessLicenceInfo.getLicenceNo()); + licenseReqDto.setMerchantName(businessLicenceInfo.getLicenceName()); + licenseReqDto.setLegalPerson(legalPersonInfo.getLegalPersonName()); + licenseReqDto.setLicenseAddress(businessLicenceInfo.getRegisteredAddress()); + licenseReqDto.setPeriodBegin(businessLicenceInfo.getLicenceStartDate()); + licenseReqDto.setPeriodEnd(businessLicenceInfo.getLicenceEndDate()); + subjectInfo.setBusinessLicenseInfo(licenseReqDto); + WechatEntryIdentityReqDto identityInfo = new WechatEntryIdentityReqDto(); + identityInfo.setIdHolderType(PayCst.ContactPersonType.LEGAL); + subjectInfo.setIdentityInfo(identityInfo); + entryParams.setSubjectInfo(subjectInfo); + + WechatEntryBusinessReqDto businessReqInfo = new WechatEntryBusinessReqDto(); + businessReqInfo.setMerchantShortname(baseInfo.getShortName()); + businessReqInfo.setServicePhone(PayCst.ContactPersonType.LEGAL.equals(baseInfo.getContactPersonType()) ? legalPersonInfo.getLegalPersonPhone() : baseInfo.getContactPhone()); + WechatEntrySalesInfoReqDto salesInfo = new WechatEntrySalesInfoReqDto(); + salesInfo.setSalesScenesType(List.of("SALES_SCENES_STORE", "SALES_SCENES_MINI_PROGRAM")); + WechatEntryStoreInfoReqDto bizStoreInfo = new WechatEntryStoreInfoReqDto(); + bizStoreInfo.setBizStoreName(baseInfo.getShortName()); + bizStoreInfo.setBizAddressCode(storeInfo.getMercAreaCode()); + bizStoreInfo.setBizStoreAddress(storeInfo.getBusinessAddress()); + bizStoreInfo.setStoreEntrancePic(List.of(storeInfo.getDoorPic().getWechatId())); + bizStoreInfo.setIndoorPic(List.of(storeInfo.getInsidePic().getWechatId(), storeInfo.getCashierDeskPic().getWechatId())); + salesInfo.setBizStoreInfo(bizStoreInfo); + WechatEntryMiniProgramReqDto miniProgramInfo = new WechatEntryMiniProgramReqDto(); + miniProgramInfo.setMiniProgramAppid("wxd88fffa983758a30"); + salesInfo.setMiniProgramInfo(miniProgramInfo); + businessReqInfo.setSalesInfo(salesInfo); + entryParams.setBusinessInfo(businessReqInfo); + + WechatEntrySettleReqDto settlementReqInfo = new WechatEntrySettleReqDto(); + settlementReqInfo.setSettlementId("0".equals(baseInfo.getUserType()) ? "719" : "716"); + settlementReqInfo.setQualificationType("餐饮"); + settlementReqInfo.setActivitiesId("20191030111cff5b5e"); + settlementReqInfo.setActivitiesRate("0.38"); + entryParams.setSettlementInfo(settlementReqInfo); + + WechatEntryBankAccountReqDto bankAccountReqInfo = new WechatEntryBankAccountReqDto(); + bankAccountReqInfo.setBankAccountType("21".equals(settlementInfo.getSettlementCardType()) ? "BANK_ACCOUNT_TYPE_CORPORATE" : "BANK_ACCOUNT_TYPE_PERSONAL"); + bankAccountReqInfo.setAccountName(encryptor.encrypt(settlementInfo.getSettlementName())); + bankAccountReqInfo.setAccountBank(settlementInfo.getBankName()); + bankAccountReqInfo.setBankBranchId(settlementInfo.getBankBranchCode()); + bankAccountReqInfo.setBankName(settlementInfo.getBankBranchName()); + bankAccountReqInfo.setAccountNumber(encryptor.encrypt(settlementInfo.getSettlementCardNo())); + entryParams.setBankAccountInfo(bankAccountReqInfo); + + return entryParams; + } + public static void main(String[] args) throws IOException { WechatPayConfigDto dto = new WechatPayConfigDto() .setMerchantId("1643779408") diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatReqUtils.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatReqUtils.java index 57a831c80..13a1e2137 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatReqUtils.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatReqUtils.java @@ -40,6 +40,9 @@ public class WechatReqUtils { } private static String req(WechatPayConfigDto configDto, String url, String method, String body) { + if (configDto == null) { + configDto = WechatPayConfigDto.getDefaultConfig(); + } long timestamp = getTimestamp(); String nonce = getNonceStr(); String signature = encryptReqParam(configDto, method, url, body, timestamp, nonce); @@ -83,12 +86,11 @@ public class WechatReqUtils { public static String encryptReqParam(WechatPayConfigDto configDto, String method, String url, String body, long timestamp, String nonce) { String encryptStr = String.format("%s\n%s\n%d\n%s\n%s\n", method, url, timestamp, nonce, body); - log.info("encryptStr = {}", encryptStr); Config config = WechatConfig.getRsaConfig(configDto); Signer signer = config.createSigner(); String signature = signer.sign(encryptStr).getSign(); - log.info("签名 signature:{}", signature); + log.info("微信签名 encryptStr = {},\nsignature:{}", encryptStr, signature); return signature; } From f89fda069876b3b6525b5fc9b49d82585aa71061 Mon Sep 17 00:00:00 2001 From: gong <1157756119@qq.com> Date: Wed, 7 Jan 2026 15:01:33 +0800 Subject: [PATCH 16/19] =?UTF-8?q?=E6=9E=84=E5=BB=BA=E6=94=AF=E4=BB=98?= =?UTF-8?q?=E5=AE=9D=E8=BF=9B=E4=BB=B6=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/czg/EntryManager.java | 8 +- .../com/czg/dto/req/SettlementInfoDto.java | 5 + .../czg/third/alipay/AlipayEntryManager.java | 114 +++++++++++++++++- .../czg/third/wechat/WechatEntryManager.java | 11 +- .../com/czg/third/wechat/WechatReqUtils.java | 4 +- 5 files changed, 133 insertions(+), 9 deletions(-) diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/EntryManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/EntryManager.java index a90b242da..0aa4bc0a8 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/EntryManager.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/EntryManager.java @@ -295,6 +295,8 @@ public class EntryManager { SettlementInfoDto settlementInfo = reqDto.getSettlementInfo(); AssertUtil.isBlank(settlementInfo.getSettlementCardNo(), "结算卡号不能为空"); AssertUtil.isBlank(settlementInfo.getSettlementName(), "结算账户户名不能为空"); + AssertUtil.isBlank(settlementInfo.getBankName(), "结算银行名称不能为空"); + AssertUtil.isBlank(settlementInfo.getBankInstId(), "结算银行缩写不能为空"); AssertUtil.isBlank(settlementInfo.getBankMobile(), "结算银行预留手机号不能为空"); AssertUtil.isBlank(settlementInfo.getSettlementCardType(), "结算卡类型不能为空"); AssertUtil.isBlank(settlementInfo.getOpenAccProvinceId(), "结算开户行省ID不能为空"); @@ -346,8 +348,9 @@ public class EntryManager { verifyEntryParam(merchantDto); uploadParamImage(merchantDto); System.out.println(merchantDto); - entryMerchant(merchantDto, PayCst.Platform.WECHAT); -// entryMerchant(merchantDto, PayCst.Platform.WECHAT, PayCst.Platform.ALIPAY); +// entryMerchant(merchantDto, PayCst.Platform.WECHAT); +// entryMerchant(merchantDto, PayCst.Platform.ALIPAY); + entryMerchant(merchantDto, PayCst.Platform.WECHAT, PayCst.Platform.ALIPAY); } private static AggregateMerchantDto getTestMerchantEntryData() { @@ -420,6 +423,7 @@ public class EntryManager { settlementInfoDto.setOpenAccCity("深圳市"); settlementInfoDto.setOpenAccArea("南山区"); settlementInfoDto.setBankName("中国工商银行"); + settlementInfoDto.setBankInstId("ICBC"); settlementInfoDto.setBankType("1"); settlementInfoDto.setBankBranchName("广东省深圳市南山区"); settlementInfoDto.setBankBranchCode("440300"); diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/SettlementInfoDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/SettlementInfoDto.java index b58705cea..c0b9c6dc4 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/SettlementInfoDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/SettlementInfoDto.java @@ -81,6 +81,11 @@ public class SettlementInfoDto { */ private String bankName; + /** + * 开户行缩写 + */ + private String bankInstId; + /** * 开户行编号 */ diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayEntryManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayEntryManager.java index de32ddd66..feeb47dc5 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayEntryManager.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayEntryManager.java @@ -4,11 +4,17 @@ import com.alibaba.fastjson2.JSONArray; import com.alipay.api.DefaultAlipayClient; import com.alipay.api.FileItem; import com.alipay.api.domain.AlipayFinancialnetAuthPbcnameQueryModel; +import com.alipay.api.domain.AntMerchantExpandIndirectZftCreateModel; import com.alipay.api.domain.AntMerchantExpandIndirectZftSimplecreateModel; +import com.alipay.api.domain.SiteInfo; import com.alipay.api.request.AlipayFinancialnetAuthPbcnameQueryRequest; import com.alipay.api.request.AntMerchantExpandIndirectImageUploadRequest; +import com.alipay.api.request.AntMerchantExpandIndirectZftCreateRequest; +import com.alipay.api.request.AntMerchantExpandIndirectZftSimplecreateRequest; import com.alipay.api.response.AlipayFinancialnetAuthPbcnameQueryResponse; import com.alipay.api.response.AntMerchantExpandIndirectImageUploadResponse; +import com.alipay.api.response.AntMerchantExpandIndirectZftCreateResponse; +import com.alipay.api.response.AntMerchantExpandIndirectZftSimplecreateResponse; import com.alipay.v3.ApiClient; import com.alipay.v3.ApiException; import com.alipay.v3.Configuration; @@ -17,10 +23,11 @@ import com.alipay.v3.api.AntMerchantExpandIndirectImageApi; import com.alipay.v3.model.*; import com.alipay.v3.util.model.AlipayConfig; import com.czg.PayCst; -import com.czg.dto.req.AggregateMerchantDto; +import com.czg.dto.req.*; import com.czg.dto.resp.BankBranchDto; import com.czg.dto.resp.EntryRespDto; import com.czg.dto.resp.EntryThirdRespDto; +import com.czg.exception.CzgException; import com.czg.third.alipay.dto.config.AlipayConfigDto; import com.czg.third.wechat.dto.req.entry.WechatEntryReqDto; import com.czg.utils.UploadFileUtil; @@ -50,12 +57,25 @@ public class AlipayEntryManager { * @param reqDto 请求信息 */ public static EntryThirdRespDto entryMerchant(AlipayConfigDto configDto, AggregateMerchantDto reqDto) { - AntMerchantExpandIndirectZftSimplecreateModel entryReqDto = buildEntryParams(reqDto); + AntMerchantExpandIndirectZftCreateModel entryReqDto = buildEntryParams(reqDto); EntryThirdRespDto respDto = new EntryThirdRespDto() .setPlatform(PayCst.Platform.ALIPAY); try { -// entry(configDto, entryReqDto); + AntMerchantExpandIndirectZftCreateRequest request = new AntMerchantExpandIndirectZftCreateRequest(); + DefaultAlipayClient defaultAlipayClient = AlipayClient.getDefaultClient(configDto); + request.setBizModel(entryReqDto); + AntMerchantExpandIndirectZftCreateResponse response = defaultAlipayClient.execute(request); + log.info("支付宝进件结果:{}", response.getBody()); + if (response.isSuccess()) { + respDto.setStatus(PayCst.EntryStatus.INIT); + respDto.setEntryId(response.getOrderId()); + respDto.setErrorMsg(""); + } else { + respDto.setStatus(PayCst.EntryStatus.FAIL); + respDto.setEntryId(""); + respDto.setErrorMsg(response.getSubMsg()); + } } catch (Exception e) { log.error("支付宝进件报错:{}", e.getMessage(), e); respDto.setStatus(PayCst.EntryStatus.FAIL); @@ -135,9 +155,93 @@ public class AlipayEntryManager { * @param reqDto 请求参数 * @return 进件参数 */ - private static AntMerchantExpandIndirectZftSimplecreateModel buildEntryParams(AggregateMerchantDto reqDto) { - AntMerchantExpandIndirectZftSimplecreateModel entryParams = new AntMerchantExpandIndirectZftSimplecreateModel(); + private static AntMerchantExpandIndirectZftCreateModel buildEntryParams(AggregateMerchantDto reqDto) { + AntMerchantExpandIndirectZftCreateModel entryParams = new AntMerchantExpandIndirectZftCreateModel(); + MerchantBaseInfoDto baseInfo = reqDto.getMerchantBaseInfo(); + LegalPersonInfoDto legalPersonInfo = reqDto.getLegalPersonInfo(); + BusinessLicenceInfoDto businessLicenceInfo = reqDto.getBusinessLicenceInfo(); + StoreInfoDto storeInfo = reqDto.getStoreInfo(); + SettlementInfoDto settlementInfo = reqDto.getSettlementInfo(); + + entryParams.setExternalId(reqDto.getMerchantCode()); + if ("0".equals(baseInfo.getUserType())) { + entryParams.setMerchantType("07"); + } else if ("1".equals(baseInfo.getUserType())) { + switch (baseInfo.getCompanyChildType()) { + case "1" -> entryParams.setMerchantType("01"); + case "2" -> entryParams.setMerchantType("02"); + case "3" -> entryParams.setMerchantType("05"); + case "4" -> entryParams.setMerchantType("04"); + default -> throw new CzgException("主体类型错误"); + } + } else { + throw new CzgException("用户类型错误"); + } + entryParams.setName(businessLicenceInfo.getLicenceName()); + entryParams.setAliasName(baseInfo.getShortName()); + entryParams.setMcc(baseInfo.getMccCode()); + entryParams.setService(List.of("当面付", "jsapi支付", "小程序支付")); + entryParams.setInDoorImages(List.of(storeInfo.getInsidePic().getAlipayId(), storeInfo.getCashierDeskPic().getAlipayId())); + entryParams.setOutDoorImages(List.of(storeInfo.getDoorPic().getAlipayId())); + + // 证件类型(目前只支持个体和企业,所以都是营业执照) + entryParams.setCertType("201"); + entryParams.setCertImage(businessLicenceInfo.getLicensePic().getAlipayId()); + entryParams.setCertNo(businessLicenceInfo.getLicenceNo()); + + entryParams.setLegalName(legalPersonInfo.getLegalPersonName()); + entryParams.setLegalCertNo(legalPersonInfo.getLegalPersonId()); + entryParams.setLegalCertFrontImage(legalPersonInfo.getIdCardFrontPic().getAlipayId()); + entryParams.setLegalCertBackImage(legalPersonInfo.getIdCardBackPic().getAlipayId()); + + entryParams.setServicePhone(PayCst.ContactPersonType.LEGAL.equals(baseInfo.getContactPersonType()) ? legalPersonInfo.getLegalPersonPhone() : baseInfo.getContactPhone()); + + com.alipay.api.domain.AddressInfo addressInfo = new com.alipay.api.domain.AddressInfo(); + addressInfo.setCityCode(storeInfo.getMercCityCode()); + addressInfo.setDistrictCode(storeInfo.getMercAreaCode()); + addressInfo.setProvinceCode(storeInfo.getMercProvCode()); + addressInfo.setAddress(storeInfo.getBusinessAddress()); + entryParams.setBusinessAddress(addressInfo); + + com.alipay.api.domain.SettleCardInfo settleCardInfo = new com.alipay.api.domain.SettleCardInfo(); + settleCardInfo.setAccountHolderName(settlementInfo.getSettlementName()); + settleCardInfo.setAccountNo(settlementInfo.getSettlementCardNo()); + settleCardInfo.setAccountInstProvince(settlementInfo.getOpenAccProvince()); + settleCardInfo.setAccountInstCity(settlementInfo.getOpenAccCity()); + settlementInfo.setBankBranchName(settlementInfo.getBankBranchName()); + settleCardInfo.setUsageType("21".equals(settlementInfo.getSettlementCardType()) ? "01" : "02"); + settleCardInfo.setAccountType("DC"); + settleCardInfo.setAccountInstName(settlementInfo.getBankName()); + settleCardInfo.setAccountInstId(settlementInfo.getBankInstId()); + settleCardInfo.setBankCode(settlementInfo.getBankBranchCode()); + entryParams.setBizCards(List.of(settleCardInfo)); + + com.alipay.api.domain.ContactInfo contactInfo = new com.alipay.api.domain.ContactInfo(); + if (PayCst.ContactPersonType.SUPER.equals(baseInfo.getContactPersonType())) { + contactInfo.setName(baseInfo.getContactName()); + contactInfo.setMobile(baseInfo.getContactPhone()); + contactInfo.setEmail(baseInfo.getContactEmail()); + contactInfo.setIdCardNo(baseInfo.getContactPersonId()); + } else if (PayCst.ContactPersonType.LEGAL.equals(baseInfo.getContactPersonType())) { + contactInfo.setName(legalPersonInfo.getLegalPersonName()); + contactInfo.setMobile(legalPersonInfo.getLegalPersonPhone()); + contactInfo.setEmail(legalPersonInfo.getLegalPersonEmail()); + contactInfo.setIdCardNo(legalPersonInfo.getLegalPersonId()); + } else { + throw new CzgException("联系人类型错误"); + } + entryParams.setContactInfos(List.of(contactInfo)); + + entryParams.setLicenseAuthLetterImage(businessLicenceInfo.getLicensePic().getAlipayId()); + + // 小程序 + SiteInfo miniAppInfo = new SiteInfo(); + miniAppInfo.setSiteType("06"); + miniAppInfo.setSiteUrl("https://sxczgkj.cn"); + miniAppInfo.setSiteName("银收客"); + miniAppInfo.setTinyAppId("2021004145625815"); + entryParams.setSites(List.of(miniAppInfo)); return entryParams; } diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java index c9904ccaa..29568043a 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java @@ -49,7 +49,16 @@ public class WechatEntryManager { try { String params = JSONObject.toJSONString(entryReqDto, JSONWriter.Feature.IgnoreEmpty); String respBody = WechatReqUtils.postReq(configDto, "/v3/applyment4sub/applyment/", params); - System.out.println("调用成功:" + respBody); + JSONObject object = JSONObject.parseObject(respBody); + if (object.containsKey("applyment_id")) { + respDto.setStatus(PayCst.EntryStatus.INIT); + respDto.setEntryId(object.getString("applyment_id")); + respDto.setErrorMsg(""); + } else { + respDto.setStatus(PayCst.EntryStatus.FAIL); + respDto.setEntryId(""); + respDto.setErrorMsg(object.getString("message")); + } } catch (Exception e) { log.error("微信进件报错:{}", e.getMessage(), e); respDto.setStatus(PayCst.EntryStatus.FAIL); diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatReqUtils.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatReqUtils.java index 13a1e2137..32c95eec2 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatReqUtils.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatReqUtils.java @@ -1,6 +1,7 @@ package com.czg.third.wechat; import cn.hutool.http.HttpRequest; +import cn.hutool.http.HttpResponse; import cn.hutool.http.HttpUtil; import com.czg.exception.CzgException; import com.czg.third.wechat.dto.config.WechatPayConfigDto; @@ -62,7 +63,8 @@ public class WechatReqUtils { .header("Wechatpay-Serial", configDto.getPublicKeyId()); default -> throw new CzgException("不支持的请求方法"); }; - String s = request.execute().body(); + HttpResponse response = request.execute(); + String s = response.body(); log.info("微信支付请求:url = {}, method: {}, body: {}, resp: {}", url, method, body, s); return s; } From 006035f71b82397aa040fc9272311f08d6622320 Mon Sep 17 00:00:00 2001 From: gong <1157756119@qq.com> Date: Wed, 7 Jan 2026 17:10:10 +0800 Subject: [PATCH 17/19] =?UTF-8?q?=E8=BF=9B=E4=BB=B6=E7=8A=B6=E6=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/czg/PayCst.java | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/PayCst.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/PayCst.java index 5000c63ac..52de66b27 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/PayCst.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/PayCst.java @@ -25,15 +25,35 @@ public interface PayCst { * 进件状态 */ class EntryStatus { + /** + * 待提交 + */ + public static final String WAIT = "WAIT"; + /** * 待处理 */ public static final String INIT = "INIT"; + /** + * 审核中 + */ + public static final String AUDIT = "AUDIT"; + + /** + * 待签约 + */ + public static final String SIGN = "SIGN"; + + /** + * 已完成 + */ + public static final String FINISH = "FINISH"; + /** * 失败 */ - public static final String FAIL = "FAIL"; + public static final String REJECTED = "REJECTED"; } /** From 21b9acf3c96be29598b9a8ad324dbe685fc967d6 Mon Sep 17 00:00:00 2001 From: gong <1157756119@qq.com> Date: Wed, 7 Jan 2026 17:51:52 +0800 Subject: [PATCH 18/19] =?UTF-8?q?=E6=9F=A5=E8=AF=A2=E8=BF=9B=E4=BB=B6?= =?UTF-8?q?=E7=8A=B6=E6=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/czg/EntryManager.java | 23 ++- .../com/czg/dto/resp/QueryStatusResp.java | 49 +++++++ .../czg/third/alipay/AlipayEntryManager.java | 128 +++++++++++++++-- .../czg/third/wechat/WechatEntryManager.java | 132 +++++++++++------- .../wechat/dto/resp/WechatAuditDetail.java | 29 ++++ .../wechat/dto/resp/WechatQueryStateResp.java | 70 ++++++++++ 6 files changed, 361 insertions(+), 70 deletions(-) create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/dto/resp/QueryStatusResp.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/resp/WechatAuditDetail.java create mode 100644 cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/resp/WechatQueryStateResp.java diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/EntryManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/EntryManager.java index 0aa4bc0a8..125864422 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/EntryManager.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/EntryManager.java @@ -6,6 +6,7 @@ import com.czg.dto.req.*; import com.czg.dto.resp.BankBranchDto; import com.czg.dto.resp.EntryRespDto; import com.czg.dto.resp.EntryThirdRespDto; +import com.czg.dto.resp.QueryStatusResp; import com.czg.exception.CzgException; import com.czg.third.alipay.AlipayEntryManager; import com.czg.third.wechat.WechatEntryManager; @@ -33,7 +34,27 @@ public class EntryManager { * @param instId 顶级机构ID CMB */ public static List queryBankBranchList(String province, String city, String instId) { - return AlipayEntryManager.queryBankBranchList(instId, province, city); + return AlipayEntryManager.queryBankBranchList(null, instId, province, city); + } + + /** + * 查询微信进件状态 + * + * @param merchantCode 商户编号 + * @return 进件状态 + */ + public static QueryStatusResp queryWechatEntryStatus(String merchantCode) { + return WechatEntryManager.queryMerchantEntryStatus(null, merchantCode); + } + + /** + * 查询支付宝进件状态 + * + * @param merchantCode 商户编号 + * @return 进件状态 + */ + public static QueryStatusResp queryAlipayEntryStatus(String merchantCode) { + return AlipayEntryManager.queryMerchantEntryStatus(null, merchantCode); } /** diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/resp/QueryStatusResp.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/resp/QueryStatusResp.java new file mode 100644 index 000000000..b6edf25f2 --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/resp/QueryStatusResp.java @@ -0,0 +1,49 @@ +package com.czg.dto.resp; + +import lombok.Data; + +/** + * 查询进件状态 + * @author yjjie + * @date 2026/1/7 17:12 + */ +@Data +public class QueryStatusResp { + + /** + * 平台 + * {@link com.czg.PayCst.Platform} + */ + private String platform; + + /** + * 商户编号 + */ + private String merchantCode; + + /** + * 进件编号 + */ + private String applyId; + + /** + * 三方商户id + */ + private String thirdMerchantId; + + /** + * 进件状态 + * {@link com.czg.PayCst.EntryStatus} + */ + private String status; + + /** + * 签约地址 + */ + private String signUrl; + + /** + * 失败原因 + */ + private String failReason; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayEntryManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayEntryManager.java index feeb47dc5..105476b38 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayEntryManager.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/alipay/AlipayEntryManager.java @@ -1,35 +1,36 @@ package com.czg.third.alipay; +import cn.hutool.core.util.StrUtil; import com.alibaba.fastjson2.JSONArray; +import com.alipay.api.AlipayApiException; import com.alipay.api.DefaultAlipayClient; import com.alipay.api.FileItem; -import com.alipay.api.domain.AlipayFinancialnetAuthPbcnameQueryModel; -import com.alipay.api.domain.AntMerchantExpandIndirectZftCreateModel; -import com.alipay.api.domain.AntMerchantExpandIndirectZftSimplecreateModel; -import com.alipay.api.domain.SiteInfo; +import com.alipay.api.domain.*; import com.alipay.api.request.AlipayFinancialnetAuthPbcnameQueryRequest; import com.alipay.api.request.AntMerchantExpandIndirectImageUploadRequest; import com.alipay.api.request.AntMerchantExpandIndirectZftCreateRequest; -import com.alipay.api.request.AntMerchantExpandIndirectZftSimplecreateRequest; +import com.alipay.api.request.AntMerchantExpandIndirectZftorderQueryRequest; import com.alipay.api.response.AlipayFinancialnetAuthPbcnameQueryResponse; import com.alipay.api.response.AntMerchantExpandIndirectImageUploadResponse; import com.alipay.api.response.AntMerchantExpandIndirectZftCreateResponse; -import com.alipay.api.response.AntMerchantExpandIndirectZftSimplecreateResponse; +import com.alipay.api.response.AntMerchantExpandIndirectZftorderQueryResponse; import com.alipay.v3.ApiClient; import com.alipay.v3.ApiException; import com.alipay.v3.Configuration; import com.alipay.v3.api.AlipayOpenAgentApi; -import com.alipay.v3.api.AntMerchantExpandIndirectImageApi; -import com.alipay.v3.model.*; +import com.alipay.v3.model.AlipayOpenAgentCreateDefaultResponse; +import com.alipay.v3.model.AlipayOpenAgentCreateModel; +import com.alipay.v3.model.AlipayOpenAgentCreateResponseModel; +import com.alipay.v3.model.ContactModel; import com.alipay.v3.util.model.AlipayConfig; import com.czg.PayCst; import com.czg.dto.req.*; import com.czg.dto.resp.BankBranchDto; -import com.czg.dto.resp.EntryRespDto; import com.czg.dto.resp.EntryThirdRespDto; +import com.czg.dto.resp.QueryStatusResp; import com.czg.exception.CzgException; import com.czg.third.alipay.dto.config.AlipayConfigDto; -import com.czg.third.wechat.dto.req.entry.WechatEntryReqDto; +import com.czg.third.wechat.dto.resp.WechatQueryStateResp; import com.czg.utils.UploadFileUtil; import lombok.extern.slf4j.Slf4j; @@ -41,7 +42,6 @@ import java.util.List; /** * 支付宝进件管理 - * * ... * * @author yjjie @@ -50,6 +50,104 @@ import java.util.List; @Slf4j public class AlipayEntryManager { + /** + * 查询商户进件状态 + * + * @param configDto 配置信息 + * @param merchantCode 自系统的商户编号 + * @return 进件状态 + */ + public static QueryStatusResp queryMerchantEntryStatus(AlipayConfigDto configDto, String merchantCode) { + QueryStatusResp queryStatusResp = new QueryStatusResp(); + queryStatusResp.setPlatform(PayCst.Platform.ALIPAY); + queryStatusResp.setMerchantCode(merchantCode); + + AntMerchantExpandIndirectZftorderQueryRequest request = new AntMerchantExpandIndirectZftorderQueryRequest(); + + AntMerchantExpandIndirectZftorderQueryModel model = new AntMerchantExpandIndirectZftorderQueryModel(); + model.setExternalId(merchantCode); + + request.setBizModel(model); + + try { + DefaultAlipayClient defaultAlipayClient = AlipayClient.getDefaultClient(configDto); + AntMerchantExpandIndirectZftorderQueryResponse response = defaultAlipayClient.execute(request); + log.info("支付宝查询进件状态结果:{}", response.getBody()); + + if (response.isSuccess()) { + List orders = response.getOrders(); + if (orders != null && !orders.isEmpty()) { + ZftSubMerchantOrder first = orders.getFirst(); + queryStatusResp.setApplyId(first.getExternalId()); + + if ("99".equals(first.getStatus())) { + // 已完成 + queryStatusResp.setStatus(PayCst.EntryStatus.FINISH); + queryStatusResp.setThirdMerchantId(first.getSmid()); + queryStatusResp.setFailReason(""); + return queryStatusResp; + } + if ("-1".equals(first.getStatus())) { + // 拒绝 + queryStatusResp.setStatus(PayCst.EntryStatus.REJECTED); + queryStatusResp.setFailReason(first.getReason()); + return queryStatusResp; + } + + if (StrUtil.isNotBlank(first.getFkAudit())) { + if ("REJECT".equals(first.getFkAudit())) { + // 风控拒绝 + queryStatusResp.setStatus(PayCst.EntryStatus.REJECTED); + queryStatusResp.setFailReason(first.getFkAuditMemo()); + return queryStatusResp; + } + + if ("CREATE".equals(first.getFkAudit())) { + queryStatusResp.setStatus(PayCst.EntryStatus.AUDIT); + queryStatusResp.setFailReason(first.getFkAuditMemo()); + return queryStatusResp; + } + } + + if (StrUtil.isNotBlank(first.getKzAudit())) { + if ("REJECT".equals(first.getKzAudit())) { + // 风控拒绝 + queryStatusResp.setStatus(PayCst.EntryStatus.REJECTED); + queryStatusResp.setFailReason(first.getKzAuditMemo()); + return queryStatusResp; + } + + if ("CREATE".equals(first.getKzAudit())) { + queryStatusResp.setStatus(PayCst.EntryStatus.AUDIT); + queryStatusResp.setFailReason(first.getKzAuditMemo()); + return queryStatusResp; + } + } + + if (StrUtil.isNotBlank(first.getSubConfirm()) && "FAIL".equals(first.getSubConfirm())) { + // 签约失败 + queryStatusResp.setStatus(PayCst.EntryStatus.REJECTED); + queryStatusResp.setFailReason("签约失败"); + return queryStatusResp; + } + + queryStatusResp.setStatus(PayCst.EntryStatus.SIGN); + queryStatusResp.setSignUrl(first.getSubSignQrCodeUrl()); + return queryStatusResp; + } + } else { + queryStatusResp.setStatus(PayCst.EntryStatus.REJECTED); + queryStatusResp.setFailReason(response.getSubMsg()); + } + } catch (AlipayApiException e) { + log.error("支付宝查询进件状态报错:{}", e.getMessage(), e); + queryStatusResp.setStatus(PayCst.EntryStatus.INIT); + } + + + return queryStatusResp; + } + /** * 进件商户 * @@ -72,13 +170,13 @@ public class AlipayEntryManager { respDto.setEntryId(response.getOrderId()); respDto.setErrorMsg(""); } else { - respDto.setStatus(PayCst.EntryStatus.FAIL); + respDto.setStatus(PayCst.EntryStatus.REJECTED); respDto.setEntryId(""); respDto.setErrorMsg(response.getSubMsg()); } } catch (Exception e) { log.error("支付宝进件报错:{}", e.getMessage(), e); - respDto.setStatus(PayCst.EntryStatus.FAIL); + respDto.setStatus(PayCst.EntryStatus.REJECTED); respDto.setEntryId(""); respDto.setErrorMsg(e.getMessage()); } @@ -128,7 +226,7 @@ public class AlipayEntryManager { * @param province 省份 陕西省 * @param city 城市 西安市 */ - public static List queryBankBranchList(String instId, String province, String city) { + public static List queryBankBranchList(AlipayConfigDto configDto, String instId, String province, String city) { try { AlipayFinancialnetAuthPbcnameQueryRequest request = new AlipayFinancialnetAuthPbcnameQueryRequest(); @@ -138,7 +236,7 @@ public class AlipayEntryManager { model.setCity(city); request.setBizModel(model); - DefaultAlipayClient defaultAlipayClient = AlipayClient.getDefaultClient(null); + DefaultAlipayClient defaultAlipayClient = AlipayClient.getDefaultClient(configDto); AlipayFinancialnetAuthPbcnameQueryResponse response = defaultAlipayClient.execute(request); String data = response.getPbcQueryResult(); diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java index 29568043a..0b320481e 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/WechatEntryManager.java @@ -5,6 +5,7 @@ import com.alibaba.fastjson2.JSONWriter; import com.czg.PayCst; import com.czg.dto.req.*; import com.czg.dto.resp.EntryThirdRespDto; +import com.czg.dto.resp.QueryStatusResp; import com.czg.exception.CzgException; import com.czg.third.wechat.dto.config.WechatPayConfigDto; import com.czg.third.wechat.dto.req.entry.*; @@ -14,6 +15,8 @@ import com.czg.third.wechat.dto.req.entry.business.WechatEntryLicenseReqDto; import com.czg.third.wechat.dto.req.entry.business.sales.WechatEntryMiniProgramReqDto; import com.czg.third.wechat.dto.req.entry.business.sales.WechatEntrySalesInfoReqDto; import com.czg.third.wechat.dto.req.entry.business.sales.WechatEntryStoreInfoReqDto; +import com.czg.third.wechat.dto.resp.WechatAuditDetail; +import com.czg.third.wechat.dto.resp.WechatQueryStateResp; import com.czg.utils.UploadFileUtil; import com.wechat.pay.java.core.Config; import com.wechat.pay.java.core.cipher.PrivacyEncryptor; @@ -35,6 +38,63 @@ import java.util.Map; @Slf4j public class WechatEntryManager { + /** + * 查询商户进件状态 + * + * @param configDto 配置信息 + * @param merchantCode 自系统的商户编号 + * @return 进件状态 + */ + public static QueryStatusResp queryMerchantEntryStatus(WechatPayConfigDto configDto, String merchantCode) { + QueryStatusResp queryStatusResp = new QueryStatusResp(); + queryStatusResp.setPlatform(PayCst.Platform.WECHAT); + queryStatusResp.setMerchantCode(merchantCode); + + String resp = WechatReqUtils.getReq(configDto, "/v3/applyment4sub/applyment/business_code/" + merchantCode, Map.of()); + JSONObject object = JSONObject.parseObject(resp); + JSONObject data = object.getJSONObject("data"); + if (data == null) { + log.error("微信查询进件状态失败:{}", resp); + queryStatusResp.setFailReason(object.getString("message")); + queryStatusResp.setStatus(PayCst.EntryStatus.REJECTED); + return queryStatusResp; + } + log.info("微信查询进件状态:{}", resp); + WechatQueryStateResp stateResp = JSONObject.parseObject(data.toJSONString(), WechatQueryStateResp.class); + + queryStatusResp.setApplyId(stateResp.getApplyId()); + switch (stateResp.getApplyState()) { + case "APPLYMENT_STATE_EDITTING" -> { + queryStatusResp.setStatus(PayCst.EntryStatus.WAIT); + queryStatusResp.setFailReason(""); + } + case "APPLYMENT_STATE_AUDITING" -> { + queryStatusResp.setStatus(PayCst.EntryStatus.AUDIT); + queryStatusResp.setFailReason(""); + } + case "APPLYMENT_STATE_REJECTED" -> { + queryStatusResp.setStatus(PayCst.EntryStatus.REJECTED); + StringBuilder msg = new StringBuilder(); + for (WechatAuditDetail auditDetail : stateResp.getAuditDetail()) { + msg.append(auditDetail.getRejectReason()).append(","); + } + queryStatusResp.setFailReason(msg.toString()); + } + case "APPLYMENT_STATE_TO_BE_CONFIRMED", "APPLYMENT_STATE_TO_BE_SIGNED" -> { + queryStatusResp.setStatus(PayCst.EntryStatus.SIGN); + queryStatusResp.setFailReason(""); + queryStatusResp.setSignUrl(stateResp.getSignUrl()); + } + case "APPLYMENT_STATE_SIGNING", "APPLYMENT_STATE_FINISHED" -> { + queryStatusResp.setStatus(PayCst.EntryStatus.FINISH); + queryStatusResp.setFailReason(""); + queryStatusResp.setThirdMerchantId(stateResp.getSubMchId()); + } + } + + return queryStatusResp; + } + /** * 进件商户 * @@ -46,22 +106,25 @@ public class WechatEntryManager { EntryThirdRespDto respDto = new EntryThirdRespDto() .setPlatform(PayCst.Platform.WECHAT); + log.info("微信进件参数:{}", JSONObject.toJSONString(entryReqDto)); try { String params = JSONObject.toJSONString(entryReqDto, JSONWriter.Feature.IgnoreEmpty); String respBody = WechatReqUtils.postReq(configDto, "/v3/applyment4sub/applyment/", params); JSONObject object = JSONObject.parseObject(respBody); - if (object.containsKey("applyment_id")) { + JSONObject data = object.getJSONObject("data"); + log.info("微信进件结果:{}", respBody); + if (data != null) { respDto.setStatus(PayCst.EntryStatus.INIT); - respDto.setEntryId(object.getString("applyment_id")); + respDto.setEntryId(data.getString("applyment_id")); respDto.setErrorMsg(""); } else { - respDto.setStatus(PayCst.EntryStatus.FAIL); + respDto.setStatus(PayCst.EntryStatus.REJECTED); respDto.setEntryId(""); respDto.setErrorMsg(object.getString("message")); } } catch (Exception e) { log.error("微信进件报错:{}", e.getMessage(), e); - respDto.setStatus(PayCst.EntryStatus.FAIL); + respDto.setStatus(PayCst.EntryStatus.REJECTED); respDto.setEntryId(""); respDto.setErrorMsg(e.getMessage()); } @@ -71,22 +134,25 @@ public class WechatEntryManager { public static JSONObject queryBankList(WechatPayConfigDto configDto, Integer offset, Integer limit) { String resp = WechatReqUtils.getReq(configDto, "/v3/capital/capitallhh/banks/corporate-banking", Map.of("offset", offset, "limit", limit)); - log.info("查询银行列表:{}", resp); + log.info("微信查询银行列表:{}", resp); return JSONObject.parseObject(resp); } public static JSONObject queryBankBranchList(WechatPayConfigDto configDto, String bankAliceCode, String cityCode, Integer offset, Integer limit) { String resp = WechatReqUtils.getReq(configDto, "/v3/capital/capitallhh/banks/" + bankAliceCode + "/branches", Map.of("city_code", cityCode, "offset", offset, "limit", limit)); + log.info("微信查询银行支行列表:{}", resp); return JSONObject.parseObject(resp); } public static JSONObject queryProvinceList(WechatPayConfigDto configDto) { String resp = WechatReqUtils.getReq(configDto, "/v3/capital/capitallhh/areas/provinces", Map.of()); + log.info("微信查询省份列表:{}", resp); return JSONObject.parseObject(resp); } public static JSONObject queryCityList(WechatPayConfigDto configDto, String provinceCode) { String resp = WechatReqUtils.getReq(configDto, "/v3/capital/capitallhh/areas/provinces/" + provinceCode + "/cities", Map.of()); + log.info("微信查询城市列表:{}", resp); return JSONObject.parseObject(resp); } @@ -257,58 +323,16 @@ public class WechatEntryManager { } public static void main(String[] args) throws IOException { - WechatPayConfigDto dto = new WechatPayConfigDto() - .setMerchantId("1643779408") - .setApiV3Key("a92baac5eb7a36ed8ec198113e769a03") - .setSerialNumber("4DE9BAC2EA584C3F274F694C9753CA814C4E9BF4") - .setPublicKey(""" - -----BEGIN PUBLIC KEY----- - MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtbeWXEEjBaYtw2OyM+SC - aCEMbryRXi4duKxx3vYG4rUVix+d5/Jz7Khev4Upml9zC+Xxvv/G9bHWAUyolzqD - wefahGurIxr43r4GJVnQ4i5G6BbBVw5d4Vuz0y/9Zd14zmc/EmBpT0Ml26H7tOZl - n1LSbQ4xNFkrRKrNEcExBLxkCd+K5K2TREZznywIi0izbHImvuzM8IneuR51FiqK - pdFnAjTwb126EIj6ECkL6KLCl8RWqpfiX8SFiolSQLs1/w79O0sIUk96X2zWpnoW - rTDFatPif/VEKl3y2dTlxxDxoZtVi48yTDW00OMzVl5D67oX3FVK0KsjHJSCfGlZ - 6wIDAQAB - -----END PUBLIC KEY-----""") - .setPrivateKey(""" - -----BEGIN PRIVATE KEY----- - MIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQDqnAZhTxT572fo - 6wvSr8Rt0vRXg+EFKC6UvUiNE24oocQU5fjedX9KL/+fmoqay/xqIxvxvCNFTs4J - zlMqavSl6bMWCpjvf/Ry82JmN1v2kJEO4lgP8BsEiqlUpObCH8BMAVUOn1j+9q4Q - uZJJcbtRvec2fNweDM8EJp4B7RlUdDbHm86lfcDVp8iini7VjDp6D7aHT+C8A8OT - ugxQIquDec778wVd9r2Sv3+t6rAzFs+n+Zu++2xtFEPhO5N0wjrLHaukl+9crU+1 - lktjDzcPd07SwGZ+A+3BTmW3UCramI3506e/3MWBECB7ge+gM4URAV0nJJCLH/Im - WgEvPMr5AgMBAAECggEBAKv+wraoMWqiVv1tA/froAgbtcJLDranJK8qrXuvmPz0 - yzm+91qvrSgIVFEADUk67swo/R2Vng37nhWWS2Y3jy/rSr2H+2Lp3Z5ATA0/3I3A - onfU/FaC4mvL9CP32KzMdj/CYkccDzSsSCQ+x75MQNXGcTGDDCSDo2kZnpEu73j3 - aqvO1jbqTGWigRfjOIaIhStjQIT8nEm/3mJ4f5dM9M6FMz33mhax8EahSgvdahYB - t45iaGOWw81OJhmry47EvpwjXBl7jtO2HX3LiLbq5Ebcwu1zqDz5NM7ttnnGAqWC - 6y7JN5Vt4wPYrCydiUDe7dj0looffr2yw6MkNfYjLGECgYEA+FAvbEInQEi9YguS - CQtLHngqvYeai66tvyykog9o38KHnPGx2Myf+rn/Hcp7KNRfjd5G34CCNg7KLnrx - YIYh6+2bY3jirzdYUxuNKGbvM4gky/6M/P9zHF/uALKOE02yArdqemf4UxUvrYCc - JdXsAMqvbpdvW1aGgNRB32YCkG0CgYEA8d89vawsCjNCEUh0VWTMoBLFoex3qBMZ - rfzYQeBo6bDCRlAlUVzl+ouBUxSYxP/U8rzeNaRzGUwRLmlGMjyIr58FBlHsg2cR - DlsX3HVCUjpS6sgPXOqakdiLfhMcHZAspislSyVfeS3TbUWiA45+5PuNUq+EZYwl - ESsB1+yfRT0CgYEA0Ct49ksnWM8iZbXJgeeD3FFlk2rBd2TDqEem5W4Bv8T3p+0/ - 6b7yR2HyrGj5gys3yFmWFP1JLESN3xWWkhMhEQcrg+LuN3Iwi8vHNR3GXu892f7W - 96q4OAt8Hf2S+j/igkB99YyANDbIt63gOh/zMF67X/14j5wkOpC3gK+maqkCgYEA - s7nIrPoUt3ejLiiCmTmPe5q3VDzcJP4cZNau8zSHgK6hjZHcSPsYwPWMoWl6o1fe - qoiBLacHB9MoKS58xLOKdcVZ/Ho/ntylJd+2eVCAeY1xM5h5IfgJ5znbXVFh4O3S - 357L1Wzt5qOQqW/GlZH65LevKbPWU4axvHISqpnfN5kCgYEAqiqLuAPu84VSsqsE - GFh25t+1f0JY1sNfilE3/t9AdQeeCFv/5z9KB1kMt3a5ZFeVonsFIvCyaOJjhSkj - 4HCB94vWS7NuN5G9r874lMaPbZYQGwrcVaf265tN7cYYr3gUx1qB6+u+fh/kcft1 - BBmTzhb0zp5k8ngwAkA1g/LK204= - -----END PRIVATE KEY-----""") - .setPublicKeyId("PUB_KEY_ID_0116437794082025111000382377001000") - .setDomain("https://api.mch.weixin.qq.com"); - int offset = 0; - Integer limit = 100; -// JSONObject resp = queryBankList(dto, offset, limit); + + queryMerchantEntryStatus(null, "20220106000000000001"); + +// int offset = 0; +// Integer limit = 100; +// JSONObject resp = queryBankList(null, offset, limit); // queryBankBranchList(dto, "1000009561", "110000", offset, limit); - queryBankBranchList(dto, "1000009561", "29", offset, limit); +// queryBankBranchList(dto, "1000009561", "29", offset, limit); // queryProvinceList(dto); // queryCityList(dto, "28"); diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/resp/WechatAuditDetail.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/resp/WechatAuditDetail.java new file mode 100644 index 000000000..6e9deea6f --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/resp/WechatAuditDetail.java @@ -0,0 +1,29 @@ +package com.czg.third.wechat.dto.resp; + +import com.alibaba.fastjson2.annotation.JSONField; +import lombok.Data; + +/** + * @author yjjie + * @date 2026/1/7 15:46 + */ +@Data +public class WechatAuditDetail { + /** + * 字段名 + */ + @JSONField(name = "field") + public String field; + + /** + * 字段名称 + */ + @JSONField(name = "field_name") + public String fieldName; + + /** + * 驳回原因 + */ + @JSONField(name = "reject_reason") + public String rejectReason; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/resp/WechatQueryStateResp.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/resp/WechatQueryStateResp.java new file mode 100644 index 000000000..c351d3f3f --- /dev/null +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/third/wechat/dto/resp/WechatQueryStateResp.java @@ -0,0 +1,70 @@ +package com.czg.third.wechat.dto.resp; + +import com.alibaba.fastjson2.annotation.JSONField; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.util.List; + +/** + * 微信进件状态查询返回参数 + * @author yjjie + * @date 2026/1/7 15:42 + */ +@Data +@Accessors(chain = true) +public class WechatQueryStateResp { + + /** + * 业务申请编号 + */ + @JSONField(name = "business_code") + public String businessCode; + + /** + * 微信支付申请单号 + */ + @JSONField(name = "applyment_id") + public String applyId; + + /** + * 特约商户号 + * 当申请单状态为APPLYMENT_STATE_TO_BE_SIGNED、APPLYMENT_STATE_SIGNING、APPLYMENT_STATE_FINISHED时才返回。 + */ + @JSONField(name = "sub_mchid") + public String subMchId; + + /** + * 超级管理员签约链接 + * 1、超级管理员用微信扫码,关注“微信支付商家助手”公众号后,公众号将自动发送签约消息;超管需点击消息,根据指引完成核对联系信息、账户验证、签约等操作; + * 2、超管完成核对联系信息,后续申请单进度可通过公众号自动通知超级管理员。 + */ + @JSONField(name = "sign_url") + public String signUrl; + + /** + * 申请单状态 + * APPLYMENT_STATE_EDITTING:(编辑中)提交申请发生错误导致,请尝试重新提交。 + * APPLYMENT_STATE_AUDITING:(审核中)申请单正在审核中,超级管理员用微信打开“签约链接”,完成绑定微信号后,申请单进度将通过微信公众号通知超级管理员,引导完成后续步骤。 + * APPLYMENT_STATE_REJECTED:(已驳回)请按照驳回原因修改申请资料,超级管理员用微信打开“签约链接”,完成绑定微信号,后续申请单进度将通过微信公众号通知超级管理员。 + * APPLYMENT_STATE_TO_BE_CONFIRMED:(待账户验证)请超级管理员使用微信打开返回的“签约链接”,根据页面指引完成账户验证。 + * APPLYMENT_STATE_TO_BE_SIGNED:(待签约)请超级管理员使用微信打开返回的“签约链接”,根据页面指引完成签约。 + * APPLYMENT_STATE_SIGNING:(开通权限中)系统开通相关权限中,请耐心等待。 + * APPLYMENT_STATE_FINISHED:(已完成)商户入驻申请已完成。 + * APPLYMENT_STATE_CANCELED:(已作废)申请单已被撤销。 + */ + @JSONField(name = "applyment_state") + public String applyState; + + /** + * 申请状态描述 + */ + @JSONField(name = "applyment_state_msg") + public String applyStateMsg; + + /** + * 驳回原因详情 + */ + @JSONField(name = "audit_detail") + public List auditDetail; +} From e5be2779412caa3dd81b68025687464a6932bf21 Mon Sep 17 00:00:00 2001 From: wangw <1594593906@qq.com> Date: Thu, 8 Jan 2026 10:49:30 +0800 Subject: [PATCH 19/19] =?UTF-8?q?=E8=BF=9B=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/EntryManagerController.java | 75 ++++++++++ .../com/czg/mq/EntryManagerMqListener.java | 124 ++++++++++++++++ .../main/java/com/czg/mq/PrintMqListener.java | 47 ++----- .../java/com/czg/task/EntryManagerTask.java | 87 ++++++++++++ .../src/main/java/com/czg/task/OTimeTask.java | 1 + .../controller/admin/SysCommonController.java | 61 ++++++++ .../java/com/czg/config/RabbitConfig.java | 35 ++++- .../java/com/czg/config/RabbitConstants.java | 3 +- .../java/com/czg/config/RabbitPublisher.java | 7 + .../main/java/com/czg/config/RedisCst.java | 2 + .../java/com/czg/account/entity/ShopInfo.java | 8 ++ .../czg/account/service/ShopInfoService.java | 5 + .../czg/order/entity/ShopDirectMerchant.java | 111 +++++++++++++++ .../com/czg/system/entity/SysBankInfo.java | 82 +++++++++++ .../czg/system/entity/SysCategoryInfo.java | 77 ++++++++++ .../java/com/czg/system/entity/SysRegion.java | 70 +++++++++ .../system/service/SysBankInfoService.java | 19 +++ .../service/SysCategoryInfoService.java | 20 +++ .../czg/system/service/SysRegionService.java | 17 +++ .../com/czg/system/vo/SysCategoryInfoVO.java | 40 ++++++ .../src/main/java/com/czg/PayCst.java | 11 +- .../com/czg/dto/req/AggregateMerchantDto.java | 5 + .../com/czg/dto/req/MerchantBaseInfoDto.java | 2 +- .../service/impl/ShopInfoServiceImpl.java | 9 ++ .../order/dto/AggregateMerchantVO.java | 52 +++++++ .../mapper/ShopDirectMerchantMapper.java | 14 ++ .../service/ShopDirectMerchantService.java | 19 +++ .../impl/ShopDirectMerchantServiceImpl.java | 133 ++++++++++++++++++ .../mapper/ShopDirectMerchantMapper.xml | 7 + cash-service/pay-service/pom.xml | 5 + .../system/mapper/SysBankInfoMapper.java | 14 ++ .../system/mapper/SysCategoryInfoMapper.java | 14 ++ .../system/mapper/SysRegionMapper.java | 14 ++ .../service/impl/SysBankInfoServiceImpl.java | 26 ++++ .../impl/SysCategoryInfoServiceImpl.java | 43 ++++++ .../service/impl/SysRegionServiceImpl.java | 56 ++++++++ .../resources/mapper/SysBankInfoMapper.xml | 7 + .../mapper/SysCategoryInfoMapper.xml | 7 + .../main/resources/mapper/SysRegionMapper.xml | 7 + 39 files changed, 1290 insertions(+), 46 deletions(-) create mode 100644 cash-api/order-server/src/main/java/com/czg/controller/admin/EntryManagerController.java create mode 100644 cash-api/order-server/src/main/java/com/czg/mq/EntryManagerMqListener.java create mode 100644 cash-api/order-server/src/main/java/com/czg/task/EntryManagerTask.java create mode 100644 cash-api/system-server/src/main/java/com/czg/controller/admin/SysCommonController.java create mode 100644 cash-common/cash-common-service/src/main/java/com/czg/order/entity/ShopDirectMerchant.java create mode 100644 cash-common/cash-common-service/src/main/java/com/czg/system/entity/SysBankInfo.java create mode 100644 cash-common/cash-common-service/src/main/java/com/czg/system/entity/SysCategoryInfo.java create mode 100644 cash-common/cash-common-service/src/main/java/com/czg/system/entity/SysRegion.java create mode 100644 cash-common/cash-common-service/src/main/java/com/czg/system/service/SysBankInfoService.java create mode 100644 cash-common/cash-common-service/src/main/java/com/czg/system/service/SysCategoryInfoService.java create mode 100644 cash-common/cash-common-service/src/main/java/com/czg/system/service/SysRegionService.java create mode 100644 cash-common/cash-common-service/src/main/java/com/czg/system/vo/SysCategoryInfoVO.java create mode 100644 cash-service/order-service/src/main/java/com/czg/service/order/dto/AggregateMerchantVO.java create mode 100644 cash-service/order-service/src/main/java/com/czg/service/order/mapper/ShopDirectMerchantMapper.java create mode 100644 cash-service/order-service/src/main/java/com/czg/service/order/service/ShopDirectMerchantService.java create mode 100644 cash-service/order-service/src/main/java/com/czg/service/order/service/impl/ShopDirectMerchantServiceImpl.java create mode 100644 cash-service/order-service/src/main/resources/mapper/ShopDirectMerchantMapper.xml create mode 100644 cash-service/system-service/src/main/java/com/czg/service/system/mapper/SysBankInfoMapper.java create mode 100644 cash-service/system-service/src/main/java/com/czg/service/system/mapper/SysCategoryInfoMapper.java create mode 100644 cash-service/system-service/src/main/java/com/czg/service/system/mapper/SysRegionMapper.java create mode 100644 cash-service/system-service/src/main/java/com/czg/service/system/service/impl/SysBankInfoServiceImpl.java create mode 100644 cash-service/system-service/src/main/java/com/czg/service/system/service/impl/SysCategoryInfoServiceImpl.java create mode 100644 cash-service/system-service/src/main/java/com/czg/service/system/service/impl/SysRegionServiceImpl.java create mode 100644 cash-service/system-service/src/main/resources/mapper/SysBankInfoMapper.xml create mode 100644 cash-service/system-service/src/main/resources/mapper/SysCategoryInfoMapper.xml create mode 100644 cash-service/system-service/src/main/resources/mapper/SysRegionMapper.xml diff --git a/cash-api/order-server/src/main/java/com/czg/controller/admin/EntryManagerController.java b/cash-api/order-server/src/main/java/com/czg/controller/admin/EntryManagerController.java new file mode 100644 index 000000000..bd70c794c --- /dev/null +++ b/cash-api/order-server/src/main/java/com/czg/controller/admin/EntryManagerController.java @@ -0,0 +1,75 @@ +package com.czg.controller.admin; + +import com.czg.EntryManager; +import com.czg.annotation.Debounce; +import com.czg.dto.req.AggregateMerchantDto; +import com.czg.dto.resp.BankBranchDto; +import com.czg.service.order.dto.AggregateMerchantVO; +import com.czg.service.order.service.ShopDirectMerchantService; +import com.czg.resp.CzgResult; +import com.czg.sa.StpKit; +import com.czg.task.EntryManagerTask; +import jakarta.annotation.Resource; +import lombok.AllArgsConstructor; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * 进件管理 + * + * @author ww + */ +@AllArgsConstructor +@RestController +@RequestMapping("/admin/data/entryManager") +public class EntryManagerController { + + @Resource + private ShopDirectMerchantService shopDirectMerchantService; + @Resource + private EntryManagerTask entryManagerTask; + + /** + * 查询银行支行列表 + * + * @param province 省份 陕西省 从 /system/admin/common/region获取 + * @param city 城市 西安市 从 /system/admin/common/region获取 + * @param instId 顶级机构ID CMB 从 /system/admin/common/bankInfo 获取 + */ + @GetMapping("bankBranchList") + public CzgResult> queryBankBranchList(String province, String city, String instId) { + return CzgResult.success(EntryManager.queryBankBranchList(province, city, instId)); + } + + + /** + * 获取进件信息 + */ + @GetMapping + public CzgResult getEntry(Long shopId) { + return CzgResult.success(shopDirectMerchantService.getEntry(shopId)); + } + + /** + * 主动查询进件信息状态 + * 进件状态是INIT 待处理 AUDIT 审核中 SIGN 待签约 + * 3分钟内只能查一次 + */ + @GetMapping + @Debounce(value = "#shopId", interval = 1000 * 60 * 3) + public CzgResult queryEntry(Long shopId) { + entryManagerTask.entryManager(shopId); + return CzgResult.success(); + } + + /** + * 申请进件 + */ + @Debounce(value = "#reqDto.shopId") + @PostMapping + public CzgResult entryManager(@RequestBody AggregateMerchantDto reqDto) { + return CzgResult.success(shopDirectMerchantService.entryManager(reqDto)); + } + +} diff --git a/cash-api/order-server/src/main/java/com/czg/mq/EntryManagerMqListener.java b/cash-api/order-server/src/main/java/com/czg/mq/EntryManagerMqListener.java new file mode 100644 index 000000000..540c3ecdd --- /dev/null +++ b/cash-api/order-server/src/main/java/com/czg/mq/EntryManagerMqListener.java @@ -0,0 +1,124 @@ +package com.czg.mq; + +import cn.hutool.core.util.StrUtil; +import com.czg.EntryManager; +import com.czg.PayCst; +import com.czg.config.RabbitConstants; +import com.czg.config.RedisCst; +import com.czg.dto.resp.EntryRespDto; +import com.czg.order.entity.ShopDirectMerchant; +import com.czg.service.RedisService; +import com.czg.service.order.dto.AggregateMerchantVO; +import com.czg.service.order.service.ShopDirectMerchantService; +import com.rabbitmq.client.Channel; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.apache.logging.log4j.ThreadContext; +import org.springframework.amqp.core.Message; +import org.springframework.amqp.rabbit.annotation.*; +import org.springframework.stereotype.Component; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +/** + * 打印mq消息处理器 + * + * @author Administrator + */ +@Component +@Slf4j +public class EntryManagerMqListener { + @Resource + private RedisService redisService; + @Resource + private ShopDirectMerchantService shopDirectMerchantService; + + String key = RedisCst.SHOP_ENTRY; + + @RabbitListener( + bindings = @QueueBinding( + value = @Queue(value = "${spring.profiles.active}-" + RabbitConstants.Queue.SHOP_ENTRY_MANAGER, + durable = "true", exclusive = "false", autoDelete = "false"), + exchange = @Exchange(value = "${spring.profiles.active}-" + RabbitConstants.Exchange.CASH_EXCHANGE), + key = "${spring.profiles.active}-" + RabbitConstants.Queue.SHOP_ENTRY_MANAGER + ), + concurrency = "5" + ) + @RabbitHandler + public void handle(Message message, Channel channel, String msg) throws IOException { + String messageId = message.getMessageProperties().getMessageId(); + if (hasMessageId(messageId)) { + return; + } + try { + Long shopId = Long.valueOf(msg); + // 将唯一标识添加到日志上下文 + ThreadContext.put("traceId", messageId); + // 安全转换shopId + if (shopId == null) { + channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, false); + return; + } + AggregateMerchantVO entry = shopDirectMerchantService.getEntry(Long.valueOf(msg)); + if (entry != null) { + EntryManager.uploadParamImage(entry); + List platform = new ArrayList<>(); + if (PayCst.EntryStatus.WAIT.equals(entry.getAlipayStatus())) { + platform.add(PayCst.Platform.ALIPAY); + } + if (PayCst.EntryStatus.WAIT.equals(entry.getWechatStatus())) { + platform.add(PayCst.Platform.WECHAT); + } + EntryRespDto resp = EntryManager.entryMerchant(entry, platform.toArray(new String[0])); + ShopDirectMerchant merchant = new ShopDirectMerchant(); + merchant.setShopId(entry.getShopId()); + + merchant.setWechatStatus(resp.getWechatStatus()); + merchant.setWechatErrorMsg(resp.getWechatErrorMsg()); + + merchant.setAlipayStatus(resp.getAlipayStatus()); + merchant.setAlipayErrorMsg(resp.getAlipayErrorMsg()); + shopDirectMerchantService.updateById(merchant); + } + channel.basicAck(message.getMessageProperties().getDeliveryTag(), false); + } catch (Exception e) { + log.error("进件MQ对接业务异常shopId:{}", msg, e); + ShopDirectMerchant merchant = new ShopDirectMerchant(); + merchant.setShopId(Long.valueOf(msg)); + merchant.setWechatStatus(PayCst.EntryStatus.REJECTED); + merchant.setAlipayStatus(PayCst.EntryStatus.REJECTED); + merchant.setErrorMsg("系统错误,请联系管理员后重试。"); + shopDirectMerchantService.updateById(merchant); + + channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, false); + } finally { + delMessageId(messageId); + // 清除日志上下文信息 + ThreadContext.remove("messageId"); + } + } + + public boolean hasMessageId(String messageId) { + if (!redisService.hasKey(key)) { + if (StrUtil.isNotBlank(messageId)) { + redisService.leftPush(key, messageId); + return false; + } else { + return true; + } + } + List list = redisService.lGet(key, 0, -1); + if (!list.contains(messageId)) { + redisService.leftPush(key, messageId); + return false; + } + return true; + } + + public void delMessageId(String messageId) { + redisService.lRemove(key, 0, messageId); + } + +} diff --git a/cash-api/order-server/src/main/java/com/czg/mq/PrintMqListener.java b/cash-api/order-server/src/main/java/com/czg/mq/PrintMqListener.java index 0657298ac..c098099e7 100644 --- a/cash-api/order-server/src/main/java/com/czg/mq/PrintMqListener.java +++ b/cash-api/order-server/src/main/java/com/czg/mq/PrintMqListener.java @@ -29,18 +29,14 @@ public class PrintMqListener { private MqLogService mqLogService; @Resource private FunUtil funUtil; - - // 注入自定义线程池(建议单独配置,避免使用默认线程池) - @Resource - private ThreadPoolTaskExecutor asyncExecutor; @Lazy @Resource private PrinterHandler printerHandler; - private void invokeFun(String type, String plat, T data, Consumer consumer) { + private void invokeFun(String queue, String type, String plat, T data, Consumer consumer) { long startTime = DateUtil.date().getTime(); log.info("接收到{}打印消息:{}", type, data); - MqLog mqLog = new MqLog().setQueue(RabbitConstants.Queue.ORDER_MACHINE_PRINT_QUEUE).setMsg(data.toString()) + MqLog mqLog = new MqLog().setQueue(queue).setMsg(data.toString()) .setType(type).setPlat(plat).setCreateTime(DateUtil.date().toLocalDateTime()); try { consumer.accept(data); @@ -56,7 +52,7 @@ public class PrintMqListener { @RabbitListener(queues = {"${spring.profiles.active}-" + RabbitConstants.Queue.ORDER_MACHINE_PRINT_QUEUE}) public void orderPrint(String req) { // 执行核心打印逻辑 - invokeFun("orderPrint", "java.order", req, (data) -> { + invokeFun(RabbitConstants.Queue.ORDER_MACHINE_PRINT_QUEUE, "orderPrint", "java.order", req, (data) -> { JSONObject jsonObject = JSONObject.parseObject(data); String orderId = jsonObject.getString("orderId"); if (orderId == null) { @@ -68,33 +64,6 @@ public class PrintMqListener { return null; }, RedisCst.getLockKey("orderPrint", orderId)); }); -// // 使用异步线程池执行延迟任务,不阻塞当前消费者线程 -// CompletableFuture.runAsync(() -> { -// try { -// // 延迟3秒处理 -// TimeUnit.SECONDS.sleep(3); -// // 执行核心打印逻辑 -// invokeFun("orderPrint", "java.order", req, (data) -> { -// JSONObject jsonObject = JSONObject.parseObject(data); -// String orderId = jsonObject.getString("orderId"); -// if (orderId == null) { -// throw new RuntimeException("订单打印失败,未传递orderId"); -// } -// Boolean printOrder = jsonObject.getBoolean("printOrder"); -// funUtil.runFunAndCheckKey(() -> { -// printerHandler.handler(orderId, printOrder != null && !printOrder ? PrinterHandler.PrintTypeEnum.ONE : PrinterHandler.PrintTypeEnum.ONE_AND_ORDER); -// return null; -// }, RedisCst.getLockKey("orderPrint", orderId)); -// }); -// } catch (InterruptedException e) { -// Thread.currentThread().interrupt(); -// // 记录中断日志 -// log.warn("打印任务被中断,req:{}", req, e); -// } catch (Exception e) { -// // 记录业务异常日志 -// log.error("打印任务处理失败,req:{}", req, e); -// } -// }, asyncExecutor); } /** @@ -102,14 +71,16 @@ public class PrintMqListener { */ @RabbitListener(queues = {"${spring.profiles.active}-" + RabbitConstants.Queue.ORDER_HANDOVER_PRINT_QUEUE}) public void handoverPrint(String id) { - invokeFun("handoverPrint", "java.order", id, (data) -> printerHandler.handler(data, PrinterHandler.PrintTypeEnum.HANDOVER)); + invokeFun(RabbitConstants.Queue.ORDER_HANDOVER_PRINT_QUEUE, "handoverPrint", "java.order", id, (data) -> + printerHandler.handler(data, PrinterHandler.PrintTypeEnum.HANDOVER)); } /** - * 交班打印 + * 叫号打印 */ - @RabbitListener(queues = {"${spring.profiles.active}-" + RabbitConstants.Queue.CALL_TABLE_PRINT_QUEUE}) + @RabbitListener(queues = {"${spring.profiles.active}-" + RabbitConstants.Queue.CALL_TABLE_QUEUE}) public void callTablePrint(String id) { - invokeFun("handoverPrint", "java.order", id, (data) -> printerHandler.handler(data, PrinterHandler.PrintTypeEnum.CALL)); + invokeFun(RabbitConstants.Queue.CALL_TABLE_QUEUE, "callTable", "java.order", id, (data) -> + printerHandler.handler(data, PrinterHandler.PrintTypeEnum.CALL)); } } diff --git a/cash-api/order-server/src/main/java/com/czg/task/EntryManagerTask.java b/cash-api/order-server/src/main/java/com/czg/task/EntryManagerTask.java new file mode 100644 index 000000000..e8662c092 --- /dev/null +++ b/cash-api/order-server/src/main/java/com/czg/task/EntryManagerTask.java @@ -0,0 +1,87 @@ +package com.czg.task; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.StrUtil; +import com.czg.EntryManager; +import com.czg.PayCst; +import com.czg.account.entity.ShopInfo; +import com.czg.account.service.ShopInfoService; +import com.czg.dto.resp.QueryStatusResp; +import com.czg.order.entity.ShopDirectMerchant; +import com.czg.order.service.ShopOrderStatisticService; +import com.czg.order.service.ShopProdStatisticService; +import com.czg.order.service.ShopTableOrderStatisticService; +import com.czg.service.RedisService; +import com.czg.service.order.service.ShopDirectMerchantService; +import com.mybatisflex.core.query.QueryWrapper; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.apache.dubbo.config.annotation.DubboReference; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.List; + +/** + * 进件查询 + * + * @author ww + */ +@Component +@Slf4j +public class EntryManagerTask { + @Resource + private ShopDirectMerchantService shopDirectMerchantService; + @DubboReference + private ShopInfoService shopInfoService; + + //每10分钟查一次 + @Scheduled(cron = "0 0/10 * * * ? ") + public void run() { + log.info("进件查询,定时任务执行"); + long start = System.currentTimeMillis(); + entryManager(null); + log.info("进件查询,定时任务执行完毕,耗时:{}ms", start - System.currentTimeMillis()); + } + + /** + * 查询状态为待处理、待签约、待审核的进件 + */ + public void entryManager(Long shopId) { + List list = shopDirectMerchantService.list(QueryWrapper.create() + .eq(ShopDirectMerchant::getShopId, shopId) + .in(ShopDirectMerchant::getWechatStatus, PayCst.EntryStatus.NEED_QUERY_LIST) + .or(ShopDirectMerchant::getAlipayStatus).in(PayCst.EntryStatus.NEED_QUERY_LIST)); + if (CollUtil.isEmpty(list)) { + return; + } + for (ShopDirectMerchant shopDirectMerchant : list) { + String wechatMerchantId = ""; + String alipayMerchantId = ""; + if (PayCst.EntryStatus.NEED_QUERY_LIST.contains(shopDirectMerchant.getWechatStatus())) { + QueryStatusResp wechatStatus = EntryManager.queryWechatEntryStatus(shopDirectMerchant.getMerchantCode()); + shopDirectMerchant.setWechatStatus(wechatStatus.getStatus()); + shopDirectMerchant.setWechatErrorMsg(wechatStatus.getFailReason()); + shopDirectMerchant.setWechatSignUrl(wechatStatus.getSignUrl()); + if (PayCst.EntryStatus.FINISH.equals(wechatStatus.getStatus())) { + wechatMerchantId = wechatStatus.getThirdMerchantId(); + } + } + if (PayCst.EntryStatus.NEED_QUERY_LIST.contains(shopDirectMerchant.getAlipayStatus())) { + QueryStatusResp alipayStatus = EntryManager.queryAlipayEntryStatus(shopDirectMerchant.getMerchantCode()); + shopDirectMerchant.setAlipayStatus(alipayStatus.getStatus()); + shopDirectMerchant.setAlipayErrorMsg(alipayStatus.getFailReason()); + shopDirectMerchant.setAlipaySignUrl(alipayStatus.getSignUrl()); + if (PayCst.EntryStatus.FINISH.equals(alipayStatus.getStatus())) { + alipayMerchantId = alipayStatus.getThirdMerchantId(); + } + } + shopDirectMerchantService.updateById(shopDirectMerchant); + if (StrUtil.isNotBlank(wechatMerchantId) || StrUtil.isNotBlank(alipayMerchantId)) { + shopInfoService.editEntry(shopDirectMerchant.getShopId(), wechatMerchantId, alipayMerchantId); + } + } + } +} \ No newline at end of file diff --git a/cash-api/order-server/src/main/java/com/czg/task/OTimeTask.java b/cash-api/order-server/src/main/java/com/czg/task/OTimeTask.java index b94bc7c66..7a6f4fdfa 100644 --- a/cash-api/order-server/src/main/java/com/czg/task/OTimeTask.java +++ b/cash-api/order-server/src/main/java/com/czg/task/OTimeTask.java @@ -28,6 +28,7 @@ import java.util.List; /** * 订单过期处理 + * 退款失败 补偿 * * @author ww */ diff --git a/cash-api/system-server/src/main/java/com/czg/controller/admin/SysCommonController.java b/cash-api/system-server/src/main/java/com/czg/controller/admin/SysCommonController.java new file mode 100644 index 000000000..2585c6995 --- /dev/null +++ b/cash-api/system-server/src/main/java/com/czg/controller/admin/SysCommonController.java @@ -0,0 +1,61 @@ +package com.czg.controller.admin; + +import com.czg.BaseQueryParam; +import com.czg.resp.CzgResult; +import com.czg.system.entity.SysBankInfo; +import com.czg.system.entity.SysCategoryInfo; +import com.czg.system.entity.SysRegion; +import com.czg.system.service.SysBankInfoService; +import com.czg.system.service.SysCategoryInfoService; +import com.czg.system.service.SysRegionService; +import com.czg.system.vo.SysCategoryInfoVO; +import com.mybatisflex.core.paginate.Page; +import jakarta.annotation.Resource; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; +import java.util.Map; + +/** + * 通用 + * + * @author Administrator + */ +@RestController +@RequestMapping("/admin/common") +public class SysCommonController { + @Resource + private SysRegionService sysRegionService; + @Resource + private SysBankInfoService bankInfoService; + @Resource + private SysCategoryInfoService categoryInfoService; + + /** + * 获取所有地域 + */ + @GetMapping("/region") + public CzgResult> region() { + return CzgResult.success(sysRegionService.regionList()); + } + + /** + * 获取银行信息 + */ + @GetMapping("/bankInfo") + public CzgResult> bankInfo(BaseQueryParam param, @RequestParam String bankName) { + return CzgResult.success(bankInfoService.bankInfoList(param, bankName)); + } + + + /** + * 类目信息表 + */ + @GetMapping("/category") + public CzgResult> category() { + return CzgResult.success(categoryInfoService.categoryList()); + } +} diff --git a/cash-common/cash-common-mq/src/main/java/com/czg/config/RabbitConfig.java b/cash-common/cash-common-mq/src/main/java/com/czg/config/RabbitConfig.java index 5ba087dca..ab5b007cc 100644 --- a/cash-common/cash-common-mq/src/main/java/com/czg/config/RabbitConfig.java +++ b/cash-common/cash-common-mq/src/main/java/com/czg/config/RabbitConfig.java @@ -21,12 +21,24 @@ public class RabbitConfig { @Value("${spring.profiles.active}") private String activeProfile; + @Bean @Primary public DirectExchange directExchange() { return new DirectExchange(activeProfile + "-" + RabbitConstants.Exchange.CASH_EXCHANGE); } + //------------------------------------------------------ 商家入驻 + @Bean + public Queue entryManagerQueue() { + return new Queue(activeProfile + "-" + RabbitConstants.Queue.SHOP_ENTRY_MANAGER, true, false, false); + } + + @Bean + public Binding entryManagerExchange(Queue entryManagerQueue, DirectExchange exchange) { + return BindingBuilder.bind(entryManagerQueue).to(exchange).with(activeProfile + "-" + RabbitConstants.Queue.SHOP_ENTRY_MANAGER); + } + //------------------------------------------------------订单打印队列 @Bean public Queue orderPrintQueue() { @@ -36,6 +48,7 @@ public class RabbitConfig { args.put("x-message-ttl", 180000); return new Queue(activeProfile + "-" + RabbitConstants.Queue.ORDER_PRINT_QUEUE, true, false, false, args); } + @Bean public Binding bindingOrderPrintExchange(Queue orderPrintQueue, DirectExchange exchange) { return BindingBuilder.bind(orderPrintQueue).to(exchange).with(activeProfile + "-" + RabbitConstants.Queue.ORDER_PRINT_QUEUE); @@ -51,6 +64,7 @@ public class RabbitConfig { // args.put("x-message-ttl", 180000); return new Queue(activeProfile + "-" + RabbitConstants.Queue.ORDER_MACHINE_PRINT_QUEUE, true, false, false); } + @Bean public Binding bindingOrderMachinePrintExchange(Queue orderMachinePrintQueue, DirectExchange exchange) { return BindingBuilder.bind(orderMachinePrintQueue).to(exchange).with(activeProfile + "-" + RabbitConstants.Queue.ORDER_MACHINE_PRINT_QUEUE); @@ -61,6 +75,7 @@ public class RabbitConfig { public Queue handoverPrintQueue() { return new Queue(activeProfile + "-" + RabbitConstants.Queue.ORDER_HANDOVER_PRINT_QUEUE, true, false, false); } + @Bean public Binding bindingHandoverPrintExchange(Queue handoverPrintQueue, DirectExchange exchange) { return BindingBuilder.bind(handoverPrintQueue).to(exchange).with(activeProfile + "-" + RabbitConstants.Queue.ORDER_HANDOVER_PRINT_QUEUE); @@ -69,11 +84,12 @@ public class RabbitConfig { //------------------------------------------------------叫号 打票 @Bean public Queue callTablePrintQueue() { - return new Queue(activeProfile + "-" + RabbitConstants.Queue.CALL_TABLE_PRINT_QUEUE, true, false, false); + return new Queue(activeProfile + "-" + RabbitConstants.Queue.CALL_TABLE_QUEUE, true, false, false); } + @Bean public Binding bindingCallTablePrintExchange(Queue callTablePrintQueue, DirectExchange exchange) { - return BindingBuilder.bind(callTablePrintQueue).to(exchange).with(activeProfile + "-" + RabbitConstants.Queue.CALL_TABLE_PRINT_QUEUE); + return BindingBuilder.bind(callTablePrintQueue).to(exchange).with(activeProfile + "-" + RabbitConstants.Queue.CALL_TABLE_QUEUE); } //------------------------------------------------------订单取消 @@ -81,9 +97,10 @@ public class RabbitConfig { public Queue orderCancelQueue() { return new Queue(activeProfile + "-" + RabbitConstants.Queue.ORDER_CANCEL_QUEUE, true); } + @Bean - public Binding bindingOrderCancelExchange(Queue orderPrintQueue, DirectExchange exchange) { - return BindingBuilder.bind(orderPrintQueue).to(exchange).with(activeProfile + "-" + RabbitConstants.Queue.ORDER_CANCEL_QUEUE); + public Binding bindingOrderCancelExchange(Queue orderCancelQueue, DirectExchange exchange) { + return BindingBuilder.bind(orderCancelQueue).to(exchange).with(activeProfile + "-" + RabbitConstants.Queue.ORDER_CANCEL_QUEUE); } //------------------------------------------------------ 订单库存更新 @@ -91,6 +108,7 @@ public class RabbitConfig { public Queue orderStockQueue() { return new Queue(activeProfile + "-" + RabbitConstants.Queue.ORDER_STOCK_QUEUE, true); } + @Bean public Binding bindingOrderStockExchange(Queue orderStockQueue, DirectExchange exchange) { return BindingBuilder.bind(orderStockQueue).to(exchange).with(activeProfile + "-" + RabbitConstants.Queue.ORDER_STOCK_QUEUE); @@ -102,6 +120,7 @@ public class RabbitConfig { public Queue productInfoChangeQueue() { return new Queue(activeProfile + "-" + RabbitConstants.Queue.PRODUCT_INFO_CHANGE_QUEUE, true); } + @Bean public Binding bindingProductInfoChange(Queue productInfoChangeQueue, DirectExchange exchange) { return BindingBuilder.bind(productInfoChangeQueue).to(exchange).with(activeProfile + "-" + RabbitConstants.Queue.PRODUCT_INFO_CHANGE_QUEUE); @@ -112,6 +131,7 @@ public class RabbitConfig { public Queue orderRefundQueue() { return new Queue(activeProfile + "-" + RabbitConstants.Queue.ORDER_REFUND_QUEUE, true); } + @Bean public Binding bindingOrderRefundExchange(Queue orderRefundQueue, DirectExchange exchange) { return BindingBuilder.bind(orderRefundQueue).to(exchange).with(activeProfile + "-" + RabbitConstants.Queue.ORDER_REFUND_QUEUE); @@ -119,6 +139,7 @@ public class RabbitConfig { //------------------------------------------------------ 申请短信模板队列 + /** * 1,2,applySmsTemp 模版审核 * 1,2,sendMarkSms 发送营销短信 @@ -129,16 +150,18 @@ public class RabbitConfig { public Queue applySmsTemplateQueue() { return new Queue(activeProfile + "-" + RabbitConstants.Queue.APPLY_SMS_TEMPLATE_QUEUE, true); } + @Bean public Binding bindingApplySmsTemplateExchange(Queue applySmsTemplateQueue, DirectExchange exchange) { return BindingBuilder.bind(applySmsTemplateQueue).to(exchange).with(activeProfile + "-" + RabbitConstants.Queue.APPLY_SMS_TEMPLATE_QUEUE); } - //------------------------------------------------------ 生日礼品短信队列 + //------------------------------------------------------ 生日礼品短信队列 @Bean public Queue birthdayGiftSmsQueue() { return new Queue(activeProfile + "-" + RabbitConstants.Queue.BIRTHDAY_GIFT_SMS_QUEUE, true); } + @Bean public Binding bindingBirthdayGiftSmsExchange(Queue birthdayGiftSmsQueue, DirectExchange exchange) { return BindingBuilder.bind(birthdayGiftSmsQueue).to(exchange).with(activeProfile + "-" + RabbitConstants.Queue.BIRTHDAY_GIFT_SMS_QUEUE); @@ -149,6 +172,7 @@ public class RabbitConfig { public Queue orderProductStatusQueue() { return new Queue(activeProfile + "-" + RabbitConstants.Queue.ORDER_PRODUCT_STATUS_QUEUE, true); } + @Bean public Binding bindingOrderProductStatusExchange(Queue orderProductStatusQueue, DirectExchange exchange) { return BindingBuilder.bind(orderProductStatusQueue).to(exchange).with(activeProfile + "-" + RabbitConstants.Queue.ORDER_PRODUCT_STATUS_QUEUE); @@ -160,6 +184,7 @@ public class RabbitConfig { public Queue orderDetailStatusQueue() { return new Queue(activeProfile + "-" + RabbitConstants.Queue.ORDER_DETAIL_STATUS_QUEUE, true); } + @Bean public Binding bindingOrderDetailStatusExchange(Queue orderDetailStatusQueue, DirectExchange exchange) { return BindingBuilder.bind(orderDetailStatusQueue).to(exchange).with(activeProfile + "-" + RabbitConstants.Queue.ORDER_DETAIL_STATUS_QUEUE); diff --git a/cash-common/cash-common-mq/src/main/java/com/czg/config/RabbitConstants.java b/cash-common/cash-common-mq/src/main/java/com/czg/config/RabbitConstants.java index c43827b41..d4a0a9b69 100644 --- a/cash-common/cash-common-mq/src/main/java/com/czg/config/RabbitConstants.java +++ b/cash-common/cash-common-mq/src/main/java/com/czg/config/RabbitConstants.java @@ -10,13 +10,14 @@ public interface RabbitConstants { } class Queue { + public static final String SHOP_ENTRY_MANAGER = "shop.entry.manager"; public static final String ORDER_STOCK_QUEUE = "order.stock.queue"; public static final String ORDER_REFUND_QUEUE = "order.refund.queue"; public static final String ORDER_CANCEL_QUEUE = "order.cancel.queue"; public static final String ORDER_PRINT_QUEUE = "order.print.queue"; public static final String ORDER_MACHINE_PRINT_QUEUE = "order.machine.print.queue"; public static final String ORDER_HANDOVER_PRINT_QUEUE = "order.handover.print.queue"; - public static final String CALL_TABLE_PRINT_QUEUE = "call.table.print.queue"; + public static final String CALL_TABLE_QUEUE = "call.table.print.queue"; public static final String PRODUCT_INFO_CHANGE_QUEUE = "product.info.change.queue"; /** diff --git a/cash-common/cash-common-mq/src/main/java/com/czg/config/RabbitPublisher.java b/cash-common/cash-common-mq/src/main/java/com/czg/config/RabbitPublisher.java index a5e49a8a5..8903cad34 100644 --- a/cash-common/cash-common-mq/src/main/java/com/czg/config/RabbitPublisher.java +++ b/cash-common/cash-common-mq/src/main/java/com/czg/config/RabbitPublisher.java @@ -130,6 +130,13 @@ public class RabbitPublisher { sendMsg(RabbitConstants.Queue.ORDER_PRODUCT_STATUS_QUEUE, qrContent); } + /** + * 订单商品状态消息 + */ + public void sendEntryManagerMsg(String shopId) { + sendMsg(RabbitConstants.Queue.SHOP_ENTRY_MANAGER, shopId); + } + /** * 订单商品状态消息 diff --git a/cash-common/cash-common-redis/src/main/java/com/czg/config/RedisCst.java b/cash-common/cash-common-redis/src/main/java/com/czg/config/RedisCst.java index cbfd9dd99..e915eb0f0 100644 --- a/cash-common/cash-common-redis/src/main/java/com/czg/config/RedisCst.java +++ b/cash-common/cash-common-redis/src/main/java/com/czg/config/RedisCst.java @@ -33,6 +33,8 @@ public interface RedisCst { public static final String EXPIRED_WECHAT = "expired:wechat:"; } + //商家进件 + String SHOP_ENTRY = "shop:entry"; String SMS_CODE = "sms:code:"; // 店铺会员动态支付码 diff --git a/cash-common/cash-common-service/src/main/java/com/czg/account/entity/ShopInfo.java b/cash-common/cash-common-service/src/main/java/com/czg/account/entity/ShopInfo.java index 359870ae8..2e6667eca 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/account/entity/ShopInfo.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/account/entity/ShopInfo.java @@ -142,6 +142,14 @@ public class ShopInfo implements Serializable { * -1 平台禁用 0-过期,1正式营业, */ private Integer status; + /** + * 微信商户id + */ + private String wechatMerchantId; + /** + * 支付宝商户id + */ + private String alipayMerchantId; /** * 到期时间 diff --git a/cash-common/cash-common-service/src/main/java/com/czg/account/service/ShopInfoService.java b/cash-common/cash-common-service/src/main/java/com/czg/account/service/ShopInfoService.java index f87dfec90..dcb5e7af2 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/account/service/ShopInfoService.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/account/service/ShopInfoService.java @@ -37,6 +37,11 @@ public interface ShopInfoService extends IService { Boolean edit(ShopInfoEditDTO shopInfoEditDTO); + /** + * 进件结果保存 + */ + Boolean editEntry(Long shopId, String wechatMerchantId, String alipayMerchantId); + ShopDetailDTO detail(Long id) throws CzgException; ShopInfoByCodeDTO getByCode(String tableCode, String lat, String lng, boolean checkState); diff --git a/cash-common/cash-common-service/src/main/java/com/czg/order/entity/ShopDirectMerchant.java b/cash-common/cash-common-service/src/main/java/com/czg/order/entity/ShopDirectMerchant.java new file mode 100644 index 000000000..5fbea4472 --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/order/entity/ShopDirectMerchant.java @@ -0,0 +1,111 @@ +package com.czg.order.entity; + +import com.mybatisflex.annotation.Column; +import com.mybatisflex.annotation.Id; +import com.mybatisflex.annotation.Table; + +import java.io.Serializable; +import java.time.LocalDateTime; + +import java.io.Serial; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 商户进件 实体类。 + * + * @author ww + * @since 2026-01-07 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Table("tb_shop_direct_merchant") +public class ShopDirectMerchant implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 店铺id + */ + @Id + private Long shopId; + + /** + * 营业执照编号 + */ + private String licenceNo; + + /** + * 商户编号(在当前系统唯一) + */ + private String merchantCode; + + /** + * 商户基础信息 + */ + private String merchantBaseInfo; + + /** + * 法人信息 + */ + private String legalPersonInfo; + + /** + * 营业执照信息 + */ + private String businessLicenceInfo; + + /** + * 门店信息 + */ + private String storeInfo; + + /** + * 结算信息 + */ + private String settlementInfo; + + @Column(onInsertValue = "now()") + private LocalDateTime createTime; + + @Column(onInsertValue = "now()", onUpdateValue = "now()") + private LocalDateTime updateTime; + + + private String errorMsg; + + /** + * 微信状态 + */ + private String wechatStatus; + + /** + * 微信进件错误信息 + */ + private String wechatErrorMsg; + /** + * 微信进件签名地址 + */ + private String wechatSignUrl; + + /** + * 支付宝状态 + */ + private String alipayStatus; + + /** + * 支付宝进件错误信息 + */ + private String alipayErrorMsg; + /** + * 支付宝进件签名地址 + */ + private String alipaySignUrl; + +} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/system/entity/SysBankInfo.java b/cash-common/cash-common-service/src/main/java/com/czg/system/entity/SysBankInfo.java new file mode 100644 index 000000000..bc298d759 --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/system/entity/SysBankInfo.java @@ -0,0 +1,82 @@ +package com.czg.system.entity; + +import com.mybatisflex.annotation.Column; +import com.mybatisflex.annotation.Id; +import com.mybatisflex.annotation.KeyType; +import com.mybatisflex.annotation.Table; +import java.io.Serializable; +import java.math.BigInteger; +import java.time.LocalDateTime; + +import java.io.Serial; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 银行账户信息表 实体类。 + * + * @author ww + * @since 2026-01-06 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Table("sys_bank_info") +public class SysBankInfo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键ID + */ + @Id(keyType = KeyType.Auto) + private BigInteger id; + + /** + * 银行名称 + */ + private String accountBank; + + /** + * 银行数字编码 + */ + private Integer accountBankCode; + + /** + * 银行别名 + */ + private String bankAlias; + + /** + * 银行别名编码 + */ + private String bankAliasCode; + + /** + * 不知道干啥的 + */ + private Boolean needBankBranch; + + /** + * 银行英文编码 + */ + private String bankCode; + + /** + * 创建时间 + */ + @Column(onInsertValue = "now()") + private LocalDateTime createTime; + + /** + * 更新时间 + */ + @Column(onInsertValue = "now()", onUpdateValue = "now()") + private LocalDateTime updateTime; + +} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/system/entity/SysCategoryInfo.java b/cash-common/cash-common-service/src/main/java/com/czg/system/entity/SysCategoryInfo.java new file mode 100644 index 000000000..1fe2a78c7 --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/system/entity/SysCategoryInfo.java @@ -0,0 +1,77 @@ +package com.czg.system.entity; + +import com.mybatisflex.annotation.Column; +import com.mybatisflex.annotation.Id; +import com.mybatisflex.annotation.KeyType; +import com.mybatisflex.annotation.Table; +import java.io.Serializable; +import java.math.BigInteger; +import java.time.LocalDateTime; + +import java.io.Serial; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 类目信息表 实体类。 + * + * @author ww + * @since 2026-01-06 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Table("sys_category_info") +public class SysCategoryInfo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键ID + */ + @Id(keyType = KeyType.Auto) + private BigInteger id; + + /** + * 一级类目 + */ + private String firstCategory; + + /** + * 二级类目code + */ + private String secondCategoryCode; + + /** + * 二级类目 + */ + private String secondCategory; + + /** + * 适用商家说明 + */ + private String applicableMerchant; + + /** + * 特殊资质(为空则无需提供) + */ + private String specialQualification; + + /** + * 创建时间 + */ + @Column(onInsertValue = "now()") + private LocalDateTime createTime; + + /** + * 更新时间 + */ + @Column(onInsertValue = "now()", onUpdateValue = "now()") + private LocalDateTime updateTime; + +} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/system/entity/SysRegion.java b/cash-common/cash-common-service/src/main/java/com/czg/system/entity/SysRegion.java new file mode 100644 index 000000000..1b50b9e9a --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/system/entity/SysRegion.java @@ -0,0 +1,70 @@ +package com.czg.system.entity; + +import com.mybatisflex.annotation.Column; +import com.mybatisflex.annotation.Id; +import com.mybatisflex.annotation.Table; +import java.io.Serializable; + +import java.io.Serial; +import java.util.List; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 行政区表 实体类。 + * + * @author ww + * @since 2026-01-06 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Table("sys_region") +public class SysRegion implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 区域编码 + */ + @Id + private String regionId; + + /** + * 上级区域编码 + */ + private String parentRegionId; + + /** + * 区域级别:1=国家,2=省,3=市,4=县 + */ + @Id + private Integer regionLevel; + + /** + * 区域中文全称 + */ + private String regionName; + + /** + * 区域拼音 + */ + private String regionPinyin; + + /** + * 全级别名称(如“中国|北京|北京市|东城区) + */ + private String fullName; + + /** + * 子级区域 + */ + @Column(ignore = true) + private List children; + +} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/system/service/SysBankInfoService.java b/cash-common/cash-common-service/src/main/java/com/czg/system/service/SysBankInfoService.java new file mode 100644 index 000000000..d4510f052 --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/system/service/SysBankInfoService.java @@ -0,0 +1,19 @@ +package com.czg.system.service; + +import com.czg.BaseQueryParam; +import com.mybatisflex.core.paginate.Page; +import com.mybatisflex.core.service.IService; +import com.czg.system.entity.SysBankInfo; + +import java.util.List; + +/** + * 银行账户信息表 服务层。 + * + * @author ww + * @since 2026-01-06 + */ +public interface SysBankInfoService extends IService { + + Page bankInfoList(BaseQueryParam param, String bankName); +} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/system/service/SysCategoryInfoService.java b/cash-common/cash-common-service/src/main/java/com/czg/system/service/SysCategoryInfoService.java new file mode 100644 index 000000000..78eaee526 --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/system/service/SysCategoryInfoService.java @@ -0,0 +1,20 @@ +package com.czg.system.service; + +import com.czg.system.vo.SysCategoryInfoVO; +import com.mybatisflex.core.service.IService; +import com.czg.system.entity.SysCategoryInfo; + +import java.util.List; +import java.util.Map; + +/** + * 类目信息表 服务层。 + * + * @author ww + * @since 2026-01-06 + */ +public interface SysCategoryInfoService extends IService { + + + List categoryList(); +} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/system/service/SysRegionService.java b/cash-common/cash-common-service/src/main/java/com/czg/system/service/SysRegionService.java new file mode 100644 index 000000000..d1f2646ec --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/system/service/SysRegionService.java @@ -0,0 +1,17 @@ +package com.czg.system.service; + +import com.mybatisflex.core.service.IService; +import com.czg.system.entity.SysRegion; + +import java.util.List; + +/** + * 行政区表 服务层。 + * + * @author ww + * @since 2026-01-06 + */ +public interface SysRegionService extends IService { + + List regionList(); +} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/system/vo/SysCategoryInfoVO.java b/cash-common/cash-common-service/src/main/java/com/czg/system/vo/SysCategoryInfoVO.java new file mode 100644 index 000000000..a3d535d7a --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/system/vo/SysCategoryInfoVO.java @@ -0,0 +1,40 @@ +package com.czg.system.vo; + +import com.czg.system.entity.SysCategoryInfo; +import com.mybatisflex.annotation.Column; +import com.mybatisflex.annotation.Id; +import com.mybatisflex.annotation.KeyType; +import com.mybatisflex.annotation.Table; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serial; +import java.io.Serializable; +import java.math.BigInteger; +import java.time.LocalDateTime; +import java.util.List; + +/** + * 类目信息表 实体类。 + * + * @author ww + * @since 2026-01-06 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class SysCategoryInfoVO implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 一级类目 + */ + private String firstCategory; + + private List child; +} diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/PayCst.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/PayCst.java index 52de66b27..8bce68aae 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/PayCst.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/PayCst.java @@ -1,7 +1,10 @@ package com.czg; +import java.util.List; + /** * 支付相关常量 + * * @author yjjie * @date 2026/1/7 09:20 */ @@ -34,7 +37,6 @@ public interface PayCst { * 待处理 */ public static final String INIT = "INIT"; - /** * 审核中 */ @@ -54,6 +56,13 @@ public interface PayCst { * 失败 */ public static final String REJECTED = "REJECTED"; + + + /** + * 需要查询的状态列表 + * 待处理、待签约、待审核的进件 + */ + public static final List NEED_QUERY_LIST = List.of(INIT, AUDIT, SIGN); } /** diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/AggregateMerchantDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/AggregateMerchantDto.java index bdc521828..e72937618 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/AggregateMerchantDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/AggregateMerchantDto.java @@ -10,9 +10,14 @@ import lombok.Data; */ @Data public class AggregateMerchantDto { + /** + * 商户Id + */ + private Long shopId; /** * 【必填】 + * 自己生成 CZGyyyy-MM-dd HH:mm:ss.SSS * 商户编号(在当前系统唯一) */ private String merchantCode; diff --git a/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/MerchantBaseInfoDto.java b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/MerchantBaseInfoDto.java index ae8384f60..3bebf4567 100644 --- a/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/MerchantBaseInfoDto.java +++ b/cash-sdk/aggregation-pay/src/main/java/com/czg/dto/req/MerchantBaseInfoDto.java @@ -16,7 +16,7 @@ public class MerchantBaseInfoDto { * 商户类型 * 0: 个体商户; * 1: 企业商户; - * 3: 小微商户 + * 3: 小微商户 暂不支持 */ private String userType; diff --git a/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/ShopInfoServiceImpl.java b/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/ShopInfoServiceImpl.java index f273175cc..388b789e0 100644 --- a/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/ShopInfoServiceImpl.java +++ b/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/ShopInfoServiceImpl.java @@ -324,6 +324,15 @@ public class ShopInfoServiceImpl extends ServiceImpl i return false; } + @Override + @CacheEvict(key = "#shopId") + public Boolean editEntry(Long shopId, String wechatMerchantId, String alipayMerchantId) { + ShopInfo shopInfo = new ShopInfo(); + shopInfo.setWechatMerchantId(wechatMerchantId); + shopInfo.setAlipayMerchantId(alipayMerchantId); + return update(shopInfo, new QueryWrapper().eq(ShopInfo::getId, shopId)); + } + @Override public ShopDetailDTO detail(Long id) throws CzgException { ShopInfo shopInfo = queryChain().eq(ShopInfo::getId, id == null ? StpKit.USER.getShopId() : id).one(); diff --git a/cash-service/order-service/src/main/java/com/czg/service/order/dto/AggregateMerchantVO.java b/cash-service/order-service/src/main/java/com/czg/service/order/dto/AggregateMerchantVO.java new file mode 100644 index 000000000..28498f898 --- /dev/null +++ b/cash-service/order-service/src/main/java/com/czg/service/order/dto/AggregateMerchantVO.java @@ -0,0 +1,52 @@ +package com.czg.service.order.dto; + +import com.czg.dto.req.*; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * @author ww + */ +@Data +public class AggregateMerchantVO extends AggregateMerchantDto{ + + private LocalDateTime createTime; + + private LocalDateTime updateTime; + + private String errorMsg; + + /** + * {@link com.czg.PayCst.EntryStatus} + * 微信状态 + * WAIT 待提交 INIT 待处理 AUDIT 审核中 SIGN 待签约 REJECTED 失败 FINISH 已完成 + */ + private String wechatStatus; + + /** + * 微信进件错误信息 + */ + private String wechatErrorMsg; + /** + * 微信进件签名地址 + */ + private String wechatSignUrl; + + /** + * {@link com.czg.PayCst.EntryStatus} + * 支付宝状态 + * WAIT 待提交 INIT 待处理 AUDIT 审核中 SIGN 待签约 REJECTED 失败 FINISH 已完成 + */ + private String alipayStatus; + + /** + * 支付宝进件错误信息 + */ + private String alipayErrorMsg; + /** + * 支付宝进件签名地址 + */ + private String alipaySignUrl; + +} diff --git a/cash-service/order-service/src/main/java/com/czg/service/order/mapper/ShopDirectMerchantMapper.java b/cash-service/order-service/src/main/java/com/czg/service/order/mapper/ShopDirectMerchantMapper.java new file mode 100644 index 000000000..3b97bdb5a --- /dev/null +++ b/cash-service/order-service/src/main/java/com/czg/service/order/mapper/ShopDirectMerchantMapper.java @@ -0,0 +1,14 @@ +package com.czg.service.order.mapper; + +import com.mybatisflex.core.BaseMapper; +import com.czg.order.entity.ShopDirectMerchant; + +/** + * 商户进件 映射层。 + * + * @author ww + * @since 2026-01-07 + */ +public interface ShopDirectMerchantMapper extends BaseMapper { + +} diff --git a/cash-service/order-service/src/main/java/com/czg/service/order/service/ShopDirectMerchantService.java b/cash-service/order-service/src/main/java/com/czg/service/order/service/ShopDirectMerchantService.java new file mode 100644 index 000000000..6519ae2af --- /dev/null +++ b/cash-service/order-service/src/main/java/com/czg/service/order/service/ShopDirectMerchantService.java @@ -0,0 +1,19 @@ +package com.czg.service.order.service; +import com.czg.dto.req.AggregateMerchantDto; +import com.czg.service.order.dto.AggregateMerchantVO; +import com.mybatisflex.core.service.IService; +import com.czg.order.entity.ShopDirectMerchant; + +/** + * 商户进件 服务层。 + * + * @author ww + * @since 2026-01-07 + */ +public interface ShopDirectMerchantService extends IService { + + + AggregateMerchantVO getEntry(Long shopId); + + boolean entryManager(AggregateMerchantDto reqDto); +} diff --git a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/ShopDirectMerchantServiceImpl.java b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/ShopDirectMerchantServiceImpl.java new file mode 100644 index 000000000..cf146543f --- /dev/null +++ b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/ShopDirectMerchantServiceImpl.java @@ -0,0 +1,133 @@ +package com.czg.service.order.service.impl; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.date.LocalDateTimeUtil; +import cn.hutool.core.io.unit.DataSizeUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson2.JSONObject; +import com.czg.EntryManager; +import com.czg.PayCst; +import com.czg.config.RabbitPublisher; +import com.czg.dto.req.*; +import com.czg.service.order.dto.AggregateMerchantVO; +import com.czg.utils.FunUtils; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.mybatisflex.spring.service.impl.ServiceImpl; +import com.czg.order.entity.ShopDirectMerchant; +import com.czg.service.order.service.ShopDirectMerchantService; +import com.czg.service.order.mapper.ShopDirectMerchantMapper; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Service; + +import java.util.Date; +import java.util.concurrent.atomic.AtomicLong; + +/** + * 商户进件 服务层实现。 + * + * @author ww + * @since 2026-01-07 + */ +@Service +public class ShopDirectMerchantServiceImpl extends ServiceImpl implements ShopDirectMerchantService { + + @Resource + private RabbitPublisher rabbitPublisher; + // 全局原子计数器,按天重置(避免数值过大) + private static final AtomicLong COUNTER = new AtomicLong(0); + // 记录上一次的日期,用于重置计数器 + private static String LAST_DATE = DateUtil.format(new Date(), "yyyyMMdd"); + + @Override + public AggregateMerchantVO getEntry(Long shopId) { + ShopDirectMerchant merchant = getById(shopId); + if (merchant == null) { + return null; + } + return convertVO(merchant); + } + + @Override + public boolean entryManager(AggregateMerchantDto reqDto) { + boolean isSave = false; + boolean result; + if (StrUtil.isBlank(reqDto.getMerchantCode())) { + reqDto.setMerchantCode(getMerchantCode()); + isSave = true; + } + EntryManager.verifyEntryParam(reqDto); + + + ShopDirectMerchant merchant = new ShopDirectMerchant(); + merchant.setShopId(reqDto.getShopId()); + merchant.setMerchantCode(reqDto.getMerchantCode()); + merchant.setLicenceNo(reqDto.getBusinessLicenceInfo().getLicenceNo()); + + merchant.setMerchantBaseInfo(JSONObject.toJSONString(reqDto.getMerchantBaseInfo())); + merchant.setLegalPersonInfo(JSONObject.toJSONString(reqDto.getLegalPersonInfo())); + merchant.setBusinessLicenceInfo(JSONObject.toJSONString(reqDto.getBusinessLicenceInfo())); + merchant.setStoreInfo(JSONObject.toJSONString(reqDto.getStoreInfo())); + merchant.setSettlementInfo(JSONObject.toJSONString(reqDto.getSettlementInfo())); + merchant.setWechatStatus(PayCst.EntryStatus.WAIT); + merchant.setAlipayStatus(PayCst.EntryStatus.WAIT); + if (isSave) { + result = save(merchant); + } else { + result = updateById(merchant); + } + //发送进件队列消息 + FunUtils.transactionSafeRun(() -> rabbitPublisher.sendEntryManagerMsg(reqDto.getShopId().toString())); + return result; + } + + private static String getMerchantCode() { + Date now = new Date(); + // 1. 获取当前日期(yyyyMMdd) + String currentDate = DateUtil.format(now, "yyyyMMdd"); + // 2. 每天重置计数器,避免数值溢出 + synchronized (COUNTER) { + if (!currentDate.equals(LAST_DATE)) { + COUNTER.set(0); + LAST_DATE = currentDate; + } + } + // 3. 原子递增,获取唯一序号(同一毫秒内不会重复) + long seq = COUNTER.incrementAndGet(); + // 4. 时间戳(毫秒级)+ 6位序号(补零) + String timeStr = DateUtil.format(now, "yyyyMMddHHmmss"); + String seqStr = String.format("%03d", seq); + return "CZG" + timeStr + seqStr; + } + + + public AggregateMerchantVO convertVO(ShopDirectMerchant entity) { + if (entity == null) { + return null; + } + + AggregateMerchantVO vo = new AggregateMerchantVO(); + vo.setShopId(entity.getShopId()); + vo.setMerchantCode(entity.getMerchantCode()); + + // 解析JSON字段 + vo.setMerchantBaseInfo(JSONObject.parseObject(entity.getMerchantBaseInfo(), MerchantBaseInfoDto.class)); + vo.setLegalPersonInfo(JSONObject.parseObject(entity.getLegalPersonInfo(), LegalPersonInfoDto.class)); + vo.setBusinessLicenceInfo(JSONObject.parseObject(entity.getBusinessLicenceInfo(), BusinessLicenceInfoDto.class)); + vo.setStoreInfo(JSONObject.parseObject(entity.getStoreInfo(), StoreInfoDto.class)); + vo.setSettlementInfo(JSONObject.parseObject(entity.getSettlementInfo(), SettlementInfoDto.class)); + + // 设置其他字段 + vo.setCreateTime(entity.getCreateTime()); + vo.setUpdateTime(entity.getUpdateTime()); + vo.setWechatStatus(entity.getWechatStatus()); + vo.setWechatErrorMsg(entity.getWechatErrorMsg()); + vo.setWechatSignUrl(entity.getWechatSignUrl()); + vo.setAlipayStatus(entity.getAlipayStatus()); + vo.setAlipayErrorMsg(entity.getAlipayErrorMsg()); + vo.setAlipaySignUrl(entity.getAlipaySignUrl()); + + return vo; + } +} diff --git a/cash-service/order-service/src/main/resources/mapper/ShopDirectMerchantMapper.xml b/cash-service/order-service/src/main/resources/mapper/ShopDirectMerchantMapper.xml new file mode 100644 index 000000000..ba52848f4 --- /dev/null +++ b/cash-service/order-service/src/main/resources/mapper/ShopDirectMerchantMapper.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/cash-service/pay-service/pom.xml b/cash-service/pay-service/pom.xml index 92db97998..522c91c55 100644 --- a/cash-service/pay-service/pom.xml +++ b/cash-service/pay-service/pom.xml @@ -26,6 +26,11 @@ czg-pay ${project.version} + + com.czg + aggregation-pay + ${project.version} + diff --git a/cash-service/system-service/src/main/java/com/czg/service/system/mapper/SysBankInfoMapper.java b/cash-service/system-service/src/main/java/com/czg/service/system/mapper/SysBankInfoMapper.java new file mode 100644 index 000000000..92c6db03a --- /dev/null +++ b/cash-service/system-service/src/main/java/com/czg/service/system/mapper/SysBankInfoMapper.java @@ -0,0 +1,14 @@ +package com.czg.service.system.mapper; + +import com.mybatisflex.core.BaseMapper; +import com.czg.system.entity.SysBankInfo; + +/** + * 银行账户信息表 映射层。 + * + * @author ww + * @since 2026-01-06 + */ +public interface SysBankInfoMapper extends BaseMapper { + +} diff --git a/cash-service/system-service/src/main/java/com/czg/service/system/mapper/SysCategoryInfoMapper.java b/cash-service/system-service/src/main/java/com/czg/service/system/mapper/SysCategoryInfoMapper.java new file mode 100644 index 000000000..84d0d82a8 --- /dev/null +++ b/cash-service/system-service/src/main/java/com/czg/service/system/mapper/SysCategoryInfoMapper.java @@ -0,0 +1,14 @@ +package com.czg.service.system.mapper; + +import com.mybatisflex.core.BaseMapper; +import com.czg.system.entity.SysCategoryInfo; + +/** + * 类目信息表 映射层。 + * + * @author ww + * @since 2026-01-06 + */ +public interface SysCategoryInfoMapper extends BaseMapper { + +} diff --git a/cash-service/system-service/src/main/java/com/czg/service/system/mapper/SysRegionMapper.java b/cash-service/system-service/src/main/java/com/czg/service/system/mapper/SysRegionMapper.java new file mode 100644 index 000000000..b438c3d3d --- /dev/null +++ b/cash-service/system-service/src/main/java/com/czg/service/system/mapper/SysRegionMapper.java @@ -0,0 +1,14 @@ +package com.czg.service.system.mapper; + +import com.mybatisflex.core.BaseMapper; +import com.czg.system.entity.SysRegion; + +/** + * 行政区表 映射层。 + * + * @author ww + * @since 2026-01-06 + */ +public interface SysRegionMapper extends BaseMapper { + +} diff --git a/cash-service/system-service/src/main/java/com/czg/service/system/service/impl/SysBankInfoServiceImpl.java b/cash-service/system-service/src/main/java/com/czg/service/system/service/impl/SysBankInfoServiceImpl.java new file mode 100644 index 000000000..9678422fb --- /dev/null +++ b/cash-service/system-service/src/main/java/com/czg/service/system/service/impl/SysBankInfoServiceImpl.java @@ -0,0 +1,26 @@ +package com.czg.service.system.service.impl; + +import com.czg.BaseQueryParam; +import com.mybatisflex.core.paginate.Page; +import com.mybatisflex.spring.service.impl.ServiceImpl; +import com.czg.system.entity.SysBankInfo; +import com.czg.system.service.SysBankInfoService; +import com.czg.service.system.mapper.SysBankInfoMapper; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 银行账户信息表 服务层实现。 + * + * @author ww + * @since 2026-01-06 + */ +@Service +public class SysBankInfoServiceImpl extends ServiceImpl implements SysBankInfoService { + + @Override + public Page bankInfoList(BaseQueryParam param, String bankName) { + return page(Page.of(param.getPage(), param.getSize()), query().like(SysBankInfo::getBankAlias, bankName)); + } +} diff --git a/cash-service/system-service/src/main/java/com/czg/service/system/service/impl/SysCategoryInfoServiceImpl.java b/cash-service/system-service/src/main/java/com/czg/service/system/service/impl/SysCategoryInfoServiceImpl.java new file mode 100644 index 000000000..f8ea19e9e --- /dev/null +++ b/cash-service/system-service/src/main/java/com/czg/service/system/service/impl/SysCategoryInfoServiceImpl.java @@ -0,0 +1,43 @@ +package com.czg.service.system.service.impl; + +import cn.hutool.core.collection.CollStreamUtil; +import cn.hutool.core.collection.CollUtil; +import com.czg.system.vo.SysCategoryInfoVO; +import com.mybatisflex.spring.service.impl.ServiceImpl; +import com.czg.system.entity.SysCategoryInfo; +import com.czg.system.service.SysCategoryInfoService; +import com.czg.service.system.mapper.SysCategoryInfoMapper; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * 类目信息表 服务层实现。 + * + * @author ww + * @since 2026-01-06 + */ +@Service +public class SysCategoryInfoServiceImpl extends ServiceImpl implements SysCategoryInfoService { + + @Cacheable(value = "common:category", key = "'all'") + @Override + public List categoryList() { + List list = list(); + if (CollUtil.isEmpty(list)) { + return List.of(); + } + List result = new ArrayList<>(); + Map> stringListMap = CollStreamUtil.groupByKey(list, SysCategoryInfo::getFirstCategory); + stringListMap.forEach((k, v) -> { + SysCategoryInfoVO vo = new SysCategoryInfoVO(); + vo.setFirstCategory(k); + vo.setChild(v); + result.add(vo); + }); + return result; + } +} diff --git a/cash-service/system-service/src/main/java/com/czg/service/system/service/impl/SysRegionServiceImpl.java b/cash-service/system-service/src/main/java/com/czg/service/system/service/impl/SysRegionServiceImpl.java new file mode 100644 index 000000000..4820a7190 --- /dev/null +++ b/cash-service/system-service/src/main/java/com/czg/service/system/service/impl/SysRegionServiceImpl.java @@ -0,0 +1,56 @@ +package com.czg.service.system.service.impl; + +import com.czg.service.system.mapper.SysRegionMapper; +import com.czg.system.entity.SysRegion; +import com.czg.system.service.SysRegionService; +import com.mybatisflex.spring.service.impl.ServiceImpl; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * 行政区表 服务层实现。 + * + * @author ww + * @since 2026-01-06 + */ +@Service +public class SysRegionServiceImpl extends ServiceImpl implements SysRegionService { + + + @Cacheable(value = "common:region", key = "'all'") + @Override + public List regionList() { + // 1. 单次查询获取所有数据 + List allRegions = list(query().ne(SysRegion::getRegionLevel, 1)); + // 2. 一次性按层级分组,减少流遍历次数 + Map> regionByLevel = allRegions.stream() + .collect(Collectors.groupingBy(SysRegion::getRegionLevel)); + + // 3. 获取各层级数据,默认空列表避免空指针 + List parents = regionByLevel.getOrDefault(2, List.of()); + List level3Regions = regionByLevel.getOrDefault(3, List.of()); + List level4Regions = regionByLevel.getOrDefault(4, List.of()); + + // 4. 构建3级地区的子节点映射(4级),使用HashMap保证性能 + Map> level4ByParentId = level4Regions.stream() + .collect(Collectors.groupingBy(SysRegion::getParentRegionId, Collectors.toList())); + + level3Regions.forEach(level3 -> { + List children = level4ByParentId.getOrDefault(level3.getRegionId(), List.of()); + level3.setChildren(children); + }); + + Map> level3ByParentId = level3Regions.stream() + .collect(Collectors.groupingBy(SysRegion::getParentRegionId)); + + parents.forEach(parent -> { + List children = level3ByParentId.getOrDefault(parent.getRegionId(), List.of()); + parent.setChildren(children); + }); + return parents; + } +} diff --git a/cash-service/system-service/src/main/resources/mapper/SysBankInfoMapper.xml b/cash-service/system-service/src/main/resources/mapper/SysBankInfoMapper.xml new file mode 100644 index 000000000..0edfabab3 --- /dev/null +++ b/cash-service/system-service/src/main/resources/mapper/SysBankInfoMapper.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/cash-service/system-service/src/main/resources/mapper/SysCategoryInfoMapper.xml b/cash-service/system-service/src/main/resources/mapper/SysCategoryInfoMapper.xml new file mode 100644 index 000000000..b3a1df485 --- /dev/null +++ b/cash-service/system-service/src/main/resources/mapper/SysCategoryInfoMapper.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/cash-service/system-service/src/main/resources/mapper/SysRegionMapper.xml b/cash-service/system-service/src/main/resources/mapper/SysRegionMapper.xml new file mode 100644 index 000000000..bb643d005 --- /dev/null +++ b/cash-service/system-service/src/main/resources/mapper/SysRegionMapper.xml @@ -0,0 +1,7 @@ + + + + +