支付寶支付

寫這篇文章的主要目的是做一個(gè)學(xué)習(xí)的備忘器紧,避免同樣的坑再爬一遍??耀销,下面開始正文。
文章的順序铲汪,就是開發(fā)的流程
1熊尉、將Alipay SDK包,添加到項(xiàng)目中

Alipay SDK

2掌腰、編譯項(xiàng)目狰住,會出現(xiàn)以下問題:

1)"Unknown type name ‘NSString‘ "或"Unknown type name ‘NSData‘ "

,但是本人并沒有遇到齿梁,參考網(wǎng)友的時(shí)候有這樣的問題催植,一并附上,主要看解釋原因

報(bào)錯(cuò)信息

這是因?yàn)槿鄙貴oundation類庫和UIKit類庫勺择,支付寶Demo中之所以沒有出現(xiàn)此錯(cuò)誤创南,是因?yàn)樵?pch文件中導(dǎo)入過這些類庫

解決辦法:只需要在出現(xiàn)錯(cuò)誤的文件中導(dǎo)入這些類庫即可

需要導(dǎo)入的庫

2)‘openssl/asn1.h‘ file not found,這個(gè)坑填了幾個(gè)小時(shí)??

報(bào)錯(cuò)信息

這是openssl文件夾頭文件鏈接問題省核,如果openssl文件夾隨意拉進(jìn)項(xiàng)目中稿辙,即使添加頭文件鏈接,也可能解決不了此問題气忠,這也是一開始就將所需要的文件放到一個(gè)新建文件夾中再添加到項(xiàng)目中的原因邻储。(試了各種方法添加檩奠,最終是先將Alipay拖放到文件中祖娘,再將Alipay拖到項(xiàng)目工程中,這樣添加的)

解決辦法:

Targets->Build Settings->Header Search Path中添加AliPaySDK文件夾的路徑

截圖

截圖

具體怎么寫(一個(gè)參數(shù)設(shè)置的時(shí)候)
多個(gè)參數(shù)設(shè)置的時(shí)候

這個(gè)參數(shù)需要設(shè)置多個(gè)值的時(shí)候,通過雙引號括起來

3)linker command failed with exit code 1 (use -v to see invocation)

這邊的解決辦法:”Build Settings”->”Enable Bitcode”設(shè)置為NO

(附帶的將Other Linker Flags下的屬性全刪除了在岂,可能不刪除也是可以跑的嘴瓤,沒有試)

4.編譯項(xiàng)目场梆,會出現(xiàn)以下問題:

報(bào)錯(cuò)信息

解決方法:在xcode中摹芙,點(diǎn)擊項(xiàng)目名,選擇"target"->"Link Binary With Libraries"添加依賴庫袱瓮。

需要添加的庫

編輯程序缤骨,已經(jīng)可以成功編譯了,接下來就是集成代碼了尺借,這邊主要做的是直接在前端集成代碼
5绊起、添加非https請求


截圖

(App Transport Security Settings 和Allow Arbitrary Loads)

6、代碼

#import "ViewController.h"
#import "AliOrder.h"
#import "DataSigner.h"
#import <AlipaySDK/AlipaySDK.h>


@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    
    //添加通知
    //客戶端安裝支付寶的情況下燎斩,支付成功的情況下虱歪,在delegate中通過通知進(jìn)行回傳數(shù)據(jù)
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(aliPaySucceeded) name:ALIPAY_SUCCEEDED object:nil];
    
}
- (void)viewDidUnload
{
    //移除通知
    [[NSNotificationCenter defaultCenter] removeObserver:self name:ALIPAY_SUCCEEDED object:nil];
    
    
    [super viewDidUnload];
}


