iOS 应用内付费(IAP)开发步骤
测试的话不需要有上线产品,随便创一个应用就行了不过需要配置一些信息
上面圈出的里面的内容要全部填完才能成功
1.点击“Request”,填写一下Legal Entity的基本信息, 完成之后同意一个协议并提交
之后页面会变为
2.需要分别填写里面的内容,大致需要以下信息
姓名,邮箱,标题,电话号码,传真(可选)
CNAPS Code,这个号有的地方说是联行号,可以理解为每个银行支行的唯一ID吧,这个可以打电话问你银行卡开户行,就是他们那的一个唯一12位的标示号码,也可以通过苹果的Look up Transit Number去搜索。
银行账户号码 帐户持有人姓名
银行账户的货币,人命币是CNY
个人或组织名字
注册地-中国
contact
bank
tax
3.填写完毕后,进入我的app
选择功能
点击添加
没有填写上面信息的话只有一个免费订阅
现在进去填写相关信息,保存就行了
4.创建沙盒测试员,进行模拟测试
填写相关信息,测试的时候就用你这个测试的电子邮件和密码就行了
5.代码方面
导入库文件
// ViewController.m
// ApplePayTest
//
// Created by apple on 15/9/28.
// Copyright (c) 2015年 tqh. All rights reserved.
//
#import "ViewController.h"
#import <StoreKit/StoreKit.h>
@interface ViewController ()<SKProductsRequestDelegate,SKPaymentTransactionObserver>
@end
@implementation ViewController
- (void)dealloc {
[[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
}
- (void)viewDidLoad {
[super viewDidLoad];
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
NSLog(@"点击屏幕获取产品列表信息");
}
// 下面的ProductId应该是事先在itunesConnect中添加好的,已存在的付费项目。否则查询会失败。
- (void)getProductInfo {
//这里填你的产品id,根据创建的名字
//ProductIdofvip
//ProductId
NSSet * set = [NSSet setWithArray:@[@"ProductId"]];
SKProductsRequest * request = [[SKProductsRequest alloc] initWithProductIdentifiers:set];
request.delegate = self;
[request start];
NSLog(@"请求开始请等待...");
}
#pragma mark - 以上查询的回调函数-------
// 以上查询的回调函数
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response {
//
NSArray *myProduct = response.products;
NSLog(@"%@",myProduct);
if (myProduct.count == 0) {
NSLog(@"无法获取产品信息,购买失败。");
return;
}
SKPayment * payment = [SKPayment paymentWithProduct:myProduct[0]];
[[SKPaymentQueue defaultQueue] addPayment:payment];
}
#pragma mark - 🚩🚩🚩🚩🚩🚩🚩🚩事件监听
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
//查询是否允许内付费
if ([SKPaymentQueue canMakePayments]) {
// 执行下面提到的第5步:
[self getProductInfo];
} else {
NSLog(@"失败,用户禁止应用内付费购买.");
}
}
#pragma mark - others 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://交易失败
NSLog(@"交易失败");
[self failedTransaction:transaction];
break;
case SKPaymentTransactionStateRestored://已经购买过该商品
NSLog(@"已经购买过该产品");
[self restoreTransaction:transaction];
break;
case SKPaymentTransactionStatePurchasing: //商品添加进列表
NSLog(@"商品添加进列表");
break;
default:
break;
}
}
}
- (void)completeTransaction:(SKPaymentTransaction *)transaction {
// Your application should implement these two methods.
NSLog(@"---------进入了这里");
NSString * productIdentifier = transaction.payment.productIdentifier;
//transaction.transactionReceipt
// NSString * receipt = [[NSString alloc]initWithData:transaction.transactionReceipt encoding:NSUTF8StringEncoding];
//这里要用base64编码
//
// NSLog(@"%@",receipt);
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];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
@end
用起来不怎么方便,封装了下:
// WJIAPManager.h
// ApplePayTest
//
// Created by apple on 15/10/8.
// Copyright (c) 2015年 tqh. All rights reserved.
//
#import <Foundation/Foundation.h>
typedef void (^successfulBlock)();
typedef void (^failureBlock)();
typedef void (^cancelBlock)();
@interface WJIAPManager : NSObject
//初始化的时候用
//+ (instancetype)instance;
//调用的时候用
+ (void)startIapWithProductId:(NSString *)ProductId
successful:(successfulBlock)successful
failure:(failureBlock)failure
cancel:(cancelBlock)cancel ;
@end
// WJIAPManager.m
// ApplePayTest
//
// Created by apple on 15/10/8.
// Copyright (c) 2015年 tqh. All rights reserved.
//
#import "WJIAPManager.h"
#import <StoreKit/StoreKit.h>
static successfulBlock _successfulBlock;
static failureBlock _failureBlock;
static cancelBlock _cancelBlock;
__strong static WJIAPManager *_manager = nil;
@interface WJIAPManager ()<SKProductsRequestDelegate,SKPaymentTransactionObserver> {
SKPaymentTransaction *_transaction;
}
@end
@implementation WJIAPManager
- (void)dealloc {
[[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
}
+ (instancetype)instance {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_manager = [[WJIAPManager alloc]init];
[_manager initIap];
});
return _manager;
}
- (void)initIap {
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
}
+ (void)startIapWithProductId:(NSString *)ProductId
successful:(successfulBlock)successful
failure:(failureBlock)failure
cancel:(cancelBlock)cancel {
[WJIAPManager instance];
_successfulBlock = [successful copy];
_failureBlock = [failure copy];
_cancelBlock = [cancel copy];
[_manager startIapWithProductId:ProductId];
}
- (void)startIapWithProductId:(NSString *)ProductId {
//查询是否允许内付费
if ([SKPaymentQueue canMakePayments]) {
// 执行下面提到的第5步:
[self getProductInfoWithProductId:(NSString *)ProductId];
} else {
NSLog(@"失败,用户禁止应用内付费购买.");
}
}
+ (void)finish {
[_manager finish];
}
- (void)finish {
[[SKPaymentQueue defaultQueue] finishTransaction: _transaction];
}
// 下面的ProductId应该是事先在itunesConnect中添加好的,已存在的付费项目。否则查询会失败。
- (void)getProductInfoWithProductId:(NSString *)ProductId {
//这里填你的产品id,根据创建的名字
//ProductIdofvip
//ProductId
//com.mai.moaivip
NSSet * set = [NSSet setWithArray:@[ProductId]];
SKProductsRequest * request = [[SKProductsRequest alloc] initWithProductIdentifiers:set];
request.delegate = self;
[request start];
NSLog(@"请求开始请等待...");
}
#pragma mark - 以上查询的回调函数-------
// 以上查询的回调函数
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response {
//
NSArray *myProduct = response.products;
NSLog(@"%@",myProduct);
if (myProduct.count == 0) {
NSLog(@"无法获取产品信息,购买失败。");
return;
}
SKPayment * payment = [SKPayment paymentWithProduct:myProduct[0]];
[[SKPaymentQueue defaultQueue] addPayment:payment];
}
#pragma mark - others SKPaymentTransactionObserver
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions {
for (SKPaymentTransaction *transaction in transactions)
{
switch (transaction.transactionState)
{
case SKPaymentTransactionStatePurchased://交易完成
NSLog(@"transactionIdentifier = %@", transaction.transactionIdentifier);
[WJIAPManager completeTransaction:transaction];
break;
case SKPaymentTransactionStateFailed://交易失败
NSLog(@"交易失败");
[WJIAPManager failedTransaction:transaction];
break;
case SKPaymentTransactionStateRestored://已经购买过该商品
NSLog(@"已经购买过该产品");
[self restoreTransaction:transaction];
break;
case SKPaymentTransactionStatePurchasing: //商品添加进列表
NSLog(@"商品添加进列表");
break;
default:
break;
}
}
}
+ (void)completeTransaction:(SKPaymentTransaction *)transaction {
// Your application should implement these two methods.
NSLog(@"---------进入了这里");
NSString * productIdentifier = transaction.payment.productIdentifier;
//transaction.transactionReceipt
// NSString * receipt = [[NSString alloc]initWithData:transaction.transactionReceipt encoding:NSUTF8StringEncoding];
//这里要用base64编码
// NSLog(@"%@",receipt);
if ([productIdentifier length] > 0) {
// 向自己的服务器验证购买凭证
}
_successfulBlock();
[[SKPaymentQueue defaultQueue] finishTransaction: transaction];
}
+ (void)failedTransaction:(SKPaymentTransaction *)transaction {
if(transaction.error.code != SKErrorPaymentCancelled) {
NSLog(@"购买失败");
_failureBlock();
} else {
NSLog(@"用户取消交易");
_cancelBlock();
}
[[SKPaymentQueue defaultQueue] finishTransaction: transaction];
}
- (void)restoreTransaction:(SKPaymentTransaction *)transaction {
// 对于已购商品,处理恢复购买的逻辑
[[SKPaymentQueue defaultQueue] finishTransaction: transaction];
}
@end
内购价格表:
差不多就这样的,弄清楚流程就简单了,如果觉得还没怎么弄懂的话就看下面一些链接吧,-0-
网址链接
iOS应用内购内付费:http://blog.csdn.net/shenjie12345678/article/details/40978977
iap(程序内购买)完全攻略:http://fei263.blog.163.com/blog/static/927937242011321105241823/
iOS应用内付费开发步骤:http://blog.csdn.net/xiaoxiangzhu660810/article/details/17434907
iOS应用内付费开发步骤列表:http://www.cocoachina.com/industry/20130313/5814.html
iOS应用iap设置总结:http://www.cocoachina.com/ios/20120214/3976.html
补充:
可能会出现一些错误
Error Domain=SKErrorDomain Code=0 "Cannot connect to iTunes Store" UserInfo=0x7fe263f12ff0 {NSLocalizedDescription=Cannot connect to iTunes Store}
这个原因最大可能是你用的模拟器,需要用真机测试
流程:
1.后台有配好商品,传入的productid要和配得一致 2、bundle id要一致 3、要真机测试,要有沙盒测试账号,真机上面的AppStore登录的非沙盒账号要注销
其他情况链接:http://www.bubuko.com/infodetail-607353.html
有个第三方库封装了内购MKStoreKit,可以看下
github链接:https://github.com/MugunthKumar/MKStoreKit
demo链接:http://pan.baidu.com/s/1dDDagq1