iOS 集成银联支付

今天闲着没事做,集成了一下银联支付,原来的项目中都是支付宝、微信支付。其实步骤很简单,只要配置正确了,还是挺好做的。

首先是sdk下载地址:https://open.unionpay.com/ajweb/help/file/toDetailPage?id=346&flag=2

以下是测试用卡号、手机号等信息(此类信息仅供测试使用,不会发生真实交易

   招商银行借记卡:6226090000000048
    手机号:18100000000
    密码:111101
    短信验证码:123456(先点获取验证码之后再输入
    证件类型:01身份证
    证件号:510265790128303
    姓名:张三

   华夏银行贷记卡:6226388000000095
    手机号:18100000000
    CVN2:248
    有效期:1219
    短信验证码:123456(先点获取验证码之后再输入
    证件类型:01身份证
    证件号:510265790128303
    姓名:张三

一,工程配置

1、      使用UPPaymentControl需要添加CFNetwork.framework、SystemConfiguration.framework、libz、libPaymentControl.a到工程中,添加后如下图:

iOS 集成银联支付_第1张图片

2、在工程info.plist设置中添加一个URL Types回调协议(在UPPayDemo工程中使用“UPPayDemo”作为协议),用于在支付完成后返回商户客户端。

iOS 集成银联支付_第2张图片

3、http请求设置

在Xcode7.0之后的版本中进行http请求时,需要在工程对应的plist文件中添加NSAppTransportSecurity  Dictionary并同时设置里面NSAllowsArbitraryLoads 属性值为 YES,具体设置可参照以下截图:

 

4、添加协议白名单

在Xcode7.0之后的版本中进行开发,需要在工程对应的plist文件中,添加LSApplicationQueriesSchemes  Array并加入uppaysdk、uppaywallet、uppayx1、uppayx2、uppayx3五个item,具体设置可参考以下截图:

iOS 集成银联支付_第3张图片

或者直接添加如下代码到plist文件中:

<key>LSApplicationQueriesSchemes</key>

     <array>

        <string>uppaysdk</string>

        <string>uppaywallet</string>

        <string>uppayx1</string>

        <string>uppayx2</string>

        <string>uppayx3</string>

     </array>


5. 将涉及到引用 UPPayPlugin.h 的源文件的后缀名都改为.mm;

6.工程的 Build Settings 中找到 Other Linker Flags 中添加-ObjC 宏;

二,注意

银联支付目测只需要2个参数 1 tn 其实就是订单号 2 mode 是测试环境还是线上环境

和支付宝不同的是 支付宝要求本地把订单的信息书写完毕 调起sdk支付即可 银联是我把一些生成订单的信息 如 付款方 收款方 订单描述 金额等信息传递到服务器 由服务器生成一个订单号 然后客户端调起sdk进入支付

mode 是个字符串  "00" 表示线上环境"01"表示测试环境

返回的代理结果 :success、fail、cancel,分别代表:支付成功、支付失败、用户取消支付

三,集成到工程中

1,工程Appdelegate.m

#import "AppDelegate.h"

#import "UPPaymentControl.h"

#import <CommonCrypto/CommonDigest.h>

#import "RSA.h"

@interface AppDelegate ()


@end


@implementation AppDelegate


- (BOOL) application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {

    [[UPPaymentControldefaultControl]handlePaymentResult:urlcompleteBlock:^(NSString *code,NSDictionary *data)

     {

         //结果code为成功时,先校验签名,校验成功后做后续处理

         if ([codeisEqualToString:@"success"]) {

             //数据从NSDictionary转换为NSString

             NSDictionary *data;

             NSData *signData = [NSJSONSerializationdataWithJSONObject:data

                                                                options:0

                                                                  error:nil];

             NSString *sign = [[NSStringalloc]initWithData:signDataencoding:NSUTF8StringEncoding];

             

             //判断签名数据是否存在

             if(data ==nil){

                 //如果没有签名数据,建议商户app后台查询交易结果

                 return;

             }

             

             //验签证书同后台验签证书

             //此处的verify,商户需送去商户后台做验签

             if([selfverify:sign]) {

                 //支付成功且验签成功,展示支付成功提示

             }

             else {

                //验签失败,交易结果数据被篡改,商户app后台查询交易结果

             }

         }

         elseif([codeisEqualToString:@"fail"]) {

             //交易失败

         }

         elseif([codeisEqualToString:@"cancel"]) {

             //交易取消

         }

     }];

    

    returnYES;

}

- (NSString *) readPublicKey:(NSString *) keyName

{

    if (keyName ==nil || [keyNameisEqualToString:@""])returnnil;

    

    NSMutableArray *filenameChunks = [[keyNamecomponentsSeparatedByString:@"."]mutableCopy];

    NSString *extension = filenameChunks[[filenameChunkscount] -1];

    [filenameChunks removeLastObject];// remove the extension

    NSString *filename = [filenameChunkscomponentsJoinedByString:@"."];// reconstruct the filename with no extension

    

    NSString *keyPath = [[NSBundlemainBundle]pathForResource:filenameofType:extension];

    

    NSString *keyStr = [NSStringstringWithContentsOfFile:keyPathencoding:NSUTF8StringEncodingerror:nil];

    

    return keyStr;

}


-(BOOL) verify:(NSString *) resultStr {

    

    //验签证书同后台验签证书

    //此处的verify,商户需送去商户后台做验签

    returnNO;

}

- (NSString*)sha1:(NSString *)string

{

    unsignedchar digest[CC_SHA1_DIGEST_LENGTH];

    CC_SHA1_CTX context;

    NSString *description;

    

    CC_SHA1_Init(&context);

    

    memset(digest,0,sizeof(digest));

    

    description = @"";

    

    

    if (string ==nil)

    {

        returnnil;

    }

    

    // Convert the given 'NSString *' to 'const char *'.

    constchar *str = [stringcStringUsingEncoding:NSUTF8StringEncoding];

    

    // Check if the conversion has succeeded.

    if (str ==NULL)

    {

        returnnil;

    }

    

    // Get the length of the C-string.

    int len = (int)strlen(str);

    

    if (len ==0)

    {

        returnnil;

    }

    

    

    if (str ==NULL)

    {

        returnnil;

    }

    

    CC_SHA1_Update(&context, str, len);

    

    CC_SHA1_Final(digest, &context);

    

    description = [NSStringstringWithFormat:

                   @"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",

                   digest[ 0], digest[1], digest[2], digest[3],

                   digest[ 4], digest[5], digest[6], digest[7],

                   digest[ 8], digest[9], digest[10], digest[11],

                   digest[12], digest[13], digest[14], digest[15],

                   digest[16], digest[17], digest[18], digest[19]];

    

    return description;

}

2. 支付页面 ViewController.mm

#import "ViewController.h"

#import "UPPaymentControl.h"

#define kVCTitle          @"商户测试"

#define kBtnFirstTitle    @"获取订单,开始测试"

#define kWaiting          @"正在获取TN,请稍后..."

#define kNote             @"提示"

#define kConfirm          @"确定"

#define kErrorNet         @"网络错误"

#define kResult           @"支付结果:%@"


//线上环

#define kMode_Development             @"01"

//在后台开发实现消费(获取tn)请求前,demo里默认由银联的一个商户仿真获取tn(http://202.101.25.178:8080/sim/gettn或http://101.231.204.84:8091/sim/getacptn)之后需要改从商户自己的后台那里获取tn的。

#define kURL_TN_Normal                @"http://101.231.204.84:8091/sim/getacptn"


@interface ViewController ()

{

    UITextField *_curField;

    UIAlertView* _alertView;

    NSMutableData* _responseData;

    CGFloat _maxWidth;

    CGFloat _maxHeight;

}

/** 测试环境 */

@property (copy,nonatomic)NSString *tnMode;

/** 订单 */

@property (copy,nonatomic)NSString *tn;

@end


@implementation ViewController


- (void)viewDidLoad {

    [superviewDidLoad];

    // Do any additional setup after loading the view, typically from a nib.

}


- (void)didReceiveMemoryWarning {

    [superdidReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}

/** 银联支付 */

- (IBAction)unionPayBtnClick:(UIButton *)sender

{

//    //支付环境: "00"表示线上环境"01"表示测试环境

//    NSString *tnMode = @"01";

//    //订单号

//    NSString *tn = @"20161234514531";

//    //当判断用户手机是否已经安装了银联APP

//    if ([[UPPaymentControl defaultControl]isPaymentAppInstalled]) {

//        //商户App从商户服务器获取tn,当tn不为空时,调用支付接口

//        if (tn !=nil && tn.length > 0) {

//            [[UPPaymentControl defaultControl]startPay:tn fromScheme:@"UPPayDemo" mode:tnMode viewController:self];

//        }

//    }


    self.tnMode =kMode_Development;

    [selfstartNetWithURL:[NSURLURLWithString:kURL_TN_Normal]];

    

}

- (void)startNetWithURL:(NSURL *)url

{

    [_curFieldresignFirstResponder];

    _curField =nil;

    [selfshowAlertWait];

    

    NSURLRequest * urlRequest=[NSURLRequestrequestWithURL:url];

    NSURLConnection* urlConn = [[NSURLConnectionalloc]initWithRequest:urlRequestdelegate:self];

    [urlConn start];

}

#pragma mark - Alert

- (void)showAlertWait

{

    [selfhideAlert];

    _alertView = [[UIAlertViewalloc]initWithTitle:kWaitingmessage:nildelegate:selfcancelButtonTitle:nilotherButtonTitles:nil];

    [_alertViewshow];

    UIActivityIndicatorView* aiv = [[UIActivityIndicatorViewalloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];

    aiv.center =CGPointMake(_alertView.frame.size.width / 2.0f - 15,_alertView.frame.size.height / 2.0f + 10 );

    [aiv startAnimating];

    [_alertViewaddSubview:aiv];

    

}


- (void)showAlertMessage:(NSString*)msg

{

    [selfhideAlert];

    _alertView = [[UIAlertViewalloc]initWithTitle:kNotemessage:msgdelegate:selfcancelButtonTitle:kConfirmotherButtonTitles:nil,nil];

    

}

- (void)hideAlert

{

    if (_alertView !=nil)

    {

        [_alertViewdismissWithClickedButtonIndex:0animated:NO];

        _alertView =nil;

    }

}


- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex

{

    _alertView =nil;

}

#pragma mark UPPayPluginResult支付完成的返回结果

- (void)UPPayPluginResult:(NSString *)result

{

    NSString* msg = [NSStringstringWithFormat:kResult, result];

    [selfshowAlertMessage:msg];

}

#pragma mark - 网络请求代理方法connection

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse*)response

{

    NSHTTPURLResponse* rsp = (NSHTTPURLResponse*)response;

    NSInteger code = [rspstatusCode];

    if (code !=200)

    {

        

        [selfshowAlertMessage:kErrorNet];

        [connection cancel];

    }

    else

    {

        

        _responseData = [[NSMutableDataalloc]init];

    }

}


- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data

{

    [_responseDataappendData:data];

}


- (void)connectionDidFinishLoading:(NSURLConnection *)connection

{

    [selfhideAlert];

    NSString* tn = [[NSMutableStringalloc]initWithData:_responseDataencoding:NSUTF8StringEncoding];

   

    if (tn !=nil && tn.length >0)

    {

        

        NSLog(@"tn=%@",tn);

        [[UPPaymentControldefaultControl]startPay:tnfromScheme:@"UPPayDemo"mode:self.tnModeviewController:self];

        

    }

    

    

}


-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error

{

    [selfshowAlertMessage:kErrorNet];

}



四、效果图

iOS 集成银联支付_第4张图片




你可能感兴趣的:(ios,银联支付)