支付寶支付大致流程為 :
1. 公司與支付寶進行簽約 ,獲得商戶ID(partner)和賬號ID(seller)和私鑰(privateKey),開發中用到的,很重要。
3. 生成訂單 ,簽名加密。
4. 開始支付,調起支付寶客戶端或者網頁端,然後進行支付,由支付寶與銀行系統進行打交道,並由支付寶返回處理的結果給客戶端。
5. 展示對應的支付結果給客戶。
生成方式一(推薦):使用支付寶提供的一鍵生成工具(內附使用說明)
Windows:下載MAC OSX:下載
OpenSSL> pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt -out rsa_private_key_pkcs8.pem #Java開發者需要將私鑰轉換成PKCS8格式
OpenSSL> rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem #生成公鑰
OpenSSL> exit #退出OpenSSL程序
解壓打開文件夾,直接運行“支付寶RAS密鑰生成器SHAwithRSA1024_V1.0.bat”(WINDOWS)或“SHAwithRSA1024_V1.0.command”(MACOSX),點擊“生成RSA密鑰”,會自動生成公私鑰,然後點擊“打開文件位置”,即可找到工具自動生成的密鑰。
生成方式二:也可以使用OpenSSL工具命令生成
首先進入OpenSSL工具,再輸入以下命令。
OpenSSL> genrsa -out rsa_private_key.pem
1024
#生成私鑰
經過以上步驟,開發者可以在當前文件夾中(OpenSSL運行文件夾),看到rsa_private_key.pem(RSA私鑰)、rsa_private_key_pkcs8.pem(pkcs8格式RSA私鑰)和rsa_public_key.pem(對應RSA公鑰)3個文件。開發者將私鑰保留,將公鑰提交給支付寶網關,用於驗證簽名。以下為私鑰文件和公鑰文件示例。
注意:對於使用Java的開發者,將pkcs8在console中輸出的私鑰去除頭尾、換行和空格,作為開發者私鑰,對於.NET和PHP的開發者來說,無需進行pkcs8命令行操作。
更詳細信息:https://doc.open.alipay.com/doc2/detail?treeId=58&articleId=103242&docType=1
進入OpenSSL工具,再輸入以下命令。
1
2
3
4
5
OpenSSL> dsaparam-outdsa_param.pem
1024
#生成參數文件
OpenSSL> gendsa-outdsa_private_key.pemdsa_param.pem#生成私鑰
OpenSSL> pkcs8-topk8-informPEM-indsa_private_key.pem-outformPEM-nocrypt-outdsa_private_key_pkcs8.pem#Java開發者需要將私鑰轉換成PKCS8格式
OpenSSL> dsa-indsa_private_key_pkcs8.pem-pubout-outdsa_public_key.pem #生成公鑰
OpenSSL> exit #退出OpenSSL程序
經過以上步驟,開發者可以在當前文件夾中(OpenSSL運行文件夾),看到dsa_private_key.pem(DSA私鑰)、dsa_private_key_pkcs8.pem(pkcs8格式DSA私鑰)、dsa_public_key.pem(對應DSA公鑰)和dsa_param.pem(參數文件)4個文件。開發者將私鑰保留,將公鑰提交給支付寶網關,用於驗證簽名。
注意:對於使用Java的開發者,將pkcs8在console中輸出的私鑰去除頭尾、換行和空格,作為開發者私鑰,對於.NET和PHP的開發者來說,無需進行pkcs8命令行操作。
更詳細信息:https://doc.open.alipay.com/doc2/detail.htm?spm=a219a.7629140.0.0.JDjRVa&treeId=58&articleId=103581&docType=1
上傳RSA商戶公鑰: https://doc.open.alipay.com/doc2/detail.htm?spm=a219a.7629140.0.0.kDer5c&treeId=58&articleId=103578&docType=1
查看支付寶RSA生成公鑰: https://doc.open.alipay.com/doc2/detail.htm?spm=a219a.7629140.0.0.50COsb&treeId=58&articleId=103546&docType=1
上傳DSA商戶公鑰:https://doc.open.alipay.com/doc2/detail.htm?spm=a219a.7629140.0.0.6SrtUf&treeId=58&articleId=103577&docType=1
查看支付寶DSA生成公鑰: https://doc.open.alipay.com/doc2/detail.htm?spm=a219a.7629140.0.0.c9oA4U&treeId=58&articleId=103576&docType=1
通過上面的講解:
大家應該吧 : 商戶私鑰、 支付寶公鑰、商戶ID(partner)和賬號ID(seller) 都記錄下來。
1. 從下載出來的SDK中吧以下文件取出來,並保存到另外一個文件夾,如下文件:
2。我們把上面這個文件拖入新建的工程裡面。
3. 導入依賴庫 (出現莫名其妙的錯誤的時候,多檢查下 依賴庫, 看是不是添加少了)
然後編譯程序, 然後發現 unknown type nesting ,int, nsdata之類的語句, 這個是因為沒有引入對應的框架。
解決辦法在出錯的類裡面加上
#import#import
在編譯程序:說openssl/asn1.h not found.
解決方法如下:
現在編譯項目,應該是編譯通過了。
設置 URL types
設置 支付寶白名單。 在info.plist 文件中添加
項目結構預覽:
#import#import "Product.h" @protocol alipyDelegate -(void)alipydidSuccess; -(void)alipydidFaile; @end @interface AppDelegate : UIResponder @property (strong, nonatomic) UIWindow *window; @property (weak , nonatomic) id aliDelegate; -(void)payByAlipay:(Product *)product; @end
#import "AppDelegate.h" #import#import "Product.h" #import "Order.h" #import "DataSigner.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 *)app openURL:(NSURL *)url options:(NSDictionary *)options{ [self alipayUrlAction:url]; return YES; } -(BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation{ //有多中支付方式,要用scheme 來進行判斷,看是那種途徑的url. [self alipayUrlAction:url]; return YES; } -(BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url{ [self alipayUrlAction:url]; return YES; } -(void)alipayUrlAction:(NSURL *)url{ [[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) { if ([[resultDic valueForKey:@"resultStatus"] intValue] == 9000) { if ([_aliDelegate respondsToSelector:@selector(alipydidSuccess)]) { [_aliDelegate alipydidSuccess]; } }else{ if ([_aliDelegate respondsToSelector:@selector(alipydidFaile)]) { [_aliDelegate alipydidFaile]; } } }]; } -(void)payByAlipay:(Product *)product{ /* *商戶的唯一的parnter和seller。 *簽約後,支付寶會為每個商戶分配一個唯一的 parnter 和 seller。 */ /*============================================================================*/ /*=======================需要填寫商戶app申請的===================================*/ /*============================================================================*/ NSString *partner = @""; //商戶id NSString *seller = @""; //賬戶id 簽約賬號。 NSString *privateKey = @""; // md5 //partner和seller獲取失敗,提示 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; } /* *生成訂單信息及簽名 */ //將商品信息賦予AlixPayOrder的成員變量 Order *order = [[Order alloc] init]; order.partner = partner; order.sellerID = seller; order.outTradeNO = @"xxxxxx"; //訂單ID(由商家自行制定) order.subject = product.productName; //商品標題 order.body = product.productName; //商品描述 order.totalFee = [NSString stringWithFormat:@"%.2f",product.price]; //商品價格 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 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) { NSLog(@"reslut = %@",resultDic); if ([[resultDic valueForKey:@"resultStatus"] intValue] == 9000) { //成功 if ([_aliDelegate respondsToSelector:@selector(alipydidSuccess)]) { [_aliDelegate alipydidSuccess]; } }else{ //失敗 if ([_aliDelegate respondsToSelector:@selector(alipydidFaile)]) { [_aliDelegate alipydidFaile]; } } }]; } } @end
#import@interface ViewController : UIViewController @end
#import "ViewController.h" #import "Product.h" #import "Order.h" #import#import "AppDelegate.h" @interface ViewController () @property (weak, nonatomic) IBOutlet UITableView *myTableView; @property(nonatomic, strong)NSMutableArray *productList; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; [self generateData]; } #pragma mark - #pragma mark ==============產生隨機訂單號============== - (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; } #pragma mark - #pragma mark ==============產生訂單信息============== - (void)generateData{ // NSArray *subjects = @[@"1", // @"2",@"3",@"4", // @"5",@"6",@"7", // @"8",@"9",@"10"]; NSArray *body = @[@"我是測試數據", @"我是測試數據", @"我是測試數據", @"我是測試數據", @"我是測試數據", @"我是測試數據", @"我是測試數據", @"我是測試數據", @"我是測試數據", @"我是測試數據"]; self.productList = [[NSMutableArray alloc] init]; for (int i = 0; i < [body count]; ++i) { Product *product = [[Product alloc] init]; product.productName = [body objectAtIndex:i]; product.price = 0.01f+pow(10,i-2); [self.productList addObject:product]; } } #pragma mark - #pragma mark UITableViewDelegate - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { return 55.0f; } #pragma mark - #pragma mark UITableViewDataSource - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return [self.productList count]; } // //用TableView呈現測試數據,外部商戶不需要考慮 // - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"Cell"]; Product *product = [self.productList objectAtIndex:indexPath.row]; cell.textLabel.text = product.productName; cell.detailTextLabel.text = [NSString stringWithFormat:@"一口價:%.2f",product.price]; return cell; } #pragma mark - #pragma mark ==============點擊訂單模擬支付行為============== // //選中商品調用支付寶極簡支付 // - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { /* *點擊獲取prodcut實例並初始化訂單信息 */ Product *product = [self.productList objectAtIndex:indexPath.row]; AppDelegate *appdele = (AppDelegate *)[UIApplication sharedApplication].delegate; [appdele payByAlipay:product]; [tableView deselectRowAtIndexPath:indexPath animated:YES]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end
#import@interface Product : NSObject @property (nonatomic, copy) NSString* productName; @property (nonatomic, assign) float price; @end
#import "Product.h" @implementation Product @end
上傳RSA公鑰