Android--支付寶沙箱集成(詳細圖解)

效果圖

在這裏插入圖片描述

關於官方的Demo

這裏我們先跑一個官方給的demo試試

進入開發者平臺

沙箱應用
創建一個沙箱應用
在這裏插入圖片描述
在這裏插入圖片描述
關鍵信息:APPID、UID、商家賬號



下載他的沙箱版支付寶

如果是在模擬器運行的代碼記得把這個沙箱版安裝在模擬器裏面
在這裏插入圖片描述
下載完成之後,可以登錄(賬號在上面截圖的位置,每個人創建的應用不同賬號也不同)進去看看,也給以試着往裏面加錢,最大可以加999999999…吧…好像,要是真的就好了。。。

下載官方給的SDK

下載地址
在這裏插入圖片描述
下載解壓後有幾個文件(和以前的老版不一樣,這個坑…老版教程不適用)
在這裏插入圖片描述
Android_Demo這個文件夾打開後的文件直接導入在Android studio裏面打開



導入官方給的Demo

文件結構如下圖
在這裏插入圖片描述
然後複製Android_SDK這個文件夾下的aar文件
在這裏插入圖片描述


導入SDK

指導文檔
在這裏插入圖片描述
給出了新版SDK也就是後綴爲aar文件和之前老版jar文件的導入區別,跟着文檔來,記錄一下:下面這個語句要改一下,因爲文檔的name和自己下的sdk版本名稱可能不一致導致報錯,最後同步一下項目(我的和你的版本可能也不一樣,自己對着自己的版本改)

// 添加下面的內容
    implementation (name: 'alipaysdk-15.8.00.201112210139', ext: 'aar')

修改APPID、PID、TARGET_ID

在PayDemoActivity這個類下修改相關參數
在這裏插入圖片描述

RSA2_PRIVATE問題也就是這個沙箱的公鑰和私鑰

在這裏插入圖片描述
在這裏插入圖片描述
這個要從這個軟件裏面獲取
下載密鑰工具
在這裏插入圖片描述
下載後打開工具
在這裏插入圖片描述
將生成的應用公鑰複製到之前的沙箱應用管理裏面
在這裏插入圖片描述
再複製之前工具生成的私鑰放進代碼裏面
看文檔好像是說的2048字節長度
在這裏插入圖片描述










最後加入這條語句EnvUtils.setEnv(EnvUtils.EnvEnum.SANDBOX);在onCreate()方法裏面

在這裏插入圖片描述
應該可以運行成功的
然後下面就是改一下部署到自己項目裏面

效果圖的代碼

SDK導入方式和前面說的一樣,再然後就是將官方給的demo裏面的這幾個文件複製進自己項目
在這裏插入圖片描述

activity佈局文件

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.newapplication.MainActivity">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/constraintLayout"
        android:layout_width="match_parent"
        android:layout_height="140dp"
        android:layout_marginStart="10dp"
        android:layout_marginLeft="10dp"
        android:layout_marginTop="20dp"
        android:layout_marginEnd="10dp"
        android:layout_marginRight="10dp"
        android:background="@drawable/activity_search_tv_shape"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"><!--這個background可以刪-->

        <ImageView
            android:id="@+id/imageView"
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:layout_marginStart="15dp"
            android:layout_marginLeft="15dp"
            android:src="@drawable/ma"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <TextView
            android:id="@+id/textView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="二維碼"
            android:textColor="#555555"
            android:textSize="20sp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toEndOf="@+id/imageView"
            app:layout_constraintTop_toTopOf="@+id/imageView" />

        <TextView
            android:id="@+id/textView2"
            android:layout_width="260dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="5dp"

            android:layout_marginLeft="5dp"
            android:ellipsize="end"
            android:lines="2"
            android:text="二維碼又稱二維條碼,常見的二維碼爲QR Code,QR全稱Quick Response,是一個近幾年來移動設備上超流行的一種編碼方式,它比傳統的Bar Code條形碼能存更多的信息,也能表示更多的數據類型"
            android:textColor="#666666"
            android:textSize="18sp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toEndOf="@+id/imageView"
            app:layout_constraintTop_toBottomOf="@+id/textView" />

        <TextView
            android:id="@+id/textView3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="價格:"
            android:textColor="#333333"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toStartOf="@+id/price"
            app:layout_constraintTop_toBottomOf="@+id/textView2"
            app:layout_constraintVertical_bias="0.65999997" />

        <TextView
            android:id="@+id/price"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginEnd="20dp"
            android:layout_marginRight="20dp"
            android:text="¥1599.00"
            android:textColor="#D81E06"
            app:layout_constraintBottom_toBottomOf="@+id/textView3"
            app:layout_constraintEnd_toEndOf="@+id/textView2"
            app:layout_constraintTop_toTopOf="@+id/textView3"
            app:layout_constraintVertical_bias="0.0" />
    </androidx.constraintlayout.widget.ConstraintLayout>

    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_marginTop="10dp"
        android:text="支付"
        android:textSize="25sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/constraintLayout" />


