iOS接入支付寶支付(小白都能看懂的支付寶支付)

因?yàn)榻陧?xiàng)目中需要接入支付寶支付功能妖碉,自己也爬了很多的坑忽肛,所以做了一下這邊文章供大家學(xué)習(xí)參考,遠(yuǎn)離爬坑损敷,文章主要講到以下五部分:


一葫笼、支付寶開(kāi)放平臺(tái)創(chuàng)建應(yīng)用

二、簽約移動(dòng)支付功能

三拗馒、接入支付前的準(zhǔn)備工作附準(zhǔn)備工作中遇到難題的解決方法

四路星、配置官方Demo附BUG解決方法

五、集成項(xiàng)目诱桂,具體代碼編寫洋丐、


本文為本人學(xué)習(xí)記錄筆記,如需轉(zhuǎn)載挥等,請(qǐng)注明出處@iOSlyon


支付寶開(kāi)放平臺(tái)創(chuàng)建應(yīng)用 登錄支付寶開(kāi)放平臺(tái)

管理中心創(chuàng)建應(yīng)用

1. 應(yīng)用創(chuàng)建完成后點(diǎn)擊查看我的應(yīng)用詳情進(jìn)行移動(dòng)支付功能的簽約
或者
2.進(jìn)入支付寶商家服務(wù)頁(yè)面"https://b.alipay.com/newIndex.htm"選擇移動(dòng)支付功能進(jìn)行簽約


簽約過(guò)程以下以簽約移動(dòng)支付功能為例子

商戶簽約審核簽約審核具體步驟請(qǐng)參見(jiàn)支付寶官方文檔簽約與審核
或者
??????? 下列圖示

  • 填寫簽約信息


    填寫簽約信息

上圖的附件文檔因?yàn)橛写挝臋n錯(cuò)誤導(dǎo)致審核不通過(guò)友绝,所以以下貼出審核成功的文檔供大家參考

Paste_Image.png

上述簽約步驟審核通過(guò)之后就可以開(kāi)始集成工作了


接入前準(zhǔn)備工作

第一步、商戶密鑰管理密鑰作用

2.1.生成步驟
2.2.上傳步驟

這個(gè)步驟完全可以看官方文檔中的操作肝劲,官方文檔寫得很詳細(xì)迁客,但是其中有幾點(diǎn)需要說(shuō)明:

一郭宝、說(shuō)明問(wèn)題
上傳密鑰步驟不知道怎么上傳?因?yàn)槊荑€是pem文件哲泊,但是上傳的是字符串文本剩蟀。
一、解決方法
將生成的pem文件復(fù)制一份到桌面切威,改成Txt文件打開(kāi)即可獲取我們需要的字符串育特,記住當(dāng)我們引用這兩個(gè)長(zhǎng)的字符串時(shí),字符串不能包括先朦,換行缰冤,空格,以及其他誤加的字符喳魏,所以復(fù)制的時(shí)候一定要小心棉浸。

二、說(shuō)明問(wèn)題
Mac 自帶openssl環(huán)境刺彩,不用安裝迷郑,直接終端輸入openssl就可以。


配置官方Demo代碼部分下載Demo

支付寶官方Demo中需要配置商戶的資料(如下)

//開(kāi)放平臺(tái)登錄https://openhome.alipay.com/platform/appManage.htm
//管理中心獲取APPID
#define MXAlipayAPPID       @"請(qǐng)配置你的AppID"
//支付寶私鑰(用戶自主生成创倔,使用pkcs8格式的私鑰)
#define MXAlipayPrivateKey  @"請(qǐng)配置你的支付寶pkcs8私鑰"
 
配置以上數(shù)據(jù)后嗡害,真機(jī)編譯,遇到以下問(wèn)題
  • 輸出錯(cuò)誤信息如配置信息中的私鑰(即上述PartnerPrivKey)使用的不適pkcs8的私鑰的話畦攘,則會(huì)報(bào)以下錯(cuò)誤
rsa_private read error : private key is NULL
  • 解決方法:
  • 方法一將私鑰轉(zhuǎn)成PKCS8替換一下原私鑰即可轉(zhuǎn)換方法如下
    ( PHP服務(wù)端語(yǔ)言讀取私鑰不需要PKCS8轉(zhuǎn)換)
OpenSSL> genrsa -out rsa_private_key.pem   1024  #生成私鑰
OpenSSL> pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt -out rsa_private_key_pkcs8.pem #Java開(kāi)發(fā)者需要將私鑰轉(zhuǎn)換成PKCS8格式
OpenSSL> rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem #生成公鑰
OpenSSL> exit #退出OpenSSL程序
  • 方法二檢查PID是否寫正確
