ios使用支付寶進行支付,注意事項& 集成支付寶錢包支付iOS SDK的方法與經驗。

 

下載

首先,你要想找到這個SDK,都得費點功夫。如今的SDK更名叫移動支付集成開發包了,下載頁面在 這裏 的 「請點此下載集成開發包css

Baidu和Googlep排在前面的支付寶開放平臺,裏面的SDK已是2年前的版本了,並且還不支持64位架構。html

文檔

壓縮包裏有兩個相關文檔 :
《支付寶錢包支付接口開發包2.0標準版.pdf》
《支付寶錢包支付接口開發包2.0標準版接入與使用規則.pdf》
iOS相關內容能夠主要看第一個文檔,第二個文檔名字和裏面寫的不同,內容實際上是個附錄;文檔裏面多個平臺都涉及到了,內容有些雜亂。下面先解釋下總體SDK的流程和要作的事,就好對症下藥找文檔內相應的內容了。ios

流程

摘自第一個文檔《支付寶錢包支付接口開發包2.0標準版.pdf》c++

業務流程圖
業務流程圖

圖中的「商戶客戶端」就是咱們的iOS客戶端須要作的事情:web

  • 調用支付寶支付接口
  • 處理支付寶返回的支付結果

在調用支付寶支付接口前,咱們還須要先生成一個訂單,文檔中描述時,是將這步也放在客戶端來作了,但也能夠在服務器端生成這個訂單(圖中支付寶會在支付成功後通知服務器端,因此在服務器端生成訂單的話,你能夠掌握全部訂單,並且也會更安全):算法

  • 生成訂單(能夠在iOS客戶端內生成,也能夠在服務器端生成)
  • 調用支付寶支付接口,發送訂單
  • 處理支付寶返回的支付結果

其實對於業務來講,這些步驟已經夠了,可是有一個安全性問題,你確定不但願你接收到的支付結果被截獲修改,因此,這就須要在生成訂單和處理支付結果的時候作一個安全性校驗:
生成訂單時對數據簽名,收到支付結果時對數據進行簽名驗證,以檢驗數據是否被篡改過。
支付寶目前只支持採用RSA加密方式作簽名驗證。api

RSA加密算法 除了可加解密外,還可用來做簽名校驗。
簡單的說,RSA會生成一個私鑰和一個公鑰,私鑰你應該獨自保管,公鑰你能夠分發出去。
作簽名驗證時,你能夠用私鑰對須要傳輸的數據作簽名加密,生成一個簽名值,以後分發數據,接收方經過公鑰對簽名值作校驗,若是一致則認爲數據無篡改。安全

具體到支付寶使用RSA作簽名驗證,就是在生產訂單時,須要使用私鑰生成簽名值;在處理返回的支付結果時,須要使用公鑰驗證返回結果是否被篡改了。
具體須要對哪些值,怎樣生成簽名,對哪些值最簽名驗證,能夠在第一個文檔中找找,後面我會簡單提一下,但仍是以文檔或實踐爲準吧。bash

集成

清楚了流程後,就好理解怎麼集成了。服務器

支付SDK

若是隻須要發送訂單和處理支付返回結果,只須要添加AlipaySDK.bundleAlipaySDK.framework就好了。

這裏再吐槽下,以前用的舊版本,和如今的版本相比,還不光是把類名字給改了,原先是用的類方法,如今新版又給改爲了單例了。。還真是任性啊,這要是哪家小廠的SDK,估計早被棄用了把。。

發送訂單的方法:

- (void)payOrder:(NSString *)orderStr fromScheme:(NSString *)schemeStr callback:(CompletionBlock)completionBlock;
  • 若是手機內沒安裝支付寶的app,會直接展示支付寶web支付界面,經過callback返回支付結果;
  • 若是手機內安裝了支付寶的app,會跳轉到支付寶的app支付,而後經過openURL的回調返回支付結果。

支付寶的SDK只給了一個處理返回結果的方法,而不像其餘第三方的SDK提供一個處理openURL的方法,因此你須要經過DEMO或者在第二個文檔裏找處處理openURL的方式:

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

