Android笔记:应用内支付宝支付集成

来源:互联网 发布:网络热门词汇英语 编辑:程序博客网 时间:2024/05/16 11:18

 

 

## 准备工作

1. 要有一个支付宝账号

2. 去http://ms.alipay.com 登录和自助签约 “无线部-自助签约-手机安全支付”;

3. 完成后登录 ms.alipay.com 在“我的产品页” 会见到 账户信息像以下内容

账户名:abc@xxx.com

账户ID:208800*******993

合作商户ID:2088*******993

4. 这个时候先不管密钥管理,先去下载SDK包和文档,

    下载地址 https://mobiless.alipay.com/product/product_down_load.htm?product_id=1

     解压出以下东东备用

  • DEMO项目  //里面有好多现成的类,好东西~
  • mobile_sp.jar //支付的类库
  • mobile_sp.apk //支付宝安全支付控件,手机支付的前提,可捆绑在应用安装包内支付前检测和提示用户安装
  • RSA密钥的W32生成工具 //不解释... 交易流程sign用

5. 按文档说明生成商家私钥、公钥对,再将私钥转换为 PKCS8 格式,备用~

6. 回到 ms.alipay.com 进入账号信息下的密钥管理,上传刚生成的商家公钥,获得 AliPay的对应公钥,备用~

(注意不要混淆 商家pub_key 和Ali_pub_key)

 

## 准备工作 part.2

呃,还得准备准备,刚才说了DEMO里面有很多好东西,可以直接拿来就用,省下不少爬文档和代码的时间省力又省心..有用的是

  1. AlixId.java
  2. Base64.java
  3. BaseHelper.java
  4. MobileSecurePayer.java
  5. MobileSecurePayHelper.java
  6. NetworkManager.java
  7. ResultChecker.java
  8. Rsa.java

全部拿出来扔到我们自己的项目包内,然后逐一来看看

AlixId.java ——这个不需要动,只是一些静态的全局变量;

Base64.java ——编码算法,不动;

Rsa.java ——同上,不动;

BaseHelper.java ——一些调用 ProgressDialog AlertDialog 还有格式转换的现成的方法,不动;