接下來(lái)重新運(yùn)行霸妹,上述錯(cuò)誤已經(jīng)解決,但遇到新問(wèn)題如下圖
  • 彈框顯示


  • 解決方法: 可參考百度中查到的結(jié)果上述問(wèn)題解決方法

    • 問(wèn)題源頭是因?yàn)樗借€跟商戶上傳的公鑰不匹配

處理完上述問(wèn)題之后,就可以進(jìn)行支付操作了


測(cè)試Demo具體操作

1.創(chuàng)建一個(gè)AlipayDemoTest項(xiàng)目
2.新建一個(gè)AliSDK文件夾知押,提取SDK包中以下文件到此文件夾里叹螟,

支付寶所需導(dǎo)入SDK文件

3.編譯項(xiàng)目,會(huì)出現(xiàn)以下問(wèn)題:

1)"Unknown type name ‘NSString‘ "或"Unknown type name ‘NSData‘ "

報(bào)錯(cuò)信息

這是因?yàn)槿鄙貴oundation類庫(kù)和UIKit類庫(kù)台盯,支付寶Demo中之所以沒(méi)有出現(xiàn)此錯(cuò)誤罢绽,是因?yàn)樵?pch文件中導(dǎo)入過(guò)這些類庫(kù)

解決辦法:只需要在出現(xiàn)錯(cuò)誤的文件中導(dǎo)入這些類庫(kù)即可

導(dǎo)入庫(kù)

2)‘openssl/asn1.h‘ file not found

報(bào)錯(cuò)信息

這是openssl文件夾頭文件鏈接問(wèn)題,如果openssl文件夾隨意拉進(jìn)項(xiàng)目中静盅,即使添加頭文件鏈接有缆,也可能解決不了此問(wèn)題,

這也是一開(kāi)始就將所需要的文件放到一個(gè)新建文件夾中再添加到項(xiàng)目中的原因温亲。

解決辦法:
Targets->Build Settings->Header Search Path中添加AliPaySDK文件夾的路徑


4.編譯項(xiàng)目棚壁,會(huì)出現(xiàn)以下問(wèn)題:

Paste_Image.png

解決方法:在xcode中,點(diǎn)擊項(xiàng)目名栈虚,選擇"target"->"Link Binary With Libraries"添加依賴庫(kù)袖外。

Paste_Image.png
編輯程序,已經(jīng)可以成功編譯了魂务,接下來(lái)就是集成代碼了

#import "AppDelegate.h"
#import <AlipaySDK/AlipaySDK.h>
@interface AppDelegate ()

@end

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    return YES;
}

- (BOOL)application:(UIApplication *)application
            openURL:(NSURL *)url
  sourceApplication:(NSString *)sourceApplication
         annotation:(id)annotation
{
    
    if ([url.host isEqualToString:@"safepay"]) {
        //跳轉(zhuǎn)支付寶錢包進(jìn)行支付曼验,處理支付結(jié)果
        [[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) {
            NSLog(@"result = %@",resultDic);
        }];
    }
    return YES;
}

// NOTE: 9.0以后使用新API接口
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString*, id> *)options
{
    if ([url.host isEqualToString:@"safepay"]) {
        //跳轉(zhuǎn)支付寶錢包進(jìn)行支付泌射,處理支付結(jié)果
        [[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) {
            NSLog(@"result = %@",resultDic);
        }];
    }
    return YES;
}

@end
#import "ViewController.h"
#import "Order.h"
#import "DataSigner.h"
#import <AlipaySDK/AlipaySDK.h>

@interface ViewController ()

@end

