iOS開發之支付寶集成

 

項目中要用到支付功能,須要支付寶,微信,銀聯三大支付,因此打算總結一下,寫兩篇文章,方便之後的查閱, 你們在作的時候也能稍微參考下,用到的地方避免再次被坑。這是第二篇支付寶集成,第一篇銀聯支付在這裏。原本要用那個ping++的神器,能夠集成各類支付手段,異常的方便,可是考慮到安全性問題的話,支付的渠道仍是不讓第三方參與的好,否則會不安全,因而就苦逼地慢慢的一個一個集成了。。。。這裏就代理支付寶的集成過程:html

 

剛開始覺得支付寶集成仍是比較簡單的,看了幾個文章,網上的各位大神也是各類秀操做,說集成很簡單,可是,真正作起來就不是那回事了, 特別是新版的1月11號更新的,我正好是這一天開始看的,網上的經驗什麼的 大都是比較老的,比較新的能用到的文章很少(可是好文章仍是有的,對我幫助也很大),如今我就來一步一步說一下本身集成支付寶的血淚史!前端

下載支付寶SDK

首先是開發包下載,仍是比較難發現的,網上之前文章中的連接都打不開,我找了很久才找到的。最新的地址在這裏(注意的是下載出來的SDK包裏面並無傳說中的開發文檔,須要其餘地方找或者看網頁上的)。
公鑰、私鑰、PID、sellerID、key這些東西的用途和獲取方式在文檔上都有詳細的說明,這裏再也不贅述,必定要把概念分清楚再去作,否則一會就亂了。若是遇到問題的話我們能夠再一塊兒探討。git

支付流程理解

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


交互流程


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

到這裏就完成了支付的過程了。我以爲這個流程仍是很容易理解的。
其中我們就是商戶客戶端須要作的就是:
• 調用支付寶支付接口
• 處理支付寶返回的支付結果
支付寶文檔上的應用範例:算法

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目錄,以下圖:


用到的文件

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

推薦幾篇好文章,能夠參考下,減小點坑(一、四、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官方文檔

相關文章
相關標籤/搜索