Primero veamos el efecto de los sobres rojos en efectivo emitidos por la cuenta oficial:
Es necesario llamar a la interfaz de la plataforma comercial, y las reglas de distribución de la interfaz son las siguientes:
1. Enviar límite de frecuencia: predeterminado 1800/min
2. El límite superior del número de envíos, calculado de acuerdo con el predeterminado 1800/min
3. Cantidad de límite superior: dependiendo de la ID de escena entrante, el límite superior predeterminado se puede establecer y solicitar en la configuración del producto de la plataforma comercial, con un máximo de no más de 4,999 yuan por unidad
4. ¿Qué otras restricciones sobre la "cantidad" hay? - El número máximo de veces que el usuario recibe ese día es 10 por defecto
5. Si la cantidad no puede satisfacer nuestras necesidades, ¿cómo podemos aumentar cada límite superior? -El límite de cantidad máxima y el número máximo de veces que el usuario recibe el mismo día se puede configurar en la plataforma comercial
Nota: cuando la cantidad de envoltura roja es mayor que 200, el parámetro de solicitud escena_id debe pasarse, y la descripción del parámetro se muestra a continuación.
Nota 2 - De acuerdo con los requisitos reglamentarios, se requieren dos condiciones para usar sobres rojos en efectivo para cuentas comerciales recientemente aplicadas: 1. El tiempo de entrada excede los 90 días 2. Transacciones normales continuas durante 30 días.
Solicitar url https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack
Si se requiere un certificado (consulte el certificado de comerciante para más detalles)
Solicitud del método de publicación
Ejemplo de datos de solicitud:
<xml> <sign> <! [CDATA [E1EE61A91C8E90F299DE6AE075D60A2D]]> </20 000046545]]> </mch_billno> <mch_id> <! [Cdata [888]]> </mch_id> <wxappid> <! [Cdata [wxcbda96de0b165486]> </wxap pid> <ent_name> <! [Cdata [send_name]]> </send_name> <RE_OPENID> <! [CDATA [ONQOJJMM1TAD-3ROPNCN-YUFA6UI]]> </r e_openid> <total_AMOUNT> <! [Cdata [200]]> </total_amount> <total_num> <! [CDATA [1]]> </Total_num> <sishing> <! [CD ATA [Felicitaciones por hacerse rico]]> </isitando> <client_ip> <! [CDATA [127.0.0.1]]> </ Client_ip> <Act_Name> <! [CDATA [New Year Red Envelope]]> </ACT_NAME> <NOWS> <! [CDATA [Año nuevo Red Red Red Envoltura]]> </comentario> <cene_id> <! [CDATA [Product_2]]> </escena_id> <consumo_mch_id> <! [CDATA [10 000097]]> </consumo_mch_id> <nonce_str> <! [CDATA [50780E0CCA98C8C8E814883E5CAA672E]]> </nonce_str> <riesgo_inf o> PostTime%3D123123412%26 ClientVersion%3D234134%26Mobile%3D1223444545%26DeviceID%3Dios </Risk_info> </xml>
La interfaz requiere la llamada al certificado de la plataforma comercial, y el certificado debe descargarse desde la plataforma comercial:
Luego use el certificado en la interfaz. Primero, creamos una nueva clase Weixinssl
@ComponentPublic Class weixinssl { / *** Tipo de certificado* / @Value ("$ {werchant.storekey}") privado string storekey; / *** ruta de archivo*/ @Value ("$ {werchant.sslfile}") privado cadena sslfile; / *** Número de comerciante*/ @Value ("$ {werchant.merchantNumber}") String private MerchantNumber; public String getStorekey () {return storeKey; } public void setStoreKey (string storeKey) {this.storekey = storeKey; } public String getSslFile () {return sslfile; } public void setsslfile (string sslfile) {this.sslfile = sslfile; } public String getMerchantNumber () {return MerchantNumber; } public void setMerchantNumber (String MerchantNumber) {this.merChantNumber = MerchantNumber; }}Encapsular la clase HTTPClientsSL para implementar la solicitud HTTPS para agregar un certificado:
@ComponentPublic Class httpClientsSl {@aUtowired private weixinssl weixinssl; // Tiempo de espera de solicitud (MilliseConds) 5 segundos Public Static SolicConfig requestConfig; // Tiempo de espera de respuesta (milisegundos) 60 segundos Public static int http_revonse_timeout = 60 * 1000; // HttpClient Carácter que codifica public String String Coding = "UTF-8"; Public static requestConfig getRequestConfig () {return requitConfig.custom (). setConnectTimeOut (5 * 1000) .SetConnectionRequestTimeOut (http_response_timeout) .Build (); } public static void setRequestConfig (requestConfig requestConfig) {httpclientssl.RequestConfig = requitConfig; } / *** Certificado de falsificación de solicitudes https* @return* / public CloseableHttpClient DefaultsslClient () {SSLContext sslContext = null; Pruebe {nuevo sslContextBuilder (). LoadTrustMaterial (null, nuevo TrustStrategy () {@Override public boolean istrusted (x509Certificate [] cadena, string authtype) arroja java.security.cert.CertificateException {return False;}); } Catch (nosuchalgorithMexception | KeyStoreException e) {E.PrintStackTrace (); } SslconnectionsocketFactory factory = new SSLConnectionsocketFactory (SSLContext); return httpclients.custom (). setsslsocketFactory (fábrica) .Build (); } / *** HTTPS Solicitud para agregar certificado* @return* / public ClosableHttpClient DefaultsslClientFile () {if (this.weixinssl == null) {return this.defaultsslclient (); } FileInputStream inputStream = null; KeyStore KeyStore = NULL; Pruebe {// SSL Type KeyStore = KeyStore.getInstance (weixinssl.getStoreKey ()); // ssl file inputStream = new FileInputStream (weixinssl.getsslfile ()); // Establezca la contraseña SLL KeyStore.load (inputStream, weixinssl.getMerchantNumber (). ToCarArray ()); } Catch (KeyStoreException | NosuchalgorithMexxception | CertificateException | ioException e1) {e1.printStackTrace (); } finalmente {try {inputStream.Close (); } catch (ioException e) {E.PrintStackTrace (); }} SslContext sslContext = null; Pruebe {sslContext = sslContexts.custom (). LoadKeMaterial (KeyStore, weixinssl.getMerChantNumber (). toCarArray ()). Build (); } Catch (UnrecoverableKeyException | NosuchalgorithMException | KeyStoreException | KeyManagementException e) {E.PrintStackTrace (); } SslconnectionsocketFactory factory = new SSLConnectionsocketFactory (SSLContext, new String [] {"TLSV1"}, NULL, SSLConnectionsocketFactory.Browser_Compatible_HostName_verifier); return httpclients.custom (). setsslsocketFactory (fábrica) .Build (); } / *** Método encapsular para enviar las solicitudes* @throws UnsPportedEncodingException* / public String send (String Url, String Data, ClosableHttpClient CloseableHttpClient) lanza UnspportedEncodingException {cierreHttpClient Client = cierreHttpClient; Httppost httpPost = new httppost (urlDecoder.decode (url, codificación)); httppost.addheader ("conexión", "mantener alive"); httppost.addheader ("aceptar", "*/*"); httppost.addHeader ("Content-type", "Application/x-www-form-urlencoded; charset = utf-8"); httppost.addheader ("host", "api.mch.weixin.qq.com"); httppost.addHeader ("X-solicitada con", "xmlhttprequest"); httppost.addHeader ("Cache-Control", "max-edad = 0"); httppost.addheader ("agente de usuario", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0)"); httppost.setConfig (this.getRequestConfig ()); // Establecer el tiempo de espera cerrablehttTpResponse respuesta = null; // Poner el parámetro en StringEntity Entity = New StringEntity (datos, codificación); entity.setContentEncoding (codificación); entity.setContentType ("Aplicación/XML"); httppost.setEntity (entidad); intente {respuesta = cliente.execute (httppost); if (respuesta.getStatUsline (). getStatUscode () == 200) {httpentity httpentity = (httpentity) respuesta.getEntity (); if (respuesta! = null) {return entityUtil.ToString (httpentity, codificación); }}} Catch (ioException e) {E.PrintStackTrace (); } return null; }} De esta manera, encapsulamos una clase de entidad que solicita el certificado con HTTPS, y luego generamos la interfaz de envoltura roja WeChat solicitada:
Firma de parámetros de https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack:
/*** CLASE DE ENTRADA DEL PARAMETER DE ROJO*@throws UnsupportedEnCodingException*/ @ComponentPublic Class SendRedpack implementa serializable {/****/private Static final Long SerialVersionUid = -10004892280999916099l; cadena privada nonce_str; // cadena aleatoria de cadena privada de cadena de cadena; // firma privada cadena mch_billno; // número de orden de comerciante cadena privada mch_id; // número de comerciante cadena privada privada wxappid; // Cuenta pública Cadena privada send_name; // Nombre de comercio Nombre privado RE_Openid; // Usuario privado privado int total_amount Unidad de cantidad de pago: privado int total; envoltura de bendición privada cadena privada client_ip; // Dirección IP String String Act_name; // Nombre de actividad Cadena privada Comentarios; // Notas Cadena pública getNonce_str () {return nonce_str; } public void setnonce_str (string nonce_str) {this.nonce_str = nonce_str; } cadena pública getSign () {firma de retorno; } public void setSign (signo de cadena) {this.sign = sign; } 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 Wishing; } public void setwishing (string wishing) {this.wishing = wishing; } 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 () {comentario return; } public void setRemark (observación de cadena) {this.remark = observación; }}El siguiente es el controlador que envía el paquete rojo:
/*** controlador de envolvente rojo* @author zengliang*/ @controler @requestmapping (value = "/redenseveloSreceive") clase pública redenseveloSreceIvecontroller {// wechat un único identificador @Value ("$ {weixin.appid}") Private String AppID; // Identificador de contraseña de desarrollador WeChat @Value ("$ {weixin.appsecret}") public string appSecret; @AUtowired private sendedpack sendredpack; @AUtowired private httpclientssl httpclientssl; /*** Enviar parámetros XML* @author Zengliang*/@ResponseBody @RequestMapping (valor = "/sendxml") public String sendxml (String OpenId, Long Redenvelopes_ID, String MCH_BILLNO) {redenvolloes redense = redenopesservice.findone (redenopes_id); Xmlutil xmlutil = new XmlUtil (); sendedpack.setact_name (redenve.getact_name ()); sendedpack.setNonce_str (xmlutil.random ()); sendedpack.setre_openid (OpenID); sendredpack.setClient_ip (redenve.getClient_ip ()); sendredpack.setmch_billno (mch_billno); sendredpack.setmch_id (redenve.getmch_id ()); Cadena xx = redenve.getRemark (); sendedpack.setRemark (stringUtils.isEmpty (xx) == falso? xx: "vacío"); sendedpack.setsend_name (redenve.getsend_name ()); sendredpack.settotal_amount (redenve.gettotal_amount ()); sendredpack.settotal_num (redenve.gettotal_num ()); sendedpack.setwishing (redenve.getwishing ()); sendedpack.setwxappid (redenve.getwxappidxx ()); // Generar String String Params = this.CreatesEndedPackordersign (sendedpack, redenve.getstore_key ()); sendedpack.setsign (params); xmlutil.xstream (). alias ("xml", sendredpack.getclass ()); // extiende XStream para admitir la cadena de bloque CDATA requestxml = xmlutil.xstream (). Toxml (sendedpack); Resultado de la cadena; Pruebe {resultado = httpclientssl.send ("https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack", requestxml, httpclientssl.defaultsslclientfile ()); System.out.println ("Valor de retorno exitoso"+resultado); resultado de retorno; } catch (UnsupportedEncodingException e) {E.PrintStackTrace (); } return null; }/ ** * Generar firma * @param redpack * @return */ public string CreateDedRedPackordersign (sendedpack redpack, string storeKey) {StringBuffer Sign = new StringBuffer (); Sign.append ("Act_name ="). Append (redpack.getact_name ()); sign.append ("& client_ip ="). append (redpack.getclient_ip ()); sign.append ("& re_billno ="). append (redpack.getmch_billno ()); sign.append ("& observación ="). append (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 ("& observación ="). 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 (firm.ToString ()). toUpperCase (); }}Luego necesitamos usar una clase de herramientas para analizar XML para analizar XML devuelto por WeChat para analizar 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 = nuevo hashmap <string, string> (); Documento doc = nulo; intente {doc = documentHelper.parsetext (xml); // Convertir la cadena en el elemento xml rootelt = doc.getRootElement (); // Obtenga la lista del nodo raíz <ememem> list = rootelt.elements (); // Obtenga todos los nodos en el nodo raíz para (elemento elemento: list) {// Node de Tranquility Map.put (element.getName (), element.gettext ()); // El nombre del nodo es la tecla MAP, y el texto es el valor del mapa}} Catch (DocumentException e) {E.PrintStackTrace (); } catch (Exception e) {E.PrintStackTrace (); } mapa de retorno; } / *** extender XSTREAM para admitir el bloque Cdata Bloock* / private XSTREAM XSTREAM = new xStream (new XPPDRiver (new NonameNeMeCoder ()) {@Override public HierarchicalStriter Solds @SupessWarnings ("RawTypes") public void StartNode (String Name, Class Clazz) {Super.StartNode (name, Clazz); Writer.Write (Text); Private XStream inclueunderLinexStream = new XStream (new DomDriver (NULL, New XMLFIFELYLYNAMECODER ("_-", "_"))); public XStream getxStreamInClueunderLine () {return inclueunderLinexStream; } public xStream xStream () {return xStream; } / *** Genere el número aleatorio* @return* / public string Random () {String Random = UUID.RandomUUid (). ToString (). Reemplazar ("-", ""); regresar al azar; }}Luego llamamos al método SendXML para enviar sobres rojos al usuario.
Lo anterior es todo el contenido de este artículo. Espero que sea útil para el aprendizaje de todos y espero que todos apoyen más a Wulin.com.