微信apiv3 特约商户进件

2023-10-14 02:30

本文主要是介绍微信apiv3 特约商户进件,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

特约商户进件接口字段太多,费九牛二虎之力
1.接口地址

微信支付-开发者文档

2.创建v3 httpClient  获取平台证书列表  上传图片到微信服务器,敏感信息加密工具类
 

@Slf4j
public class WechatPay {private static final String appId = "xxxxxx";  //  服务商商户的 APPID 小程序等appidprivate 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添加商户信息// 从证书管理器中获取verifierVerifier 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();//发送jsonrootNode.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());//服务商小程序APPIDList<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());//入驻结算规则IDruleNode.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());//优惠费率活动IDruleNode.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);}

这篇关于微信apiv3 特约商户进件的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/207522

相关文章

W外链微信推广短连接怎么做?

制作微信推广链接的难点分析 一、内容创作难度 制作微信推广链接时,首先需要创作有吸引力的内容。这不仅要求内容本身有趣、有价值,还要能够激起人们的分享欲望。对于许多企业和个人来说,尤其是那些缺乏创意和写作能力的人来说,这是制作微信推广链接的一大难点。 二、精准定位难度 微信用户群体庞大,不同用户的需求和兴趣各异。因此,制作推广链接时需要精准定位目标受众,以便更有效地吸引他们点击并分享链接

uniapp设置微信小程序的交互反馈

链接:uni.showToast(OBJECT) | uni-app官网 (dcloud.net.cn) 设置操作成功的弹窗: title是我们弹窗提示的文字 showToast是我们在加载的时候进入就会弹出的提示。 2.设置失败的提示窗口和标签 icon:'error'是设置我们失败的logo 设置的文字上限是7个文字,如果需要设置的提示文字过长就需要设置icon并给

基于微信小程序与嵌入式系统的智能小车开发(详细流程)

一、项目概述 本项目旨在开发一款智能小车,结合微信小程序与嵌入式系统,提供实时图像处理与控制功能。用户可以通过微信小程序远程操控小车,并实时接收摄像头采集的图像。该项目解决了传统遥控小车在图像反馈和控制延迟方面的问题,提升了小车的智能化水平,适用于教育、科研和娱乐等多个领域。 二、系统架构 1. 系统架构设计 本项目的系统架构主要分为以下几个部分: 微信小程序:负责用户界面、控制指令的

微信小程序uniappvue3版本-控制tabbar某一个的显示与隐藏

1. 首先在pages.json中配置tabbar信息 2. 在代码根目录下添加 tabBar 代码文件 直接把微信小程序文档里面的四个文件复制到自己项目中就可以了   3. 根据自己的需求更改index.js文件 首先我这里需要判断什么时候隐藏某一个元素,需要引入接口 然后在切换tabbar时,改变tabbar当前点击的元素 import getList from '../

微信小程序(一)数据流与数据绑定

一、单向数据流和双向数据流 1、单项数据流:指的是我们先把模板写好,然后把模板和数据(数据可能来自后台)整合到一起形成HTML代码,然后把这段HTML代码插入到文档流里面 优点:数据跟踪方便,流向单一,追寻问题比较方便【主要体现:微信小程序】。 缺点:就是写起来不太方便,如果修改UI界面数据需要维护对应的model对象 2、双向数据流:值和UI是双向绑定的,大家都知道,只要UI里面的值发生

微信小程序学习网站

小程序--柯神博客 http://www.cnblogs.com/nosqlcoco 案例地址: https://github.com/cocoli/weixin_smallexe/tree/master/weixin_demo/pages/component/uploadfile

分享一个基于uniapp科技馆服务微信小程序 博物馆管理小程序(源码、调试、LW、开题、PPT)

💕💕作者:计算机源码社 💕💕个人简介:本人 八年开发经验,擅长Java、Python、PHP、.NET、Node.js、Android、微信小程序、爬虫、大数据、机器学习等,大家有这一块的问题可以一起交流! 💕💕学习资料、程序开发、技术解答、文档报告 💕💕如需要源码,可以扫取文章下方二维码联系咨询 💕💕Java项目 💕💕微信小程序项目 💕💕Android项目 �

flutter开发实战-flutter build web微信无法识别二维码及小程序码问题

flutter开发实战-flutter build web微信无法识别二维码及小程序码问题 GitHub Pages是一个直接从GitHub存储库托管的静态站点服务,‌它允许用户通过简单的配置,‌将个人的代码项目转化为一个可以在线访问的网站。‌这里使用flutter build web来构建web发布到GitHub Pages。 最近通过flutter build web,通过发布到GitHu

1-3 微信小程序协同工作和发布

协同工作和发布 🥟🥞以权限管理需求为例 一个项目组,一般有不同的岗位,不同角色的员工同时参与项目成员 流程 成员管理的两个方面 不同项目成员对应的权限 版本

Deepin Linux 下安装微信

在下载和运行这个项目之前,你需要在电脑上安装Git和Node.js (来自npm)。在命令行中输入: 安装Git和nodejs 命令:sudo apt-get install git  sudo apt-get install nodejs 执行完上面命令之后运行下面命令 # 下载仓库 git clone https://github.com/geeeeeeeeek/elec