java后台程序员转android 之《三B》 支付宝支付 client join server 及采坑记录
生活随笔
收集整理的這篇文章主要介紹了
java后台程序员转android 之《三B》 支付宝支付 client join server 及采坑记录
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
目錄
前言:
介紹:
demo:
先看下 我的目錄結構?
java 代碼
activit代碼
總結思路:
server? 端 開發思路
前言:
最近公司打算做先關android 方面的技術,然后招andirod 還挺貴,老板打算讓我來搞搞,那就搞一搞,順便做些總結,從java后臺轉型快速入手 android 的小策略支付還是挺總要的一部分畢竟用手機主要一點就是支付所以記錄一下經驗。
?
andoird 官網地址?https://developer.android.google.cn/
?
介紹:
- 首先查看下支付寶沙箱文檔?https://docs.open.alipay.com/200/105311/
- 這個文檔中很詳細的介紹了些內容
- 然后去獲取一下appid 等賬號,還有加密的秘鑰等內容
- 接下來就是看代碼了
- 官方提供的demo是為了方便把代碼都放到了android?
- 這里為了方便我把代碼順便分了下那些放到server那些放到android center
demo:
- https://download.csdn.net/download/weixin_42749765/10992832
- 這里為了方便純開發java后臺的朋友 還帶上來我之前講的 webview 混合開發的代碼
- 混合開發的時候就通過js調用java方法 然后啟動 alipay 的方法 來實現支付
- 這里不做太多介紹
- ?
先看下 我的目錄結構?
- 紅色地方都是重點需要關注的
?
java 代碼
package com.example.app002;import android.Manifest; import android.annotation.SuppressLint; import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; import android.content.pm.PackageManager; import android.os.Build; import android.os.Handler; import android.os.Message; import android.support.v4.app.ActivityCompat; import android.support.v4.content.ContextCompat; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.text.TextUtils; import android.util.Log; import android.view.View; import android.webkit.WebView; import android.widget.TextView; import android.widget.Toast;import com.alipay.sdk.app.AuthTask; import com.alipay.sdk.app.PayTask; import com.example.alipay.base.AuthResult; import com.example.alipay.base.PayResult; import com.example.alipay.uitl.OrderInfoUtil2_0;import org.json.JSONArray; import org.json.JSONObject;import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map;/*** java主啟動類**/ public class MainActivity extends AppCompatActivity implements JsBridge{public void MainActivity(){}//定義日志private static final String TAG = "MainActivity";//定義一個webview 操作界面使用private WebView mwebView;//定義一個textview 操作界面文字使用private TextView mtextView;//定義一個 hadlerprivate Handler mHandler;//自帶的啟動方法@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//初始化添加接口內容initWidgets(savedInstanceState);requestPermission();}/*** 初始化以下** @param savedInstanceState*/private void initWidgets(Bundle savedInstanceState){//鏈接到activitymain.xml中的配置的id(webview)mwebView = findViewById(R.id.webview);//鏈接到activitymain.xml中的配置的id(tv_result)mtextView = findViewById(R.id.tv_result);mHandler = new Handler();//允許webview加載jsmwebView.getSettings().setJavaScriptEnabled(true);//給WebView添加js接口 java中new ImoocJsInterface()對象等于js中 imoocJsInterface調用的時候使用mwebView.addJavascriptInterface(new ImoocJsInterface(this),"imoocJsInterface");//加載頁面 file:///android_asset/index.htmlmwebView.loadUrl("file:///android_asset/index.html");//調試使用if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {mwebView.setWebContentsDebuggingEnabled(true);}}//實現接口中操作文本及傳遞數據使用@Overridepublic void setTextViewValue(final String value) {Log.d(TAG, "value2="+value);//通過mHandler.post(方法操作mtextView文本mHandler.post(new Runnable() {@Overridepublic void run() {mtextView.setText(value);}});String cz = value + "vk";Map ma = new HashMap();String sdkver = "";Log.d("liteavsdk", "liteav sdk version is : " + sdkver);ma.put("ab","sss"+sdkver);//調用js方法CallJS(ma);}/*** java調用js方法** @param str 傳遞的是一個map的數據也可以傳遞別的類型*/public void CallJS(final Map str){// 通過Handler發送消息//通過mHandler.post(方法操作mwebView并且調用js方法mwebView.post(new Runnable() {@Overridepublic void run() {// 注意調用的JS方法名要對應上// 調用javascript的remo()方法mwebView.loadUrl("javascript:if(window.remo){window.remo('"+str+"');}");}});}//-----------------------------------------支付寶相關--------------------------------------------------------public static final String PID = "";//用于支付寶賬戶登錄授入權業務的參 pid。public static final String TARGET_ID = "";//用于支付寶賬戶登錄授權業務的入參 target_id。private static final int SDK_PAY_FLAG = 1;private static final int SDK_AUTH_FLAG = 2;@SuppressLint("HandlerLeak")private Handler alipayHandler = 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;}};};//從這往下和下邊那個方法放到服務器上其他的都放在android 中public static final String APPID = "201********";//用于支付寶支付業務的入參 app_id。public static final String RSA2_PRIVATE = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwg************************==";public static final String RSA_PRIVATE = "";/*** 獲取 加密內容 這個方法放在 服務器上** @return*/public String getorderParamSgin(){if (TextUtils.isEmpty(APPID) || (TextUtils.isEmpty(RSA2_PRIVATE) && TextUtils.isEmpty(RSA_PRIVATE))) {return null;}boolean rsa2 = (RSA2_PRIVATE.length() > 0);Map<String, String> params = OrderInfoUtil2_0.buildOrderParamMap(APPID, rsa2);String orderParam = OrderInfoUtil2_0.buildOrderParam(params);String privateKey = rsa2 ? RSA2_PRIVATE : RSA_PRIVATE;String sign = OrderInfoUtil2_0.getSign(params, privateKey, rsa2);String orderInfo = orderParam + "&" +sign;return orderInfo;}/*** 支付寶支付業務示例*/public void payV22(View v) {final String orderInfo = getorderParamSgin();final Runnable payRunnable = new Runnable() {@Overridepublic 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;alipayHandler.sendMessage(msg);}};// 必須異步調用Thread payThread = new Thread(payRunnable);payThread.start();}/*** 支付寶賬戶授權業務示例*/public void authV2(View v) {if (TextUtils.isEmpty(PID) || TextUtils.isEmpty(APPID)|| (TextUtils.isEmpty(RSA2_PRIVATE) && TextUtils.isEmpty(RSA_PRIVATE))|| TextUtils.isEmpty(TARGET_ID)) {showAlert(this, getString(R.string.error_auth_missing_partner_appid_rsa_private_target_id));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;Runnable authRunnable = new Runnable() {@Overridepublic void run() {// 構造AuthTask 對象AuthTask authTask = new AuthTask(MainActivity.this);// 調用授權接口,獲取授權結果Map<String, String> result = authTask.authV2(authInfo, true);Message msg = new Message();msg.what = SDK_AUTH_FLAG;msg.obj = result;alipayHandler.sendMessage(msg);}};// 必須異步調用Thread authThread = new Thread(authRunnable);authThread.start();}/*** 獲取支付寶 SDK 版本號。*/public void showSdkVersion(View v) {PayTask payTask = new PayTask(this);String version = payTask.getVersion();showAlert(this, getString(R.string.alipay_sdk_version_is) + version);}/*** 獲取權限使用的 RequestCode*/private static final int PERMISSIONS_REQUEST_CODE = 1002;/*** 檢查支付寶 SDK 所需的權限,并在必要的時候動態獲取。* 在 targetSDK = 23 以上,READ_PHONE_STATE 和 WRITE_EXTERNAL_STORAGE 權限需要應用在運行時獲取。* 如果接入支付寶 SDK 的應用 targetSdk 在 23 以下,可以省略這個步驟。*/private void requestPermission() {// Here, thisActivity is the current activityif (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE)!= PackageManager.PERMISSION_GRANTED|| ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED) {ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.READ_PHONE_STATE,Manifest.permission.WRITE_EXTERNAL_STORAGE}, PERMISSIONS_REQUEST_CODE);} else {showToast(this, getString(R.string.permission_already_granted));}}/*** 權限獲取回調*/@Overridepublic void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {switch (requestCode) {case PERMISSIONS_REQUEST_CODE: {// 用戶取消了彈權限窗if (grantResults.length == 0) {showToast(this, getString(R.string.permission_rejected));return;}// 用戶拒絕了某些權限for (int x : grantResults) {if (x == PackageManager.PERMISSION_DENIED) {showToast(this, getString(R.string.permission_rejected));return;}}// 所需的權限均正常獲取showToast(this, getString(R.string.permission_granted));}}}private static void showAlert(Context ctx, String info) {showAlert(ctx, info, null);}private static void showAlert(Context ctx, String info, DialogInterface.OnDismissListener onDismiss) {final AlertDialog show = new AlertDialog.Builder(ctx).setMessage(info).setPositiveButton(R.string.confirm, null)// .setOnDismissListener(onDismiss).show();}private static void showToast(Context ctx, String msg) {Toast.makeText(ctx, msg, Toast.LENGTH_LONG).show();}//-----------------------------------------支付寶相關--------------------------------------------------------}- 代碼中專門做了表中除了 appid 和秘鑰 還有一個方法放到服務端剩下的都放在android 中就ok
- 對于引用aar包看官方文檔就好
- 在demo中還有些alipay目錄下的代碼也放到服務端
- 其中有些 TextUitl 類中的方法 java server中可能沒有 可以自己建一個類 然后放上 比較方法和判斷為空的方法
?
activit代碼
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.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=".MainActivity"><WebViewandroid:id="@+id/webview"android:layout_width="match_parent"android:layout_height="733dp"tools:layout_editor_absoluteX="0dp"tools:layout_editor_absoluteY="0dp" /><TextViewandroid:id="@+id/tv_result"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Hello World!"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toTopOf="parent" /><Buttonandroid:id="@+id/payV2"android:layout_width="match_parent"android:layout_height="wrap_content"android:onClick="payV22"android:text="@string/pay_with_alipay"android:textAllCaps="false"tools:layout_editor_absoluteX="0dp"tools:layout_editor_absoluteY="180dp" /></android.support.constraint.ConstraintLayout>- activity 中重要的就是一個button 的點擊按鈕 別的沒啥用是沒有刪除
- 里邊有個webview 方便開發使用,不需要的key直接刪了就好
總結思路:
- android 集成alipay 的思路就是通過調用 alipay的方法直接就可以啟動alipay 支付寶的內容
?
?
server? 端 開發思路
- 先看張圖
- 這里專門介紹下server策略
- 1.通過客戶端向服務端發起請求獲取 加密的數據和加簽
- 2.服務端獲取到請求后解析出用戶相關信息
- 3.然后通過demo中的 代碼生成 加密數據和加簽數據
- 4.傳回到client 中
ok
?
文章持續更新!
?
?
?
?
總結
以上是生活随笔為你收集整理的java后台程序员转android 之《三B》 支付宝支付 client join server 及采坑记录的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Redies未授权访问
- 下一篇: Unity DOTS 一文开启ECS大门