天天看點

Android的支付接入(一):支付寶

相信相同過App擷取利潤的都會需要接入計費SDK,下邊就跟大家走一遍完整的支付寶SDK接入,支付系列均通過計費Button觸發,計費所有代碼均放到一個java檔案實作,這樣雖然會有點違背java面向對象及封裝性,但這樣做的一個好處是可以快速內建到不同的遊戲中,将改動的檔案降到最低,各有利弊吧,如果大家有什麼更好的方法,望一起交流,好了,廢話不多說了,開始幹活。

PS:初次寫博文,各方面還不夠完善,看到此博文的朋友有什麼意見或者建議請回複或者留言,你們的支援是我最大的動力。 注意事項 1.添加android.permission.INTERNET權限和android.permission.ACCESS_NETWORK_STATE權限 2.代碼中出現注釋的地方重點看,沒注釋的地方可以不看 3.想擷取支付寶合作商戶ID,及支付寶公鑰請點選支付寶連結,生成密鑰及PKCS8轉碼工具在文檔中 代碼   MainActivity:

[java]  view plain copy

  1. package com.example.blogforzfb;  
  2. import android.os.Bundle;  
  3. import android.view.View;  
  4. import android.app.Activity;  
  5. public class MainActivity extends Activity {  
  6.  @Override  
  7.  protected void onCreate(Bundle savedInstanceState) {  
  8.   super.onCreate(savedInstanceState);  
  9.   setContentView(R.layout.activity_main);  
  10.   findViewById(R.id.button1).setOnClickListener(  
  11.     new View.OnClickListener() {  
  12.      @Override  
  13.      public void onClick(View v) {  
  14.       // TODO Auto-generated method stub  
  15.       // 拿到Fiap對象并傳入容器  
  16.       Fiap fiap = new Fiap(MainActivity.this);  
  17.       // 調用支付方法,并傳入支付金額  
  18.       fiap.android_pay(0.01);  
  19.      }  
  20.     });  
  21.  }  
  22. }  

