React Native (IOS和Android) 支付寶和微信支付整合實戰(支付寶Android篇)
序言:React Native無論是在社群和應用程度上,在國內外是十分廣泛和普及的。而支付寶和微信在支付模組上都有或多或少的支援,雖然沒有完整的Demo,不過在我做過一個相關整合的專案後,在此我把相關的步驟和方法總結出來和大家分享,希望能夠幫助大家少走彎路,快速整合。
支付寶——Android整合
一、下載客戶端SDK並且進行配置
用Android Studio 開啟你專案裡的/android,以Project形式展開專案,並且在/app目錄下新建資料夾libs(如果沒有該資料夾),
將下載的SDK jar包拖入或複製至libs資料夾內,如下圖:
接著在 /android/app/build.gradle 內新增依賴, 如下圖,注意jar包的名字要統一:
然後修改AndroidManifest.xml檔案,新增以下內容:
-
<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>
-
<uses-permission android:name="android.permission.INTERNET" />
-
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
-
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
-
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
-
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
最後再在proguard-rules.pro檔案內末尾處新增以下內容:
-
-keep class com.alipay.android.app.IAlixPay{*;}
-
-keep class com.alipay.android.app.IAlixPay$Stub{*;}
-
-keep class com.alipay.android.app.IRemoteServiceCallback{*;}
-
-keep class com.alipay.android.app.IRemoteServiceCallback$Stub{*;}
-
-keep class com.alipay.sdk.app.PayTask{ public *;}
-
-keep class com.alipay.sdk.app.AuthTask{ public *;}
-
-keep class com.alipay.sdk.app.H5PayCallback {
-
<fields>;
-
<methods>;
-
}
-
-keep class com.alipay.android.phone.mrpc.core.** { *; }
-
-keep class com.alipay.apmobilesecuritysdk.** { *; }
-
-keep class com.alipay.mobile.framework.service.annotation.** { *; }
-
-keep class com.alipay.mobilesecuritysdk.face.** { *; }
-
-keep class com.alipay.tscenter.biz.rpc.** { *; }
-
-keep class org.json.alipay.** { *; }
-
-keep class com.alipay.tscenter.** { *; }
-
-keep class com.ta.utdid2.** { *;}
-
-keep class com.ut.device.** { *;}
至此Android配置已經完成,如果你在AndroidManifest.xml下,用Android Studio發現 alipay的 <actvity> 標籤是紅色未知引用狀態,重啟Android Studio即可,若還是紅色,右鍵 alipaySdk jar包,選擇Add as library 並且點選OK 即可。
二、編寫React Native原生程式碼
首先我們用Android Studio 以Android檔案目錄格式開啟,並且在java/com.app_demo目錄下建立alipay package, 並且在其目錄下新建PayAction.java和PayResult.java檔案, 如下圖:
接著呼叫react native 原生內容,編寫方法,PayAction程式碼如下:
-
package com.app_demo.alipay;
-
import android.app.Activity;
-
import android.text.TextUtils;
-
import com.alipay.sdk.app.EnvUtils;
-
import com.alipay.sdk.app.PayTask;
-
import com.app_demo.MainActivity;
-
import com.facebook.react.bridge.ReactContextBaseJavaModule;
-
import com.facebook.react.bridge.Promise;
-
import com.facebook.react.bridge.ReactApplicationContext;
-
import com.facebook.react.bridge.ReactMethod;
-
import java.util.Map;
-
public class PayAction extends ReactContextBaseJavaModule {
-
public PayAction(ReactApplicationContext reactContext) {
-
super(reactContext);
-
}
-
@Override
-
public String getName() {
-
return "PayAction";
-
}
-
@ReactMethod
-
public void pay(final String orderInfo, final Promise promise) {
-
//支付寶沙箱android測試需要呼叫
-
//EnvUtils.setEnv(EnvUtils.EnvEnum.SANDBOX);
-
Runnable payRunnable = new Runnable() {
-
@Override
-
public void run() {
-
Activity activty = MainActivity.getActivity();
-
PayTask alipay = new PayTask(activty);
-
Map<String, String> result = alipay.payV2(orderInfo, true);
-
PayResult payResult = new PayResult((Map<String, String>) result);
-
String resultInfo = payResult.getResult();
-
String resultStatus = payResult.getResultStatus();
-
String memo = payResult.getMemo();
-
try {
-
if (TextUtils.equals(resultStatus, "9000")) {
-
promise.resolve(resultInfo);
-
} else {
-
promise.reject("error", memo);
-
}
-
} catch (Exception e) {
-
promise.reject("error", e.getMessage());
-
}
-
}
-
};
-
Thread payThread = new Thread(payRunnable);
-
payThread.start();
-
}
-
}
PayResult 程式碼如下:
-
package com.app_demo.alipay;
-
import java.util.Map;
-
import android.text.TextUtils;
-
public class PayResult {
-
private String resultStatus;
-
private String result;
-
private String memo;
-
public PayResult(Map<String, String> rawResult) {
-
if (rawResult == null) {
-
return;
-
}
-
for (String key : rawResult.keySet()) {
-
if (TextUtils.equals(key, "resultStatus")) {
-
resultStatus = rawResult.get(key);
-
} else if (TextUtils.equals(key, "result")) {
-
result = rawResult.get(key);
-
} else if (TextUtils.equals(key, "memo")) {
-
memo = rawResult.get(key);
-
}
-
}
-
}
-
@Override
-
public String toString() {
-
return "resultStatus={" + resultStatus + "};memo={" + memo
-
+ "};result={" + result + "}";
-
}
-
/**
-
* @return the resultStatus
-
*/
-
public String getResultStatus() {
-
return resultStatus;
-
}
-
/**
-
* @return the memo
-
*/
-
public String getMemo() {
-
return memo;
-
}
-
/**
-
* @return the result
-
*/
-
public String getResult() {
-
return result;
-
}
-
}
緊接著將該方法暴露出來給React Native 前端使用,即在com.app_demo下建立AlipayReactPackage.java檔案,程式碼如下
-
package com.app_demo;
-
import com.app_demo.alipay.PayAction;
-
import com.facebook.react.ReactPackage;
-
import com.facebook.react.bridge.NativeModule;
-
import com.facebook.react.bridge.ReactApplicationContext;
-
import com.facebook.react.uimanager.ViewManager;
-
import java.util.ArrayList;
-
import java.util.Collections;
-
import java.util.List;
-
public class AlipayReactPackage implements ReactPackage {
-
@Override
-
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
-
return Collections.emptyList();
-
}
-
@Override
-
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
-
List<NativeModule> modules = new ArrayList<>();
-
modules.add(new PayAction(reactContext));
-
return modules;
-
}
-
}
然後修改MainActivity裡的方法,使MainActivity可以在PayAction中可以獲取,修改後程式碼如下:
-
package com.app_demo;
-
import android.app.Activity;
-
import android.os.Bundle;
-
import com.facebook.react.ReactActivity;
-
import com.facebook.soloader.SoLoader;
-
public class MainActivity extends ReactActivity {
-
private static Activity mCurrentMainActivity = null;
-
/**
-
* Returns the name of the main component registered from JavaScript.
-
* This is used to schedule rendering of the component.
-
*/
-
@Override
-
protected String getMainComponentName() {
-
return "App_Demo";
-
}
-
@Override
-
protected void onCreate(Bundle savedInstanceState) {
-
super.onCreate(savedInstanceState);
-
mCurrentMainActivity = this;
-
}
-
public static Activity getActivity() {
-
Activity activity = mCurrentMainActivity;
-
return activity;
-
}
-
}
接著在MainApplication 裡新增剛剛寫好的AlipayReactPackage包,程式碼如下:
-
@Override
-
protected List<ReactPackage> getPackages() {
-
return Arrays.<ReactPackage>asList(
-
new AlipayReactPackage(),
-
new MainReactPackage()
-
);
-
}
最後編寫React Native Js內容,呼叫該pay方法:
-
_alipay = () => {
-
var payAction = NativeModules.PayAction
-
//呼叫支付寶服務端整合的方法,獲取訂單資訊
-
axios.post('http://192.168.1.45:3000/alipay/pay').then(({ data }) => {
-
return payAction.pay(data)
-
}).then((res) => {
-
alert(res)
-
//此處處理支付成功的方法
-
console.log(res)
-
}).catch((err) => {
-
alert(err)
-
console.log(err)
-
})
-
}
-
render(){
-
return <View><Button title='Alipay 支付' onPress={this._alipay} /></View>
-
}
至此支付寶Android端的整合就全部完成了,總體來說,比較簡單,程式碼也很清晰,建議在開發過程中,多以真實App的環境進行開發,因為沙箱偶爾會出現網路或者其他未知的問題,而如果在真實環境中,也會出現各種問題,那就絕對是你程式碼的問題,例如簽名錯誤。