IOS開發支付寶集成

開發準備


1.首先新建項目,而後去官網下載最新的開發包:
http://doc.open.alipay.com/doc2/detail?treeId=59&articleId=103563&docType=1,
固然也能夠用CocoaPods來下載不過用這個下載的話只會下載到單純的客戶端與網絡服務請求的SDK不包含加密的那些代碼,而有些公司是要把加密作到本地的因此選擇哪一種方式看開發者的習慣於公司需求.
2.下載後打開點擊開發包能夠打開更新日誌來比對當前版本不要去一些非官網的地方下載SDK有可能不是最新版本會出現BUG
3.打開客戶端開發包找到IOS對應的包文件解壓獲得開發包,包含1個framework文件一個bundle文件一個Demo文件夾swift

通常狀況下支付功能的交互流程


好比咱們去某個APP去支付一個產品,流程爲:
1.用戶點擊支付->
2.客戶端請求服務器用戶支付->
3.服務器接收請求生成金額訂單等要給第三方支付的一切信息,並生成回調參數傳給客戶端->
4.客戶端接收信息(通常會再讓用戶確認支付或者乾脆購買後是生成訂單,而後纔是付款)並將服務器給的信息分別傳入SDK須要的參數中,調用SDK的支付方法->
5.由SDK向SDK本身的服務器發出支付請求,SDK本身的服務器接收支付請求處理成功後,給客戶端自己與公司的後臺都發送一條支付成功的消息,客戶端與後臺根據這條消息再作處理.服務器

針對開發環境的一些設置


支付又分爲2種狀況本地簽名,和服務器簽名,我用到正好都是公司要求本地籤,服務器的我就稍微說1點.網絡

服務器簽名:
/**
 *  支付接口
 *
 *  @param orderStr       訂單信息
 *  @param schemeStr      調用支付的app註冊在info.plist中的scheme
 *  @param compltionBlock 支付結果回調Block
 */
- (void)payOrder:(NSString *)orderStr
      fromScheme:(NSString *)schemeStr
        callback:(CompletionBlock)completionBlock;

服務器簽名注意的是在callback:回調中要進行驗籤,就是把服務器給的訂單簽名信息在用公鑰解密,比對訂單細節,檢查是否被他人篡改,而且若是是wap支付,不會反回在appDelegateapplication:openURL方法.app

本地簽名:

先拖入實現加密的文件與模型:框架


加密的文件.png

這時候會報錯(補充一點: 有些朋友找不到NSString或者一些數據類型報錯都是由於缺乏Foundation頭文件,可能我寫的不太明白,有些朋友仍是不太懂)大部分錯誤都是由於一些文件中在支付寶的Demo的Pch文件中統一添加的#import <Foundation/Foundation.h>,若是咱們的項目中沒有這一步,那麼要麼也創建pch要麼單獨添加上.工具

這時還會有一個錯誤:測試

路徑找不到.png

注意這裏的Header Search Paths 路徑爲空:編碼

路徑爲空.png

打開電腦這個文件的所在地 雙擊Header Search Paths將電腦的文件拖入Header Search Paths會生成一個路徑:加密

生成的路徑.png

導入一來框架: 這個最好跟着Demo一個一個往裏添加,也不要光看網上資料主要仍是看Demo:url

導入框架.png


添加SDK和靜態庫:

SDK靜態庫.png

報錯:這個錯誤與另一種說SDK不支持64位比較常見,都是把靜態庫或者SDK都刪了從新導入就好了

錯誤信息.png
到這裏應該已經能夠運行程序了.
若是仍是出現了編譯錯誤等問題,導入框架不全與SDK靜態庫的路徑錯誤比例比較大.
建議等可以運行程序後在進行開發.

正式開發

首先咱們介紹一段代碼:

  NSString *orderSpec = [order description];

將商品的信息添加爲字符串order是一個對象,而description]是將這個對象的屬性進行拼接返回一個字符串.

在介紹3個屬性:

//合做商戶ID。用簽約支付寶帳號登陸ms.alipay.com後,在帳戶信息頁面獲取。
NSString *partner = @"";
//帳戶ID。用簽約支付寶帳號登陸ms.alipay.com後,在帳戶信息頁面獲取。
NSString *seller = @"";
//商戶私鑰,自助生成
NSString *privateKey = @"";

這3個屬性必須是我的或公司申請後才能獲得的..我用的公司的就不寫上了請自行填寫.

