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 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应用集成支付宝接口的简化的更多相关文章
- Android集成支付宝接口 实现在线支付
手机的在线支付,被认为是2012年最看好的功能,我个人认为这也是移动互联网较传统互联网将会大放光彩的一个功能. 人人有手机,人人携带手机,花钱买东西,不再需要取钱付现,不再需要回家上网银,想买什么,扫 ...
- Android App集成支付宝
原地址:http://blog.csdn.net/wenbingoon/article/details/7933078 手机的在线支付,被认为是2012年最看好的功能,我个人认为这也是移动互联网较传统 ...
- Android中集成支付宝
手机的在线支付,被认为是2012年最看好的功能,我个人认为这也是移动互联网较传统互联网将会大放光彩的一个功能. 人人有手机,人人携带手机,花钱买东西,不再需要取钱付现,不再需要回家上网银,想买什么,扫 ...
- android app 集成 支付宝支付 微信支付
项目中部分功能点需要用到支付功能,移动端主要集成支付宝支付和微信支付 支付宝sdk以及demo下载地址:https://doc.open.alipay.com/doc2/detail.htm?spm= ...
- Node.js集成支付宝接口注意事项
目录 签名 发送请求表单 验签 总结 签名 使用node.js自带的加密模块crypto和字符编码模块iconv-lite 根据支付宝接口文档参数格式得到签名之前的字符串beforeSignStr,然 ...
- android应用程序如何调用支付宝接口
最近在做一个关于购物商城的项目,项目里面付款这块我选的是调用支付宝的接口,因为用的人比较多. 在网上搜索了以下,有很多这方面的教程,但大部分教程过于陈旧,而且描述的过于简单.而且支付宝提供的接口一直在 ...
- android应用程序如何调用支付宝接口(转)
最近在做一个关于购物商城的项目,项目里面付款这块我选的是调用支付宝的接口,因为用的人比较多. 在网上搜索了以下,有很多这方面的教程,但大部分教程过于陈旧,而且描述的过于简单.而且支付宝提供的接口一直在 ...
- android开发支付宝接口开发流程(密钥篇)
参考博客:http://blog.it985.com/12276.html 官方下载地址:http://download.alipay.com/public/api/base/WS_MOBILE_PA ...
- Android 开发之Android 应用程序如何调用支付宝接口
1.到支付宝官网,下载支付宝集成开发包 由于android设备一般用的都是无线支付,所以我们申请的就是支付宝无线快捷支付接口.下面是申请的地址以及下载接口开发包的网址:https://b.alipay ...
随机推荐
- 200 OK (from cache) 与 304 Not Modified
解释: 200 OK (from cache) 是浏览器没有跟服务器确认,直接用了浏览器缓存: 304 Not Modified 是浏览器和服务器多确认了一次缓存有效性,再用的缓存. 触发区别: 2 ...
- C++的引用类型的变量到底占不占用内存空间?
——by karottc 分析一下 C++ 里面的引用类型(例如: int &r = a; )中的 r 变量是否占用内存空间呢?是否和 int *p = &a; 中的 p 变量 ...
- Java基础 —— 概述
Java语言: JDK(Java Development Kit)开发工具包,提供Java的开发环境和运行环境 --> 适合于开发 JRE(Java Runtime Environment)Ja ...
- deep learning 的java库
deepLearning4j: https://github.com/deeplearning4j/libnd4j/issues/208 deepLearn ...
- 通过用 .NET 生成自定义窗体设计器来定制应用程序
通过用 .NET 生成自定义窗体设计器来定制应用程序 https://www.microsoft.com/china/MSDN/library/netFramework/netframework/Cu ...
- A JavaFX based Game Authoring System
http://www.mirkosertic.de/doku.php/javastuff/javafxgameauthoring ——————————————————————————————————— ...
- Codeforces Round #368 (Div. 2) A. Brain's Photos (水题)
Brain's Photos 题目链接: http://codeforces.com/contest/707/problem/A Description Small, but very brave, ...
- Bash's ArithmeticExpression
[Bash's ArithmeticExpression] let command: let a=17+23 echo "a = $a" # Prints a = 40 let a ...
- 新 esb-cs-tool.jar 参数说明
旧esb-cs-tool.jar 使用说明 : invoke(RequestBusinessObject requestBo) 旧参数说明: requestBo : 封装好的请求参数大对象 Req ...
- hdu 2084 数塔 (简单dp)
http://acm.hdu.edu.cn/showproblem.php?pid=2084 数塔 Time Limit: 1000/1000 MS (Java/Others) Memory L ...