先附上一篇介绍怎么填写协议、税务和银行业务的文章
本文主要介绍内购代码部分
首先导入StoreKit/StoreKit.h,再遵循两个代理SKPaymentTransactionObserver,SKProductsRequestDelegate
.h文件
@interface ApplePayManager : NSObject
+ (instancetype)sharedApplePayManager;
// 创建订单号
- (void)createPayOrderWithOrderModel:(OrderPayModel *)orderModel;
@end
.m文件
@interface ApplePayManager ()<SKPaymentTransactionObserver,SKProductsRequestDelegate>
@property (nonatomic,strong) OrderPayModel *orderModel;
@property (nonatomic,copy) NSString *productId;
@property (nonatomic,strong) PayModel *payModel;// 充值信息
@end
@implementation ApplePayManager
+ (instancetype)sharedApplePayManager{
static ApplePayManager *manager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
manager = [[self alloc] init];
//添加一个交易队列观察者
[[SKPaymentQueue defaultQueue] addTransactionObserver:manager];
});
return manager;
}
- (void)createPayOrderWithOrderModel:(OrderPayModel *)orderModel{
// 该方法里是请求支付的一些信息
// ...
[self gotoApplePayWithProductId:@"对应的内购项目id"];
}
// 去购买
- (void)gotoApplePayWithProductId:(NSString *)productId{
if([SKPaymentQueue canMakePayments]){
self.productId = productId;
[self requestProductData:self.productId];
}else{
[APP_WIN makeToast:@"您的设备不支持苹果支付" duration:2 position:CSToastPositionCenter];
}
}
//去苹果服务器请求商品
- (void)requestProductData:(NSString *)productId{
// 加载
[GMBProgressHUD showHUDAddedTo:APP_WIN animated:YES];
NSArray *product = [[NSArray alloc] initWithObjects:productId,nil];
NSSet *nsset = [NSSet setWithArray:product];
SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers:nsset];
request.delegate = self;
[request start];
}
#pragma mark -- SKProductsRequestDelegate
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response{
NSArray *productArr = response.products;
if (productArr.count == 0) {
[GMBProgressHUD hideHUDForView:APP_WIN animated:YES];
[APP_WIN makeToast:@"该商品已下架" duration:2 position:CSToastPositionCenter];
return;
}
SKProduct *skPro = nil;
for (SKProduct *pro in productArr) {
if ([pro.productIdentifier isEqualToString:self.productId]) {
skPro = pro;
}
}
if (!skPro) {
[APP_WIN makeToast:@"没有该商品" duration:2 position:CSToastPositionCenter];
return;
}
SKPayment *payment = [SKPayment paymentWithProduct:skPro];
//发送内购请求
[[SKPaymentQueue defaultQueue] addPayment:payment];
}
#pragma mark -- SKRequestDelegate
- (void)requestDidFinish:(SKRequest *)request {
[GMBProgressHUD hideHUDForView:APP_WIN animated:YES];
}
- (void)request:(SKRequest *)request didFailWithError:(NSError *)error {
[APP_WIN makeToast:@"支付失败" duration:2 position:CSToastPositionCenter];
}
#pragma mark -- SKPaymentTransactionObserver
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray<SKPaymentTransaction *> *)transactions {
for (SKPaymentTransaction *tran in transactions) {
switch (tran.transactionState) {
case SKPaymentTransactionStatePurchased: //交易完成
// 发送到苹果服务器验证凭证
GLog(@"交易完成");
[self verifyPurchaseWithPaymentTrasactionWithSandBox:NO];
[[SKPaymentQueue defaultQueue] finishTransaction:tran];
break;
case SKPaymentTransactionStatePurchasing: //商品添加进列表
GLog(@"商品添加进列表");
break;
case SKPaymentTransactionStateRestored: //购买过
GLog(@"购买过");
[[SKPaymentQueue defaultQueue] finishTransaction:tran];
break;
case SKPaymentTransactionStateFailed: //交易失败
GLog(@"交易失败");
[[SKPaymentQueue defaultQueue] finishTransaction:tran];
[APP_WIN makeToast:@"购买失败" duration:2 position:CSToastPositionCenter];
break;
default:
break;
}
}
}
/*
* 发送到苹果服务器验证凭证
*/
// 二次验证(沙盒还是正式环境)
- (void)verifyPurchaseWithPaymentTrasactionWithSandBox:(BOOL)sandBox{
// 验证凭据,获取到苹果返回的交易凭据
// appStoreReceiptURL iOS7.0增加的,购买交易完成后,会将凭据存放在该地址
NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
// 从沙盒中获取到购买凭据
NSData *receiptData = [NSData dataWithContentsOfURL:receiptURL];
if (!receiptData) {
GLog(@"没有数据");
}
// 发送网络POST请求,对购买凭据进行验证
//测试验证地址:https://sandbox.itunes.apple.com/verifyReceipt
//正式验证地址:https://buy.itunes.apple.com/verifyReceipt
NSString *url;
if (sandBox == YES) {
url = @"https://sandbox.itunes.apple.com/verifyReceipt";
} else {
url = @"https://buy.itunes.apple.com/verifyReceipt";
}
// 根据苹果官方文档来操作 https://developer.apple.com/library/content/releasenotes/General/ValidateAppStoreReceipt/Chapters/ValidateRemotely.html
NSDictionary *requestContents = @{@"receipt-data":[receiptData base64EncodedStringWithOptions:0]};
NSData *requestData = [NSJSONSerialization dataWithJSONObject:requestContents options:0 error:nil];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:url]];
request.HTTPMethod = @"POST";
request.HTTPBody = requestData;
NSURLSessionDataTask *dataTask = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
dispatch_async(dispatch_get_main_queue(), ^{
if (error) {
[APP_WIN makeToast:error.domain duration:2 position:CSToastPositionCenter];
} else {
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
GLog(@"%@",dict);
if ([dict[@"status"] isEqual:@0]) {// 正确
// 发数据给自己公司后台
[self checkPayment];
} else if([dict[@"status"] isEqual:@21007]){// 此收据来自测试环境,但已发送至生产环境进行验证。切换环境
[self verifyPurchaseWithPaymentTrasactionWithSandBox:YES];
}
}
});
}];
[dataTask resume];
}
@end
错误集:
1、刚开始没用单利,在dealloc里[[SKPaymentQueue defaultQueue] removeTransactionObserver:self],导致代理不走
2、发送到苹果服务器验证凭证出现21002,后来按照官方文档操作成功
网友评论