iOS開發之支付寶集成


 

項目中要用到支付功能,需要支付寶,微信,銀聯三大支付,所以打算總結一下,寫兩篇文章,方便以后的查閱, 大家在做的時候也能稍微參考下,用到的地方避免再次被坑。這是第二篇支付寶集成,第一篇銀聯支付在這里。本來要用那個ping++的神器,可以集成各種支付手段,異常的方便,但是考慮到安全性問題的話,支付的渠道還是不讓第三方參與的好,不然會不安全,於是就苦逼地慢慢的一個一個集成了。。。。這里就代理支付寶的集成過程:

 

剛開始以為支付寶集成還是比較簡單的,看了幾個文章,網上的各位大神也是各種秀操作,說集成很簡單,但是,真正做起來就不是那回事了, 特別是新版的1月11號更新的,我正好是這一天開始看的,網上的經驗什么的 大都是比較老的,比較新的能用到的文章不多(但是好文章還是有的,對我幫助也很大),現在我就來一步一步說一下自己集成支付寶的血淚史!

下載支付寶SDK

首先是開發包下載,還是比較難發現的,網上以前文章中的鏈接都打不開,我找了好久才找到的。最新的地址在這里(注意的是下載出來的SDK包里面並沒有傳說中的開發文檔,需要其他地方找或者看網頁上的)。
公鑰、私鑰、PID、sellerID、key這些東西的用途和獲取方式在文檔上都有詳細的說明,這里不再贅述,一定要把概念分清楚再去做,不然一會就亂了。如果遇到問題的話咱們可以再一起探討。

支付流程理解

開發文檔、開發文檔、開發文檔,重要的事情一定要說三遍!!!建議先把開發文檔仔仔細細看一遍,一定要看,本小白剛開始的時候沒有老老實實地看完,結果遇到很多很多的坑,以血和淚勸解大家,浪費的挺多的時間的,所以建議一定要好好看看,特別是交互流程這一部分


交互流程


流程就是跟咱們平時在手機上買東西是一樣的:
1.用戶選好了商品后,點擊提交訂單(一般是這樣),選擇使用支付寶付款。
2.手機客戶端(你做的APP)把用戶選擇的商品的信息傳給你們后台服務器。
3.后台的服務器將各種數據拼接簽名后生成一個簽名后的字符串,回傳到客戶端APP上。
4.用戶點擊確認支付按鈕,調用手機支付寶客戶端(在你手機上裝的那個),利用后台傳過來的那個參數調起支付寶,讓支付寶客戶端傳給他們服務器交互,進行付款。(這一步是支付寶自己完成的,安全性高)
5.支付寶的服務器將支付的結果(可能成功也可能不成功)返回給手機支付寶客戶端和你們公司的后台服務器。
6.你們公司后台服務器收到后一般是更新下數據信息(這個咱們不用管),手機支付寶客戶端會顯示一下支付成功,咱們的客戶端也可以顯示一個訂單支付成功之類的東西(就像在手機12306訂票,用支付寶支付后支付寶客戶端會說一次支付成功,12306也會說一次支付成功,咱們就像12306客戶端一樣,需要再說一次訂單支付成功)。

到這里就完成了支付的過程了。我覺得這個流程還是很容易理解的。
其中咱們就是商戶客戶端需要做的就是:
• 調用支付寶支付接口
• 處理支付寶返回的支付結果
支付寶文檔上的應用范例:

ps:簽名部分為了安全起見都放在了后台,如果你們執意要在手機客戶端做簽名,不怕被攔截那就再加上一步簽名。也才三步,還是很簡單。

調用支付接口

在調用支付寶支付接口前,我們需要先生成一個訂單,文檔中描述時,是將這步也放在客戶端來做了,但這個最好是 放在服務器端來做,后台生成訂單然后拼接,簽名,然后服務器端直接給客戶端傳一個加密簽名過的參數就可以了,這樣比較安全,官方demo上放在客戶端生成訂單並且簽名是因為沒有服務給你用啊,所以就客戶端上生成了~~~。
我做的時候,為了安全,生成訂單,拼接字符串,簽名,都是在服務器上做的,所有的訂單信息,商戶信息等都掌握在自己的手中,這樣的話APP端就不怕被攔截數據,並且調用起來也就特別簡單了,只需要調用支付的接口,打開支付寶APP客戶端進行支付就行了,沒有用戶的手機上沒有安裝支付寶客戶端的話會調用網頁來支付,也是一樣的。
如果只需要發送訂單和處理支付返回結果,只需要添加AlipaySDK.bundle和AlipaySDK.framework這兩個就行了,下載的SDK中很容易發現。
快捷支付方法是這個:

