2019独角兽企业重金招聘Python工程师标准>>>
一:SDK下载
v3.3.3银联SDK下载地址 :https://open.unionpay.com/ajweb/help/file/toDetailPage?id=346&flag=1
二:流程图
三:测试账号
招商银行借记卡:6226090000000048 |
华夏银行贷记卡:6226388000000095 |
四:集成过程
4.1 文件拖入到项目中
4.2工程配置
使用UPPaymentControl需要添加CFNetwork.framework、SystemConfiguration.framework 、libz、libPaymentControl.a到工程中,添加后如下图:
4.3http请求设置
在Xcode7.0之后的版本中进行http请求时,需要在工程对应的plist文件中添加NSAppTransportSecurity Dictionary 并同时设置里面NSAllowsArbitraryLoads 属性值为 YES,具体设置可参照以下截图:
或者
在Xcode7.0之后的版本中进行开发,需要在工程对应的plist文件中,添加LSApplicationQueriesSchemes Array并加入uppaysdk、uppaywallet、uppayx1、uppayx2、uppayx3五个item,具体设置可参考以下截图:
或者直接添加如下代码到plist文件中:
LSApplicationQueriesSchemes
uppaysdk
uppaywallet
uppayx1
uppayx2
uppayx3
4.5调用插件
在需要调用支付控件接口的代码文件内引用头文件UPPaymentControl.h。
(注意:如果工程的compile source as 选项的值不是Objective–C++,则引用此头文件的文件类型都要改为.mm)
1、支付接口调用
商户App从商户服务器获取tn,当tn不为空时,调用支付接口。
//当获得的tn不为空时,调用支付接口
if (tn != nil && tn.length > 0)
{
[[UPPaymentControl defaultControl]
startPay:tn
fromScheme:@"UPPayDemo"
mode:self.tnMode
viewController:self];
}
2、检测是否已安装银联App接口调用
if([[UPPaymentControl defaultControl] isPaymentAppInstalled])
{
//当判断用户手机上已安装银联App,商户客户端可以做相应个性化处理
}
3、返回结果接口调用
支付控件结果处理函数handlePaymentResult: completeBlock:需要在工程AppDelegate文件的application: openURL: sourceApplication: annotation: 方法中进行调用。
支付控件结果处理函数handlePaymentResult: completeBlock:包含两个参数,参数1url为支付结果串,由handlePaymentResult: completeBlock:方法解析url内容;参数2completionBlock为商户APP定义的结果处理方法,包含两个传入参数code和data,其中code表示支付结果,取值为suceess,fail,cancel分别表示支付成功、支付失败和支付取消,data表示结果签名数据,商户使用银联公钥验证结果真实性。
对于新增的签名信息需注意以下几点:
1. 前台返回的支付结果中包含银联签名,要在商户后台对签名进行校验后才能展示结果。
2. 前台签名使用的密钥和算法与后台结果中的签名一致。
3. 如果商户APP在客户端内进行签名验证,要自行实现签名密钥更新的机制,否则更换密钥后会导致验签失败。(不推荐)
4. 商户订单是否成功支付应该以商户后台收到全渠道返回的支付结果为准,此处支付控件返回的结果仅作为参考。
调用支付接口后,结果处理方法示例代码:
- (BOOL) application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
[[UPPaymentControl defaultControl] handlePaymentResult:url completeBlock:^(NSString *code, NSDictionary *data) {
//结果code为成功时,先校验签名,校验成功后做后续处理
if([code isEqualToString:@"success"]) {
//数据从NSDictionary转换为NSString
NSDictionary *data;
NSData *signData = [NSJSONSerialization dataWithJSONObject:data
options:0
error:nil];
NSString *sign = [[NSString alloc] initWithData:signData encoding:NSUTF8StringEncoding];
//判断签名数据是否存在
if(data == nil){
//如果没有签名数据,建议商户app后台查询交易结果
return;
}
//验签证书同后台验签证书
//此处的verify,商户需送去商户后台做验签
if([self verify:sign]) {
//支付成功且验签成功,展示支付成功提示
}
else {
//验签失败,交易结果数据被篡改,商户app后台查询交易结果
}
}
else if([code isEqualToString:@"fail"]) {
//交易失败
}
else if([code isEqualToString:@"cancel"]) {
//交易取消
}
}];
return YES;
}
completeBlock中的NSDictionary *data结构如下:
sign —— 签名后做Base64的数据 data —— 用于签名的原始数据,结构如下: pay_result —— 支付结果success,fail,cancel tn —— 订单号 |
Data转换为String后的示例如下:
"{"sign":"ZnZY4nqFGu/ugcXNIhniJh6UDVriWANlHtIDRzV9w120E6tUgpL9Z7jIFzWrSV73hmrkk8BZMXMc/9b8u3Ex1ugnZn0OZtWfMZk2I979dxp2MmOB+1N+Zxf8iHr7KNhf9xb+VZdEydn3Wc/xX/B4jncg0AwDJO/0pezhSZqdhSivTEoxq7KQTq2KaHJmNotPzBatWI5Ta7Ka2l/fKUv8zr6DGu3/5UaPqHhnUq1IwgxEWOYxGWQgtyTMo/tDIRx0OlXOm4iOEcnA9DWGT5hXTT3nONkRFuOSyqS5Rzc26gQE6boD+wkdUZTy55ns8cDCdaPajMrnuEByZCs70yvSgA==","data":"pay_result=success&tn=201512151321481233778"}"
问题总结
1 常见问题总结
更多请参见https://open.unionpay.com帮助中心-FAQ
1.1 怎样加-ObjC宏
选择工程targets——》build settings ->Linking->other linker flags
1.2 编译时提示Undefined for architecture XXX 错误
如:
1)由于支付控件使用到了C、C++和OC混编的情况,所以商户工程引入UPPaymentControl.h头文件以后可能会出现链接错误,这个时候可以通过以下三种方式解决:
① 将涉及到引用UPPaymentControl.h的源文件的后缀名都改为.mm;
② 如果商户不想修改源文件的后缀名,可以在工程中添加一个空的继承自NSObject的类,并将文件.m后缀名该改为.mm即可方法为new file->Objective-C class->类名自取->保存->修改后缀名为.mm;
③ 将工程的compile source as 选项的值设置为Objective–C++;
2)由于在UPPayDemo工程中添加了自定义的库文件libPaymentControl.a
,当编译Demo工程时,应该检查工程设置Search Paths里的Framework Search Paths、Header Search Paths、Library Search Paths的路径设置,看设置路径是否正确,另外还要注意里边是否多余一些不确定的路径。
3) 将xcode工程中Build Setting -> Apple LLVM compiler Language 标签下的C++ Language Dialect 和 C++ Standard Library 属性值修改为 Compiler Default如实在无法解决,尝试添加-ObjC宏的地方修改为 -force_load+空格+控件路径,如:-force_load $(PROJECT_DIR)/ libPaymentControl.a,如果还报错,上下文应该会有libPaymentControl.a文件找不到异常,比如ld: file not found: /Users/apple/Desktop/Communication 2/ libPaymentControl.a
clang: error: linker command failed with exit code 1 (use -v to see invocation)
请确定libPaymentControl.a文件确实存在于此路径,可能为上下文路径配错。
1.3 控件闪退异常'NSInvalidArgumentException', reason: '-[__NSCFConstantString newSizeWithFont:详略]'
'NSInvalidArgumentException', reason: '-[__NSCFConstantString newSizeWithFont:以下略]: unrecognized selector sent to instance 0x[随机数]'
如图:
出现以上问题是由于添加-ObjC宏的地方没有配置正确,如果配-ObjC实在解决不了的话,可尝试去掉-ObjC,改为-force_load+空格+控件路径,如:-force_load $(PROJECT_DIR)/ libPaymentControl.a。
1.4 orientation异常
详细现象为控件崩溃,报错信息:Terminating app due to uncaught exception ‘UIApplicationInvalidInterfaceOrientation’, reason: ‘Supported orientations has no common orientation with the application, and shouldAutorotate is returning YES’
请勿修改横竖屏配置,iphone控件只能竖屏,ipad控件才支持横竖屏。
如果app本身为横屏,请代码控制横竖屏,勿修改配置。
1.5 其他第三方静态库(如支付宝、微信等)的文件产生冲突duplicate symbols for architecture XXX
如:
请尝试将添加-ObjC宏的地方修改为 -force_load+空格+控件路径,如:-force_load $(PROJECT_DIR)/ libPaymentControl.a,这样做不会影响支付宝等其他支付渠道功能。
1.6 控件界面无限加载
1. 调用控件的逻辑应当在主线程中执行,子线程中尽量不要进行UI操作,无限加载等待实际是子线程死锁所致。
2. 请参考控件使用指南iOS “添加SDK包“里“添加-ObjC宏”,特别注意大小写不要弄混。(此步骤操作有问题时也可修改为 -force_load+空格+控件路径,如:-force_load $(PROJECT_DIR)/ libPaymentControl.a)。
3. Build Setting -> Apple LLVM compiler Language-C++:
1.7 Attempt to present XX on XX while a presentation is in progress!
Warning: Attempt to present
animation完成的时候再调用我们的插件,两个present同时起会出警告。