一、准备工作
〉1、下载开发包
压缩包下的“支付宝钱包支付接口开发包”中即有Andoid使用支付宝的JAR和Demo
〉2、创建支付宝应用
在支付宝开放平台申请创建应用
https://open.alipay.com/index.htm
支付宝平台的应用创建仅限于公司实名认证用户,个人帐号是不能创建应用的,应用申请我没试过,暂且不做说明
〉3、AndroidManifest.xml 修改 (权限、界面、服务等申明)
>4、获取开发所需要的参数数据
商户私钥和支付宝公钥都是需要通过支付宝开发包中的openssl文件夹下的bin目录下的OpenSSL程序生成
命令如下:
RSA密钥生成命令生成RSA私钥openssl>genrsa-outrsa_private_key.pem1024
生成RSA公钥openssl>rsa-inrsa_private_key.pem-pubout-outrsa_public_key.pem
将RSA私钥转换成PKCS8格式openssl>pkcs8-topk8-nocrypt-inform PEM-inrsa_private_key.pem-outform PEM outform
开发者的私钥
1、必须保证只有一行文字,即,没有回车、换行、空格等
2、去掉“—–BEGIN RSA PRIVATE KEY—–”、“—–END RSA PRIVATE KEY—–”,只保存这两条文字之中的部分
◆开发者的公钥
1、必须保证只有一行文字,即,没有回车、换行、空格等
2、去掉“—–BEGIN PUBLIC KEY—–”、“—–END PUBLIC KEY—–”,只保存这两条文字之中的部分
3、保存到一个临时的记事本中。
参数设置完成
〉5、加载Jar文件
将开发包中的alipay-sdk-common文件夹下面的jar文件复制到项目的libs目录下并加载
〉6、添加混淆规则
在gradle.properties文件中添加如下代码
-libraryjars libs/alipaysdk.jar
-libraryjars libs/alipaysecsdk.jar
-libraryjars libs/alipayutdid.jar
-keepclasscom.alipay.android.app.IAlixPay{*;}
-keepclasscom.alipay.android.app.IAlixPay$Stub{*;}
-keepclasscom.alipay.android.app.IRemoteServiceCallback{*;}
-keepclasscom.alipay.android.app.IRemoteServiceCallback$Stub{*;}
-keepclasscom.alipay.sdk.app.PayTask{public*;}
-keepclasscom.alipay.sdk.app.AuthTask{public*;}
-keepclasscom.alipay.mobilesecuritysdk.*
-keepclasscom.ut.*
二、开发
/**
* create the order info. 创建订单信息
*/
privateString getOrderInfo(String subject, String body, String price) {
// 签约合作者身份ID
String orderInfo ="partner="+"\""+PARTNER+"\"";
// 签约卖家支付宝账号
orderInfo +="&seller_id="+"\""+SELLER+"\"";
// 商户网站唯一订单号
orderInfo +="&out_trade_no="+"\""+ getOutTradeNo() +"\"";
// 商品名称
orderInfo +="&subject="+"\""+ subject +"\"";
// 商品详情
orderInfo +="&body="+"\""+ body +"\"";
// 商品金额
orderInfo +="&total_fee="+"\""+ price +"\"";
// 服务器异步通知页面路径
orderInfo +="¬ify_url="+"\""+"http://notify.msp.hk/notify.htm"+"\"";
// 服务接口名称, 固定值
orderInfo +="&service=\"mobile.securitypay.pay\"";
// 支付类型, 固定值
orderInfo +="&payment_type=\"1\"";
// 参数编码, 固定值
orderInfo +="&_input_charset=\"utf-8\"";
// 设置未付款交易的超时时间
// 默认30分钟,一旦超时,该笔交易就会自动被关闭。
// 取值范围:1m~15d。
// m-分钟,h-小时,d-天,1c-当天(无论交易何时创建,都在0点关闭)。
// 该参数数值不接受小数点,如1.5h,可转换为90m。
orderInfo +="&it_b_pay=\"30m\"";
// extern_token为经过快登授权获取到的alipay_open_id,带上此参数用户将使用授权的账户进行支付
// orderInfo += "&extern_token=" + "\"" + extern_token + "\"";
// 支付宝处理完请求后,当前页面跳转到商户指定页面的路径,可空
orderInfo +="&return_url=\"m.alipay.com\"";
// 调用银行卡支付,需配置此参数,参与签名, 固定值 (需要签约《无线银行卡快捷支付》才能使用)
// orderInfo += "&paymethod=\"expressGateway\"";
returnorderInfo;
}
2、调用SDK支付
/**
* 特别注意,这里的签名逻辑需要放在服务端,切勿将私钥泄露在代码中!
*/
String sign = sign(orderInfo);
try {
/**
* 仅需对sign 做URL编码
*/
sign = URLEncoder.encode(sign, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
/**
* 完整的符合支付宝参数规范的订单信息
*/
final String payInfo = orderInfo + "&sign=\"" + sign + "\"&" + getSignType();
Runnable payRunnable = new Runnable() {
@Override
public void run() {
// 构造PayTask 对象
PayTask alipay = new PayTask(MainActivity.this);
// 调用支付接口,获取支付结果
String result = alipay.pay(payInfo, true);
Message msg = new Message();
msg.what = SDK_PAY_FLAG;
msg.obj = result;
mHandler.sendMessage(msg);
}
};
// 必须异步调用
Thread payThread = new Thread(payRunnable);
payThread.start();
3、支付结果获取和处理
@SuppressLint("HandlerLeak")
privateHandlermHandler=newHandler() {
@SuppressWarnings("unused")
public voidhandleMessage(Message msg) {
switch(msg.what) {
caseSDK_PAY_FLAG: {
PayResult payResult =newPayResult((String) msg.obj);
// Log.d("MainActivity", "msg.obj:" + msg.obj);
/**
* 同步返回的结果必须放置到服务端进行验证(验证的规则请看https://doc.open.alipay.com/doc2/
* detail.htm?spm=0.0.0.0.xdvAU6&treeId=59&articleId=103665&
* docType=1) 建议商户依赖异步通知
*/
String resultInfo = payResult.getResult();// 同步返回需要验证的信息
String resultStatus = payResult.getResultStatus();
// 判断resultStatus 为“9000”则代表支付成功,具体状态码代表含义可参考接口文档
if(TextUtils.equals(resultStatus,"9000")) {
Toast.makeText(MainActivity.this,"支付成功", Toast.LENGTH_SHORT).show();
}else{
// 判断resultStatus 为非"9000"则代表可能支付失败
// "8000"代表支付结果因为支付渠道原因或者系统原因还在等待支付结果确认,最终交易是否成功以服务端异步通知为准(小概率状态)
if(TextUtils.equals(resultStatus,"8000")) {
Toast.makeText(MainActivity.this,"支付结果确认中", Toast.LENGTH_SHORT).show();
}else{
// 其他值就可以判断为支付失败,包括用户主动取消支付,或者系统返回的错误
Toast.makeText(MainActivity.this,"支付失败", Toast.LENGTH_SHORT).show();
}
}
break;
}
default:
break;
}
}
};
源码地址:https://github.com/LostDeer