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.   
  3. import android.os.Bundle;  
  4. import android.view.View;  
  5. import android.app.Activity;  
  6.   
  7. public class MainActivity extends Activity {  
  8.   
  9.  @Override  
  10.  protected void onCreate(Bundle savedInstanceState) {  
  11.   super.onCreate(savedInstanceState);  
  12.   setContentView(R.layout.activity_main);  
  13.   findViewById(R.id.button1).setOnClickListener(  
  14.     new View.OnClickListener() {  
  15.      @Override  
  16.      public void onClick(View v) {  
  17.       // TODO Auto-generated method stub  
  18.       // 拿到Fiap对象并传入容器  
  19.       Fiap fiap = new Fiap(MainActivity.this);  
  20.       // 调用支付方法,并传入支付金额  
  21.       fiap.android_pay(0.01);  
  22.      }  
  23.     });  
  24.  }  
  25.   
  26. }  

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

以上即为支付宝SDK的接入流程
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值