现在支付宝有两个支付接口,一个是老版的移动支付接口,一个是现在最新版(alipaySdk-20161009)的app支付接口。本文主要讲述的是最新版的app支付以及老版本支付(1.0)升级新版本(2.0)需注意的几个问题。
首先肯定要有支付宝账户,然后认证之后在支付宝开放平台创建应用,配置密钥,最后就是签约了。以上步骤请自行查看文档或咨询在线客服,这部分不涉及到技术开发。
接下来就是集成到自己的应用里了。参考支付宝开发文档
将支付sdk和demo下载下来,将alipaySdk-20161009.jar这个jar包导入工程,然后在清单文件里加上权限。
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
接下来将demo里的Base64.java、PayResult.java和SignUtils.java文件原封不动拷入项目里,然后将util包下的OrderInfoUtil2_0.java文件拷入项目里,然后将里面的buildOrderParamMap()方法略作修改。
demo里这个方法的代码如下:
/**
* 构造支付订单参数列表
* @param pid
* @param app_id
* @param target_id
* @return
*/
public static Map<String, String> buildOrderParamMap(String app_id) {
Map<String, String> keyValues = new HashMap<String, String>();
keyValues.put("app_id", app_id);
keyValues.put("biz_content", "{\"timeout_express\":\"30m\",\"product_code\":\"QUICK_MSECURITY_PAY\",\"total_amount\":\"0.01\",\"subject\":\"1\",\"body\":\"我是测试数据\",\"out_trade_no\":\"" + getOutTradeNo() + "\"}");
keyValues.put("charset", "utf-8");
keyValues.put("method", "alipay.trade.app.pay");
keyValues.put("sign_type", "RSA");
keyValues.put("timestamp", "2016-07-29 16:55:53");
keyValues.put("version", "1.0");
return keyValues;
}
这些参数含义见App支付请求参数说明。
这个方法还需要加上一个notify_url参数,这是异步通知路径,问后台要这个url地址。
然后参考PayDemoActivity这个类的代码自己写一个调用支付的类。
/**
* 支付宝调起支付类
*/
public class Alipay {
/** 支付宝支付业务:入参app_id */
public static final String APPID = "";
/** 商户私钥,pkcs8格式 */
public static final String RSA_PRIVATE = "";
private static final int SDK_PAY_FLAG = 1;
private String price;
private String subject;
private String body;
private String orderNo;
private Activity activity;
public Alipay(String price, String subject, String body, String orderNo, Activity activity) {
this.price = price;
this.subject = subject;
this.body = body;
this.orderNo = orderNo;
this.activity = activity;
}
@SuppressLint("HandlerLeak")
private Handler mHandler = new Handler() {
@SuppressWarnings("unused")
public void handleMessage(Message msg) {
switch (msg.what) {
case SDK_PAY_FLAG: {
@SuppressWarnings("unchecked")
PayResult payResult = new PayResult((Map) msg.obj);
/**
对于支付结果,请商户依赖服务端的异步通知结果。同步通知结果,仅作为支付结束的通知。
*/
String resultInfo = payResult.getResult();// 同步返回需要验证的信息
String resultStatus = payResult.getResultStatus();
// 判断resultStatus 为9000则代表支付成功
if (TextUtils.equals(resultStatus, "9000")) {
// 该笔订单是否真实支付成功,需要依赖服务端的异步通知。
Toast.makeText(activity, "支付成功", Toast.LENGTH_SHORT).show();
} else {
// 该笔订单真实的支付结果,需要依赖服务端的异步通知。
Toast.makeText(activity, "支付失败", Toast.LENGTH_SHORT).show();
}
break;
}
default:
break;
}
};
};
/**
* 支付宝支付业务
*
*/
public void payV2() {
if (TextUtils.isEmpty(APPID) || TextUtils.isEmpty(RSA_PRIVATE)) {
new AlertDialog.Builder(activity).setTitle("警告").setMessage("需要配置APPID | RSA_PRIVATE")
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialoginterface, int i) {
//
// finish();
}
}).show();
return;
}
/**
* 这里只是为了方便直接向商户展示支付宝的整个支付流程;所以Demo中加签过程直接放在客户端完成;
* 真实App里,privateKey等数据严禁放在客户端,加签过程务必要放在服务端完成;
* 防止商户私密数据泄露,造成不必要的资金损失,及面临各种安全风险;
*
* orderInfo的获取必须来自服务端;
*/
Map params = OrderInfoUtil2_0.buildOrderParamMap(APPID, price, subject, body, orderNo);
String orderParam = OrderInfoUtil2_0.buildOrderParam(params);
String sign = OrderInfoUtil2_0.getSign(params, RSA_PRIVATE);
final String orderInfo = orderParam + "&" + sign;
Log.e("orderInfo",orderInfo);
Runnable payRunnable = new Runnable() {
@Override
public void run() {
PayTask alipay = new PayTask(activity);
Map result = alipay.payV2(orderInfo, true);
Log.i("msp", result.toString());
Message msg = new Message();
msg.what = SDK_PAY_FLAG;
msg.obj = result;
mHandler.sendMessage(msg);
}
};
Thread payThread = new Thread(payRunnable);
payThread.start();
}
}
其中要注意的事项已经写在方法里了,构造交易数据并签名必须在商户服务端完成,商户的应用私钥绝对不能保存在商户APP客户端中,也不能从服务端下发。
其中alipay.payV2(orderInfo, true);的第二个参数是代表是否需要一个loading做为在钱包唤起之前的过渡。
一些支付成功后的后续操作请在mHandler 里进行,就无需多说了。
调用代码:
new Alipay("0.01","支付测试","测试支付0.01元","1234567890",MainActivity.this).payV2();
至此支付宝支付就集成好了。
如果你以前已经集成好了支付宝支付,要升级到最新版需注意以下几个问题:
1、需重新签约,不然其他的步骤即便是对了最后也无法支付成功。重新签约不影响以前1.0版本支付接口的使用。参考接口签约方案
2、如果未在支付宝开放平台上创建应用请新建应用并配置好密钥。使用这个配套的私钥。不能使用以前配置好的密钥。开放配置密钥也不影响1.0支付接口的使用。配置密钥参考配置应用环境
这个两个坑困扰了我好几天,代码没有问题就是支付不了,希望能为其他人提供一些帮助,少走一些弯路。