// // AlipaySDKHelper.m // MingMen // // Created by 尚旅客户端 on 2017/8/18. // Copyright © 2017年 尚旅客户端. All rights reserved. // #import "AlipaySDKHelper.h" #import #import "Order.h" #import "APAuthV2Info.h" #import "RSADataSigner.h" @implementation AlipaySDKHelper static AlipaySDKHelper *sharedObj = nil; + (instancetype)sharedInstance { static dispatch_once_t onceToken = 0; dispatch_once(&onceToken, ^{ sharedObj = [[super allocWithZone: NULL] init]; }); return sharedObj; // static NIMSDKHelper *instance = nil; // static dispatch_once_t onceToken; // dispatch_once(&onceToken, ^{ // instance = [[NIMSDKHelper alloc] init]; // }); // return instance; } + (id) allocWithZone:(struct _NSZone *)zone { return [self sharedInstance]; } - (id) copyWithZone:(NSZone *) zone { return self; } #pragma mark - iOS9.0以后使用新API回调 - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options { // 支付跳转支付宝钱包进行支付,处理支付结果 [[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) { //NSLog(@"支付结果 result = %@",resultDic); _NewAlipayCallback(resultDic); }]; // 授权跳转支付宝钱包,处理授权结果 [[AlipaySDK defaultService] processAuth_V2Result:url standbyCallback:^(NSDictionary *resultDic) { //NSLog(@"授权结果结果 result = %@",resultDic); _NewAliauthCallback(resultDic); /* // 解析 auth code NSString *result = resultDic[@"result"]; NSString *authCode = nil; if (result.length>0) { NSArray *resultArr = [result componentsSeparatedByString:@"&"]; for (NSString *subResult in resultArr) { if (subResult.length > 10 && [subResult hasPrefix:@"auth_code="]) { authCode = [subResult substringFromIndex:10]; break; } } } NSLog(@"授权结果 authCode = %@", authCode?:@""); */ }]; return YES; } #pragma mark - iOS9.0之前使用旧API回调 - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { // 支付跳转支付宝钱包进行支付,处理支付结果 [[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) { //NSLog(@"支付结果 result = %@",resultDic); _NewAlipayCallback(resultDic); }]; // 授权跳转支付宝钱包,处理授权结果 [[AlipaySDK defaultService] processAuth_V2Result:url standbyCallback:^(NSDictionary *resultDic) { //NSLog(@"授权结果结果 result = %@",resultDic); _NewAliauthCallback(resultDic); /* // 解析 auth code NSString *result = resultDic[@"result"]; NSString *authCode = nil; if (result.length>0) { NSArray *resultArr = [result componentsSeparatedByString:@"&"]; for (NSString *subResult in resultArr) { if (subResult.length > 10 && [subResult hasPrefix:@"auth_code="]) { authCode = [subResult substringFromIndex:10]; break; } } } NSLog(@"授权结果 authCode = %@", authCode?:@""); */ }]; return YES; } - (NSString *)generateTradeNO { static int kNumber = 15; NSString *sourceStr = @"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; NSMutableString *resultStr = [[NSMutableString alloc] init]; srand((unsigned)time(0)); for (int i = 0; i < kNumber; i++) { unsigned index = rand() % [sourceStr length]; NSString *oneStr = [sourceStr substringWithRange:NSMakeRange(index, 1)]; [resultStr appendString:oneStr]; } return resultStr; } #pragma mark - #pragma mark ==============点击订单支付============== // //选中商品调用支付宝极简支付 // - (void)alipayPay:(NSDictionary *)payDictionary order:(NSDictionary *)orderDictionary { //重要说明 //这里只是为了方便直接向商户展示支付宝的整个支付流程;所以Demo中加签过程直接放在客户端完成; //真实App里,privateKey等数据严禁放在客户端,加签过程务必要放在服务端完成; //防止商户私密数据泄露,造成不必要的资金损失,及面临各种安全风险; /*============================================================================*/ /*=======================需要填写商户app申请的===================================*/ /*============================================================================*/ NSString *appID = payDictionary[@"AlipayAppid"]; // 如下私钥,rsa2PrivateKey 或者 rsaPrivateKey 只需要填入一个 // 如果商户两个都设置了,优先使用 rsa2PrivateKey // rsa2PrivateKey 可以保证商户交易在更加安全的环境下进行,建议使用 rsa2PrivateKey // 获取 rsa2PrivateKey,建议使用支付宝提供的公私钥生成工具生成, // 工具地址:https://doc.open.alipay.com/docs/doc.htm?treeId=291&articleId=106097&docType=1 NSString *rsa2PrivateKey = payDictionary[@"AlipayPrivateKey"];//私钥 NSString *rsaPrivateKey = payDictionary[@"AlipayPublicKey"];//公钥 /*============================================================================*/ /*============================================================================*/ /*============================================================================*/ //partner和seller获取失败,提示 //message:@"缺少pid或者appID或者私钥。" if ([appID length] == 0 || ([rsa2PrivateKey length] == 0 && [rsaPrivateKey length] == 0)) { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:@"提交订单信息发生错误,请稍后再试" delegate:self cancelButtonTitle:@"确定" otherButtonTitles:nil]; [alert show]; return; } /* *生成订单信息及签名 */ //将商品信息赋予AlixPayOrder的成员变量 Order* order = [Order new]; // NOTE: app_id设置 order.app_id = appID; // NOTE: 支付接口名称 order.method = @"alipay.trade.app.pay"; // NOTE: 参数编码格式 order.charset = @"utf-8"; // NOTE: 当前时间点 NSDateFormatter* formatter = [NSDateFormatter new]; [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"]; order.timestamp = [formatter stringFromDate:[NSDate date]]; // NOTE: 支付版本 order.version = @"1.0"; // NOTE: sign_type 根据商户设置的私钥来决定 order.sign_type = (rsa2PrivateKey.length > 1)?@"RSA2":@"RSA"; // NOTE: 商品数据 order.biz_content = [BizContent new]; order.biz_content.body = orderDictionary[@"body"]; order.biz_content.subject = orderDictionary[@"subject"]; order.biz_content.out_trade_no = orderDictionary[@"out_trade_no"]; //订单ID(由商家自行制定)[self generateTradeNO] order.biz_content.timeout_express = orderDictionary[@"timeout_express"]; //超时时间设置 order.biz_content.total_amount = orderDictionary[@"total_amount"]; //商品价格 [NSString stringWithFormat:@"%.2f", 0.01] //将商品信息拼接成字符串 NSString *orderInfo = [order orderInfoEncoded:NO]; NSString *orderInfoEncoded = [order orderInfoEncoded:YES]; NSLog(@"orderSpec = %@",orderInfo); // NOTE: 获取私钥并将商户信息签名,外部商户的加签过程请务必放在服务端,防止公私钥数据泄露; // 需要遵循RSA签名规范,并将签名字符串base64编码和UrlEncode NSString *signedString = nil; RSADataSigner* signer = [[RSADataSigner alloc] initWithPrivateKey:((rsa2PrivateKey.length > 1)?rsa2PrivateKey:rsaPrivateKey)]; if ((rsa2PrivateKey.length > 1)) { signedString = [signer signString:orderInfo withRSA2:YES]; } else { signedString = [signer signString:orderInfo withRSA2:NO]; } // NOTE: 如果加签成功,则继续执行支付 if (signedString != nil) { //应用注册scheme,在AliSDKDemo-Info.plist定义URL types NSString *appScheme = @"iosbjmingmen"; // NOTE: 将签名成功字符串格式化为订单字符串,请严格按照该格式 NSString *orderString = [NSString stringWithFormat:@"%@&sign=%@", orderInfoEncoded, signedString]; // NOTE: 调用支付结果开始支付 [[AlipaySDK defaultService] payOrder:orderString fromScheme:appScheme callback:^(NSDictionary *resultDic) { //NSLog(@"支付结果 result = %@",resultDic); _NewAlipayCallback(resultDic); }]; } } #pragma mark ==============点击授权============== - (void)alipayAuth:(NSDictionary *)authDictionary { //重要说明 //这里只是为了方便直接向商户展示支付宝的整个支付流程;所以Demo中加签过程直接放在客户端完成; //真实App里,privateKey等数据严禁放在客户端,加签过程务必要放在服务端完成; //防止商户私密数据泄露,造成不必要的资金损失,及面临各种安全风险; /*============================================================================*/ /*=======================需要填写商户app申请的===================================*/ /*============================================================================*/ NSString *pid = authDictionary[@"AlipayPid"]; NSString *appID = authDictionary[@"AlipayAppid"]; // 如下私钥,rsa2PrivateKey 或者 rsaPrivateKey 只需要填入一个 // 如果商户两个都设置了,优先使用 rsa2PrivateKey // rsa2PrivateKey 可以保证商户交易在更加安全的环境下进行,建议使用 rsa2PrivateKey // 获取 rsa2PrivateKey,建议使用支付宝提供的公私钥生成工具生成, // 工具地址:https://doc.open.alipay.com/docs/doc.htm?treeId=291&articleId=106097&docType=1 NSString *rsa2PrivateKey = authDictionary[@"AlipayPrivateKey"];//私钥 NSString *rsaPrivateKey = authDictionary[@"AlipayPublicKey"];//公钥 /*============================================================================*/ /*============================================================================*/ /*============================================================================*/ //pid和appID获取失败,提示 if ([pid length] == 0 || [appID length] == 0 || ([rsa2PrivateKey length] == 0 && [rsaPrivateKey length] == 0)) { //message:@"缺少pid或者appID或者私钥。" UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:@"申请授权发生错误,请稍后再试" delegate:self cancelButtonTitle:@"确定" otherButtonTitles:nil]; [alert show]; return; } /* //生成 auth info 对象 APAuthV2Info *authInfo = [APAuthV2Info new]; authInfo.pid = pid; authInfo.appID = appID; authInfo.targetID = authDictionary[@"targetID"]; //授权类型,AUTHACCOUNT:授权;LOGIN:登录 NSString *authType = [[NSUserDefaults standardUserDefaults] objectForKey:@"authType"]; if (authType) { authInfo.authType = authType; } // 将授权信息拼接成字符串 NSString *authInfoStr = [authInfo description]; NSLog(@"authInfoStr = %@",authInfoStr); // 获取私钥并将商户信息签名,外部商户可以根据情况存放私钥和签名,只需要遵循RSA签名规范,并将签名字符串base64编码和UrlEncode NSString *signedString = nil; RSADataSigner* signer = [[RSADataSigner alloc] initWithPrivateKey:((rsa2PrivateKey.length > 1)?rsa2PrivateKey:rsaPrivateKey)]; if ((rsa2PrivateKey.length > 1)) { signedString = [signer signString:authInfoStr withRSA2:YES]; } else { signedString = [signer signString:authInfoStr withRSA2:NO]; } */ //应用注册scheme,在AlixPayDemo-Info.plist定义URL types NSString *appScheme = @"iosbjmingmen"; // 将签名成功字符串格式化为订单字符串,请严格按照该格式 // signedString.length > 0 if ([authDictionary[@"sign_url"] length] > 0) { //authInfoStr = [NSString stringWithFormat:@"%@&sign=%@&sign_type=%@", authInfoStr, signedString, ((rsa2PrivateKey.length > 1)?@"RSA2":@"RSA")]; //如果APP处于前台,则通过此方法拿到支付宝的回调信息 [[AlipaySDK defaultService] auth_V2WithInfo:authDictionary[@"sign_url"] fromScheme:appScheme callback:^(NSDictionary *resultDic) { //NSLog(@"授权结果结果 result = %@",resultDic); _NewAliauthCallback(resultDic); /* // 解析 auth code NSString *result = resultDic[@"result"]; NSString *authCode = nil; if (result.length>0) { NSArray *resultArr = [result componentsSeparatedByString:@"&"]; for (NSString *subResult in resultArr) { if (subResult.length > 10 && [subResult hasPrefix:@"auth_code="]) { authCode = [subResult substringFromIndex:10]; break; } } } NSLog(@"授权结果 authCode = %@", authCode?:@""); */ }]; } } @end