前言
项目里需要做支付, 在github看到的插件多多少少都遇到了坑, 实在是爬不出来。参考了支付宝官方文档 还有别的一些大佬的文章,做个记录
这里只写了支付宝的,微信集成文章很多,都不需要做改动,所以就没有写
安卓集成
1.在app目录下新建libs目录,将sdk 包放在应用工程的 libs 目录下
2.在主项目的 build.gradle 中,添加下面的内容,将 libs 目录作为依赖仓库:
allprojects {
repositories {
// 添加下面的内容
flatDir {
dirs 'libs'
}
// ... jcenter() 等其他仓库
}
}
3.App Module 的 build.gradle中(项目的app 目录下),添加下面的内容,将支付宝 SDK 作为项目依赖:
//官方用的是compile,两者都可以 用implementation更好
implementation (name: 'alipaySdk-15.6.5-20190718211159-noUtdid', ext: 'aar')
4.支付宝 SDK 需要使用下面这些权限,在AndroidManifest.xml下添加:
<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另一位大佬的,膜拜)
5.android/app/src/main/java/com.xx下创建alipay,如下图
6.创建AlipayModule.java,代码如下:
(注意: 第一行的包名一定要写对)
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,代码如下:(还是要注意包名)
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版本的添加包与旧版本有些区别)
@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;
}
ios集成
1.sdk安装
(1).rn 0.6以上的版本
1.通过 CocoaPods 添加
在项目路径/ios/podfile 里添加如下代码
pod 'AlipaySDK-iOS'
添加完成后执行 pod install
(2)手动导入
因为我是用的新版本所以没有手动导入,需要的老哥参考下文末链接或者支付宝开发文档
2.设置URL Schemes
在Xcode中打开项目,设置项目属性中的URL Schemes为你支付宝开放平台对此App设置的唯一标识。如图标红位置所示:
3.在项目目录下创建Group Alipay,并创建RCTAlipay模块,如下图所示:
4.编写RCTAlipay.h代码如下:
#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
5.编写RCTAlipay.m代码如下:
#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的值为空的话,就写死在代码里,简单粗暴
6 网页支付返回APP
【重要】此时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调用
1.编写Alipay.js
工具类
import { NativeModules } from 'react-native';
export default NativeModules.Alipay;
2.在支付页面调用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 Hacking
参考1:支付宝集成官方文档
参考2:react-native集成支付宝支付)
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。