Vamos primeiro olhar para o efeito dos envelopes vermelhos em dinheiro emitidos pela conta oficial:
É necessário chamar a interface da plataforma do comerciante, e as regras de distribuição de interface são as seguintes:
1. Limite de frequência de envio - padrão 1800/min/min
2. O limite superior do número de envio - calculado de acordo com o padrão de 1800/min padrão/min
3. Valor Limite superior - Dependendo do ID da cena que entra, o limite superior padrão pode ser definido e solicitado nas configurações de produto da plataforma do comerciante, com um máximo de não mais que 4.999 yuan por unidade
4. Que outras restrições em "quantidade" existem? - O número máximo de vezes que o usuário recebe naquele dia é 10 por padrão
5. Se a quantidade não puder atender às nossas necessidades, como podemos aumentar cada limite superior? -O limite máximo de quantidade e o número máximo de vezes que o usuário recebe no mesmo dia pode ser definido na plataforma de comerciantes
Nota- Quando a quantidade de envelope vermelho é maior que 200, o parâmetro de solicitação cenário_id deve ser passado e a descrição do parâmetro é mostrada abaixo.
NOTA 2 - De acordo com os requisitos regulatórios, duas condições são necessárias para usar envelopes vermelhos em dinheiro para contas de comerciantes recém -aplicadas: 1. O tempo de entrada excede 90 dias 2. Transações normais contínuas por 30 dias.
Solicite url https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack
Se um certificado é necessário é (consulte o certificado do comerciante para obter detalhes)
Postagem do método de solicitação
Solicitar exemplo de dados:
<xml> <Sign> <! [CDATA [E1EE61A91C8E90F299DE6AE075D60A2D]]> </SIGN> <MCH_BILLNO> <! [CDATA [0010010404201411170 000046545]]> </mch_billno> <mch_id> <! [CDATA [888]]> </mch_id> <wxappid> <! [CDATA [WXCBDA96DE0B165486]] </wxap pid> <Snd_Name> <! [CDATA [SEND_NAME]]> </NEND_NAME> <Re_OPENID> <! [CDATA [onqojjm1tad-3ropncn-yufa6ui]]> </r E_OPENID> <Total_amount> <! [CDATA [200]]> </tall_amount> <Total_Num> <! [CDATA [1]]> </tall_num> <Sisseing> <! [CD ATA [Parabéns por ficar rico]]> </se Wishing> <Client_IP> <! [CDATA [127.0.0.1]]> </client_ip> <CTe_Name> <! [CDATA [Ano Novo Red ENVELOPE]]> </AT_NAME> <! Envelope]]> </muily> <cenário_id> <! [CDATA [Product_2]]> </cenário_id> <consume_mch_id> <! [CDATA [10 000097]]> </consume_mch_id> <Nonce_Str> <! [CDATA [50780E0CCA98C8C8E814883E5CAA672E]]> </NONCE_STR> <RISCO_INF O> pós -tempo%3D123123412%26clientVersion%3D234134%26Mobile%3D122344545%26DeviceId%3DIOS </sistert_info> </xml>
A interface requer a chamada para o certificado da plataforma do comerciante, e o certificado precisa ser baixado da plataforma do comerciante:
Em seguida, use o certificado na interface. Primeiro, criamos uma nova classe Weixinssl
@ComPonentPublic Classe weixinssl { / *** Tipo de certificado* / @Value ("$ {Werchant.storeKey}") private String storeKey; / *** Caminho do arquivo*/ @Value ("$ {werchant.ssslfile}") private string sslfile; / *** Número do comerciante*/ @Value ("$ {werchant.merchantnumber}") private string MerchantNumber; public String getStoreKey () {return storeKey; } public void setStoreKey (String storeKey) {this.storeKey = storeKey; } public string getslfile () {return sslfile; } public void SetSslFile (String sslfile) {this.ssslfile = sslfile; } public String getMerChantNumber () {return MerchantNumber; } public void setMerChantNumber (String MerchantNumber) {this.merchantNumber = MerchantNumber; }}Encapsular a classe HTTPClientSL para implementar a solicitação HTTPS para adicionar um certificado:
@ComponentPublic Classe httpClientsSl {@AUTOWIRED PRIVADO WEIXINSSL WEIXINSSL; // Timeout de solicitação (milissegundos) 5 segundos Public Static RequestConfig RequestConfig; // Tempo limite de resposta (milissegundos) 60 segundos public static int http_Response_timeout = 60 * 1000; // caractere httpclient que codifica public static string coding = "utf-8"; public static requestconfig getRequestConfig () {return requestconfig.custom (). setConnectTimeout (5 * 1000) .SetConnectionRequestTimeout (http_response_timeout) .build (); } public static void setRequestConfig (requestconfig requestconfig) {httpclientsl.requestconfig = requestconfig; } /** tente {new sslContextBuilder (). LoadTrustMaterial (null, new TrustStrategy () {@Override public boolean isTrusted (x509Certificate [] Chain, String Authtype) lança java.Security.Cert.CertificateException {Return false;}}); } catch (nosuchalgorithMexception | keystoreException e) {e.printStackTrace (); } SSLConnectionSocketFactory Factory = new SSLConnectionSocketFactory (SSLContext); return httpClients.custom (). SetSsLockFactory (Factory) .build (); } / *** solicitação https para adicionar certificado* @return* / public CloseableHttpClient defaultSlClientFile () {if (this.weixinssl == null) {return this.defaultSlClient (); } FileInputStream inputStream = null; Keystore keystore = null; tente {// ssl tipo keystore = keystore.getInstance (weixinssl.getStoreKey ()); // arquivo ssl inputStream = new FileInputStream (weixinssl.getSslfile ()); // Defina o SSL senha keystore.load (inputStream, weixinssl.getmerchantNumber (). ToCharArray ()); } catch (keystoreException | nosuchalgorithMexception | CertificateException | ioException e1) {e1.printStackTrace (); } finalmente {tente {inputStream.close (); } catch (ioexception e) {e.printStackTrace (); }} SslContext sslContext = null; tente {sslContext = sslContext.custom (). loadkeymaterial (keystore, weixinssl.getmerchantNumber (). toCharArray (). } Catch (não -vendido } SSLConnectionSocketFactory Factory = new SSLConnectionSocketFactory (SSLContext, new String [] {"TLSV1"}, NULL, SSLCONNECTOLECTFACTORY.Browser_Compatible_Hostname_Verifier); return httpClients.custom (). SetSsLockFactory (Factory) .build (); } / *** Encapsula o método para enviar solicitações* @THOWS UnsupportEdEncodingException* / public String send (URL da String, Dados da String, ClosableHttpClient ClosableHttpClient) lança sem suportesCodingException {ClosableHttpClient HttpPost httppost = new httppost (urldecoder.decode (url, codificação)); httppost.addheader ("conexão", "Keep-alive"); httppost.addheader ("aceitar", "*/*"); httppost.addheader ("content-type", "Application/x-www-forma-urlncoded; charset = utf-8"); httppost.addheader ("host", "api.mch.weixin.qq.com"); httppost.addheader ("x-requestado-with", "xmlhttprequest"); httppost.addheader ("Controle de cache", "max-AGE = 0"); httppost.addheader ("user-agent", "mozilla/4.0 (compatível; msie 8.0; windows nt 6.0)"); httppost.setConfig (this.getRequestConfig ()); // Definir o tempo limite mais próximo da resposta da resposta = null; // Coloque o parâmetro em stringentity entity = new stringentity (dados, codificação); entity.setContentEncoding (codificação); entity.setContentType ("Application/XML"); httppost.setentity (entidade); tente {Response = client.execute (httppost); if (Respons.getStatusline (). getStatuscode () == 200) {httPentity httpentity = (httpentity) resposta.getEntity (); if (resposta! = null) {return entityutils.toString (httpentity, codificação); }}} catch (ioexception e) {e.printStackTrace (); } retornar nulo; }} Dessa forma, encapsulamos uma classe de entidade que solicita o certificado com HTTPS e, em seguida, geramos a interface do envelope Red WeChat Red solicitada:
Assinatura do parâmetro de https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack:
/*** Classe de entidade do parâmetro do envelope vermelho*@THOWS UnsupportEdEncodingException*/ @ComponentPublic Classe sendRedPack implementa serializável {/****/private estático final serialversionuid = -1000489228099916099l; String privada Nonce_str; // string aleatória string privada sinal; // assinatura string privada mch_billno; // Número do pedido do comerciante Private String mch_id; // Número do comerciante String privada string wxappid; // public string privado string string_name; // Merchant Name Unit: private string re_openId; // user private/ total/ total; Desejo; // Red Envelope Blessing Private String client_ip; // Endereço IP Private String Act_name; // Nome da atividade String privada observação; // notas public string getNonce_str () {return noNe_str; } public void setNonce_str (string nonce_str) {this.nonce_str = nonce_str; } public string getSign () {retornar sinal; } public void Setsign (string signo) {this.sign = signe; } public string getMch_billno () {return mch_billno; } public void setMch_billno (string mch_billno) {this.mch_billno = mch_billno; } public String getMch_id () {return mch_id; } public void setMch_id (string mch_id) {this.mch_id = mch_id; } public string getwxappid () {return wxappid; } public void setWxAppid (string wxappid) {this.wxappid = wxappid; } public string getSend_name () {return send_name; } public void setSend_name (string send_name) {this.send_name = send_name; } public string getre_openid () {return re_openid; } public void setre_openid (string re_openid) {this.re_openid = re_openid; } public int gettotal_amount () {return total_amount; } public void setTotal_amount (int total_amount) {this.total_amount = total_amount; } public int gettotal_num () {return total_num; } public void setTotal_num (int total_num) {this.total_num = total_num; } public string getWishing () {return desejando; } public void setWishing (string desejando) {this.wishing = desejando; } public string getClient_ip () {return client_ip; } public void setClient_ip (string client_ip) {this.client_ip = client_ip; } public string getAct_name () {return Act_name; } public void setAct_name (string Act_name) {this.act_name = Act_name; } public string getRemark () {retornar observação; } public void setRemark (string observação) {this.remark = observação; }}Em seguida, é o controlador que envia o pacote vermelho:
/*** Controlador de envelope vermelho* @Author ZenGgliang*/ @controlador @requestmapping (value = "/redenveloSreceive") classe pública redenvelonseCeivecontroller {// wechat identificador exclusivo @value ("$ {weixin.Appid}") private string; // WeChat Developer Senha Identifier @Value ("$ {weixin.appsecret}") public string appSecret; @Autowired Private SendRedPack SendRedPack; @AUTOWIRED PRIVADO HTTPCLIENTSLSL HTTPCLIENTSSL; /*** Enviar parâmetros xml* @Author ZenGgliang*/@ResponseBody @ReQuestMapping (value = "/sendxml") public String sendxml (String OpenId, Long Redenveloptes_ID, String mch_billno) {RedenEnveltes Redenve = RedenvelgnOnNeRex; Xmlutil xmlutil = new Xmlutil (); sendRedPack.Setact_Name (redenve.getact_name ()); sendRedPack.SetNonce_Str (xmlutil.random ()); sendredpack.setre_openid (OpenId); sendredpack.setClient_ip (redenve.getclient_ip ()); sendredpack.setmch_billno (mch_billno); sendredpack.setmch_id (redenve.getmch_id ()); String xx = redenve.getRemark (); sendRedPack.SetRemark (stringUtils.isEmpty (xx) == false? xx: "vazio"); sendredpack.setsend_name (redenve.getSend_name ()); sendredpack.setTotal_amount (redenve.gettotal_amount ()); sendredpack.settotal_num (redenve.gettotal_num ()); sendredpack.setWishing (redenve.getwishing ()); sendRedPack.setwxappid (redenve.getwxappidxx ()); // gerar string de assinatura params = this.createsendredpackordersign (sendRedpack, redenve.getstore_key ()); sendRedPack.SetSign (params); xmlutil.xStream (). Alias ("xml", sendredpack.getclass ()); // estende o xStream para suportar o bloco CDATA requestXml = xmlutil.xstream (). Toxml (sendRedPack); Resultado da string; tente {resultado = httpclientsl.send ("https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack", requestXml, httpclientsl.defaultSllientFile ()); System.out.println ("Valor de retorno bem -sucedido"+resultado); resultado de retorno; } Catch (UnsupportEdEncodingException e) {E.PrintStackTrace (); } retornar nulo; }/ ** * GERENA ASSINATURA * @param redpack * @return */ public string CreateEsendRedPackorDersign (sendRedPack RedPack, String StoreKey) {StringBuffer Sign = new StringBuffer (); SIGN.APPEND ("ACT_NAME ="). APEND (RedPack.getAct_Name ()); Sign.append ("& client_ip ="). Append (redpack.getclient_ip ()); SIGN.APPEND ("& re_billno ="). Append (redpack.getmch_billno ()); SIGN.APPEND ("& OBRIGADO ="). APÊNHE (RedPack.getmch_id ()); Sign.append ("& send_str ="). Append (redpack.getnonce_str ()); SIGN.APPEND (RedPack.getNonce_str ()); Sign.append ("& re_openid ="). Append (redpack.getre_openid ()); SIGN.APPEND ("& OBTENHA ="). Append (redpack.getRemark ()); Sign.append ("& send_name ="). Append (redpack.getSend_name ()); Sign.append ("& total_amount ="). Append (redpack.gettotal_amount ()); Sign.Append ("& total_num ="). Append (redpack.gettotal_num ()); SIGN.APPEND ("& Wishing ="). Append (redpack.getwishing ()); Sign.append ("& wxappid ="). Append (redpack.getwxappid ()); Sign.append ("& key ="). Append (StoreKey); return digestutils.md5hex (signs.toString ()). toupppercase (); }}Então precisamos usar uma classe de ferramentas para analisar XML para analisar XML retornado por WeChat para analisar XML
/** * Parsing XML tool class * @author zengliang */@Componentpublic class XMLUtil { /** * Parsing XML returned by WeChat * @param xml * @return * @throws Exception */ @SuppressWarnings("unchecked") public Map<String, String> parseXml(String xml)throws Exception { Map<String,String> map = novo hashmap <string, string> (); Documento doc = null; tente {doc = documentHelper.parseText (xml); // converte a sequência em elemento xml rootelt = doc.getrootelement (); // Obtenha a lista de nó raiz <Emment> list = rootelt.Elements (); // Obtenha todos os nós no nó raiz para (elemento elemento: list) {// Tranquility Node map.put (element.getName (), element.getText ()); // O nome do nó é a chave do mapa e o texto é o valor do mapa}} catch (documentException e) {e.printStackTrace (); } catch (Exceção e) {e.printStackTrace (); } mapa de retorno; } / *** Estenda o xStream para suportar bloco CDATA* / privado xstream xStream = new XStream (novo XppDriver (new nonamecoder ()) {@Override public hierárquico hierárquico TRAUSTRATRATRATER (Writer Out) {Return bylessWriter (out) {// Add CDATA para todos os nódulos xml). @Supresswarnings ("rawtypes") public void startNode (nome da string, classe clazz) {super.startNode (nome, clazz); Writer.Write (Texto); private xStream IncluiUnderLineXStream = new XStream (novo Domdriver (NULL, novo XMLIFLIGLYNAMECODER ("_-", "_"))); public xstream getxStreaminclueUnderLine () {return InclueUnderLineXStream; } public xstream xStream () {return xstream; } / *** gerar número aleatório* @return* / public string aleator () {string aleatória = uuid.randomuuid (). Tostring (). Substituir ("-", ""); retornar aleatório; }}Em seguida, chamamos o método sendxml para enviar envelopes vermelhos para o usuário.
O exposto acima é todo o conteúdo deste artigo. Espero que seja útil para o aprendizado de todos e espero que todos apoiem mais o wulin.com.