轉-android 支付寶SDK集成

 

http://blog.csdn.net/kroclin/article/details/40746779java

1、前言android

最近作的項目恰好要集成支付寶,上網找了不少資料,介紹得感受不是很全面,因此我通過這兩天的集成,順便記錄下來,學習交流。須要的朋友也能夠看看。主要集成仍是參照了官方給出的demo,再參照demo進行封裝,如今使用起來變得方便好多。並且文章裏面還提到了集成過程當中遇到的一些問題,固然最後也都解決了。安全

 

2、準備工做app

支付寶開放平臺上面也明確了,目前僅僅支持企業用戶申請,因此我的開發者就無法使用到。但願支付寶早日能夠開放給我的開發者。學習

 

支付寶的集成是相對比較麻煩,其中涉及到了不少東西要弄,要生成私鑰公鑰等等。文檔裏面也有詳細說到如何如何生成那些東西,不過就是文檔的內容量有點多了,看起來總抓不住先後,這裏我稍做整理,把android須要用到的提取出來了。測試

一、PIDui

首先說一下就是支付寶的支付是這樣的,企業用戶申請了支付寶以後,支付寶就會提供一個合做者id,就是所謂的pid,是2088開頭的16位純數字;編碼

二、支付寶帳戶url

這個就是你用於收款用的支付寶帳號,要跟申請時候同一個。spa

 

如下幾個要運行我附件中的「移動支付接口智能SDK版"中,\openssl\bin文件夾下面的openssl.exe生成,這個是由支付寶提供的

三、RSA私鑰:genrsa -out rsa_private_key.pem 1024

運行完命令行能夠看到bin文件夾下面會生成私鑰

 

四、RSA公鑰:rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem

運行完命令行後能夠看到生成了公鑰

 

五、PKCS8編碼的私鑰:pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt

運行完後,將生成的東西拷貝下來放到文本文件裏面就行。這後面要用到的!!包括begin跟end那兩句一塊兒存起來

 

3、支付過程

須要進行再封裝的主要有下面這個類,作幾點說明,AliPayParamsBO是我封裝的一個實體類,由於我把剛剛上面講到的那些PID、私鑰啊等等都放在服務端了,這樣會比較安全,就算別人反編譯了你的項目,那也看不到什麼東西,支付寶官方也是這樣建議的。測試的時候,能夠把這個AliPayParamsBO類,裝進你生成的那些參數去測試就好啦,至於OrderBO類,也是我封裝的一個類,裏面主要包含的是這個訂單相關的一些東西,好比商品名稱、商品介紹,價格等等,這些在支付過程當中都是必要的。

而須要強調一點就是,產生這個支付過程當中,我先是構造好須要請求的參數,注意一點就是我在createOrderInfo()方法中對參數進行構造,可是 sign、sign_type 兩個參數先不要參與,由於這兩個參數不須要參與簽名,等前面那些參數構造好了以後,簽完名再將sign、sign_type 兩個參數構造進去,再進行支付。

 

