美文网首页
ReactNative iOS集成银联支付20-05-09

ReactNative iOS集成银联支付20-05-09

作者: 你坤儿姐 | 来源:发表于2020-05-10 20:58 被阅读0次

刨了3天的坑特来分享
公司要求用reactnative开发,本iOS小菜瓜开始学习reactnative,最近做到支付要求用微信、支付宝、银联支付,由于比较懒集成银联的时候就去GitHub上找 reactnative unionpay相关的来操作,结果。。。找到5个都被各种报错,,最后决定自己动手。

1.首先在xcode上集成iOS版的银联支付
2.在ReactNative端调用

废话结束,开始干

一.集成iOS银联支付

1.到银联技术开发平台下载开发包
截屏2020-05-10 17.40.25.png

然后:


截屏2020-05-10 17.43.16.png
下载完毕后打开这个: 截屏2020-05-10 17.48.10.png
然后看这里(没时间你也可以不看,我来带你操作)
截屏2020-05-10 17.49.05.png
OK,打开上图控件开发包,找到下图俩文件
截屏2020-05-10 17.54.10.png
截屏2020-05-10 17.54.19.png
2.把这两个文件添加到Xcode项目中,如图: 截屏2020-05-10 17.58.09.png
3.接着把CFNetwork.frameworkSystemConfiguration.frameworklibz.tbdlibPaymentControl.a添加到工程中
image
4.再然后,去添加URL Schemes
截屏2020-05-10 20.04.11.png
5.接下来,在测试环境测试时,需要在工程对应的plist文件中添加NSAppTransportSecurity Dictionary 并同时设置里面NSAllowsArbitraryLoads 属性值为 YES.发生产环境可删除此设置。向Apple发布正式版本时请删除此设置
image
6.在Xcode7.0之后的版本中进行开发,需要在工程对应的plist文件中,添加LSApplicationQueriesSchemes Array并加入uppaysdkuppaywalletuppayx1uppayx2uppayx3五个item,如图: 截屏2020-05-10 18.13.27.png
7.8.按照步骤集成完毕后,其中中国银联手机支付控件接入指南iOS中说的在需要调用支付控件接口的代码文件内引用头文件UPPaymentControl.h。 (注意:如果工程的compile source as 选项的值不是Objective–C++,则引用此头文件的文件类型都要改为.mm)下面几个图是别人验证的拿来分享下:
image
image image

接下来就是主要使用方法了,由于我们要用reactnative调用iOS的银联支付,建议没有用reactnative掉过原生的小盆友去reactnative文档里看看reactnative与原生交互最好先操作一下它的例子避免后面的坑,

1.在xcode创建银联文件,如图
截屏2020-05-10 18.33.11.png

UPPayControl.h文件:

#import <Foundation/Foundation.h>
#import "React/RCTBridgeModule.h"

@interface UPPayControl : NSObject <RCTBridgeModule>
@end

UPPayControl.m文件:

#import "UPPayControl.h"
#import "UPPaymentControl.h"

static RCTPromiseResolveBlock UPPay_resolve;
static RCTPromiseRejectBlock UPPay_reject;

@implementation UPPayControl
//MARK:必须实现协议,指定模块名,如果不规定模块名,那么将以类名作为模块名(UPPayControl);
RCT_EXPORT_MODULE();

//这个方法将会被reactnative调用
RCT_REMAP_METHOD(pay, payTN:(NSString *)tn isProduction:(BOOL)isProduction resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
{
   NSLog(@"%@",tn); 
}
@end
2.接着去reactnative中你要调用的js文件中调用一下看看,能否调通

UPPayControl.js文件:

import React, { Component } from 'react';
import {
  View,
  Button,
  NativeModules
} from 'react-native';

var UPPayControl = NativeModules.UPPayControl;

export default class AllCommentsPage extends React.Component {
  render() {
    return (
      <View >
        <Button title='支付' 
        onPress={()=>{
          this.iosLoad();
        }}
        />
      </View>
    );
  }
  iosLoad(){ 
    UPPayControl.pay('527786897964432783704',false).then((resp)=>{
      console.log("支付成功:"+resp);
  },(err)=>{
      console.log("支付失败:"+err);
  });
  }
}

如果iOS那边能把527786897964432783704打印出来,那么恭喜你,调通了,接下来继续:

3.到xcode的UPPayControl.mm里添加:
#import "UPPayControl.h"
#import "UPPaymentControl.h"

static RCTPromiseResolveBlock UPPay_resolve;
static RCTPromiseRejectBlock UPPay_reject;

@implementation UPPayControl
//MARK:必须实现协议,指定模块名,如果不规定模块名,那么将以类名作为模块名(UPPayControl);
RCT_EXPORT_MODULE();


RCT_REMAP_METHOD(pay, payTN:(NSString *)tn isProduction:(BOOL)isProduction resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
{
  NSLog(@"%@",tn);
    //取URL Schemes
    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 ||
           //unionpay需要和你的设置的一致,如代码下方的图
            (multiUrls && [@"unionpay" isEqualToString:url[@"CFBundleURLName"]])) {
            [appScheme appendString:schemes[0]];
            break;
        }
    }
    
    if ([appScheme isEqualToString:@""]) {
        NSString *error = @"url scheme cannot be empty";
        reject(@"10000", error, [NSError errorWithDomain:error code:10000 userInfo:NULL]);
        return;
    }
    
    UPPay_resolve = resolve;
    UPPay_reject = reject;
    
    NSString *model = isProduction?@"00":@"01";//00对应正式环境,01对应测试环境
    dispatch_async(dispatch_get_main_queue(), ^{
        [[UPPaymentControl defaultControl] startPay:tn fromScheme:appScheme mode:model viewController:[UIApplication sharedApplication].keyWindow.rootViewController];
    });
}
截屏2020-05-10 20.10.40.png