- (IBAction)zhifubaoPay:(id)sender {
    
    [self payForAlipayWithProductName:@"翼停支付" productDescription:@"翼停支付"];
}
-(void)payForAlipayWithProductName:(NSString *)productName productDescription:(NSString *)productDescription
{
    // 進(jìn)入跳轉(zhuǎn)支付寶支付流程
    NSString *partner = Partner;
    NSString *seller = Seller;
    NSString *privateKey = PrivateKey;
    
    //partner和seller獲取失敗,提示
    if ([partner length] == 0 || [seller length] == 0)
    {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示"
                                                        message:@"缺少partner或者seller。"
                                                       delegate:self
                                              cancelButtonTitle:@"確定"
                                              otherButtonTitles:nil];
        [alert show];
        return;
    }
    
    AliOrder *aliOrder = [[AliOrder alloc] init];
    aliOrder.partner = partner;
    aliOrder.seller = seller;
    aliOrder.tradeNO = [self generateTradeNO];
    aliOrder.productName = productName; //商品標(biāo)題
    aliOrder.productDescription = productDescription; //商品描述
    
    aliOrder.amount = @"0.01"; //商品價(jià)格
    aliOrder.notifyURL = @"http://www.xxx.com"; //回調(diào)URL

    aliOrder.service = @"mobile.securitypay.pay";
    aliOrder.paymentType = @"1";
    aliOrder.inputCharset = @"utf-8";
    aliOrder.itBPay = @"30m";
    
    //應(yīng)用注冊scheme,在AlixPayDemo-Info.plist定義URL types
    NSString *appScheme = @"com.leaguerdtv.yuting";
    //將商品信息拼接成字符串
    NSString *orderSpec = [aliOrder description];
//    NSLog(@"orderSpec = %@",orderSpec);
    
    //獲取私鑰并將商戶信息簽名,外部商戶可以根據(jù)情況存放私鑰和簽名,只需要遵循 RSA 簽名規(guī)范, 并將簽名字符串 base64 編碼和 UrlEncode
    id<DataSigner> signer = CreateRSADataSigner(privateKey);
    NSString *signedString = [signer signString:orderSpec];
    //將簽名成功字符串格式化為訂單字符串,請嚴(yán)格按照該格式
    NSString *orderString = nil;
    if (signedString != nil) {
        orderString = [NSString stringWithFormat:@"%@&sign=\"%@\"&sign_type=\"%@\"",
                       orderSpec, signedString, @"RSA"];
        [[AlipaySDK defaultService] payOrder:orderString fromScheme:appScheme callback:^(NSDictionary *resultDic) {
            //裝了支付寶客戶端的栅表,這個(gè)block不會被執(zhí)行
            //裝了支付寶的笋鄙,通過在delegate中的通知進(jìn)行調(diào)用
            
            
            NSLog(@"result = %@", resultDic);
            NSLog(@"result = %@", resultDic);
            NSLog(@"[resultDic valueForKey:resultStatus] = %@", [resultDic valueForKey:@"resultStatus"]);
          
            switch ([resultDic[@"resultStatus"] integerValue])
            {
                case 9000: //支付成功
                {
                    NSLog(@"ViewController界面-支付寶支付成功~~~!怪瓶!!");
                    [self aliPaySucceeded];
                }
                    break;
                case 6001:
                {
                    NSLog(@"ViewController界面-訂單已取消~~~O袈洹!!");

                    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:@"訂單已取消" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
                    [alert show];
                }
                    break;
                case 6002:
                {
                    NSLog(@"ViewController界面-網(wǎng)絡(luò)連接出錯(cuò)~~~O捶 找岖!!");
                    
                    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:@"網(wǎng)絡(luò)連接出錯(cuò)" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
                    [alert show];
                }
                    break;
                case 4000:
                {
                    NSLog(@"ViewController界面-訂單支付失敗~~~!敛滋!!");
                    
                    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:@"訂單支付失敗" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
                    [alert show];
                }
                    break;
                default:
                {
                    NSLog(@"ViewController界面-未知錯(cuò)誤~~~!绎晃!!");

                    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:@"未知錯(cuò)誤" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
                    [alert show];
                }
                    break;
            }
        }];
    }
}
#pragma mark 產(chǎn)生隨機(jī)訂單號
- (NSString *)generateTradeNO {
    static int kNumber = 15;
    
    NSString *sourceStr = @"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    NSMutableString *resultStr = [[NSMutableString alloc] init];
    //    srand(time(0)); // 此行代碼有警告:
    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;
}

- (void)aliPaySucceeded
{
    // 通知后臺充值訂單支付成功
    NSLog(@"通知后臺消除這個(gè)訂單或者充值成功");
}

@end

delegate中代碼:

#import "AppDelegate.h"
#import <AlipaySDK/AlipaySDK.h>


@interface AppDelegate ()

@end

@implementation AppDelegate


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
    return YES;
}

//支付寶-回調(diào)
//9.0之前調(diào)用的方法
-(BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
{
    return [self alipayOrWeiXinCallbackWithOpenUrl:url];
}
//9.0之前調(diào)用的方法
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary*)options
{
    return [self alipayOrWeiXinCallbackWithOpenUrl:url];
}
//9.0之后調(diào)用的方法
- (BOOL)application:(UIApplication *)application
            openURL:(NSURL *)url
  sourceApplication:(NSString *)sourceApplication
         annotation:(id)annotation
{
    return [self alipayOrWeiXinCallbackWithOpenUrl:url];
}