-(void)payOrder:(NSString *)orderStr fromScheme:(NSString *)schemeStr callback:(CompletionBlock)completionBlock;

在支付的按鈕中,試用支付寶這個類,再調用這個方法就行啦!如下如:


調用這個方法

在調用支付寶接口的時候,我們需要兩個參數,orderStringAPPScheme, APPScheme是app在info.plist注冊的scheme。
orderstring 這個是一個訂單的字符串,由后台拼接生成的,還需要簽名的。例如:
partner="2088101568358171"&seller_id="xxx@alipay.com"&out_trade_no="0819145412-6177"&subject="測試"&body="測試測試"&total_fee="0.01"&notify_url="http://notify.msp.hk/notify.htm"&service="mobile.securitypay.pay"&payment_type="1"&input_charset="utf-8"&it_bpay="30m"&sign="lBBK%2F0w5LOajrMrji7DUgEqNjIhQbidR13GovA5r3TgIbNqv231yC1NksLdw%2Ba3JnfHXoXuet6XNNHtn7VE%2BeCoRO1O%2BR1KugLrQEZMtG5jmJIe2pbjm%2F3kb%2FuGkpG%2BwYQYI51%2BhA3YBbvZHVQBYveBqK%2Bh8mUyb7GM1HxWs9k4%3D"&sign_type="RSA".

流程就這么簡單,接下來是集成SDK的時間,這部分很坑,因為是我們是商品的數據簽名什么的都在后台做的,所以客戶端做的時候遇到的坑就不多說了,可以參考這篇文章,基本上遇到的坑都能找到。
還有這篇是有人對這個進行的一個簡單的封裝,如果簽名,數據部分需要在APP上做的話,可以直接用這個,封裝很簡單,也是加了個類目進行做出來的,實現很簡單。大家可以參考一下。

支付寶的SDK給了一個處理返回結果的方法,就是那個openURL的那個,在demo的appdelegate里面有。

if ([url.host isEqualToString:@"safepay"]) { [[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) { NSLog(@"result = %@",resultDic); ​ }]; }

關於簽名(主要是在客戶端簽名時候注意的)

支付寶上要用那個RSA,這是個算法,所以為了方便,可以使用第三方的方法,或者找demo上的代碼粘貼上去!不過還是那句話,為了安全,最好還是后台的做,不怕被攔截了 。
簽名的時候,涉及到了RSA公鑰、私鑰的生產,RSA的簽名、驗證簽名,SHA1值的計算,base64和URL編碼等等等等煩人的東西,估計支付的程序猿也不想麻煩,就用了一個開源的代碼來統一解決這些問題,就是openssl這個文件夾。
如果你執意要在客戶端上簽名(前面說過,並不安全),也可以用demo中的openssl這個文件夾,那你需要導入這幾個文件夾:DEMO中的openssl目錄頭文件,兩個庫文件libcrypto.a libssl.a,DEMO里支付寶自己寫的Util目錄,如下圖:


用到的文件

支付寶文檔上的集成流程詳解,寫的很詳細了,一般遇到的問題都有提到。

推薦幾篇好文章,可以參考下,減少點坑(1、4、5務必看看,很有啟發的):
1.集成支付寶錢包支付iOS SDK的方法與經驗
2.IOS集成到支付寶的步驟及問題
3.這個也是遇到的一些問題和解決方法
4.iOS應用之支付寶集成總結
5.iOS 集成支付寶


這篇文章是在客戶端做簽名的,寫的也很詳細


今天又遇到個問題:調起了支付寶客戶端,但是支付不了。


支付失敗

