首先要引入#import <StoreKit/StoreKit.h>
本文介绍的是有服务器的情况下,已经从服务器获取到了productId
#import <StoreKit/StoreKit.h>
#import "IapManager.h"
@implementation IapManager {
NSMutableDictionary *products;
}
static IapManager *_instance;
+ (IapManager *)instance {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [[IapManager alloc] init];
});
return _instance;
}
- (id) init {
self = [super init];
products = [[NSMutableDictionary alloc] init];
return self;
}
/**
* productId: 已经从服务器获取到了productId
* outTradeNo: 服务器自己构建的校验订单
*/
+ (void)iapPay:(NSString *)productId
outTradeNo:(NSString *)outTradeNo {
[[IapManager instance] iapPay:productId
outTradeNo:outTradeNo];
}
/**
* 执行实际的支付逻辑
*/
- (void)iapPay:(NSString *)productId
outTradeNo:(NSString *)outTradeNo {
if (productId == nil || outTradeNo == nil) {
NSLog(@"iap pay fail, invalid parameter.");
// 此处应该通知客户端
return;
}
if (![SKPaymentQueue canMakePayments]) {
NSLog(@"iap pay fail, can not make payments.");
NSLog(@"失败,用户禁止应用内付费购买.");
// 此处应该通知客户端
return;
}
SKProduct *product = nil;
@synchronized (self) {
product = products[productId];
}
if (product == nil) {
NSLog(@"iap pay fail, no product info.");
// 此处应该通知客户端
return;
}
NSLog(@"iap start payment -> {productId:%@, outTradeNo:%@}",
productId,
outTradeNo);
SKMutablePayment *payment = [SKMutablePayment paymentWithProduct:product];
payment.quantity = 1;
payment.applicationUsername = outTradeNo;
[[SKPaymentQueue defaultQueue] addPayment:payment];
NSLog(@"iap inprogress.");
}
/**
* 监听Iap交易的状态
*/
- (void)paymentQueue:(SKPaymentQueue *)queue
updatedTransactions:(NSArray *)transactions {
NSLog(@"监听Iap交易的状态");
for (SKPaymentTransaction *trans in transactions) {
NSLog(@"%d",trans.error.code);
switch (trans.transactionState) {
case SKPaymentTransactionStatePurchased:
NSLog(@"交易ok");
[self transactionSuccess:trans];
break;
case SKPaymentTransactionStatePurchasing:
NSLog(@"交易中");
//[self transactionAbort:trans];
// 正在支付中这个状态,会在刚刚发起支付,弹出用户名密码对话框的时候调用一次。
break;
case SKPaymentTransactionStateFailed:
[self transactionFail:trans];
break;
case SKPaymentTransactionStateDeferred:
NSLog(@"交易deferred");
// 这个状态应该是在出现家长监护的时候出现。
break;
case SKPaymentTransactionStateRestored:
// 不存在不同设备间恢复的问题,因此直接结束当前的订单。
[self transactionFinish:trans];
break;
default:
// 不知名情况的订单,也直接结束掉。
[self transactionFinish:trans];
break;
}
}
}
/**
* 交易成功。
*/
- (void)transactionSuccess:(SKPaymentTransaction *)trans {
NSLog(@"交易成功");
if (trans == nil) {
return;
}
NSURL *receiptUrl = [[NSBundle mainBundle] appStoreReceiptURL];
NSData *receipt = [NSData dataWithContentsOfURL:receiptUrl];
NSString *receiptDataString = [receipt base64EncodedStringWithOptions:0];
NSString *outTradeNo = trans.payment.applicationUsername;
NSString *productId = trans.payment.productIdentifier;
NSLog(@"注意transactionIdentifier %@",trans.transactionIdentifier);
NSLog(@"iap pay success. productId:%@, outTradeNo:%@, receipt:%@",
productId,
outTradeNo,
receiptDataString);
// 此处应该通知客户端
[[SKPaymentQueue defaultQueue] finishTransaction:trans];
}
/**
* 交易失败
*/
- (void)transactionFail:(SKPaymentTransaction *)trans {
NSLog(@"交易失败");
if (trans == nil) {
return;
}
NSString *outTradeNo = trans.payment.applicationUsername;
NSString *productId = trans.payment.productIdentifier;
NSLog(@"iap pay fail. productId:%@, outTradeNo:%@",
productId,
outTradeNo);
// 此处应该通知客户端
[[SKPaymentQueue defaultQueue] finishTransaction:trans];
}
/**
* 交易完成
*/
- (void)transactionFinish:(SKPaymentTransaction *)trans {
NSLog(@"交易结束");
if (trans == nil) {
return;
}
NSString *outTradeNo = trans.payment.applicationUsername;
NSString *productId = trans.payment.productIdentifier;
NSLog(@"iap pay finish. productId:%@, outTradeNo:%@",
productId,
outTradeNo);
[[SKPaymentQueue defaultQueue] finishTransaction:trans];
}
网友评论