一,安全支付服务简介:
1.1,安全支付服务介绍。
安全支付服务是安装在本地Android操作系统上的一个组件,主要用来向其它的应用程序提供便捷、安全以及可靠的支付服务。正如平常系统上所提供的其它服务,如电子邮件和电话服务一样。本文主要描述安全支付服务应用开发接口的使用方法,供合作伙伴以及其它第三方应用开发者参考。
1.2,安全支付服务业务流程。
1.3,调用安全支付数据流程图
二,安全支付接入流程
2.1,接入前期准备
接入前期准备工作包括商户签约和密钥配置,已完成商户可略过。
2.1.1,商户签约
首先,商户需要在https://ms.alipay.com进行注册,并签约安全支付服务。签约成功后可获取支付宝分配的合作商户ID(PartnerID),账户ID(SellerID),如图:
签约过程中需要任何帮助请致电:0571-88158090(支付宝商户服务专线)
2.1.2,密钥配置
签约成功后,商户可登陆https://ms.alipay.com获取商户账号对应的支付宝公钥,具体获取步骤请见3.2 RSA密钥详解
接着,商户生成商户公钥和商户私钥(具体生成步骤请见3.2 RSA密钥详解),并登陆https://ms.alipay.com,上传商户公钥(具体上传步骤请见3.2 RSA密钥详解)。
至此,接入前期准备工作完成,下一节将使用demo测试准备工作是否正确。
2.2,Demo
为了便于商户的接入,我们提供了安全支付demo。通过本demo,商户可测试2.1节的前期准备工作是否正确完成,同时还可参考demo的代码完成接入。(注意:请勿在模拟器下测试demo,否则可能导致付款账户被锁定!)
2.2.1,Demo 配置运行
步骤 1:
解压下载的安全支付开发资料压缩包WS_SECURE_PAY,进入目录“WS_SECURE_PAY\Android”,其中“AppDemo4_0413”即demo的项目文件,将其导入eclipse,步骤如图:
项目结构如图:
步骤 2:
打开“PartnerConfig.java”文件,按照注释添加商户账号信息,具体包括:合作商户ID、账户ID、支付宝公钥(即服务器公钥)、商户公钥、商户私钥。如下图:
步骤 3:
在真机或者模拟器上运行项目(下图以模拟器为例),首次启动时,由于系统未安装安全支付服务,将出现以下提示:
此时,可以选择“确定”进行安装,安装后该提示不会再出现。此时点击任意商品进行购买,即启动安全支付:
首次运行安全支付服务,会进行安全认证,此时选择“支付宝账户”付款(注意:付款用的账户应为某一真实账户,交易金额也是真实的!),输入账户信息,按照提示一步步进行:
完成安全认证后,若出现如下提示,说明密钥配置有误,请仔细阅读3.2 RSA密钥详解
若出现“确认支付”页面,说明密钥配置无误,接入前期准备工作全部正确完成。接下来将正式进行安全支付的接入集成。
2.2.2,Demo结构说明
2.3 安全支付集成
本章指导在商户项目中集成安全支付,关键代码以Demo为例。
步骤 1:添加jar文件
添加demo中的alipay_msp.jar包添加工程中。
步骤 2:初始化安全支付服务
在调用安全支付进行支付前,需要先初始化安全支付服务,主要代码如下:
private ServiceConnection mAlixPayConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
// Wake up the binder to continue.
synchronized (lock) {
mAlixPay = IAlixPay.Stub.asInterface(service);
lock.notify();
}
}
public void onServiceDisconnected(ComponentName className) {
mAlixPay = null;
}
};
...
// Bind the service, then can call the service.
mActivity.bindService(new Intent(IAlixPay.class.getName()),
mAlixPayConnection, Context.BIND_AUTO_CREATE);
在调用安全支付时,需要提交订单信息orderInfo其中参数以“key=value”形式呈现,参数之间以“&”分割,所有参数不可缺。示例如下:(红色参数表示该参数值需与示例一致,不可自定义;蓝色参数表示值可自定义。具体参数说明请见订单信息描述)
其中sign值的生成,请见商品信息签名。需要特别注意的是:对数据签名后得到的sign值必须进行URLEncode,之后才可作为参数。
partner="2088002007260245"&seller="2088002007260245"&out_trade_no="500000000006548"&subject="商品名称"&body="这是商品描述"&total_fee="30"¬ify_url="http://notify.java.jpxx.org/index.jsp"&sign="kU2Fa3x6V985g8ayTozI1eJ5fHtm8%2FJGeJQf9in%2BcVmRJjHaExbirnGGKJ%2F7B63drqc4Kjlk%2FSg6vtSIkOtdvVBrRDpYaKxXVqkJTzRYgUwrrpMudbIj9aMS2O3dHG0GPyL4Zb6jKDYXHabGG0aBJY3QA7JuTJ23t6SqV%2B5f1xg%3D"&sign_type="RSA"
步骤 4:调用安全支付
2.4 应用发布
准备好参数后,即可调用安全支付进入支付流程并获得调用结果,代码如下:
result = mAlixPay.Pay(orderInfo);
AliXPay函数具体说明请见AlixPay方法描述。
步骤 5:支付结果获取和处理
调用安全支付后,将通过两种途径获得支付结果:
1、 AliXpay.pay()方法的返回
该方法将返回表示支付结果的字符串,详细信息详见
2、支付宝服务器通知
商户需要提供一个http协议的接口,包含在参数里传递给安全支付,即notify_url。支付宝服务器在支付完成后,会用POST方法调用notufy_url,以xml为数据格式传输支付结果,详见
接下来以Demo代码为例,介绍整个流程:
/*
* Initialize serviceConnection to get the stub
* Referrence class: MobileSecurePayer
*/
private ServiceConnection mAlixPayConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
// wake up the binder to continue.
synchronized (lock) {
mAlixPay = IAlixPay.Stub.asInterface(service);
lock.notify();
}
}
/*
* Prepare the Info which will be used to call SecurePayment service
* Referrence class: AlixDemo
* Referrence method: onItemClick
*/
String orderInfo = getOrderInfo(arg2);
String signType = getSignType();
String strsign = sign(signType, orderInfo); //
strsign = URLEncoder.encode(strsign);
String info = orderInfo + "&sign=" + "\"" + strsign + "\"" + "&"
+ getSignType();
class: MobileSecurePayer
*/
public boolean pay(final String orderInfo, final Handler callback,
final int myWhat, final Activity activity) {
// Return false if it’s paying.
if (mIsPaying)
return false;
// Return true if it’s not paying.
mIsPaying = true;
mActivity = activity;
// bind the service.
if (mAlixPay == null) {
mActivity.bindService(new Intent(IAlixPay.class.getName()),
mAlixPayConnection, Context.BIND_AUTO_CREATE);
}
new Thread(new Runnable() {
public void run() {
try {
/**
* wait for the service bind operation to completely
* finished. Note: this is important, otherwise the next
* mAlixPay.Pay() will fail.
*/
synchronized (lock) {
if (mAlixPay == null)
lock.wait();
}
// register a Callback for the service.
mAlixPay.registerCallback(mCallback);
// call the MobileSecurePay service.
result = mAlixPay.Pay(orderinfo);
/**
* set the flag to indicate that we have finished.
* unregister the Callback, and unbind the service.
*/
mIsPaying = false;
mAlixPay.unregisterCallback(mCallback);
mActivity.unbindService(mAlixPayConnection);
// send the result back to caller.
Message msg = new Message();
msg.what = myWhat;
msg.obj = result;
callback.sendMessage(msg);
} catch (Exception e) {
e.printStackTrace();
// send the result back to caller.
Message msg = new Message();
msg.what = myWhat;
msg.obj = e.toString();
// msg.obj = strRet;
callback.sendMessage(msg);
}
}
}).start();
return true;
}
}
2.4 应用发布
为了提升用户体验,避免捆绑安装旧版本的安全支付服务之后,接着又需要重新升级并安装成最新版本,我们目前推荐结合使用以上两种集成方式。在最新的demo中,会首先连接支付宝服务器,检测并判断捆绑在第三方客户端中的alipay_plugin.apk是否为最新版本,如果是,则直接安装。如果捆绑在第三方客户端中的alipay_plugin.apk不是最新版本,则从服务器中下载最新版本的安装包,然后进行安装。
2.4.1运行时安装
运行时安装的具体步骤如下所示:
1) 将alipay_plugin.apk作为资源复制到第三方应用工程中的assets目录。
2) 第三方应用在需要付款时(或者其它恰当时机),先检测安全支付服务是否已经安装。如果尚未安装,则从assets目录中提取alipay_plugin.apk到手机存储。
3) 安装手机存储中的安全支付服务apk。
以下是一个代码片段,演示上述过程。
// Install the APK of SecurePayment which is included in the merchant’s App. public boolean retrieveApkFromAssets(Context context, String fileName, String path) { boolean isRetrieve = false; InputStream input = null; FileOutputStream output = null; try { input = context.getAssets().open(fileName); File file = new File(path); file.createNewFile(); output = new FileOutputStream(file); byte[] temp = new byte[1024]; int i = 0; while ((i = input.read(temp)) > 0) { output.write(temp, 0, i); } isRetrieve = true != null){ try { output.close(); } catch (IOException e) { } } if(input != null){ try { input.close(); } catch (IOException e) { } } } return isRetrieve; }
2.4.2 动态下载安装
动态下载安装的具体步骤如下所示:
1) 由支付宝预先将安全支付服务apk放置到约定的远程下载服务器。
2) 第三方应用在需要付款时(或者其它恰当时机),先检测安全支付服务是否已经安装。如果尚未安装,则从约定的远程下载服务器提取alipay_plugin.apk到手机存储。
3) 安装手机存储中的安全支付服务apk。
以下是一个代码片段,演示上述过程。
// Download the APK of SecurePayment public boolean retrieveApkFromNet(Context context, String strurl, String filename) { boolean isRetrieve = false; try { NetworkManager networkManager = new NetworkManager(this.mContext); isRetrieve = networkManager.downloadToFile(context, strurl, filename); } catch (Exception e) { e.printStackTrace(); } return isRetrieve; } } catch (IOException e) { e.printStackTrace (); }finally{ if(output != null){ try { output.close(); } catch (IOException e) { } } if(input != null){ try { input.close(); } catch (IOException e) { } } } return isRetrieve; }
第三章 RSA详解
以下内容加*号为重点
3.1 RSA和OpenSSL介绍
3.1.1什么是RSA
RSA是一种非对称的签名算法,即签名密钥(私钥)与验签密钥(公钥)是不一样的,私钥用于签名,公钥用于验签。
在与支付宝交易中,会有2对公私钥,即商户公私钥,支付宝公钥。
商户公私钥:由商户生成,商户私钥用于对商户发往支付宝的数据签名;商户公钥需要上传至支付宝,当支付宝收到商户发来的数据时用该公钥验证签名。
支付宝公钥:支付宝提供给商户,当商户收到支付宝发来的数据时,用该公钥验签。
3.1.2为什么要用RSA
使用这种算法可以起到防止数据被篡改的功能,保证支付订单和支付结果不可抵赖(商户私钥只有商户知道)。
3.1.3什么是OpenSSL
一句话概括:OpenSSL是基于众多的密码算法、公钥基础设施标准以及SSL协议安全开发包。
3.1.4为什么要用OpenSSL
通过OpenSSL生成的签名和内置的算法可以做到跨平台,这样在不同的开发语言中均可以签名和验签。
3.2 RSA密钥详解*
3.2.1找到生成
RSA密钥工具
(1)下载开发指南和集成资料,如下图,您能看到此文档说明指南和集成包已经下载了。
(2)解压下载的压缩包
(WS_SECURE_PAY),找到并解压
openssl-0.9.8k_WIN32(RSA密钥生成工具
).zip工具包
3.2.2生成商户密钥并获取支付宝公钥
(1) 生成原始
RSA商户私钥文件
假设解压后的目录为
c:\alipay,命令行进入目录
C:\alipay\bin,执行
“opensslgenrsa-out rsa_private_key.pem 1024”,在C:\alipay\bin下会生成文件rsa_private_key.pem,
其内容为
原始的商户私钥(请妥善保存该文件),以下为命令正确执行截图:
(2) 将原始
RSA商户私钥转换为
pkcs8格式
命令行执行
“ openssl pkcs8 -topk8 -inform PEM -inrsa_private_key.pem -outform PEM-nocrypt”得到转换为pkcs8格式的私钥。复制下图红框内的内容至新建txt文档,去掉换行,最后另存为“private_key.txt”(请妥善保存,签名时使用)。
(3)生成RSA商户公钥
命令行执行“ openssl rsa -in rsa_private_key.pem -pubout -outrsa_public_key.pem”,在C:\alipay\bin文件夹下生成文件rsa_public_key.pem。接着用记事本打开rsa_public_key.pem,复制全部内容至新建的txt文档,删除文件头“-----BEGIN PUBLICKEY-----”与文件尾“-----ENDPUBLIC KEY-----”及空格、换行,如下图。最后得到一行字符串并保存该txt文件为“public_key.txt”。
(4)上传商户公钥至支付宝
浏览器访问https://ms.alipay.com/index.htm并用签约帐号登录,点击菜单栏“我的产品”,右侧点击“密钥管理”,见下图红色框内
(5)获取RSA支付宝公钥
成功上传公钥至支付宝后,页面显示如下:
其中红色框内部分即支付宝公钥,请复制至新建txt文档,去掉换行和空格,妥善保存(用于验签收到的支付宝通知)。
3.3 RSA签名和验签*
建议:签名和验签尽量在商户服务器端进行,同时一些敏感数据(如公私钥等)也应存储在服务器端,避免可能的安全隐患。
3.3.1 RSA签名
(1)在项目中添加下面的类:
对不起各位,最近比较忙,一直没时间编辑,下面放出官方源文件,大家可以直接下载查看!
http://download.csdn.net/detail/gulaer/5017686