内购项目-代码篇
一、分步骤说明
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];
}