@implementation ViewController
 
 
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    /*=========================================================*/
    /*====客戶端調(diào)用支付寶支付(實(shí)際操作請(qǐng)放到服務(wù)端)=================*/
    /*=========================================================*/
    
    //AppId和PrivateKey沒(méi)有配置下的提示
    if (  [MXAlipayAPPID length] == 0
        ||[MXAlipayPrivateKey length] == 0
        ||[MXAlipayAPPID isEqualToString:@"請(qǐng)配置你的AppID"]
        ||[MXAlipayPrivateKey isEqualToString:@"請(qǐng)配置你的支付寶pkcs8私鑰"])
    {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示"
                                                        message:@"缺少appId或者私鑰。"
                                                       delegate:self
                                              cancelButtonTitle:@"確定"
                                              otherButtonTitles:nil];
        [alert show];
        return;
    }
    
    //商品價(jià)格
    NSString *price = [NSString stringWithFormat:@"%.2f", 0.01];
    
    
    //將商品信息賦予AlixPayOrder的成員變量
    Order* order    = [Order new];
    order.app_id    = MXAlipayAPPID;// NOTE: app_id設(shè)置
    order.method    = MXUrlAlipay;  // NOTE: 支付接口名稱
    order.charset = @"utf-8";       // NOTE: 參數(shù)編碼格式
    
    NSDateFormatter* formatter = [NSDateFormatter new];
    [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    order.timestamp = [formatter stringFromDate:[NSDate date]];    // NOTE: 當(dāng)前時(shí)間點(diǎn)
    
    order.version   = @"1.0";       // NOTE: 支付版本
    order.sign_type = @"RSA";       // NOTE: sign_type設(shè)置
    
    // NOTE: 商品數(shù)據(jù)
    order.biz_content                   = [BizContent new];
    order.biz_content.body              = @"我是測(cè)試數(shù)據(jù)";
    order.biz_content.subject           = @"1";
    order.biz_content.out_trade_no      = [self generateTradeNO];   //訂單ID(由商家自行制定)
    order.biz_content.timeout_express   = @"30m";                   //超時(shí)時(shí)間設(shè)置
    order.biz_content.total_amount      = price;                    //商品價(jià)格
    
    //將商品信息拼接成字符串
    NSString *orderInfo         = [order orderInfoEncoded:NO];
    NSString *orderInfoEncoded  = [order orderInfoEncoded:YES];
    NSLog(@"orderSpec = %@",orderInfo);
    
    // NOTE: 獲取私鑰并將商戶信息簽名鬓照,外部商戶的加簽過(guò)程請(qǐng)務(wù)必放在服務(wù)端熔酷,防止公私鑰數(shù)據(jù)泄露;
    //       需要遵循RSA簽名規(guī)范豺裆,并將簽名字符串base64編碼和UrlEncode
    id<DataSigner> signer = CreateRSADataSigner(MXAlipayPrivateKey);
    NSString *signedString = [signer signString:orderInfo];
    
    // NOTE: 如果加簽成功拒秘,則繼續(xù)執(zhí)行支付
    if (signedString != nil) {
        //應(yīng)用注冊(cè)scheme,在AliSDKDemo-Info.plist定義URL types
        NSString *appScheme = MXURLScheme;
        
        // NOTE: 將簽名成功字符串格式化為訂單字符串,請(qǐng)嚴(yán)格按照該格式
        NSString *orderString = [NSString stringWithFormat:@"%@&sign=%@",
                                 orderInfoEncoded, signedString];
        
        // NOTE: 調(diào)用支付結(jié)果開(kāi)始支付
        [[AlipaySDK defaultService] payOrder:orderString fromScheme:appScheme callback:^(NSDictionary *resultDic) {
            NSLog(@"reslut = %@",resultDic);
        }];
    }
}

#pragma mark - Private Method

//==============產(chǎn)生隨機(jī)訂單號(hào)==============

+ (NSString *)generateTradeNO
{
    static int kNumber = 15;
    
    NSString *sourceStr = @"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    NSMutableString *resultStr = [[NSMutableString alloc] init];
    srand((unsigned)time(0));
    for (int i = 0; i < kNumber; i++)
    {
        unsigned index = rand() % [sourceStr length];
        NSString *oneStr = [sourceStr substringWithRange:NSMakeRange(index, 1)];
        [resultStr appendString:oneStr];
    }
    return resultStr;
}
@end

這里也可以下載我自己搭建的DEMO

已解決所有錯(cuò)誤

下載后替換掉MXAlipayConfig.h中的配置參數(shù)即可運(yùn)行,前提是你的參數(shù)不能錯(cuò)

使用方法可以參考Demo中的ReadMe文件

正式接入階段


服務(wù)端
負(fù)責(zé)生成訂單及簽名,及接受支付異步通知臭猜。
客戶端
負(fù)責(zé)使用服務(wù)端傳來(lái)的訂單信息調(diào)用支付寶支付接口躺酒,及根據(jù)SDK同步返回的支付結(jié)果展示結(jié)果頁(yè)。
服務(wù)端接入
私鑰必須放在服務(wù)端蔑歌,簽名過(guò)程必須放在服務(wù)端羹应。


集成支付寶后打包ipa,報(bào)如下一系列警告:


Paste_Image.png

解決方法:

  1. Go to Build Settings -> Build Options -> Debug Information Format
  2. Change the Debug setting from "DWARF with dSYM File" to "DWARF"
  3. Leave the Release setting at "DWARF with dSYM File"
    AlipaySDK.framework 是先 build 的靜態(tài) lib 次屠,然后轉(zhuǎn)成的 framework 园匹,但是在 build 靜態(tài) lib 時(shí) CLANG_ENABLE_MODULES 沒(méi)有被設(shè)置成 disabled 。

