Java微信小微商户进件,已经解决接口暂无权限,稍后再试的问题

我们先来讲小微商户进件
图片上传教程

官方文档:
https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/tool/applyment/chapter3_1.shtml

在这里插入图片描述
文档也说了“特约商户进件”文档和小微商户是同一接口,不同的请求参数
当然下文也会给大家特约商户的教程

代码实现

控制层

@ApiOperation(value = "小微商户微信进件", notes = "小微商户")
    @PostMapping("/wx/into")
    public Result addWxInto(@Valid @RequestBody WxIntoVo intoVo) {
        try {
            String contactName = intoVo.getContactName(); // 超级管理员姓名
            String contactIdNum = intoVo.getContactIdNum(); // 身份证号码
            String contactMobile = intoVo.getContactMobile(); // 手机号码
            String contactMail = intoVo.getContactMail(); // 联系邮箱 作者qq1023732997不会的呼叫
            String microName = intoVo.getMicroName(); // 门店名称(也用于简称)

            // 门店省市编码
            // 参考:https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/ecommerce/applyments/chapter4_1.shtml
            String microAddressCode = intoVo.getMicroAddressCode();
            String microAddress = intoVo.getMicroAddress(); // 门店地址

            String idCardCopy = intoVo.getIdCardCopy(); // 身份证正面照
            String idCardNational = intoVo.getIdCardNational(); // 身份证反面照

            String cardPeriodBegin = intoVo.getCardPeriodBegin(); // 身份证有效期开始时间2018-10-23
            String cardPeriodEnd = intoVo.getCardPeriodEnd();// 身份证有效期结束时间2011-06-24
            String servicePhone = intoVo.getServicePhone();// 客服电话; 无特殊使用管理员手机号码
            String accountBank = intoVo.getAccountBank(); // 开户银行
            String bankAddressCode = intoVo.getBankAddressCode(); // 开户银行省市编码至少精确到市,详细参见《省市区编号对照表》 示例值:110000;

            // 1、“开户银行”为17家直连银行无需填写 作者qq:1023732997 不懂的加我
            // 2、“开户银行”为其他银行,则开户银行全称(含支行)和开户银行联行号二选一
            // 3、需填写银行全称,如"深圳农村商业银行XXX支行",详细参见《开户银行全称(含支行)对照表》
            // 示例值:昆明市西山区西山支行
            String bankName = intoVo.getBankName(); // 开户银行全称(含支行]
            String accountNumber = intoVo.getAccountNumber(); // 银行账号
            ApplymentBo t = new ApplymentBo();
            String str = t.exe(contactName, contactIdNum, contactMobile, contactMail, microName, microAddressCode, microAddress, idCardCopy, idCardNational,
                    cardPeriodBegin, cardPeriodEnd, servicePhone, accountBank, bankAddressCode, bankName, accountNumber);
            return Result.success(str);
        } catch (Exception e) {
            log.error("系统出错:{}", e);
            return Result.fail("系统出错");
        }
    }

WxIntoVo类

package com.shifen.manager.vo;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

@ApiModel(value = "进件信息")
@Data
public class WxIntoVo {
    @ApiModelProperty(value = "超级管理员姓名")
    private String contactName;

    @ApiModelProperty(value = "身份证号码")
    private String contactIdNum;

    @ApiModelProperty(value = "手机号码")
    private String contactMobile;

    @ApiModelProperty(value = "联系邮箱")
    private String contactMail;

    @ApiModelProperty(value = "门店名称(也用于简称)")
    private String microName;

    // 门店省市编码
    // 参考:https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/ecommerce/applyments/chapter4_1.shtml
    @ApiModelProperty(value = "门店省市编码")
    private String microAddressCode;

    @ApiModelProperty(value = "门店地址")
    private String microAddress;

    @ApiModelProperty(value = "身份证正面照")
    private String idCardCopy;