</androidx.constraintlayout.widget.ConstraintLayout>


在這裏插入圖片描述

MainActivity文件

package com.example.newapplication;

import androidx.appcompat.app.AppCompatActivity;

import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.alipay.sdk.app.EnvUtils;
import com.alipay.sdk.app.PayTask;

import java.util.Map;

public class MainActivity extends AppCompatActivity {
   
   
    /**
     * 用於支付寶支付業務的入參 app_id。
     */
    public static final String APPID = "202100011******4";//參數都填自己的

    /**
     * 用於支付寶賬戶登錄授權業務的入參 pid。
     */
    public static final String PID = "208862195******4";

    /**
     * 用於支付寶賬戶登錄授權業務的入參 target_id。
     */
    public static final String TARGET_ID = "lvuk******.com";

    /**
     *  pkcs8 格式的商戶私鑰。
     *
     * 	如下私鑰,RSA2_PRIVATE 或者 RSA_PRIVATE 只需要填入一個,如果兩個都設置了,本 Demo 將優先
     * 	使用 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_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")) {
   
   
                        // 該筆訂單是否真實支付成功,需要依賴服務端的異步通知。
                        showAlert(MainActivity.this, getString(R.string.pay_success) + payResult);
                    } else {
   
   
                        // 該筆訂單真實的支付結果,需要依賴服務端的異步通知。
                        showAlert(MainActivity.this, getString(R.string.pay_failed) + payResult);
                    }
                    break;
                }
                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")) {
   
   
                        // 獲取alipay_open_id,調支付時作爲參數extern_token 的value
                        // 傳入,則支付賬戶爲該授權賬戶
                        showAlert(MainActivity.this, getString(R.string.auth_success) + authResult);
                    } else {
   
   
                        // 其他狀態值則爲授權失敗
                        showAlert(MainActivity.this, getString(R.string.auth_failed) + authResult);
                    }
                    break;
                }
                default:
                    break;
            }
        };
    };



    @Override
    protected void onCreate(Bundle savedInstanceState) {
   
   
        EnvUtils.setEnv(EnvUtils.EnvEnum.SANDBOX);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button button = findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
   
   
            @Override
            public void onClick(View v) {
   
   
                payV2(v);
            }
        });
    }


    /**
     * 支付寶支付業務示例
     */
    public void payV2(View v) {
   
   
        if (TextUtils.isEmpty(APPID) || (TextUtils.isEmpty(RSA2_PRIVATE) && TextUtils.isEmpty(RSA_PRIVATE))) {
   
   
            showAlert(this, getString(R.string.error_missing_appid_rsa_private));
            return;
        }

        /*
         * 這裏只是爲了方便直接向商戶展示支付寶的整個支付流程;所以Demo中加簽過程直接放在客戶端完成;
         * 真實App裏,privateKey等數據嚴禁放在客戶端,加簽過程務必要放在服務端完成;
         * 防止商戶私密數據泄露,造成不必要的資金損失,及面臨各種安全風險;
         *
         * orderInfo 的獲取必須來自服務端;
         */
        boolean rsa2 = (RSA2_PRIVATE.length() > 0);

        Map<String, String> params = OrderInfoUtil2_0.buildOrderParamMap(APPID, rsa2,"1599.00");
        String orderParam = OrderInfoUtil2_0.buildOrderParam(params);

        String privateKey = rsa2 ? RSA2_PRIVATE : RSA_PRIVATE;
        String sign = OrderInfoUtil2_0.getSign(params, privateKey, rsa2);
        final String orderInfo = orderParam + "&" + sign;

        final Runnable payRunnable = new Runnable() {
   
   

            @Override
            public void run() {
   
   
                PayTask alipay = new PayTask(MainActivity.this);
                Map<String, String> 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();
    }
    private static void showAlert(Context ctx, String info) {
   
   
        showAlert(ctx, info, null);
    }

    private static void showAlert(Context ctx, String info, DialogInterface.OnDismissListener onDismiss) {
   
   
        new AlertDialog.Builder(ctx)
                .setMessage(info)
                .setPositiveButton(R.string.confirm, null)
                .show();
    }

    private static void showToast(Context ctx, String msg) {
   
   
        Toast.makeText(ctx, msg, Toast.LENGTH_LONG).show();
    }

    private static String bundleToString(Bundle bundle) {
   
   
        if (bundle == null) {
   
   
            return "null";
        }
        final StringBuilder sb = new StringBuilder();
        for (String key: bundle.keySet()) {
   
   
            sb.append(key).append("=>").append(bundle.get(key)).append("\n");
        }
        return sb.toString();
    }
}

有兩處改動

string.xml文件改一下(從官方Demo複製)
在
改一下剛剛從demo複製的OrderInfoUtil2_0類下的方法,根據需要自己改(訂單的構造方法)
在這裏插入圖片描述
就這樣集成完畢!!!



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章