IOS開發支付寶集成

jopen 8年前發布 | 58K 次閱讀 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文件夾

一般情況下支付功能的交互流程


比如我們去某個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方法.

本地簽名:

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


加密的文件.png

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

這時還會有一個錯誤:


路徑找不到.png

注意這里的Header Search Paths 路徑為空:


路徑為空.png

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


生成的路徑.png

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


導入框架.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

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!