最近、私は自分の仕事でWeChatの支払いについていくつかのことにさらされました。私が与えたデモはすべてPHPバージョンであることがわかりました、そして、私はWeChatの支払い文書に本当に満足していませんでした。多くの落とし穴を経験した後、私は要約をするためにアイドル状態になりました。
1。準備
WeChatを開発するには、最初に公開アカウントを申請する必要があります。アプリケーションが成功した後、メールで送信されます。パブリックアカウントには、開発文書、開発中の必要な情報、およびテストのためのデータクエリが含まれています。
2。ツール
1.MD5暗号化ツールクラス
パッケージcom.pay.utils.weixin; Import java.security.messagegest; public class md5util {public final static string md5(string s){char hexdigits [] = {'0'、 '1'、 '2'、 '3'、 '4'、 '5'、 '6'、 '7'、 '8'、 '9'、 ''、 'b'、 'c'、 'd'、 'e'、 'f'}; try {byte [] btinput = s.getBytes(); // MD5ダイジェストアルゴリズムのMESSAGED GIGEST MDINST = MESSAGEDGEST.GETINSTANCE( "MD5")のMESSAGEDGESTオブジェクトを取得します。 // Digest mdinst.update(btinput)を更新します。 // ciphertext byte [] md = mdinst.digest()を取得します。 // ciphertextを16進ストリングフォームint j = md.lengthに変換します。 char str [] = new char [j * 2]; int k = 0; for(int i = 0; i <j; i ++){byte byte0 = md [i]; str [k ++] = hexdigits [byte0 >>> 4&0xf]; str [k ++] = hexdigits [byte0&0xf]; } new String(str)を返します。 } catch(Exception e){e.printstacktrace(); nullを返します。 }}}2。WeChatに必要なXMLを交換するために使用されるCommonUtilツールクラス。次のreturn new String(xml.toString()。getBytes()、 "ISO8859-1");ツールクラスのUTF-8をISO8859-1に変更します。そうしないと、WeChat順序の中国のテキストが文字化けされ、変更後に正しく表示できます。
パッケージcom.pay.utils.weixin; Import java.io.unsupportedencodingincection; Import java.net.urlencoder; import java.util。*; import java.util.map.entry; public class commonutil {public Static String CreateNonCestre){String Chars = chars "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789";文字列res = ""; for(int i = 0; i <length; i ++){random rd = new Random(); res += chars.indexof(rd.nextint(chars.length()-1)); } RESを返します。 } public static string createNoncestr(){string chars = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789";文字列res = ""; for(int i = 0; i <16; i ++){random rd = new Random(); res += chars.charat(rd.nextint(chars.length() - 1)); } RESを返します。 } public static string formatqueryparamap(hashmap <string、string>パラメーター)sdkruntimeexception {string buff = ""; try {list <map.entry <string、string >> infoids = new arraylist <map.entry <string、string >>(parameters.entryset()); collections.sort(infoids、new Comparator <map.entry <string、string >>(){public int compare(map.entry <string、string> o1、map.entry <string、string> o2){return(o1.getkey())。 for(int i = 0; i <infoids.size(); i ++){map.entry <string、string> item = infoids.get(i); if(item.getKey()!= ""){buff + = item.getKey() + "=" + urlencoder.encode(item.getValue()、 "utf-8") + "&"; }} if(buff.isempty()== false){buff = buff.substring(0、buff.length() - 1); }} catch(Exception e){新しいsdkruntimeexception(e.getmessage()); } return buff; } public static string formatbizqueryparamap(hashmap <string、string> paramap、boolean urlencode)throws sdkruntimeexception {string buff = ""; try {list <map.entry <string、string >> infoids = new arraylist <map.entry <string、string >>(paramap.entryset()); collections.sort(infoids、new Comparator <map.entry <string、string >>(){public int compare(map.entry <string、string> o1、map.entry <string、string> o2){return(o1.getkey())。 for(int i = 0; i <infoids.size(); i ++){map.entry <string、string> item = infoids.get(i); //system.out.println(item.getKey()); if(item.getKey()!= ""){string key = item.getKey();文字列val = item.getValue(); if(urlencode){val = urlencoder.encode(val、 "utf-8"); } buff + = key.tolowercase() + "=" + val + "&"; }} if(buff.isempty()== false){buff = buff.substring(0、buff.length() - 1); }} catch(Exception e){新しいsdkruntimeexception(e.getmessage()); } return buff; } public static boolean isNumeric(string str){if(str.matches( "// d *")){return true; } else {return false; }} public static string arraytoxml(hashmap <string、string> arr){string xml = "<xml>"; iterator <entry <string、string >> iter = arr.entryset()。iterator(); while(iter.hasnext()){entry <string、string> entry = iter.next();文字列key = entry.getKey();文字列val = entry.getValue(); if(isnumeric(val)){xml + = "<" + key + ">" + "</" + key + ">"; } else xml + = "<" + key + "> <![cdata [" + val + "]]> </" + key + ">"; } xml += "</xml>"; try {return new String(xml.toString()。getBytes()、 "ISO8859-1"); } catch(unsupportedencodingexception e){// todo auto-enerated catch block e.printstacktrace(); } 戻る ""; }}3.ClientCustomSSLツールクラス。サインを生成し、WeChat Orderパッケージcom.pay.utils.weixinを作成するために使用されます。
java.util.arraylist; Import java.util.collections; import java.util.comparator; import java.util.util.list; Import java.util.map; import org.springframework.util.tringutils; */public class clientcustomsSl {public static string getBizsign(hashmap <string、string> bizobj)throws sdkruntimeexception {hashmap <string、string> bizparameters = new hashmap <string、string>(); List <Map.Entry <String、String >> infoids = new ArrayList <Map.Entry <String、String >>(bizobj.entryset()); System.out.println(infoids); collections.sort(infoids、new Comparator <map.entry <string、string >>(){public int compare(map.entry <string、string> o1、map.entry <string、string> o2){o1.getKey())。 System.out.println(infoids); for(int i = 0; i <infoids.size(); i ++){map.entry <string、string> item = infoids.get(i); if(item.getKey()!= ""){bizparameters.put(item.getKey()。tolowercase()、item.getValue()); }} //bizparameters.put("key "、" 1234567812345678123456781234567812345671 "); string bizstring = commonutil.formatbizqueryparamap(bizparameters、false); bizString += "&key = 123456781234567812345671"; System.out.println( "***************"); System.out.println(bizstring); // sha1util.sha1(bizstring); md5util.md5(bizstring)を返します。 } / ** * wechat create order * @param noncestr * @param orderdescribe * @param orderno * @param timestart * @param timeexpire * @throws sdkruntimeexception * / public static string CreateNativePackage(String Orderdescripe、String odry、String desscripe、String odry createNativePackage) sdkruntimeexception {hashmap <string、string> nativeobj = new hashmap <string、string>(); Nativeobj.put( "appid"、 "パブリックアカウントを参照"); // publicアカウントID nativeobj.put( "mch_id"、 "see email"); // merchant number nativeobj.put( "nonce_str"、noncestr); //ランダム文字列nativeobj.put( "body"、orderdescribe); //製品説明nativeobj.put( "attach"、 "tradeno"); //添付データnativeobj.put( "out_trade_no"、orderno); //マーチャントオーダー番号(グローバルユニーク)nativeobj.put( "total_fee"、price); //合計金額(単位はセントで、小数点で取得できません)natimalobj.put( "spbill_create_ip"、 "192.168.0.144"); // Terminal IP Nativeobj.put( "time_start"、timestart); //トランザクション開始時間nativeobj.put( "time_expire"、timeExpire); //トランザクションの終了時間nativeobj.put( "notify_url"、customizedpropertyplaceholderconfigurer.getContextProperty( "wxurl")+"/weixin_callback/weixincallback/init.action"); // callback通知アドレスNativeobj.put( "trade_type"、 "native"); //トランザクションタイプ文字列sign = getBizsign(nativeobj); Nativeobj.put( "sign"、sign.touppercase()); return commonutil.arraytoxml(nativeobj); } /*** wechat注文支払いQuery* @param noncestr* @param Orderdescribe* @param Orderno* @Param Timestart* @Param TimeExpire* @Throws SDKRUNTIMEEXCEPTION* /PUBLIC STATIC STRING SEARCHNATINEPACKAGE(STRING TRANDENO、STRING OUTTRADENO、STRING NONCESTRIE) {hashmap <string、string> nativeobj = new hashmap <string、string>(); nativeobj.put( "appid"、 "see public councount"); //パブリックアカウントidnativeobj.put( "mch_id"、 "ememail"); // merchant number nativeobj.put( "nonce_str"、noncestr); //ランダム文字列if(!stringutils.isempty(transactionId)){nativeobj.put( "transaction_id"、transactionId); } if(!stringutils.isempty(outtradeno)){nativeobj.put( "out_trade_no"、outtradeno); //ランダム文字列}文字列sign = getBizsign(nativeobj); nativeobj.put( "sign"、sign.touppercase()); return commonutil.arraytoxml(nativeobj); /*** wechat refund* @param outtradeno* @param outrefundno* @param totalfee* @param totalfee* @param refundfee* @return* @throws sdkruntimeexception*/public static string refundinativepackage(string outtradeno、string outrefundno、String outrefundno、String、String、String refundfee、 sdkruntimeexception {hashmap <string、string> nativeobj = new hashmap <string、string>(); nativeobj.put( "appid"、 "see publicアカウント"); //パブリックアカウントidnativeobj.put( "mch_id"、 "see email"); Nativeobj.put( "out_trade_no"、outtradeno); // merchant order number(global inquire)nativeobj.put( "out_refund_no"、outrefundno); // merchant refund order number(global sinqueobj.put( "total_fee"、totalfee); Nativeobj.put( "refund_fee"、refundfee); // refund額(セントの単位、小数点を取ることはできません)natimalobj.put( "op_user_id"、 "mail"); string sign = getbizsign(nativeobj); Nativeobj.put( "sign"、sign.touppercase()); return commonutil.arraytoxml(nativeobj);}/*** wechatは支払われますcreatejsapipackage(string noncestr、string orderdescribe、string orderno、string price、string timestart、string timexpire、string openid)throws sdkruntimeexception {hashmap <string、string> nativeobj = new hashmap <string、string、string>(); natidobj.put( OpenID); //パブリックアカウントIDNATIVEOBJ.PUT( "MCH_ID"、 "See Email")// Merchant Number Nativeobj.put( "nonce_str"、noncestr); // random String nativeobj.put( "body"、orderdescribe); Orderno); // Merchant Order Number(Global Unique)nativeobj.put( "total_fee"、rice); //合計金額(ユニットはセント、小数点を取ることはできません)natimobj.put( "spbill_create_ip"、 "192.168.0.144"); Nativeobj.put( "time_expire"、timeExpire)//トランザクション終了時間nativeobj.put( "notify_url"、customizedpropertyplaceholderconfigurer.getContextProperty( "wxurl")+"/weixin_callback/weixincallback/incurtion); "jsapi"); //トランザクションタイプ文字列sign = getBizsign(nativeobj); nativeobj.put( "sign"、sign.touppercase()); return commonutil.arraytoxml(artobj);}/*** wechat* @param noncestr* @param orderdescribe* @param orderno* @param price* @param timestart* @param openid* @param openid* @return* @thruntimeexception*/public Straden optradeno( sdkruntimeexception {hashmap <string、string> washmap <string、string>(); nativeobj.put( "appid"、 "publicアカウント") (グローバルに一意)nativeobj.put( "nonce_str"、noncestr "、noncestr); //ランダム文字列sign = getbizsign(nativeobj); nativeobj.put(" sign "、sign.touppercase()); return commonutil.arraytoxml(nativeobj);}} 4. WeChat Payment Interfaceを呼び出します
パッケージcom.pay.controller.weixin; Import java.io.file; import java.io.fileinputStream; import java.security.keyStore; Import java.text.simpledateformat; Import java.util.date; Import Java.util.list; Import Javax.net.net.net.net.ssl.sl.sl.sl.sl.sl.sl.sl.sl.sl.sl.sl.sl.sl.sl.sl.sl.sl.sl.sl.sl.sl.sl.sl.sl.sl.sl.sl.sl.sl.sl.sl.sl.sl.sl. javax.servlet.http.httpservletrequest; Import javax.servlet.http.httpservletresponse; Import net.sf.json.jsonarray; Import net.sf.json.jsonobject; Import org.apache.http.httpentity; Import; org.apache.http.client.methods.closeablehttpresponse; Import org.apache.http.client.methods.httppost; Import org.apache.http.conn.ssl.sslconnectionSocketAftory; Import org.apache.http.conn.ssl.slconts; apache.http.entity.stringentity; Import org.apache.http.impl.client.closablehttpclient; Import org.apache.http.impl.client.httpclient; Import org.apache.http.util.entityutils; Import org.dom4j.document; org.dom4j.documenthelper; import org.dom4j.element; Import org.dom4j.io.saxreader; Import org.springframework.beans.factory.annotation.autowired; import org.springframework.http.httpstatus; import.springframework; org.springframework.web.bind.annotation.requestmapping; Import org.springframework.web.bind.annotation.requestmethod; import org.springframework.web.bind.annotation.ansponsestatus; Import org.springframework.web.bind.annotation.rest.Restcontation com.pay.bo.payhistants.import com.pay.constants.payhistorypaystatus; import com.pay.constants.payhistorypaytype; import com.pay.service.weixinpayservice; import com.pay.utils.weixin.clientCustOSSL;インポートcom.pay.utils.weixin.closeweixinoderutils;インポートcom.pay.utils.weixin.customizedplopertyplaceholderconfigurer;@restcontroller@requestmapping( "/pay")public class weixinpaycontroller {@autowired weixinervice weixinpayservice; Private Static Long StandardTime = 1662652800000L; /** * QRコードを生成するURLを返します * @param request * @param Response * @return */@RequestMapping(value = "/getUrl"、method = requestmethod.post)@responsestatus(httpstatus.ok)public object geturl(httpservletresponse responsens @requestbody string jsono = Jsono jsonobject.fromobject(body); Payhist ph = null; // list <map <string、object >> td = weixinpayservice.gettrade(orderno);日付dt = new date(); SimpleDateFormat sdf = new SimpledateFormat( "yyyymmddhhmmss"); string noncestr = sdf.format(dt).toString();日付= new date(); string tredepayno = jsono.get( "orderno")。toString()+string.format( "%10d"、stardandtime -now.gettime())。サブストリング(0、10); system.out.println( "订单标号orderno ======="+jsono.get( "orderno")。toString()); System.out.println( "10位随机数======="+string.format( "%10d"、stardandtime -now.gettime())。サブストリング(0、10)); string rice = math.round(float.valueof(jsono.get( "price")。toString())*100)+""; long timeExpireStrold = dt.getTime(); long timeNew = long.parselong(customizedpropertyplaceholderconfigurer.getContextProperty( "weixin.send2finish.overtime")。toString()); long timeexpirenew = timeexpireStrold+timeNew;日付dttimeexpire = new Date(TimeExpirenew); SimpleDateFormat dtsdf = new SimpledateFormat( "yyyymmdhhmmss"); string timeExpire = dtsdf.format(dttimeexpire).toString(); system.out.println( "noncestr =="+noncestr); system.out.println( "orderno =="+jsono.get( "orderno")。toString()); System.out.println( "price =="+price); system.out.println( "timestart =="+noncestr); System.out.println( "timeExpire =="+timeExpire); jsonobject result =(jsonobject)seturl(noncestr "、order"、tredepayno、price、noncestr、timexpire); if(result.get( "status")。toString()。equals( "success")){ph = new Payhist(); ph.settradepayurl(result.getString( "weixinpayurl")); //このフィールドは支払いリンクです。 QRコードを生成してコードをスキャンしてPh.setPaytradeno(jsono.get( "orderno")。toString())を支払うことができます。 ph.settradepayno(tredepayno); Ph.SetPayStatus(PayHistoryPayStatus.Wechat_Pay_status_Wait); Ph.SetPayType(PayhistoryPayType.Wechat); ph.setappkey(jsono.getString( "appkey")。toString()); Ph.SetPayAmount(価格); result.put( "paytradeno"、ph.getpaytradeno()); result.put( "tredepayno"、ph.gettradepayno()); result.put( "paystatus"、ph.getpaystatus()); result.put( "paytype"、ph.getPayType()); } return result; } catch(Exception e){e.printstacktrace(); jsonObject result = new jsonobject(); result.put( "status"、 "error"); result.put( "msg"、e.getmessage()); // return result.toString(); } nullを返します。 } public object seturl(string noncestr、string orderdescribe、string orderno、string rice、string timestart、string timexpire){try {keystore keystore = keystore.getInstance( "pkcs12"); fileInputStream entream = new fileInputStream(new file(weChat証明書の絶対パス)); try {keystore.load(instream、 "merchant id" .tochararray()); }最後に{enterstream.close(); } //信頼しているCAおよびすべての自己署名証明書SSLCONTEXT SSLCONTEXT = SSLCONTEXTS.CUSTOM()。loadKeymaterial(keystore、<span style = "font-family:arial、helvetica、sans-serif;"> merchant id </span> .tochararray())。 // TLSV1プロトコルのみを許可するSSLConnectionSocketFactory SSLSF = new SSLConnectionSocketFactory(SSLContext、new String [] {"Tlsv1"}、null、sslConnectionSocketSocketFactory.Allow_all_hostname_verifier); closeablehttpclient httpclient = httpclient.custom().setsslsocketfactory(sslsf).build(); // httpget httpget = new // httpget( "https://api.mch.weixin.qq.com/secapi/pay/refund"); httppost httppost = new httppost( "https://api.mch.weixin.qq.com/pay/unidedorder"); string xml = client -customssl.createnativePackage(noncestr、orderdescribe、orderno、price、timestart、timexpire); try {Stringentity SE = new Stringentity(XML); httppost.setentity(se); system.out.println( "requestの実行" + httppost.getRequestline()); CLOSEABLEHTTPRESPONSE RESPONSENENTRY = HTTPCLIENT.EXECUTE(HTTPPOST); try {httpentity entity = responsentry.getEntity(); System.out.println("----------------------------------------"); system.out.println(ResponseTentry.getStatusline()); if(entity!= null){system.out.println( "応答コンテンツ長:" + entity.getContentLength()); /* BufferedReader BufferedReader = new BufferedReader(new inputStreamReader(entity.getContent()));文字列テキスト; while((text = bufferedreader.readline())!= null){system.out.println( "=================="+text); }*/ saxreader saxreader = new Saxreader(); document document = saxreader.read(entity.getContent());要素rootelt = document.getRootelement(); System.out.println( "root node:" + rootelt.getName()); System.out.println( "==="+rootelt.ElementText( "result_code")); system.out.println( "==="+rootelt.ElementText( "return_msg")); string resultCode = rootelt.ElementText( "result_code"); jsonObject result = new jsonobject(); documentxml = documenthelper.parsetext(xml);要素rooteltxml = documentxml.getRootelement(); if(resultCode.equals( "success")){system.out.println( "========================================================================================= System.out.println( "===================================================================== result.put( "weixinpayurl"、rootelt.elementText( "code_url")); result.put( "prepayid"、rootelt.elementText( "prepay_id")); result.put( "status"、 "success"); result.put( "msg"、 "success"); } else {result.put( "status"、 "false"); result.put( "msg"、rootelt.elementText( "err_code_des")); } return result; } entityutils.consume(entity); }最後に{ResponseTentry.Close(); }}最後に{httpclient.close(); } nullを返します。 } catch(Exception e){e.printstacktrace(); jsonObject result = new jsonobject(); result.put( "status"、 "error"); result.put( "msg"、e.getmessage());返品結果; }}} httpclient jarパッケージとJSON JARパッケージ:アドレスをダウンロードします。
上記はこの記事のすべての内容です。みんなの学習に役立つことを願っています。誰もがwulin.comをもっとサポートすることを願っています。