//支付寶回調(diào)方法處理
-(BOOL)alipayOrWeiXinCallbackWithOpenUrl:(NSURL *)url
{
    //跳轉(zhuǎn)支付寶錢包進(jìn)行支付,需要將支付寶錢包的支付結(jié)果回傳給SDK
    //裝了支付寶的庶艾,這個(gè)方法才會被調(diào)用,通過在delegate中的通知進(jìn)行調(diào)用
    
    if ([url.host isEqualToString:@"safepay"]) {//支付寶支付相關(guān)操作
        [[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) {
            NSLog(@"result = %@", resultDic);
            NSLog(@"result = %@", resultDic);
            NSLog(@"[resultDic valueForKey:resultStatus] = %@", [resultDic valueForKey:@"resultStatus"]);
            
            if ([[resultDic valueForKey:@"resultStatus"] integerValue] == 9000 && [[resultDic valueForKey:@"result"] rangeOfString:@"success=\"true\""].length>0) {
                [[NSNotificationCenter defaultCenter] postNotificationName:ALIPAY_SUCCEEDED object:self];
            }else if ([[resultDic valueForKey:@"resultStatus"] integerValue] == 6001){
                
                NSLog(@"delegate-6001");
                UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:@"訂單已取消" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
                [alert show];
                
            }else if ([[resultDic valueForKey:@"resultStatus"] integerValue] == 6002){
                NSLog(@"delegate-6002");
                UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:@"網(wǎng)絡(luò)連接出錯(cuò)" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
                [alert show];
                
            }else if ([[resultDic valueForKey:@"resultStatus"] integerValue] == 4000){
                
                NSLog(@"delegate-4000");
                UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:@"訂單支付失敗" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
                [alert show];
                
            }else{
                UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:@"未知錯(cuò)誤" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
                [alert show];
            }
            
        }];
    }else if ([url.host isEqualToString:@"pay"]){//微信支付相關(guān)操作
        
    }
    return YES;
    
}

- (void)applicationWillResignActive:(UIApplication *)application {
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
    // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
}


- (void)applicationDidEnterBackground:(UIApplication *)application {
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}


