iOS之支付宝支付

一、下载支付宝sdk
公钥、私钥、PID、sellerID、key这些东西的用途和获取方式在文档上都有详细的说明,按照文档说明进行操作。
二、支付流程理解
开发文档、开发文档、开发文档,重要的事情一定要说三遍!!!建议先把开发文档仔仔细细看一遍,一定要看,本小白刚开始的时候没有老老实实地看完,结果遇到很多很多的坑,以血和泪劝解大家,浪费的挺多的时间的,所以建议一定要好好看看,特别是交互流程这一部分


三、跳转支付宝客户端进行支付,处理支付结果


// 9.0之后
//- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary*)options
//{
//
//}
- (BOOL)application:(UIApplication*)applicationopenURL:(NSURL*)urlsourceApplication:(NSString*)sourceApplicationannotation:(id)annotation 
{
// 跳转支付宝客户端进行支付,处理支付结果
     [[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary*resultDic) {
//
     NSLog(@"回调结果 = %@", resultDic);
// 用SBJSON 或者 JSONKit 将回调信息(字典)转成字符串
     SBJSON *sbJson = [[SBJSON alloc] init];
     NSString*resultDicToString = [sbJson stringWithObject:resultDic error:nil];
         [selfpaymentResult:resultDicToString];
     }];
     returnYES;
}

#pragma mark - 对独立客户端回调结果验证


