iOS之支付
iOS支付
iOS支付分為兩類,第三方支付和應用內支付(內購)。
第三方支付包括:支付寶支付、微信支付、銀聯支付、百度錢包、京東支付等等。
應用內支付(In-App Purchase):在應用程序內購買虛擬商品。如果你在App Store上銷售的應用程序,將收到支付金額的70%。
第三方支付
彈出方式
網頁
有些第三方支付沒有安裝客戶端,可以直接彈出網頁進行支付。(比如支付寶)
調用APP
手機中安裝了客戶端可以跳轉到APP中進行支付。微信支付只能調用App進行支付。
支付寶支付
相關資料
- 支付寶開放平臺(SDK&開發文檔): open.alipay.com/platform/ho…
- 移動支付集成: doc.open.alipay.com/doc2/detail…
- 商戶服務平臺(與支付寶簽約需要填寫的公司資料): b.alipay.com/newIndex.ht…
支付流程
在商戶服務平臺先與支付寶簽約,獲得商戶ID(partner)和賬號ID(seller),需要提供公司資質或者營業執照,個人無法申請。
文檔地址: doc.open.alipay.com/doc2/detail…
生成并下載相應的公鑰私鑰文件(加密簽名用)
文檔地址: doc.open.alipay.com/doc2/detail…
下載支付寶SDK: doc.open.alipay.com/doc2/detail…
生成訂單信息
調用支付寶客戶端,由支付寶客戶端跟支付寶安全服務器打交道
支付完畢后返回支付結果給商戶客戶端和服務器
SDK里有集成支付寶功能的一個Demo,集成支付功能的具體操作方式,可以參考Demo。
代碼集成流程
參考文檔地址: doc.open.alipay.com/doc2/detail…
下載官方SDK
下載地址: doc.open.alipay.com/doc2/detail…
本Demo使用的SDK是從官方Demo整理出來的,整理的SDK版本:201501022。
下載地址:7xooko.com1.z0.glb.clouddn.com/AlipaySDK.z…
目錄結構如下:
├── AlipaySDK.bundle ├── AlipaySDK.framework ├── Order.h ├── Order.m ├── Util ├── libcrypto.a ├── libssl.a └── openssl 復制代碼其中:
- AlipaySDK.bundle和AlipaySDK.framework是支付寶SDK
- Order類:定義訂單信息
- Util、libcrypto.a、libssl.a、openssl:數據簽名,對訂單信息進行加密
添加依賴庫
其中,需要注意的是:
如果是Xcode 7.0之后的版本,需要添加libc++.tbd、libz.tbd;
如果是Xcode 7.0之前的版本,需要添加libc++.dylib、libz.dylib。
創建prefix header filePCH文件,添加#import <Foundation/Foundation.h>
在Build Settings中的prefix header設置pch文件路徑
在Build Settings中Header Search Paths添加頭文件引用路徑,[文件路徑]/AlipaySDK/
在需要調用AlipaySDK的文件中,增加頭文件引用。
#import??<AlipaySDK/AlipaySDK.h>#import?"Order.h"
#import?"DataSigner.h"
復制代碼
生成訂單信息及簽名
//將商品信息賦予AlixPayOrder的成員變量Order?*order?=?[[Order?alloc]?init];
order.partner?=?PartnerID;?//?商戶ID
order.seller?=?SellerID;?//?賬號ID
order.tradeNO?=?@"20150923";?//訂單ID(由商家自行制定)
order.productName?=?@"iPhone6s";?//商品標題
order.productDescription?=?@"新年打折";?//商品描述
order.amount?=?@"0.01";?//商品價格(單位:元)
order.notifyURL?=??@"http://www.chaosky.me";?//回調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?=?@"AliPayDemo";
//將商品信息拼接成字符串
NSString?*orderSpec?=?[order?description];
NSLog(@"orderSpec?=?%@",orderSpec);
//獲取私鑰并將商戶信息簽名,外部商戶可以根據情況存放私鑰和簽名,只需要遵循RSA簽名規范,并將簽名字符串base64編碼和UrlEncode
id<DataSigner>?signer?=?CreateRSADataSigner(PartnerPrivKey);
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);
????}];
}
復制代碼
Xcode設置URL scheme
iPhone SDK可以把你的App和一個自定義的URL Scheme綁定。該URL Scheme可用來從瀏覽器或別的App啟動你的App。
配置方法:打開info.plist文件,找到或者添加如圖所示的鍵值對:
URL Scheme值為代碼中對應的值,必須一致。
配置支付寶客戶端返回url處理方法
AppDelegate.m文件中,增加引用代碼:
#import?<AlipaySDK/AlipaySDK.h>復制代碼
在@implementation AppDelegate中增加如下代碼:
-?(BOOL)application:(UIApplication?*)application?openURL:(NSURL?*)url?sourceApplication:(NSString?*)sourceApplication?annotation:(id)annotation{
????//如果極簡開發包不可用,會跳轉支付寶錢包進行支付,需要將支付寶錢包的支付結果回傳給開發包
????if?([url.host?isEqualToString:@"safepay"])?{
????????[[AlipaySDK?defaultService]?processOrderWithPaymentResult:url?standbyCallback:^(NSDictionary?*?resultDic)?{
????//【由于在跳轉支付寶客戶端支付的過程中,商戶app在后臺很可能被系統kill了,所以pay接口的callback就會失效,請商戶對standbyCallback返回的回調結果進行處理,就是在這個方法里面處理跟callback一樣的邏輯】
????????????NSLog(@"result?=?%@",resultDic);
????????}];
????}
????if?([url.host?isEqualToString:@"platformapi"]){//支付寶錢包快登授權返回authCode
????????[[AlipaySDK?defaultService]?processAuthResult:url?standbyCallback:^(NSDictionary?*?resultDic)?{
????????????//【由于在跳轉支付寶客戶端支付的過程中,商戶app在后臺很可能被系統kill了,所以pay接口的callback就會失效,請商戶對standbyCallback返回的回調結果進行處理,就是在這個方法里面處理跟callback一樣的邏輯】
????????????NSLog(@"result?=?%@",resultDic);
????????}];
????}
????return?YES;
}
復制代碼
微信支付
需要提供公司資質或者營業執照,個人無法申請。
相關文檔
- 微信開放平臺:open.weixin.qq.com
- 微信支付商戶平臺:pay.weixin.qq.com/index.php
- 微信公眾平臺:mp.weixin.qq.com
支付流程
向微信注冊你的應用程序id
開發者應用登記頁面 進行登記,登記并選擇移動應用進行設置后,將獲得AppID,可立即用于開發。但應用登記完成后還需要提交審核,只有審核通過的應用才能正式發布使用。
微信APP支付接入商戶服務中心
參考文檔鏈接:open.weixin.qq.com/cgi-bin/sho…
下載微信SDK文件,如果在項目中應使用SDK的最新版。
官方資源下載地址:open.weixin.qq.com/cgi-bin/sho…
本Demo使用的SDK是從官方Demo整理出來的,整理的SDK版本:1.6.1。
下載地址:7xooko.com1.z0.glb.clouddn.com/AlipaySDK.z…
目錄結構如下:
├── SDKExport │?? ├── WXApi.h │?? ├── WXApiObject.h │?? ├── libWeChatSDK.a │?? └── read_me.txt └── lib├── ApiXml.h├── ApiXml.mm├── WXUtil.h├── WXUtil.mm├── payRequsestHandler.h└── payRequsestHandler.mm 復制代碼其中:
SDKExport文件夾:SDK文件
lib文件夾:工具類
添加依賴庫
SystemConfiguration.framework libz.dylib libsqlite3.dylib libc++.dylib CoreTelephony.framework CoreGraphics.framework 復制代碼在需要調用WeChatSDK的文件中,增加頭文件引用。
#import?"WXApi.h"#import?"payRequsestHandler.h"
復制代碼
生成訂單信息及簽名
#pragma?mark?-?微信支付-?(void)wechatPayAction:(UIButton?*)?sender
{
????//?判斷用戶是否安裝微信
????if?(![WXApi?isWXAppInstalled])?{
????????UIAlertView?*?alertView?=?[[UIAlertView?alloc]?initWithTitle:@"提示"?message:@"請安裝微信客戶端"?delegate:nil?cancelButtonTitle:@"確定"?otherButtonTitles:nil];
????????[alertView?show];
????????return;
????}
????
????//?實現支付
????[self?sendPay_demo];
}
-?(void)sendPay_demo
{
????//{{{
????//本實例只是演示簽名過程,?請將該過程在商戶服務器上實現
????
????//?配置微信支付的參數
????//創建支付簽名對象
????payRequsestHandler?*req?=?[[payRequsestHandler?alloc]?init];
????//初始化支付簽名對象
????[req?init:__WXappID?mch_id:__WXmchID];
????//設置密鑰
????[req?setKey:__WXpaySignKey];
????
????//}}}
????
????//獲取到實際調起微信支付的參數后,在app端調起支付
????NSMutableDictionary?*dict?=?[req?sendPay_demo];
????
????if(dict?==?nil){
????????//錯誤提示
????????NSString?*debug?=?[req?getDebugifo];
????????
????????[self?alert:@"提示信息"?msg:debug];
????????
????????NSLog(@"%@\n\n",debug);
????}else{
????????NSLog(@"%@\n\n",[req?getDebugifo]);
????????//[self?alert:@"確認"?msg:@"下單成功,點擊OK后調起支付!"];
????????
????????NSMutableString?*stamp??=?[dict?objectForKey:@"timestamp"];
????????
????????//調起微信支付
????????PayReq*?req?????????????=?[[PayReq?alloc]?init];
????????req.openID??????????????=?[dict?objectForKey:@"appid"];
????????req.partnerId???????????=?[dict?objectForKey:@"partnerid"];
????????req.prepayId????????????=?[dict?objectForKey:@"prepayid"];
????????req.nonceStr????????????=?[dict?objectForKey:@"noncestr"];
????????req.timeStamp???????????=?stamp.intValue;
????????req.package?????????????=?[dict?objectForKey:@"package"];
????????req.sign????????????????=?[dict?objectForKey:@"sign"];
????????
????????//?調用微信支付
????????[WXApi?sendReq:req];
????}
}
//客戶端提示信息
-?(void)alert:(NSString?*)title?msg:(NSString?*)msg
{
????UIAlertView?*alter?=?[[UIAlertView?alloc]?initWithTitle:title?message:msg?delegate:nil?cancelButtonTitle:@"OK"?otherButtonTitles:nil];
????
????[alter?show];
}
復制代碼
?
Xcode設置URL scheme
在Xcode中,選擇你的工程設置項,選中“TARGETS”一欄,在“info”標簽欄的“URL type“添加“URL scheme”為你所注冊的應用程序id(如下圖所示)。
在你需要使用微信終端API的文件中import WXApi.h 頭文件,并增加 WXApiDelegate 協議。
//?微信所有的API接口#import?"WXApi.h"
//?APP端簽名相關頭文件
#import?"payRequsestHandler.h"
@interface?AppDelegate?()<WXApiDelegate>
@end
復制代碼
要使你的程序啟動后微信終端能響應你的程序,必須在代碼中向微信終端注冊你的id。(如下圖所示,在 AppDelegate 的 didFinishLaunchingWithOptions 函數中向微信注冊id)。
-?(BOOL)application:(UIApplication?*)application?didFinishLaunchingWithOptions:(NSDictionary?*)launchOptions?{????//?Override?point?for?customization?after?application?launch.
????//向微信注冊
????[WXApi?registerApp:APP_ID?withDescription:@"demo?2.0"];
????return?YES;
}
復制代碼
重寫AppDelegate的handleOpenURL和openURL方法:
-?(BOOL)application:(UIApplication?*)application?handleOpenURL:(NSURL?*)url{
????return?[WXApi?handleOpenURL:url?delegate:self];
}
-?(BOOL)application:(UIApplication?*)application?openURL:(NSURL?*)url?sourceApplication:(NSString?*)sourceApplication?annotation:(id)annotation
{
????return?[WXApi?handleOpenURL:url?delegate:self];
}
復制代碼
現在,你的程序要實現和微信終端交互的具體請求與回應,因此需要實現WXApiDelegate協議的兩個方法:
-(void)?onReq:(BaseReq*)req{
????if([req?isKindOfClass:[GetMessageFromWXReq?class]])
????{
????????//?微信請求App提供內容,?需要app提供內容后使用sendRsp返回
????????NSString?*?strTitle?=?[NSString?stringWithFormat:@"微信請求App提供內容"];
????????NSString?*?strMsg?=?@"微信請求App提供內容,App要調用sendResp:GetMessageFromWXResp返回給微信";
????????UIAlertView?*?alert?=?[[UIAlertView?alloc]?initWithTitle:strTitle?message:strMsg?delegate:self?cancelButtonTitle:@"OK"?otherButtonTitles:nil,?nil];
????????alert.tag?=?1000;
????????[alert?show];
????}
????else?if([req?isKindOfClass:[ShowMessageFromWXReq?class]])
????{
????????ShowMessageFromWXReq?*??temp?=?(ShowMessageFromWXReq*)req;
????????WXMediaMessage?*?msg?=?temp.message;
????????//顯示微信傳過來的內容
????????WXAppExtendObject?*?obj?=?msg.mediaObject;
????????NSString?*?strTitle?=?[NSString?stringWithFormat:@"微信請求App顯示內容"];
????????NSString?*?strMsg?=?[NSString?stringWithFormat:@"標題:%@?\n內容:%@?\n附帶信息:%@?\n縮略圖:%lu?bytes\n\n",?msg.title,?msg.description,?obj.extInfo,?msg.thumbData.length];
????????UIAlertView?*?alert?=?[[UIAlertView?alloc]?initWithTitle:strTitle?message:strMsg?delegate:self?cancelButtonTitle:@"OK"?otherButtonTitles:nil,?nil];
????????[alert?show];
????}
????else?if([req?isKindOfClass:[LaunchFromWXReq?class]])
????{
????????//從微信啟動App
????????NSString?*?strTitle?=?[NSString?stringWithFormat:@"從微信啟動"];
????????NSString?*?strMsg?=?@"這是從微信啟動的消息";
????????UIAlertView?*?alert?=?[[UIAlertView?alloc]?initWithTitle:strTitle?message:strMsg?delegate:self?cancelButtonTitle:@"OK"?otherButtonTitles:nil,?nil];
????????[alert?show];
????}
}
復制代碼
onReq是微信終端向第三方程序發起請求,要求第三方程序響應。第三方程序響應完后必須調用sendRsp返回。在調用sendRsp返回時,會切回到微信終端程序界面。
-(void)?onResp:(BaseResp*)resp?{
?????NSString?*?strMsg?=?[NSString?stringWithFormat:@"errcode:%d",?resp.errCode];
?????NSString?*?strTitle;
?????if([resp?isKindOfClass:[SendMessageToWXResp?class]])
?????{
?????????strTitle?=?[NSString?stringWithFormat:@"發送媒體消息結果"];
?????}
?????if([resp?isKindOfClass:[PayResp?class]]){
?????????//支付返回結果,實際支付結果需要去微信服務器端查詢
?????????strTitle?=?[NSString?stringWithFormat:@"支付結果"];
?????????switch?(resp.errCode)?{
?????????????case?WXSuccess:
?????????????????strMsg?=?@"支付結果:成功!";
?????????????????NSLog(@"支付成功-PaySuccess,retcode?=?%d",?resp.errCode);
?????????????????break;
?????????????default:
?????????????????strMsg?=?[NSString?stringWithFormat:@"支付結果:失敗!retcode?=?%d,?retstr?=?%@",?resp.errCode,resp.errStr];
?????????????????NSLog(@"錯誤,retcode?=?%d,?retstr?=?%@",?resp.errCode,resp.errStr);
?????????????????break;
?????????}
?????}
?????UIAlertView?*?alert?=?[[UIAlertView?alloc]?initWithTitle:strTitle?message:strMsg?delegate:self?cancelButtonTitle:@"OK"?otherButtonTitles:nil,?nil];
?????[alert?show];
?}
復制代碼
如果第三方程序向微信發送了sendReq的請求,那么onResp會被回調。sendReq請求調用后,會切到微信終端程序界面。
應用內購買(In-App Purchase)
在應用程序內購買虛擬商品。如果你在App Store上銷售的應用程序,將收到支付金額的70%。
相關資料
支付流程
配置App ID
配置iTunes Connect
填寫相關的稅務,銀行,聯系人信息
參考鏈接:iOS App提交指南(二)-協議、稅務和銀行業務
添加一個用于在sandbox付費的測試用戶
用該App ID創建一個新的應用。
創建應用內付費項目,選擇付費類型。
App 內購買項目摘要填寫
主要代碼實現
在工程中引入 StoreKit.framework 和#import <StoreKit/StoreKit.h>
獲得所有的付費Product ID列表。這個可以用常量存儲在本地,也可以由自己的服務器返回。
//在內購項目中創建的商品單號#define?ProductID_IAP_FTHJ?@"com.1000phone.IAPDemo.fthj_purple"?//?方天畫戟?488元
#define?ProductID_IAP_XYJ?@"com.1000phone.IAPDemo.xyj"?//?軒轅劍?6,498元
#define?ProductID_IAP_JB?@"com.1000phone.IAPDemo.jb"?//?金幣?6元=6金幣
復制代碼
?
制作界面,展示所有的應用內付費項目。這些應用內付費項目的價格和介紹信息可以從App Store服務器請求,也可以是自己的服務器返回。向App Store查詢速度非常慢,通常需要2-3秒鐘,最好從服務器請求。
-?(void)createViews{
????NSArray?*?buttonNames?=?@[@"軒轅劍?6498元",?@"方天畫戟?488元",?@"金幣6元=6金幣"];
????__weak?typeof(self)?weakSelf?=?self;
????[buttonNames?enumerateObjectsUsingBlock:^(NSString?*?buttonName,?NSUInteger?idx,?BOOL?*?stop)?{
????????UIButton?*?button?=?[UIButton?buttonWithType:UIButtonTypeSystem];
????????[weakSelf.view?addSubview:button];
????????button.frame?=?CGRectMake(100,?100?+?idx???*?60,?150,?50);
????????button.titleLabel.font?=?[UIFont?systemFontOfSize:18];
????????[button?setTitle:buttonName?forState:UIControlStateNormal];
????????//?設置tag值
????????button.tag?=?PAY_BUTTON_BEGIN_TAG?+?idx;
????????[button?addTarget:self?action:@selector(buyProduct:)?forControlEvents:UIControlEventTouchUpInside];
????}];
}
-?(void)buyProduct:(UIButton?*)?sender
{
}
復制代碼
?
當用戶點擊了一個IAP項目,我們先查詢用戶是否允許應用內付費。
-?(void)buyProduct:(UIButton?*)?sender{
????self.buyType?=?sender.tag?-?PAY_BUTTON_BEGIN_TAG;
????if?([SKPaymentQueue?canMakePayments])?{
????????//?執行下面提到的第5步:
????????[self?requestProductData];
????????NSLog(@"允許程序內付費購買");
????}
????else
????{
????????NSLog(@"不允許程序內付費購買");
????????UIAlertView?*alerView?=??[[UIAlertView?alloc]?initWithTitle:@"提示"
????????????????????????????????????????????????????????????message:@"您的手機沒有打開程序內付費購買"
???????????????????????????????????????????????????????????delegate:nil?cancelButtonTitle:NSLocalizedString(@"關閉",nil)?otherButtonTitles:nil];
????????[alerView?show];
????}
}
復制代碼
我們先通過該IAP的ProductID向AppStore查詢,獲得SKPayment實例,然后通過SKPaymentQueue的 addPayment方法發起一個購買的操作。
//?下面的ProductId應該是事先在itunesConnect中添加好的,已存在的付費項目。否則查詢會失敗。-?(void)requestProductData?{
???NSLog(@"---------請求對應的產品信息------------");
???NSArray?*product?=?nil;
???switch?(self.buyType)?{
???????case?0:
???????????product?=?[NSArray?arrayWithObject:ProductID_IAP_XYJ];
???????????break;
???????case?1:
???????????product?=?[NSArray?arrayWithObject:ProductID_IAP_FTHJ];
???????????break;
???????case?2:
???????????product?=?[NSArray?arrayWithObject:ProductID_IAP_JB];
???????????break;
???}
???NSSet?*nsset?=?[NSSet?setWithArray:product];
???SKProductsRequest?*request=[[SKProductsRequest?alloc]?initWithProductIdentifiers:?nsset];
???request.delegate=self;
???[request?start];
}
#pragma?mark?-?SKProductsRequestDelegate
//?收到的產品信息回調
-?(void)productsRequest:(SKProductsRequest?*)request?didReceiveResponse:(SKProductsResponse?*)response{
???NSLog(@"-----------收到產品反饋信息--------------");
???NSArray?*myProduct?=?response.products;
???if?(myProduct.count?==?0)?{
???????NSLog(@"無法獲取產品信息,購買失敗。");
???????return;
???}
???NSLog(@"產品Product?ID:%@",response.invalidProductIdentifiers);
???NSLog(@"產品付費數量:?%d",?(int)[myProduct?count]);
???//?populate?UI
???for(SKProduct?*product?in?myProduct){
???????NSLog(@"product?info");
???????NSLog(@"SKProduct?描述信息%@",?[product?description]);
???????NSLog(@"產品標題?%@"?,?product.localizedTitle);
???????NSLog(@"產品描述信息:?%@"?,?product.localizedDescription);
???????NSLog(@"價格:?%@"?,?product.price);
???????NSLog(@"Product?id:?%@"?,?product.productIdentifier);
???}
???SKPayment?*?payment?=?[SKPayment?paymentWithProduct:myProduct[0]];
???NSLog(@"---------發送購買請求------------");
???[[SKPaymentQueue?defaultQueue]?addPayment:payment];
}
//彈出錯誤信息
-?(void)request:(SKRequest?*)request?didFailWithError:(NSError?*)error{
???NSLog(@"-------彈出錯誤信息----------");
???UIAlertView?*alerView?=??[[UIAlertView?alloc]?initWithTitle:NSLocalizedString(@"Alert",NULL)?message:[error?localizedDescription]
??????????????????????????????????????????????????????delegate:nil?cancelButtonTitle:NSLocalizedString(@"Close",nil)?otherButtonTitles:nil];
???[alerView?show];
}
-(void)?requestDidFinish:(SKRequest?*)request
{
???NSLog(@"----------反饋信息結束--------------");
}
復制代碼
在viewDidLoad方法中,將購買頁面設置成購買的Observer。
-?(void)viewDidLoad?{????[super?viewDidLoad];
????[self?createViews];
????//?監聽購買結果
????[[SKPaymentQueue?defaultQueue]?addTransactionObserver:self];
}
-?(void)dealloc
{
????[[SKPaymentQueue?defaultQueue]?removeTransactionObserver:self];
}
復制代碼
當用戶購買的操作有結果時,就會觸發下面的回調函數,相應進行處理即可。
#pragma?mark?-?SKPaymentTransactionObserver//?處理交易結果
-?(void)paymentQueue:(SKPaymentQueue?*)queue?updatedTransactions:(NSArray?*)transactions?{
????for?(SKPaymentTransaction?*transaction?in?transactions)
????{
????????switch?(transaction.transactionState)
????????{
????????????case?SKPaymentTransactionStatePurchased://交易完成
????????????????NSLog(@"transactionIdentifier?=?%@",?transaction.transactionIdentifier);
????????????????[self?completeTransaction:transaction];
????????????????break;
????????????case?SKPaymentTransactionStateFailed://交易失敗
????????????????[self?failedTransaction:transaction];
????????????????break;
????????????case?SKPaymentTransactionStateRestored://已經購買過該商品
????????????????[self?restoreTransaction:transaction];
????????????????break;
????????????case?SKPaymentTransactionStatePurchasing:??????//商品添加進列表
????????????????NSLog(@"商品添加進列表");
????????????????break;
????????????default:
????????????????break;
????????}
????}
}
//?交易完成
-?(void)completeTransaction:(SKPaymentTransaction?*)transaction?{
????NSString?*?productIdentifier?=?transaction.payment.productIdentifier;
//????NSString?*?receipt?=?[transaction.transactionReceipt?base64EncodedString];
????if?([productIdentifier?length]?>?0)?{
????????//?向自己的服務器驗證購買憑證
????}
????//?Remove?the?transaction?from?the?payment?queue.
????[[SKPaymentQueue?defaultQueue]?finishTransaction:?transaction];
}
//?交易失敗
-?(void)failedTransaction:(SKPaymentTransaction?*)transaction?{
????if(transaction.error.code?!=?SKErrorPaymentCancelled)?{
????????NSLog(@"購買失敗");
????}?else?{
????????NSLog(@"用戶取消交易");
????}
????[[SKPaymentQueue?defaultQueue]?finishTransaction:?transaction];
}
//?已購商品
-?(void)restoreTransaction:(SKPaymentTransaction?*)transaction?{
????//?對于已購商品,處理恢復購買的邏輯
????[[SKPaymentQueue?defaultQueue]?finishTransaction:?transaction];
}
復制代碼
服務器驗證憑證(Optional)。如果購買成功,我們需要將憑證發送到服務器上進行驗證。考慮到網絡異常情況,iOS端的發送憑證操作應該進行持久化,如果程序退出,崩潰或網絡異常,可以恢復重試。
參考鏈接
蘋果支付(? Pay)
蘋果支付是一種在應用內運行的具有隱秘性和安全性非接觸式的支付方式。它允許觸摸付款,你可以用來購買實體商品和服務。
Apple 不會存儲或共享客戶的實際信用卡和借記卡卡號,因此商家和 App 開發者無需負責管理和保護實際的信用卡和借記卡卡號。
先決條件
除了使用 PassKit 框架實施 Apple Pay 之外,您還必須:
-
通過付款處理機構或網關設置一個帳戶。
-
通過“證書、標識符和描述文件”(“Certificates, Identifiers & Profiles”)注冊一個商家 ID。
-
生成一個 Apple Pay 證書,用于加密和解密付款令牌。
-
在您的 App 中包括一個 Apple Pay 授權。
-
遵循“應用審核準則”的第 29 節中列出的要求。
-
遵循《App 審核準則》(“App Review Guidelines”)第 29 節中列出的要求。
參考資料
? Pay VS In-App Purchase
| 框架 | PassKit | StoreKit |
| 適用范圍 | 實體商品(如食品雜貨、服裝和電器)和服務(如俱樂部會員、酒店預訂和活動門票) | 銷售虛擬商品,如適用于您的 App 的優質內容及訂閱數字內容;程序內的內容和功能性;程序內貨幣服務;數碼訂閱 |
| 支付處理 | 自己的支付平臺處理付款 | 蘋果公司處理付款 |
總結
- 上一篇: PostgreSQL索引页
- 下一篇: 邮件发送工具类