1. 程式人生 > >React Native (IOS和Android) 支付寶和微信支付整合實戰(支付寶Android篇)

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檔案,新增以下內容:

  1. <activity

  2. android:name="com.alipay.sdk.app.H5PayActivity"

  3. android:configChanges="orientation|keyboardHidden|navigation|screenSize"

  4. android:exported="false"

  5. android:screenOrientation="behind"

  6. android:windowSoftInputMode="adjustResize|stateHidden" >

  7. </activity>

  8. <activity

  9. android:name="com.alipay.sdk.app.H5AuthActivity"

  10. android:configChanges="orientation|keyboardHidden|navigation"

  11. android:exported="false"

  12. android:screenOrientation="behind"

  13. android:windowSoftInputMode="adjustResize|stateHidden" >

  14. </activity>

  1. <uses-permission android:name="android.permission.INTERNET" />

  2. <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

  3. <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

  4. <uses-permission android:name="android.permission.READ_PHONE_STATE" />

  5. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

最後再在proguard-rules.pro檔案內末尾處新增以下內容:

  1. -keep class com.alipay.android.app.IAlixPay{*;}

  2. -keep class com.alipay.android.app.IAlixPay$Stub{*;}

  3. -keep class com.alipay.android.app.IRemoteServiceCallback{*;}

  4. -keep class com.alipay.android.app.IRemoteServiceCallback$Stub{*;}

  5. -keep class com.alipay.sdk.app.PayTask{ public *;}

  6. -keep class com.alipay.sdk.app.AuthTask{ public *;}

  7. -keep class com.alipay.sdk.app.H5PayCallback {

  8. <fields>;

  9. <methods>;

  10. }

  11. -keep class com.alipay.android.phone.mrpc.core.** { *; }

  12. -keep class com.alipay.apmobilesecuritysdk.** { *; }

  13. -keep class com.alipay.mobile.framework.service.annotation.** { *; }

  14. -keep class com.alipay.mobilesecuritysdk.face.** { *; }

  15. -keep class com.alipay.tscenter.biz.rpc.** { *; }

  16. -keep class org.json.alipay.** { *; }

  17. -keep class com.alipay.tscenter.** { *; }

  18. -keep class com.ta.utdid2.** { *;}

  19. -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程式碼如下:

  1. package com.app_demo.alipay;

  2. import android.app.Activity;

  3. import android.text.TextUtils;

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

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

  6. import com.app_demo.MainActivity;

  7. import com.facebook.react.bridge.ReactContextBaseJavaModule;

  8. import com.facebook.react.bridge.Promise;

  9. import com.facebook.react.bridge.ReactApplicationContext;

  10. import com.facebook.react.bridge.ReactMethod;

  11. import java.util.Map;

  12. public class PayAction extends ReactContextBaseJavaModule {

  13. public PayAction(ReactApplicationContext reactContext) {

  14. super(reactContext);

  15. }

  16. @Override

  17. public String getName() {

  18. return "PayAction";

  19. }

  20. @ReactMethod

  21. public void pay(final String orderInfo, final Promise promise) {

  22. //支付寶沙箱android測試需要呼叫

  23. //EnvUtils.setEnv(EnvUtils.EnvEnum.SANDBOX);

  24. Runnable payRunnable = new Runnable() {

  25. @Override

  26. public void run() {

  27. Activity activty = MainActivity.getActivity();

  28. PayTask alipay = new PayTask(activty);

  29. Map<String, String> result = alipay.payV2(orderInfo, true);

  30. PayResult payResult = new PayResult((Map<String, String>) result);

  31. String resultInfo = payResult.getResult();

  32. String resultStatus = payResult.getResultStatus();

  33. String memo = payResult.getMemo();

  34. try {

  35. if (TextUtils.equals(resultStatus, "9000")) {

  36. promise.resolve(resultInfo);

  37. } else {

  38. promise.reject("error", memo);

  39. }

  40. } catch (Exception e) {

  41. promise.reject("error", e.getMessage());

  42. }

  43. }

  44. };

  45. Thread payThread = new Thread(payRunnable);

  46. payThread.start();

  47. }

  48. }

