🆕 #1667 微信支付增加电商收付通-二级商户进件相关接口

电商收付通二级商户进件

Co-authored-by: 曾浩 <epdcgsi@dingtalk.com>
This commit is contained in:
cloudX 2020-08-18 10:19:16 +08:00 committed by GitHub
parent a2783832d4
commit 17c20422e2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 1274 additions and 5 deletions

View File

@ -0,0 +1,796 @@
package com.github.binarywang.wxpay.bean.ecommerce;
import com.github.binarywang.wxpay.v3.SpecEncrypt;
import com.google.gson.annotations.SerializedName;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* <pre>
* 电商平台可使用该接口帮助其二级商户进件成为微信支付商户
* 文档地址:https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/ecommerce/applyments/chapter3_1.shtml
* </pre>
*/
@Data
@NoArgsConstructor
public class ApplymentsRequest implements Serializable {
/**
* <pre>
* 字段名业务申请编号
* 变量名out_request_no
* 是否必填
* 类型string(124)
* 描述
* 1服务商自定义的商户唯一编号
* 2每个编号对应一个申请单每个申请单审核通过后会生成一个微信支付商户号
* 3若申请单被驳回可填写相同的业务申请编号即可覆盖修改原申请单信息
* 示例值APPLYMENT_00000000001
* </pre>
*/
@SerializedName(value = "out_request_no")
private String outRequestNo;
/**
* <pre>
* 字段名主体类型
* 变量名organization_type
* 是否必填
* 类型string(4)
* 描述
* 枚举值
* 2401小微商户指无营业执照的商户
* 4个体工商户营业执照上的主体类型一般为个体户个体工商户个体经营
* 2企业营业执照上的主体类型一般为有限公司有限责任公司
* 3党政机关及事业单位包括国内各级各类政府机构事业单位等公安党团司法交通旅游工商税务市政医疗教育学校等机构
* 1708其他组织不属于企业政府/事业单位的组织机构如社会团体民办非企业基金会要求机构已办理组织机构代码证
* 示例值2401
* </pre>
*/
@SerializedName(value = "organization_type")
private String organizationType;
/**
* <pre>
* 字段名+营业执照/登记证书信息
* 变量名business_license_info
* 是否必填条件选填
* 类型object
* 描述
* 1主体为小微不填
* 2主体为个体工商户/企业请上传营业执照
* 3主体为党政机关及事业单位/其他组织请上传登记证书
* </pre>
*/
@SerializedName(value = "business_license_info")
private BusinessLicenseInfo businessLicenseInfo;
/**
* <pre>
* 字段名+组织机构代码证信息
* 变量名organization_cert_info
* 是否必填条件选填
* 类型object
* 描述主体为企业/党政机关及事业单位/其他组织且证件号码不是18位时必填
* </pre>
*/
@SerializedName(value = "organization_cert_info")
private OrganizationCertInfo organizationCertInfo;
/**
* <pre>
* 字段名经营者/法人证件类型
* 变量名id_doc_type
* 是否必填
* 类型string(64)
* 描述
* 1主体为小微只可选择身份证
* 2主体为个体户/企业/党政机关及事业单位/其他组织可选择任一证件类型
* 3若没有填写系统默认选择身份证
* 枚举值:
* IDENTIFICATION_TYPE_MAINLAND_IDCARD中国大陆居民-身份证
* IDENTIFICATION_TYPE_OVERSEA_PASSPORT其他国家或地区居民-护照
* IDENTIFICATION_TYPE_HONGKONG中国香港居民来往内地通行证
* IDENTIFICATION_TYPE_MACAO中国澳门居民来往内地通行证
* IDENTIFICATION_TYPE_TAIWAN中国台湾居民来往大陆通行证
* 示例值IDENTIFICATION_TYPE_MACAO
* </pre>
*/
@SerializedName(value = "id_doc_type")
private String idDocType;
/**
* <pre>
* 字段名+经营者/法人身份证信息
* 变量名id_card_info
* 是否必填条件选填
* 类型object
* 描述
* 请填写经营者/法人的身份证信息
* 证件类型为身份证时填写
*
* </pre>
*/
@SerializedName(value = "id_card_info")
@SpecEncrypt
private IdCardInfo idCardInfo;
/**
* <pre>
* 字段名+经营者/法人其他类型证件信息
* 变量名id_doc_info
* 是否必填条件选填
* 类型object
* 描述证件类型为来往内地通行证来往大陆通行证护照时填写
* </pre>
*/
@SerializedName(value = "id_doc_info")
private IdDocInfo idDocInfo;
/**
* <pre>
* 字段名是否填写结算账户信息
* 变量名need_account_info
* 是否必填
* 类型bool
* 描述
* 可根据实际情况填写truefalse
* 1若为true则需填写结算账户信息
* 2若为false则无需填写结算账户信息
* 示例值true
* </pre>
*/
@SerializedName(value = "need_account_info")
private Boolean needAccountInfo;
/**
* <pre>
* 字段名+结算账户信息
* 变量名account_info
* 是否必填条件选填
* 类型object
* 描述"是否填写结算账户信息"填写为true, 则必填填写为false不填
* </pre>
*/
@SerializedName(value = "account_info")
@SpecEncrypt
private AccountInfo accountInfo;
/**
* <pre>
* 字段名+超级管理员信息
* 变量名contact_info
* 是否必填
* 类型object
* 描述
* 请填写店铺的超级管理员信息
* 超级管理员需在开户后进行签约并可接收日常重要管理信息和进行资金操作请确定其为商户法定代表人或负责人
* </pre>
*/
@SerializedName(value = "contact_info")
@SpecEncrypt
private ContactInfo contactInfo;
/**
* <pre>
* 字段名+店铺信息
* 变量名sales_scene_info
* 是否必填
* 类型object
* 描述请填写店铺信息
* </pre>
*/
@SerializedName(value = "sales_scene_info")
private SalesSceneInfo salesSceneInfo;
/**
* <pre>
* 字段名商户简称
* 变量名merchant_shortname
* 是否必填
* 类型string(64)
* 描述
* UTF-8格式中文占3个字节即最多16个汉字长度将在支付完成页向买家展示需与商家的实际售卖商品相符
* 示例值腾讯
* </pre>
*/
@SerializedName(value = "merchant_shortname")
private String merchantShortname;
/**
* <pre>
* 字段名特殊资质
* 变量名qualifications
* 是否必填
* 类型string(1024)
* 描述
* 1若店铺业务包含互联网售药则需上传特殊资质-互联网药品交易服务证
* 2最多可上传5张照片请填写通过图片上传接口预先上传图片生成好的MediaID
* 示例值[\"jTpGmxUX3FBWVQ5NJInE4d2I6_H7I4\"]
* </pre>
*/
@SerializedName(value = "qualifications")
private String qualifications;
/**
* <pre>
* 字段名补充材料
* 变量名business_addition_pics
* 是否必填
* 类型string(1024)
* 描述
* 最多可上传5张照片请填写通过图片上传接口预先上传图片生成好的MediaID
* 示例值[\"jTpGmg05InE4d2I6_H7I4\"]
* </pre>
*/
@SerializedName(value = "business_addition_pics")
private String businessAdditionPics;
/**
* <pre>
* 字段名补充说明
* 变量名business_addition_desc
* 是否必填
* 类型string(256)
* 描述
* 可填写512字以内
* 示例值特殊情况说明原因
* </pre>
*/
@SerializedName(value = "business_addition_desc")
private String businessAdditionDesc;
@Data
@NoArgsConstructor
public static class BusinessLicenseInfo implements Serializable{
/**
* <pre>
* 字段名证件扫描件
* 变量名business_license_copy
* 是否必填
* 类型string(256)
* 描述
* 1主体为个体工商户/企业请上传营业执照的证件图片
* 2主体为党政机关及事业单位/其他组织请上传登记证书的证件图片
* 3可上传1张图片请填写通过图片上传接口预先上传图片生成好的MediaID
* 4图片要求
* 1请上传证件的彩色扫描件或彩色数码拍摄件黑白复印件需加盖公章公章信息需完整
* 2不得添加无关水印非微信支付商户申请用途的其他水印
* 3需提供证件的正面拍摄件完整照面信息清晰可见信息不清晰扭曲压缩变形反光不完整均不接受
* 4不接受二次剪裁翻拍PS的证件照片
* 示例值 47ZC6GC-vnrbEny__Ie_An5-tCpqxucuxi-vByf3Gjm7KE53JXvGy9tqZm2XAUf-4KGprrKhpVBDIUv0OF4wFNIO4kqg05InE4d2I6_H7I4
* </pre>
*/
@SerializedName(value = "business_license_copy")
private String businessLicenseCopy;
/**
* <pre>
* 字段名证件注册号
* 变量名business_license_number
* 是否必填
* 类型string(18)
* 描述
* 1主体为个体工商户/企业请填写营业执照上的注册号/统一社会信用代码须为15位数字或 18位数字|大写字母
* 2主体为党政机关及事业单位/其他组织请填写登记证书的证书编号
* 示例值123456789012345678
* 特殊规则长度最小15个字节
* </pre>
*/
@SerializedName(value = "business_license_number")
private String businessLicenseNumber;
/**
* <pre>
* 字段名商户名称
* 变量名merchant_name
* 是否必填
* 类型string(128)
* 描述
* 1请填写营业执照/登记证书的商家名称2~110个字符支持括号
* 2个体工商户/党政机关及事业单位不能以公司结尾
* 3个体工商户若营业执照上商户名称为空或为请填写"个体户+经营者姓名"个体户张三
* 示例值腾讯科技有限公司
* </pre>
*/
@SerializedName(value = "merchant_name")
private String merchantName;
/**
* <pre>
* 字段名经营者/法定代表人姓名
* 变量名legal_person
* 是否必填
* 类型string(128)
* 描述
* 请填写证件的经营者/法定代表人姓名
* 示例值张三
* </pre>
*/
@SerializedName(value = "legal_person")
private String legalPerson;
/**
* <pre>
* 字段名注册地址
* 变量名company_address
* 是否必填条件选填
* 类型string(128)
* 描述
* 主体为党政机关及事业单位/其他组织时必填请填写登记证书的注册地址
* 示例值深圳南山区科苑路
* </pre>
*/
@SerializedName(value = "company_address")
private String companyAddress;
/**
* <pre>
* 字段名营业期限
* 变量名business_time
* 是否必填条件选填
* 类型string(256)
* 描述
* 1主体为党政机关及事业单位/其他组织时必填请填写证件有效期
* 2若证件有效期为长期请填写长期
* 3结束时间需大于开始时间
* 4有效期必须大于60天即结束时间距当前时间需超过60天
* 示例值[\"2014-01-01\",\"长期\"]
* </pre>
*/
@SerializedName(value = "business_time")
private String businessTime;
}
@Data
@NoArgsConstructor
public static class OrganizationCertInfo implements Serializable {
/**
* <pre>
* 字段名组织机构代码证照片
* 变量名organization_copy
* 是否必填
* 类型string(256)
* 描述
* 可上传1张图片请填写通过图片上传接口预先上传图片生成好的MediaID
* 示例值vByf3Gjm7KE53JXv\prrKhpVBDIUv0OF4wFNIO4kqg05InE4d2I6_H7I4
* </pre>
*/
@SerializedName(value = "organization_copy")
private String organizationCopy;
/**
* <pre>
* 字段名组织机构代码
* 变量名organization_number
* 是否必填
* 类型string(256)
* 描述
* 1请填写组织机构代码证上的组织机构代码
* 2可填写9或10位 数字|字母|连字符
* 示例值12345679-A
* </pre>
*/
@SerializedName(value = "organization_number")
private String organizationNumber;
/**
* <pre>
* 字段名组织机构代码有效期限
* 变量名organization_time
* 是否必填
* 类型string(256)
* 描述
* 1请填写组织机构代码证的有效期限注意参照示例中的格式
* 2若证件有效期为长期请填写长期
* 3结束时间需大于开始时间
* 4有效期必须大于60天即结束时间距当前时间需超过60天
* 示例值[\"2014-01-01\",\"长期\"]
* </pre>
*/
@SerializedName(value = "organization_time")
private String organizationTime;
}
@Data
@NoArgsConstructor
public static class IdCardInfo implements Serializable {
/**
* <pre>
* 字段名身份证人像面照片
* 变量名id_card_copy
* 是否必填
* 类型string(256)
* 描述
* 1请上传经营者/法定代表人的身份证人像面照片
* 2可上传1张图片请填写通过图片上传接口预先上传图片生成好的MediaID
* 示例值xpnFuAxhBTEO_PvWkfSCJ3zVIn001D8daLC-ehEuo0BJqRTvDujqhThn4ReFxikqJ5YW6zFQ
* </pre>
*/
@SerializedName(value = "id_card_copy")
private String idCardCopy;
/**
* <pre>
* 字段名身份证国徽面照片
* 变量名id_card_national
* 是否必填
* 类型string(256)
* 描述
* 1请上传经营者/法定代表人的身份证国徽面照片
* 2可上传1张图片请填写通过图片上传接口预先上传图片生成好的MediaID
* 示例值vByf3Gjm7KE53JXvGy9tqZm2XAUf-4KGprrKhpVBDIUv0OF4wFNIO4kqg05InE4d2I6_H7I4
* </pre>
*/
@SerializedName(value = "id_card_national")
private String idCardNational;
/**
* <pre>
* 字段名身份证姓名
* 变量名id_card_name
* 是否必填
* 类型string(256)
* 描述
* 1请填写经营者/法定代表人对应身份证的姓名2~30个中文字符英文字符符号
* 2该字段需进行加密处理加密方法详见敏感信息加密说明
* 示例值pVd1HJ6v/69bDnuC4EL5Kz4jBHLiCa8MRtelw/wDa4SzfeespQO/0kjiwfqdfg==
* 字段加密:使用APIv3定义的方式加密
* </pre>
*/
@SerializedName(value = "id_card_name")
@SpecEncrypt
private String idCardName;
/**
* <pre>
* 字段名身份证号码
* 变量名id_card_number
* 是否必填
* 类型string(18)
* 描述
* 1请填写经营者/法定代表人对应身份证的号码
* 215位数字或17位数字+1位数字|X 该字段需进行加密处理加密方法详见敏感信息加密说明
* 示例值zV+BEmytMNQCqQ8juwEc4P4TG5xzchG/5IL9DBd+Z0zZXkw==4
* 特殊规则长度最小15个字节
* </pre>
*/
@SerializedName(value = "id_card_number")
@SpecEncrypt
private String idCardNumber;
/**
* <pre>
* 字段名身份证有效期限
* 变量名id_card_valid_time
* 是否必填
* 类型string(128)
* 描述
* 1请填写身份证有效期的结束时间注意参照示例中的格式
* 2若证件有效期为长期请填写长期
* 3证件有效期需大于60天
* 示例值2026-06-06长期
* </pre>
*/
@SerializedName(value = "id_card_valid_time")
private String idCardValidTime;
}
@Data
@NoArgsConstructor
public static class IdDocInfo implements Serializable {
/**
* <pre>
* 字段名证件姓名
* 变量名id_doc_name
* 是否必填
* 类型string(128)
* 描述
* 请填写经营者/法人姓名
* 示例值jTpGmxUX3FBWVQ5NJTZvlKX_gdU4LC-ehEuo0BJqRTvDujqhThn4ReFxikqJ5YW6zFQ
* </pre>
*/
@SerializedName(value = "id_doc_name")
private String idDocName;
/**
* <pre>
* 字段名证件号码
* 变量名id_doc_number
* 是否必填
* 类型string(128)
* 描述
* 7~11位 数字|字母|连字符
* 示例值jTpGmxUX3FBWVQ5NJTZvlKX_go0BJqRTvDujqhThn4ReFxikqJ5YW6zFQ
* </pre>
*/
@SerializedName(value = "id_doc_number")
private String idDocNumber;
/**
* <pre>
* 字段名证件照片
* 变量名id_doc_copy
* 是否必填
* 类型string(256)
* 描述
* 1可上传1张图片请填写通过图片上传接口预先上传图片生成好的MediaID
* 22M内的彩色图片格式可为bmppngjpegjpg或gif
* 示例值xi-vByf3Gjm7KE53JXvGy9tqZm2XAUf-4KGprrKhpVBDIUv0OF4wFNIO4kqg05InE4d2I6_H7I4
* </pre>
*/
@SerializedName(value = "id_doc_copy")
private String idDocCopy;
/**
* <pre>
* 字段名证件结束日期
* 变量名doc_period_end
* 是否必填
* 类型string(128)
* 描述
* 1请按照示例值填写
* 2若证件有效期为长期请填写长期
* 3证件有效期需大于60天
* 示例值2020-01-02
* </pre>
*/
@SerializedName(value = "doc_period_end")
private String docPeriodEnd;
}
@Data
@NoArgsConstructor
public static class AccountInfo implements Serializable {
/**
* <pre>
* 字段名账户类型
* 变量名bank_account_type
* 是否必填
* 类型string(2)
* 描述
* 1若主体为企业/党政机关及事业单位/其他组织可填写74-对公账户
* 2若主体为小微可填写75-对私账户
* 3若主体为个体工商户可填写74-对公账户或75-对私账户
* 示例值75
* </pre>
*/
@SerializedName(value = "bank_account_type")
private String bankAccountType;
/**
* <pre>
* 字段名开户银行
* 变量名account_bank
* 是否必填
* 类型string(10)
* 描述
* 详细参见开户银行对照表
* 示例值工商银行
* </pre>
*/
@SerializedName(value = "account_bank")
private String accountBank;
/**
* <pre>
* 字段名开户名称
* 变量名account_name
* 是否必填
* 类型string(128)
* 描述
* 1选择经营者个人银行卡时开户名称必须与身份证姓名一致
* 2选择对公账户时开户名称必须与营业执照上的商户名称一致
* 3该字段需进行加密处理加密方法详见敏感信息加密说明
* 示例值AOZdYGISxo4yw96uY1Pk7Rq79Jtt7+I8juwEc4P4TG5xzchG/5IL9DBd+Z0zZXkw==
* </pre>
*/
@SerializedName(value = "account_name")
@SpecEncrypt
private String accountName;
/**
* <pre>
* 字段名开户银行省市编码
* 变量名bank_address_code
* 是否必填
* 类型string(12)
* 描述
* 至少精确到市详细参见省市区编号对照表
* 示例值110000
* </pre>
*/
@SerializedName(value = "bank_address_code")
private String bankAddressCode;
/**
* <pre>
* 字段名开户银行联行号
* 变量名bank_branch_id
* 是否必填条件选填
* 类型string(64)
* 描述
* 117家直连银行无需填写如为其他银行开户银行全称含支行和开户银行联行号二选一
* 2详细参见开户银行全称含支行对照表
* 示例值402713354941
* </pre>
*/
@SerializedName(value = "bank_branch_id")
private String bankBranchId;
/**
* <pre>
* 字段名开户银行全称 含支行)
* 变量名bank_name
* 是否必填条件选填
* 类型string(128)
* 描述
* 117家直连银行无需填写如为其他银行开户银行全称含支行和开户银行联行号二选一
* 2需填写银行全称"深圳农村商业银行XXX支行"
* 3详细参见开户银行全称含支行对照表
* 示例值施秉县农村信用合作联社城关信用社
* </pre>
*/
@SerializedName(value = "bank_name")
private String bankName;
/**
* <pre>
* 字段名银行帐号
* 变量名account_number
* 是否必填
* 类型string(128)
* 描述
* 1数字长度遵循系统支持的对公/对私卡号长度要求表
* 2该字段需进行加密处理加密方法详见敏感信息加密说明
* 示例值 d+xT+MQCvrLHUVDWv/8MR/dB7TkXLVfSrUxMPZy6jWWYzpRrEEaYQE8ZRGYoeorwC+w==
* </pre>
*/
@SerializedName(value = "account_number")
@SpecEncrypt
private String accountNumber;
}
@Data
@NoArgsConstructor
public static class ContactInfo implements Serializable {
/**
* <pre>
* 字段名超级管理员类型
* 变量名contact_type
* 是否必填
* 类型string(2)
* 描述
* 1小微商户选择65-法人/经营者
* 2个体工商户/企业/党政机关及事业单位/其他组织可选择65-法人/经营者66- 负责人 负责人经商户授权办理微信支付业务的人员授权范围包括但不限于签约入驻过程需完成账户验证
* 示例值65
* </pre>
*/
@SerializedName(value = "contact_type")
private String contactType;
/**
* <pre>
* 字段名超级管理员姓名
* 变量名contact_name
* 是否必填
* 类型string(256)
* 描述
* 1若管理员类型为法人则该姓名需与法人身份证姓名一致
* 2若管理员类型为经办人则可填写实际经办人的姓名
* 3该字段需进行加密处理加密方法详见敏感信息加密说明
* 后续该管理员需使用实名微信号完成签约
* 示例值 pVd1HJ6zyvPedzGaV+X3IdGdbDnuC4Eelw/wDa4SzfeespQO/0kjiwfqdfg==
* </pre>
*/
@SerializedName(value = "contact_name")
@SpecEncrypt
private String contactName;
/**
* <pre>
* 字段名超级管理员身份证件号码
* 变量名contact_id_card_number
* 是否必填
* 类型string(256)
* 描述
* 1若管理员类型为法人则该身份证号码需与法人身份证号码一致若管理员类型为经办人则可填写实际经办人的身份证号码
* 2可传身份证来往内地通行证来往大陆通行证护照等证件号码
* 3超级管理员签约时校验微信号绑定的银行卡实名信息是否与该证件号码一致
* 4该字段需进行加密处理加密方法详见敏感信息加密说明
* 示例值pVd1HJ6zmty7/mYNxLMpRSvMRtelw/wDa4SzfeespQO/0kjiwfqdfg==
* </pre>
*/
@SerializedName(value = "contact_id_card_number")
@SpecEncrypt
private String contactIdCardNumber;
/**
* <pre>
* 字段名超级管理员手机
* 变量名mobile_phone
* 是否必填
* 类型string(256)
* 描述
* 1请填写管理员的手机号11位数字 用于接收微信支付的重要管理信息及日常操作验证码
* 2该字段需进行加密处理加密方法详见敏感信息加密说明
* 示例值pVd1HJ6zyvPedzGaV+X3qtmrq9bb9tPROvwia4ibL+F6mfjbzQIzfb3HHLEjZ4YiNWWNeespQO/0kjiwfqdfg==
* </pre>
*/
@SerializedName(value = "mobile_phone")
@SpecEncrypt
private String mobilePhone;
/**
* <pre>
* 字段名超级管理员邮箱
* 变量名contact_email
* 是否必填
* 类型string(256)
* 描述
* 1用于接收微信支付的开户邮件及日常业务通知
* 2需要带@遵循邮箱格式校验
* 3该字段需进行加密处理加密方法详见敏感信息加密说明
* 示例值pVd1HJ6zyvPedzGaV+X3qtmrq9bb9tPROvwia4ibL+FWWNUlw/wDa4SzfeespQO/0kjiwfqdfg==
* </pre>
*/
@SerializedName(value = "contact_email")
@SpecEncrypt
private String contactEmail;
}
@Data
@NoArgsConstructor
public static class SalesSceneInfo implements Serializable {
/**
* <pre>
* 字段名店铺名称
* 变量名store_name
* 是否必填
* 类型string(256)
* 描述
* 请填写店铺全称
* 示例值爱烧烤
* </pre>
*/
@SerializedName(value = "store_name")
private String storeName;
/**
* <pre>
* 字段名店铺链接
* 变量名store_url
* 是否必填二选一
* 类型string(1024)
* 描述
* 1店铺二维码or店铺链接二选一必填
* 2请填写店铺主页链接需符合网站规范
* 示例值http://www.qq.com
* </pre>
*/
@SerializedName(value = "store_url")
private String storeUrl;
/**
* <pre>
* 字段名店铺二维码
* 变量名store_qr_code
* 是否必填1店铺二维码 or 店铺链接二选一必填 2若为电商小程序可上传店铺页面的小程序二维码 3请填写通过图片上传接口预先上传图片生成好的MediaID仅能上传1张图片 示例值jTpGmxUX3FBWVQ5NJTZvlKX_gdU4cRz7z5NxpnFuAxhBTEO1D8daLC-ehEuo0BJqRTvDujqhThn4ReFxikqJ5YW6zFQ
* 类型string(256)
* 描述
* </pre>
*/
@SerializedName(value = "store_qr_code")
private String storeQrCode;
}
}

