美文网首页
100行代码搞定苹果IAP应用内购

100行代码搞定苹果IAP应用内购

作者: _moses | 来源:发表于2017-07-20 22:30 被阅读3297次
#import "ViewController.h"
#import <StoreKit/StoreKit.h>

@interface ViewController () <SKPaymentTransactionObserver, SKProductsRequestDelegate>

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor whiteColor];
}
// 添加支付监听
- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [[SKPaymentQueue defaultQueue] addTransactionObserver:self];
}
// 移除支付监听
- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    [[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    // 模拟用户选择了6元档
    [self pay:6];
}

- (void)pay:(NSInteger)money {
    if ([SKPaymentQueue canMakePayments]) {
        // 此处建议为bundleID.金额(假设我的bundleID为com.apple.pay)
        NSSet *productIDSet = [NSSet setWithObject:[NSString stringWithFormat:@"com.apple.pay.%zd", money]];
        SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers:productIDSet];
        request.delegate = self;
        [request start];
    }
}

- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response {
    if([response.products count] == 0) {
        return;
    }
    // 由于上面productID只传了一个值,此处只需要创建一个订单
    SKPayment *payment = [SKPayment paymentWithProduct:response.products[0]];
    [[SKPaymentQueue defaultQueue] addPayment:payment];
}

- (void)request:(SKRequest *)request didFailWithError:(NSError *)error {
    // 如果上面的productID不存在,就会报错
    NSLog(@"error:%@", error);
}

- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transaction {
    if (transaction.count == 0) {
        return;
    }
    for (SKPaymentTransaction *paymentTransaction in transaction) {
        switch (paymentTransaction.transactionState) {
            case SKPaymentTransactionStatePurchased: {
                // 为了安全,支付完成需要验证一下
                NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
                NSData *receiptData = [NSData dataWithContentsOfURL:receiptURL];
                NSString *receipt_data = [receiptData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
                NSDictionary *param = @{@"receipt-data": receipt_data};
                // 获取到receipt-data,需要拿他去请求苹果服务器
                [self completeTransaction:paymentTransaction param:param];
            }   break;
            case SKPaymentTransactionStateFailed:
                // 一定不要忘记完成订单,不然进到这个页面就会执行该监听方法:(paymentQueue:updatedTransactions:)而且无法购买相同金额的的产品
                [[SKPaymentQueue defaultQueue] finishTransaction:paymentTransaction];
                break;
            default:
                break;
        }
    }
}
// 该步骤验证需要在服务器操作,测试阶段可以先在客户端体验一下
- (void)completeTransaction:(SKPaymentTransaction *)transaction param:(NSDictionary *)param {
    NSData *data = [NSJSONSerialization dataWithJSONObject:param options:(NSJSONWritingPrettyPrinted) error:nil];
    // 正式环境应为(https://buy.itunes.apple.com/verifyReceipt)
    NSURL *url = [NSURL URLWithString:@"https://sandbox.itunes.apple.com/verifyReceipt"];
    NSMutableURLRequest *connectionRequest = [NSMutableURLRequest requestWithURL:url];
    [connectionRequest setHTTPMethod:@"POST"];
    [connectionRequest setCachePolicy:NSURLRequestUseProtocolCachePolicy];
    [connectionRequest setHTTPBody:data];
    
    NSError *error;
    NSData *responseData = [NSURLConnection sendSynchronousRequest:connectionRequest returningResponse:nil error:&error];
    if (error) {
        NSLog(@"error:%@",error);
        return;
    }
    NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingAllowFragments error:nil];
    NSLog(@"success:%@",dic);
    if ([dic[@"status"] integerValue] == 0) {
        // 如果status值为0说明支付成功,需要手动调用此方法;如果status为21007说明接口使用错误,此时为沙盒环境,需要用sandbox接口
        [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
    }
}

@end

相关文章

网友评论

      本文标题:100行代码搞定苹果IAP应用内购

      本文链接:https://www.haomeiwen.com/subject/jfajkxtx.html