項目裏須要作支付, 在github看到的插件多多少少都遇到了坑, 實在是爬不出來。參考了支付寶官方文檔 還有別的一些大佬的文章,作個記錄java
allprojects { repositories { // 添加下面的內容 flatDir { dirs 'libs' } // ... jcenter() 等其餘倉庫 } }
//官方用的是compile,二者均可以 用implementation更好 implementation (name: 'alipaySdk-15.6.5-20190718211159-noUtdid', ext: 'aar')
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.CAMERA"/>
以上sdk的配置基本完成 下面就須要和原生作橋接(下面代碼基本是copy另外一位大佬的,膜拜)react
6.建立AlipayModule.java,代碼以下:
(注意: 第一行的包名必定要寫對)android
package com.xxxx.alipay; import com.alipay.sdk.app.PayTask; import com.facebook.react.bridge.Arguments; import com.facebook.react.bridge.Promise; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactContextBaseJavaModule; import com.facebook.react.bridge.ReactMethod; import com.facebook.react.bridge.WritableMap; import java.util.Map; public class AlipayModule extends ReactContextBaseJavaModule { public AlipayModule(ReactApplicationContext reactContext) { super(reactContext); } @Override public String getName() { return "Alipay"; } @ReactMethod public void pay(final String orderInfo, final Promise promise) { Runnable payRunnable = new Runnable() { @Override public void run() { WritableMap map = Arguments.createMap(); PayTask alipay = new PayTask(getCurrentActivity()); Map<String, String> result = alipay.payV2(orderInfo,true); for (Map.Entry<String, String> entry: result.entrySet()) map.putString(entry.getKey(), entry.getValue()); promise.resolve(map); } }; // 必須異步調用 Thread payThread = new Thread(payRunnable); payThread.start(); } }
7.建立AlipayPackage.java,代碼以下:(仍是要注意包名)ios
package com.xxxx.alipay; 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 AlipayPackage 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 AlipayModule(reactContext)); return modules; } }
8.在com.xxxx下的MainApplication中註冊模塊:
(注意:這裏和原文有點區別 0.6版本的添加包與舊版本有些區別)git
@Override protected List<ReactPackage> getPackages() { @SuppressWarnings("UnnecessaryLocalVariable") List<ReactPackage> packages = new PackageList(this).getPackages(); // Packages that cannot be autolinked yet can be added manually here, for example: packages.add(new AlipayPackage()); return packages; }
1.經過 CocoaPods 添加 在項目路徑/ios/podfile 裏添加以下代碼 pod 'AlipaySDK-iOS' 添加完成後執行 pod install
由於我是用的新版本因此沒有手動導入,須要的老哥參考下文末連接或者支付寶開發文檔
在Xcode中打開項目,設置項目屬性中的URL Schemes爲你支付寶開放平臺對此App設置的惟一標識。如圖標紅位置所示:
#import <Foundation/Foundation.h> #import <React/RCTBridgeModule.h> #import <UIKit/UIKit.h> #import <AlipaySDK/AlipaySDK.h> @interface RCTAlipay : NSObject<RCTBridgeModule> +(void) handleCallback:(NSURL *)url; @end
#import "RCTAlipay.h" static RCTPromiseResolveBlock _resolve; static RCTPromiseRejectBlock _reject; @implementation RCTAlipay RCT_EXPORT_MODULE(); RCT_REMAP_METHOD(pay, payInfo:(NSString *)payInfo resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { NSArray *urls = [[NSBundle mainBundle] infoDictionary][@"CFBundleURLTypes"]; NSMutableString *appScheme = [NSMutableString string]; BOOL multiUrls = [urls count] > 1; for (NSDictionary *url in urls) { NSArray *schemes = url[@"CFBundleURLSchemes"]; if (!multiUrls || (multiUrls && [@"alipay" isEqualToString:url[@"CFBundleURLName"]])) { [appScheme appendString:schemes[0]]; break; } } if ([appScheme isEqualToString:@""]) { NSString *error = @"scheme cannot be empty"; reject(@"10000", error, [NSError errorWithDomain:error code:10000 userInfo:NULL]); return; } _resolve = resolve; _reject = reject; [[AlipaySDK defaultService] payOrder:payInfo fromScheme:appScheme callback:^(NSDictionary *resultDic) { [RCTAlipay handleResult:resultDic]; }]; } +(void) handleResult:(NSDictionary *)resultDic { NSString *status = resultDic[@"resultStatus"]; if ([status integerValue] >= 8000) { _resolve(@[resultDic]); } else { _reject(status, resultDic[@"memo"], [NSError errorWithDomain:resultDic[@"memo"] code:[status integerValue] userInfo:NULL]); } } +(void) handleCallback:(NSURL *)url { //若是極簡開發包不可用,會跳轉支付寶錢包進行支付,須要將支付寶錢包的支付結果回傳給開發包 if ([url.host isEqualToString:@"safepay"]) { [[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) { //【因爲在跳轉支付寶客戶端支付的過程當中,商戶app在後臺極可能被系統kill了,因此pay接口的callback就會失效,請商戶對standbyCallback返回的回調結果進行處理,就是在這個方法裏面處理跟callback同樣的邏輯】 [self handleResult:resultDic]; }]; } if ([url.host isEqualToString:@"platformapi"]){//支付寶錢包快登受權返回authCode [[AlipaySDK defaultService] processAuthResult:url standbyCallback:^(NSDictionary *resultDic) { //【因爲在跳轉支付寶客戶端支付的過程當中,商戶app在後臺極可能被系統kill了,因此pay接口的callback就會失效,請商戶對standbyCallback返回的回調結果進行處理,就是在這個方法裏面處理跟callback同樣的邏輯】 [self handleResult:resultDic]; }]; } } @end
注意:這裏是經過配置文件來獲取scheme,若是獲取到appScheme的值爲空的話,就寫死在代碼裏,簡單粗暴
github
【重要】此時iOS的調起支付寶網頁支付(即未安裝支付寶App)在RN中能夠實現支付完成返回App進行相關操做,可是調起支付寶App支付完成後會發現相關支付完成的操做失效,因此要在`Appdelegate.m`中導入`RCTAlipay.h`進行相關回調:
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary*)options { //若是極簡開發包不可用,會跳轉支付寶錢包進行支付,須要將支付寶錢包的支付結果回傳給開發包 if ([url.host isEqualToString:@"safepay"]) { [RCTAlipay handleCallback:url]; return YES; } //此處是微信支付 XXXXXX:微信urlsheme if ([url.scheme isEqualToString:@"XXXXXX"]) { return [WXApi handleOpenURL:url delegate:(id<WXApiDelegate>)self]; } return YES; }
注意:微信支付完成也是要使用改方法, 得在裏面判斷一下
react-native
Alipay.js
工具類import { NativeModules } from 'react-native'; export default NativeModules.Alipay;
import Alipay from './Alipay' async aliPayAction(payStr){ //payStr爲從後臺獲取的支付字符串 Alipay.pay(payStr).then((data) =>{ let resultDic = {}; /*筆者iOS端和安卓端返回的支付回調結果數據不一致,可能和支付寶sdk版本有關, 讀者可自行根據返回數據進行相關處理,iOS(RCTAlipay.m)和安卓(AlipayModule) 可自行選擇須要resolve回調判斷處理的數據,如只返回resultStatus*/ if (Platform.OS === 'ios'){ resultDic = data[0]; } else { resultDic = data; } if (resultDic.resultStatus == '9000'){ //支付成功 }else { //支付失敗 } }).catch((err) => { console.log('err='+err); this.refs.toast.show('支付失敗'); }); }
到這裏支付寶就集成完了,剛開始一頭霧水,看了下rn的官方文檔,支付寶的官方文檔,還有其餘大佬的文章。終於拼湊完成了。作個記錄
Happy Hackingapi
參考1:支付寶集成官方文檔
參考2:react-native集成支付寶支付)promise