//將商品信息賦予AlixPayOrder的成員變量
    Order *order = [[Order alloc] init];
    order.partner = partner;
    order.seller = seller;
    order.tradeNO = @"G111111111111"; //訂單ID(由商家自行制定)
    order.productName = @"個人測試"; //商品標題
    order.productDescription = @"個人商品描述"; //商品描述
    order.amount = @"0.01"; //商品價格
    order.notifyURL =  @"http://www.xxx.com"; //回調URL

    order.service = @"mobile.securitypay.pay";
    order.paymentType = @"1";
    order.inputCharset = @"utf-8";
    order.itBPay = @"30m";
    order.showUrl = @"m.alipay.com";

    //應用註冊scheme,在AlixPayDemo-Info.plist定義URL types
    NSString *appScheme = @"alisdkdemo";

    //將商品信息拼接成字符串
    NSString *orderSpec = [order description];
    NSLog(@"orderSpec = %@",orderSpec);

    //獲取私鑰並將商戶信息簽名,外部商戶能夠根據狀況存放私鑰和簽名,只須要遵循RSA簽名規範,並將簽名字符串base64編碼和UrlEncode
    id<DataSigner> signer = CreateRSADataSigner(privateKey);
    NSString *signedString = [signer signString:orderSpec];


    NSString *orderString = nil;

生成加密後的字符串 注意的是

NSString *appScheme = @"alisdkdemo";

這個值是從支付寶的商戶地址中填寫的,請保持一致.

最後處理結果:

if (signedString != nil) {
        orderString = [NSString stringWithFormat:@"%@&sign=\"%@\"&sign_type=\"%@\"",
                       orderSpec, signedString, @"RSA"];

        [[AlipaySDK defaultService] payOrder:orderString fromScheme:appScheme callback:^(NSDictionary *resultDic) {

            //結果處理,其實就是取字典裏面的內容,這個取字符串而後變個模型就行了 或者直接取不便模型,方法不少.
            NSLog(@"開始確認支付狀態 %@",resultDic[@"resultStatus"]);
            AlixPayResult* resultModel = [AlixPayResult itemWithDictory:resultDic];
            if (resultModel)
            {
                //狀態返回9000爲成功
                if (resultModel.statusCode == 9000)
                {
                    /*
                     *用公鑰驗證簽名 嚴格驗證請使用result.resultString與result.signString驗籤
                     */
                    NSLog(@"支付寶交易成功");

                    /*
                     *用公鑰驗證簽名 嚴格驗證請使用result.resultString與result.signString驗籤
                     */

                    //交易成功
                    NSString* key = AlipayPubKey;//簽約賬戶後獲取到的支付寶公鑰
                    id<DataVerifier> verifier;
                    verifier = CreateRSADataVerifier(key);

                    // 驗證簽名
                    if ([verifier verifyString:resultModel.resultString withSign:resultModel.signString])
                    {
                        //驗證簽名成功,交易結果無篡改
                        NSLog(@"驗證成功");
                    }
                }
            }
            else if([resultDic[@"resultStatus"]isEqualToString:@"6001"])
            {
                               //用戶取消
                NSLog(@"用戶主動取消支付");
            }else
            {

            }
        }];
}

這裏注意:if([resultDic[@"resultStatus"]isEqualToString:@"6001"])支付寶有BUG 這個6001 不要信,能夠和公司商量下,是加個確認接口仍是必定時間內檢查後臺,總之頗有可能用戶付錢成功,SDK通知你用戶手動取消,這個BUG是在弱網狀態下比較多.

而後記得在 AppDelegate裏面加上以下代碼:

//只要是調用手機上的支付寶客戶端,在支付寶客戶端操做完成返回本身的app時,都會調用這個方法,
- (BOOL)application:(UIApplication *)application
            openURL:(NSURL *)url
  sourceApplication:(NSString *)sourceApplication
         annotation:(id)annotation {
    //跳轉支付寶錢包進行支付,須要將支付寶錢包的支付結果回傳給SDK(這個是將支付寶客戶端的支付結果傳回給SDK)
    if ([url.host isEqualToString:@"safepay"]) {
        [[AlipaySDK defaultService]
         processOrderWithPaymentResult:url
         standbyCallback:^(NSDictionary *resultDic)
         {
             NSLog(@" ------result = %@",resultDic);//返回的支付結果
         }];
    }
    return YES;
}

 

最後記得把這裏寫了:

URL.Types.png

NSString *appScheme = @"alisdkdemo"代碼 網頁上申請的 圖片上那裏填寫的保持一致.


補充: 若是要用swift來調用支付寶SDK 最好把支付的與回調的邏輯單獨創建工具類傳遞數據便好,從流程上自己無太大區別稍微注意的是在swiftAlipaySDK.h有可能由於語言環境問題出現缺乏引入類的狀況,少什麼補什麼就好,其餘也同樣.



文/曾迦(簡書做者) 原文連接:http://www.jianshu.com/p/2b9bbfcb7ec4 著做權歸做者全部,轉載請聯繫做者得到受權,並標註「簡書做者」。
相關文章
相關標籤/搜索