简单记录。
1.协议填写
登录苹果商店中心直达链接选择协议条款填写信息。
进去填写资料即可,具体填写可参考[Lebus的文章]
。
2.创建商品
进入
我的App
-功能
-App内购买项目
-点击加号
选择对应的商品
ps:作者项目用到的是会员功能,选择的是非续期订阅,多次购买会提示续订或延长订阅时间达到续费的目的
具体创建商品设置
以上配置工程基本完成
未完成部分
1.工程中开启内购功能
2.沙盒账号添加(用于付款)
ps:1.不用退出手机设置中的APPID,内购时系统检测到沙盒环境(个人猜测)自动弹出登录框登录并保存沙盒账号,输入沙盒账号密码即可
2.退出沙盒账号。
设置
-APPID
-iTunes Store 与 App Store
- 最底部就可以看到沙盒账户,点击对应账户就有退出登录选项
实现APP内购买功能(代码部分)
头文件部分
#import
#import
NS_ASSUME_NONNULL_BEGIN
@class SuenAppStorePay;
@protocol SuenAppStrorePayDelegate
@optional
/// 内购支付成功回调
/// @param appStorePay 当前类
/// @param transaction 返回值
-(void)SuenAppStorePay:(SuenAppStorePay *)appStorePay responseAppStorePaySuccess:(SKPaymentTransaction *)transaction;
/// 内购支付结果回调提示
/// @param appStorePay 当前类
/// @param transaction 返回值
- (void)SuenAppStorePay:(SuenAppStorePay *)appStorePay responseAppStorePayStatusshow:(SKPaymentTransaction *)transaction;
@end
@interface SuenAppStorePay : NSObject
/**商品ID*/
@property (nonatomic,strong) NSString *goodsId;
@property (nonatomic,weak) id delegate;
+(instancetype)sharedInstance;
/// 购买商品
/// @param goodsID 商品ID
-(void)starBuyToAppStore:(NSString *)goodsID;
@end
NS_ASSUME_NONNULL_END
实现文件
#import "SuenAppStorePay.h"
@implementation SuenAppStorePay
+(instancetype)sharedInstance{
static SuenAppStorePay *s;
static dispatch_once_t onceToken;
dispatch_once(&onceToken,^{
s = [[SuenAppStorePay alloc]init];
});
return s;
}
-(instancetype)init{
self = [super init];
if (self) {
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
}
return self;
}
#pragma mark -释放TransactionObserver
-(void)dealloc{
[[SKPaymentQueue defaultQueue]removeTransactionObserver:self];
}
#pragma mark -购买商品
-(void)starBuyToAppStore:(NSString *)goodsID{
// 判断是否开启支付功能
if ([SKPaymentQueue canMakePayments]) {
[self getRequestAppleProduct:goodsID];
}else{
//提示开启支付功能
[FRObj showAlert:@"请开启支付功能" time:1];
}
}
#pragma makr -private 购买方法
-(void)getRequestAppleProduct:(NSString *)goodsID{
self.goodsId = goodsID;
SKProductsRequest *request = [[SKProductsRequest alloc]initWithProductIdentifiers:[NSSet setWithObject:goodsID]];
request.delegate = self;
[request start];
}
#pragma mark -SKProductsRequestDelegate
-(void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response{
SKProduct *product = nil;
if (response.products.count > 0) {
for (SKProduct *s in response.products) {
if ([s.productIdentifier isEqualToString:self.goodsId]) {
product = s;
}
}
if (product) {
// 发送购买请求
SKPayment *payment = [SKPayment paymentWithProduct:product];
[[SKPaymentQueue defaultQueue] addPayment:payment];
}
}else{
// 结束加载视图
NSLog(@"没有这个产品");
return;
}
}
-(void)request:(SKRequest *)request didFailWithError:(NSError *)error{
// 请求产品失败
NSLog(@"请求产品失败");
}
-(void)requestDidFinish:(SKRequest *)request{
// 请求产品结束
}
-(void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions{
// 购买状态
if (self.delegate && [self.delegate respondsToSelector:@selector(SuenAppStorePay:responseAppStorePayStatusshow:)]) {
if (transactions.count != 0) {
SKPaymentTransaction *transaction = transactions[0];
[self.delegate SuenAppStorePay:self responseAppStorePayStatusshow:transaction];
}
}
for (SKPaymentTransaction *transaction in transactions) {
switch (transaction.transactionState) {
case SKPaymentTransactionStatePurchased:
[self completeTransaction:transaction];
// 交易完成
break;
case SKPaymentTransactionStateRestored:
// 购买过
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
break;
case SKPaymentTransactionStateFailed:
// 交易失败
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
break;
default:
break;
}
}
}
#pragma mark ------ 支付完成
- (void)completeTransaction:(SKPaymentTransaction *)transaction{
// [transaction transactionIdentifier];
if (self.delegate && [self.delegate respondsToSelector:@selector(SuenAppStorePay:responseAppStorePaySuccess:)]) {
[self.delegate SuenAppStorePay:self responseAppStorePaySuccess:transaction];
}
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
}
@end
使用方法
@interface YourViewController ()
//设置代理
[SuenAppStorePay sharedInstance].delegate = self;
//出入商品ID
[[SuenAppStorePay sharedInstance] starBuyToAppStore:goodsId];
#pragma mark -SuenAppStorePayDelegate
-(void)SuenAppStorePay:(SuenAppStorePay *)appStorePay responseAppStorePayStatusshow:(SKPaymentTransaction *)transaction{
// 状态回调
switch (transaction.transactionState) {
case SKPaymentTransactionStateFailed:
NSLog(@"取消或失败");
break;
case SKPaymentTransactionStateRestored:
NSLog(@"从用户的购买历史中恢复。客户应完成交易");
break;
default:
break;
}
}
-(void)SuenAppStorePay:(SuenAppStorePay *)appStorePay responseAppStorePaySuccess:(SKPaymentTransaction *)transaction {
//支付完成,需要二次验证的在此操作(后台大佬不搞二次验证,苹果不建议APP内验证故没做)
}
Swift 简单版
import UIKit
import StoreKit
//Block模式
typealias SuenStorePayStatusBlock = (_ transaction :SKPaymentTransaction) ->(Void)
typealias SuenStorePaySuccessBlock = (_ transaction :SKPaymentTransaction) ->(Void)
//代理模式
protocol SuenIAPPayDelegate : NSObjectProtocol {
func SuenAppStorePayStatus(iapPay: SuenIAPPay,transaction: SKPaymentTransaction)
func SuenAppStorePaySuccess(iapPay: SuenIAPPay,transaction: SKPaymentTransaction)
}
class SuenIAPPay: NSObject,SKPaymentTransactionObserver,SKProductsRequestDelegate {
/// 商品id
var goodsId : String?
/// 代理
static weak var delegate : SuenIAPPayDelegate?
//Block
var statusBlock : SuenStorePayStatusBlock?
var successBlock : SuenStorePaySuccessBlock?
/// 单例
static let su : SuenIAPPay = {
let instance = SuenIAPPay()
SKPaymentQueue.default().add(instance)
return instance
}()
/// 实例购买方法
/// - Parameter goodsId: 商品id
func buyToAppStore(goodsId: String){
if SKPaymentQueue.canMakePayments() {
self.goodsId = goodsId
let set = NSSet.init(object: goodsId)
let productsRequest = SKProductsRequest.init(productIdentifiers: set as! Set)
productsRequest.delegate = self
productsRequest.start()
}else {
print("请开启支付功能")
}
}
/// 购买
/// - Parameter goodsId: 商品id
class func starBuyToAppStore(goodsId: String){
if SKPaymentQueue.canMakePayments() {
su.goodsId = goodsId
let set = NSSet.init(object: goodsId)
let productsRequest = SKProductsRequest.init(productIdentifiers: set as! Set)
productsRequest.delegate = su
productsRequest.start()
}else {
print("请开启支付功能")
}
}
/// 支付完成
/// - Parameter transaction: 购买的产品
func completeTransaction(transaction: SKPaymentTransaction){
if (SuenIAPPay.delegate != nil) {
SuenIAPPay.delegate?.SuenAppStorePaySuccess(iapPay: self, transaction: transaction)
}
SKPaymentQueue.default().finishTransaction(transaction)
}
///SKPaymentTransactionObserver
func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
if transactions.count > 0 {
SuenIAPPay.delegate?.SuenAppStorePayStatus(iapPay: SuenIAPPay.su, transaction: transactions[0])
}
for transaction in transactions {
switch transaction.transactionState {
case .purchased:
// 交易完成
self.completeTransaction(transaction: transaction)
break;
case .restored:
// 购买过
SKPaymentQueue.default().finishTransaction(transaction)
break
case .failed:
// 失败
SKPaymentQueue.default().finishTransaction(transaction)
break
default: break
}
}
}
///SKProductsRequestDelegate
func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {
if response.products.count > 0 {
var product : SKProduct?
for s in response.products {
if s.productIdentifier == SuenIAPPay.su.goodsId || s.productIdentifier == self.goodsId{
product = s
}
}
if (product != nil) {
let payment = SKPayment.init(product: product!)
SKPaymentQueue.default().add(payment)
}
}else{
print("没有这个产品")
}
}
func requestDidFinish(_ request: SKRequest) {
// 请求产品完成
}
func request(_ request: SKRequest, didFailWithError error: Error) {
// 请求失败
}
}
使用
import UIKit
import StoreKit
class ViewController: UIViewController,SuenIAPPayDelegate {
let suenIap = SuenIAPPay()
override func viewDidLoad() {
super.viewDidLoad()
/*
单例购买
SuenIAPPay.delegate = self
SuenIAPPay.starBuyToAppStore(goodsId: "goods123")
*/
//实例购买(Block)
suenIap.buyToAppStore(goodsId: "bdymember01")
suenIap.statusBlock = {(_ tr : SKPaymentTransaction) in
print("状态回调")
}
suenIap.successBlock = {(_ tr : SKPaymentTransaction) in
print("购买成功")
}
// Do any additional setup after loading the view.
}
// TODO:状态
func SuenAppStorePayStatus(iapPay: SuenIAPPay, transaction: SKPaymentTransaction) {
}
// TODO:交易完成
func SuenAppStorePaySuccess(iapPay: SuenIAPPay, transaction: SKPaymentTransaction) {
}
}