Android应用集成支付宝接口的简化

拿到支付宝接口的andriod demo后有点无语,集成一个支付服务而已,要在十几个java类之间引用来引用去,这样不仅容易导致应用本身代码结构的复杂化,调试起来也很累,于是操刀改造之:

该删的删,该改写的改写,MobileSecurePayer之外的内容全部整合到MobileSecurePayerHelper之中。

?
 
/*
  * Copyright (C) 2010 The MobileSecurePay Project
  * All right reserved.
  * author: [email protected]
  
  *modify: fangle
  */
  
package  com.alipay.android;
  
import  java.io.BufferedReader;
import  java.io.File;
import  java.io.FileOutputStream;
import  java.io.IOException;
import  java.io.InputStream;
import  java.io.InputStreamReader;
import  java.io.OutputStream;
import  java.net.HttpURLConnection;
import  java.net.URL;
import  java.security.KeyFactory;
import  java.security.PrivateKey;
import  java.security.PublicKey;
import  java.security.Signature;
import  java.security.spec.PKCS8EncodedKeySpec;
import  java.security.spec.X509EncodedKeySpec;
import  java.util.ArrayList;
import  java.util.List;
  
import  javax.crypto.Cipher;
  
import  org.apache.http.client.entity.UrlEncodedFormEntity;
import  org.apache.http.message.BasicNameValuePair;
import  org.json.JSONException;
import  org.json.JSONObject;
  
import  android.content.Context;
import  android.content.Intent;
import  android.content.pm.PackageInfo;
import  android.net.Uri;
import  android.os.Handler;
import  android.os.Message;
import  android.util.Base64;
  
public  class  MobileSecurePayHelper {
     static  final  String TAG =  "MobileSecurePayHelper" ;
  
     public  static  final  String PARTNER =  "" ;
     public  static  final  String SELLER =  "" ;
     public  static  final  String RSA_PRIVATE =  "" ;
     public  static  final  String RSA_ALIPAY_PUBLIC =  "" ;
  
     Context mContext =  null ;
     Handler mHandler =  null ;
     String mUrl =  null ;
     String mPath =  null ;
  