View File

@ -0,0 +1,43 @@
package com.github.binarywang.wxpay.bean.ecommerce;
import com.google.gson.annotations.SerializedName;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* 二级商户进件 提交申请结果响应
*/
@Data
@NoArgsConstructor
public class ApplymentsResult implements Serializable {
/**
* <pre>
* 字段名微信支付申请单号
* 变量名applyment_id
* 是否必填
* 类型uint64
* 描述
* 微信支付分配的申请单号
* 示例值2000002124775691
* </pre>
*/
@SerializedName(value = "applyment_id")
private String applymentId;
/**
* <pre>
* 字段名业务申请编号
* 变量名out_request_no
* 是否必填
* 类型string(124)
* 描述
* 服务商自定义的商户唯一编号每个编号对应一个申请单每个申请单审核通过后会生成一个微信支付商户号
* 示例值APPLYMENT_00000000001
* </pre>
*/
@SerializedName(value = "out_request_no")
private String outRequestNo;
}

View File

@ -0,0 +1,308 @@
package com.github.binarywang.wxpay.bean.ecommerce;
import com.google.gson.annotations.SerializedName;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.util.List;
@Data
@NoArgsConstructor
public class ApplymentsStatusResult implements Serializable {
/**
* <pre>
* 字段名申请状态
* 变量名applyment_state
* 是否必填
* 类型string(32)
* 描述
* 枚举值
* CHECKING资料校验中
* ACCOUNT_NEED_VERIFY待账户验证
* AUDITING审核中
* REJECTED已驳回
* NEED_SIGN待签约
* FINISH完成
* FROZEN已冻结
* 示例值FINISH
* </pre>
*/
@SerializedName(value = "applyment_state")
private String applymentState;
/**
* <pre>
* 字段名申请状态描述
* 变量名applyment_state_desc
* 是否必填
* 类型string(32)
* 描述
* 申请状态描述
* 示例值审核中
* </pre>
*/
@SerializedName(value = "applyment_state_desc")
private String applymentStateDesc;
/**
* <pre>
* 字段名签约链接
* 变量名sign_url
* 是否必填
* 类型string(256)
* 描述
* 1当申请状态为NEED_SIGN时才返回
* 2建议将链接转为二维码展示需让申请单-管理者用微信扫码打开完成签约
* 示例值https://pay.weixin.qq.com/public/apply4ec_sign/s?applymentId=2000002126198476&sign=b207b673049a32c858f3aabd7d27c7ec
* </pre>
*/
@SerializedName(value = "sign_url")
private String signUrl;
/**
* <pre>
* 字段名电商平台二级商户号
* 变量名sub_mchid
* 是否必填
* 类型string(32)
* 描述
* 当申请状态为NEED_SIGN或FINISH时才返回
* 示例值1542488631
* </pre>
*/
@SerializedName(value = "sub_mchid")
private String subMchid;
/**
* <pre>
* 字段名+汇款账户验证信息
* 变量名account_validation
* 是否必填
* 类型object
* 描述当申请状态为ACCOUNT_NEED_VERIFY 时有返回可根据指引汇款完成账户验证
* </pre>
*/
@SerializedName(value = "account_validation")
private AccountValidation accountValidation;
/**
* <pre>
* 字段名+驳回原因详情
* 变量名audit_detail
* 是否必填
* 类型array
* 描述各项资料的审核情况当申请状态为REJECTED或 FROZEN时才返回
* </pre>
*/
@SerializedName(value = "audit_detail")
private List<AuditDetail> auditDetail;
/**
* <pre>
* 字段名法人验证链接
* 变量名legal_validation_url
* 是否必填
* 类型string(256)
* 描述
* 1当申请状态为
* ACCOUNT_NEED_VERIFY且通过系统校验的申请单将返回链接
* 2建议将链接转为二维码展示让商户法人用微信扫码打开完成账户验证
* 示例值 https://pay.weixin.qq.com/public/apply4ec_sign/s?applymentId=2000002126198476&sign=b207b673049a32c858f3aabd7d27c7ec
* </pre>
*/
@SerializedName(value = "legal_validation_url")
private String legalValidationUrl;
/**
* <pre>
* 字段名业务申请编号
* 变量名out_request_no
* 是否必填
* 类型string(124)
* 描述
* 提交接口填写的业务申请编号
* 示例值APPLYMENT_00000000001
* </pre>
*/
@SerializedName(value = "out_request_no")
private String outRequestNo;
/**
* <pre>
* 字段名微信支付申请单号
* 变量名applyment_id
* 是否必填
* 类型uint64
* 描述
* 微信支付分配的申请单号
* 示例值2000002124775691
* </pre>
*/
@SerializedName(value = "applyment_id")
private String applymentId;
@Data
@NoArgsConstructor
public static class AccountValidation implements Serializable{
/**
* <pre>
* 字段名付款户名
* 变量名account_name
* 是否必填
* 类型uint64
* 描述
* 需商户使用该户名的账户进行汇款
* 示例值 rDdICA3ZYXshYqeOSslSjSMf+MhhC4oaujiISFzq3AE+as7mAEDJly+DgRuVs74msmKUH8pl+3oA==
* </pre>
*/
@SerializedName(value = "account_name")
private String accountName;
/**
* <pre>
* 字段名付款卡号
* 变量名account_no
* 是否必填
* 类型string(128)
* 描述
* 结算账户为对私时会返回商户需使用该付款卡号进行汇款
* 示例值9nZYDEvBT4rDdICA3ZYXshYqeOSslSjSauAE+as7mAEDJly+DgRuVs74msmKUH8pl+3oA==
* </pre>
*/
@SerializedName(value = "account_no")
private String accountNo;
/**
* <pre>
* 字段名汇款金额
* 变量名pay_amount
* 是否必填
* 类型string(32)
* 描述
* 需要汇款的金额(单位)
* 示例值124
* </pre>
*/
@SerializedName(value = "pay_amount")
private String payAmount;
/**
* <pre>
* 字段名收款卡号
* 变量名destination_account_number
* 是否必填
* 类型string(128)
* 描述
* 收款账户的卡号
* 示例值7222223333322332
* </pre>
*/
@SerializedName(value = "destination_account_number")
private String destinationAccountNumber;
/**
* <pre>
* 字段名收款户名
* 变量名destination_account_name
* 是否必填
* 类型string(128)
* 描述
* 收款账户名
* 示例值财付通支付科技有限公司
* </pre>
*/
@SerializedName(value = "destination_account_name")
private String destinationAccountName;
/**
* <pre>
* 字段名开户银行
* 变量名destination_account_bank
* 是否必填
* 类型string(128)
* 描述
* 收款账户的开户银行名称
* 示例值招商银行威盛大厦支行
* </pre>
*/
@SerializedName(value = "destination_account_bank")
private String destinationAccountBank;
/**
* <pre>
* 字段名省市信息
* 变量名city
* 是否必填
* 类型string(128)
* 描述
* 收款账户的省市
* 示例值深圳
* </pre>
*/
@SerializedName(value = "city")
private String city;
/**
* <pre>
* 字段名备注信息
* 变量名remark
* 是否必填
* 类型string(128)
* 描述
* 商户汇款时需要填写的备注信息
* 示例值入驻账户验证
* </pre>
*/
@SerializedName(value = "remark")
private String remark;
/**
* <pre>
* 字段名汇款截止时间
* 变量名deadline
* 是否必填
* 类型string(20)
* 描述
* 请在此时间前完成汇款
* 示例值2018-12-1017:09:01
* </pre>
*/
@SerializedName(value = "deadline")
private String deadline;
}
@Data
@NoArgsConstructor
public static class AuditDetail implements Serializable{
/**
* <pre>
* 字段名参数名称
* 变量名param_name
* 是否必填
* 类型string(32)
* 描述
* 提交申请单的资料项名称
* 示例值id_card_copy
* </pre>
*/
@SerializedName(value = "param_name")
private String paramName;
/**
* <pre>
* 字段名驳回原因
* 变量名reject_reason
* 是否必填
* 类型string(32)
* 描述
* 提交资料项被驳回原因
* 示例值身份证背面识别失败请上传更清晰的身份证图片
* </pre>
*/
@SerializedName(value = "reject_reason")
private String rejectReason;
}
}