SDK也提供了一個處理openURL返回結果的方法

- (void)processOrderWithPaymentResult:(NSURL *)resultUrl standbyCallback:(CompletionBlock)completionBlock;

兩個回調block都統必定義爲typedef void(^CompletionBlock)(NSDictionary *resultDic);
返回了一個字典,可是SDK裏徹底沒有提示有哪些key。。
你能夠在文檔裏找到,或者本身實際試一下,返回的信息以下:

  • resultStatus,狀態碼,SDK裏沒對應信息,第一個文檔裏有提到:memo, 提示信息,好比狀態碼爲6001時,memo就是「用戶中途取消」。但千萬別徹底依賴這個信息,若是未安裝支付寶app,採用網頁支付時,取消時狀態碼是6001,但這個memo是空的。。(當我發現這個問題的時候,我就決定,對於這麼不靠譜的SDK,仍是儘可能靠本身吧。。)
    • 9000 訂單支付成功
    • 8000 正在處理中
    • 4000 訂單支付失敗
    • 6001 用戶中途取消
    • 6002 網絡鏈接出錯
  • result,訂單信息,以及簽名驗證信息。若是你不想作簽名驗證,那這個字段能夠忽略了。。

若是你對支付的安全性不那麼在乎或重視的話,到這裏就能夠完成支付寶的集成了。
若是想更加安全,仍是須要增長下面的簽名驗證的。

簽名驗證

首先,RSA只是一種算法,因此你可使用任何一種開源的、或者本身去實現這個算法來實現簽名和驗證的目的。

在整個流程當中,由於涉及到了RSA公鑰、私鑰的生產,RSA的簽名、驗證簽名,SHA1值的計算,base64和URL編碼,因此支付寶用了一個開源的代碼來統一解決這些問題,就是openssl(順便再吐槽下,這DEMO裏一放openssl,不知道又會引來多少公司的產品裏使用openssl了,估計阿里本身也沒少用,何時都能跟老羅、華爲同樣去贊助點呢。。)

若是你想省事,也用openssl,那你須要把這些東西都加入到項目中:DEMO中的openssl目錄頭文件,兩個庫文件libcrypto.a libssl.a,DEMO裏支付寶本身寫的Util目錄

訂單簽名

上面說了,訂單簽名應該用私鑰,可是把私鑰放到app裏其實自己就不安全,由於你的app是分發到用戶手裏的,私鑰應該放在本身的手裏,分發出去的應該是公鑰。
因此私鑰最好是放在本身的服務器上,訂單加密這個工做放在服務器端來作,服務器將包含簽名的訂單信息返回給app,app再經過SDK發送給支付寶,這樣會更安全些;並且服務器也能掌握全部的訂單情況。

若是你非要將私鑰集成到app裏,那能夠參考SDK的DEMO,由於這個DEMO就是在app本地經過私鑰作的訂單簽名。。

支付結果簽名驗證

上面的回調block提到了返回的內容,返回的支付結果中的result字段裏是帶有訂單信息和簽名信息的,因此簽名驗證就是須要這個字段的值。

文檔中有一個這個字段的例子,實際結果沒有換行,我換一下行便於閱讀:

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_b_pay="30m"&success="true" &sign_type="RSA" &sign="hkFZr+zE9499nuqDNLZEF7W75RFFPsly876QuRSeN8WMaUgcdR00IKy5ZyBJ4eldhoJ/2zghqrD4E2G2mNjs3aE+HCLiBXrPDNdLKCZ gSOIqmv46TfPTEqopYfhs+o5fZzXxt34fwdrzN4mX6S13cr3UwmEV4L3Ffir/02RBVtU="

總共分爲三個部分

  • 第一部分是訂單信息,每一個字段的具體含義能夠在文檔裏找;
  • 中間sign_type是簽名用的算法,文檔裏說了,目前只支持RSA;
  • 最後的sign就是簽名值。