MobileSecurePayer.java ——不用改动,里面的 pay((String, Handler, int, Activity) ,支付用它;

MobileSecurePayHelper.java ——这里要注意,捆绑安装支付控件的话,要把mobile_sp.apk 放到项目 assets 路径下,文件名可以改别的随便,但要注意与源码中52行 cachePath 文件名一致,还有 retrieveApkFromAssets()中的第二个文件名参数一致。若还打算提供在线下载安装控件的话还要更改 apkUrl ,url根据实际情况修改。其余的不用动,是一些检验、安装安全控件的方法;

NetworkManager.java ——不用动,上面如果启用了在线下载安装控件,就要用到这个包实现下载。

ResultChecker.java ——支付结果的解释和校验用,留意 Rsa.doCheck() 的第三个参数,这里要用的是 Ali_pub_key;

 

## 开工集成

public class Pay extends Activity { 
 Spinner spPrice;   //下拉菜单,有几个不同金额的支付项目选择
 Button btAlipayl; //支付按钮
 ProgressDialog pd; //提示Loading信息用

 
 /** Called when the activity is first created. */
 @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.pay);

        //绑定实例
        spPrice = (Spinner) findViewById(R.id.sp_pay);
        btAlipay = (Button) findViewById(R.id.bt_pay_alipay);
        pd = new ProgressDialog(this);
        pd.setCancelable(false);

        //点击支付按钮
        btAlipay.setOnClickListener(new OnClickListener(){

   @Override
   public void onClick(View v) {
    // TODO Auto-generated method stub

    // check to see if the MobileSecurePay is already installed. 没有支付安全控件的话提示安装
    MobileSecurePayHelper mspHelper =  new MobileSecurePayHelper(Pay.this);
    boolean isMobile_spExist = mspHelper.detectMobile_sp();
    if( !isMobile_spExist )
     return;
        
    // start pay for this order.
    try
    {  
     // prepare the order info.
     String orderInfo  = getOrderInfo(spPrice.getSelectedItemPosition()); //组织要发去支付接口的数据,这里传递了一个下拉菜单的选中序号,我在Array.xml仲分别定义了下拉菜单各项对应的商品名称、详情、价格数组
     String strsign   = Rsa.sign(orderInfo,getString(R.string.privateKey_Rsa)); //rsa算法,文档说支持md5,我用出错不清楚原因,换回来了
     strsign    = URLEncoder.encode(strsign);
     String info   =  orderInfo
           + "&sign=" +  "\"" + strsign  + "\""
           + "&" + getSignType();
     
     // start the pay. 支付
     MobileSecurePayer msp = new MobileSecurePayer();
     boolean bRet = msp.pay(info, mHandler, AlixId.RQF_PAY, Pay.this);
     
     if( bRet )
     {// 尝试收起ProgressDialog
      try
         { if( pd != null ) pd.dismiss(); }
         catch(Exception e)
         {e.printStackTrace(); }
      //然后投放支付中的提示
         pd.setMessage("正在支付");
         pd.show();         
     }
     else ;
    }
    catch (Exception ex)
    {showMsg(getString(R.string.remote_call_failed), false); }    
  } });

}

 

 //Alipay 的函数族
 // get the selected order info for pay. 组织交易数据
 String getOrderInfo(int arg2)
 {
  //以下内容在string.xml 或Array.xml中定义,参考SDK文档
  String strOrderInfo = "partner=" + "\"" + getString(R.string.partner) + "\"";
  strOrderInfo   += "&";
  strOrderInfo   += "seller=" + "\"" + getString(R.string.seller) + "\"";
  strOrderInfo   += "&";
  strOrderInfo  += "out_trade_no=" + "\"" + getOutTradeNo() + "\"";
  strOrderInfo   += "&";
  strOrderInfo  += "subject=" + "\"" + getString(R.string.subject) + "\"";
  strOrderInfo   += "&";
  strOrderInfo  += "body=" + "\"" + getResources().getStringArray(R.array.pay_name)[arg2] + "\"";
  strOrderInfo   += "&";
  strOrderInfo  += "total_fee=" + "\"" + getResources().getStringArray(R.array.pay_ap)[arg2] + "\"";
  strOrderInfo   += "&";
  strOrderInfo  += "notify_url="  + "\"" + getString(R.string.notify_url) + "\"";

  return strOrderInfo;
 }
 
 // get the out_trade_no for an order.根据文档生成一个不重复的商家交易号ID
 String getOutTradeNo()
 {
  SimpleDateFormat format = new SimpleDateFormat("MMddHHmmss");
  Date date = new Date();
  String strKey = format.format(date);
  
  java.util.Random r = new java.util.Random();
  strKey = strKey + r.nextInt();
  strKey = strKey.substring(0, 15);
  return strKey;
 }
 
 // get the sign type we use. 定义签名的算法,这里用了RSA
 String getSignType()
 {
  String getSignType = "sign_type=" + "\"" + "RSA" + "\"";
  return getSignType;
 }
 
  // the handler use to receive the pay result. 接收响应支付结果的 Handler
 private Handler mHandler = new Handler()
 {
  public void handleMessage(Message msg)
  { 
   try
   {
    String strRet = (String)msg.obj;  //这个是交易结果返回的信息由几部分组成,如: resultStatus={};memo={};result={}
    switch (msg.what)
    {
     case AlixId.RQF_PAY:
     {
      //如果支付中提示仍在,收起
      try
         {if( pd != null )  pd.dismiss();}
          catch(Exception e)
         {e.printStackTrace(); }      
      
      //把返回的结果拆包..解析成各部分信息,包括交易结果的状态码、错误信息等
      try
      {
       String memo  = "memo=";
       int imemoStart  = strRet.indexOf("memo=");
       imemoStart  +=  memo.length();
       int imemoEnd  = strRet.indexOf(";result=");
       memo = strRet.substring(imemoStart, imemoEnd);
            
       BaseHelper.showDialog(PayForm.this, "提示", memo, R.drawable.icon);
       
       // handle result
       ResultChecker resultChecker = new ResultChecker(strRet);
       boolean isPayOk = resultChecker.isPayOk(); //这种是严谨的验证支付结果是否成功的方法,不严谨的可以只检测状态码是否9000详情参考文档说明
       if(isPayOk){//支付成功了,以下该干啥干啥...
           ... ...
           }else ;  //支付不成功的处理...
      }
      catch(Exception e)
      { e.printStackTrace();      }

     }
     break;
    }

    super.handleMessage(msg);
   }
   catch(Exception e)
   {e.printStackTrace();}
 } }; 

}

0 0