內購項目-代碼篇
一、分步驟說明
1、獲取商品列表
由於蘋果服務器返回很慢,並且一般我們都會有一個自己的商店界面,就不必向蘋果服務器去請求商品列表了。
購買時傳要購買商品的ID(在App Store Connect 創建的產品ID)就可以了。
/// 請求蘋果的服務器能夠銷售的商品
/// @param products 【產品ID】
- (void)requestProductsWithProductArray:(NSArray *)products
{
NSSet *set = [[NSSet alloc] initWithArray:products];
// "異步"請求蘋果能否銷售
SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers:set];
request.delegate = self;
// 啓動請求
[request start];
}
2、蘋果服務器返回的可購買商品
#pragma mark - SKProductsRequestDelegate
/// 獲取請求結果,把商品加入到自己的商品列表
/// @param request 請求
/// @param response 返回結果
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{
if (self.productDict == nil) {
self.productDict = [NSMutableDictionary dictionaryWithCapacity:response.products.count];
}
NSMutableArray *productArray = [NSMutableArray array];
for (SKProduct *product in response.products) {
//NSLog(@"%@", product.productIdentifier);
[self.productDict setObject:product forKey:product.productIdentifier];
[productArray addObject:product];
}
// 通知代理
[self.delegate IAPToolGotProducts:productArray];
}
3、下單購買商品
拿到了蘋果服務器返回的可購買商品後,下單進行購買。
/// 下單購買商品
/// @param productID 商品ID
- (void)buyProduct:(NSString *)productID
{
// 從自己的商品列表中取出要購買的商品
SKProduct *product = self.productDict[productID];
// 要購買的產品生成單據
SKPayment *payment = [SKPayment paymentWithProduct:product];
// 加入隊列準備付款購買
[[SKPaymentQueue defaultQueue] addPayment:payment];
}
4、購買隊列狀態變化,判斷購買狀態是否成功
typedef NS_ENUM(NSInteger, SKPaymentTransactionState) {
SKPaymentTransactionStatePurchasing, //交易被添加到服務器隊列中
SKPaymentTransactionStatePurchased, // 交易正在排隊,用戶已被收費。客戶應完成交易
SKPaymentTransactionStateFailed, // 交易在添加到服務器隊列之前被取消或失敗
SKPaymentTransactionStateRestored, // 交易已從用戶的購買歷史中恢復
SKPaymentTransactionStateDeferred, // 等待外部操作
};
#pragma mark - SKPaymentTransaction Observer
#pragma mark 購買隊列狀態變化,判斷購買狀態是否成功
/// 當交易數組發生更改(添加或狀態更改)時發送。客戶端應該檢查交易的狀態並適當地完成
/// @param queue 隊列
/// @param transactions 交易
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
{
// 處理結果
for (SKPaymentTransaction *transaction in transactions) {
NSLog(@"隊列狀態變化 %@", transaction);
// 如果收據狀態是購買完成
switch (transaction.transactionState) {
case SKPaymentTransactionStatePurchased: { // 完成交易
//NSLog(@"購買完成 %@", transaction.payment.productIdentifier);
if (self.CheckAfterPay) {
// 需要向蘋果服務器驗證一下
// 通知代理
[self.delegate IAPToolBeginCheckingdWithProductID:transaction.payment.productIdentifier];
// 驗證購買憑據
[self verifyPruchaseWithID:transaction.payment.productIdentifier];
} else {
// 不需要向蘋果服務器驗證
// 驗證憑據,獲取到蘋果返回的交易憑據
// appStoreReceiptURL iOS7.0增加的,購買交易完成後,會將憑據存放在該地址
NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
// 從沙盒中獲取到購買憑據
NSData *receiptData = [NSData dataWithContentsOfURL:receiptURL];
NSString *encodeStr = [receiptData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
// 通知代理
[self.delegate IAPToolBoughtProductSuccessedWithProductID:transaction.payment.productIdentifier
andInfo:nil receipt:encodeStr];
}
// 將交易從交易隊列中刪除
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
}
break;
case SKPaymentTransactionStateRestored: { // 恢復購買
//NSLog(@"恢復成功 :%@", transaction.payment.productIdentifier);
// 通知代理
[self.delegate IAPToolRestoredProductID:transaction.payment.productIdentifier];
// 將交易從交易隊列中刪除
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
}
break;
case SKPaymentTransactionStateFailed: { // 加入隊列之前取消或失敗
// 將交易從交易隊列中刪除
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
//NSLog(@"交易失敗");
[self.delegate IAPToolCanceldWithProductID:transaction.payment.productIdentifier];
}
break;
case SKPaymentTransactionStatePurchasing: { // 交易被添加到服務器隊列中
NSLog(@"正在購買");
}
break;
default: {
NSLog(@"state:%ld",(long)transaction.transactionState);
// 將交易從交易隊列中刪除
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
}
break;
}
}
}
5、交易驗證
// 發送網絡POST請求,對購買憑據進行驗證
// 沙盒測試 https://sandbox.itunes.apple.com/verifyReceipt
// 正式環境 https://buy.itunes.apple.com/verifyReceipt
當SKPaymentTransactionStatePurchased 完成交易時,我們需要驗證一下。
a、拿到收據上傳到自己的服務器進行驗證。
NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
// 從沙盒中獲取到購買憑據
NSData *receiptData = [NSData dataWithContentsOfURL:receiptURL];
NSString *encodeStr = [receiptData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
b、如果是單機就本地向蘋果服務器請求驗證。
/// 驗證購買憑據
/// @param ProductID 商品ID
- (void)verifyPruchaseWithID:(NSString *)ProductID
{
// 驗證憑據,獲取到蘋果返回的交易憑據
// appStoreReceiptURL iOS7.0增加的,購買交易完成後,會將憑據存放在該地址
NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
// 從沙盒中獲取到購買憑據
NSData *receiptData = [NSData dataWithContentsOfURL:receiptURL];
// 發送網絡POST請求,對購買憑據進行驗證
//In the test environment, use https://sandbox.itunes.apple.com/verifyReceipt
//In the real environment, use https://buy.itunes.apple.com/verifyReceipt
// Create a POST request with the receipt data.
NSURL *url = [NSURL URLWithString:checkURL];
NSLog(@"checkURL:%@",checkURL);
// 國內訪問蘋果服務器比較慢,timeoutInterval需要長一點
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:20.0f];
request.HTTPMethod = @"POST";
NSString *encodeStr = [receiptData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
NSString *payload = [NSString stringWithFormat:@"{\"receipt-data\" : \"%@\"}", encodeStr];
NSData *payloadData = [payload dataUsingEncoding:NSUTF8StringEncoding];
request.HTTPBody = payloadData;
// 提交驗證請求,並獲得官方的驗證JSON結果
[[[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSData *result = data;
// 官方驗證結果爲空
if (result == nil) {
//NSLog(@"驗證失敗");
//驗證失敗,通知代理
[self.delegate IAPToolCheckFailedWithProductID:ProductID
andInfo:result];
}
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:result
options:NSJSONReadingAllowFragments error:nil];
//NSLog(@"RecivedVerifyPruchaseDict:%@", dict);
if (dict != nil) {
// 驗證成功,通知代理
[self.delegate IAPToolBoughtProductSuccessedWithProductID:ProductID
andInfo:dict receipt:encodeStr];
} else {
//驗證失敗,通知代理
[self.delegate IAPToolCheckFailedWithProductID:ProductID
andInfo:result];
}
}] resume];
}
6、拿到的收據信息是,此App所有購買的記錄
{
environment = Sandbox;
receipt = {
"adam_id" = 0;
"app_item_id" = 0;
"application_version" = 5;
"bundle_id" = "com.fly.app";
"download_id" = 0;
"in_app" = (
{
"is_trial_period" = false;
"original_purchase_date" = "2020-07-04 12:56:09 Etc/GMT";
"original_purchase_date_ms" = 1587214569000;
"original_purchase_date_pst" = "2020-07-04 05:56:09 America/Los_Angeles";
"original_transaction_id" = 1000000653555670;
"product_id" = VIP1;
"purchase_date" = "2020-07-04 12:56:09 Etc/GMT";
"purchase_date_ms" = 1587214569000;
"purchase_date_pst" = "2020-07-04 05:56:09 America/Los_Angeles";
quantity = 1;
"transaction_id" = 1000000653555670;
},
{
"is_trial_period" = false;
"original_purchase_date" = "2020-07-04 14:38:05 Etc/GMT";
"original_purchase_date_ms" = 1587220685000;
"original_purchase_date_pst" = "2020-04-18 07:38:05 America/Los_Angeles";
"original_transaction_id" = 1000000653568586;
"product_id" = VIP2;
"purchase_date" = "2020-07-04 14:38:05 Etc/GMT";
"purchase_date_ms" = 1587220685000;
"purchase_date_pst" = "2020-07-04 07:38:05 America/Los_Angeles";
quantity = 1;
"transaction_id" = 1000000653568586;
}
);
"original_application_version" = "1.0";
"original_purchase_date" = "2013-08-01 07:00:00 Etc/GMT";
"original_purchase_date_ms" = 1375340400000;
"original_purchase_date_pst" = "2013-08-01 00:00:00 America/Los_Angeles";
"receipt_creation_date" = "2020-07-04 07:08:53 Etc/GMT";
"receipt_creation_date_ms" = 1593832014000;
"receipt_creation_date_pst" = "2020-07-04 00:08:53 America/Los_Angeles";
"receipt_type" = ProductionSandbox;
"request_date" = "2020-07-04 07:08:55 Etc/GMT";
"request_date_ms" = 1593832035030;
"request_date_pst" = "2020-07-04 00:08:55 America/Los_Angeles";
"version_external_identifier" = 0;
};
status = 0;
}
7、恢復商品
非消耗型項目一定要有恢復商品的功能,不會被拒絕哦~
/// 恢復商品
- (void)restorePurchase
{
// 恢復已經完成的所有交易.(僅限永久有效商品)
[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
}
二、詳細代碼
封裝內購工具類
FSInAppPurchaseTool.h
#import <Foundation/Foundation.h>
#import <StoreKit/StoreKit.h>
NS_ASSUME_NONNULL_BEGIN
/// 內購工具的代理
@protocol FSInAppPurchaseToolDelegate <NSObject>
/// 系統錯誤
-(void)IAPToolSysWrong;
/// 可購買商品
/// @param products 商品數組
-(void)IAPToolGotProducts:(NSMutableArray *)products;
/// 購買成功
/// @param productID 購買成功的商品ID
/// @param infoDic 官方驗證結果
/// @param receipt 憑證
-(void)IAPToolBoughtProductSuccessedWithProductID:(NSString *)productID
andInfo:(nullable NSDictionary *)infoDic receipt:(nonnull NSString *)receipt;
/// 取消購買
/// @param productID 商品ID
-(void)IAPToolCanceldWithProductID:(NSString *)productID;
/// 購買成功,開始驗證購買
/// @param productID 商品ID
-(void)IAPToolBeginCheckingdWithProductID:(NSString *)productID;
/// 驗證失敗
/// @param productID 商品ID
/// @param infoData 官方驗證結果
-(void)IAPToolCheckFailedWithProductID:(NSString *)productID
andInfo:(NSData *)infoData;
/// 恢復了已購買的商品(永久性商品)
/// @param productID 商品ID
-(void)IAPToolRestoredProductID:(NSString *)productID;
/// 恢復了已購買的商品(永久性商品)
/// @param products 商品信息
/// @param receipt 憑證
-(void)IAPToolPaymentQueueRestoreCompletedTransactionsFinished:(NSArray *)products receipt:(nonnull NSString *)receipt;
@optional
/// 連接itunes store 錯誤
/// @param error 錯誤信息
-(void)IAPToolPaymentQueueRestoreCompletedTransactionsFailedWithError:(NSString *)error;
@end
#pragma mark -FSInAppPurchaseTool
/// 內購工具
@interface FSInAppPurchaseTool : NSObject
@property (nonatomic, weak) id <FSInAppPurchaseToolDelegate> delegate;
/// 購買完後是否在iOS端向服務器驗證一次,默認爲YES
@property (nonatomic, assign) BOOL CheckAfterPay;
+ (FSInAppPurchaseTool *)defaultTool;
/// 詢問蘋果的服務器能夠銷售哪些商品
/// @param products 商品ID的數組
- (void)requestProductsWithProductArray:(NSArray *)products;
/// 用戶決定購買商品
/// @param productID 商品ID
- (void)buyProduct:(NSString *)productID;
/// 恢復商品(僅限永久有效商品)
- (void)restorePurchase;
@end
NS_ASSUME_NONNULL_END
FSInAppPurchaseTool.m
#import "FSInAppPurchaseTool.h"
/// 蘋果服務器購買憑據進行驗證
#ifdef DEBUG
#define checkURL @"https://sandbox.itunes.apple.com/verifyReceipt"
#else
#define checkURL @"https://buy.itunes.apple.com/verifyReceipt"
#endif
@interface FSInAppPurchaseTool ()<SKPaymentTransactionObserver,SKProductsRequestDelegate>
/// 商品字典
@property(nonatomic,strong)NSMutableDictionary *productDict;
@end
@implementation FSInAppPurchaseTool
static FSInAppPurchaseTool *storeTool;
+ (FSInAppPurchaseTool *)defaultTool{
if(!storeTool){
storeTool = [FSInAppPurchaseTool new];
[storeTool setup];
}
return storeTool;
}
#pragma mark 初始化
- (void)setup{
self.CheckAfterPay = YES;
// 設置購買隊列的監聽器
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
}
#pragma mark 請求蘋果的服務器能夠銷售的商品
/// 請求蘋果的服務器能夠銷售的商品
/// @param products 產品
- (void)requestProductsWithProductArray:(NSArray *)products
{
// 能夠銷售的商品
NSSet *set = [[NSSet alloc] initWithArray:products];
// "異步"請求蘋果能否銷售
SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers:set];
request.delegate = self;
// 啓動請求
[request start];
}
#pragma mark - SKProductsRequestDelegate
/// 獲取請求結果,把商品加入到自己的商品列表
/// @param request 請求
/// @param response 返回結果
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{
if (self.productDict == nil) {
self.productDict = [NSMutableDictionary dictionaryWithCapacity:response.products.count];
}
NSMutableArray *productArray = [NSMutableArray array];
for (SKProduct *product in response.products) {
//NSLog(@"%@", product.productIdentifier);
[self.productDict setObject:product forKey:product.productIdentifier];
[productArray addObject:product];
}
// 通知代理
[self.delegate IAPToolGotProducts:productArray];
}
#pragma mark - 下單購買商品
/// 下單購買商品
/// @param productID 商品ID
- (void)buyProduct:(NSString *)productID
{
// 從自己的商品列表中取出要購買的商品
SKProduct *product = self.productDict[productID];
// 要購買的產品生成單據
SKPayment *payment = [SKPayment paymentWithProduct:product];
// 加入隊列準備付款購買
[[SKPaymentQueue defaultQueue] addPayment:payment];
}
#pragma mark - SKPaymentTransaction Observer
#pragma mark 購買隊列狀態變化,判斷購買狀態是否成功
/// 當交易數組發生更改(添加或狀態更改)時發送。客戶端應該檢查事務的狀態並適當地完成
/// @param queue 隊列
/// @param transactions 交易
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
{
// 處理結果
for (SKPaymentTransaction *transaction in transactions) {
NSLog(@"隊列狀態變化 %@", transaction);
// 如果收據狀態是購買完成
switch (transaction.transactionState) {
case SKPaymentTransactionStatePurchased: { // 完成交易
//NSLog(@"購買完成 %@", transaction.payment.productIdentifier);
if (self.CheckAfterPay) {
// 需要向蘋果服務器驗證一下
// 通知代理
[self.delegate IAPToolBeginCheckingdWithProductID:transaction.payment.productIdentifier];
// 驗證購買憑據
[self verifyPruchaseWithID:transaction.payment.productIdentifier];
} else {
// 不需要向蘋果服務器驗證
// 驗證憑據,獲取到蘋果返回的交易憑據
// appStoreReceiptURL iOS7.0增加的,購買交易完成後,會將憑據存放在該地址
NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
// 從沙盒中獲取到購買憑據
NSData *receiptData = [NSData dataWithContentsOfURL:receiptURL];
NSString *encodeStr = [receiptData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
// 通知代理
[self.delegate IAPToolBoughtProductSuccessedWithProductID:transaction.payment.productIdentifier
andInfo:nil receipt:encodeStr];
}
// 將交易從交易隊列中刪除
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
}
break;
case SKPaymentTransactionStateRestored: { // 恢復購買
//NSLog(@"恢復成功 :%@", transaction.payment.productIdentifier);
// 通知代理
[self.delegate IAPToolRestoredProductID:transaction.payment.productIdentifier];
// 將交易從交易隊列中刪除
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
}
break;
case SKPaymentTransactionStateFailed: { // 加入隊列之前取消或失敗
// 將交易從交易隊列中刪除
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
//NSLog(@"交易失敗");
[self.delegate IAPToolCanceldWithProductID:transaction.payment.productIdentifier];
}
break;
case SKPaymentTransactionStatePurchasing: { // 交易被添加到服務器隊列中
NSLog(@"正在購買");
}
break;
default: {
NSLog(@"state:%ld",(long)transaction.transactionState);
// 將交易從交易隊列中刪除
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
}
break;
}
}
}
/// 當用戶購買歷史中的所有事務都已成功添加回隊列時發送。
/// @param queue 隊列
- (void)paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue {
NSMutableArray *products = [[NSMutableArray alloc] init];
NSLog(@"received restored transactions: %lu", (unsigned long)queue.transactions.count);
for (SKPaymentTransaction *transaction in queue.transactions)
{
[products addObject:transaction.payment.productIdentifier];
}
NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
NSData *receiptData = [NSData dataWithContentsOfURL:receiptURL];
NSString *encodeStr = [receiptData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
[self.delegate IAPToolPaymentQueueRestoreCompletedTransactionsFinished:products receipt:encodeStr];
}
/// 當事務從隊列中移除時發送(通過finishTransaction:)
/// @param queue 隊列
/// @param transactions 交易
- (void)paymentQueue:(SKPaymentQueue *)queue removedTransactions:(NSArray<SKPaymentTransaction *> *)transactions API_AVAILABLE(ios(3.0), macos(10.7)) {
}
/// 在將用戶購買歷史記錄中的事務添加回隊列時遇到錯誤時發送
/// @param queue 隊列
/// @param error 錯誤信息
- (void)paymentQueue:(SKPaymentQueue *)queue restoreCompletedTransactionsFailedWithError:(NSError *)error API_AVAILABLE(ios(3.0), macos(10.7)) {
NSDictionary *userinfo = [[NSDictionary alloc] initWithDictionary:error.userInfo];
if(userinfo) {
NSString *str = userinfo[NSLocalizedDescriptionKey];
if (str.length) {
if ([self.delegate respondsToSelector:@selector(IAPToolPaymentQueueRestoreCompletedTransactionsFailedWithError:)]) {
[self.delegate IAPToolPaymentQueueRestoreCompletedTransactionsFailedWithError:str];
}
}
} else {
if ([self.delegate respondsToSelector:@selector(IAPToolPaymentQueueRestoreCompletedTransactionsFailedWithError:)]) {
[self.delegate IAPToolPaymentQueueRestoreCompletedTransactionsFailedWithError:@""];
}
}
}
#pragma mark - 恢復商品
/// 恢復商品
- (void)restorePurchase
{
// 恢復已經完成的所有交易.(僅限永久有效商品)
[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
}
#pragma mark 驗證購買憑據
/// 驗證購買憑據
/// @param ProductID 商品ID
- (void)verifyPruchaseWithID:(NSString *)ProductID
{
// 驗證憑據,獲取到蘋果返回的交易憑據
// appStoreReceiptURL iOS7.0增加的,購買交易完成後,會將憑據存放在該地址
NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
// 從沙盒中獲取到購買憑據
NSData *receiptData = [NSData dataWithContentsOfURL:receiptURL];
// 發送網絡POST請求,對購買憑據進行驗證
//In the test environment, use https://sandbox.itunes.apple.com/verifyReceipt
//In the real environment, use https://buy.itunes.apple.com/verifyReceipt
// Create a POST request with the receipt data.
NSURL *url = [NSURL URLWithString:checkURL];
NSLog(@"checkURL:%@",checkURL);
// 國內訪問蘋果服務器比較慢,timeoutInterval需要長一點
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:20.0f];
request.HTTPMethod = @"POST";
NSString *encodeStr = [receiptData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
NSString *payload = [NSString stringWithFormat:@"{\"receipt-data\" : \"%@\"}", encodeStr];
NSData *payloadData = [payload dataUsingEncoding:NSUTF8StringEncoding];
request.HTTPBody = payloadData;
// 提交驗證請求,並獲得官方的驗證JSON結果
[[[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSData *result = data;
// 官方驗證結果爲空
if (result == nil) {
//NSLog(@"驗證失敗");
//驗證失敗,通知代理
[self.delegate IAPToolCheckFailedWithProductID:ProductID
andInfo:result];
}
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:result
options:NSJSONReadingAllowFragments error:nil];
//NSLog(@"RecivedVerifyPruchaseDict:%@", dict);
if (dict != nil) {
// 驗證成功,通知代理
[self.delegate IAPToolBoughtProductSuccessedWithProductID:ProductID
andInfo:dict receipt:encodeStr];
} else {
//驗證失敗,通知代理
[self.delegate IAPToolCheckFailedWithProductID:ProductID
andInfo:result];
}
}] resume];
}
@end
應用內購工具類
// 創建單例
{
FSInAppPurchaseTool *IAPTool = [FSInAppPurchaseTool defaultTool];
IAPTool.delegate = self;
}
/// 請求store產品
/// @param payno 服務器訂單號
/// @param pid store 產品id
- (void)startApplePayWithPayno:(NSString*)payno PID:(NSString*)pid {
if (!payno.length) {
ALERT(@"下訂單失敗,請稍後操作!");
return;
}
if (!pid.length) {
ALERT(@"請稍後操作!");
return;
}
[self showHUD];
[[FSInAppPurchaseTool defaultTool] requestProductsWithProductArray:@[pid]];
}
/// 恢復購買
- (IBAction)onRestoreButtonClick:(id)sender {
[self showHUD];
//檢查是否有恢復購買項
[[FSInAppPurchaseTool defaultTool] restorePurchase];
}
#pragma mark -------- FSInAppPurchaseToolDelegate
/// 蘋果返回可購買的商品,前往購買
/// @param products 商品數組【SKProduct】
-(void)IAPToolGotProducts:(NSMutableArray *)products {
NSLog(@"GotProducts:%@",products);
[self hideHUD];
if (products.count) {
SKProduct *product = products[0];
[self showHUD];
[[FSInAppPurchaseTool defaultTool] buyProduct:product.productIdentifier];
}
// for (SKProduct *product in products){
// NSLog(@"localizedDescription:%@\nlocalizedTitle:%@\nprice:%@\npriceLocale:%@\nproductID:%@",
// product.localizedDescription,
// product.localizedTitle,
// product.price,
// product.priceLocale,
// product.productIdentifier);
// NSLog(@"--------------------------");
// }
}
/// 支付失敗/取消
/// @param productID 商品id
-(void)IAPToolCanceldWithProductID:(NSString *)productID {
NSLog(@"canceld:%@",productID);
[self hideHUD];
}
/// 支付成功 本地向蘋果服務器進行驗證 (CheckAfterPay爲YES 執行此步驟)
/// @param productID 商品id
-(void)IAPToolBeginCheckingdWithProductID:(NSString *)productID {
FSLog(@"BeginChecking:%@",productID);
[self hideHUD];
}
/// 支付成功,拿到收據傳到自己的服務器進行驗證 (CheckAfterPay爲NO 執行此步驟,爲YES時,驗證成功也會執行)
/// @param productID 商品id
/// @param infoDic 驗證結果
/// @param receipt 收據
-(void)IAPToolBoughtProductSuccessedWithProductID:(NSString *)productID
andInfo:(nullable NSDictionary *)infoDic receipt:(nonnull NSString *)receipt {
FSLog(@"BoughtSuccessed:%@",productID);
FSLog(@"successedInfo:%@",infoDic);
[self hideHUD];
NSString *payno = self.payinfo[productID];
if (payno.length) {
// 請求自己服務器進行驗證
[self requestPortCheckApplePay:receipt Payno:payno];
} else {
FSLog(@"訂單號有誤");
}
}
/// 支付成功了,但向蘋果服務器驗證失敗了
/// @param productID 商品id
/// @param infoData 驗證結果
-(void)IAPToolCheckFailedWithProductID:(NSString *)productID
andInfo:(NSData *)infoData {
FSLog(@"CheckFailed:%@",productID);
[self hideHUD];
}
/// 挨個返回已購買的商品(僅限永久有效商品)
/// @param productID 商品id
-(void)IAPToolRestoredProductID:(NSString *)productID {
FSLog(@"Restored:%@",productID);
}
/// 返回所有已購買的記錄
/// @param products 商品數組
/// @param receipt 收據
-(void)IAPToolPaymentQueueRestoreCompletedTransactionsFinished:(NSArray *)products receipt:(NSString *)receipt {
FSLog(@"Restored Finished%@",products);
[self hideHUD];
self.restoreProducts = products;
self.restoreReceipt = receipt;
if (products.count) {
/// 有購買記錄就顯示恢復購買
self.restoreButton.hidden = NO;
if (self.restoreReceipt.length) {
// 向自己服務器請求恢復購買
[self requestPortRestore:self.restoreReceipt];
}
} else {
ALERT(@"沒有購買記錄,無需購買恢復");
}
}
/// 恢復購買失敗 (登錄appleid 彈窗 取消)
- (void)IAPToolPaymentQueueRestoreCompletedTransactionsFailedWithError:(NSString *)error {
FSLog(@"Restored Failed%@",error);
[self hideHUD];
}
//內購系統錯誤了
-(void)IAPToolSysWrong {
FSLog(@"SysWrong");
[self hideHUD];
}