zoukankan      html  css  js  c++  java
  • 转-android 支付宝SDK集成

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

    一、前言

    最近做的项目刚好要集成支付宝,上网找了很多资料,介绍得感觉不是很全面,所以我经过这两天的集成,顺便记录下来,学习交流。需要的朋友也可以看看。主要集成还是参照了官方给出的demo,再参照demo进行封装,现在使用起来变得方便好多。而且文章里面还提到了集成过程中遇到的一些问题,当然最后也都解决了。

    二、准备工作

    支付宝开放平台上面也明确了,目前仅仅支持企业用户申请,所以个人开发者就没法使用到。希望支付宝早日可以开放给个人开发者。

    支付宝的集成是相对比较麻烦,其中涉及到了很多东西要弄,要生成私钥公钥等等。文档里面也有详细说到如何如何生成那些东西,不过就是文档的内容量有点多了,看起来总抓不住前后,这里我稍作整理,把android需要用到的提取出来了。

    1、PID

    首先说一下就是支付宝的支付是这样的,企业用户申请了支付宝之后,支付宝就会提供一个合作者id,就是所谓的pid,是2088开头的16位纯数字;

    2、支付宝账户

    这个就是你用于收款用的支付宝账号,要跟申请时候同一个。

    以下几个要运行我附件中的“移动支付接口智能SDK版"中,opensslin文件夹下面的openssl.exe生成,这个是由支付宝提供的

    3、RSA私钥:genrsa -out rsa_private_key.pem 1024

    运行完命令行可以看到bin文件夹下面会生成私钥

    4、RSA公钥:rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem

    运行完命令行后可以看到生成了公钥

    5、PKCS8编码的私钥:pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt

    运行完后,将生成的东西拷贝下来放到文本文件里面就行。这后面要用到的!!包括begin跟end那两句一起存起来

    三、支付过程

    需要进行再封装的主要有下面这个类,做几点说明,AliPayParamsBO是我封装的一个实体类,因为我把刚刚上面讲到的那些PID、私钥啊等等都放在服务端了,这样会比较安全,就算别人反编译了你的项目,那也看不到什么东西,支付宝官方也是这样建议的。测试的时候,可以把这个AliPayParamsBO类,装进你生成的那些参数去测试就好啦,至于OrderBO类,也是我封装的一个类,里面主要包含的是这个订单相关的一些东西,比如商品名称、商品介绍,价格等等,这些在支付过程中都是必要的。

    而需要强调一点就是,产生这个支付过程中,我先是构造好需要请求的参数,注意一点就是我在createOrderInfo()方法中对参数进行构造,但是 sign、sign_type 两个参数先不要参与,因为这两个参数不需要参与签名,等前面那些参数构造好了之后,签完名再将sign、sign_type 两个参数构造进去,再进行支付。

    [java] view plaincopy
     
    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 plaincopy
     
    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 plaincopy
     
    1. String sign = Rsa.sign(info, aliPayBO.getPrivate_key_pkcs8());  


    签名时用的就是 “PKCS8编码的私钥”(原本出问题是用到RSA私钥),代码中改过来了。这次就行了啦,无论4.0以下还是以上通杀。界面如下:

    好啦,客户端的集成大概就是这样,其他相关的类是按照支付宝demo里面的,就不要展示出来了,需要的到代码下载里面去下载就ok啦~

     

  • 相关阅读:
    android 中 文件的 MIME 类型 【部分内容】
    Linux下的计划任务 crontab
    监控 某个目录下文件的创建,给据创建的文件进行执行命令
    SUSE下试着搭建了一个web 做个记录
    Android 学习 — Activity
    数据库字段不规范
    浅谈测试团队规范建设
    QA拒绝上线的理由
    Bugzilla安装部署精要
    Linux下部署Bugzilla和TestLink
  • 原文地址:https://www.cnblogs.com/awkflf11/p/4609186.html
Copyright © 2011-2022 走看看