     public  static  String Stream2String(InputStream is) {
         BufferedReader reader =  new  BufferedReader( new  InputStreamReader(is));
         StringBuilder sb =  new  StringBuilder();
         String line =  null ;
         try  {
             while  ((line = reader.readLine()) !=  null )
                 sb.append(line);
             is.close();
         catch  (IOException e) {
             e.printStackTrace();
         }
         return  sb.toString();
     }
  
     public  static  JSONObject string2JSON(String str, String split) {
         JSONObject json =  new  JSONObject();
         try  {
             String[] arrStr = str.split(split);
             for  ( int  i =  0 ; i < arrStr.length; i++) {
                 String[] arrKeyValue = arrStr[i].split( "=" );
                 json.put(arrKeyValue[ 0 ],
                         arrStr[i].substring(arrKeyValue[ 0 ].length() +  1 ));
             }
         catch  (Exception e) {
             e.printStackTrace();
         }
         return  json;
     }
  
     public  static  String SendAndWaitResponse(String strReqData, String strUrl) {
         String strResponse =  null ;
         ArrayList<BasicNameValuePair> pairs =  new  ArrayList<BasicNameValuePair>();
         pairs.add( new  BasicNameValuePair( "requestData" , strReqData));
  
         HttpURLConnection conn =  null ;
         UrlEncodedFormEntity p_entity;
         try  {
             p_entity =  new  UrlEncodedFormEntity(pairs,  "utf-8" );
             URL url =  new  URL(strUrl);
             conn = (HttpURLConnection) url.openConnection();
             conn.setConnectTimeout( 30  1000 );
             conn.setReadTimeout( 30  1000 );
             conn.setDoOutput( true );
             conn.addRequestProperty( "Content-type" ,
                     "application/x-www-form-urlencoded;charset=utf-8" );
             conn.connect();
  
             OutputStream os = conn.getOutputStream();
             p_entity.writeTo(os);
             os.flush();
             InputStream content = conn.getInputStream();
             strResponse = Stream2String(content);
         catch  (IOException e) {
             e.printStackTrace();
         finally  {
             conn.disconnect();
         }
         return  strResponse;
     }
  
     public  static  boolean  urlDownloadToFile(Context context, String strurl,
             String path) {
         boolean  bRet =  false ;
         try  {
             URL url =  new  URL(strurl);
             HttpURLConnection conn =  null ;
             conn = (HttpURLConnection) url.openConnection();
             conn.setConnectTimeout( 30  1000 );
             conn.setReadTimeout( 30  1000 );
             conn.setDoInput( true );
             conn.connect();
             InputStream is = conn.getInputStream();
             File file =  new  File(path);
             file.createNewFile();
             FileOutputStream fos =  new  FileOutputStream(file);
             byte [] temp =  new  byte [ 1024 ];
             int  i =  0 ;
             while  ((i = is.read(temp)) >  0 )
                 fos.write(temp,  0 , i);
             fos.close();
             is.close();
             bRet =  true ;
         catch  (IOException e) {
             e.printStackTrace();
         }
         return  bRet;
     }
  
     public  static  String RsaEncode(String content, String key) {
         try  {
             X509EncodedKeySpec x509 =  new  X509EncodedKeySpec(Base64.decode(key,
                     Base64.DEFAULT));
             KeyFactory kf = KeyFactory.getInstance( "RSA" );
             PublicKey pubKey = kf.generatePublic(x509);
             Cipher cipher = Cipher.getInstance( "RSA/ECB/PKCS1Padding" );
             cipher.init(Cipher.ENCRYPT_MODE, pubKey);
             byte  plaintext[] = content.getBytes( "UTF-8" );
             byte [] output = cipher.doFinal(plaintext);
             return  new  String(Base64.encode(output, Base64.DEFAULT));
         catch  (Exception e) {
             e.printStackTrace();
         }
         return  null ;
     }
  
     public  static  String RsaSign(String content, String privateKey) {
         try  {
             PKCS8EncodedKeySpec pkcs8 =  new  PKCS8EncodedKeySpec(Base64.decode(
                     privateKey, Base64.DEFAULT));
             KeyFactory kf = KeyFactory.getInstance( "RSA" );
             PrivateKey priKey = kf.generatePrivate(pkcs8);
             Signature signature = Signature.getInstance( "SHA1WithRSA" );
             signature.initSign(priKey);
             signature.update(content.getBytes( "utf-8" ));
             byte [] signed = signature.sign();
             return  new  String(Base64.encode(signed, Base64.DEFAULT));
         catch  (Exception e) {
             e.printStackTrace();
         }
         return  null ;
     }
  
     public  static  boolean  RsaCheck(String content, String sign, String publicKey) {
         try  {
             KeyFactory keyFactory = KeyFactory.getInstance( "RSA" );
             byte [] encodedKey = Base64.decode(publicKey, Base64.DEFAULT);
             PublicKey pubKey = keyFactory
                     .generatePublic( new  X509EncodedKeySpec(encodedKey));
             Signature signature = Signature.getInstance( "SHA1WithRSA" );
             signature.initVerify(pubKey);
             signature.update(content.getBytes( "utf-8" ));
             boolean  bverify = signature.verify(Base64.decode(sign,
                     Base64.DEFAULT));
             return  bverify;
         catch  (Exception e) {
             e.printStackTrace();
         }
         return  false ;
     }
  
     public  MobileSecurePayHelper(Context context, Handler handler) {
         mContext = context;
         mHandler = handler;
     }
  
     public  boolean  detectService() {
         boolean  isExist =  false ;
         List<PackageInfo> pkgList = mContext.getPackageManager()
                 .getInstalledPackages( 0 );
         for  ( int  i =  0 ; i < pkgList.size(); i++) {
             if  (pkgList.get(i).packageName
                     .equalsIgnoreCase( "com.alipay.android.app" ))
                 isExist =  true ;
         }
         return  isExist;
     }
  
     public  void  downloadAliMSP() {
         JSONObject Resp =  null ;
         try  {
             JSONObject req =  new  JSONObject();
             req.put( "action" "update" );
             JSONObject data =  new  JSONObject();
             data.put( "platform" "android" );
             data.put( "version" "2.2.3" );
             data.put( "partner" "" );
             req.put( "data" , data);
             Resp =  new  JSONObject(SendAndWaitResponse(req.toString(),
                     "https://msp.alipay.com/x.htm" ));
             mUrl = Resp.getString( "updateUrl" );
         catch  (JSONException e) {
             e.printStackTrace();
             return ;
         }
         new  Thread( new  Runnable() {
             public  void  run() {
                 mPath = mContext.getCacheDir().getAbsolutePath() +  "/temp.apk" ;
                 urlDownloadToFile(mContext, mUrl, mPath);
                 Message msg =  new  Message();
                 msg.what =  2 ;
                 mHandler.sendMessage(msg);
             }
         }).start();
     }
  
     public  void  installAliMSP() {
         if  (mPath ==  null )
             return ;
         try  {
             Runtime.getRuntime().exec( "chmod 777 "  + mPath);
         catch  (IOException e) {
             e.printStackTrace();
         }
         Intent intent =  new  Intent(Intent.ACTION_VIEW);
         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
         intent.setDataAndType(Uri.parse( "file://"  + mPath),
                 "application/vnd.android.package-archive" );
         mContext.startActivity(intent);
     }
}

集成很简单,一个OnClickListener负责调用支付服务,一个Handler负责处理支付过程中的相应事件:

?
 
private  Handler m_mspHandler =  new  Handler() {
     public  void  handleMessage(Message m) {
         // 1:支付返回
         // 2:支付组件下载完成
         TextView tv = (TextView) findViewById(R.id.order_tips);
         Button bt = (Button) findViewById(R.id.order_ok);
         ProgressBar pb = (ProgressBar) findViewById(R.id.order_wait);
         switch  (m.what) {
         case  1 :
             String ret = (String) m.obj;
             String memo =  "memo={" ;
             int  start = ret.indexOf(memo) + memo.length();
             int  end = ret.indexOf( "};result=" );
             memo = ret.substring(start, end);
             m_tips += memo;
             if  (memo.indexOf( "付款成功" ) >=  0 )
                 m_tips +=  "\r\n请注意查看短信,您将收到二维码凭证" ;
             tv.setText(m_tips);
             bt.setVisibility( 0 );
             pb.setVisibility( 4 );
             break ;
         case  2 :
             m_tips +=  "安全支付组件下载完成,开始安装...\r\n" ;
             tv.setText(m_tips);
             m_mspHelper.installAliMSP();
             bt.setVisibility( 0 );
             pb.setVisibility( 4 );
             break ;
         }
     }
};
  
private  OnClickListener m_orderButtonListener =  new  OnClickListener() {
     public  void  onClick(View v) {
         String mobile = m_mobileEdt.getText().toString();
         m_tips =  "" ;
         TextView tv = (TextView) findViewById(R.id.order_tips);
         Button bt = (Button) findViewById(R.id.order_ok);
         ProgressBar pb = (ProgressBar) findViewById(R.id.order_wait);
         if  (mobile.length() !=  11 ) {
             m_tips +=  "无效的收货号码\r\n" ;
             tv.setText(m_tips);
             return ;
         }
         if  (!m_date.after(m_today)) {
             m_tips +=  "订货日期不能早于明天\r\n" ;
             tv.setText(m_tips);
             return ;
         }
         SoapObject request =  new  SoapObject( "http://airtimes.cn/" ,
                 "MakeOrder" );
         request.addProperty( "Uname" , m_intent.getStringExtra( "userid" ));
         request.addProperty( "ProductId" ,
                 m_intent.getStringExtra( "item_PID" ));
         request.addProperty( "Sum" "1" );
         request.addProperty( "PayAmount" ,
                 m_intent.getStringExtra( "item_price" ));
         request.addProperty( "SMSMobile" , mobile);
         request.addProperty(
                 "ExpireDate" ,
                 String.format( "%04d-%02d-%02d" , m_date.get( 1 ),
                         m_date.get( 2 ) +  1 , m_date.get( 5 )));
  
         // 显示等待条,提交订单信息
         m_tips +=  "正在创建订单,请稍候...\r\n" ;
         tv.setText(m_tips);
         bt.setVisibility( 4 );
         pb.setVisibility( 0 );
  
         HttpTransportSE httpTransport =  new  HttpTransportSE(
                 "http://www.android-study.com/serv.asmx" );
         SoapSerializationEnvelope envelope =  new  SoapSerializationEnvelope(
                 SoapEnvelope.VER11);
         envelope.dotNet =  true ;
         envelope.bodyOut = request;
         String respond;
         try  {
             httpTransport.call(request.getNamespace() + request.getName(),
                     envelope);
             if  (envelope.getResponse() !=  null )
                 respond = envelope.getResponse().toString();
             else
                 respond =  "false,null" ;
         catch  (Exception ex) {
             respond =  "false,"  + ex.getMessage();
         }
         if  (respond.substring( 0 5 ).equals( "false" )) {
             m_tips +=  "创建订单失败:"  + respond.substring( 6 ) +  "\r\n" ;
             tv.setText(m_tips);
             bt.setVisibility( 0 );
             pb.setVisibility( 4 );
             return ;
         }
  
         String msgs[] = respond.split( "[,]" );
         String order;
         m_tips +=  "创建订单成功,开始支付...\r\n" ;
         tv.setText(m_tips);
  
         if  (!m_mspHelper.detectService()) {
             m_tips +=  "未安装安全支付组件,开始下载...\r\n" ;
             tv.setText(m_tips);
             m_mspHelper.downloadAliMSP();
             return ;
         }
  
         order = String.format( "partner=\"%s\"" ,
                 MobileSecurePayHelper.PARTNER);
         order += String.format( "&seller=\"%s\"" ,
                 MobileSecurePayHelper.SELLER);
         order += String.format( "&out_trade_no=\"%s\"" , msgs[ 1 ]);
         order += String.format( "&subject=\"%s\"" ,
                 m_intent.getStringExtra( "item_type" ));
         order += String.format( "&body=\"%s\"" ,
                 m_intent.getStringExtra( "item_name" ));
         order += String.format( "&total_fee=\"%s\"" ,
                 m_intent.getStringExtra( "item_price" ));
         order += String.format( "?ify_url=\"%s\"" ,
                 "http://www.android-study.com/alipay.aspx" );
         String sign = URLEncoder.encode(MobileSecurePayHelper.RsaSign(
                 order, MobileSecurePayHelper.RSA_PRIVATE));
         order += String.format( "&sign=\"%s\"" , sign);
         order += String.format( "&sign_type=\"%s\"" "RSA" );
  
         com.alipay.android.MobileSecurePayer msp =  new  com.alipay.android.MobileSecurePayer();
         if  (!msp.pay(order, m_mspHandler,  1 , OrderingActivity. this )) {
             m_tips +=  "调用安全支付功能失败\r\n" ;
             tv.setText(m_tips);
             bt.setVisibility( 0 );
             pb.setVisibility( 4 );
             return ;
         }
     }
};

你可能感兴趣的:(android)