首先,贴上支付宝官方开放平台地址和部分开发文档:
主要流程如下:
- 申请开发者,身份选择系统服务商ISV,创建应用并获取APPID。秘钥生成链接:生成密钥:快速生成RSA私钥公钥
- 配置应用,集成并配置SDK。参考APP支付宝登录快速接入
- 调用接口
注意:
(1)这里是APP支付宝第三方登录,不是第三方应用授权,开发文档不要参考错了
(2)不要在沙箱环境下做调试,直接在第一步将创建的应用上线然后再调试即可(APPID用创建的应用ID,不要用沙箱的)
(3)关于PID参数,不太好找,贴出来位置合作伙伴身份(PID)
下面是代码
/**
* APP支付宝登录
*
* 这里只是为了方便,直接向加签过程直接放在客户端完成;
* 真实App里,privateKey等数据严禁放在客户端,加签过程务必要放在服务端完成;
* 防止商户私密数据泄露,造成不必要的资金损失,及面临各种安全风险;
*/
public class ALiLoginUtils {
public Activity activity;
/** 支付宝支付业务:入参app_id */
public static final String APPID = "你创建的应用APPID";
/** 支付宝账户登录授权业务:入参pid值 */
public static final String PID = "合作伙伴身份PID";
/** 支付宝账户登录授权业务:入参target_id值 可自定义,保证唯一性即可*/
public static final String TARGET_ID = "保证唯一性即可";
/** 商户私钥,pkcs8格式 */
/** 如下私钥,RSA2_PRIVATE 或者 RSA_PRIVATE 只需要填入一个 */
/** 如果商户两个都设置了,优先使用 RSA2_PRIVATE */
/** RSA2_PRIVATE 可以保证商户交易在更加安全的环境下进行,建议使用 RSA2_PRIVATE */
/** 获取 RSA2_PRIVATE,建议使用支付宝提供的公私钥生成工具生成, */
/** 工具地址:https://doc.open.alipay.com/docs/doc.htm?treeId=291&articleId=106097&docType=1 */
public static final String RSA2_PRIVATE = "填你自己的应用私钥,要和配置应用时的应用公钥对应";
public static final String RSA_PRIVATE = "";
private static final int SDK_AUTH_FLAG = 2;
public ALiLoginUtils(Activity activity){
this.activity = activity;
}
@SuppressLint("HandlerLeak")
private Handler mHandler = new Handler() {
@SuppressWarnings("unused")
public void handleMessage(Message msg) {
switch (msg.what) {
case SDK_AUTH_FLAG: {
@SuppressWarnings("unchecked")
AuthResult authResult = new AuthResult((Map<String, String>) msg.obj, true);
String resultStatus = authResult.getResultStatus();
String resultCode = authResult.getResultCode();
Log.e("ALiLoginActivity", "=====resultStatus=====" + resultStatus);
Log.e("ALiLoginActivity", "=====resultCode=====" + resultCode);
// 判断resultStatus 为“9000”且result_code
// 为“200”则代表授权成功,具体状态码代表含义可参考授权接口文档
if (TextUtils.equals(resultStatus, "9000") && TextUtils.equals(authResult.getResultCode(), "200")) {
// 获取alipay_open_id,调支付时作为参数extern_token 的value
// 传入,则支付账户为该授权账户
Log.e("ALiLoginActivity", "授权成功\n" + String.format("authCode:%s", authResult.getAuthCode()));
// Toast.makeText(activity,"授权成功\n" + String.format("authCode:%s", authResult.getAuthCode()), Toast.LENGTH_SHORT).show();
} else {
// 其他状态值则为授权失败
Log.e("ALiLoginActivity", "授权失败\n" + String.format("authCode:%s", authResult.getAuthCode()));
// Toast.makeText(activity,"授权失败" + String.format("authCode:%s", authResult.getAuthCode()), Toast.LENGTH_SHORT).show();
}
break;
}
default:
break;
}
};
};
/**
* 支付宝账户授权业务
*/
public void authV2() {
if (TextUtils.isEmpty(PID) || TextUtils.isEmpty(APPID)
|| (TextUtils.isEmpty(RSA2_PRIVATE) && TextUtils.isEmpty(RSA_PRIVATE))
|| TextUtils.isEmpty(TARGET_ID)) {
new AlertDialog.Builder(activity).setTitle("警告").setMessage("需要配置PARTNER |APP_ID| RSA_PRIVATE| TARGET_ID")
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialoginterface, int i) {
}
}).show();
return;
}
/**
* 这里只是为了方便直接向商户展示支付宝的整个支付流程;所以Demo中加签过程直接放在客户端完成;
* 真实App里,privateKey等数据严禁放在客户端,加签过程务必要放在服务端完成;
* 防止商户私密数据泄露,造成不必要的资金损失,及面临各种安全风险;
*
* authInfo的获取必须来自服务端;
*/
boolean rsa2 = (RSA2_PRIVATE.length() > 0);
Map<String, String> authInfoMap = OrderInfoUtil2_0.buildAuthInfoMap(PID, APPID, TARGET_ID, rsa2);
String info = OrderInfoUtil2_0.buildOrderParam(authInfoMap);
String privateKey = rsa2 ? RSA2_PRIVATE : RSA_PRIVATE;
String sign = OrderInfoUtil2_0.getSign(authInfoMap, privateKey, rsa2);
final String authInfo = info + "&" + sign;
Log.e("ALiLoginActivity", "=====authInfo=====" + authInfo);
Runnable authRunnable = new Runnable() {
@Override
public void run() {
// 构造AuthTask 对象
AuthTask authTask = new AuthTask(activity);
// 调用授权接口,获取授权结果
Map<String, String> result = authTask.authV2(authInfo, true);
Message msg = new Message();
msg.what = SDK_AUTH_FLAG;
msg.obj = result;
mHandler.sendMessage(msg);
}
};
// 必须异步调用
Thread authThread = new Thread(authRunnable);
authThread.start();
}
}
然后在Activity中直接调用工具类,如下:
/** 支付宝授权登录 */
case R.id.iv_alipay:
ALiLoginUtils aLiLogin = new ALiLoginUtils(LoginActivity.this);
aLiLogin.authV2();
break;
这里,直接把privateKey等数据放在客户端,实际加签过程务必要放在服务端完成;防止商户私密数据泄露,造成不必要的资金损失,及面临各种安全风险;authInfo(这里拼接了要向支付宝发送的所有数据信息,尤为重要)的获取必须来自服务端;
最后,代码只贴出了主要的流程,并不完整,其余的可以参考 App支付客户端DEMO&SDK
有兴趣或者需要的朋友,这里还有 Android 第三方登录之新浪微博授权登录