[java]  view plain copy
 
  1. import java.io.UnsupportedEncodingException;  
  2. import java.net.URLEncoder;  
  3.   
  4. import android.os.Handler;  
  5. import android.os.Message;  
  6.   
  7. import com.alipay.android.app.sdk.AliPay;  
  8. import com.common.ui.BaseActivity;  
  9. import com.common.utils.CLog;  
  10. import com.onecity.cs.bo.AliPayParamsBO;  
  11. import com.onecity.cs.bo.OrderBO;  
  12.   
  13. /** 
  14.  * @author 林楷鵬 
  15.  * @description 支付寶相關操做 
  16.  * @create 2014-11-1下午12:11:20 
  17.  *  
  18.  */  
  19. public class AlipayUtil {  
  20.       
  21.     private static final String TAG = "PayActivity";  
  22.     public static final int RQF_PAY = 1;  
  23.     public static final int RQF_LOGIN = 2;  
  24.       
  25.       
  26.     public static void pay(final BaseActivity activity, AliPayParamsBO aliPayBO, OrderBO orderBO, final Handler handler){  
  27.         try {  
  28.             String info = createOrderInfo(orderBO, aliPayBO);  
  29.             String sign = Rsa.sign(info, aliPayBO.getPrivate_key_pkcs8());  
  30.             sign = URLEncoder.encode(sign, "utf-8");  
  31.             info += "&sign=\"" + sign + "\"&" + getSignType();  
  32.             CLog.log("ExternalPartner", "start pay");  
  33.             // start the pay.  
  34.             CLog.log(TAG, "info = " + info);  
  35.   
  36.             final String orderInfo = info;  
  37.             new Thread() {  
  38.                 public void run() {  
  39.                     AliPay alipay = new AliPay(activity, handler);  
  40.                       
  41.                     //設置爲沙箱模式,不設置默認爲線上環境  
  42.                     //alipay.setSandBox(true);  
  43.   
  44.                     String result = alipay.pay(orderInfo);  
  45.                     CLog.log(TAG, "result = " + result);  
  46.                     Message msg = handler.obtainMessage();  
  47.                     msg.what = RQF_PAY;  
  48.                     msg.obj = result;  
  49.                     handler.sendMessage(msg);  
  50.                 }  
  51.             }.start();  
  52.   
  53.         } catch (Exception ex) {  
  54.             ex.printStackTrace();  
  55.         }  
  56.     }  
  57.   
  58.     /** 
  59.      * 封裝訂單信息 
  60.      * @param orderBO 
  61.      * @return 
  62.      * @throws UnsupportedEncodingException 
  63.      */  
  64.     private static String createOrderInfo(OrderBO orderBO, AliPayParamsBO aliPayBO)  
  65.             throws UnsupportedEncodingException {  
  66.         StringBuilder sb = new StringBuilder();  
  67.         sb.append("partner=\"");  
  68.         sb.append(aliPayBO.getPid());  
  69.         sb.append("\"&out_trade_no=\"");  
  70.         sb.append(orderBO.getOrder_sn());  
  71.         sb.append("\"&subject=\"");  
  72.         sb.append(orderBO.getSubject());  
  73.         sb.append("\"&body=\"");  
  74.         sb.append(orderBO.getBody());  
  75.         sb.append("\"&total_fee=\"");  
  76.         sb.append(/*orderBO.getAmount()*/"0.01");  
  77.         sb.append("\"¬ify_url=\"");  
  78.   
  79.         // 網址須要作URL編碼  
  80.         sb.append(URLEncoder.encode(aliPayBO.getNotify_url(), "utf-8"));  
  81.         sb.append("\"&service=\"mobile.securitypay.pay");  
  82.         sb.append("\"&_input_charset=\"UTF-8");  
  83.         sb.append("\"&return_url=\"");  
  84.         sb.append(URLEncoder.encode("http://m.alipay.com", "utf-8"));  
  85.         sb.append("\"&payment_type=\"1");  
  86.         sb.append("\"&seller_id=\"");  
  87.         sb.append(aliPayBO.getAccount());  
  88.   
  89.         // 若是show_url值爲空,可不傳  
  90.         // sb.append("\"&show_url=\"");  
  91.         sb.append("\"&it_b_pay=\"1m");  
  92.         sb.append("\"");  
  93.   
  94.         return new String(sb);  
  95.     }  
  96.     /** 
  97.      * 獲取sign_type參數信息,由於該參數不須要參加簽名 
  98.      * @return 
  99.      */  
  100.     private static String getSignType() {  
  101.         return "sign_type=\"RSA\"";  
  102.     }  
  103. }  

 

 

遇到的問題:整個過程仍是比較順利的,一開始我是使用了4.0系統的手機進行測試,也可以正常使用。可是跑給同事手機以後,問題出現了,竟然出現了。。點擊支付的時候始終喚不起支付頁面,還報了 failure calling remote service 異常,而後就挺納悶,查了代碼發現好像沒啥問題。

立刻去打印log,看到了以下問題:

看了以上異常信息以後個人第一反應就是難道個人私鑰弄錯了,但想一想4.0仍是沒問題的啊。後來就追查到了代碼中,就在Rsa類中的sign方法,這是支付寶給出的類,我就在異常中將異常信息打印出來,果然

仍是編碼問題。

 

[java]  view plain copy
 
  1. public static String sign(String content, String privateKey) {  
  2.         String charset = "UTF-8";  
  3.         try {  
  4.             PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(  
  5.                     Base64.decode(privateKey));  
  6.             KeyFactory keyf = KeyFactory.getInstance("RSA");  
  7.             PrivateKey priKey = keyf.generatePrivate(priPKCS8);  
  8.   
  9.             java.security.Signature signature = java.security.Signature  
  10.                     .getInstance(SIGN_ALGORITHMS);  
  11.   
  12.             signature.initSign(priKey);  
  13.             signature.update(content.getBytes(charset));  
  14.   
  15.             byte[] signed = signature.sign();  
  16.   
  17.             return Base64.encode(signed);  
  18.         } catch (Exception e) {  
  19.             e.printStackTrace();  
  20.             System.out.println("Exception="+e.getMessage());  
  21.         }  
  22.   
  23.         return null;  
  24.     }  


而後我就忽然想到了上面生成的  「PKCS8編碼的私鑰」,而後將剛剛上面那個AlipayUtil類的pay方法裏面的

 

 

[java]  view plain copy
 
  1. String sign = Rsa.sign(info, aliPayBO.getPrivate_key_pkcs8());  


簽名時用的就是 「PKCS8編碼的私鑰」(本來出問題是用到RSA私鑰),代碼中改過來了。此次就好了啦,不管4.0如下仍是以上通殺。界面以下:

 

 

好啦,客戶端的集成大概就是這樣,其餘相關的類是按照支付寶demo裏面的,就不要展現出來了,須要的到代碼下載裏面去下載就ok啦~

相關文章
相關標籤/搜索