1. Primeiro solicite desenvolvimento e aplicação na plataforma aberta do WeChat. A plataforma Open WeChat gerará o Appid de identificação exclusiva do aplicativo. Como a segurança do pagamento é necessária, o nome do pacote de aplicativos do comerciante e a assinatura do aplicativo precisam estar vinculados à plataforma aberta, e o pagamento só pode ser iniciado normalmente depois de configurá -lo.
2. Registre o Appid (isso pode ser colocado no aplicativo do projeto)
O pacote WeChat Jar é introduzido no projeto de aplicativo comerciante. Antes de ligar para a API, você precisa registrar seu Appid no WeChat. O código é o seguinte:
final iwxapi msgapi = wxapifactory.createwxapi (context, null); // registre o aplicativo no weChat msgapi.registerApp ("wxd930a5d5a258f4f"); 3. Ligue para a API único unificado para gerar um pedido de pré -pagamento. Depois de obter o pré -pagamento, assine os parâmetros e transmita -os ao aplicativo para iniciar o pagamento.
exemplo:
O número do pedido no código a seguir precisa ser gerado em segundo plano
String url = "https://api.mch.weixin.qq.com/pay/unifiedorder"; WxPrepost post = new wxPrepost (); post.Appid = "Seu Appid"; post.mch_id = "seu número de comerciante"; post.nonce_str = stringUtils.gennoCest (); // string aleatória ** 1 post.body = "Nome do produto"; post.detail = "Descrição do produto"; post.out_trade_no = out_trade_no; // Número da ordem do comerciante ** 2 post.total_fee = "Preço da commodities"; // A unidade é dividida em post.spbill_create_ip = getLocalipaddress (); // endereço IP ** 3 post.notify_url = "; post.sign = genpackagesign (post); // assinatura ** 4 lista <NameValuepair> primeiroSignParams = getFirstSignParams (post); String xml = toxml (primeiroSignParams); Entidade de string = null; tente {entity = new String (xml.getBytes (), "ISO8859-1"); byte [] buf = util.httpPost (url, entidade); if (buf! = null) {string content = new String (buf); Mapa <string, string> map = decodexml (content); if (map! = null) {// assinar novamente (os campos que participam da assinatura são: Appid PartnerID PACOTO DE TIMESTAMP PRAPAYID PRAPAYID) String Appid = ""; String pré -anyid = ""; String noncestr = ""; para (map.entry <string, string> entrada: map.entrySet ()) {if ("Appid" .equals (entradas.getKey ())) {Appid = Entry.getValue (); } else if ("pré -any_id" .equals (entradas.getKey ())) {pré -yid = entrada.getValue (); } else if ("nonce_str" .equals (entradas.getKey ()))) {noncestr = entradas.getValue (); }} Log.d (tag, "RUN::" + Appid + "/" + pré -condyID + "/" + não -cest + "/"); String timestamp = string.valueof (gentiMestamp ()); // ok, obtenha a string de assinatura secundária SecondPackagesign = GensOndPackagesign (getSecondSignParams (Appid, PdayID, Non -CEST, Timestamp)); Payreq req = new PayReq (); req.appid = Appid; req.partnerid = "Número do comerciante"; req.PrepayId = pré -pagador; req.NoCestr = Non -Cest; req.timestamp = timestamp; req.packageValue = "signe = wxpay"; req.sign = SecondPackagesign; req.extData = "Dados do aplicativo"; // opcional // System.out.println ("GenPackagesign3:"+Post.getSign ()+"/"+SecondPackagesign); // Antes do pagamento, se o aplicativo não estiver registrado no WeChat, você deve primeiro ligar para iwxmsg.registerApp para registrar o aplicativo no weChat mapi.sendreq (req); Log.d (tag, "run:" + appid + "/" + pré -ayid + "/" + não -cest + "/" + timestamp + "/" + SecondPackagesign); }}} catch (Exceção e) {} public static byte [] httpPost (String url, string entity) {if (url == null || url.length () == 0) {log.e (tag, "httppost, url é nulo"); retornar nulo; } HttpClient httpClient = getNewHttpClient (); HttpPost httpPost = new httppost (url); tente {httppost.setentity (nova stringentity (entidade)); httppost.setheader ("aceitar", "aplicativo/json"); httppost.setheader ("content-type", "Application/json"); HttpResponse resp = httpclient.execute (httppost); if (resp.getStatusline (). getStatuscode ()! = httpstatus.sc_ok) {log.e (tag, "httpget falha, code =" + resp.getStatusLine (). getStatuscode ()); retornar nulo; } retornar entityutils.tobytearray (resp.getEntity ()); } catch (Exceção e) {log.e (tag, "Exceção httppot, e =" + e.getMessage ()); E.PrintStackTrace (); retornar nulo; }} // Método para obter string aleatória public static string gennoncest () {aleatório aleatória = new Random (); retornar md5.getMessagedigest (string.valueof (random.nextInt (10000)). getBytes ()); } private String 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 (); } mapa público <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 ()); } quebrar; case xmlpullParser.end_tag: break; } evento = parser.Next (); } retornar xml; } catch (Exceção e) {} retornar null; } @Nonnull Private List <NameValuepair> getFirstSignParams (parâmetros wxPrepost) {list <nameValuepair> packageParams = new LinkedList <> (); packageParams.add (new BasicNameValuepair ("Appid", "Appid")); packageParams.add (new BasicNameValuepair ("corpo", params.body)); packageParams.add (new BasicNameValuepair ("detalhe", params.detail)); packageParams.add (new BasicNameValuepair ("mch_id", "Número do comerciante")); packageParams.add (new BasicNameValuepair ("nonce_str", params.nonce_str)); packageParams.add (new BasicNameValuepair ("notify_url", params.notify_url)); packageParams.add (new BasicNameValuepair ("out_trade_no", params.out_trade_no)); packageParams.add (new BasicNameValuepair ("spbill_create_ip", params.spbill_create_ip)); packageParams.add (new BasicNameValuepair ("total_fee", params.total_fee + "")); packageParams.add (new BasicNameValuepair ("Trade_type", params.trade_type)); packageParams.add (new BasicNameValuepair ("sinal", params.sign)); retornar packageParams; } classe pública wxprepost {// Os parâmetros que devem ser trazidos com a string pública appid; // Application Appid aprovado pela plataforma WeChat Open Public String mch_id; // O número do comerciante atribuído pelo weChat paga public string nonce_str; // string aleatória, não mais que 32 dígitos. Algoritmo de geração de números aleatórios recomendados sinal de string pública; // assinatura, consulte o algoritmo de geração de assinatura Body String Body; // O formato do campo de transação da descrição do produto está de acordo com o seguinte formato, de acordo com diferentes cenários de aplicação: Nome do aplicativo - Nome do aplicativo que precisa ser passado para o mercado de aplicativos - nome real do produto, a Recarga de jogo do Tiantian Aiying. public string out_trade_no; // O número do pedido dentro do sistema de comerciantes, que pode conter letras dentro de 32 caracteres. Para outras instruções, consulte o número da ordem do comerciante public int total_fee; // O valor total da ordem está no centavo. Para detalhes, consulte o valor do pagamento public string spbill_create_ip; // o IP public string real notify_url; // O endereço de retorno de chamada para receber notificações assíncronas de pagamento do WeChat, o URL de notificação deve ser um URL diretamente acessível e não pode transportar parâmetros. (Fornecido em segundo plano) public string trade_type; // Tipo de pagamento // parâmetros que não precisam ser transportados de string public device_info; // Número do dispositivo do terminal (número do armazenamento ou ID do dispositivo de caixa), passe a "web" por padrão; // Detalhes do nome do produto Public String Anex; // dados adicionais, retornados como na API de consulta e notificação de pagamento. Este campo é usado principalmente para dados personalizados de comerciantes que transportam pedidos de string pública Fee_type; // Código de letra de três dígitos que cumpre com o padrão ISO 4217, padrão RMB: CNY, consulte o tipo de moeda para outras listas de valor para obter detalhes // public string time_start; // O tempo de geração de pedidos é yyyymmddhhmms, conforme mostrado em 20091225091010, conforme mostrado em 20091225091010. Para outros detalhes, consulte as regras do tempo // public string time_expire; // Tempo de expiração do pedido, o formato é yyyymmddhhmmss, conforme mostrado em 20091227091010 às 9:10 em 27 de dezembro de 2009. Consulte as regras de tempo para outros detalhes. Nota: O intervalo de tempo de expiração mínima deve ser superior a 5 minutos. Public string bens_tag; // Parâmetros de tags de produto, vouchers ou descontos com desconto. Para detalhes, consulte os vouchers ou descontos com descontos. // public string limite_pay; // no_credit-especifique que você não pode usar um cartão de crédito para pagar public string 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; } public string getSign () {retornar sinal; } public void Setsign (string signo) {this.sign = signe; } public string getBody () {retornar corpo; } 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; } public string 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 = device_info; } public string getDetail () {return detalhe; } public void setDetail (String detalhe) {this.Detail = detalhe; } public string getAttach () {return Anex; } public void setAtTach (string anex) {this.attach = anex; } public string getfee_type () {retorna taxa_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_expire () {return time_expire; } public void settime_expire (string time_expire) {this.time_expire = time_expire; } public string getgoods_tag () {return bens_tag; } public void setGoods_tag (string bens_tag) {this.goods_tag = bens_tag; } public string getlimit_pay () {return limite_pay; } public void Setlimit_pay (string limite_pay) {this.limit_pay = limite_pay; }}Os parâmetros fornecidos aqui podem ser obtidos pelo próprio terminal móvel. Obviamente, é melhor nos fornecer os antecedentes por razões de segurança.
Após a conclusão do pagamento, o WeChat ligará de volta WxPayEntryActivity. Não vou entrar em detalhes aqui. O documento do WeChat declara claramente os resultados do pagamento do WeChat devolvido no OnRESP () da WxPayEntryActivity (Nota: Este resultado não pode ser o resultado de comprarmos o produto com sucesso. Devemos usar o retorno de chamada do WeChat ao Estreito de Taiwan e depois retornar ao Estreito de Taiwan para nos dizer o resultado do pagamento).
if (resp.getType () == ConstantApi.Command_Pay_By_WX) {int code = resp.errcode; switch (código) {case 0: log.d (tag, "onPayfinish, errcode =" + "page sucesso"); // Após o pagamento do pagamento do WeChat, vá para o segundo plano, o resultado do pagamento retornado pelo plano de fundo é a base. // Este é o retorno de chamada após a conclusão do pagamento do WeChat. Aqui está um pedido para os antecedentes e peça que ele nos diga se o pagamento é bem -sucedido. quebrar; Caso -1: Toast.MakeText (isto, "Pay falhou 1", Toast.Length_Short) .Show (); Log.d (tag, "onPayfinish, errcode =" + "falha no pagamento 1"); terminar(); quebrar; Caso -2: Toast.MakeText (isto, "Pay Cancel", Toast.Length_Short) .Show (); Log.d (tag, "onPayfinish, errcode =" + "pay cancel"); terminar(); quebrar; padrão: // TOAST.MAKETEXT (isto, "Pay falhou 2", Toast.Length_Short) .Show (); Log.d (tag, "onPayfinish, errcode =" + "falha no pagamento 2"); setresult (resultado_ok); terminar(); quebrar; }}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.