這個是因為,如果訂單來自服務器此錯誤表示后台返回的簽名訂單含有特殊字符 ,需要編碼。
由於RSA簽名機制每次生成的簽名都不一樣,也就是是二進制數,后台返回簽名的訂單時,是基於base64位編碼的 。可能基於base64位編碼生成帶有+=/等在url序列中不被允許的字符。當我們拿着后台不進行特殊字符處理的訂單作為參數去調用支付寶的接口時,便會出現由於支付寶客戶端吊起支付寶服務器是URL有問題,導致錯誤ALI64 。
解決辦法是 讓后台處理一下參數中的特殊字符,具體的這里有示例.



文/WK_IOSDevelpoer(簡書作者)
原文鏈接:http://www.jianshu.com/p/b88f87a552a1
 
 
補充:
 

iOS 移動支付之種類

iOS 端的移動支付,大概包括:支付寶支付、微信支付、銀聯卡支付、paypal支付,現在又多出一個Apple pay支付;

如何集成這些種類的支付方式

談及如何集成這些支付方式,面對各種支付方式的SDK以及Demo寫的詳細的完美無缺,我還真不如還如何去寫,這里我就接地氣的寫寫,寫的不好請勿噴哦☺!

支付寶支付

大致有以下步驟:

1.向支付寶申請, 與支付寶簽約,獲得商戶PID(partner)和賬號ID(seller)和私鑰(privateKey)

注:*這一步,一般公司會搞定的,這里只是讓你知道來龍去脈☺
  沒有支付寶賬號的同學,可以點擊這里注冊賬號
  已經有支付寶賬號的同學點擊這里申請移動支付
申請簽約有個門檻比較難,就是不管你是個人還是企業,都需要營業執照,這點有點蛋疼,不過人家也是為了有質量的管理申請者嘛,可以理解,我這里沒有營業執照,申請工作就死在了搖籃里,不過大致流程,我基本弄清楚了,不過作為開發者,這申請工作就不用多關心了,一般公司都會有申請過的,我這里寫出來也就是讓我們開發者也大概知道流程,而不是直接就是用,只知去向,不知來龍。  
申請簽約成功后,就可以查看 PID(partner)和賬號ID(seller)和私鑰(privateKey) ,查看地址點擊這里 進行登錄,點擊下圖中的查詢PID和Key;
Pay

但是這里查詢到的Key 是公鑰,不是私鑰,你到底該怎么弄私鑰呢?同學們,不用急,支付寶文檔寫的還是比較清楚的,點擊這里可以查看RSA私鑰及公鑰生成

這里文檔給出了兩種平台下的生產方式,我們既然是iOS 開發者,那就選擇Linux用戶生產的方式吧,可以直接在Mac的終端敲這些命令; 啊神支付
敲過這些命令后,會在本地生產兩個文件,分別是私鑰和公鑰文件
在命令行敲入(以行為單位)
$cd ~/
$open . //打開文件的存放位置
想要查看文件內容,還需要使用命令
$cat rsa_private_key.pem //會在終端顯示文件中的內容,這就是私鑰
到這里,第一步基本上就可以了,具體還需要自己動手試試,不然還是會一頭霧水。

2.下載支付寶SDK以及Demo

這一步,沒啥好說的,給個地址就行SDK以及Demo下載地址

3.集成SDK到工程中(生成訂單信息,簽名加密)

支付寶官方集成文檔

集成支付寶SDK的步驟,這里是官方給出的集成文檔, 按照步驟集成總是會出錯,這不是我們腦子不行,而是官方畢竟是官方。
查看支付寶給出的Demo,會發現這些文件必須要加到項目中: 啊神
其中小方框中的為必須加入,而除了小方框以外的,那就要看你們后台人員是否將簽名成功字符串格式化的訂單字符串,給你傳到前端來,如果沒有,那就必須你自己在前端處理; 按理說,這些應該由后台來處理,為了訂單信息的安全,以及前端業務的輕運行,都該有后端來處理(注:這點不懂,不要緊,后面還會根據代碼在進行講解;

集成中可能遇到的錯誤

1)Cannot find interface declaration for ‘NSObject’
啊神
解決方案:a. 可以在報錯的文件中加入#import <Foundation/Foundation.h>
b. 可以建個pch文件加入

`
#ifdef __OBJC__
#import UIKit/UIKit.h
#import Foundation/Foundation.h
#endif
`

 