Fiap.java(支付邏輯所在檔案)   [java]  view plain copy

  1. package com.example.blogforzfb;  
  2. // 支付寶應用支付  
  3. // 2012-09-20 14:41:47  
  4. // (c) 2012 Catcap  
  5. import java.io.BufferedReader;  
  6. import java.io.File;  
  7. import java.io.FileOutputStream;  
  8. import java.io.IOException;  
  9. import java.io.InputStream;  
  10. import java.io.InputStreamReader;  
  11. import java.io.OutputStream;  
  12. import java.net.HttpURLConnection;  
  13. import java.net.InetSocketAddress;  
  14. import java.net.Proxy;  
  15. import java.net.URL;  
  16. import java.net.URLEncoder;  
  17. import java.security.KeyFactory;  
  18. import java.security.PrivateKey;  
  19. import java.security.PublicKey;  
  20. import java.security.spec.PKCS8EncodedKeySpec;  
  21. import java.security.spec.X509EncodedKeySpec;  
  22. import java.util.ArrayList;  
  23. import java.util.List;  
  24. import javax.net.ssl.HostnameVerifier;  
  25. import javax.net.ssl.HttpsURLConnection;  
  26. import javax.net.ssl.SSLSession;  
  27. import org.apache.http.client.entity.UrlEncodedFormEntity;  
  28. import org.apache.http.message.BasicNameValuePair;  
  29. import org.json.JSONException;  
  30. import org.json.JSONObject;  
  31. import com.alipay.android.app.IAlixPay;  
  32. import com.alipay.android.app.IRemoteServiceCallback;  
  33. import android.annotation.SuppressLint;  
  34. import android.app.Activity;  
  35. import android.app.AlertDialog;  
  36. import android.app.ProgressDialog;  
  37. import android.content.ComponentName;  
  38. import android.content.Context;  
  39. import android.content.DialogInterface;  
  40. import android.content.Intent;  
  41. import android.content.ServiceConnection;  
  42. import android.content.pm.PackageInfo;  
  43. import android.content.pm.PackageManager;  
  44. import android.net.ConnectivityManager;  
  45. import android.net.NetworkInfo;  
  46. import android.net.Uri;  
  47. import android.os.Bundle;  
  48. import android.os.Handler;  
  49. import android.os.IBinder;  
  50. import android.os.Looper;  
  51. import android.os.Message;  
  52. import android.os.RemoteException;  
  53. import android.util.Log;  
  54. import android.view.KeyEvent;  
  55. import android.widget.Toast;  
  56. @SuppressLint ("HandlerLeak")  
  57. public class Fiap{  
  58.     Activity mActivity = null;  
  59.     // ===================================  
  60.     // JAVA 的接口  
  61.     // ===================================  
  62.     public Fiap(Activity activity){  
  63.     mActivity = activity;  
  64.     }  
  65.     //這裡傳過來的是想支付多少錢(最好定義成double的,友善調試,畢竟每次測試都支付幾元大洋不是每個人都負擔的起的)  
  66.     public void android_pay (double coin){  
  67.     //支付寶支付必須依賴網絡,是以在這裡必須加網絡判定  
  68.         if (!is_can_internet (mActivity)){  
  69.             fiapHandler.sendEmptyMessage(1);  
  70.             return;  
  71.         }  
  72.         Message msg = new Message ();  
  73.         Bundle bundle = new Bundle();  
  74.         bundle.putDouble("coin", coin);  
  75.         msg.setData(bundle);  
  76.         msg.what = 1;  
  77.         fss.sendMessage (msg);  
  78.     }  
  79.     private Handler fiapHandler = new Handler(){  
  80.     public void handleMessage(Message msg) {  
  81.     if (msg.what == 1) {  
  82.     new AlertDialog.Builder (mActivity).setTitle ("提示").setMessage ("連接配接不到網絡。").setPositiveButton ("确定", new DialogInterface.OnClickListener() {  
  83. @Override  
  84. public void onClick(DialogInterface dialog, int which) {  
  85. // TODO Auto-generated method stub  
  86. Intent intent = new Intent(  
  87. "android.settings.WIFI_SETTINGS");  
  88. mActivity.startActivity(intent);  
  89. }  
  90. }).create ().show ();  
  91. }  
  92.     };  
  93.     };  
  94.     // ===================================  
  95.     // 支付寶  
  96.     // ===================================  
  97.     public class PartnerConfig {  
  98. //以下配置涉及到公司内容,是以略去,需自己配置  
  99.         // 合作商戶ID。用簽約支付寶賬号登入ms.alipay.com後,在賬戶資訊頁面擷取。  
  100.         public static final String PARTNER = "";   
  101.         // 商戶收款的支付寶賬号  
  102.         public static final String SELLER = "";  
  103.         // 商戶(RSA)私鑰(注意一定要轉PKCS8格式,否則在Android4.0及以上系統會支付失敗)  
  104.         public static final String RSA_PRIVATE = "";  
  105.         // 支付寶(RSA)公鑰用簽約支付寶賬号登入ms.alipay.com後,在密鑰管理頁面擷取。  
  106.         public static final String RSA_ALIPAY_PUBLIC = "";  
  107.     }  
  108.     private ProgressDialog mProgress = null;  
  109.     public static class AlixOnCancelListener implements DialogInterface.OnCancelListener {  
  110.         Activity mcontext;  
  111.         AlixOnCancelListener (Activity context){  
  112.             mcontext = context;  
  113.         }  
  114.         public void onCancel (DialogInterface dialog){  
  115.             mcontext.onKeyDown (KeyEvent.KEYCODE_BACK, null);  
  116.         }  
  117.     }  
  118.     private Handler fss = new Handler (){  
  119.         @SuppressWarnings ("deprecation")  
  120.         public void handleMessage (Message msg){  
  121.             MobileSecurePayHelper mspHelper = new MobileSecurePayHelper (mActivity);  
  122.             boolean isMobile_spExist = mspHelper.detectMobile_sp ();  
  123.             if (!isMobile_spExist)  
  124.                 return;  
  125.             // 根據訂單資訊開始進行支付  
  126.             try{  
  127.                 // 準備訂單資訊  
  128.                 Bundle bundle = msg.getData();  
  129.                 double _coin = bundle.getDouble("coin");  
  130.                 String orderInfo = getOrderInfo(_coin);  
  131.                 // 這裡根據簽名方式對訂單資訊進行簽名  
  132.                 String signType = getSignType ();  
  133.                 String strsign = sign (signType, orderInfo);  
  134.                 // 對簽名進行編碼  
  135.                 strsign = URLEncoder.encode (strsign);  
  136.                 // 組裝好參數  
  137.                 String info = orderInfo + "&sign=" + """ + strsign + """ + "&" + getSignType ();  
  138.                 // 調用pay方法進行支付  
  139.                 MobileSecurePayer msp = new MobileSecurePayer ();  
  140.                 boolean bRet = msp.pay (info, mHandler, AlixId.RQF_PAY, mActivity);  
  141.                 if (bRet){  
  142.                     // 顯示“正在支付”進度條  
  143.                     closeProgress ();  
  144.                     mProgress = BaseHelper.showProgress (mActivity, null, "正在支付", false, true);  
  145.                 }  
  146.             } catch (Exception ex){  
  147.                 ex.printStackTrace ();  
  148.             }  
  149.         }  
  150.     };  
  151.     private Handler mHandler = new Handler (){  
  152.         public void handleMessage (Message msg){  
  153.             try{  
  154.                 String strRet = (String) msg.obj;  
  155.                 switch (msg.what){  
  156.                     case AlixId.RQF_PAY:{  
  157.                         //  
  158.                         closeProgress ();  
  159.                         // 處理交易結果  
  160.                         try{  
  161.                             // 擷取交易狀态碼,具體狀态代碼請參看文檔  
  162.                             String tradeStatus = "resultStatus={";  
  163.                             int imemoStart = strRet.indexOf ("resultStatus=");  
  164.                             imemoStart += tradeStatus.length ();  
  165.                             int imemoEnd = strRet.indexOf ("};memo=");  
  166.                             tradeStatus = strRet.substring (imemoStart, imemoEnd);  
  167.                             //先驗簽通知  
  168.                             ResultChecker resultChecker = new ResultChecker (strRet);  
  169.                             int retVal = resultChecker.checkSign ();  
  170.                             if (retVal == ResultChecker.RESULT_CHECK_SIGN_FAILED){  
  171.                                 BaseHelper.showDialog (mActivity, "提示", "您的訂單資訊已被非法篡改。", android.R.drawable.ic_dialog_alert);  
  172.                             } else{  
  173.                                 if (tradeStatus.equals ("9000")){  
  174.                                     //程式到這裡表示支付已經成功了,想幹什麼就在這裡幹吧 -v-  
  175.                                 Toast.makeText(mActivity, "支付成功",Toast.LENGTH_LONG).show();  
  176.                                 Log.i("result of this pay:", "successful");  
  177.                                 } else if (!tradeStatus.equals ("4000")){  
  178.                                 //程式到這裡表示此次支付失敗,檢視具體原因可以從這裡列印個log  
  179.                                 Toast.makeText(mActivity, "支付失敗,交易狀态碼為:" + tradeStatus, Toast.LENGTH_LONG).show();  
  180.                                 Log.e("result of this pay", "falied");  
  181.                                 }  
  182.                             }  
  183.                         } catch (Exception e){  
  184.                             e.printStackTrace ();  
  185.                         }  
  186.                     }  
  187.                         break;  
  188.                 }  
  189.                 super.handleMessage (msg);  
  190.             } catch (Exception e){  
  191.                 e.printStackTrace ();  
  192.             }  
  193.         }  
  194.     };  
  195.     String getSignType (){  
  196.         String getSignType = "sign_type=" + """ + "RSA" + """;  
  197.         return getSignType;  
  198.     }  
  199.     void closeProgress (){  
  200.         try{  
  201.             if (mProgress != null){  
  202.                 mProgress.dismiss ();  
  203.                 mProgress = null;  
  204.             }  
  205.         } catch (Exception e){  
  206.             e.printStackTrace ();  
  207.         }  
  208.     }  
  209.     String getOrderInfo (double position){  
  210.         String strOrderInfo = "partner=" + """ + PartnerConfig.PARTNER + """;  
  211.         strOrderInfo += "&";  
  212.         strOrderInfo += "seller=" + """ + PartnerConfig.SELLER + """;  
  213.         strOrderInfo += "&";  
  214.         strOrderInfo += "out_trade_no=" + """ + get_order_id () + """;  
  215.         strOrderInfo += "&";  
  216.         //這裡是顯示到支付寶支付界面上的付費資訊提示(這裡一定要嚴格按照此格式填寫)  
  217.         strOrderInfo += "subject=" + ""貓币"";  
  218.         strOrderInfo += "&";  
  219.         strOrderInfo += "body=" + ""購買貓币"";  
  220.         strOrderInfo += "&";  
  221.         strOrderInfo += "total_fee=" + """ + position + """;  
  222.         strOrderInfo += "&";  
  223.         strOrderInfo += "notify_url=" + """ + "http://notify.java.jpxx.org/index.jsp" + """;  
  224.         return strOrderInfo;  
  225.     }  
  226.     String sign (String signType, String content){  
  227.         return Rsa.sign (content, PartnerConfig.RSA_PRIVATE);  
  228.     }  
  229.     public boolean is_can_internet (final Context context){  
  230.         try{  
  231.             ConnectivityManager manger = (ConnectivityManager) context.getSystemService (Context.CONNECTIVITY_SERVICE);  
  232.             NetworkInfo info = manger.getActiveNetworkInfo ();  
  233.             return (info != null && info.isConnected ());  
  234.         } catch (Exception e){  
  235.             return false;  
  236.         }  
  237.     }  
  238.     public String get_order_id (){  
  239.         long ran1 = get_round (1111, 9999);  
  240.         long ran2 = get_round (1111, 9999);  
  241.         //注掉的這裡是傳回的管道号(我們用的友盟)+随機數和目前系統時間組合  
  242.         //return android_get_umeng_channel () + "_" + ran1 + System.currentTimeMillis () + ran2;  
  243.         return "_"+ran1 + System.currentTimeMillis () + ran2;  
  244.     }  
  245.     public long get_round (int min, int max){  
  246.         return Math.round (Math.random () * (max - min) + min);  
  247.     }  
  248.      =================================================================================================  
  249.     //   
  250.     // 支付寶不用動的  
  251.     // ==================================================================================================  
  252.     public final class AlixId {  
  253.         public static final int BASE_ID = 0;  
  254.         public static final int RQF_PAY = BASE_ID + 1;  
  255.         public static final int RQF_INSTALL_CHECK = RQF_PAY + 1;  
  256.     }  
  257.     final class AlixDefine {  
  258.         public static final String IMEI = "imei";  
  259.         public static final String IMSI = "imsi";  
  260.         public static final String KEY = "key";  
  261.         public static final String USER_AGENT = "user_agent";  
  262.         public static final String VERSION = "version";  
  263.         public static final String DEVICE = "device";  
  264.         public static final String SID = "sid";  
  265.         public static final String partner = "partner";  
  266.         public static final String charset = "charset";  
  267.         public static final String sign_type = "sign_type";  
  268.         public static final String sign = "sign";  
  269.         public static final String URL = "URL";  
  270.         public static final String split = "&";  
  271.         public static final String AlixPay = "AlixPay";  
  272.         public static final String action = "action";  
  273.         public static final String actionUpdate = "update";  
  274.         public static final String data = "data";  
  275.         public static final String platform = "platform";  
  276.     }  
  277.     public static final class Base64 {  
  278.         static private final int BASELENGTH = 128;  
  279.         static private final int LOOKUPLENGTH = 64;  
  280.         static private final int TWENTYFOURBITGROUP = 24;  
  281.         static private final int EIGHTBIT = 8;  
  282.         static private final int SIXTEENBIT = 16;  
  283.         static private final int FOURBYTE = 4;  
  284.         static private final int SIGN = -128;  
  285.         static private final char PAD = '=';  
  286.         static private final boolean fDebug = false;  
  287.         static final private byte[] base64Alphabet = new byte[BASELENGTH];  
  288.         static final private char[] lookUpBase64Alphabet = new char[LOOKUPLENGTH];  
  289.         static{  
  290.             for (int i = 0; i < BASELENGTH; ++i){  
  291.                 base64Alphabet[i] = -1;  
  292.             }  
  293.             for (int i = 'Z'; i >= 'A'; i--){  
  294.                 base64Alphabet[i] = (byte) (i - 'A');  
  295.             }  
  296.             for (int i = 'z'; i >= 'a'; i--){  
  297.                 base64Alphabet[i] = (byte) (i - 'a' + 26);  
  298.             }  
  299.             for (int i = '9'; i >= '0'; i--){  
  300.                 base64Alphabet[i] = (byte) (i - '0' + 52);  
  301.             }  
  302.             base64Alphabet['+'] = 62;  
  303.             base64Alphabet['/'] = 63;  
  304.             for (int i = 0; i <= 25; i++){  
  305.                 lookUpBase64Alphabet[i] = (char) ('A' + i);  
  306.             }  
  307.             for (int i = 26, j = 0; i <= 51; i++, j++){  
  308.                 lookUpBase64Alphabet[i] = (char) ('a' + j);  
  309.             }  
  310.             for (int i = 52, j = 0; i <= 61; i++, j++){  
  311.                 lookUpBase64Alphabet[i] = (char) ('0' + j);  
  312.             }  
  313.             lookUpBase64Alphabet[62] = (char) '+';  
  314.             lookUpBase64Alphabet[63] = (char) '/';  
  315.         }  
  316.         private static boolean isWhiteSpace (char octect){  
  317.             return (octect == 0x20 || octect == 0xd || octect == 0xa || octect == 0x9);  
  318.         }  
  319.         private static boolean isPad (char octect){  
  320.             return (octect == PAD);  
  321.         }  
  322.         private static boolean isData (char octect){  
  323.             return (octect < BASELENGTH && base64Alphabet[octect] != -1);  
  324.         }  
  325.         public static String encode (byte[] binaryData){  
  326.             if (binaryData == null){  
  327.                 return null;  
  328.             }  
  329.             int lengthDataBits = binaryData.length * EIGHTBIT;  
  330.             if (lengthDataBits == 0){  
  331.                 return "";  
  332.             }  
  333.             int fewerThan24bits = lengthDataBits % TWENTYFOURBITGROUP;  
  334.             int numberTriplets = lengthDataBits / TWENTYFOURBITGROUP;  
  335.             int numberQuartet = fewerThan24bits != 0? numberTriplets + 1 : numberTriplets;  
  336.             char encodedData[] = null;  
  337.             encodedData = new char[numberQuartet * 4];  
  338.             byte k = 0, l = 0, b1 = 0, b2 = 0, b3 = 0;  
  339.             int encodedIndex = 0;  
  340.             int dataIndex = 0;  
  341.             if (fDebug){  
  342.                 System.out.println ("number of triplets = " + numberTriplets);  
  343.             }  
  344.             for (int i = 0; i < numberTriplets; i++){  
  345.                 b1 = binaryData[dataIndex++];  
  346.                 b2 = binaryData[dataIndex++];  
  347.                 b3 = binaryData[dataIndex++];  
  348.                 if (fDebug){  
  349.                     System.out.println ("b1= " + b1 + ", b2= " + b2 + ", b3= " + b3);  
  350.                 }  
  351.                 l = (byte) (b2 & 0x0f);  
  352.                 k = (byte) (b1 & 0x03);  
  353.                 byte val1 = ((b1 & SIGN) == 0)? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);  
  354.                 byte val2 = ((b2 & SIGN) == 0)? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0);  
  355.                 byte val3 = ((b3 & SIGN) == 0)? (byte) (b3 >> 6) : (byte) ((b3) >> 6 ^ 0xfc);  
  356.                 if (fDebug){  
  357.                     System.out.println ("val2 = " + val2);  
  358.                     System.out.println ("k4   = " + (k << 4));  
  359.                     System.out.println ("vak  = " + (val2 | (k << 4)));  
  360.                 }  
  361.                 encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];  
  362.                 encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)];  
  363.                 encodedData[encodedIndex++] = lookUpBase64Alphabet[(l << 2) | val3];  
  364.                 encodedData[encodedIndex++] = lookUpBase64Alphabet[b3 & 0x3f];  
  365.             }  
  366.             // form integral number of 6-bit groups  
  367.             if (fewerThan24bits == EIGHTBIT){  
  368.                 b1 = binaryData[dataIndex];  
  369.                 k = (byte) (b1 & 0x03);  
  370.                 if (fDebug){  
  371.                     System.out.println ("b1=" + b1);  
  372.                     System.out.println ("b1<<2 = " + (b1 >> 2));  
  373.                 }  
  374.                 byte val1 = ((b1 & SIGN) == 0)? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);  
  375.                 encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];  
  376.                 encodedData[encodedIndex++] = lookUpBase64Alphabet[k << 4];  
  377.                 encodedData[encodedIndex++] = PAD;  
  378.                 encodedData[encodedIndex++] = PAD;  
  379.             } else if (fewerThan24bits == SIXTEENBIT){  
  380.                 b1 = binaryData[dataIndex];  
  381.                 b2 = binaryData[dataIndex + 1];  
  382.                 l = (byte) (b2 & 0x0f);  
  383.                 k = (byte) (b1 & 0x03);  
  384.                 byte val1 = ((b1 & SIGN) == 0)? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);  
  385.                 byte val2 = ((b2 & SIGN) == 0)? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0);  
  386.                 encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];  
  387.                 encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)];  
  388.                 encodedData[encodedIndex++] = lookUpBase64Alphabet[l << 2];  
  389.                 encodedData[encodedIndex++] = PAD;  
  390.             }  
  391.             return new String (encodedData);  
  392.         }  
  393.         public static byte[] decode (String encoded){  
  394.             if (encoded == null){  
  395.                 return null;  
  396.             }  
  397.             char[] base64Data = encoded.toCharArray ();  
  398.             // remove white spaces  
  399.             int len = removeWhiteSpace (base64Data);  
  400.             if (len % FOURBYTE != 0){  
  401.                 return null;// should be divisible by four  
  402.             }  
  403.             int numberQuadruple = (len / FOURBYTE);  
  404.             if (numberQuadruple == 0){  
  405.                 return new byte[0];  
  406.             }  
  407.             byte decodedData[] = null;  
  408.             byte b1 = 0, b2 = 0, b3 = 0, b4 = 0;  
  409.             char d1 = 0, d2 = 0, d3 = 0, d4 = 0;  
  410.             int i = 0;  
  411.             int encodedIndex = 0;  
  412.             int dataIndex = 0;  
  413.             decodedData = new byte[(numberQuadruple) * 3];  
  414.             for (; i < numberQuadruple - 1; i++){  
  415.                 if (!isData ((d1 = base64Data[dataIndex++])) || !isData ((d2 = base64Data[dataIndex++])) || !isData ((d3 = base64Data[dataIndex++])) || !isData ((d4 = base64Data[dataIndex++]))){  
  416.                     return null;  
  417.                 }// if found "no data" just return null  
  418.                 b1 = base64Alphabet[d1];  
  419.                 b2 = base64Alphabet[d2];  
  420.                 b3 = base64Alphabet[d3];  
  421.                 b4 = base64Alphabet[d4];  
  422.                 decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);  
  423.                 decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));  
  424.                 decodedData[encodedIndex++] = (byte) (b3 << 6 | b4);  
  425.             }  
  426.             if (!isData ((d1 = base64Data[dataIndex++])) || !isData ((d2 = base64Data[dataIndex++]))){  
  427.                 return null;// if found "no data" just return null  
  428.             }  
  429.             b1 = base64Alphabet[d1];  
  430.             b2 = base64Alphabet[d2];  
  431.             d3 = base64Data[dataIndex++];  
  432.             d4 = base64Data[dataIndex++];  
  433.             if (!isData ((d3)) || !isData ((d4))){// Check if they are PAD characters  
  434.                 if (isPad (d3) && isPad (d4)){  
  435.                     if ((b2 & 0xf) != 0)// last 4 bits should be zero  
  436.                     {  
  437.                         return null;  
  438.                     }  
  439.                     byte[] tmp = new byte[i * 3 + 1];  
  440.                     System.arraycopy (decodedData, 0, tmp, 0, i * 3);  
  441.                     tmp[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);  
  442.                     return tmp;  
  443.                 } else if (!isPad (d3) && isPad (d4)){  
  444.                     b3 = base64Alphabet[d3];  
  445.                     if ((b3 & 0x3) != 0)// last 2 bits should be zero  
  446.                     {  
  447.                         return null;  
  448.                     }  
  449.                     byte[] tmp = new byte[i * 3 + 2];  
  450.                     System.arraycopy (decodedData, 0, tmp, 0, i * 3);  
  451.                     tmp[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);  
  452.                     tmp[encodedIndex] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));  
  453.                     return tmp;  
  454.                 } else{  
  455.                     return null;  
  456.                 }  
  457.             } else{ // No PAD e.g 3cQl  
  458.                 b3 = base64Alphabet[d3];  
  459.                 b4 = base64Alphabet[d4];  
  460.                 decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);  
  461.                 decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));  
  462.                 decodedData[encodedIndex++] = (byte) (b3 << 6 | b4);  
  463.             }  
  464.             return decodedData;  
  465.         }  
  466.         private static int removeWhiteSpace (char[] data){  
  467.             if (data == null){  
  468.                 return 0;  
  469.             }  
  470.             // count characters that's not whitespace  
  471.             int newSize = 0;  
  472.             int len = data.length;  
  473.             for (int i = 0; i < len; i++){  
  474.                 if (!isWhiteSpace (data[i])){  
  475.                     data[newSize++] = data[i];  
  476.                 }  
  477.             }  
  478.             return newSize;  
  479.         }  
  480.     }  
  481.     public static class BaseHelper {  
  482.         public static String convertStreamToString (InputStream is){  
  483.             BufferedReader reader = new BufferedReader (new InputStreamReader (is));  
  484.             StringBuilder sb = new StringBuilder ();  
  485.             String line = null;  
  486.             try{  
  487.                 while ((line = reader.readLine ()) != null){  
  488.                     sb.append (line);  
  489.                 }  
  490.             } catch (IOException e){  
  491.                 e.printStackTrace ();  
  492.             } finally{  
  493.                 try{  
  494.                     is.close ();  
  495.                 } catch (IOException e){  
  496.                     e.printStackTrace ();  
  497.                 }  
  498.             }  
  499.             return sb.toString ();  
  500.         }  
  501.         public static void showDialog (Activity context, String strTitle, String strText, int icon){  
  502.             AlertDialog.Builder tDialog = new AlertDialog.Builder (context);  
  503.             tDialog.setIcon (icon);  
  504.             tDialog.setTitle (strTitle);  
  505.             tDialog.setMessage (strText);  
  506.             tDialog.setPositiveButton ("确定", null);  
  507.             tDialog.show ();  
  508.         }  
  509.         public static void log (String tag, String info){  
  510.             // Log.d(tag, info);  
  511.         }  
  512.         public static void chmod (String permission, String path){  
  513.             try{  
  514.                 String command = "chmod " + permission + " " + path;  
  515.                 Runtime runtime = Runtime.getRuntime ();  
  516.                 runtime.exec (command);  
  517.             } catch (IOException e){  
  518.                 e.printStackTrace ();  
  519.             }  
  520.         }  
  521.         //  
  522.         // show the progress bar.  
  523.         public static ProgressDialog showProgress (Context context, CharSequence title, CharSequence message, boolean indeterminate, boolean cancelable){  
  524.             ProgressDialog dialog = new ProgressDialog (context);  
  525.             dialog.setTitle (title);  
  526.             dialog.setMessage (message);  
  527.             dialog.setIndeterminate (indeterminate);  
  528.             dialog.setCancelable (false);  
  529.             // dialog.setDefaultButton(false);  
  530.             dialog.setOnCancelListener (new Fiap.AlixOnCancelListener ((Activity) context));  
  531.             dialog.show ();  
  532.             return dialog;  
  533.         }  
  534.         public static JSONObject string2JSON (String str, String split){  
  535.             JSONObject json = new JSONObject ();  
  536.             try{  
  537.                 String[] arrStr = str.split (split);  
  538.                 for (int i = 0; i < arrStr.length; i++){  
  539.                     String[] arrKeyValue = arrStr[i].split ("=");  
  540.                     json.put (arrKeyValue[0], arrStr[i].substring (arrKeyValue[0].length () + 1));  
  541.                 }  
  542.             } catch (Exception e){  
  543.                 e.printStackTrace ();  
  544.             }  
  545.             return json;  
  546.         }  
  547.     }  
  548.     public class Constant {  
  549.         public final static String server_url = "https://msp.alipay.com/x.htm";  
  550.     }  
  551.     public class MobileSecurePayer {  
  552.         Integer lock = 0;  
  553.         IAlixPay mAlixPay = null;  
  554.         boolean mbPaying = false;  
  555.         Activity mActivity = null;  
  556.         // 和安全支付服務建立連接配接  
  557.         private ServiceConnection mAlixPayConnection = new ServiceConnection (){  
  558.             public void onServiceConnected (ComponentName className, IBinder service){  
  559.                 //  
  560.                 // wake up the binder to continue.  
  561.                 // 獲得通信通道  
  562.                 synchronized (lock){  
  563.                     mAlixPay = IAlixPay.Stub.asInterface (service);  
  564.                     lock.notify ();  
  565.                 }  
  566.             }  
  567.             public void onServiceDisconnected (ComponentName className){  
  568.                 mAlixPay = null;  
  569.             }  
  570.         };  
  571.         public boolean pay (final String strOrderInfo, final Handler callback, final int myWhat, final Activity activity){  
  572.             if (mbPaying)  
  573.                 return false;  
  574.             mbPaying = true;  
  575.             //  
  576.             mActivity = activity;  
  577.             // bind the service.  
  578.             // 綁定服務  
  579.             if (mAlixPay == null){  
  580.                 // 綁定安全支付服務需要擷取上下文環境,  
  581.                 // 如果綁定不成功使用mActivity.getApplicationContext().bindService  
  582.                 // 解綁時同理  
  583.                 mActivity.getApplicationContext ().bindService (new Intent (IAlixPay.class.getName ()), mAlixPayConnection, Context.BIND_AUTO_CREATE);  
  584.             }  
  585.             // else ok.  
  586.             // 執行個體一個線程來進行支付  
  587.             new Thread (new Runnable (){  
  588.                 public void run (){  
  589.                     try{  
  590.                         // wait for the service bind operation to completely  
  591.                         // finished.  
  592.                         // Note: this is important,otherwise the next mAlixPay.Pay()  
  593.                         // will fail.  
  594.                         // 等待安全支付服務綁定操作結束  
  595.                         // 注意:這裡很重要,否則mAlixPay.Pay()方法會失敗  
  596.                         synchronized (lock){  
  597.                             if (mAlixPay == null)  
  598.                                 lock.wait ();  
  599.                         }  
  600.                         // register a Callback for the service.  
  601.                         // 為安全支付服務注冊一個回調  
  602.                         mAlixPay.registerCallback (mCallback);  
  603.                         // call the MobileSecurePay service.  
  604.                         // 調用安全支付服務的pay方法  
  605.                         String strRet = mAlixPay.Pay (strOrderInfo);  
  606.                         // set the flag to indicate that we have finished.  
  607.                         // unregister the Callback, and unbind the service.  
  608.                         // 将mbPaying置為false,表示支付結束  
  609.                         // 移除回調的注冊,解綁安全支付服務  
  610.                         mbPaying = false;  
  611.                         mAlixPay.unregisterCallback (mCallback);  
  612.                         mActivity.getApplicationContext ().unbindService (mAlixPayConnection);  
  613.                         // send the result back to caller.  
  614.                         // 發送交易結果  
  615.                         Message msg = new Message ();  
  616.                         msg.what = myWhat;  
  617.                         msg.obj = strRet;  
  618.                         callback.sendMessage (msg);  
  619.                     } catch (Exception e){  
  620.                         e.printStackTrace ();  
  621.                         // send the result back to caller.  
  622.                         // 發送交易結果  
  623.                         Message msg = new Message ();  
  624.                         msg.what = myWhat;  
  625.                         msg.obj = e.toString ();  
  626.                         callback.sendMessage (msg);  
  627.                     }  
  628.                 }  
  629.             }).start ();  
  630.             return true;  
  631.         }  
  632.         private IRemoteServiceCallback mCallback = new IRemoteServiceCallback.Stub (){  
  633.             public void startActivity (String packageName, String className, int iCallingPid, Bundle bundle) throws RemoteException{  
  634.                 Intent intent = new Intent (Intent.ACTION_MAIN, null);  
  635.                 if (bundle == null)  
  636.                     bundle = new Bundle ();  
  637.                 // else ok.  
  638.                 try{  
  639.                     bundle.putInt ("CallingPid", iCallingPid);  
  640.                     intent.putExtras (bundle);  
  641.                 } catch (Exception e){  
  642.                     e.printStackTrace ();  
  643.                 }  
  644.                 intent.setClassName (packageName, className);  
  645.                 mActivity.startActivity (intent);  
  646.             }  
  647.             @Override  
  648.             public boolean isHideLoadingScreen () throws RemoteException{  
  649.                 return false;  
  650.             }  
  651.             @Override  
  652.             public void payEnd (boolean arg0, String arg1) throws RemoteException{  
  653.             }  
  654.         };  
  655.     }  
  656.     public class MobileSecurePayHelper {  
  657.         static final String TAG = "MobileSecurePayHelper";  
  658.         private ProgressDialog mProgress = null;  
  659.         Context mContext = null;  
  660.         public MobileSecurePayHelper (Context context){  
  661.             this.mContext = context;  
  662.         }  
  663.         public boolean detectMobile_sp (){  
  664.             boolean isMobile_spExist = isMobile_spExist ();  
  665.             if (!isMobile_spExist){  
  666.                 // 擷取系統緩沖絕對路徑擷取/data/data//cache目錄  
  667.                 File cacheDir = mContext.getCacheDir ();  
  668.                 final String cachePath = cacheDir.getAbsolutePath () + "/temp.apk";  
  669.                 mProgress = BaseHelper.showProgress (mContext, null, "正在檢測安全支付服務版本", false, true);  
  670.                 // 執行個體新線程檢測是否有新版本進行下載下傳  
  671.                 new Thread (new Runnable (){  
  672.                     public void run (){  
  673.                         // 檢測是否有新的版本。  
  674.                         String newApkdlUrl = checkNewUpdate ();  
  675.                         closeProgress ();  
  676.                         // 動态下載下傳  
  677.                         if (newApkdlUrl != null)  
  678.                             retrieveApkFromNet (mContext, newApkdlUrl, cachePath);  
  679.                         showInstallConfirmDialog (mContext, cachePath);  
  680.                     }  
  681.                 }).start ();  
  682.             }  
  683.             return isMobile_spExist;  
  684.         }  
  685.         public void showInstallConfirmDialog (final Context context, final String cachePath){  
  686.             Looper.prepare ();  
  687.             AlertDialog.Builder tDialog = new AlertDialog.Builder (context);  
  688.             tDialog.setTitle ("安裝提示");  
  689.             tDialog.setMessage ("為保證您的交易安全,需要您安裝支付寶安全支付服務,才能進行付款。\n\n點選确定,立即安裝。");  
  690.             tDialog.setPositiveButton ("确定", new DialogInterface.OnClickListener (){  
  691.                 public void onClick (DialogInterface dialog, int which){  
  692.                     //  
  693.                     // 修改apk權限  
  694.                     BaseHelper.chmod ("777", cachePath);  
  695.                     //  
  696.                     // install the apk.  
  697.                     // 安裝安全支付服務APK  
  698.                     Intent intent = new Intent (Intent.ACTION_VIEW);  
  699.                     intent.addFlags (Intent.FLAG_ACTIVITY_NEW_TASK);  
  700.                     intent.setDataAndType (Uri.parse ("file://" + cachePath), "application/vnd.android.package-archive");  
  701.                     context.startActivity (intent);  
  702.                 }  
  703.             });  
  704.             tDialog.setNegativeButton ("取消", new DialogInterface.OnClickListener (){  
  705.                 public void onClick (DialogInterface dialog, int which){}  
  706.             });  
  707.             tDialog.show ();  
  708.             Looper.loop ();  
  709.         }  
  710.         public boolean isMobile_spExist (){  
  711.             PackageManager manager = mContext.getPackageManager ();  
  712.             List<PackageInfo> pkgList = manager.getInstalledPackages (0);  
  713.             for (int i = 0; i < pkgList.size (); i++){  
  714.                 PackageInfo pI = pkgList.get (i);  
  715.                 if (pI.packageName.equalsIgnoreCase ("com.alipay.android.app"))  
  716.                     return true;  
  717.             }  
  718.             return false;  
  719.         }  
  720.         public boolean retrieveApkFromAssets (Context context, String fileName, String path){  
  721.             boolean bRet = false;  
  722.             try{  
  723.                 InputStream is = context.getAssets ().open (fileName);  
  724.                 File file = new File (path);  
  725.                 file.createNewFile ();  
  726.                 FileOutputStream fos = new FileOutputStream (file);  
  727.                 byte[] temp = new byte[1024];  
  728.                 int i = 0;  
  729.                 while ((i = is.read (temp)) > 0){  
  730.                     fos.write (temp, 0, i);  
  731.                 }  
  732.                 fos.close ();  
  733.                 is.close ();  
  734.                 bRet = true;  
  735.             } catch (IOException e){  
  736.                 e.printStackTrace ();  
  737.             }  
  738.             return bRet;  
  739.         }  
  740.         public PackageInfo getApkInfo (Context context, String archiveFilePath){  
  741.             PackageManager pm = context.getPackageManager ();  
  742.             PackageInfo apkInfo = pm.getPackageArchiveInfo (archiveFilePath, PackageManager.GET_META_DATA);  
  743.             return apkInfo;  
  744.         }  
  745.         public String checkNewUpdate (){  
  746.             String url = null;  
  747.             try{  
  748. //                JSONObject resp = sendCheckNewUpdate (packageInfo.versionName);  
  749.                  JSONObject resp = sendCheckNewUpdate("1.0.0");  
  750.                 if (resp.getString ("needUpdate").equalsIgnoreCase ("true")){  
  751.                     url = resp.getString ("updateUrl");  
  752.                 }  
  753.                 // else ok.  
  754.             } catch (Exception e){  
  755.                 e.printStackTrace ();  
  756.             }  
  757.             return url;  
  758.         }  
  759.         public JSONObject sendCheckNewUpdate (String versionName){  
  760.             JSONObject objResp = null;  
  761.             try{  
  762.                 JSONObject req = new JSONObject ();  
  763.                 req.put (AlixDefine.action, AlixDefine.actionUpdate);  
  764.                 JSONObject data = new JSONObject ();  
  765.                 data.put (AlixDefine.platform, "android");  
  766.                 data.put (AlixDefine.VERSION, versionName);  
  767.                 data.put (AlixDefine.partner, "");  
  768.                 req.put (AlixDefine.data, data);  
  769.                 objResp = sendRequest (req.toString ());  
  770.             } catch (JSONException e){  
  771.                 e.printStackTrace ();  
  772.             }  
  773.             return objResp;  
  774.         }  
  775.         public JSONObject sendRequest (final String content){  
  776.             NetworkManager nM = new NetworkManager (this.mContext);  
  777.             //  
  778.             JSONObject jsonResponse = null;  
  779.             try{  
  780.                 String response = null;  
  781.                 synchronized (nM){  
  782.                     //  
  783.                     response = nM.SendAndWaitResponse (content, Constant.server_url);  
  784.                 }  
  785.                 jsonResponse = new JSONObject (response);  
  786.             } catch (Exception e){  
  787.                 e.printStackTrace ();  
  788.             }  
  789.             //  
  790.             if (jsonResponse != null)  
  791.                 BaseHelper.log (TAG, jsonResponse.toString ());  
  792.             return jsonResponse;  
  793.         }  
  794.         public boolean retrieveApkFromNet (Context context, String strurl, String filename){  
  795.             boolean bRet = false;  
  796.             try{  
  797.                 NetworkManager nM = new NetworkManager (this.mContext);  
  798.                 bRet = nM.urlDownloadToFile (context, strurl, filename);  
  799.             } catch (Exception e){  
  800.                 e.printStackTrace ();  
  801.             }  
  802.             return bRet;  
  803.         }  
  804.         //  
  805.         // close the progress bar  
  806.         void closeProgress (){  
  807.             try{  
  808.                 if (mProgress != null){  
  809.                     mProgress.dismiss ();  
  810.                     mProgress = null;  
  811.                 }  
  812.             } catch (Exception e){  
  813.                 e.printStackTrace ();  
  814.             }  
  815.         }  
  816.     }  
  817.     public class NetworkManager {  
  818.         static final String TAG = "NetworkManager";  
  819.         private int connectTimeout = 30 * 1000;  
  820.         private int readTimeout = 30 * 1000;  
  821.         Proxy mProxy = null;  
  822.         Context mContext;  
  823.         public NetworkManager (Context context){  
  824.             this.mContext = context;  
  825.             setDefaultHostnameVerifier ();  
  826.         }  
  827.         @SuppressWarnings ("deprecation")  
  828.         private void detectProxy (){  
  829.             ConnectivityManager cm = (ConnectivityManager) mContext.getSystemService (Context.CONNECTIVITY_SERVICE);  
  830.             NetworkInfo ni = cm.getActiveNetworkInfo ();  
  831.             if (ni != null && ni.isAvailable () && ni.getType () == ConnectivityManager.TYPE_MOBILE){  
  832.                 String proxyHost = android.net.Proxy.getDefaultHost ();  
  833.                 int port = android.net.Proxy.getDefaultPort ();  
  834.                 if (proxyHost != null){  
  835.                     final InetSocketAddress sa = new InetSocketAddress (proxyHost, port);  
  836.                     mProxy = new Proxy (Proxy.Type.HTTP, sa);  
  837.                 }  
  838.             }  
  839.         }  
  840.         private void setDefaultHostnameVerifier (){  
  841.             //  
  842.             HostnameVerifier hv = new HostnameVerifier (){  
  843.                 public boolean verify (String hostname, SSLSession session){  
  844.                     return true;  
  845.                 }  
  846.             };  
  847.             HttpsURLConnection.setDefaultHostnameVerifier (hv);  
  848.         }  
  849.         public String SendAndWaitResponse (String strReqData, String strUrl){  
  850.             //  
  851.             detectProxy ();  
  852.             String strResponse = null;  
  853.             ArrayList<BasicNameValuePair> pairs = new ArrayList<BasicNameValuePair> ();  
  854.             pairs.add (new BasicNameValuePair ("requestData", strReqData));  
  855.             HttpURLConnection httpConnect = null;  
  856.             UrlEncodedFormEntity p_entity;  
  857.             try{  
  858.                 p_entity = new UrlEncodedFormEntity (pairs, "utf-8");  
  859.                 URL url = new URL (strUrl);  
  860.                 if (mProxy != null){  
  861.                     httpConnect = (HttpURLConnection) url.openConnection (mProxy);  
  862.                 } else{  
  863.                     httpConnect = (HttpURLConnection) url.openConnection ();  
  864.                 }  
  865.                 httpConnect.setConnectTimeout (connectTimeout);  
  866.                 httpConnect.setReadTimeout (readTimeout);  
  867.                 httpConnect.setDoOutput (true);  
  868.                 httpConnect.addRequestProperty ("Content-type", "application/x-www-form-urlencoded;charset=utf-8");  
  869.                 httpConnect.connect ();  
  870.                 OutputStream os = httpConnect.getOutputStream ();  
  871.                 p_entity.writeTo (os);  
  872.                 os.flush ();  
  873.                 InputStream content = httpConnect.getInputStream ();  
  874.                 strResponse = BaseHelper.convertStreamToString (content);  
  875.                 BaseHelper.log (TAG, "response " + strResponse);  
  876.             } catch (IOException e){  
  877.                 e.printStackTrace ();  
  878.             } finally{  
  879.                 httpConnect.disconnect ();  
  880.             }  
  881.             return strResponse;  
  882.         }  
  883.         public boolean urlDownloadToFile (Context context, String strurl, String path){  
  884.             boolean bRet = false;  
  885.             //  
  886.             detectProxy ();  
  887.             try{  
  888.                 URL url = new URL (strurl);  
  889.                 HttpURLConnection conn = null;  
  890.                 if (mProxy != null){  
  891.                     conn = (HttpURLConnection) url.openConnection (mProxy);  
  892.                 } else{  
  893.                     conn = (HttpURLConnection) url.openConnection ();  
  894.                 }  
  895.                 conn.setConnectTimeout (connectTimeout);  
  896.                 conn.setReadTimeout (readTimeout);  
  897.                 conn.setDoInput (true);  
  898.                 conn.connect ();  
  899.                 InputStream is = conn.getInputStream ();  
  900.                 File file = new File (path);  
  901.                 file.createNewFile ();  
  902.                 FileOutputStream fos = new FileOutputStream (file);  
  903.                 byte[] temp = new byte[1024];  
  904.                 int i = 0;  
  905.                 while ((i = is.read (temp)) > 0){  
  906.                     fos.write (temp, 0, i);  
  907.                 }  
  908.                 fos.close ();  
  909.                 is.close ();  
  910.                 bRet = true;  
  911.             } catch (IOException e){  
  912.                 e.printStackTrace ();  
  913.             }  
  914.             return bRet;  
  915.         }  
  916.     }  
  917.     public class ResultChecker {  
  918.         public static final int RESULT_INVALID_PARAM = 0;  
  919.         public static final int RESULT_CHECK_SIGN_FAILED = 1;  
  920.         public static final int RESULT_CHECK_SIGN_SUCCEED = 2;  
  921.         String mContent;  
  922.         public ResultChecker (String content){  
  923.             this.mContent = content;  
  924.         }  
  925.         int checkSign (){  
  926.             int retVal = RESULT_CHECK_SIGN_SUCCEED;  
  927.             try{  
  928.                 JSONObject objContent = BaseHelper.string2JSON (this.mContent, ";");  
  929.                 String result = objContent.getString ("result");  
  930.                 result = result.substring (1, result.length () - 1);  
  931.                 // 擷取待簽名資料  
  932.                 int iSignContentEnd = result.indexOf ("&sign_type=");  
  933.                 String signContent = result.substring (0, iSignContentEnd);  
  934.                 // 擷取簽名  
  935.                 JSONObject objResult = BaseHelper.string2JSON (result, "&");  
  936.                 String signType = objResult.getString ("sign_type");  
  937.                 signType = signType.replace (""", "");  
  938.                 String sign = objResult.getString ("sign");  
  939.                 sign = sign.replace (""", "");  
  940.                 // 進行驗簽 傳回驗簽結果  
  941.                 if (signType.equalsIgnoreCase ("RSA")){  
  942.                     if (!Rsa.doCheck (signContent, sign, PartnerConfig.RSA_ALIPAY_PUBLIC))  
  943.                         retVal = RESULT_CHECK_SIGN_FAILED;  
  944.                 }  
  945.             } catch (Exception e){  
  946.                 retVal = RESULT_INVALID_PARAM;  
  947.                 e.printStackTrace ();  
  948.             }  
  949.             return retVal;  
  950.         }  
  951.     }  
  952.     public static class Rsa {  
  953.         public static final String SIGN_ALGORITHMS = "SHA1WithRSA";  
  954.         public static String sign (String content, String privateKey){  
  955.             String charset = "utf-8";  
  956.             try{  
  957.                 PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec (Base64.decode (privateKey));  
  958.                 KeyFactory keyf = KeyFactory.getInstance ("RSA");  
  959.                 PrivateKey priKey = keyf.generatePrivate (priPKCS8);  
  960.                 java.security.Signature signature = java.security.Signature.getInstance (SIGN_ALGORITHMS);  
  961.                 signature.initSign (priKey);  
  962.                 signature.update (content.getBytes (charset));  
  963.                 byte[] signed = signature.sign ();  
  964.                 return Base64.encode (signed);  
  965.             } catch (Exception e){  
  966.                 e.printStackTrace ();  
  967.             }  
  968.             return null;  
  969.         }  
  970.         public static boolean doCheck (String content, String sign, String publicKey){  
  971.             try{  
  972.                 KeyFactory keyFactory = KeyFactory.getInstance ("RSA");  
  973.                 byte[] encodedKey = Base64.decode (publicKey);  
  974.                 PublicKey pubKey = keyFactory.generatePublic (new X509EncodedKeySpec (encodedKey));  
  975.                 java.security.Signature signature = java.security.Signature.getInstance (SIGN_ALGORITHMS);  
  976.                 signature.initVerify (pubKey);  
  977.                 signature.update (content.getBytes ("utf-8"));  
  978.                 boolean bverify = signature.verify (Base64.decode (sign));  
  979.                 return bverify;  
  980.             } catch (Exception e){  
  981.                 e.printStackTrace ();  
  982.             }  
  983.             return false;  
  984.         }  
  985.     }  
  986. }  

以上即為支付寶SDK的接入流程

繼續閱讀