常見(jiàn)問(wèn)題

APP支付報(bào)錯(cuò)ALI64處理方案
APP支付報(bào)錯(cuò)ALI40247處理方案

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末劫灶,一起剝皮案震驚了整個(gè)濱河市裸违,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌浑此,老刑警劉巖累颂,帶你破解...
    沈念sama閱讀 211,496評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件滞详,死亡現(xiàn)場(chǎng)離奇詭異凛俱,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)料饥,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,187評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門蒲犬,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人岸啡,你說(shuō)我怎么就攤上這事原叮。” “怎么了巡蘸?”我有些...
    開(kāi)封第一講書人閱讀 157,091評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵奋隶,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我悦荒,道長(zhǎng)唯欣,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 56,458評(píng)論 1 283
  • 正文 為了忘掉前任搬味,我火速辦了婚禮境氢,結(jié)果婚禮上蟀拷,老公的妹妹穿的比我還像新娘。我一直安慰自己萍聊,他們只是感情好问芬,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,542評(píng)論 6 385
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著寿桨,像睡著了一般此衅。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上牛隅,一...
    開(kāi)封第一講書人閱讀 49,802評(píng)論 1 290
  • 那天炕柔,我揣著相機(jī)與錄音,去河邊找鬼媒佣。 笑死匕累,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的默伍。 我是一名探鬼主播欢嘿,決...
    沈念sama閱讀 38,945評(píng)論 3 407
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼也糊!你這毒婦竟也來(lái)了炼蹦?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 37,709評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤狸剃,失蹤者是張志新(化名)和其女友劉穎掐隐,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體钞馁,經(jīng)...
    沈念sama閱讀 44,158評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡虑省,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,502評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了僧凰。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片探颈。...
    茶點(diǎn)故事閱讀 38,637評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖训措,靈堂內(nèi)的尸體忽然破棺而出伪节,到底是詐尸還是另有隱情,我是刑警寧澤绩鸣,帶...
    沈念sama閱讀 34,300評(píng)論 4 329
  • 正文 年R本政府宣布怀大,位于F島的核電站,受9級(jí)特大地震影響呀闻,放射性物質(zhì)發(fā)生泄漏化借。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,911評(píng)論 3 313
  • 文/蒙蒙 一总珠、第九天 我趴在偏房一處隱蔽的房頂上張望屏鳍。 院中可真熱鬧勘纯,春花似錦、人聲如沸钓瞭。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,744評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)山涡。三九已至堤结,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間鸭丛,已是汗流浹背竞穷。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,982評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留鳞溉,地道東北人瘾带。 一個(gè)月前我還...
    沈念sama閱讀 46,344評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像熟菲,于是被迫代替她去往敵國(guó)和親看政。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,500評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • 文章主要講到以下五部分: 一抄罕、支付寶開(kāi)放平臺(tái)創(chuàng)建應(yīng)用 二允蚣、簽約移動(dòng)支付功能 三、接入支付前的準(zhǔn)備工作附準(zhǔn)備工作中遇...
    sillen閱讀 17,854評(píng)論 1 10
  • 因?yàn)榻陧?xiàng)目中需要接入支付寶支付功能呆贿,自己也爬了很多的坑嚷兔,所以做了一下這邊文章供大家學(xué)習(xí)參考,遠(yuǎn)離爬坑做入,文章主要講...
    啓蘊(yùn)閱讀 2,296評(píng)論 0 4
  • 支付寶集成過(guò)程詳解——運(yùn)行DEMO 前言冒晰,夢(mèng)想是需要堅(jiān)持的,在路上母蛛,一路前行翩剪。加油乳怎。 這兩天軟件需要集成支付寶了彩郊,...
    改昵稱已被占用閱讀 19,043評(píng)論 2 39
  • 你是我年少的歡喜 是我深夜的惦記 是我發(fā)呆時(shí)候想的人 夜闌臥聽(tīng)風(fēng)吹雨 鐵馬冰河 都是你
    伊娃是個(gè)做夢(mèng)鬼閱讀 252評(píng)論 0 0
  • 在老家的生活并不輕松,我和姥姥姥爺住在一個(gè)房間蚪缀,而這個(gè)家還有我舅舅舅媽秫逝,。 他們有一對(duì)兒女询枚,也是我所謂的表姐违帆,表弟...
    逝怯懦安閱讀 170評(píng)論 0 0