概述
1,去网站下载demo
https://docs.open.alipay.com/54/104509/
2,之前由于粗心,只顾着搞支付,忘记仔细研究代码,这个demo里包含了支付和授权登录也就是三方登录。
下面是我对代码简单的理解。项目最终还是要放到自己的项目里,下面就以我的项目为例。
支付:
1,导包,
2,AndroidManifest文件里增加代码:至于权限就不在啰嗦了,别忘了把demo里的需要的代码也拷过来。
<!-- alipay sdk begin -->
<activity
android:name="com.alipay.sdk.app.H5PayActivity"
android:configChanges="orientation|keyboardHidden|navigation|screenSize"
android:exported="false"
android:screenOrientation="behind"
android:windowSoftInputMode="adjustResize|stateHidden"></activity>
<activity
android:name="com.alipay.sdk.app.H5AuthActivity"
android:configChanges="orientation|keyboardHidden|navigation"
android:exported="false"
android:screenOrientation="behind"
android:windowSoftInputMode="adjustResize|stateHidden"></activity>
<!-- alipay sdk end -->
1,类代码
package com.flyandroid.view;
import android.os.Bundle;
import java.util.Map;
import com.alipay.sdk.app.PayTask;
import com.flyandroid.R;
import com.flyandroid.alipay.AuthResult;
import com.flyandroid.alipay.PayResult;
import com.flyandroid.utils.Httpurl;
import com.flyandroid.utils.To;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.FragmentActivity;
import android.text.TextUtils;
import android.widget.Toast;
import org.json.JSONException;
import org.json.JSONObject;
import org.xutils.common.Callback;
import org.xutils.http.RequestParams;
import org.xutils.x;
/**
* Created by lake
* 此类的功能:支付宝支付界面
*/
public class ALiPay extends FragmentActivity{
private static final int SDK_PAY_FLAG = 1;
private static final int SDK_AUTH_FLAG = 2;
@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<String, String>) msg.obj);
/**
对于支付结果,请商户依赖服务端的异步通知结果。同步通知结果,仅作为支付结束的通知。
*/
String resultInfo = payResult.getResult();// 同步返回需要验证的信息
String resultStatus = payResult.getResultStatus();
// 判断resultStatus 为9000则代表支付成功
if (TextUtils.equals(resultStatus, "9000")) {
// 该笔订单是否真实支付成功,需要依赖服务端的异步通知。
Toast.makeText(ALiPay.this, "支付成功", Toast.LENGTH_SHORT).show();
finish();
} else {
// 该笔订单真实的支付结果,需要依赖服务端的异步通知。
Toast.makeText(ALiPay.this, "支付失败", Toast.LENGTH_SHORT).show();
finish();
}
break;
}
default:
break;
}
};
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// EnvUtils.setEnv(EnvUtils.EnvEnum.SANDBOX); 沙箱测试
setContentView(R.layout.pay_main);
init();
}
private void init() { //这是上个界面传递过来的值 ,标题,订单号,金额
Intent intent = getIntent();
String title = intent.getStringExtra("title");
String num = intent.getStringExtra("num");
String money = intent.getStringExtra("money");
getorder(title,num,money);
}
//获取传递支付宝需要的data
// String subject 商品标题
// String tradeNo 商家订单编号
// String totalAmount 总订单金额
private void getorder(String t,String n,String m) {
String url = Httpurl.zfbzf; //自己的接口,把三个参数给后台,我要用的是Xuils,okhttp也是一样的。
RequestParams params = new RequestParams(url);
params.addBodyParameter("subject", t);
params.addBodyParameter("tradeNo", n);
params.addBodyParameter("totalAmount", m);
x.http().post(params, new Callback.CommonCallback<String>() {
@Override
public void onSuccess(String result) {
try {
JSONObject obj = new JSONObject(result);
// Log.e("支付宝", obj.toString());
if (obj.getInt("error")==0) {
zhifu(obj.getString("data")); //这是后台返回的data,目的是为了安全,防止重要的信息暴露。后台可以看看demo或者官方api,怎么生成的。
} else {
To.oo(obj.getString("msg")); //失败打印的信息,就是toast
}
} catch (JSONException e) {
e.printStackTrace();
}
}
@Override
public void onError(Throwable ex, boolean isOnCallback) {
}
@Override
public void onCancelled(Callback.CancelledException cex) {
}
@Override
public void onFinished() {
}
});
}
//支付
private void zhifu(final String data) {
Runnable payRunnable = new Runnable() {
@Override
public void run() {
PayTask alipay = new PayTask(ALiPay.this);
Map<String, String> result = alipay.payV2(data, true);
Message msg = new Message();
msg.what = SDK_PAY_FLAG;
msg.obj = result;
mHandler.sendMessage(msg);
}
};
Thread payThread = new Thread(payRunnable);
payThread.start();
}
}
布局文件:这个根据自己的情况而定,一般是写在订单的界面,不需要这个布局,我的是因为与rn交互,不得不写一个界面。读者只要看代码就行,布局忽略。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ImageView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@drawable/msp_demo_title_bg"
android:scaleType="center"
android:src="@drawable/msp_demo_title"
tools:ignore="ContentDescription" />
</LinearLayout>
ok支付完毕。我们再来看看授权登录
其实登录和支付一样。
1,之前的配置样。
2,点击事件
case R.id.ll_zfblogin:
To.oo("支付宝登录中,请稍后...");
CallZfb();
break;
3,调接口
private void CallZfb() {
RequestParams params = new RequestParams(ceshi); //自己的url,向后台请求数据。同上边一样,为了安全
x.http().post(params, new Callback.CommonCallback<String>() {
@Override
public void onSuccess(String result) {
denglu();
// Log.e("返回的登录", result.toString());
try {
JSONObject obj = new JSONObject(result);
if (obj.getInt("error") == 0) {
//解析后台给的数据
denglu(“后台返回的数据”);//去调起授权,下面有解释
} else {
To.oo(obj.getString("msg"));
}
} catch (JSONException e) {
e.printStackTrace();
}
}
@Override
public void onError(Throwable ex, boolean isOnCallback) {
}
@Override
public void onCancelled(CancelledException cex) {
}
@Override
public void onFinished() {
}
});
}
4, 去支付宝授权
需要的参数,为了前端临时测试用,APPID,PID , RSA2_PRIVATE 这些是不可以暴露的,需要后台存储。测试的时候可以先向后台要。
/**
* 支付宝支付业务:入参app_id
*/
public static final String APPID = "";
/**
* 支付宝账户登录授权业务:入参pid值
*/
public static final String PID = "";
/**
* 支付宝账户登录授权业务:入参target_id值
*/
public static final String TARGET_ID = "openservice";
/** 商户私钥,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 = "";
private static final int SDK_PAY_FLAG = 1;
private static final int SDK_AUTH_FLAG = 2;
private void denglu(String data) {
//下面的代码是为了前端测试专用,实际中,都不用。下面的authInfo就是data是后台返回来的,为了安全,只能是后台生成。
//下面的代码就是生成authInfo的方法。
if (TextUtils.isEmpty(PID) || TextUtils.isEmpty(APPID)
|| (TextUtils.isEmpty(RSA2_PRIVATE) && TextUtils.isEmpty(RSA_PRIVATE))
|| TextUtils.isEmpty(TARGET_ID)) {
new AlertDialog.Builder(this).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);
//一般来说,有的后台会返回2个参数,pid和appid和datas(后台可以看看api,必须后台返回),有的后台会直接把authInfo返回来。如果直接返回来最好,如果不能直接返回,那就把返回的参数(pid,appid)+TARGET_ID, rsa2,用下面的方法转化。至于TARGET_ID, rsa2,是常量(上面有),可以直接写死,String info = OrderInfoUtil2_0.buildOrderParam(authInfoMap);用这个方法。然后自己拼接一下,再去支付宝请求。
final String authInfo = info + "&" + datas;
Runnable authRunnable = new Runnable() {
@Override
public void run() {
// 构造AuthTask 对象
AuthTask authTask = new AuthTask(Login.this);
// 调用授权接口,获取授权结果
// Map<String, String> result = authTask.authV2(datas, true);
Map<String, String> result = authTask.authV2(authInfo, true);
Message msg = new Message();
msg.what = SDK_AUTH_FLAG;
msg.obj = result;
mHandler1.sendMessage(msg);
}
};
// 必须异步调用
Thread authThread = new Thread(authRunnable);
authThread.start();
}
@SuppressLint("HandlerLeak")
private Handler mHandler1 = 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();
// 判断resultStatus 为“9000”且result_code
// 为“200”则代表授权成功,具体状态码代表含义可参考授权接口文档
if (TextUtils.equals(resultStatus, "9000") && TextUtils.equals(authResult.getResultCode(), "200")) {
//返回的code 把这个传给后台,获取个人信息。
Log.e("789", "handleMessage: " + String.format("authCode:%s", authResult.getAuthCode()));
callzfb(authResult.getAuthCode());//把code给后台,一个简单的联网请求,这里就不写了。
} else {
// 其他状态值则为授权失败
// Toast.makeText(Login.this,
// "授权失败" + String.format("authCode:%s", authResult.getAuthCode()), Toast.LENGTH_SHORT).show();
}
break;
}
default:
break;
}
}
};
到这里支付和登录授权完毕,不足之处,多海涵。
PS:我按照官网集成支付宝的登录,但是问题来了,第一次登录,app闪退了,直接推到桌面(不是崩溃),大约5秒又回到支付宝登录界面。提示授权,完毕后一切正常,第二次就不会闪退。那位大神帮忙解释下。不胜感激!!!
下面是阿里的文档。
https://docs.open.alipay.com/api_2/alipay.user.info.share
最后
以上就是危机吐司为你收集整理的支付宝登录和支付的全部内容,希望文章能够帮你解决支付宝登录和支付所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复