PayResult 程式碼如下:

  1. package com.app_demo.alipay;

  2. import java.util.Map;

  3. import android.text.TextUtils;

  4. public class PayResult {

  5. private String resultStatus;

  6. private String result;

  7. private String memo;

  8. public PayResult(Map<String, String> rawResult) {

  9. if (rawResult == null) {

  10. return;

  11. }

  12. for (String key : rawResult.keySet()) {

  13. if (TextUtils.equals(key, "resultStatus")) {

  14. resultStatus = rawResult.get(key);

  15. } else if (TextUtils.equals(key, "result")) {

  16. result = rawResult.get(key);

  17. } else if (TextUtils.equals(key, "memo")) {

  18. memo = rawResult.get(key);

  19. }

  20. }

  21. }

  22. @Override

  23. public String toString() {

  24. return "resultStatus={" + resultStatus + "};memo={" + memo

  25. + "};result={" + result + "}";

  26. }

  27. /**

  28. * @return the resultStatus

  29. */

  30. public String getResultStatus() {

  31. return resultStatus;

  32. }

  33. /**

  34. * @return the memo

  35. */

  36. public String getMemo() {

  37. return memo;

  38. }

  39. /**

  40. * @return the result

  41. */

  42. public String getResult() {

  43. return result;

  44. }

  45. }

緊接著將該方法暴露出來給React Native 前端使用,即在com.app_demo下建立AlipayReactPackage.java檔案,程式碼如下

  1. package com.app_demo;

  2. import com.app_demo.alipay.PayAction;

  3. import com.facebook.react.ReactPackage;

  4. import com.facebook.react.bridge.NativeModule;

  5. import com.facebook.react.bridge.ReactApplicationContext;

  6. import com.facebook.react.uimanager.ViewManager;

  7. import java.util.ArrayList;

  8. import java.util.Collections;

  9. import java.util.List;

  10. public class AlipayReactPackage implements ReactPackage {

  11. @Override

  12. public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {

  13. return Collections.emptyList();

  14. }

  15. @Override

  16. public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {

  17. List<NativeModule> modules = new ArrayList<>();

  18. modules.add(new PayAction(reactContext));

  19. return modules;

  20. }

  21. }

然後修改MainActivity裡的方法,使MainActivity可以在PayAction中可以獲取,修改後程式碼如下:

  1. package com.app_demo;

  2. import android.app.Activity;

  3. import android.os.Bundle;

  4. import com.facebook.react.ReactActivity;

  5. import com.facebook.soloader.SoLoader;

  6. public class MainActivity extends ReactActivity {

  7. private static Activity mCurrentMainActivity = null;

  8. /**

  9. * Returns the name of the main component registered from JavaScript.

  10. * This is used to schedule rendering of the component.

  11. */

  12. @Override

  13. protected String getMainComponentName() {

  14. return "App_Demo";

  15. }

  16. @Override

  17. protected void onCreate(Bundle savedInstanceState) {

  18. super.onCreate(savedInstanceState);

  19. mCurrentMainActivity = this;

  20. }

  21. public static Activity getActivity() {

  22. Activity activity = mCurrentMainActivity;

  23. return activity;

  24. }

  25. }

接著在MainApplication 裡新增剛剛寫好的AlipayReactPackage包,程式碼如下:

  1. @Override

  2. protected List<ReactPackage> getPackages() {

  3. return Arrays.<ReactPackage>asList(

  4. new AlipayReactPackage(),

  5. new MainReactPackage()

  6. );

  7. }

最後編寫React Native Js內容,呼叫該pay方法:

  1. _alipay = () => {

  2. var payAction = NativeModules.PayAction

  3. //呼叫支付寶服務端整合的方法,獲取訂單資訊

  4. axios.post('http://192.168.1.45:3000/alipay/pay').then(({ data }) => {

  5. return payAction.pay(data)

  6. }).then((res) => {

  7. alert(res)

  8. //此處處理支付成功的方法

  9. console.log(res)

  10. }).catch((err) => {

  11. alert(err)

  12. console.log(err)

  13. })

  14. }

  15. render(){

  16. return <View><Button title='Alipay 支付' onPress={this._alipay} /></View>

  17. }

至此支付寶Android端的整合就全部完成了,總體來說,比較簡單,程式碼也很清晰,建議在開發過程中,多以真實App的環境進行開發,因為沙箱偶爾會出現網路或者其他未知的問題,而如果在真實環境中,也會出現各種問題,那就絕對是你程式碼的問題,例如簽名錯誤。