View File

@ -130,6 +130,12 @@ public class WxPayConfig {
* 私钥信息
*/
private PrivateKey privateKey;
/**
* 证书自动更新时间差(分钟)默认一分钟
*/
private int certAutoUpdateTime = 60;
/**
* p12证书文件内容的字节数组.
*/
@ -245,8 +251,7 @@ public class WxPayConfig {
AutoUpdateCertificatesVerifier verifier = new AutoUpdateCertificatesVerifier(
new WxPayCredentials(mchId, new PrivateKeySigner(certSerialNo, merchantPrivateKey)),
apiV3Key.getBytes(StandardCharsets.UTF_8));
apiV3Key.getBytes(StandardCharsets.UTF_8), this.getCertAutoUpdateTime());
CloseableHttpClient httpClient = WxPayV3HttpClientBuilder.create()
.withMerchant(mchId, certSerialNo, merchantPrivateKey)

View File

@ -0,0 +1,55 @@
package com.github.binarywang.wxpay.service;
import com.github.binarywang.wxpay.bean.ecommerce.ApplymentsRequest;
import com.github.binarywang.wxpay.bean.ecommerce.ApplymentsResult;
import com.github.binarywang.wxpay.bean.ecommerce.ApplymentsStatusResult;
import com.github.binarywang.wxpay.exception.WxPayException;
/**
* <pre>
* 电商收付通相关服务类.
* 接口规则https://wechatpay-api.gitbook.io/wechatpay-api-v3
* </pre>
*
* @author cloudX
* @date 2020/08/17
*/
public interface EcommerceService {
/**
* <pre>
* 二级商户进件API
* 接口地址: https://api.mch.weixin.qq.com/v3/ecommerce/applyments/
* 文档地址: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/ecommerce/applyments/chapter3_1.shtml
*
* </pre>
*
* @param request 请求对象
* @return .
*/
ApplymentsResult createApply(ApplymentsRequest request) throws WxPayException;
/**
* <pre>
* 查询申请状态API
* 请求URL: https://api.mch.weixin.qq.com/v3/ecommerce/applyments/{applyment_id}
* 文档地址: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/ecommerce/applyments/chapter3_2.shtml
* </pre>
*
* @param applymentId 申请单ID
* @return .
*/
ApplymentsStatusResult queryApplyStatusByApplymentId(String applymentId) throws WxPayException;
/**
* <pre>
* 查询申请状态API
* 请求URL: https://api.mch.weixin.qq.com/v3/ecommerce/applyments/out-request-no/{out_request_no}
* 文档地址: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/ecommerce/applyments/chapter3_2.shtml
* </pre>
*
* @param outRequestNo 业务申请编号
* @return .
*/
ApplymentsStatusResult queryApplyStatusByOutRequestNo(String outRequestNo) throws WxPayException;
}

View File

@ -126,6 +126,12 @@ public interface WxPayService {
*/
PayScoreService getPayScoreService();
/**
* 获取电商收付通服务类
* @return
*/
EcommerceService getEcommerceService();
/**
* 设置企业付款服务类允许开发者自定义实现类.
*

View File

@ -62,6 +62,7 @@ public abstract class BaseWxPayServiceImpl implements WxPayService {
private ProfitSharingService profitSharingService = new ProfitSharingServiceImpl(this);
private RedpackService redpackService = new RedpackServiceImpl(this);
private PayScoreService payScoreService = new PayScoreServiceImpl(this);
private EcommerceService ecommerceService = new EcommerceServiceImpl(this);
/**
* The Config.
@ -88,6 +89,11 @@ public abstract class BaseWxPayServiceImpl implements WxPayService {
return this.redpackService;
}
@Override
public EcommerceService getEcommerceService() {
return ecommerceService;
}
@Override
public void setEntPayService(EntPayService entPayService) {
this.entPayService = entPayService;

View File

@ -0,0 +1,52 @@
package com.github.binarywang.wxpay.service.impl;
import com.github.binarywang.wxpay.bean.ecommerce.ApplymentsRequest;
import com.github.binarywang.wxpay.bean.ecommerce.ApplymentsResult;
import com.github.binarywang.wxpay.bean.ecommerce.ApplymentsStatusResult;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.EcommerceService;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.v3.util.RsaCryptoUtil;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.net.URI;
public class EcommerceServiceImpl implements EcommerceService {
private static final Gson GSON = new GsonBuilder().create();
private WxPayService payService;
/**
*
* @param payService
*/
public EcommerceServiceImpl(WxPayService payService) {
this.payService = payService;
}
@Override
public ApplymentsResult createApply(ApplymentsRequest request) throws WxPayException {
String url = String.format("%s/v3/ecommerce/applyments/", this.payService.getPayBaseUrl());
RsaCryptoUtil.encryptFields(request, this.payService.getConfig().getVerifier().getValidCertificate());
String result = this.payService.postV3WithWechatpaySerial(url, GSON.toJson(request));
return GSON.fromJson(result, ApplymentsResult.class);
}
@Override
public ApplymentsStatusResult queryApplyStatusByApplymentId(String applymentId) throws WxPayException {
String url = String.format("%s/v3/ecommerce/applyments/%s", this.payService.getPayBaseUrl(), applymentId);
String result = this.payService.getV3(URI.create(url));
return GSON.fromJson(result, ApplymentsStatusResult.class);
}
@Override
public ApplymentsStatusResult queryApplyStatusByOutRequestNo(String outRequestNo) throws WxPayException {
String url = String.format("%s/v3/ecommerce/applyments/out-request-no/%s", this.payService.getPayBaseUrl(), outRequestNo);
String result = this.payService.getV3(URI.create(url));
return GSON.fromJson(result, ApplymentsStatusResult.class);
}
}

View File

@ -29,10 +29,8 @@ public class RsaCryptoUtil {
public static void encryptFields(Object encryptObject, X509Certificate certificate) throws WxPayException {
try {
encryptField(encryptObject, certificate);
} catch (IllegalAccessException | IllegalBlockSizeException e) {
} catch (Exception e) {
throw new WxPayException("敏感信息加密失败", e);
} catch (Exception e2) {
throw new WxPayException("敏感信息加密失败", e2);
}
}