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

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

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

 
/*
 * Copyright (C) 2010 The MobileSecurePay Project
 * All right reserved.
 * author: shiqun.shi@alipay.com
  
 *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(05).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;
        }
    }
};
原文地址:https://www.cnblogs.com/firecode/p/2723165.html