1. Primero solicite el desarrollo y la aplicación en la plataforma WeChat Open. La plataforma WeChat Open generará la aplicación de identificación única de la aplicación. Dado que se requiere seguridad de pago, el nombre del paquete de la aplicación comercial y la firma de la aplicación deben estar obligadas en la plataforma abierta, y el pago solo se puede iniciar normalmente después de configurarlo.
2. Registre la aplicación (esto se puede colocar en la aplicación del proyecto)
El paquete WeChat Jar se introduce en el proyecto de la aplicación Merchant. Antes de llamar a la API, debe registrar su APPID con WeChat. El código es el siguiente:
final iwxapi msgapi = wxapifactory.createwxapi (context, null); // registrar la aplicación a wechat msgapi.registerApp ("wxd930ea5d5a258f4f"); 3. Llame a la API única unificada para generar una orden de prepago. Después de obtener el prepay_id, firme los parámetros y transmítelos a la aplicación para iniciar el pago.
ejemplo:
El número de pedido en el siguiente código debe generarse en segundo plano
String url = "https://api.mch.weixin.qq.com/pay/unifiedorder"; Wxprepost post = new WxPepost (); post.appid = "tu appid"; post.mch_id = "Su número de comerciante"; post.nonce_str = stringUtils.gennoncestr (); // cadena aleatoria ** 1 post.body = "nombre del producto"; post.detail = "Descripción del producto"; post.out_trade_no = out_trade_no; // Número de orden comercial ** 2 post.total_fee = "Precio de productos básicos"; // La unidad se divide en post.spbill_create_ip = getLocalIpAddress (); // dirección ip ** 3 post.notify_url = ""; // Esta es la dirección de la dirección para el backend de aceptar el resultado de la notificación de pago. post.sign = genPackagesign (post); // Signature ** 4 LIST <NameValuePair> FirstSignParams = GetFirstSignParams (post); Cadena xml = toxml (firstsignParams); String entity = null; intente {entity = new String (xml.getBytes (), "ISO8859-1"); byte [] buf = util.httppost (url, entidad); if (buf! = null) {string content = new String (buf); Map <string, string> map = decodexml (content); if (map! = null) {// firmar nuevamente (los campos que participan en la firma son: appid asociarid prepayid non -cap paquete de marca de tiempo) string appid = ""; String PreparayId = ""; Cadena noncestr = ""; for (map.entry <string, string> Entry: map.Entryset ()) {if ("appid" .equals (entry.getKey ())) {appid = entry.getValue (); } else if ("prepay_id" .equals (entry.getKey ())) {prepayId = entry.getValue (); } else if ("nonce_str" .equals (entry.getKey ()))) {noncestr = entry.getValue (); }} Log.d (etiqueta, "run ::" + appid + "/" + prepayId + "/" + noncestr + "/"); String timestamp = string.ValueOf (gentimestamp ()); // OK Obtenga la cadena de firma secundaria SECWPACKAGSIGN = GENSECONDPACKAGSIGN (GetSecondSignParams (AppID, PrepareId, Non -Cestr, TimEdamp)); PayReq req = new PayReq (); req.appid = appid; req.partnerId = "Número de comerciante"; req.prepayid = prepayId; req.noncestr = noncestr; req.timestamp = timestamp; req.packageValue = "sign = wxpay"; req.sign = SecondPackageSign; req.extData = "data de la aplicación"; // Opcional // System.out.println ("GenPackagesign3:"+post.getSign ()+"/"+SecondPackAgage); // Antes del pago, si la solicitud no está registrada en WeChat, primero debe llamar a iwxmsg.registerApp para registrar la solicitud a wechat mapi.sendreq (req); Log.d (etiqueta, "ejecut:" + appid + "/" + prepayid + "/" + non -Cestr + "/" + timestamp + "/" + SecondPackAgage); }}} capt (excepción e) {} public static byte [] httppost (string url, string entity) {if (url == null || url.length () == 0) {log.e (etiqueta, "httppost, url es null"); regresar nulo; } HttpClient httpClient = getNewhttpClient (); Httppost httppost = new httppost (url); intente {httppost.setEntity (new StringEntity (entidad)); httppost.setheader ("aceptar", "aplicación/json"); httppost.setheader ("Content-type", "Application/JSON"); Httpresponse resp = httpclient.execute (httppost); if (resp.getStatUsline (). getStatUscode ()! = httpstatus.sc_ok) {log.e (tag, "httpget fail, status code =" + resp.getstatusline (). getStatUscode ()); regresar nulo; } return entityUtils.tobytearray (resp.getEntity ()); } catch (excepción e) {log.e (etiqueta, "excepción httppost, e =" + e.getMessage ()); E.PrintStackTrace (); regresar nulo; }} // método para obtener cadena aleatoria public static string gennoncestr () {random random = new Random (); return md5.getMessageGest (String.ValueOf (Random.NextInt (10000)). GetBytes ()); } String private toxml (list <nameValuePair> params) {StringBuilder sb = new StringBuilder (); sb.append ("<xml>"); for (int i = 0; i <params.size (); i ++) {sb.append ("<" + params.get (i) .getName () + ">"); sb.append (params.get (i) .getValue ()); sb.append ("</" + params.get (i) .getName () + ">"); } sb.append ("</xml>"); return sb.ToString (); } MAP Public <String, String> DecodExml (String Content) {try {map <string, string> xml = new HashMap <> (); Xmlpullparser parser = xml.newpullparser (); parser.setInput (new StringReader (content)); int event = parser.getEventType (); while (event! = xmlpullparser.end_document) {string nodename = parser.getName (); switch (evento) {case xmlpullparser.start_document: break; case xmlpullparser.start_tag: if (! "xml" .equals (nodename)) {xml.put (nodename, parser.nextText ()); } romper; case xmlpullparser.end_tag: break; } event = parser.next (); } return xml; } catch (excepción e) {} return null; } @Nonnull Private List <NameValuePair> getFirstSignParams (wxprepost params) {list <NameValuePair> paquete de paquetes = new LinkedList <> (); paquete de paquetes.add (new BasicNameValuePair ("Appid", "Appid")); paquete de paquetes.add (new BasicNameValuePair ("Body", Params.body)); paquetes de paquetes.add (new BasicNameValuePair ("Detalle", Params.detail)); paquete de paquetes.add (new BasicNameValuePair ("MCH_ID", "Número de comerciante")); paquete de paquetes.add (new BasicNameValuePair ("nonce_str", params.nonce_str)); paquete de paquetes.add (new BasicNameValuePair ("Notify_url", params.notify_url)); paquete de paquetes.add (new BasicNameValuePair ("out_trade_no", params.out_trade_no)); paquete de paquetes.Add (new BasicNameValuePair ("Spbill_Create_ip", params.spbill_create_ip)); paquete de paquetes.add (new BasicNameValuePair ("Total_fee", params.total_fee + "")); paquete de paquetes.add (new BasicNameValuePair ("Trade_Type", params.trade_type)); paquete de paquetes.add (new BasicNameValuePair ("Sign", Params.sign)); return PackageParams; } clase pública wxprepost {// Los parámetros que deben traerse con Public String AppID; // Application AppID aprobado por WeChat Open Platform Public String Mch_id; // El número de comerciante asignado por WeChat Pay Public String nonce_str; // cadena aleatoria, no más de 32 dígitos. Algoritmo de generación de números aleatorios recomendado signo de cadena pública; // firma, consulte el algoritmo de la generación de firma Cuerpo de cadena pública; // Descripción del producto El formato de campo de transacción está de acuerdo con el siguiente formato de acuerdo con diferentes escenarios de la aplicación: Aplicación - Nombre de la aplicación que debe pasar al mercado de aplicaciones - Nombre real del producto, Tiantian Aiying Elimina - Recarga del juego. cadena pública out_trade_no; // El número de pedido dentro del sistema comercial, que puede contener letras dentro de 32 caracteres. Para otras instrucciones, consulte el número de orden comercial público int total_fee; // El monto total del pedido está en el centavo. Para obtener más detalles, consulte el monto de pago Cadena pública Spbill_Create_ip; // La cadena pública IP real notify_url; // La dirección de devolución de llamada para recibir notificaciones asíncronas de pago WeChat, la URL de notificación debe ser una URL directamente accesible y no puede transportar parámetros. (Proporcionado en segundo plano) cadena pública comercial_type; // Tipo de pago // parámetros que no se requiere que se transporten public String Device_info; // Número de dispositivo terminal (número de almacenamiento o ID de dispositivo de cajero), pase "Web" de forma predeterminada; // Detalles del nombre del producto Adjunto de cadena pública; // datos adicionales, devueltos como en la API de consulta y la notificación de pago. Este campo se utiliza principalmente para datos personalizados de comerciantes que llevan pedidos de la cadena pública Fee_Type; // Código de letra de tres dígitos que cumple con el estándar ISO 4217 RMB: CNY, consulte el tipo de moneda para otras listas de valor para obtener detalles // public String Time_start; // El tiempo de generación de pedidos es YYYYMMDDHHMMSS, como se muestra en 20091222091010, como se muestra en 200912225091010. Para otros detalles, consulte las reglas de tiempo // public String Time_EXPIRE; // Tiempo de vencimiento del pedido, el formato es YYYYMMDDHHMMSS, como se muestra en 20091227091010 a las 9:10 del 27 de diciembre de 2009. Consulte las reglas de tiempo para otros detalles. Nota: El intervalo de tiempo de vencimiento mínimo debe ser superior a 5 minutos. Public String Goods_tag; // Parámetros de etiquetas de producto, cupones o descuentos. Para más detalles, consulte los cupones o descuentos. // public String Limit_Pay; // NO_CREDIT-Especifique que no puede usar una tarjeta de crédito para pagar una cadena pública getAppid () {return AppID; } public void setAppid (String Appid) {this.appid = appid; } public String getMch_id () {return mch_id; } public void setmch_id (string mch_id) {this.mch_id = mch_id; } public String 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 getBody () {Body de retorno; } public void setBody (string body) {this.body = body; } public String getout_trade_no () {return out_trade_no; } public void setout_trade_no (string out_trade_no) {this.out_trade_no = out_trade_no; } public int getTotal_fee () {return Total_fee; } public void settotal_fee (int total_fee) {this.total_fee = total_fee; } cadena pública getSpbill_create_ip () {return spbill_create_ip; } public void setspbill_create_ip (string spbill_create_ip) {this.spbill_create_ip = spbill_create_ip; } public String getNotify_url () {return notify_url; } public void setNotify_url (String notify_url) {this.notify_url = notify_url; } public String getTrade_Type () {return trade_type; } public void settrade_type (string trade_type) {this.trade_type = trade_type; } public String getDevice_info () {return Device_info; } public void setDevice_info (String Device_info) {this.device_info = dispositivo_info; } public String getDetail () {detallado de retorno; } public void setDetail (detalle de cadena) {this.detail = detalle; } public String getAttach () {return adject; } public void setAttach (String adjunto) {this.attach = adjunto; } public String getFee_Type () {return fee_type; } public void setfee_type (string fee_type) {this.fee_type = fee_type; } public String getTime_start () {return time_start; } public void setTime_start (String Time_start) {this.time_start = time_start; } public String getTime_Eppire () {return Time_Eppire; } public void setTime_EXPIRE (String Time_Eppire) {this.time_expire = Time_Eppire; } public String getGoods_tag () {return Goods_tag; } public void setGoods_tag (String Goods_tag) {this.goods_tag = Goods_tag; } public String getLimit_pay () {return Limit_pay; } public void setLimit_pay (String Limit_Pay) {this.limit_pay = limit_pay; }}Los parámetros dados aquí pueden ser obtenidos por el terminal móvil. Por supuesto, es mejor proporcionarnos los antecedentes por razones de seguridad.
Después de completar el pago, WeChat volverá a llamar WXPayEntryactivity. No voy a entrar en detalles aquí. El documento de WeChat establece claramente los resultados del pago de WeChat devuelto en el OnResp () de wxpayentryactivity (nota: este resultado no puede ser el resultado de si compramos el producto con éxito. Debemos usar la devolución de llamada de WeChat al Estrecho de Taiwán y luego regresar al Estrecho de Taiwán para decirnos el resultado del pago).
if (resp.gettype () == constantsapi.command_pay_by_wx) {int code = resp.errcode; switch (código) {caso 0: log.d (etiqueta, "onpayfinish, errcode =" + "pay éxito"); // Después del pago de WeChat exitoso, vaya al fondo, el resultado del pago devuelto por los antecedentes es la base. // Esta es la devolución de llamada después de completar el pago de WeChat. Aquí hay una solicitud de antecedentes y pídele que nos diga si el pago es exitoso. romper; Caso -1: toast.maketext (esto, "Pay fallado 1", toast.length_short) .show (); Log.d (etiqueta, "onpayfinish, errcode =" + "pay fallido 1"); finalizar(); romper; caso -2: toast.maketext (this, "pay Cancel", toast.length_short) .show (); Log.d (etiqueta, "onpayfinish, errcode =" + "pay cancelar"); finalizar(); romper; predeterminado: // toast.maketext (this, "Pay Falling 2", toast.length_short) .show (); Log.d (etiqueta, "onpayfinish, errcode =" + "pay fallido 2"); setResult (result_ok); finalizar(); romper; }}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.