- (void)paymentResult:(NSString *)resultDicToString
{//结果处理
AlixPayResult *result = [[AlixPayResult alloc] initWithString:resultDicToString];
if (result){ 
if (result.statusCode == 9000) {
 /** * 支付成功用公钥验证签名 严格验证请使用result.resultString与result.signString验签 */
 // 就是在生产订单时,需要使用私钥生成签名值;在处理返回的支付结果时,需要使用公钥验证返回结果是否被篡改了。
 // resultDic 返回结果所对应的值可以到支付宝开发平台上去查
  // 在处理结果之前应该先对支付结果进行签名验证,防止支付数据被篡改。  // 返回的支付结果中的result字段里是带有订单信息和签名信息的,所以签名验证就是需要这个字段的值。
 // 分发出得公钥 
 // 验证的步骤:首先把订单信息和签名值分别提取出来 
 // 订单信息就是sign_type的连字符&之前的所有字符串  
// 签名值是sign后面双引号内的内容,注意签名的结尾也是=,所以不要用split字符串的方式提取  
NSString* key = AlipayPublicKey;
//签约帐户后获取到的支付宝公钥  
id<DataVerifier>verifier; verifier = CreateRSADataVerifier(key);
// 参数1:订单信息
// 参数2:签名值
if ([verifier verifyString:result.resultString withSign:result.signString]){
// 验证签名成功,交易结果无篡改
NSLog(@"支付成功!");
}
}else{
// 支付失败
NSLog(@"%d%@", result.statusCode, result.statusMessage);
}}else{
// 支付失败
NSLog(@"支付失败!");
}}
import"ViewController.h"
#import#import"Order.h"// 订单信息
#import"DataSigner.h"// 签名
#import"PartnerConfig.h"// 配置信息
// 以下的类是验证支付结果用的  不验证不需要引用
#import"DataVerifier.h"// 验证签名
#import"AlixPayResult.h"// 支付结果处理
#import"SBJSON.h"
/**
*  官方接入流程、SDK下载请参考这里:http://doc.open.alipay.com/doc2/detail?treeId=59&articleId=103563&docType=1
*  这篇博文说的也是很好,参考这里:http://www.jianshu.com/p/fe56e122663e
*/
@interface ViewController()
@end
@implementation ViewController
- (void)viewDidLoad {
[superviewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.navigationItem.title=@"支付宝支付";
UIButton*payButton = [UIButtonbuttonWithType:UIButtonTypeCustom];
payButton.frame=CGRectMake(50,100,self.view.frame.size.width-100,60);payButton.layer.cornerRadius=5;
payButton.backgroundColor= [UIColorlightGrayColor];
[payButton setImage:[UIImageimageNamed:@"payNow_alipay"] forState:UIControlStateNormal];
[payButton setImageEdgeInsets:UIEdgeInsetsMake(5, -20,0,0)];
[payButton setTitle:@"支付宝支付"forState:UIControlStateNormal];[payButton addTarget:selfaction:@selector(alipayAction) forControlEvents:UIControlEventTouchUpInside];[self.viewaddSubview:payButton];
}

#pragma mark - 点击支付

/**
*  如果安装了支付宝客户端会直接调起客户端,没有安装会调起wap页面
*/
- (void)alipayAction{
/**
*  商户的唯一的parnter和seller。商户签约成功后,支付宝会为每
*  个商户分配一个唯一的 parnter(appID) 和 seller(支付宝账号)。
*  privateKey生成的私钥,可放在本地,建议放在服务器端
*/
NSString*partner = PartnerID;
NSString*seller = SellerID;
// partner和seller获取失败
if([partner length] ==0|| [seller length] ==0){
UIAlertView*alert = [[UIAlertViewalloc] initWithTitle:@"提示"message:@"缺少partner或者seller。"delegate:selfcancelButtonTitle:@"确定"otherButtonTitles:nil];
[alert show];
return;
}
// 应用注册scheme,在Info.plist定义URL types URL scheme
NSString*appScheme =@"test";
//程序间通信 app 调 支付宝
// 将商品信息拼接成字符串
NSString*orderSpec = [selfcreateOrderInfoWithPartner:partner Seller:seller];
// 进行签名并将签名成功后的字符串格式化为订单字符串
NSString*signedString = [selfdoRsa:orderSpec];
// 调用支付宝SDK发送数据
[selfsendValueToAliPayWithOrderString:signedString FromScheme:appScheme];
}

#warning 1.生成预支付订单信息

- (NSString*)createOrderInfoWithPartner:(NSString*)partnerSeller:(NSString*)seller{
/**
*由于demo的局限性,采用了将私钥放在本地签名的方法,商户可以根据自身情况选择签名方法(为安全起
*见,在条件允许的前提下,推荐从自己的服务器获取完整的订单信息)
*/
// 将商品信息赋予Order的成员变量
Order *order = [[Order alloc] init];
order.partner= partner;order.seller= seller;
order.tradeNO=@"123432121222";//订单ID(由商家自行制定)
order.productName=@"商品标题";//商品标题
order.productDescription=@"商品描述";//商品描述
order.amount=@"0.01";//商品价格
order.notifyURL=@"";//回调URL  退款功能
// 这以下是固定形式每个app都是这么写
order.service=@"mobile.securitypay.pay";
order.paymentType=@"1";
order.inputCharset=@"utf-8";
order.itBPay=@"30m";
order.showUrl=@"m.alipay.com";
return[order description];
}

#warning 2.将订单信息用私钥进行签名

// 获取私钥并将商户信息签名,外部商户可以根据情况存放私钥和签名,只需要遵循RSA签名规范,并将签名字符串base64编码和UrlEncode
// 此demo是在app内部做的签名
// 订单签名应该用私钥,但是把私钥放到app里其实本身就不安全,因为你的app是分发到用户手里的,私钥应该放在自己的手里,分发出去的应该是公钥。所以私钥最好是放在自己的服务器上,订单加密这个工作放在服务器端来做,服务器将包含签名的订单信息返回给app,app再通过SDK发送给支付宝,这样会更安全些;而且服务器也能掌握所有的订单状况
- (NSString*)doRsa:(NSString*)orderInfo{    idsigner;
signer = CreateRSADataSigner(PartnerPrivateKey);
NSString*signedString = [signer signString:orderInfo];
// 将签名成功字符串格式化为订单字符串,请严格按照该格式
NSString*orderString =nil;
if(signedString !=nil) {
orderString = [NSStringstringWithFormat:@"%@&sign=\"%@\"&sign_type=\"%@\"",orderInfo, signedString,@"RSA"];
NSLog(@"orderString ====  %@\nsignerString  ========== %@", orderString, signedString);}returnorderString;
}

#warning 3.调用支付宝SDK发送请求数据

- (void)sendValueToAliPayWithOrderString:(NSString*)orderString FromScheme:(NSString*)appScheme{
    [[AlipaySDK defaultService] payOrder:orderString fromScheme:appScheme callback:^(NSDictionary*resultDic) {
// 用SBJSON 或者 JSONKit 将回调信息(字典)转成字符串
        SBJSON *sbJson = [[SBJSON alloc] init];
        NSString*resultDicToString = [sbJson stringWithObject:resultDic error:nil];
        [selfpaymentResult:resultDicToString];
        NSLog(@"回调结果reslut = %@",resultDic);
//          NSLog(@"%d%@", [[resultDic objectForKey:@"resultStatus"] intValue], [resultDic objectForKey:@"memo"]); 
    }];
}

#warning 4.对支付回调的结果进行验证(这一步加上是确保数据的安全,不加不影响支付)

// 就是在生产订单时,需要使用私钥生成签名值;在处理返回的支付结果时,需要使用公钥验证返回结果是否被篡改了。
// resultDic 返回结果所对应的值可以到支付宝开发平台上去查
// 在处理结果之前应该先对支付结果进行签名验证,防止支付数据被篡改。
// 返回的支付结果中的result字段里是带有订单信息和签名信息的,所以签名验证就是需要这个字段的值。
// 验证的步骤:首先把订单信息和签名值分别提取出来
// 订单信息就是sign_type的连字符&之前的所有字符串
// 签名值是sign后面双引号内的内容,注意签名的结尾也是=
// 此demo我是用SBJSON 或者 JSONKit 将回调信息(字典)转成字符串
// 也可以不使用SBJSON或者JSONKit处理回调信息,直接在回调结果中截取需要的字符串也可以,直接调用可以直接使用Util目录下的DataVerifier来作签名验证"- (BOOL)verifyString:(NSString *)string withSign:(NSString *)signString"第一个参数就是订单信息,第二个参数就是签名值。
- (void)paymentResult:(NSString*)resultDicToString{
//结果处理
AlixPayResult *result = [[AlixPayResult alloc] initWithString:resultDicToString];
if(result)    {
/**        * 状态码       
 * 9000 订单支付成功        
* 8000 正在处理中        
* 4000 订单支付失败        
* 6001 用户中途取消        
* 6002 网络连接出错        
*/
if(result.statusCode==9000)        {
/**363918           
 *用公钥验证签名 严格验证请使用result.resultString与result.signString验签  
 */
// 交易成功
NSString* key = AlipayPublicKey;
id<DataVerifier >idverifier**;** 
verifier = CreateRSADataVerifier(key);
// 参数1:订单信息
// 参数2:签名值
/**< resultString.订单信息以及验证签名信息*/
/*如果你不想做签名验证,那这个字段可以忽略了*/
if ([verifier verifyString:result.resultString withSign:result.signString]){
// 验证签名成功,交易结果无篡改NSLog(@"支付成功!");
} else {
NSLog(@"此单被篡改无效!!");
}
}else{
NSLog(@"此单被篡改无效!!");
}
}else{
// 支付失败
NSLog(@"%d%@", result.statusCode, result.statusMessage);
}
}else{
// 支付失败
NSLog(@"支付失败!");
}
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,009评论 5 474
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,808评论 2 378
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,891评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,283评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,285评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,409评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,809评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,487评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,680评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,499评论 2 318
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,548评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,268评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,815评论 3 304
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,872评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,102评论 1 258
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,683评论 2 348
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,253评论 2 341

推荐阅读更多精彩内容

  • iOS支付 iOS支付分为两类,第三方支付和应用内支付(内购)。 第三方支付包括:支付宝支付、微信支付、银联支付、...
    请输入账号名阅读 6,169评论 3 22
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,333评论 25 707
  • iOS支付 iOS支付分为两类,第三方支付和应用内支付(内购)。 第三方支付包括:支付宝支付、微信支付、银联支付、...
    帅不过oneS阅读 2,837评论 2 8
  • 《赠高考学子》 ——红尘一凡 十年寒窗煞费心, 磨砺芳华十几春。 而今研墨临考场, 奋力拼搏跃龙门。 一榜荣登魁元...
    37度女人_8dda阅读 194评论 1 2
  • 一 我和顾青青的相识算是一场狗血剧。 第一次见她是一个冬日的上午,课间操回来。 她穿着大红大绿的衣服从我面前呼啸而...
    咯吱酒酒阅读 294评论 0 0