支付宝登录和支付

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

猜你喜欢

转载自blog.csdn.net/qq_30299243/article/details/81087174