我正在购买应用程序(非消耗类型 - 歌曲)。当用户点击购买每首歌曲购买时,我打电话给 startPurchase funtion 。我的歌曲内容通过我的服务器发送。
当我购买东西并再次尝试重新购买时,它不会被视为恢复购买。它会进行新的购买。委托方法被多次调用
实际上我的问题是,我点击购买并继续付款,并购买该项目。
再次当我尝试购买相同的商品时,苹果提醒称为“您已购买此商品,请点按”确定下载“,当我点按”确定“时。这不是< strong> SKPaymentTransactionStateRestored 而是转到 SKPaymentTransactionStatePurchased 。为什么会发生这种情况?请帮忙
请帮帮我
- (void)startPurchase:(NSString*)inProductId{
if ([SKPaymentQueue canMakePayments])
{
myProductId = inProductId
SKProductsRequest *productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet setWithObject:myProductId]];
productsRequest.delegate = self;
[productsRequest start];
}
else {
NSLog(@"Parental-controls are enabled");
}
}
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:
(SKProductsResponse *)response {
NSLog(@"response received");
SKProduct *validProduct = nil;
int count = [response.products count];
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"Message" message:
[NSString stringWithFormat:@"%d",response.products.count] delegate:
self cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alert show];
[alert release];
if (count > 0) {
validProduct = [response.products objectAtIndex:0];
NSLog(@"products available");
SKPayment *payment = [SKPayment paymentWithProductIdentifier:myProductId];
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
[[SKPaymentQueue defaultQueue] addPayment:payment];
}
else if (!validProduct) {
NSLog(@"No products available");
}
}
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
{
for (SKPaymentTransaction *transaction in transactions)
{
SKPayment *payment = [transaction payment];
if([payment.productIdentifier isEqualToString:myProductId])
{
NSLog(@"%@payement queue payment.productIdentifier",payment.productIdentifier);
switch (transaction.transactionState)
{
case SKPaymentTransactionStatePurchased:
NSLog(@"completeTransaction");
[self completeTransaction:transaction];
break;
case SKPaymentTransactionStateFailed:
NSLog(@"failedTransaction");
[self failedTransaction:transaction];
break;
case SKPaymentTransactionStateRestored:
NSLog(@"restoreTransaction");
[self restoreTransaction:transaction];
default:
break;
}
}
}
}
- (void)provideContent:(NSString *)productIdentifier
{
NSLog(@"Provide Content %@", productIdentifier);
}
- (void)recordTransaction:(SKPaymentTransaction *)transaction {
NSLog(@"inside the recordTransaction");
}
- (void) completeTransaction: (SKPaymentTransaction *)transaction
{
[self recordTransaction: transaction];
[self provideContent: transaction.payment.productIdentifier];
[[SKPaymentQueue defaultQueue] finishTransaction: transaction];
}
- (void) restoreTransaction: (SKPaymentTransaction *)transaction
{
NSLog(@"restoreTransaction transaction inside");
}
- (void) failedTransaction: (SKPaymentTransaction *)transaction
{
if (transaction.error.code != SKErrorPaymentCancelled)
{
if(transaction.error.code == SKErrorUnknown) {
NSLog(@"Unknown Error (%d), product: %@", (int)transaction.error.code, transaction.payment.productIdentifier);
UIAlertView *failureAlert = [[UIAlertView alloc] initWithTitle :@"In-App-Purchase Error:"
message: @"There was an error purchasing this item please try again."
delegate : self cancelButtonTitle:@"OK"otherButtonTitles:nil];
[failureAlert show];
[failureAlert release];
}
if(transaction.error.code == SKErrorClientInvalid) {
NSLog(@"Client invalid (%d), product: %@", (int)transaction.error.code, transaction.payment.productIdentifier);
UIAlertView *failureAlert = [[UIAlertView alloc] initWithTitle :@"In-App-Purchase Error:"
message: @"There was an error purchasing this item please try again."
delegate : self cancelButtonTitle:@"OK"otherButtonTitles:nil];
[failureAlert show];
[failureAlert release];
}
if(transaction.error.code == SKErrorPaymentInvalid) {
NSLog(@"Payment invalid (%d), product: %@", (int)transaction.error.code, transaction.payment.productIdentifier);
UIAlertView *failureAlert = [[UIAlertView alloc] initWithTitle :@"In-App-Purchase Error:"
message: @"There was an error purchasing this item please try again."
delegate : self cancelButtonTitle:@"OK"otherButtonTitles:nil];
[failureAlert show];
[failureAlert release];
}
if(transaction.error.code == SKErrorPaymentNotAllowed) {
NSLog(@"Payment not allowed (%d), product: %@", (int)transaction.error.code, transaction.payment.productIdentifier);
UIAlertView *failureAlert = [[UIAlertView alloc] initWithTitle :@"In-App-Purchase Error:"
message: @"There was an error purchasing this item please try again."
delegate : self cancelButtonTitle:@"OK"otherButtonTitles:nil];
[failureAlert show];
[failureAlert release];
}
}
[[SKPaymentQueue defaultQueue] finishTransaction: transaction];
}
答案 0 :(得分:0)
我认为您的问题添加了事务服务器重复反映 尝试下面的代码,以避免添加事务服务器重复可能是它的工作:
- (void)startPurchase:(NSString*)inProductId{
if ([SKPaymentQueue canMakePayments])
{
myProductId = inProductId
SKProductsRequest *productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet setWithObject:myProductId]];
productsRequest.delegate = self;
[productsRequest start];
}
else {
NSLog(@"Parental-controls are enabled");
}
}
static bool hasAddObserver=NO;
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:
(SKProductsResponse *)response {
NSLog(@"response received");
SKProduct *validProduct = nil;
int count = [response.products count];
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"Message" message:
[NSString stringWithFormat:@"%d",response.products.count] delegate:
self cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alert show];
[alert release];
if (count > 0) {
validProduct = [response.products objectAtIndex:0];
NSLog(@"products available");
SKPayment *payment = [SKPayment paymentWithProductIdentifier:myProductId];
if (!hasAddObserver) {
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
hasAddObserver=YES;
}
[[SKPaymentQueue defaultQueue] addPayment:payment];
}
else if (!validProduct) {
NSLog(@"No products available");
}
}
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
{
for (SKPaymentTransaction *transaction in transactions)
{
SKPayment *payment = [transaction payment];
if([payment.productIdentifier isEqualToString:myProductId])
{
NSLog(@"%@payement queue payment.productIdentifier",payment.productIdentifier);
switch (transaction.transactionState)
{
case SKPaymentTransactionStatePurchased:
NSLog(@"completeTransaction");
[self completeTransaction:transaction];
break;
case SKPaymentTransactionStateFailed:
NSLog(@"failedTransaction");
[self failedTransaction:transaction];
break;
case SKPaymentTransactionStateRestored:
NSLog(@"restoreTransaction");
[self restoreTransaction:transaction];
default:
break;
}
}
}
}
- (void)provideContent:(NSString *)productIdentifier
{
NSLog(@"Provide Content %@", productIdentifier);
}
- (void)recordTransaction:(SKPaymentTransaction *)transaction {
NSLog(@"inside the recordTransaction");
}
- (void) completeTransaction: (SKPaymentTransaction *)transaction
{
[self recordTransaction: transaction];
[self provideContent: transaction.payment.productIdentifier];
[[SKPaymentQueue defaultQueue] finishTransaction: transaction];
}
- (void) restoreTransaction: (SKPaymentTransaction *)transaction
{
NSLog(@"restoreTransaction transaction inside");
}
- (void) failedTransaction: (SKPaymentTransaction *)transaction
{
if (transaction.error.code != SKErrorPaymentCancelled)
{
if(transaction.error.code == SKErrorUnknown) {
NSLog(@"Unknown Error (%d), product: %@", (int)transaction.error.code, transaction.payment.productIdentifier);
UIAlertView *failureAlert = [[UIAlertView alloc] initWithTitle :@"In-App-Purchase Error:"
message: @"There was an error purchasing this item please try again."
delegate : self cancelButtonTitle:@"OK"otherButtonTitles:nil];
[failureAlert show];
[failureAlert release];
}
if(transaction.error.code == SKErrorClientInvalid) {
NSLog(@"Client invalid (%d), product: %@", (int)transaction.error.code, transaction.payment.productIdentifier);
UIAlertView *failureAlert = [[UIAlertView alloc] initWithTitle :@"In-App-Purchase Error:"
message: @"There was an error purchasing this item please try again."
delegate : self cancelButtonTitle:@"OK"otherButtonTitles:nil];
[failureAlert show];
[failureAlert release];
}
if(transaction.error.code == SKErrorPaymentInvalid) {
NSLog(@"Payment invalid (%d), product: %@", (int)transaction.error.code, transaction.payment.productIdentifier);
UIAlertView *failureAlert = [[UIAlertView alloc] initWithTitle :@"In-App-Purchase Error:"
message: @"There was an error purchasing this item please try again."
delegate : self cancelButtonTitle:@"OK"otherButtonTitles:nil];
[failureAlert show];
[failureAlert release];
}
if(transaction.error.code == SKErrorPaymentNotAllowed) {
NSLog(@"Payment not allowed (%d), product: %@", (int)transaction.error.code, transaction.payment.productIdentifier);
UIAlertView *failureAlert = [[UIAlertView alloc] initWithTitle :@"In-App-Purchase Error:"
message: @"There was an error purchasing this item please try again."
delegate : self cancelButtonTitle:@"OK"otherButtonTitles:nil];
[failureAlert show];
[failureAlert release];
}
}
[[SKPaymentQueue defaultQueue] finishTransaction: transaction];
}
在我检查中是否添加了交易服务器代码:
if (!hasAddObserver) {
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
hasAddObserver=YES;
}
hasAddObserver变量静态bool数据类型检查是否已经添加了易于添加的检查事务服务器!
答案 1 :(得分:0)
就官方Apple文档[1]所说,这是正常行为:
“如果用户尝试购买可恢复的产品(而不是使用您实施的恢复界面),应用程序将收到该项目的常规交易,而不是恢复交易。但是,用户不会收取费用对于该产品,您的应用程序应该将这些交易与原始交易的交易完全相同。“