下載
首先,你要想找到這個SDK,都得費點功夫。如今的SDK改名叫移動支付集成開發包了,下載頁面在 這里 的 “請點此下載集成開發包”
Baidu和Googlep排在前面的支付寶開放平台,里面的SDK已經是2年前的版本號了,並且還不支持64位架構。
文檔
壓縮包里有兩個相關文檔 :
《支付寶錢包支付接口開發包2.0標准版.pdf》
《支付寶錢包支付接口開發包2.0標准版接入與使用規則.pdf》
iOS相關內容能夠主要看第一個文檔,第二個文檔名字和里面寫的不一樣。內容事實上是個附錄;文檔里面多個平台都涉及到了。內容有些雜亂。
以下先解釋下總體SDK的流程和要做的事,就好對症下葯找文檔內對應的內容了。
流程
摘自第一個文檔《支付寶錢包支付接口開發包2.0標准版.pdf》

圖中的“商戶client”就是我們的iOSclient須要做的事情:
- 調用支付寶支付接口
- 處理支付寶返回的支付結果
在調用支付寶支付接口前,我們還須要先生成一個訂單。文檔中描寫敘述時,是將這步也放在client來做了,但也能夠在server端生成這個訂單(圖中支付寶會在支付成功后通知server端,所以在server端生成訂單的話,你能夠掌握全部訂單。並且也會更安全):
- 生成訂單(能夠在iOSclient內生成,也能夠在server端生成)
- 調用支付寶支付接口,發送訂單
- 處理支付寶返回的支付結果
事實上對於業務來說,這些步驟已經夠了,可是有一個安全性問題。你肯定不希望你接收到的支付結果被截獲改動,所以。這就須要在生成訂單和處理支付結果的時候做一個安全性校驗:
生成訂單時對數據簽名,收到支付結果時對數據進行簽名驗證。以檢驗數據是否被篡改過。
支付寶眼下僅僅支持採用RSA加密方式做簽名驗證。
RSA加密算法 除了可加解密外,還可用來作簽名校驗。
簡單的說,RSA會生成一個私鑰和一個公鑰,私鑰你應該獨自保管,公鑰你能夠分發出去。
做簽名驗證時。你能夠用私鑰對須要傳輸的數據做簽名加密,生成一個簽名值。之后分發數據,接收方通過公鑰對簽名值做校驗,假設一致則覺得數據無篡改。
詳細到支付寶使用RSA做簽名驗證,就是在生產訂單時,須要使用私鑰生成簽名值;在處理返回的支付結果時,須要使用公鑰驗證返回結果是否被篡改了。
詳細須要對哪些值,如何生成簽名。對哪些值最簽名驗證,能夠在第一個文檔中找找,后面我會簡單提一下,但還是以文檔或實踐為准吧。
集成
清楚了流程后,就好理解怎么集成了。
支付SDK
假設僅僅須要發送訂單和處理支付返回結果,僅僅須要加入AlipaySDK.bundle
和AlipaySDK.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里沒相應信息,第一個文檔里有提到:
-
- 9000 訂單支付成功
- 8000 正在處理中
- 4000 訂單支付失敗
- 6001 用戶中途取消
- 6002 網絡連接出錯
- memo, 提示信息。比方狀態碼為6001時。memo就是“用戶中途取消”。但千萬別全然依賴這個信息,假設未安裝支付寶app。採用網頁支付時。取消時狀態碼是6001,但這個memo是空的。
。
(當我發現這個問題的時候。我就決定,對於這么不靠譜的SDK。還是盡量靠自己吧。。)
- result。訂單信息,以及簽名驗證信息。假設你不想做簽名驗證,那這個字段能夠忽略了。。
假設你對支付的安全性不那么在意或重視的話。到這里就能夠完畢支付寶的集成了。
假設想更加安全。還是須要添加以下的簽名驗證的。
簽名驗證
首先,RSA僅僅是一種算法。所以你能夠使用不論什么一種開源的、或者自己去實現這個算法來實現簽名和驗證的目的。
在整個流程其中。由於涉及到了RSA公鑰、私鑰的生產,RSA的簽名、驗證簽名。SHA1值的計算,base64和URL編碼。所以支付寶用了一個開源的代碼來統一解決這些問題,就是openssl(順便再吐槽下,這DEMO里一放openssl
。不知道又會引來多少公司的產品里使用openssl
了,預計阿里自己也沒少用,什么時候都能跟老羅、華為一樣去贊助點呢。。)
假設你想省事。也用openssl
,那你須要把這些東西都增加到項目中:DEMO中的openssl文件夾
頭文件,兩個庫文件libcrypto.a libssl.a
,DEMO里支付寶自己寫的Util文件夾
訂單簽名
上面說了。訂單簽名應該用私鑰,可是把私鑰放到app里事實上本身就不安全,由於你的app是分發到用戶手里的,私鑰應該放在自己的手里。分發出去的應該是公鑰。
所以私鑰最好是放在自己的server上。訂單加密這個工作放在server端來做,server將包括簽名的訂單信息返回給app,app再通過SDK發送給支付寶,這樣會更安全些;並且server也能掌握全部的訂單狀況。
假設你非要將私鑰集成到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"¬ify_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
讀取出來使用。。
。