2)提示找不到 openssl/asn1.h 文件
啊神
解決方案:Build Settings –> Search Paths –> Header Search paths:$(PROJECT_DIR)/ASPayDemo/Alipay
啊神

3)_CNCopyCurrentNetworkInfo,referenced from:
啊神
解決方案:添加SystemConfiguration.framework

啊神

部署代碼



    NSString *partner = @""; //PID

    NSString *seller = @""; //收款賬戶,手機號或者郵箱
   
    NSString*privateKey= @"";// 私鑰
    
    if ([partner length] == 0 ||
        [seller length] == 0 ||
        [privateKey length] == 0)
    {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示"
                                                        message:@"缺少partner或者seller或者私鑰。"
                                                       delegate:self
                                              cancelButtonTitle:@"確定"
                                              otherButtonTitles:nil];
        [alert show];
        return;
    }
    
    Order *order = [[Order alloc] init];
    order.partner = partner;
    order.seller = seller;
    order.tradeNO = @"20160324012412412"; //訂單ID(由商家自行制定)
    order.productName = @"iOS 高級教程"; //商品標題
    order.productDescription = @"這是一本關於iOS的一本高級教程書"; //商品描述
    order.amount = @"0.1"; //商品價格
    order.notifyURL = @"http://www.devashen.com/Notify/Alipay/"; //回調URL
    
    order.service = @"mobile.securitypay.pay";
    order.paymentType = @"1";
    order.inputCharset = @"utf-8";
    order.itBPay = @"30m";
    order.showUrl = @"m.alipay.com";
    
    NSString *appScheme = @"alisdkdemo";
    
    //將商品信息拼接成字符串   該方法支付寶已經封好
    NSString *orderSpec = [order description];
    
    
    //獲取私鑰並將商戶信息簽名,外部商戶可以根據情況存放私鑰和簽名,只需要遵循RSA簽名規范,並將簽名字符串base64編碼和UrlEncode
    id signer = CreateRSADataSigner(privateKey);
    //調用簽名
    NSString *signedString = [signer signString:orderSpec];
    
    
    
    
    //將簽名成功字符串格式化為訂單字符串,請嚴格按照該格式
    NSString *orderString = nil;
    if (signedString != nil) {
        orderString = [NSString stringWithFormat:@"%@&sign=\"%@\"&sign_type=\"%@\"",
                       orderSpec, signedString, @"RSA"];
        
        
        //***************上面提到好的后台,會把訂單字符串直接傳給我們,而我們要做的其實也就只剩下這一步了********************/
        [[AlipaySDK defaultService] payOrder:orderString fromScheme:appScheme callback:^(NSDictionary *resultDic) {
            if ([[resultDic objectForKey:@"resultStatus"] isEqualToString:@"9000"]) {
                //9000為支付成功
                
            }
            
        }];
    }

看代碼,如果后台將簽名成功字符串格式化的訂單字符串,給你傳到前端來,那我們就只需要做很少的工作就可以了,只需要直接處理訂單字符串即可:


        [[AlipaySDK defaultService] payOrder:orderString fromScheme:appScheme callback:^(NSDictionary *resultDic) {
            if ([[resultDic objectForKey:@"resultStatus"] isEqualToString:@"9000"]) {
                //9000為支付成功
                
            }
            
        }];

最后,千萬別忘了,在Appdelegate中,處理支付寶客戶端返回url處理方法, 少了這一步,支付寶SDK的回調方法是不會執行的:


- (BOOL)application:(UIApplication *)application
            openURL:(NSURL *)url
  sourceApplication:(NSString *)sourceApplication
         annotation:(id)annotation {
   //跳轉支付寶錢包進行支付,處理支付結果
        [[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) {
            NSLog(@"result = %@",resultDic);
        }];
    return YES;
}

到這里,支付寶支付基本上完成, 迫不及待的你,趕緊去試驗試驗吧, 別忘了給你們相關負責人要對應的PID、收款賬號、以及私鑰,當然如果后台直接傳給你訂單字符串的話,你可以直接給后台要接口了,置於PID什么的你就不用管了。

相關連接

本文章對應的Demo, 包含后端是、否給你訂單字符串的兩種處理

支付寶移動支付SDK官方文檔


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM