拿到支付宝接口的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 pairs = new ArrayList();

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 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应用集成支付宝接口的简化的更多相关文章

  1. Android集成支付宝接口 实现在线支付

    手机的在线支付,被认为是2012年最看好的功能,我个人认为这也是移动互联网较传统互联网将会大放光彩的一个功能. 人人有手机,人人携带手机,花钱买东西,不再需要取钱付现,不再需要回家上网银,想买什么,扫 ...

  2. Android App集成支付宝

    原地址:http://blog.csdn.net/wenbingoon/article/details/7933078 手机的在线支付,被认为是2012年最看好的功能,我个人认为这也是移动互联网较传统 ...

  3. Android中集成支付宝

    手机的在线支付,被认为是2012年最看好的功能,我个人认为这也是移动互联网较传统互联网将会大放光彩的一个功能. 人人有手机,人人携带手机,花钱买东西,不再需要取钱付现,不再需要回家上网银,想买什么,扫 ...

  4. android app 集成 支付宝支付 微信支付

    项目中部分功能点需要用到支付功能,移动端主要集成支付宝支付和微信支付 支付宝sdk以及demo下载地址:https://doc.open.alipay.com/doc2/detail.htm?spm= ...

  5. Node.js集成支付宝接口注意事项

    目录 签名 发送请求表单 验签 总结 签名 使用node.js自带的加密模块crypto和字符编码模块iconv-lite 根据支付宝接口文档参数格式得到签名之前的字符串beforeSignStr,然 ...

  6. android应用程序如何调用支付宝接口

    最近在做一个关于购物商城的项目,项目里面付款这块我选的是调用支付宝的接口,因为用的人比较多. 在网上搜索了以下,有很多这方面的教程,但大部分教程过于陈旧,而且描述的过于简单.而且支付宝提供的接口一直在 ...

  7. android应用程序如何调用支付宝接口(转)

    最近在做一个关于购物商城的项目,项目里面付款这块我选的是调用支付宝的接口,因为用的人比较多. 在网上搜索了以下,有很多这方面的教程,但大部分教程过于陈旧,而且描述的过于简单.而且支付宝提供的接口一直在 ...

  8. android开发支付宝接口开发流程(密钥篇)

    参考博客:http://blog.it985.com/12276.html 官方下载地址:http://download.alipay.com/public/api/base/WS_MOBILE_PA ...

  9. Android 开发之Android 应用程序如何调用支付宝接口

    1.到支付宝官网,下载支付宝集成开发包 由于android设备一般用的都是无线支付,所以我们申请的就是支付宝无线快捷支付接口.下面是申请的地址以及下载接口开发包的网址:https://b.alipay ...

随机推荐

  1. VMware 命令行下安装以及导入Ubuntu系统

    前提: 鉴于个人PC性能太弱,考虑是否可以将在PC上搭建好的环境移植到高性能服务器上.想到后就干呗. 下载完对应操作系统的安装包后按如下步骤操作: 安装包名称:VMware-Workstation-F ...

  2. Python中的并发编程

    简介 我们将一个正在运行的程序称为进程.每个进程都有它自己的系统状态,包含内存状态.打开文件列表.追踪指令执行情况的程序指针以及一个保存局部变量的调用栈.通常情况下,一个进程依照一个单序列控制流顺序执 ...

  3. C语言部分

    1.内核的裁剪怎么裁剪 2.深入理解uboot 3.TCP/IP TCP/UDP原理是什么? 4.项目里你做了些什么?怎么做的?为什么要那样做? 5.指针与数组的用法及计算 6.单链表和双链表的用法 ...

  4. 一起刷LeetCode5-Longest Palindromic Substring

    发现自己原来掌握的一下算法,都忘掉了,啊啊啊 ----------------------------------------------------------------------------- ...

  5. 更改VS的运行主窗体

    Program.cs中Application.EnableVisualStyles();              Application.SetCompatibleTextRenderingDefa ...

  6. 用pdo实现的织梦后台留言板

    <?php //ini_set("display_errors", "On"); include("data/common.inc.php&qu ...

  7. 《学习OpenCV》练习题第四章第二题

    #include <highgui.h> #include <cv.h> #pragma comment (lib,"opencv_calib3d231d.lib&q ...

  8. Html.DropDownListFor

    @Html.DropDownListFor(x => x.WillAttend, new[] { new SelectListItem() {Text = "Yes, I'll be ...

  9. AnnotationSessionFactoryBean用法介绍

    http://blog.csdn.net/flyingfalcon/article/details/8273618 —————————————————————————————————————————— ...

  10. Speex for Android

    http://blog.csdn.net/chenfeng0104/article/details/7088138在Android开发中,需要录音并发送到对方设备上.这时问题来了,手机常会是GPRS. ...