要说起移动支付App调用支付支付可谓是已经不再新鲜啦,楼主第一次接触App调用支付还是N年前的事情---依稀似乎记得那时是懵逼的就完成了。不过这次着实的被SDK和官网文档的某些地方给坑了一把,因此今天好好理理一下顺序
支付宝为移动端的开发提供两种下单支付的方式:
1 App内部完成自签名
2服务端完成签名,App负责传递单据信息给支付宝完成下单
因为支付宝不推荐App内部完成自签名下单,因此1的流程我们忽略……因此我们的重点就来到了如何调用SDK与App回调之后支付结果的处理啦
嵌入SDK
1配置Info.plist
2嵌入SDK有两种
1 直接拖入
2 pod安装
针对这两种无论哪种最新的SDK都有个坑,支付宝不想支持回调啦,这也许是个坑,目前楼主遇到两种问题
1 高版本SDK无法回调寻找低版本的SDK完成
2 无论是高低版本的SDK当你的 URL Schemes短的时候都无法回调
这里不得不吐槽一下,支付宝的官网只说需要URL Schemes要特别一点不要与其他人重复了,却不给出具体有效合理规则建议
发起支付
如上图所示吧,自己App服务器提供下单服务自不必说,说说我们SDK初始化与调用SDK吧
1 Appdelegate配置与版本兼容
-(BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
if ([url.host isEqualToString:@"safepay"]) {
id<YuAliPayResponse> payResponse = [AlipaySDK defaultService].payResponse;
//跳转支付宝钱包进行支付,处理支付结果
[[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) {
NSLog(@"result = %@",resultDic);
if (payResponse) {
dispatch_async(dispatch_get_main_queue(), ^{
[payResponse aliPayResponse:resultDic];
});
}
}];
return YES;
}
}
#pragma 支付宝
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation {
if ([url.host isEqualToString:@"safepay"]) {
//跳转支付宝钱包进行支付,处理支付结果
[[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) {
NSLog(@"result = %@",resultDic);
id<YuAliPayResponse> payResponse = [AlipaySDK defaultService].payResponse;
if (payResponse) {
dispatch_async(dispatch_get_main_queue(), ^{
[payResponse aliPayResponse:resultDic];
});
}
}];
}
return YES;
}
这里没有什么好说的,支付宝的接收回调很清楚,主要是基于iOS 的API版本兼容左处理
2发起支付调用支付宝
#import "AlipaySDK+pay.h"
@implementation AlipaySDK (pay)
#define ALI_Response_KEY @"YuAliPayResponse"
-(void)setPayResponse:(id<YuAliPayResponse>)payResponse{
objc_setAssociatedObject(self, ALI_SCHEME, payResponse, OBJC_ASSOCIATION_ASSIGN);
}
-(id<YuAliPayResponse>)payResponse{
id<YuAliPayResponse> response = objc_getAssociatedObject(self, ALI_SCHEME);
// objc_removeAssociatedObjects(self);
return response;
}
-(void)payOrder:(NSString *)orderStr fromScheme:(NSString *)schemeStr callback:(CompletionBlock)completionBlock withResp:(id<YuAliPayResponse>)resp{
self.payResponse = resp;
[self payOrder:orderStr
fromScheme:schemeStr
callback:completionBlock];
}
@end
为啥给AlipaySDK做category呢?有两点好处
1 自身单例
2 通过runtime可以有效的将回调的block绑定到AlipaySDK,这样就可以在Appdelegate中的回调处理中方便拿到回调然后在发起支付的地方处理回调数据相应
回调处理
回调获取的数据十分的简洁,通过状态码来判断结果
#pragma 用户下单支付宝回调结果处理
-(void)aliPayResponse:(NSDictionary *)dic{
NSInteger resultStatus = [NSNumber numberWithString: [dic valueForKey:@"resultStatus"]].integerValue;
if (resultStatus == 9000) {
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"支付成功" message:@"请到\"我的订单\"查看" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *sure = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
[self clear];
}];
[alert addAction:sure];
[self.vc presentViewController:alert animated:NO completion:^{
}];
} else {
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"支付失败" message:@"请到\"我的订单\"重新支付" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *sure = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
[self clear];
}];
[alert addAction:sure];
[self.vc presentViewController:alert animated:NO completion:^{
}];
}
}
总结一下
当你无法回调时:
1 SDK版本
2 URL Scheme是否太短啦