到这里不出意外就能调起云闪付啦,然后到xcode端完善一下代码

1.UPPayControl.h文件中,添加回调成功后的方法

#import <Foundation/Foundation.h>
#import "React/RCTBridgeModule.h"

@interface UPPayControl : NSObject <RCTBridgeModule>
//调起银联成功后要调用的方法
+ (void)handleCallBack:(NSURL *)url;//前端的孩子们这行代码的加号不能去掉
@end

2.UPPayControl.m文件中,添加回调成功后的方法

#import "UPPayControl.h"
#import "UPPaymentControl.h"

static RCTPromiseResolveBlock UPPay_resolve;
static RCTPromiseRejectBlock UPPay_reject;

@implementation UPPayControl
//MARK:必须实现协议,指定模块名,如果不规定模块名,那么将以类名作为模块名(UPPayControl);
RCT_EXPORT_MODULE();


RCT_REMAP_METHOD(pay, payTN:(NSString *)tn isProduction:(BOOL)isProduction resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
{
  NSLog(@"%@",tn);
    //取URL Schemes
    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 && [@"unionpay" isEqualToString:url[@"CFBundleURLName"]])) {
            [appScheme appendString:schemes[0]];
            break;
        }
    }
    
    if ([appScheme isEqualToString:@""]) {
        NSString *error = @"url scheme cannot be empty";
        reject(@"10000", error, [NSError errorWithDomain:error code:10000 userInfo:NULL]);
        return;
    }
    
    UPPay_resolve = resolve;
    UPPay_reject = reject;
    
    NSString *model = isProduction?@"00":@"01";//00对应正式环境,01对应测试环境
    dispatch_async(dispatch_get_main_queue(), ^{
        [[UPPaymentControl defaultControl] startPay:tn fromScheme:appScheme mode:model viewController:[UIApplication sharedApplication].keyWindow.rootViewController];
    });
}
//调起银联成功后的方法:
//MARK:处理银联支付回调逻辑
+(void)handleCallBack:(NSURL *)url
{
    if ([url.host hasPrefix:@"uppayresult"]) {
        [[UPPaymentControl defaultControl] handlePaymentResult:url completeBlock:^(NSString *code, NSDictionary *data) {
            if ([code isEqual:@"cancel"]) {
                //交易取消
                NSString *error = @"cancel";
                UPPay_reject(@"10003",error, [NSError errorWithDomain:error code:10003 userInfo:data]);
            }else if ([code isEqual:@"success"]){
                //交易成功
                UPPay_resolve(@[data]);
            }else if ([code isEqual:@"fail"]){
                //交易失败
                NSString *error = @"fail";
                UPPay_reject(@"10002",error, [NSError errorWithDomain:error code:10002 userInfo:data]);
            }else{
                //交易出错
                NSString *error = @"error";
                UPPay_reject(@"10001",error, [NSError errorWithDomain:error code:10001 userInfo:data]);
            }
        }];
    }
}
@end

3.到AppDelegate.m文件中添加支付回调以后的方法

//支付回调9以后
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary*)options {
   //hasPrefix方法是判断字符串是否以‘uppayresult’开头
    if ([url.host hasPrefix:@"uppayresult"]) {
       //这里调用我们刚刚写的处理银联支付回调逻辑方法
       [UPPayControl handleCallBack:url];
       return YES;
    }
    return NO;
}

OK,结束,操作时发现问题可以随时提出来,一起探讨,加油💪

相关文章

网友评论

      本文标题:ReactNative iOS集成银联支付20-05-09

      本文链接:https://www.haomeiwen.com/subject/vlmlnhtx.html