- (void)applicationWillEnterForeground:(UIApplication *)application {
    // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}


- (void)applicationDidBecomeActive:(UIApplication *)application {
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}


- (void)applicationWillTerminate:(UIApplication *)application {
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}


@end

PrefixHeader.pch-配置一下pch文件

#ifndef PrefixHeader_pch
#define PrefixHeader_pch

#define ALIPAY_SUCCEEDED @"alipaySucceeded"
#endif /* PrefixHeader_pch */

7货抄、配置LSApplicationQueriesSchemes


LSApplicationQueriesSchemes配置

LSApplicationQueriesSchemes不配置的話朱转,是在項(xiàng)目內(nèi)調(diào)用支付寶進(jìn)行支付积暖;
配置了LSApplicationQueriesSchemes參數(shù),它會自動判斷當(dāng)前手機(jī)有沒有安裝支付寶夺刑,安裝了就跳支付寶應(yīng)用,沒有安裝直接應(yīng)用內(nèi)跳支付寶支付
(只要設(shè)置alipay這一個(gè)參數(shù)就可以了)

8遍愿、配置URL Schemes


URL Schemes plist中配置

這邊涂鴉掉的是代碼中 [[AlipaySDK defaultService] payOrder:orderString fromScheme:appScheme callback:^(NSDictionary *resultDic) {
里面的appScheme參數(shù)設(shè)置成一樣的存淫,這樣支付寶回調(diào)的時(shí)候就知道調(diào)用手機(jī)中那個(gè)標(biāo)識的應(yīng)用
一般不在plist文件中設(shè)置這個(gè)參數(shù),而是在圖形界面中沼填,這樣比較的方便


URL Schemes圖形配置

URL Schemes配置桅咆,主要可以讓支付寶可以正確的回調(diào)當(dāng)前應(yīng)用,并傳人相關(guān)的支付信息(成功坞笙、失敗岩饼、取消)

9、遇到的問題-備注一下薛夜,便于理解
1)籍茧、在AppDelegate.m中加入這兩個(gè)方法(對舊版本的支持):

//重要更新,一下兩個(gè)方法IOS9.0以后被廢棄了梯澜,所以如果你是Xcode7.2的話寞冯,可能會出現(xiàn)不能進(jìn)入微信的onResp回調(diào)方法,原因是下邊兩個(gè)方法沒有被調(diào)用腊徙,所以這里更新一下简十,改用另外一個(gè)方法(并不建議刪除這兩個(gè)方法,新方法是9.0以后的方法撬腾,可能系統(tǒng)低版本的用戶不支持螟蝙。所以我三種方法都留下了,如果有人發(fā)現(xiàn)不能都留下的話民傻,請簡信告訴我一下胰默,再次謝過了)

-(BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url;

-(BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation漓踢;

//改用方法為

- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary*)options牵署;

2)、支付寶回調(diào)的時(shí)候分兩種情況喧半,客戶端裝了支付寶和沒有裝支付寶兩種情況
情況一:客戶端裝了支付寶
通過在delegate中handleOpenURL或者openURL接受支付回調(diào)奴迅,支付成功時(shí)通過通知去支付界面進(jìn)行銷單處理
情況二、客戶端沒有安裝支付寶
會在支付寶調(diào)用界面挺据,執(zhí)行block取具,方法如下圖


截圖
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末脖隶,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子暇检,更是在濱河造成了極大的恐慌产阱,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件构蹬,死亡現(xiàn)場離奇詭異庄敛,居然都是意外死亡铐姚,警方通過查閱死者的電腦和手機(jī)肛捍,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進(jìn)店門拙毫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來缀蹄,“玉大人,你說我怎么就攤上這事蛀醉⌒坡耄” “怎么了逝段?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵奶躯,是天一觀的道長。 經(jīng)常有香客問我账嚎,道長郭蕉,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮烟勋,結(jié)果婚禮上筐付,老公的妹妹穿的比我還像新娘瓦戚。我一直安慰自己,他們只是感情好畜疾,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布啡捶。 她就那樣靜靜地躺著瞎暑,像睡著了一般与帆。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上勿她,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天嫂拴,我揣著相機(jī)與錄音贮喧,去河邊找鬼。 笑死辩恼,一個(gè)胖子當(dāng)著我的面吹牛灶伊,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播竹椒,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼胸完,長吁一口氣:“原來是場噩夢啊……” “哼赊窥!你這毒婦竟也來了狸页?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤址遇,失蹤者是張志新(化名)和其女友劉穎傲隶,沒想到半個(gè)月后窃页,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體脖卖,經(jīng)...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡畦木,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年十籍,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片惨篱。...
    茶點(diǎn)故事閱讀 39,902評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡砸讳,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出簿寂,到底是詐尸還是另有隱情,我是刑警寧澤纳令,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布克胳,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏酗钞。R本人自食惡果不足惜来累,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一嘹锁、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧米同,春花似錦摔竿、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽粱胜。三九已至,卻和暖如春凿歼,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背答憔。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工虐拓, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蓉驹,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓狠持,卻偏偏與公主長得像喘垂,于是被迫代替她去往敵國和親绍撞。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 支付寶簡介文檔 (適用于ydm-java接口與后臺两踏,如有誤入,但愿也能給您帶來幫助) 此文檔寫于2017年3月喧枷,只...
    隔壁付叔叔閱讀 17,069評論 3 19
  • 最近做系統(tǒng)隧甚,需要實(shí)現(xiàn)在線支付功能渡冻,毫不猶豫,選擇的是支付寶的接口支付功能帽借。這里我用的是即時(shí)到帳的接口,具體實(shí)現(xiàn)的步...
    geeooooz閱讀 9,839評論 0 3
  • 此項(xiàng)目已開源 趕快來圍觀 Start支持下吧 【客戶端開源地址-JPay】【服務(wù)端端開源地址-在com.javen...
    LucasAdam閱讀 1,949評論 0 3
  • 1蒂教、App支付簡介 買家在手機(jī)凝垛、掌上電腦等無線設(shè)備的應(yīng)用程序內(nèi)蜓谋,可通過支付寶進(jìn)行付款購買特定服務(wù)或商品,資金即時(shí)到...
    PZcoder閱讀 44,019評論 5 22
  • 支付寶集成過程詳解——運(yùn)行DEMO 前言剑肯,夢想是需要堅(jiān)持的让网,在路上型将,一路前行荐虐。加油。 這兩天軟件需要集成支付寶了腕铸,...
    改昵稱已被占用閱讀 19,052評論 2 39