支付宝 图片上传

This commit is contained in:
gong
2026-01-04 14:20:24 +08:00
parent 9a1b5b5cae
commit 8d9878a316
15 changed files with 893 additions and 167 deletions

View File

@@ -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<byte[]> 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];
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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;
/**
* 支付宝进件管理
*
* <a href="https://opendocs.alipay.com/solution/9434dd99_ant.merchant.expand.indirect.zft.simplecreate?scene=bf5951260023430e944c2e9afdf7f9e2&pathHash=d3136936">...</a>
*
* @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();

View File

@@ -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;
}

View File

@@ -1,37 +0,0 @@
package com.czg.alipay.dto;
import com.alibaba.fastjson2.annotation.JSONField;
import lombok.Data;
/**
* 开启代商户签约、创建应用事务
* 在 ISV 代商户进行应用创建、产品签约时,用于开启一个操作事务,必须是第一个调用的接口。
* 场景1ISV 代商户进行应用创建、产品签约,最后提交事务后需要商户确认才能完成流程;
* 场景2服务市场订购及授权使用订单授权凭证order_ticket开启预授权模式该模式下提交事务后无需商户确认。
* @author yjjie
* @date 2025/12/29 14:19
*/
@Data
public class AlipayCreateDto {
/**
* 【必填】
* isv代操作的商户账号可以是支付宝账号也可以是pid2088开头
*/
@JSONField(name = "account")
private String account;
/**
* 【必填】
* 商户联系人信息,包含联系人名称、手机、邮箱信息。联系人信息将用于接受签约后的重要通知,如确认协议、到期提醒等。
*/
@JSONField(name = "contact_info")
private AlipayCreateContactInfoDto contactInfo;
/**
* 【选填】
* 订单授权凭证。若传入本参数,则对应事务提交后进入预授权模式。
*/
@JSONField(name = "order_ticket")
private String orderTicket;
}

View File

@@ -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;
/**
* 支付宝支付域名
* <a href="https://openapi.alipay.com"></a>
*/
private String domain;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -0,0 +1,249 @@
package com.czg.alipay.dto.entry;
import com.alibaba.fastjson2.annotation.JSONField;
import lombok.Data;
import java.util.List;
/**
* 平台商提交二级商户资料进行进件,完成二级商户入驻
* <a href="https://opendocs.alipay.com/solution/9434dd99_ant.merchant.expand.indirect.zft.simplecreate?scene=bf5951260023430e944c2e9afdf7f9e2&pathHash=d3136936">...</a>
* @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<String> service;
/**
* 【必填】
* 商户证件编号
* 按商户类型merchant_type的说明提供对应的证件编号
*/
@JSONField(name = "cert_no")
private String certNo;
/**
* 【必填】
* 商户类别码 mcc
* <a href="https://mdn.alipayobjects.com/huamei_fctrxv/afts/file/A*3TMHRZ8ppa4AAAAAAAAAAAAADs2DAQ/%E8%BF%9B%E4%BB%B6MCC%E4%B8%8E%E8%B5%84%E8%B4%A8%E8%A6%81%E6%B1%82202212.xlsx">...</a>
* 可查看 进件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;
/**
* 【选填】
* 授权函
* <a href="https://opendocs.alipay.com/open/direct-payment/cg5mkp#%E7%9B%B8%E5%85%B3%E8%B5%84%E6%96%99">《说明函》模板参考</a>
* 当商户名与结算卡户名不一致。《说明函》模板参考。涉及外籍法人(这种情况上传任意能证明身份的图片)时必填,
* 其值为使用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<AlipayQualificationsReqDto> qualifications;
/**
* 【选填】
* 交易场景
* 【枚举值】
* 小程序支付场景: TINY_APP
* H5场景: WAP
* 线下当面付场景: OFFLINE
* APP支付场景: APP
* 网站支付场景: PC
*/
@JSONField(name = "trade_scene")
private List<String> tradeScene;
}

View File

@@ -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;
}

View File

@@ -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 {
/**
* 【必填】
* 商户行业资质类型 具体选值参见 <a href="https://gw.alipayobjects.com/os/bmw-prod/7aa3a36b-2bc2-4d57-815f-08edd55ef67e.xlsx">文档</a>
* 【枚举值】
* 金融许可证: 323
* 【示例值】323
*/
@JSONField(name = "industry_qualification_type")
private String industryQualificationType;
/**
* 【必填】
* 商户行业资质图片
*/
@JSONField(name = "industry_qualification_image")
private String industryQualificationImage;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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<byte[]> 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);
}