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] =?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); }