1.集成,下载官方demo后,将alipaySdk-20151112.jar包导入工程。
修改Manifest
<!-- 支付宝支付 -->
<activity
android:name="com.alipay.sdk.app.H5PayActivity"
android:configChanges="orientation|keyboardHidden|navigation"
android:exported="false"
android:screenOrientation="behind" />
<activity
android:name="com.alipay.sdk.auth.AuthActivity"
android:configChanges="orientation|keyboardHidden|navigation"
android:exported="false"
android:screenOrientation="behind" />
添加混淆
-libraryjars libs/alipaySDK-20150602.jar
-keep class com.alipay.android.app.IAlixPay{*;}
-keep class com.alipay.android.app.IAlixPay$Stub{*;}
-keep class com.alipay.android.app.IRemoteServiceCallback{*;}
-keep class com.alipay.android.app.IRemoteServiceCallback$Stub{*;}
-keep class com.alipay.sdk.app.PayTask{ public *;}
-keep class com.alipay.sdk.app.AuthTask{ public *;}
2.公匙和私匙的获取和配置参考:Android 开发支付宝 私匙和公匙 。。注意在代码中如果是客户端开发,我们只需要使用私匙,公匙只有上传到支付宝上即可。
3.创建订单
String orderInfo = ConstantPay.getOrderInfo(name, product, money,orderId);
看看orderInfo方法
/**
* create the order info. 支付宝 创建订单信息
*
*/
public static String getOrderInfo(String subject, String body, String price,String orderId) {
// 签约合作者身份ID
String orderInfo = "partner=" + "\"" + PARTNER + "\"";
// 签约卖家支付宝账号
orderInfo += "&seller_id=" + "\"" + SELLER + "\"";
// 商户网站唯一订单号
orderInfo += "&out_trade_no=" + "\"" + orderId + "\"";
// 商品名称
orderInfo += "&subject=" + "\"" + subject + "\"";
// 商品详情
orderInfo += "&body=" + "\"" + body + "\"";
// 商品金额
orderInfo += "&total_fee=" + "\"" + price + "\"";
// 服务器异步通知页面路径
orderInfo += "¬ify_url=" + "\"" + "http://jkdc.csn2008.com/index.php/app/wxpay/notify"
+ "\"";
// 服务接口名称, 固定值
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=\"\"";
// 调用银行卡支付,需配置此参数,参与签名, 固定值 (需要签约《无线银行卡快捷支付》才能使用)
// orderInfo += "&paymethod=\"expressGateway\"";
return orderInfo;
}
4:再次签名
// 对订单做RSA 签名
String sign = ConstantPay.sign(orderInfo);
看看sign方法
/**
* 支付宝签名
*/
private static final String ALGORITHM = "RSA";
private static final String SIGN_ALGORITHMS = "SHA1WithRSA";
private static final String DEFAULT_CHARSET = "UTF-8";
public static String sign(String content) {
try {
PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(
Base64.decode(RSA_PRIVATE));
KeyFactory keyf = KeyFactory.getInstance(ALGORITHM);
PrivateKey priKey = keyf.generatePrivate(priPKCS8);
java.security.Signature signature = java.security.Signature
.getInstance(SIGN_ALGORITHMS);
signature.initSign(priKey);
signature.update(content.getBytes(DEFAULT_CHARSET));
byte[] signed = signature.sign();
return Base64.encode(signed);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
5:根据官方解释做签名
- 在请求参数列表中,除去sign、sign_type两个参数外,其他需要使用到的参数皆是要签名的参数。
- 在同步通知、服务器异步通知参数列表中,除去sign、sign_type两个参数外,凡是通知返回回来的参数皆是要验签的参数。
- sign值要做utf-8 URLencode。
try {
// 仅需对sign 做URL编码
sign = URLEncoder.encode(sign, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
6:完善订单规范
// 完整的符合支付宝参数规范的订单信息
final String payInfo = orderInfo + "&sign=\"" + sign + "\"&"
+ getSignType();
看看getSignType方法
/**
* get the sign type we use.支付宝 获取签名方式
*/
public String getSignType() {
return "sign_type=\"RSA\"";
}
7。下面就是和支付宝交互。
Android平台上的快捷支付开发包接口如下表所示:
接口名称 | 接口描述 |
---|---|
PayTask | 开发包提供支付,查询的对象接口。 |
PayTask对象主要为商户提供订单支付功能,查询该设备终端是否存在认证过的支付宝账户,及获取当前开发包版本号。
订单支付
方法名称:payTask.pay
方法原型:PayTask payTask = new PayTask(activity); payTask.pay(orderInfo,true);
方法功能:提供给商户订单支付功能。
方法参数: 实例化PayTask,传入参数activity 的实例。
参数名称 | 参数说明 |
---|---|
String orderInfo | 主要包含商户的订单信息,key=“value”形式,以&连接。 |
boolean isShowPayLoading | 用户在商户app内部点击付款,是否需要一个loading做为在钱包唤起之前的过渡,这个值设置为true,将会在调用pay接口的时候直接唤起一个loading,直到唤起H5支付页面或者唤起外部的钱包付款页面loading才消失。(建议将该值设置为true,优化点击付款到支付唤起支付页面的过渡过程。) |
Runnable payRunnable = new Runnable() {
@Override
public void run() {
// 构造PayTask 对象
PayTask alipay = new PayTask(PayTypeActivity.this);
// 调用支付接口,获取支付结果
String result = alipay.pay(payInfo);
Message msg = new Message();
msg.what = SDK_PAY_FLAG;
msg.obj = result;
myHanlder.sendMessage(msg);
}
};
// 必须异步调用
Thread payThread = new Thread(payRunnable);
payThread.start();
8:处理结果:
public class MyHanlder extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case SDK_PAY_FLAG:
PayResult payResult = new PayResult((String) msg.obj);
// 支付宝返回此次支付结果及加签,建议对支付宝签名信息拿签约时支付宝提供的公钥做验签
String resultInfo = payResult.getResult();
String resultStatus = payResult.getResultStatus();
// 判断resultStatus 为“9000”则代表支付成功,具体状态码代表含义可参考接口文档
if (TextUtils.equals(resultStatus, "9000")) {
Toast.makeText(PayTypeActivity.this, "支付成功",
Toast.LENGTH_SHORT).show();
StringRequest stringRequest = new StringRequest(Request.Method.GET, getMoccaApi().getNotifyOk(), new Response.Listener<String>() {
@Override
public void onResponse(String response) {
Intent intent = new Intent(PayTypeActivity.this,ApplySuccessActivity.class);
if ("1".equals(flag)) {
// intent.setAction(Constants.WX_FLAG_1);
intent.putExtra("signs", bicycleList.yuyued_name);
intent.putExtra("name",product);
intent.putExtra("flag",true);
}
else {
//intent.setAction(Constants.WX_FLAG_2);
intent.putExtra("signs", applyType.activity_name);
intent.putExtra("name",product);
intent.putExtra("flag",false);
}
startActivity(intent);
finish();
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
toast("通知服务器失败");
}
});
requestQueue.add(stringRequest);
} else {
// 判断resultStatus 为非“9000”则代表可能支付失败
// “8000”代表支付结果因为支付渠道原因或者系统原因还在等待支付结果确认,最终交易是否成功以服务端异步通知为准(小概率状态)
if (TextUtils.equals(resultStatus, "8000")) {
Toast.makeText(PayTypeActivity.this, "支付结果确认中",
Toast.LENGTH_SHORT).show();
} else {
// 其他值就可以判断为支付失败,包括用户主动取消支付,或者系统返回的错误
Toast.makeText(PayTypeActivity.this, "支付失败",
Toast.LENGTH_SHORT).show();
}
}
break;
}
}
}
最后是跳到支付成功的页面,我们可以通过发送广播来处理消息
flag = getIntent().getBooleanExtra("flag",false);
naem = getIntent().getStringExtra("name");
signs = getIntent().getStringExtra("signs");
if (flag){
tvEventName.setText("您报名参加了"+signs+"活动");
tvEventLook.setText("可在个人中心-我的比赛活动中查看");
}else {
tvEventName.setText("您预定了"+signs+"");
tvEventLook.setText("可在个人中心-我的订单中查看");
}
btnConfim.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setAction(Constants.WX_BUG);
sendBroadcast(intent);
finish();
}
});
private BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
UIUtils.log(action + "---------------------------");
switch (intent.getAction()) {
case Constants.WX_CODE:
toast("获取支付成功");
UIUtils.log("ectity" + ectity.toString());
break;
case Constants.WX_ERRO:
toast("获取支付信息失败");
break;
case Constants.WX_BUG:
finish();
break;
}
}
};
其实官方demo完善的很不错,我们根据官方demo写就行。