iOS调用一网通App支付

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"];
    }
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,478评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,825评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,482评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,726评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,633评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,018评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,513评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,168评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,320评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,264评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,288评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,995评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,587评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,667评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,909评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,284评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,862评论 2 339

推荐阅读更多精彩内容