美文网首页
iOS调用一网通App支付

iOS调用一网通App支付

作者: Shadowoff | 来源:发表于2018-06-15 10:10 被阅读0次

1、我接手这个项目的时候,项目已经集成了一网通的网页版支付,只不过前一段时间的需求里面并没有一网通支付,最近领导要求开通一网通支付的,我就把一网通支付的网页版打开了,也没怎么细看,反正调试好用,这两天领导让App跳转到一网通的支付,就像跳转微信,支付宝一样,看文档迷迷糊糊,网上找资料也是没有跳转App这块相关的,不过最后还是解决了,怕过段时间忘了,还是早点写出来博客,供大家参考,好了,言归正传,直接正题

1、以下是 一网通 jsonRequestData报文组织:的请求示例,有些参数是必选的,有些参数是可选的

{
    "version":"1.0",
    "sign":"见签名处理章节",
    "signType":"SHA-256",
    "reqData":{
        "dateTime":"20161216140241",
        "date":"20161216",
        "orderNo":"9999153784",
        "amount":"0.01",
        "expireTimeSpan":"30",
        "payNoticeUrl":"http://www.merchant.com/path/payNotice.do",
        "payNoticePara":"aaa",
        "branchNo":"0755",
        "merchantNo":"000054",
        "returnUrl":" yunjiazheng://callback",
        "clientIP":"99.12.43.61",
        "cardType":"",
        "encrypData":"FC779C8E6953AC0C97BE115D61FE1669AECBE5836DF120A84157D9515DFD375E00B0538C85B930E6A33BB9E0213150E07953DEB1D4E30EF4356FF0B2700357881B3A8670B37C25C76DF2378DF9",
        "encrypType":"RC4",
        "subMerchantNo":"",
        "subMerchantName":"",
        "subMerchantTPCode":"",
        "subMerchantTPName":""
    }
}

2、上面的请求报文主要是调用后台接口,然后后台人员返给前台人员,签名也是后台来做,后台做 sign 签名的时候 这个地方就需要注意了,后台拿上面报文里面的数据进行签名的时候用了多少个字段,前台传给一网通的时候就需要多少个字段,多了,或者少了都会报订单无效,签名错误

3、首先在自己的app里面配置一下白名单,否则不会跳转到一网通,如下,在plist里面添加

<key>LSApplicationQueriesSchemes</key>
    <array>
        <string>wechat</string>
        <string>weixin</string>
        <string>cmbmobilebank</string> // 一网通
    </array>

4、此时可以用iOS自带的方法进行一下验证,验证是否跳转

        if ([[UIApplication sharedApplication] canOpenURL:[NSURL  URLWithString:@"cmbmobilebank://"]]){ 
        
                 // 安装了app
        }else{
                 // 没有安装了app
                 // 调用一网通网页版支付(这个后期会更新)
        }

5、通过4的验证,我们能够打开一网通的app,接下来就需要按照一网通的开发文档拿着请求报文跳转到支付界面

5(1)后台返回的数据结构,按照一网通报文的结构



oneWangTong.h 

@property (nonatomic, strong) oneWangTongSub *reqData;
@property (nonatomic, copy) NSString *sign;
@property (nonatomic, copy) NSString *signType;
@property (nonatomic, copy) NSString *version;

oneWangTongSub.h

@property (nonatomic, copy) NSString *dateTime;
@property (nonatomic, copy) NSString *date;
@property (nonatomic, copy) NSString *orderNo;
@property (nonatomic, copy) NSString *amount;
@property (nonatomic, copy) NSString *expireTimeSpan;
@property (nonatomic, copy) NSString *payNoticeUrl;
@property (nonatomic, copy) NSString *payNoticePara;
@property (nonatomic, copy) NSString *branchNo;
@property (nonatomic, copy) NSString *merchantNo;
@property (nonatomic, copy) NSString *returnUrl;
@property (nonatomic, copy) NSString *clientIP;
@property (nonatomic, copy) NSString *cardType;


5(2)组装字典,生成JSON字符串,因为后台sign加密用到了 下面dict最后6个,所以前台拼装的时候也需要这6个,当时和后台约定好了,读者可以做的灵活些,就是所有的参数都是后台传,自己只需要组装字典,生成JSON字符串就可以了,我们对写的有点不灵活,因为需要考虑到安卓,后台,我就没有多嘴,哈哈哈哈

// 直接用接口返回的 5(1)中的oneWangTong调用下面的方法生成JSON 字符串

- (NSString *)oneWangTongchangeFromModel:(oneWangTong *)model
{
    oneWangTongSub *subModel = model.reqData;
    NSMutableDictionary *dict = [NSMutableDictionary dictionary];
    
   
    [dict setValue:subModel.dateTime forKey:@"dateTime"];
    [dict setValue:subModel.date forKey:@"date"];
    [dict setValue:subModel.orderNo forKey:@"orderNo"];
    [dict setValue:subModel.amount forKey:@"amount"];
    [dict setValue:subModel.expireTimeSpan forKey:@"expireTimeSpan"];
    [dict setValue:subModel.payNoticeUrl forKey:@"payNoticeUrl"];
    [dict setValue:subModel.payNoticePara forKey:@"payNoticePara"];
    [dict setValue:subModel.branchNo forKey:@"branchNo"];
    [dict setValue:subModel.merchantNo forKey:@"merchantNo"];
    [dict setValue:@"cmbpt365://callback" forKey:@"returnUrl"];
    [dict setValue:subModel.clientIP forKey:@"clientIP"];
    [dict setValue:subModel.cardType forKey:@"cardType"];
    [dict setValue:@"" forKey:@"encrypData"];
    [dict setValue:@"" forKey:@"encrypType"];
    [dict setValue:@"" forKey:@"subMerchantNo"];
    [dict setValue:@"" forKey:@"subMerchantName"];
    [dict setValue:@"" forKey:@"subMerchantTPCode"];
    [dict setValue:@"" forKey:@"subMerchantTPName"];
    
    //2.组装大字典
    NSMutableDictionary *resultDict = [NSMutableDictionary dictionary];
    [resultDict setValue:@"1.0" forKey:@"version"];
    [resultDict setValue:[model.sign1 uppercaseString] forKey:@"sign"];
    [resultDict setValue:@"SHA-256" forKey:@"signType"];
    [resultDict setValue:dict forKey:@"reqData"];
 
    NSError *error;
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:resultDict options:NSJSONWritingPrettyPrinted error:&error];
    
    NSString *jsonString;
    
    if (!jsonData) {
        NSLog(@"%@",error);
    }else{
        jsonString = [[NSString alloc]initWithData:jsonData encoding:NSUTF8StringEncoding];
    }
    NSMutableString *mutStr = [NSMutableString stringWithString:jsonString];
    NSRange range = {0,jsonString.length};
    // 去掉字符串中的空格
    [mutStr replaceOccurrencesOfString:@" " withString:@"" options:NSLiteralSearch range:range];
    NSRange range2 = {0,mutStr.length};
    // 去掉字符串中的换行符
    [mutStr replaceOccurrencesOfString:@"\n" withString:@"" options:NSLiteralSearch range:range2];
    NSRange range3 = {0,mutStr.length};
    // 去掉字符串中的“\\”
    [mutStr replaceOccurrencesOfString:@"\\" withString:@"" options:NSLiteralSearch range:range3];
    
    return mutStr;
    
}

5(3)当时我就直接拿着上面的JSON加上按照文档拼接的去调用,发现根本就不跳转,找了半天原因,原来文档上面写了一句话 就是 5(2)中的JSON字符串需要做urlEncode的处理,都怪没好好读文档啊


 // 当时没有调用成功的写法
 NSString *json = [NSString stringWithFormat:@"cmbmobilebank://CMBLS/FunctionJump?action=gofuncid&funcid=200007&serverid=CMBEUserPay&requesttype=post&cmb_app_trans_parms_start=here&charset=utf-8&jsonRequestData=%@",5(2)中的字符串];

5(4)对 5(2)进行urlEncode的处理

// 对JSON字符串进行urlEncode 处理
- (NSString *)URLEncodedString
{
    // CharactersToBeEscaped = @":/?&=;+!@#$()~',*";
    // CharactersToLeaveUnescaped = @"[].";
    
    NSString *unencodedString = self;
    NSString *encodedString = (NSString *)
    CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
                                                              (CFStringRef)unencodedString,
                                                              NULL,
                                                              (CFStringRef)@"!*'();:@&=+$,/?%#[]",
                                                              kCFStringEncodingUTF8));
    
    return encodedString;
}

5(5)拼接最终的请求报文

  // 拼接请求报文
                NSString *json = [NSString stringWithFormat:@"cmbmobilebank://CMBLS/FunctionJump?action=gofuncid&funcid=200007&serverid=CMBEUserPay&requesttype=post&cmb_app_trans_parms_start=here&charset=utf-8&jsonRequestData=%@",5(4)进行urlEncode处理的字符串];

5(6)用请求报文直接调用 一网通app (如下,就可以正常调用一网通直接跳转到支付界面)

    CGFloat systemVersion = [[[UIDevice currentDevice] systemVersion] floatValue];
     if (systemVersion < 10.0f) {
        BOOL success = [[UIApplication sharedApplication] openURL:url];
        if (success) {
            //跳转成功
           
            } else {
            //跳转失败
                
            }
        } else {
            [[UIApplication sharedApplication] openURL:url
                                                       options:@{}
                                             completionHandler:^(BOOL success) {
                                                 if (success) {
                                                     //跳转成功
                                               
                                                 }else {
                                                     //跳转失败
                    
                                                 }
                                             }];
                }
                
            } else {

               // 调用网页版一网通支付(后续会补充)
            }

5(7)一网通支付成功的返回我们的App

 1、文档上面有写,就是请求报文里面有一个 参数 "returnUrl"
 2、这个是后台返回的,所以需要和后台人员约定一下,返回的这个怎么写,参照文档,3就是文档的写法
 3、yunjiazheng://callback", 
 4、需要在自己的app info---URL Types(最下面),增加一项,在增加项的 URL Schemes 中填写  3中的 yunjiazheng (后后台约定,冒号前面写的什么,URL Schemes就需要写同样的)
 5、这样就可以由一网通的app返回到我们的app了

5(8)一网通支付成功结果回调

1、我当时是在 5(6)中用userDefaults做处理的 (成功标记 1 失败标记0)




    CGFloat systemVersion = [[[UIDevice currentDevice] systemVersion] floatValue];
     if (systemVersion < 10.0f) {
        BOOL success = [[UIApplication sharedApplication] openURL:url];
        if (success) {
            //跳转成功
                [[NSUserDefaults standardUserDefaults] setObject:@"1" forKey:@"yiwangtongPayStatus"];
            } else {
            //跳转失败
                [[NSUserDefaults standardUserDefaults] setObject:@"0" forKey:@"yiwangtongPayStatus"];
            }
        } else {
            [[UIApplication sharedApplication] openURL:url
                                                       options:@{}
                                             completionHandler:^(BOOL success) {
                                                 if (success) {
                                                     //跳转成功
                                                    [[NSUserDefaults standardUserDefaults] setObject:@"1" forKey:@"yiwangtongPayStatus"];
                                                 }else {
                                                     //跳转失败
                                                    [[NSUserDefaults standardUserDefaults] setObject:@"0" forKey:@"yiwangtongPayStatus"];
                                                 }
                                             }];
                }
                
            } else {

               // 调用网页版一网通支付(后续会补充)
            }

2、根据通知判断,通过发送接口来判断支付结果

// 监听进入前台
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationWillEnterForegroundNotification) name:UIApplicationWillEnterForegroundNotification object:nil];
// 进入前台
- (void)applicationWillEnterForegroundNotification {
    
    if ([[[NSUserDefaults standardUserDefaults] objectForKey:@"yiwangtongPayStatus"] isEqualToString:@"1"]) {
        [self getYiWanyTongResult]; // 发送一网通支付成功验证接口
        [[NSUserDefaults standardUserDefaults] setObject:@"0" forKey:@"yiwangtongPayStatus"];
    }
}

相关文章

  • iOS调用一网通App支付

    1、我接手这个项目的时候,项目已经集成了一网通的网页版支付,只不过前一段时间的需求里面并没有一网通支付,最近领导要...

  • iOS swift 4.0 支付宝支付

    iOS应用中调用支付宝支付的方法默认后台已经对orderString进行处理,app中直接能拿到orderStri...

  • 收录 : iOS支付开发

    iOS 银联支付开发流程iOS 微信支付开发流程iOS 支付宝支付开发流程iOS Apple Pay开发流程App...

  • 支付宝APP支付集成文档

    一、开发前提 适用于商家在App应用中集成支付宝支付功能。商家APP调用支付宝提供的SDK调用支付宝客户端内的支付...

  • 支付宝支付-1 概要

    试用场景 适用于商家在App应用中集成支付宝支付功能。 步骤 1、商家APP调用支付宝提供的SDK,SDK再调用支...

  • 集成支付宝支付

    支付宝集成相对来说还是比较简单的,官方文档的调用说明也写得很简单,集成的工程需要结合官方的【App支付iOS集成流...

  • iOS集成微信支付

    使用场景:商户APP调用微信提供的SDK调用微信支付模块,商户APP会跳转到微信中完成支付,支付完后跳回到商户AP...

  • EasyPay开发文档

    场景介绍 适用于商家在App应用中集成便利宝支付功能。 商家APP调用便利宝提供的SDK调用支付宝客户端内的支付模...

  • 支付宝微信H5支付无法返回APP解决方案

    转载iOS支付宝H5支付无法返回APP解决方案iOS微信H5支付无法返回APP解决方案

  • iOS开发-微信支付宝H5支付跳转原生APP的问题

    参考 iOS 解决微信h5支付无法直接返回APP的问题 iOS微信H5支付无法返回APP解决方案 iOS支付宝H5...

网友评论

      本文标题:iOS调用一网通App支付

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