iOS: 实现苹果的内购

来源:互联网 发布:尚宝网络 编辑:程序博客网 时间:2024/06/10 04:19

一、介绍:

在个人开发的app上架到AppStore后,苹果官方允许我们将自己的app在appstore上进行付费使用,也就是所谓的内购。其中,支付方式规定的必须是苹果的支付方式:应用内支付。

 

二、流程:

1、后台设置

(1)配置Developer.apple.com,为应用建立一个不带通配符的App ID

(2)用该应用的App ID生成和安装相应的Provisioning Profile文件

 

2、配置iTunes Connect

(1)用该App ID创建一个新的应用;

(2)在该应用中,创建应用内付费项目,选择付费类型,通常可选的是可重复消费的(Consumenable)和永久有效的(Non-Consumenable)两种,然后设置好价格、Product ID、购买介绍和截图,这里的Product ID是必须记住的,后面开发的时候要用到;

(3)添加一个用于在sandbox付费的测试用户,注意苹果对测试用户的密码要求和正是账号一样,至少8位,并且包包含数字和大小写字母;

(4)填写相关的税务。银行和联系人

 

3、iOS端开发

(1)在工程中引入storeKit.framework和#import <storeKit/storeKit.h>;

(2)获取所有的付费Product ID列表。这个可以用常量存储到本地,也可以由自己的服务器返回;

(3)制作一个界面(如tableView),显示所有的应用内付费项目。这些应用内付费项目的价格和介绍信息可以是自己的服务器返回。但如果是不带服务器的单机游戏应用或者工具类应用,则可以通过向App Store查询所得;

(4)当用户点击一个IAP项目,我们需要先查询用户是否允许应用内付费,如果不允许则不进行接下来的步骤;

(5)先通过该IAP的ProductID向AppStore查询,获取SKPayment实例,然后通过SKPaymentQueue的addPayment方法发起一个购买的操作;

(6)在ViewdidLoad方法中,将购买页面设置成购买额observe;

(7)当用户购买的操作有结果时,就会触发调用回调函数,相应的进行处理;

(8)服务器验证凭证(可选项)。如果购买成功,我们需要将凭证发送到服务器上进行验证。考虑到网路异常情况,iOS端的发送凭证操作应该可以持久化,如果程序退出、崩溃或者网络异常,可以恢复重试。

 

4、服务端开发

(1)接收iOS端发过来的购买凭证;

(2)判断凭证是否已经存在,是否验证过,然后进行存储;

(3)将该凭证发送到苹果的服务器验证,并将结果返回给客户端;

(4)如果需要,修改用户相应的会员权限。

注意:考虑到网络异常的情况,服务器的验证应该是一个可恢复的队列,如果失败了,应该进行重试。

苹果AppStore线上的购买凭证验证地址:htpps://buy.itunes.apple.com/verifyreceipt

测试的验证地址:htpps://sandbox.itunes.apple.com/verifyreceipt

 

三、iOS基本代码如下:

复制代码
//  ViewController.m////  Created by 夏远全 on 16/11/20.//  Copyright © 2016年 广州市东德网络科技有限公司. All rights reserved.//#import "ViewController.h"#import <StoreKit/StoreKit.h>@interface ViewController ()<SKProductsRequestDelegate,SKPaymentTransactionObserver>@end@implementation ViewController- (void)viewDidLoad {    [super viewDidLoad];        //监听购买结果    [[SKPaymentQueue defaultQueue] addTransactionObserver:self];}-(void)dealloc{        //移除购买监听    [[SKPaymentQueue defaultQueue] removeTransactionObserver:self];}//用户点击一个IAP项目时,首先查询用户是否允许应用内付费(tableViewCell点击时,传递内购商品ProductId,ProductID可以提前存储到本地,用到时直接获取即可)-(void)validateIsCanBought{        if ([SKPaymentQueue canMakePayments]) {        [self getProductInfo:@[@"ProductIds"]];    }else{        NSLog(@"失败,用户禁止应用内付费购买");    }}//通过该IAP的Product ID向App Store查询,获取SKPayment实例,接着通过SKPaymentQueue的addPayment方法发起一个购买的操作//下面的ProductId应该是事先在itunesConnect中添加好的,已存在的付费项目,否则会查询失败-(void)getProductInfo:(NSArray *)productIds{        NSSet *set = [NSSet setWithArray:productIds];    SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers:set];    request.delegate = self;    [request start];}#pragma mark - SKProductsRequestDelegate//查询的回调函数-(void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response{        //获取到的所有内购商品    NSArray *myProducts = response.products;        //判断个数    if (myProducts.count==0) {        NSLog(@"无法获取产品信息,购买失败。");        return;    }        //发起一个购买操作    SKPayment *payment = [SKPayment paymentWithProduct:myProducts[0]];    [[SKPaymentQueue defaultQueue] addPayment:payment];}#pragma mark - SKPaymentTransactionObserver//当用户购买的操作有结果时,就会触发下面的回调函数,相应进行处理-(void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray<SKPaymentTransaction *> *)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;    NSData *transactionReceiptData = [NSData dataWithContentsOfURL:[[NSBundle mainBundle] appStoreReceiptURL]];    NSString *receipt = [transactionReceiptData base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];        if ([productIdentifier length]>0) {        //向自己的服务器验证购买凭证        NSLog(@"%@",receipt);    }        //移除transaction购买操作    [[SKPaymentQueue defaultQueue] finishTransaction:transaction];}//交易失败后的操作-(void)failedTransaction:(SKPaymentTransaction *)transaction{        if (transaction.error.code != SKErrorPaymentCancelled) {        NSLog(@"购买失败");    }else{        NSLog(@"用户取消交易");    }    //移除transaction购买操作    [[SKPaymentQueue defaultQueue] finishTransaction:transaction];}//已经购买过该商品-(void)restoreTransaction:(SKPaymentTransaction *)transaction{     //对于已购买商品,处理恢复购买的逻辑    //移除transaction购买操作    [[SKPaymentQueue defaultQueue] finishTransaction:transaction];}@end
0 0
原创粉丝点击