驗證的步驟以下:

  • 首先把訂單信息和簽名值分別提取出來(SDK竟然都不給處理好。。)
    • 訂單信息就是sign_type的連字符&以前的全部字符串
    • 簽名值是sign後面雙引號內的內容,注意簽名的結尾也是=,因此不要用split字符串的方式提取
  • 若是你想簡單,能夠直接使用Util目錄下的DataVerifier來做簽名驗證
    • - (BOOL)verifyString:(NSString *)string withSign:(NSString *)signString;
    • 第一個參數就是訂單信息,第二個參數就是簽名值。

其實不使用openssl,用其餘第三方RSA的開源代碼也是能夠的。能夠看下DEMO裏openssl_wrapper的源碼和SDK的文檔。

  • 對於訂單信息,先作一個base64編碼(DEMO中這個還要調openssl來實現。。),再計算SHA1的值(這個也能夠徹底不用openssl,蘋果的庫中都有的。。),而後再簽名比對。
  • 對於公鑰,若是使用其餘第三方代碼,須要注意格式問題。支付寶的DEMO實現中,是把這個公鑰又轉回成openssl生成的本地文件格式,而後再寫入本地文件,再讓openssl讀取出來使用。。

以上,就是支付寶 iOS SDK的一些介紹。
整體來講,我以爲能靠本身處理的地方仍是儘可能不要依賴這個不太靠譜的SDK了。。

http://www.sxt.cn/u/4647/blog/5554 這個大神寫的問題比較不錯我也很受啓發 能夠看看。比較實用

問題一大堆: 比較重要 。不少時候都遇到這些問題 我也是找了很久的資料和論壇。

在進行ios集成支付寶的問題上,坑了很久,主要是兩個地方折騰了很久,

一、首先是search paths中Header Search paths 設置問題,粘一下別人的圖片 本身不會弄,我是直接把這個包拉到路徑上 跟他有點不同 不過也能用 。誰的好用用誰的,反正能用就行。    點擊項目名稱,點擊「Build Settings」選項卡,在搜索框中,以關鍵字「search」 搜索,對「Header Search Paths」增長頭文件路徑:「$(SRCROOT)/項目名稱/IntegratedAlipay/AlipayFiles」(注意:不包括引號,若是不是放到項目根目錄下,請在項目名稱後面加上相應的目錄名),能夠查看下面的動態圖片;

        

wKiom1Sw41_TJY_vABUvhnerrC0018.gif

 

 

搜索網上的資料,發現都是在這一項添加$(SRCROOT)/xxx/openssl這條路徑,可是發現依然提示"'openssl/asn1.h' file not found",最終查閱衆多資料發現,緣由是include <> ""的緣由,<> ""能夠簡單參考這個網址http://blog.chinaunix.net/uid-23922099-id-3586571.html,那麼解決這條錯誤方法就是將"$(SRCROOT)/xxx/openssl"替換成"$(SRCROOT)/xxx/",再次編譯,"openssl/asn1.h' file not found"這條錯誤已經沒有了

2、在沒有添加對正確的依賴庫,編譯應該會有這樣的"Undefined symbols for architecture x86_64:"的錯誤,那麼就須要在build phases->Link Binary With Libraries 添加以下四個library, "CoreMotion.framework"、"CoreTelephony.framework"、"libc++.tbd"、"libz.tbd",添加完以後而且在1中的問題解決的狀況下,能夠成功編譯;不然,請查看支付寶提供的四個文件是否已經正確添加,"AlipaySDK.bundle"、"AlipaySDK.framework"、"libcrypto.a"、"libssl.a",

順帶吐槽一下支付寶開發平臺中對於ios集成的開發文檔真夠能夠的,在解決第2個問題的時候,原本打算查看官方的集成文檔是否列出了,必須的依賴庫,找了很久,最後仍是沒有找到;最後實在沒辦法,對照支付寶的demo中的依賴庫,一個個對比,最後發現第2個問題中列舉的四個必須library。

相關文章
相關標籤/搜索