转-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啦~

相关文章
相关标签/搜索