    @ApiModelProperty(value = "身份证反面照")
    private String idCardNational;

    @ApiModelProperty(value = "身份证有效期开始时间2018-10-23")
    private String cardPeriodBegin;

    @ApiModelProperty(value = "身份证有效期结束时间2038-10-23")
    private String cardPeriodEnd;

    @ApiModelProperty(value = "客服电话; 无特殊使用管理员手机号码")
    private String servicePhone;

    @ApiModelProperty(value = "开户银行")
    private String accountBank;

    @ApiModelProperty(value = "开户银行省市编码至少精确到市,详细参见《省市区编号对照表》 示例值:110000;")
    private String bankAddressCode;

    // 1、“开户银行”为17家直连银行无需填写
    // 2、“开户银行”为其他银行,则开户银行全称(含支行)和开户银行联行号二选一
    // 3、需填写银行全称,如"深圳农村商业银行XXX支行",详细参见《开户银行全称(含支行)对照表》
    // 示例值:施秉县农村信用合作联社城关信用社

    @ApiModelProperty(value = "开户银行全称(含支行]")
    private String bankName;

    @ApiModelProperty(value = " 银行账号")
    private String accountNumber;
}

ApplymentBo类

/**
     * 进件
     *
     * @param contactName      管理员姓名
     * @param contactIdNum     管理员身份证号码
     * @param contactMobile    管理员手机号码
     * @param contactMail      管理员邮箱
     * @param microName        门店名称
     * @param microAddressCode 门店编码,参考:https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/ecommerce/applyments/chapter4_1.shtml
     * @param microAddress     门店地址
     * @param idCardCopy       身份证正面照片
     * @param idCardNational   身份证反面照片
     * @param cardPeriodBegin  身份证有效期开始时间,格式:2011-06-24
     * @param cardPeriodEnd    身份证有效期结束时间,格式:2011-06-24
     * @param servicePhone     客户电话
     * @param accountBank      开户行银行名称
     * @param bankAddressCode  开户行编码
     * @param bankName         开户银行全称(含支行] <pre>
     *                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         1、“开户银行”为17家直连银行无需填写
     *                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         2、“开户银行”为其他银行,则开户银行全称(含支行)和开户银行联行号二选一 //
     *                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         3、需填写银行全称,如"深圳农村商业银行XXX支行",详细参见《开户银行全称(含支行)对照表》
     *                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         示例值:施秉县农村信用合作联社城关信用社
     *                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         </pre>
     * @param accountNumber    银行卡号
     * @throws Exception
     */
    public String exe(String contactName, String contactIdNum, String contactMobile, String contactMail, String microName, String microAddressCode,
                      String microAddress, String idCardCopy, String idCardNational, String cardPeriodBegin, String cardPeriodEnd, String servicePhone,
                      String accountBank, String bankAddressCode, String bankName, String accountNumber) throws Exception {

        // 获取微信平台证书 并解析方法在后面
        String certString = CertUtil.getCertStr();
        ByteArrayInputStream stringStream = new ByteArrayInputStream(certString.getBytes());
        // 下面所有加密参数需要的对象
        X509Certificate certx = PemUtil.loadCertificate(stringStream);

        // 超级管理员信息
        Map<String, Object> contact_info = new HashMap<String, Object>();
        String contact_name = RsaEncryptUtil.rsaEncryptOAEP(contactName, certx); // 超级管理员姓名
        String contact_id_number = RsaEncryptUtil.rsaEncryptOAEP(contactIdNum, certx); // 超级管理员身份证件号码
        String mobile_phone = RsaEncryptUtil.rsaEncryptOAEP(contactMobile, certx);// 联系手机
        String contact_email = RsaEncryptUtil.rsaEncryptOAEP(contactMail, certx);// 联系邮箱
        contact_info.put("contact_name", contact_name);
        contact_info.put("contact_id_number", contact_id_number);
        contact_info.put("mobile_phone", mobile_phone);
        contact_info.put("contact_email", contact_email);

        // 主体资料
        String subject_type = "SUBJECT_TYPE_INDIVIDUAL"; // 主体类型
        String micro_biz_type = "MICRO_TYPE_STORE"; // 小微经营类型
        String micro_name = microName; // 门店名称
        String micro_address_code = microAddressCode; // 门店省市编码
        String micro_address = microAddress; // 门店街道名称

        String store_entrance_pic = ""; // 门店门口照片 图片上传接口获取
        String micro_indoor_copy = ""; // 店内环境照片 图片上传接口获取

        // 证件类型,IDENTIFICATION_TYPE_IDCARD
        String id_doc_type = "IDENTIFICATION_TYPE_IDCARD";
        
        String id_card_name = RsaEncryptUtil.rsaEncryptOAEP(contactName, certx); // 身份证姓名
        String id_card_number = RsaEncryptUtil.rsaEncryptOAEP(contactIdNum, certx); // 身份证号码
        // String card_period_begin = "2011-06-24"; // 身份证有效期开始时间示例值:2026-06-06
        // String card_period_end = "2021-06-24"; // 身份证有效期结束时间示例值:2026-06-06

        Map<String, Object> subject_info = new HashMap<String, Object>(); // 主体资料
        Map<String, Object> micro_biz_info = new HashMap<String, Object>(); // 小微商户辅助材料
        Map<String, Object> micro_store_info = new HashMap<String, Object>(); // 门店场所信息
        Map<String, Object> identity_info = new HashMap<String, Object>(); // 经营者身份证件
        Map<String, Object> id_card_info = new HashMap<String, Object>(); // 身份证信息

        micro_store_info.put("micro_name", micro_name);
        micro_store_info.put("micro_address_code", micro_address_code);
        micro_store_info.put("micro_address", micro_address);
        micro_store_info.put("store_entrance_pic", store_entrance_pic);
        micro_store_info.put("micro_indoor_copy", micro_indoor_copy);

        micro_biz_info.put("micro_biz_type", micro_biz_type);
        micro_biz_info.put("micro_store_info", micro_store_info);

        id_card_info.put("id_card_copy", idCardCopy);
        id_card_info.put("id_card_national", idCardNational);
        id_card_info.put("id_card_name", id_card_name);
        id_card_info.put("id_card_number", id_card_number);
        id_card_info.put("card_period_begin", cardPeriodBegin);
        id_card_info.put("card_period_end", cardPeriodEnd);

        identity_info.put("id_doc_type", id_doc_type);
        identity_info.put("id_card_info", id_card_info);

        subject_info.put("subject_type", subject_type);
        subject_info.put("micro_biz_info", micro_biz_info);
        subject_info.put("identity_info", identity_info);

        // 经营资料
        // String merchant_shortname = "张三停车场"; // 商户简称
        // String service_phone = "0755222222"; // 客服电话
        Map<String, Object> business_info = new HashMap<String, Object>();
        business_info.put("merchant_shortname", microName);
        business_info.put("service_phone", servicePhone);

        // 结算规则
        // 入驻结算规则ID;请选择结算规则ID,详细参见《费率结算规则对照表》 示例值:小微商户:703
        String settlement_id = "716";//
        String qualification_type = "电竞酒店"; // 所属行业;请填写所属行业名称,建议参见《费率结算规则对照表》 示例值:餐饮
        Map<String, Object> settlement_info = new HashMap<String, Object>();
        settlement_info.put("settlement_id", settlement_id);
        settlement_info.put("qualification_type", qualification_type);

        // 收款银行卡
        // 账户类型 若主体为小微,可填写:经营者个人银行卡 枚举值:
        // BANK_ACCOUNT_TYPE_PERSONAL:经营者个人银行卡
        // 示例值:BANK_ACCOUNT_TYPE_CORPORATE
        String bank_account_type = "BANK_ACCOUNT_TYPE_PERSONAL";

        String account_name = RsaEncryptUtil.rsaEncryptOAEP(contactName, certx); // 开户名称(该字段需进行加密处理)
        // String account_bank = "建设银行"; // 开户银行开户银行,详细参见《开户银行对照表》 示例值:工商银行
        // String bank_address_code = "440300"; // 开户银行省市编码至少精确到市,详细参见《省市区编号对照表》 示例值:110000

        // 1、“开户银行”为17家直连银行无需填写
        // 2、“开户银行”为其他银行,则开户银行全称(含支行)和开户银行联行号二选一
        // 3、需填写银行全称,如"深圳农村商业银行XXX支行",详细参见《开户银行全称(含支行)对照表》
        // 示例值:施秉县农村信用合作联社城关信用社
        // String bank_name = ""; // 开户银行全称(含支行]
        String account_number = RsaEncryptUtil.rsaEncryptOAEP(accountNumber, certx); // 银行账号(该字段需进行加密处理)
        Map<String, Object> bank_account_info = new HashMap<String, Object>();
        bank_account_info.put("bank_account_type", bank_account_type);
        bank_account_info.put("account_name", account_name);
        bank_account_info.put("account_bank", accountBank);
        bank_account_info.put("bank_address_code", bankAddressCode);
        bank_account_info.put("bank_name", bankName);
        bank_account_info.put("account_number", account_number);

        String business_code = OrderIdUtils.getGoodsOrderId(); // 申请单号
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("business_code", business_code);
        map.put("contact_info", contact_info);
        map.put("subject_info", subject_info);
        map.put("business_info", business_info);
        map.put("settlement_info", settlement_info);
        map.put("bank_account_info", bank_account_info);
        try {
            String body = JSONObject.fromObject(map).toString();
            String str = HttpUrlUtil.sendPost(body);
            System.out.println(str);
            return str;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

CertUtil类

package com.shifen.manager.utils;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.codec.binary.Base64;

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.cert.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;

/**
 * 证书工具类
 */
public class CertUtil {

    // 微信证书私钥路径(从微信商户平台下载,保存在本地)
    public static String APICLIENT_KEY = "D:\\666\\zs\\apiclient_key.pem";

    // 微信商户证书路径(从微信商户平台下载,保存在本地)
    public static String APICLIENT_CERT = "D:\\666\\zs\\apiclient_cert.pem";

    /**
     * 获取私钥。
     *
     * @param
     * @return 私钥对象
     */
    public static PrivateKey getPrivateKey() throws IOException {
        String content = new String(Files.readAllBytes(Paths.get(APICLIENT_KEY)), StandardCharsets.UTF_8);
        try {
            String privateKey = content.replace("-----BEGIN PRIVATE KEY-----", "").replace("-----END PRIVATE KEY-----", "").replaceAll("\\s+", "");
            KeyFactory kf = KeyFactory.getInstance("RSA");
            return kf.generatePrivate(new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKey)));
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("当前Java环境不支持RSA", e);
        } catch (InvalidKeySpecException e) {
            throw new RuntimeException("无效的密钥格式");
        }
    }

    /**
     * 获取商户证书。
     *
     * @param filename 证书文件路径 (required)
     * @return X509证书
     */
    public static X509Certificate getCertificate(String filename) throws IOException {
        InputStream fis = new FileInputStream(APICLIENT_CERT);
        try (BufferedInputStream bis = new BufferedInputStream(fis)) {
            CertificateFactory cf = CertificateFactory.getInstance("X509");
            X509Certificate cert = (X509Certificate) cf.generateCertificate(bis);
            cert.checkValidity();
            return cert;
        } catch (CertificateExpiredException e) {
            throw new RuntimeException("证书已过期", e);
        } catch (CertificateNotYetValidException e) {
            throw new RuntimeException("证书尚未生效", e);
        } catch (CertificateException e) {
            throw new RuntimeException("无效的证书文件", e);
        }
    }

    /**
     * 获取商户证书序列号
     *
     * @param certPath 获取商户证书序列号 传递商号证书路径 apiclient_cert
     * @return
     * @throws IOException
     */
    public static String getSerialNo(String certPath) throws IOException {
        X509Certificate certificate = getCertificate(certPath);
        return certificate.getSerialNumber().toString(16).toUpperCase();
    }

    /**
     * 获取微信平台证书序列号
     *
     * @return
     * @throws Exception
     */
    public static String getCertSerialNo() throws Exception {
        try {
            String str = HttpUrlUtil.sendGet();
            System.out.println(str);
            JSONObject json = JSONObject.fromObject(str);
            JSONArray jsonArray = JSONArray.fromObject(json.optString("data"));
            JSONObject jsonObject = jsonArray.getJSONObject(0);
            return jsonObject.optString("serial_no");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获取微信平台证书
     *
     * @return
     * @throws Exception
     */
    public static String getCertStr() throws Exception {
        try {
            String str = HttpUrlUtil.sendGet();
            JSONObject json = JSONObject.fromObject(str);
            JSONArray jsonArray = JSONArray.fromObject(json.optString("data"));
            JSONObject jsonObject = jsonArray.getJSONObject(0);
            JSONObject jsonCert = JSONObject.fromObject(jsonObject.optString("encrypt_certificate"));
//			System.out.println(str);
//			System.out.println(jsonCert);
            String certKeyString = AesUtil1.decryptToString(jsonCert.getString("associated_data").getBytes(),
                    jsonCert.getString("nonce").getBytes(), jsonCert.getString("ciphertext"));
            return certKeyString;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    
}

敏感信息加密
官方文档也有示例代码
https://wechatpay-api.gitbook.io/wechatpay-api-v3/qian-ming-zhi-nan-1/min-gan-xin-xi-jia-mi

package com.shifen.manager.utils;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.util.Base64;

/**
 * 敏感信息加密
 */
public class RsaEncryptUtil {

    /**
     * 加密
     *
     * @param message
     * @param certificate
     * @return
     * @throws IllegalBlockSizeException
     * @throws IOException
     */
    public static String rsaEncryptOAEP(String message, X509Certificate certificate) throws IllegalBlockSizeException, IOException {
        try {
            Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding");
            cipher.init(Cipher.ENCRYPT_MODE, certificate.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("解密失败");
        }
    }
}

HttpUrl工具类

package com.shifen.manager.utils;


import okhttp3.HttpUrl;
import org.apache.cxf.jaxrs.client.WebClient;

import javax.ws.rs.core.Response;
import java.security.PrivateKey;
import java.security.Signature;
import java.util.Base64;
import java.util.UUID;

/**
 * HttpUrl工具类
 */
public class HttpUrlUtil {

    public static String SCHEMA = "WECHATPAY2-SHA256-RSA2048";
    public static String merchantId = Config.MCHIDSP; // 服务商

    public static String POST = "POST";
    public static String GET = "GET";
    //
    public static String host = "https://api.mch.weixin.qq.com";
    public static String APPLY_PATH = "/v3/applyment4sub/applyment/"; // 申请单url
    public static String CERT_PATH = "/v3/certificates"; // 获取微信平台证书url
    public static String APPLY_QUERY_PATH = "/v3/applyment4sub/applyment/applyment_id/"; // 查询申请状态

    /**
     * POST请求
     */
    public static String sendPost(String body) {
        String url = host + APPLY_PATH;
        try {
            // 获取微信平台商户证书序列号
            String wxSerialNo = CertUtil.getCertSerialNo();
            String authorization = getToken(POST, url, body);
            WebClient client = WebClient.create(host);
            client.reset();
            client.header("Content-Type", "application/json; charset=UTF-8");
            client.header("Accept", "application/json");
            client.header("user-agent", "application/json");
            client.header("Wechatpay-Serial", wxSerialNo);
            client.header("Authorization", authorization);
            client.path(APPLY_PATH);
            Response r = client.post(body);
            return r.readEntity(String.class);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * get请求
     */
    public static String sendGet() {
        // 请求URL
        String url = host + CERT_PATH;
        try {
            String authorization = getToken(GET, url, "");
            WebClient client = WebClient.create(host);
            client.reset();
            client.header("Content-Type", "application/json; charset=UTF-8");
            client.header("Accept", "application/json");
            client.header("User-Agent", "application/json");
            client.header("Authorization", authorization);
            client.path(CERT_PATH);
            Response r = client.get();
            return r.readEntity(String.class);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * get请求
     */
    public static String sendGet(String applymentId) {
        // 请求URL
        String url = host + APPLY_QUERY_PATH + applymentId;
        try {
            String authorization = getToken(GET, url, "");
            WebClient client = WebClient.create(host);
            client.reset();
            client.header("Content-Type", "application/json; charset=UTF-8");
            client.header("Accept", "application/json");
            client.header("User-Agent", "application/json");
            client.header("Authorization", authorization);
            client.path(APPLY_QUERY_PATH + applymentId);
            Response r = client.get();
            return r.readEntity(String.class);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 获取加密串
     *
     * @param method
     * @param url
     * @param body
     * @return
     */
    public static String getToken(String method, String url, String body) {
        String nonceStr = String.valueOf(UUID.randomUUID());
        long timestamp = System.currentTimeMillis() / 1000;
        HttpUrl httpUrl = HttpUrl.parse(url);
        String message = buildMessage(method, httpUrl, timestamp, nonceStr, body);
        String signature = null;
        String certificateSerialNo = null;
        try {
            signature = sign(message.getBytes("utf-8"));
            certificateSerialNo = CertUtil.getSerialNo("");
        } catch (Exception e) {
            e.printStackTrace();
        }

        return SCHEMA + " mchid=\"" + merchantId + "\"," + "nonce_str=\"" + nonceStr + "\"," + "timestamp=\"" + timestamp + "\"," + "serial_no=\""
                + certificateSerialNo + "\"," + "signature=\"" + signature + "\"";
    }

    /**
     * 得到签名字符串
     */
    public static String sign(byte[] message) throws Exception {
        Signature sign = Signature.getInstance("SHA256withRSA");
        PrivateKey privateKey = CertUtil.getPrivateKey();
        sign.initSign(privateKey);
        sign.update(message);
        return Base64.getEncoder().encodeToString(sign.sign());
    }

    public static String buildMessage(String method, HttpUrl url, long timestamp, String nonceStr, String body) {
        String canonicalUrl = url.encodedPath();
        if (url.encodedQuery() != null) {
            canonicalUrl += "?" + url.encodedQuery();
        }
        return method + "\n" + canonicalUrl + "\n" + timestamp + "\n" + nonceStr + "\n" + body + "\n";
    }
}

依赖

		<dependency>
            <groupId>com.github.wechatpay-apiv3</groupId>
            <artifactId>wechatpay-apache-httpclient</artifactId>
            <version>0.2.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-rs-client</artifactId>
            <version>3.1.11</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-transports-http</artifactId>
            <version>3.1.11</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-frontend-jaxrs</artifactId>
            <version>3.1.11</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-rs-extension-providers</artifactId>
            <version>3.1.11</version>
        </dependency>

进件成功后会返回一个applyment_id单号
最后就是进件接口返回暂无权限,请稍后重试的问题
首先保证自己在微信自己的进件功能是可以实现进件的
其次弄清楚自己要做的到底是特约商户还是小微商户
搞混了就会报进件没有权限
实在不行就跟微信客服提问具体原因

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

云上上云

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值