關於集成支付寶SDK的開發

下載

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

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

文檔

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

流程

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


業務流程圖

圖中的“商戶客戶端”就是我們的iOS客戶端需要做的事情:

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

在調用支付寶支付接口前,我們還需要先生成一個訂單,文檔中描述時,是將這步也放在客戶端來做了,但也可以在服務器端生成這個訂單(圖中支付寶會在支付成功後通知服務器端,所以在服務器端生成訂單的話,你可以掌握所有訂單,而且也會更安全):

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

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

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

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

集成

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

支付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裏沒對應信息,第一個文檔裏有提到:
    • 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是分發到用戶手裏的,私鑰應該放在自己的手裏,分發出去的應該是公鑰。
所以私鑰最好是放在自己的服務器上,訂單加密這個工作放在服務器端來做,服務器將包含簽名的訂單信息返回給app,app再通過SDK發送給支付寶,這樣會更安全些;而且服務器也能掌握所有的訂單狀況。

如果你非要將私鑰集成到app裏,那可以參考SDK的DEMO,因爲這個DEMO就是在app本地通過私鑰做的訂單簽名。。

支付結果簽名驗證

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

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

partner="2088101568358171"&seller_id="[email protected]"&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了。。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章