Android

  1. 引入sdk
    android/app/build.gradle
dependencies {
  ...
  api 'com.alipay.sdk:alipaysdk-android:+@aar'
  ...
}
  1. 添加权限
    android/app/src/main/AndroidMainifest.xml
<!-- 支付宝 activity 声明 -->
<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" />
  1. 添加代码混淆规则
# 支付宝
-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.** { *;}
  1. 写android原生
    在android/app/src/main/java/com/xxx 文件里创建文件夹alipay
    创建AlipayModule.java
package com.xxx.alipay;

import com.alipay.sdk.app.PayTask;
import com.alipay.sdk.app.EnvUtils;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableMap;

import java.util.Map;

public class AlipayModule extends ReactContextBaseJavaModule {

    private final ReactApplicationContext reactContext;

    public AlipayModule(ReactApplicationContext reactContext) {
        super(reactContext);
        this.reactContext = reactContext;
    }
    @Override
    public String getName() {
        return "Alipay";
    }

    @ReactMethod
    public void setAlipayScheme(String scheme){
        // android不用设置scheme
    }

    @ReactMethod
    public void setAlipaySandbox(Boolean isSandbox) {
        if (isSandbox) {
            EnvUtils.setEnv(EnvUtils.EnvEnum.SANDBOX);
        } else {
            EnvUtils.setEnv(EnvUtils.EnvEnum.ONLINE);
        }
    }

    @ReactMethod
    public void pay(final String orderInfo, final Callback promise) {
        Runnable payRunnable = new Runnable() {
            @Override
            public void run() {
                PayTask alipay = new PayTask(getCurrentActivity());
                Map<String, String> result = alipay.payV2(orderInfo, true);
                WritableMap map = Arguments.createMap();
                map.putString("memo", result.get("memo"));
                map.putString("result", result.get("result"));
                map.putString("resultStatus", result.get("resultStatus"));
                promise.invoke(map);
            }
        };
        Thread payThread = new Thread(payRunnable);
        payThread.start();
    }
}

创建AlipayPackage.java

package com.xxx.alipay;

import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.JavaScriptModule;
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<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
        List<NativeModule> modules = new ArrayList<>();
        modules.add(new AlipayModule(reactContext));
        return modules;
    }

    public List<Class<? extends JavaScriptModule>> createJSModules() {
        return Collections.emptyList();
    }

    @Override
    public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
        return Collections.emptyList();
    }
}
  1. 添加模块
    android/app/src/main/java/com/xxx/MainApplication.java
...
import com.xxx.alipay.AlipayPackage;
...
public class MainApplication extends Application implements ReactApplication {
   ...
        protected List<ReactPackage> getPackages() {
          @SuppressWarnings("UnnecessaryLocalVariable")
          List<ReactPackage> packages = new PackageList(this).getPackages();
          ...
          packages.add(new AlipayPackage());
          return packages;
        }
      ...

IOS

  1. 打开Xcode,引入sdk
    ios/Podfile
...
pod 'AlipaySDK-iOS'
...

image.png

  1. 添加URL Schemes
    ios/xxx/Info.plist
    <key>CFBundleURLTypes</key>
    <array>
        <dict>
            <key>CFBundleTypeRole</key>
            <string>Editor</string>
            <key>CFBundleURLName</key>
            <string>alipay</string>
            <key>CFBundleURLSchemes</key>
            <array>
                <string>随便一个不重复的唯一标识</string>
            </array>
        </dict>
    </array>

image.png

  1. 写ios原生
    在ios/创建Alipay文件夹,在Xcode里创建RCTAlipay.mRCTAlipay.h文件

WeChat9701ce3fe36ba65063599babcc7af80b.png
WechatIMG679.png
WechatIMG682.png
WechatIMG681.png
image.png

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

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
  1. 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

import { NativeModules, Platform } from 'react-native';
const Alipay = NativeModules.Alipay;

const errorMessage = {
    '6001': '支付取消',
    '6002': '网络连接出错',
    '4000': '支付失败',
    '5000': '重复请求'
}

function alipay (key){
   return new Promise((resolve, reject) => {
       Alipay.pay(key).then((data) => {
           const {resultStatus} = Platform.OS === 'ios' ? data[0] : data;
           if (resultStatus == '9000'){
               //支付成功
               resolve();
           } else {
               //支付失败
               reject(errorMessage[resultStatus] || errorMessage['4000'])
           }
       }).catch(() => {
           reject(errorMessage['4000'])
       })
   })
}

perkz
51 声望28 粉丝

« 上一篇
Redux
下一篇 »
React Native微信