| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349 |
- //
- // AlipaySDKHelper.m
- // MingMen
- //
- // Created by 尚旅客户端 on 2017/8/18.
- // Copyright © 2017年 尚旅客户端. All rights reserved.
- //
- #import "AlipaySDKHelper.h"
- #import <AlipaySDK/AlipaySDK.h>
- #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<NSString*, id> *)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
|