特约商户进件接口字段太多,费九牛二虎之力
1.接口地址
2.创建v3 httpClient 获取平台证书列表 上传图片到微信服务器,敏感信息加密工具类
@Slf4j
public class WechatPay {
private static final String appId = "xxxxxx"; // 服务商商户的 APPID 小程序等appid
private static final String merchantId = "xxxxxx";// 服务商商户号
private static final String merchantSerialNumber = "xxxxxx";//商户API证书的证书序列号
private static final String apiV3Key = "xxxxxx";//apiv3密钥
/**
* 商户API私钥,如何加载商户API私钥请看 常见问题。 @link: https://github.com/wechatpay-apiv3/wechatpay-apache-httpclient#%E5%A6%82%E4%BD%95%E5%8A%A0%E8%BD%BD%E5%95%86%E6%88%B7%E7%A7%81%E9%92%A5
*/
private static PrivateKey merchantPrivateKey = null;
static {
try {
merchantPrivateKey = PemUtil.loadPrivateKey(
new ClassPathResource("apiclient_key.pem").getInputStream());
String format = merchantPrivateKey.getFormat();
System.out.println(format);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 微信支付平台证书列表. 这个文件是自己手动创建的需要运行 main方法运行一次就可以
*/
private static List<X509Certificate> wechatPayCertificates = new ArrayList<>();
static {
try {
wechatPayCertificates.add(PemUtil.loadCertificate(new ClassPathResource("cert.pem").getInputStream()));
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws Exception {
getptcert();
}
/**
* 获取平台证书 只要首次执行
* @throws URISyntaxException
* @throws IOException
*/
public static void getptcert() throws URISyntaxException, IOException, NotFoundException, GeneralSecurityException, HttpCodeException {
URIBuilder uriBuilder = new URIBuilder("https://api.mch.weixin.qq.com/v3/certificates");
HttpGet httpGet = new HttpGet(uriBuilder.build());
httpGet.addHeader("Accept", "application/json");
CloseableHttpResponse response = getHttpClient().execute(httpGet);
String bodyAsString = EntityUtils.toString(response.getEntity());
System.out.println(bodyAsString);
JSONObject resourceJsons = JSONObject.parseObject(bodyAsString);
JSONArray jsonArray = JSONArray.parseArray(resourceJsons.getString("data"));
JSONObject resourceJson2 = jsonArray.getJSONObject(0);
JSONObject resourceJson = resourceJson2.getJSONObject("encrypt_certificate");
String associated_data = resourceJson.getString("associated_data");
String nonce = resourceJson.getString("nonce");
String ciphertext = resourceJson.getString("ciphertext");
//解密,如果这里报错,就一定是APIv3密钥错误
AesUtil aesUtil = new AesUtil(apiV3Key.getBytes());
String resourceData = aesUtil.decryptToString(associated_data.getBytes(), nonce.getBytes(), ciphertext);
System.out.println("解密后=" + resourceData);
}
/**
* 敏感信息加密
* @param message
* @param
* @return
* @throws IllegalBlockSizeException
* @throws IOException
* @throws InvalidKeyException
* @throws BadPaddingException
*/
public static String rsaEncryptOAEP(String message) throws IllegalBlockSizeException, IOException, InvalidKeyException, BadPaddingException {
if(StringUtils.isBlank(message)){
return "";
}
try {
Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding");
X509Certificate x509Certificate = PemUtil.loadCertificate(new ClassPathResource("cert.pem").getInputStream());
//cipher.init(Cipher.ENCRYPT_MODE, certificate.getPublicKey());
cipher.init(Cipher.ENCRYPT_MODE, x509Certificate.getPublicKey());
byte[] data = message.getBytes("utf-8");
byte[] cipherdata = cipher.doFinal(data);
return Base64.getEncoder().encodeToString(cipherdata);
} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
throw new RuntimeException("当前Java环境不支持RSA v1.5/OAEP", e);
} catch (InvalidKeyException e) {
throw new IllegalArgumentException("无效的证书", e);
} catch (IllegalBlockSizeException | BadPaddingException e) {
throw new IllegalBlockSizeException("加密原串的长度不能超过214字节");
}
}
/**
* 敏感信息解密
* @param ciphertext
* @param privateKey
* @return
* @throws BadPaddingException
* @throws IOException
*/
public static String rsaDecryptOAEP(String ciphertext, PrivateKey privateKey)
throws BadPaddingException, IOException {
try {
Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] data = Base64.getDecoder().decode(ciphertext);
return new String(cipher.doFinal(data), "utf-8");
} catch (NoSuchPaddingException | NoSuchAlgorithmException e) {
throw new RuntimeException("当前Java环境不支持RSA v1.5/OAEP", e);
} catch (InvalidKeyException e) {
throw new IllegalArgumentException("无效的私钥", e);
} catch (BadPaddingException | IllegalBlockSizeException e) {
throw new BadPaddingException("解密失败");
}
}
/**
* 上传图片到微信服务器
* @param filePath
* @return
* @throws URISyntaxException
* @throws IOException
* @throws NotFoundException
* @throws GeneralSecurityException
* @throws HttpCodeException
*/
public static String upload(String localdoman,String filePath) throws URISyntaxException, IOException, NotFoundException, GeneralSecurityException, HttpCodeException {
if(localdoman.equals(filePath)){
return "";
}
final CloseableHttpClient httpClient = WechatPay.getHttpClient();
URI uri = new URI("https://api.mch.weixin.qq.com/v3/merchant/media/upload");
File file = new File(filePath);
String media_id = "";
try (FileInputStream ins1 = new FileInputStream(file)) {
String sha256 = DigestUtils.sha256Hex(ins1);
try (InputStream ins2 = new FileInputStream(file)) {
HttpPost request = new WechatPayUploadHttpPost.Builder(uri)
.withImage(file.getName(), sha256, ins2)
.build();
CloseableHttpResponse response = httpClient.execute(request);
String bodyAsString = EntityUtils.toString(response.getEntity());
JSONObject jsonObject = JSONObject.parseObject(bodyAsString);
if(jsonObject.containsKey("code")) {
System.out.println(jsonObject.getString("message"));
return "";
}
media_id = jsonObject.getString("media_id");
}
}
return media_id;
}
/**
* 获取微信HttpClient
* @return
*/
public static CloseableHttpClient getHttpClient() throws HttpCodeException, GeneralSecurityException, IOException, NotFoundException {
// 获取证书管理器实例
CertificatesManager certificatesManager = CertificatesManager.getInstance();
// 向证书管理器增加需要自动更新平台证书的商户信息
certificatesManager.putMerchant(merchantId, new WechatPay2Credentials(merchantId,
new PrivateKeySigner(merchantSerialNumber, merchantPrivateKey)), apiV3Key.getBytes(StandardCharsets.UTF_8));
// ... 若有多个商户号,可继续调用putMerchant添加商户信息
// 从证书管理器中获取verifier
Verifier verifier = certificatesManager.getVerifier(merchantId);
WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()
.withMerchant(merchantId, merchantSerialNumber, merchantPrivateKey)
.withValidator(new WechatPay2Validator(verifier))
.withWechatPay(wechatPayCertificates);
// ... 接下来,你仍然可以通过builder设置各种参数,来配置你的HttpClient
// 通过WechatPayHttpClientBuilder构造的HttpClient,会自动的处理签名和验签,并进行证书自动更新
//WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()
// .withMerchant(merchantId, merchantSerialNumber, merchantPrivateKey)
// .withWechatPay(wechatPayCertificates);
return builder.build();
}
}
3.组装接口数据
@AutoLog(value = "特约商户进件-申请")
@ApiOperation(value="特约商户进件-申请", notes="特约商户进件-申请")
@PostMapping(value = "/shopSend")
public Result<?> shopSend(@RequestBody String id) throws GeneralSecurityException, IOException, HttpCodeException, NotFoundException, URISyntaxException {
//WechatPay.upload(wxPayBean.getLocaldomain()+"");
//WechatPay.rsaEncryptOAEP("");//敏感信息加密
JSONObject jsonObject1 = JSONObject.parseObject(id);
String id1 = jsonObject1.getString("id");
ShopRegist shopRegist = shopRegistService.getById(id1);
//组装微信报文
//String uuid = UUID.randomUUID().toString().replaceAll("-", "").toLowerCase();
JSONObject rootNode = new JSONObject();//发送json
rootNode.put("business_code",shopRegist.getBusinessCode());//业务申请编号必填
//超级管理员信息
if("SUPER".equals(shopRegist.getContactType())){
JSONObject adminNodeSUPER = new JSONObject();
adminNodeSUPER.put("contact_type",shopRegist.getContactType());//超级管理员类型
adminNodeSUPER.put("contact_name",WechatPay.rsaEncryptOAEP(shopRegist.getContactName()));//超级管理员姓名
adminNodeSUPER.put("contact_id_doc_type",shopRegist.getContactIdDocType());//超级管理员证件类型
adminNodeSUPER.put("contact_id_number",WechatPay.rsaEncryptOAEP(shopRegist.getContactIdNumber()));//超级管理员身份证件号码
adminNodeSUPER.put("contact_id_doc_copy",WechatPay.upload(wxPayBean.getLocaldomain(),wxPayBean.getLocaldomain()+shopRegist.getContactIdDocCopy()));//超级管理员证件正面照片
adminNodeSUPER.put("contact_id_doc_copy_back",WechatPay.upload(wxPayBean.getLocaldomain(),wxPayBean.getLocaldomain()+shopRegist.getContactIdDocCopyBack()));//超级管理员证件反面照片
adminNodeSUPER.put("contact_period_begin", DateUtils.formatDate(shopRegist.getContactPeriodBegin(),"yyyy-MM-dd"));//超级管理员证件有效期开始时间
adminNodeSUPER.put("contact_period_end",DateUtils.formatDate(shopRegist.getContactPeriodEnd(),"yyyy-MM-dd")); //超级管理员证件有效期结束时间
adminNodeSUPER.put("business_authorization_letter",WechatPay.upload(wxPayBean.getLocaldomain(),wxPayBean.getLocaldomain()+shopRegist.getBusinessAuthorizationLetter()));//业务办理授权函
adminNodeSUPER.put("openid",shopRegist.getOpenid()==null?"":shopRegist.getOpenid());//超级管理员微信OpenID 可不填
adminNodeSUPER.put("mobile_phone",WechatPay.rsaEncryptOAEP(shopRegist.getMobilePhone()));//联系手机
adminNodeSUPER.put("contact_email",WechatPay.rsaEncryptOAEP(shopRegist.getContactEmail()));//联系邮箱
rootNode.put("contact_info",adminNodeSUPER);
}else{
JSONObject adminNodeLEGAL = new JSONObject();
adminNodeLEGAL.put("contact_type",shopRegist.getContactType());//超级管理员类型
adminNodeLEGAL.put("contact_name",WechatPay.rsaEncryptOAEP(shopRegist.getContactName()));//超级管理员姓名
adminNodeLEGAL.put("openid",shopRegist.getOpenid());//超级管理员微信OpenID 可不填
adminNodeLEGAL.put("mobile_phone",WechatPay.rsaEncryptOAEP(shopRegist.getMobilePhone()));//联系手机
adminNodeLEGAL.put("contact_email",WechatPay.rsaEncryptOAEP(shopRegist.getContactEmail()));//联系邮箱
rootNode.put("contact_info",adminNodeLEGAL);
}
//判断主体类型
String subjectType = shopRegist.getSubjectType();
JSONObject subjectNode = new JSONObject();
subjectNode.put("subject_type",shopRegist.getSubjectType());//超级管理员类型
subjectNode.put("finance_institution", "true".equals(shopRegist.getFinanceInstitution()));//是否是金融机构
//个体户
if("SUBJECT_TYPE_INDIVIDUAL".equals(subjectType)){
//营业执照 主体为个体户/企业,必填
JSONObject licenseNode = new JSONObject();
licenseNode.put("license_copy",WechatPay.upload(wxPayBean.getLocaldomain(),wxPayBean.getLocaldomain()+shopRegist.getLicenseCopy()));//营业执照照片 必填
licenseNode.put("license_number",shopRegist.getLicenseNumber());//注册号/统一社会信用代码 必填
licenseNode.put("merchant_name",shopRegist.getMerchantName());//商户名称 必填
licenseNode.put("legal_person",shopRegist.getLegalPerson());//个体户经营者/法人姓名 必填
licenseNode.put("license_address",shopRegist.getLicenseAddress());//注册地址 条件选填
licenseNode.put("period_begin",DateUtils.formatDate(shopRegist.getPeriodBegin(),"yyyy-MM-dd"));//有效期限开始日期 条件选填
licenseNode.put("period_end",DateUtils.formatDate(shopRegist.getPeriodEnd(),"yyyy-MM-dd"));//有效期限结束日期 条件选填
subjectNode.put("business_license_info",licenseNode);
//经营者/法人身份证件 必填
JSONObject identityNode = new JSONObject();
identityNode.put("id_holder_type",shopRegist.getIdHolderType());//证件持有人类型 条件选填 主体类型为政府机关、事业单位时选传:
//identityNode.put("owner","true".equals(shopRegist.getOwner()));//经营者/法人是否为受益人
if("LEGAL".equals(shopRegist.getIdHolderType())){
identityNode.put("id_doc_type",shopRegist.getIdDocType()); //证件类型 当证件持有人类型为法人时,填写。其他情况,无需上传。
}
if("SUPER".equals(shopRegist.getIdHolderType())){
identityNode.put("authorize_letter_copy",WechatPay.upload(wxPayBean.getLocaldomain(),wxPayBean.getLocaldomain()+shopRegist.getAuthorizeLetterCopy())); //法定代表人说明函 当证件持有人类型为经办人时,必须上传。其他情况,无需上传。
}
if("LEGAL".equals(shopRegist.getIdHolderType())&&"IDENTIFICATION_TYPE_IDCARD".equals(shopRegist.getIdDocType())){
JSONObject cardNode = new JSONObject();
//身份证信息 当证件持有人类型为经营者/法人且证件类型为“身份证”时填写。
cardNode.put("id_card_copy",WechatPay.upload(wxPayBean.getLocaldomain(),wxPayBean.getLocaldomain()+shopRegist.getIdCardCopy()));//身份证人像面照片
cardNode.put("id_card_national",WechatPay.upload(wxPayBean.getLocaldomain(),wxPayBean.getLocaldomain()+shopRegist.getIdCardNational()));//身份证国徽面照片
cardNode.put("id_card_name",WechatPay.rsaEncryptOAEP(shopRegist.getIdCardName()));//身份证姓名
cardNode.put("id_card_number",WechatPay.rsaEncryptOAEP(shopRegist.getIdCardNumber()));//身份证号码
cardNode.put("card_period_begin",DateUtils.formatDate(shopRegist.getCardPeriodBegin(),"yyyy-MM-dd"));//有效期限开始日期
cardNode.put("card_period_end",DateUtils.formatDate(shopRegist.getCardPeriodEnd(),"yyyy-MM-dd"));//有效期限结束日期
identityNode.put("id_card_info",cardNode);
}else{
//其他类型证件信息 当证件持有人类型为经营者/法人且证件类型不为“身份证”时填写。
JSONObject cardNode = new JSONObject();
cardNode.put("id_doc_copy",WechatPay.upload(wxPayBean.getLocaldomain(),wxPayBean.getLocaldomain()+shopRegist.getIdDocCopy()));//身份证人像面照片
cardNode.put("id_doc_copy_back",WechatPay.upload(wxPayBean.getLocaldomain(),wxPayBean.getLocaldomain()+shopRegist.getIdDocCopyBack()));//证件反面照片 1、若证件类型为往来通行证、外国人居留证、港澳居住证、台湾居住证时,上传证件反面照片。2、若证件类型为护照,无需上传反面照片
cardNode.put("id_doc_name",WechatPay.rsaEncryptOAEP(shopRegist.getIdDocName()));//证件姓名
cardNode.put("id_doc_number",WechatPay.rsaEncryptOAEP(shopRegist.getIdDocNumber()));//证件号码
cardNode.put("doc_period_begin",DateUtils.formatDate(shopRegist.getDocPeriodBegin(),"yyyy-MM-dd"));//有效期限开始日期
cardNode.put("doc_period_end",DateUtils.formatDate(shopRegist.getDocPeriodEnd(),"yyyy-MM-dd"));//有效期限结束日期
identityNode.put("id_doc_info",cardNode);
}
subjectNode.put("identity_info",identityNode);
}else if("SUBJECT_TYPE_ENTERPRISE".equals(subjectType)){//企业
//营业执照 主体为个体户/企业,必填
JSONObject licenseNode = new JSONObject();
licenseNode.put("license_copy",WechatPay.upload(wxPayBean.getLocaldomain(),wxPayBean.getLocaldomain()+shopRegist.getLicenseCopy()));//营业执照照片 必填
licenseNode.put("license_number",shopRegist.getLicenseNumber());//注册号/统一社会信用代码 必填
licenseNode.put("merchant_name",shopRegist.getMerchantName());//商户名称 必填
licenseNode.put("legal_person",shopRegist.getLegalPerson());//个体户经营者/法人姓名 必填
licenseNode.put("license_address",shopRegist.getLicenseAddress());//注册地址 条件选填
licenseNode.put("period_begin",DateUtils.formatDate(shopRegist.getPeriodBegin(),"yyyy-MM-dd"));//有效期限开始日期 条件选填
licenseNode.put("period_end",DateUtils.formatDate(shopRegist.getPeriodEnd(),"yyyy-MM-dd"));//有效期限结束日期 条件选填
subjectNode.put("business_license_info",licenseNode);
//最终受益人信息列表(UBO) 仅企业需要填写。
JSONArray jsonArray = new JSONArray();
JSONObject ownerNode = new JSONObject();
ownerNode.put("ubo_id_doc_type",shopRegist.getUboIdDocType());//证件类型
ownerNode.put("ubo_id_doc_copy",WechatPay.upload(wxPayBean.getLocaldomain(),wxPayBean.getLocaldomain()+shopRegist.getUboIdDocCopy()));//证件正面照片
ownerNode.put("ubo_id_doc_copy_back",WechatPay.upload(wxPayBean.getLocaldomain(),wxPayBean.getLocaldomain()+shopRegist.getUboIdDocCopyBack()));//证件反面照片 若证件类型为身份证,请上传国徽面照片。3、若证件类型为护照,无需上传反面照片。
ownerNode.put("ubo_id_doc_name",WechatPay.rsaEncryptOAEP(shopRegist.getUboIdDocName()));//证件姓名
ownerNode.put("ubo_id_doc_number",WechatPay.rsaEncryptOAEP(shopRegist.getUboIdDocNumber()));//证件号码
ownerNode.put("ubo_id_doc_address",WechatPay.rsaEncryptOAEP(shopRegist.getUboIdDocAddress()));//证件居住地址
ownerNode.put("ubo_period_begin",DateUtils.formatDate(shopRegist.getUboPeriodBegin(),"yyyy-MM-dd"));//有效期限开始日期
ownerNode.put("ubo_period_end",DateUtils.formatDate(shopRegist.getUboPeriodEnd(),"yyyy-MM-dd"));//有效期限结束日期
jsonArray.add(ownerNode);
subjectNode.put("ubo_info_list",jsonArray);
//经营者/法人身份证件 必填
JSONObject identityNode = new JSONObject();
identityNode.put("id_holder_type",shopRegist.getIdHolderType());//证件持有人类型 条件选填 主体类型为政府机关、事业单位时选传:
identityNode.put("owner","true".equals(shopRegist.getOwner()));//经营者/法人是否为受益人
if("LEGAL".equals(shopRegist.getIdHolderType())){
identityNode.put("id_doc_type",shopRegist.getIdDocType()); //证件类型 当证件持有人类型为法人时,填写。其他情况,无需上传。
}
if("SUPER".equals(shopRegist.getIdHolderType())){
identityNode.put("authorize_letter_copy",WechatPay.upload(wxPayBean.getLocaldomain(),wxPayBean.getLocaldomain()+shopRegist.getAuthorizeLetterCopy())); //法定代表人说明函 当证件持有人类型为经办人时,必须上传。其他情况,无需上传。
}
if("LEGAL".equals(shopRegist.getIdHolderType())&&"IDENTIFICATION_TYPE_IDCARD".equals(shopRegist.getIdDocType())){
JSONObject cardNode = new JSONObject();
//身份证信息 当证件持有人类型为经营者/法人且证件类型为“身份证”时填写。
cardNode.put("id_card_copy",WechatPay.upload(wxPayBean.getLocaldomain(),wxPayBean.getLocaldomain()+shopRegist.getIdCardCopy()));//身份证人像面照片
cardNode.put("id_card_national",WechatPay.upload(wxPayBean.getLocaldomain(),wxPayBean.getLocaldomain()+shopRegist.getIdCardNational()));//身份证国徽面照片
cardNode.put("id_card_name",WechatPay.rsaEncryptOAEP(shopRegist.getIdCardName()));//身份证姓名
cardNode.put("id_card_number",WechatPay.rsaEncryptOAEP(shopRegist.getIdCardNumber()));//身份证号码
//只有企业传
cardNode.put("id_card_address",WechatPay.rsaEncryptOAEP(shopRegist.getIdCardAddress()));//身份证居住地址 主体类型为企业时,需要填写。其他主体类型,无需上传。
cardNode.put("card_period_begin",DateUtils.formatDate(shopRegist.getCardPeriodBegin(),"yyyy-MM-dd"));//有效期限开始日期
cardNode.put("card_period_end",DateUtils.formatDate(shopRegist.getCardPeriodEnd(),"yyyy-MM-dd"));//有效期限结束日期
identityNode.put("id_card_info",cardNode);
}else{
//其他类型证件信息 当证件持有人类型为经营者/法人且证件类型不为“身份证”时填写。
JSONObject cardNode = new JSONObject();
cardNode.put("id_doc_copy",WechatPay.upload(wxPayBean.getLocaldomain(),wxPayBean.getLocaldomain()+shopRegist.getIdDocCopy()));//身份证人像面照片
cardNode.put("id_doc_copy_back",WechatPay.upload(wxPayBean.getLocaldomain(),wxPayBean.getLocaldomain()+shopRegist.getIdDocCopyBack()));//证件反面照片 1、若证件类型为往来通行证、外国人居留证、港澳居住证、台湾居住证时,上传证件反面照片。2、若证件类型为护照,无需上传反面照片
cardNode.put("id_doc_name",WechatPay.rsaEncryptOAEP(shopRegist.getIdDocName()));//证件姓名
cardNode.put("id_doc_number",WechatPay.rsaEncryptOAEP(shopRegist.getIdDocNumber()));//证件号码
cardNode.put("id_doc_address",WechatPay.rsaEncryptOAEP(shopRegist.getIdDocAddress()));//证件居住地址主体类型为企业时,需要填写。其他主体类型,无需上传
cardNode.put("doc_period_begin",DateUtils.formatDate(shopRegist.getDocPeriodBegin(),"yyyy-MM-dd"));//有效期限开始日期
cardNode.put("doc_period_end",DateUtils.formatDate(shopRegist.getDocPeriodEnd(),"yyyy-MM-dd"));//有效期限结束日期
identityNode.put("id_doc_info",cardNode);
}
subjectNode.put("identity_info",identityNode);
}else if("SUBJECT_TYPE_GOVERNMENT".equals(subjectType)){//政府
subjectNode.put("certificate_letter_copy",WechatPay.upload(wxPayBean.getLocaldomain(),wxPayBean.getLocaldomain()+shopRegist.getCertificateLetterCopy()));//单位证明函照片 主体类型为政府机关、事业单位选传
//登记证书 主体为政府机关/事业单位/其他组织时,必填。
JSONObject certNode = new JSONObject();
certNode.put("cert_copy",WechatPay.upload(wxPayBean.getLocaldomain(),wxPayBean.getLocaldomain()+shopRegist.getCertCopy()));//营业执照照片 必填
certNode.put("cert_type",shopRegist.getCertType());//登记证书类型
certNode.put("cert_number",shopRegist.getCertNumber());//证书号
certNode.put("merchant_name",shopRegist.getMerchantName2());//商户名称
certNode.put("company_address",shopRegist.getCompanyAddress());//注册地址
certNode.put("legal_person",shopRegist.getLegalPerson2());//法定代表人
certNode.put("period_begin",DateUtils.formatDate(shopRegist.getPeriodBegin2(),"yyyy-MM-dd"));//有效期限开始日期
certNode.put("period_end",DateUtils.formatDate(shopRegist.getPeriodEnd2(),"yyyy-MM-dd"));//有效期限结束日期
subjectNode.put("certificate_info",certNode);
//经营者/法人身份证件 必填
JSONObject identityNode = new JSONObject();
identityNode.put("id_holder_type",shopRegist.getIdHolderType());//证件持有人类型 条件选填 主体类型为政府机关、事业单位时选传:
//identityNode.put("owner","true".equals(shopRegist.getOwner()));//经营者/法人是否为受益人
if("LEGAL".equals(shopRegist.getIdHolderType())){
identityNode.put("id_doc_type",shopRegist.getIdDocType()); //证件类型 当证件持有人类型为法人时,填写。其他情况,无需上传。
}
if("SUPER".equals(shopRegist.getIdHolderType())){
identityNode.put("authorize_letter_copy",WechatPay.upload(wxPayBean.getLocaldomain(),wxPayBean.getLocaldomain()+shopRegist.getAuthorizeLetterCopy())); //法定代表人说明函 当证件持有人类型为经办人时,必须上传。其他情况,无需上传。
}
if("LEGAL".equals(shopRegist.getIdHolderType())&&"IDENTIFICATION_TYPE_IDCARD".equals(shopRegist.getIdDocType())){
JSONObject cardNode = new JSONObject();
//身份证信息 当证件持有人类型为经营者/法人且证件类型为“身份证”时填写。
cardNode.put("id_card_copy",WechatPay.upload(wxPayBean.getLocaldomain(),wxPayBean.getLocaldomain()+shopRegist.getIdCardCopy()));//身份证人像面照片
cardNode.put("id_card_national",WechatPay.upload(wxPayBean.getLocaldomain(),wxPayBean.getLocaldomain()+shopRegist.getIdCardNational()));//身份证国徽面照片
cardNode.put("id_card_name",WechatPay.rsaEncryptOAEP(shopRegist.getIdCardName()));
//身份证姓名
cardNode.put("id_card_number",WechatPay.rsaEncryptOAEP(shopRegist.getIdCardNumber()));//身份证号码
cardNode.put("card_period_begin",DateUtils.formatDate(shopRegist.getCardPeriodBegin(),"yyyy-MM-dd"));//有效期限开始日期
cardNode.put("card_period_end",DateUtils.formatDate(shopRegist.getCardPeriodEnd(),"yyyy-MM-dd"));//有效期限结束日期
identityNode.put("id_card_info",cardNode);
}else{
//其他类型证件信息 当证件持有人类型为经营者/法人且证件类型不为“身份证”时填写。
JSONObject cardNode = new JSONObject();
cardNode.put("id_doc_copy",WechatPay.upload(wxPayBean.getLocaldomain(),wxPayBean.getLocaldomain()+shopRegist.getIdDocCopy()));//身份证人像面照片
cardNode.put("id_doc_copy_back",WechatPay.upload(wxPayBean.getLocaldomain(),wxPayBean.getLocaldomain()+shopRegist.getIdDocCopyBack()));//证件反面照片 1、若证件类型为往来通行证、外国人居留证、港澳居住证、台湾居住证时,上传证件反面照片。2、若证件类型为护照,无需上传反面照片
cardNode.put("id_doc_name",WechatPay.rsaEncryptOAEP(shopRegist.getIdDocName()));//证件姓名
cardNode.put("id_doc_number",WechatPay.rsaEncryptOAEP(shopRegist.getIdDocNumber()));//证件号码
cardNode.put("doc_period_begin",DateUtils.formatDate(shopRegist.getDocPeriodBegin(),"yyyy-MM-dd"));//有效期限开始日期
cardNode.put("doc_period_end",DateUtils.formatDate(shopRegist.getDocPeriodEnd(),"yyyy-MM-dd"));//有效期限结束日期
identityNode.put("id_doc_info",cardNode);
}
subjectNode.put("identity_info",identityNode);
}else if("SUBJECT_TYPE_INSTITUTIONS".equals(subjectType)){//事业单位
subjectNode.put("certificate_letter_copy",WechatPay.upload(wxPayBean.getLocaldomain(),wxPayBean.getLocaldomain()+shopRegist.getCertificateLetterCopy()));//单位证明函照片 主体类型为政府机关、事业单位选传
//登记证书 主体为政府机关/事业单位/其他组织时,必填。
JSONObject certNode = new JSONObject();
certNode.put("cert_copy",WechatPay.upload(wxPayBean.getLocaldomain(),wxPayBean.getLocaldomain()+shopRegist.getCertCopy()));//营业执照照片 必填
certNode.put("cert_type",shopRegist.getCertType());//登记证书类型
certNode.put("cert_number",shopRegist.getCertNumber());//证书号
certNode.put("merchant_name",shopRegist.getMerchantName2());//商户名称
certNode.put("company_address",shopRegist.getCompanyAddress());//注册地址
certNode.put("legal_person",shopRegist.getLegalPerson2());//法定代表人
certNode.put("period_begin",DateUtils.formatDate(shopRegist.getPeriodBegin2(),"yyyy-MM-dd"));//有效期限开始日期
certNode.put("period_end",DateUtils.formatDate(shopRegist.getPeriodEnd2(),"yyyy-MM-dd"));//有效期限结束日期
subjectNode.put("certificate_info",certNode);
//经营者/法人身份证件 必填
JSONObject identityNode = new JSONObject();
identityNode.put("id_holder_type",shopRegist.getIdHolderType());//证件持有人类型 条件选填 主体类型为政府机关、事业单位时选传:
//identityNode.put("owner","true".equals(shopRegist.getOwner()));//经营者/法人是否为受益人
if("LEGAL".equals(shopRegist.getIdHolderType())){
identityNode.put("id_doc_type",shopRegist.getIdDocType()); //证件类型 当证件持有人类型为法人时,填写。其他情况,无需上传。
}
if("SUPER".equals(shopRegist.getIdHolderType())){
identityNode.put("authorize_letter_copy",WechatPay.upload(wxPayBean.getLocaldomain(),wxPayBean.getLocaldomain()+shopRegist.getAuthorizeLetterCopy())); //法定代表人说明函 当证件持有人类型为经办人时,必须上传。其他情况,无需上传。
}
if("LEGAL".equals(shopRegist.getIdHolderType())&&"IDENTIFICATION_TYPE_IDCARD".equals(shopRegist.getIdDocType())){
JSONObject cardNode = new JSONObject();
//身份证信息 当证件持有人类型为经营者/法人且证件类型为“身份证”时填写。
cardNode.put("id_card_copy",WechatPay.upload(wxPayBean.getLocaldomain(),wxPayBean.getLocaldomain()+shopRegist.getIdCardCopy()));//身份证人像面照片
cardNode.put("id_card_national",WechatPay.upload(wxPayBean.getLocaldomain(),wxPayBean.getLocaldomain()+shopRegist.getIdCardNational()));//身份证国徽面照片
cardNode.put("id_card_name",WechatPay.rsaEncryptOAEP(shopRegist.getIdCardName()));//身份证姓名
cardNode.put("id_card_number",WechatPay.rsaEncryptOAEP(shopRegist.getIdCardNumber()));//身份证号码
cardNode.put("card_period_begin",DateUtils.formatDate(shopRegist.getCardPeriodBegin(),"yyyy-MM-dd"));//有效期限开始日期
cardNode.put("card_period_end",DateUtils.formatDate(shopRegist.getCardPeriodEnd(),"yyyy-MM-dd"));//有效期限结束日期
identityNode.put("id_card_info",cardNode);
}else{
//其他类型证件信息 当证件持有人类型为经营者/法人且证件类型不为“身份证”时填写。
JSONObject cardNode = new JSONObject();
cardNode.put("id_doc_copy",WechatPay.upload(wxPayBean.getLocaldomain(),wxPayBean.getLocaldomain()+shopRegist.getIdDocCopy()));//身份证人像面照片
cardNode.put("id_doc_copy_back",WechatPay.upload(wxPayBean.getLocaldomain(),wxPayBean.getLocaldomain()+shopRegist.getIdDocCopyBack()));//证件反面照片 1、若证件类型为往来通行证、外国人居留证、港澳居住证、台湾居住证时,上传证件反面照片。2、若证件类型为护照,无需上传反面照片
cardNode.put("id_doc_name",WechatPay.rsaEncryptOAEP(shopRegist.getIdDocName()));//证件姓名
cardNode.put("id_doc_number",WechatPay.rsaEncryptOAEP(shopRegist.getIdDocNumber()));//证件号码
cardNode.put("doc_period_begin",DateUtils.formatDate(shopRegist.getDocPeriodBegin(),"yyyy-MM-dd"));//有效期限开始日期
cardNode.put("doc_period_end",DateUtils.formatDate(shopRegist.getDocPeriodEnd(),"yyyy-MM-dd"));//有效期限结束日期
identityNode.put("id_doc_info",cardNode);
}
subjectNode.put("identity_info",identityNode);
}else{//社会组织
//登记证书 主体为政府机关/事业单位/其他组织时,必填。
JSONObject certNode = new JSONObject();
certNode.put("cert_copy",shopRegist.getCertCopy());//营业执照照片 必填
certNode.put("cert_type",shopRegist.getCertType());//登记证书类型
certNode.put("cert_number",shopRegist.getCertNumber());//证书号
certNode.put("merchant_name",shopRegist.getMerchantName2());//商户名称
certNode.put("company_address",shopRegist.getCompanyAddress());//注册地址
certNode.put("legal_person",shopRegist.getLegalPerson2());//法定代表人
certNode.put("period_begin",DateUtils.formatDate(shopRegist.getPeriodBegin2(),"yyyy-MM-dd"));//有效期限开始日期
certNode.put("period_end",DateUtils.formatDate(shopRegist.getPeriodEnd2(),"yyyy-MM-dd"));//有效期限结束日期
subjectNode.put("certificate_info",certNode);
//经营者/法人身份证件 必填
JSONObject identityNode = new JSONObject();
identityNode.put("id_holder_type",shopRegist.getIdHolderType());//证件持有人类型 条件选填 主体类型为政府机关、事业单位时选传:
//identityNode.put("owner","true".equals(shopRegist.getOwner()));//经营者/法人是否为受益人
if("LEGAL".equals(shopRegist.getIdHolderType())){
identityNode.put("id_doc_type",shopRegist.getIdDocType()); //证件类型 当证件持有人类型为法人时,填写。其他情况,无需上传。
}
if("SUPER".equals(shopRegist.getIdHolderType())){
identityNode.put("authorize_letter_copy",WechatPay.upload(wxPayBean.getLocaldomain(),wxPayBean.getLocaldomain()+shopRegist.getAuthorizeLetterCopy())); //法定代表人说明函 当证件持有人类型为经办人时,必须上传。其他情况,无需上传。
}
if("LEGAL".equals(shopRegist.getIdHolderType())&&"IDENTIFICATION_TYPE_IDCARD".equals(shopRegist.getIdDocType())){
JSONObject cardNode = new JSONObject();
//身份证信息 当证件持有人类型为经营者/法人且证件类型为“身份证”时填写。
cardNode.put("id_card_copy",WechatPay.upload(wxPayBean.getLocaldomain(),wxPayBean.getLocaldomain()+shopRegist.getIdCardCopy()));//身份证人像面照片
cardNode.put("id_card_national",WechatPay.upload(wxPayBean.getLocaldomain(),wxPayBean.getLocaldomain()+shopRegist.getIdCardNational()));//身份证国徽面照片
cardNode.put("id_card_name",WechatPay.rsaEncryptOAEP(shopRegist.getIdCardName()));//身份证姓名
cardNode.put("id_card_number",WechatPay.rsaEncryptOAEP(shopRegist.getIdCardNumber()));//身份证号码
cardNode.put("card_period_begin",DateUtils.formatDate(shopRegist.getCardPeriodBegin(),"yyyy-MM-dd"));//有效期限开始日期
cardNode.put("card_period_end",DateUtils.formatDate(shopRegist.getCardPeriodEnd(),"yyyy-MM-dd"));//有效期限结束日期
identityNode.put("id_card_info",cardNode);
}else{
//其他类型证件信息 当证件持有人类型为经营者/法人且证件类型不为“身份证”时填写。
JSONObject cardNode = new JSONObject();
cardNode.put("id_doc_copy",WechatPay.upload(wxPayBean.getLocaldomain(),wxPayBean.getLocaldomain()+shopRegist.getIdDocCopy()));//身份证人像面照片
cardNode.put("id_doc_copy_back",WechatPay.upload(wxPayBean.getLocaldomain(),wxPayBean.getLocaldomain()+shopRegist.getIdDocCopyBack()));//证件反面照片 1、若证件类型为往来通行证、外国人居留证、港澳居住证、台湾居住证时,上传证件反面照片。2、若证件类型为护照,无需上传反面照片
cardNode.put("id_doc_name",WechatPay.rsaEncryptOAEP(shopRegist.getIdDocName()));//证件姓名
cardNode.put("id_doc_number",WechatPay.rsaEncryptOAEP(shopRegist.getIdDocNumber()));//证件号码
cardNode.put("doc_period_begin",DateUtils.formatDate(shopRegist.getDocPeriodBegin(),"yyyy-MM-dd"));//有效期限开始日期
cardNode.put("doc_period_end",DateUtils.formatDate(shopRegist.getDocPeriodEnd(),"yyyy-MM-dd"));//有效期限结束日期
identityNode.put("id_doc_info",cardNode);
}
subjectNode.put("identity_info",identityNode);
}
//是否是金融机构
if("true".equals(shopRegist.getFinanceInstitution())){
//金融机构许可证信息 当主体是金融机构时
JSONObject jrNode = new JSONObject();
jrNode.put("finance_type",shopRegist.getFinanceType());//金融机构类型 必填
List<String> list = Arrays.asList(shopRegist.getFinanceLicensePics().split(","));
List<String> imageIds = new ArrayList<>();
for(String str : list){
imageIds.add(WechatPay.upload(wxPayBean.getLocaldomain(),wxPayBean.getLocaldomain()+str));
}
jrNode.put("finance_license_pics",imageIds);//金融机构许可证图片 数组
subjectNode.put("finance_institution_info",jrNode);
}
//主体信息
rootNode.put("subject_info",subjectNode);
//经营资料
JSONObject saleNode = new JSONObject();
saleNode.put("merchant_shortname",shopRegist.getMerchantShortname());//商户简称
saleNode.put("service_phone",shopRegist.getServicePhone());//客服电话
//经营场景
JSONObject weixinNode = new JSONObject();
weixinNode.put("sales_scenes_type",Arrays.asList(shopRegist.getSalesScenesType().split(",")));//经营场景类型
//小程序
JSONObject xiaochengxuNode = new JSONObject();
xiaochengxuNode.put("mini_program_appid",shopRegist.getMiniProgramAppid());//服务商小程序APPID
List<String> list = Arrays.asList(shopRegist.getMiniProgramPics().split(","));
List<String> imageIds = new ArrayList<>();
for(String str : list){
imageIds.add(WechatPay.upload(wxPayBean.getLocaldomain(),wxPayBean.getLocaldomain()+str));
}
xiaochengxuNode.put("mini_program_pics",imageIds);//小程序截图
weixinNode.put("mini_program_info",xiaochengxuNode);//小程序场景
saleNode.put("sales_info",weixinNode);
rootNode.put("business_info",saleNode);
//结算规则
JSONObject ruleNode = new JSONObject();
ruleNode.put("settlement_id",shopRegist.getSettlementId());//入驻结算规则ID
ruleNode.put("qualification_type",shopRegist.getQualificationType());//所属行业
List<String> list1 = Arrays.asList(shopRegist.getQualifications().split(","));
List<String> imageIdss = new ArrayList<>();
for(String str : list1){
imageIdss.add(WechatPay.upload(wxPayBean.getLocaldomain(),wxPayBean.getLocaldomain()+str));
}
ruleNode.put("qualifications",imageIdss);//特殊资质图片
ruleNode.put("activities_id",shopRegist.getActivitiesId());//优惠费率活动ID
ruleNode.put("activities_rate",shopRegist.getActivitiesRate());//优惠费率活动值
rootNode.put("settlement_info",ruleNode);
//结算银行账户
JSONObject bankNode = new JSONObject();
bankNode.put("bank_account_type",shopRegist.getBankAccountType());//账户类型
bankNode.put("account_name",WechatPay.rsaEncryptOAEP(shopRegist.getAccountName()));//开户名称
bankNode.put("account_bank",shopRegist.getAccountBank());//开户银行
bankNode.put("bank_address_code",shopRegist.getBankAddressCode());//开户银行省市编码
bankNode.put("bank_branch_id",shopRegist.getBankBranchId());//开户银行联行号二选一
bankNode.put("bank_name",shopRegist.getBankName());//开户银行全称(含支行)二选一
bankNode.put("account_number",WechatPay.rsaEncryptOAEP(shopRegist.getAccountNumber()));//银行账号
rootNode.put("bank_account_info",bankNode);
CloseableHttpClient httpClient = WechatPay.getHttpClient();
HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/applyment4sub/applyment/");
httpPost.addHeader("Accept", "application/json");
httpPost.addHeader("Content-type","application/json; charset=utf-8");
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.writeValue(bos, rootNode);
httpPost.setEntity(new StringEntity(bos.toString("UTF-8"), "UTF-8"));
CloseableHttpResponse response = httpClient.execute(httpPost);
String bodyAsString = EntityUtils.toString(response.getEntity());
System.out.println("返回数据"+bodyAsString);
JSONObject jsonObject = JSONObject.parseObject(bodyAsString);
String applyment_id = jsonObject.getString("applyment_id");//查询申请状态用
shopRegist.setApplymentId(applyment_id);
shopRegist.setShopStatus("APPLYMENT_STATE_EDITTING");
shopRegistService.updateById(shopRegist);
if(jsonObject.containsKey("code")) {
System.out.println(jsonObject.getString("message"));
return Result.error(jsonObject.getString("message"));
}
return Result.OK();
}
4.查询申请状态
@AutoLog(value = "特约商户进件-查询申请状态")
@ApiOperation(value="特约商户进件-查询申请状态", notes="特约商户进件-查询申请状态")
@PostMapping(value = "/searchApply")
public Result<?> searchApply(@RequestBody String id) throws GeneralSecurityException, IOException, NotFoundException, HttpCodeException {
JSONObject jsonObject1 = JSONObject.parseObject(id);
String id1 = jsonObject1.getString("id");
ShopRegist shopRegist = shopRegistService.getById(id1);
CloseableHttpClient httpClient = WechatPay.getHttpClient();
HttpGet httpGet = new HttpGet("https://api.mch.weixin.qq.com/v3/applyment4sub/applyment/applyment_id/"+shopRegist.getApplymentId());
httpGet.addHeader("Accept", "application/json");
CloseableHttpResponse response = httpClient.execute(httpGet);
String bodyAsString = EntityUtils.toString(response.getEntity());
JSONObject jsonObject = JSONObject.parseObject(bodyAsString);
String business_code = jsonObject.getString("business_code");
String applyment_state = jsonObject.getString("applyment_state");
String applyment_state_msg = jsonObject.getString("applyment_state_msg");
if("APPLYMENT_STATE_CANCELED".equals(applyment_state)){
return Result.error(applyment_state_msg);
}
if("APPLYMENT_STATE_EDITTING".equals(applyment_state)){
return Result.error(applyment_state_msg);
}
if("APPLYMENT_STATE_AUDITING".equals(applyment_state)){
return Result.error(applyment_state_msg+"--签约连接"+jsonObject.getString("sign_url"));
}
if("APPLYMENT_STATE_TO_BE_CONFIRMED".equals(applyment_state)){
return Result.error(applyment_state_msg+"--签约连接"+jsonObject.getString("sign_url"));
}
if("APPLYMENT_STATE_TO_BE_SIGNED".equals(applyment_state)){
return Result.error(applyment_state_msg+"--签约连接"+jsonObject.getString("sign_url"));
}
//驳回
if("APPLYMENT_STATE_REJECTED".equals(applyment_state)){
//组装驳回原因
JSONArray audit_detail = jsonObject.getJSONArray("audit_detail");
for(int i = 0;i<audit_detail.size();i++){
JSONObject jsonObject2 = audit_detail.getJSONObject(i);
System.out.println("jsonObject2 = " + jsonObject2);
}
return Result.error(applyment_state_msg);
}
shopRegist.setShopStatus(applyment_state);
shopRegist.setSearchErrInfo(bodyAsString);
shopRegistService.updateById(shopRegist);
if("APPLYMENT_STATE_FINISHED".equals(applyment_state)){
//创建新的商户信息
SxzBreakfastShop shop = new SxzBreakfastShop();
shop.setAddress(shopRegist.getCompanyAddress());
shop.setDelFlag("0");
shop.setName(shopRegist.getMerchantName());
shop.setPeople(shopRegist.getLegalPerson());
shop.setPhone(shopRegist.getMobilePhone());
shop.setStatus("1");
shop.setWxRate(new BigDecimal(shopRegist.getActivitiesRate()));
int count = sxzBreakfastShopService.count(new LambdaQueryWrapper<SxzBreakfastShop>()
.eq(SxzBreakfastShop::getDelFlag, "0")
.eq(SxzBreakfastShop::getPeople, shop.getPeople())
.eq(SxzBreakfastShop::getPhone, shop.getPhone())
);
if(count==0){
sxzBreakfastShopService.save(shop);
}
}
return Result.OK(applyment_state_msg);
}