0
votes

i am newbie on ios programming and this is my first time to use in app purchases. All of my IAPs are consumable and i have no error on my code. However, somethings are wrong. Because i tested my IAPs with sandbox environment and when i tried to purchase my first item which is tier 1, alert view showed me tier 5 item.

You can check all of my code about IAP:

@interface ViewController (){
    NSString *currencyString;
    SKProduct *validProduct;
}

- (void)validateReceiptForTransaction:(SKPaymentTransaction *)transaction {
VerificationController * verifier = [VerificationController sharedInstance];
[verifier verifyPurchase:transaction completionHandler:^(BOOL success) {
    if (success) {

        UIAlertView *tmp = [[UIAlertView alloc]
                            initWithTitle:@"Complete"
                            message:@"Transaction successful!"
                            delegate:self
                            cancelButtonTitle:nil
                            otherButtonTitles:@"Ok", nil];
        [tmp show];
        [self provideContentForProductIdentifier:transaction.payment.productIdentifier];
    } else {

        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Purchase Unsuccessful"
                                                        message:@"Your purchase failed. Please try again."
                                                       delegate:self
                                              cancelButtonTitle:@"OK"
                                              otherButtonTitles:nil];
        [alert show];

        [[SKPaymentQueue defaultQueue] finishTransaction: transaction];
    }
}];
}

- (void)provideContentForProductIdentifier:(NSString *)productIdentifier {

if ([productIdentifier isEqualToString:@"100LJ"]) {
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    int j = [defaults integerForKey:@"j"];

    j += 100;

    [defaults setInteger:j forKey:@"j"];
    [defaults synchronize];
}
else if ([productIdentifier isEqualToString:@"500LJ"]) {
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    int j = [defaults integerForKey:@"j"];

    j += 500;

    [defaults setInteger:j forKey:@"j"];
    [defaults synchronize];
}
else if ([productIdentifier isEqualToString:@"1000LJ"]) {
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    int j = [defaults integerForKey:@"j"];

    j += 1000;

    [defaults setInteger:j forKey:@"j"];
    [defaults synchronize];
}
else if ([productIdentifier isEqualToString:@"5000LJ"]) {
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    int j = [defaults integerForKey:@"j"];

    j += 5000;

    [defaults setInteger:j forKey:@"j"];
    [defaults synchronize];
}
else if ([productIdentifier isEqualToString:@"10000LJ"]) {
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    int j = [defaults integerForKey:@"j"];

    j += 10000;

    [defaults setInteger:j forKey:@"j"];
    [defaults synchronize];
}
else if ([productIdentifier isEqualToString:@"50000LJ"]) {
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    int j = [defaults integerForKey:@"j"];

    j += 50000;

    [defaults setInteger:j forKey:@"j"];
    [defaults synchronize];
}
else if ([productIdentifier isEqualToString:@"100000LJ"]) {
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    int j = [defaults integerForKey:@"j"];

    j += 100000;

    [defaults setInteger:j forKey:@"j"];
    [defaults synchronize];
}

}

-(void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions {

for (SKPaymentTransaction *transaction in transactions) {
    switch (transaction.transactionState) {
        case SKPaymentTransactionStatePurchasing:{
        }

            break;

        case SKPaymentTransactionStatePurchased:{

            [_activityView stopAnimating];

            [self validateReceiptForTransaction:transaction];

            [[SKPaymentQueue defaultQueue] finishTransaction:transaction];

            [[SKPaymentQueue defaultQueue] removeTransactionObserver:self];

        }
            break;

        case SKPaymentTransactionStateRestored:{
            [_activityView stopAnimating];
            [self validateReceiptForTransaction:transaction];
            [[SKPaymentQueue defaultQueue] finishTransaction:transaction];}
            break;

        case SKPaymentTransactionStateFailed:{
            [_activityView stopAnimating];

            if (transaction.error.code != SKErrorPaymentCancelled) {
                UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Purchase Unsuccessful"
                                                                message:@"Your purchase failed. Please try again."
                                                               delegate:self
                                                      cancelButtonTitle:@"OK"
                                                      otherButtonTitles:nil];
                [alert show];
            }

            [[SKPaymentQueue defaultQueue] finishTransaction:transaction];}
            break;

        default:{}
            break;





    }
}
}

-(void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{
validProduct = nil;

int count = [response.products count];

if (count>0) {
    validProduct = [response.products objectAtIndex:0];

    NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
    [formatter setNumberStyle:NSNumberFormatterCurrencyStyle];
    [formatter setLocale:validProduct.priceLocale];
    currencyString = [formatter stringFromNumber:validProduct.price];

    if([validProduct.productIdentifier isEqual: @"100LJ"]){
        [_storebuy1 setTitle:currencyString forState:UIControlStateNormal];
    }
    else if([validProduct.productIdentifier isEqual: @"500LJ"]){
        [_storebuy2 setTitle:currencyString forState:UIControlStateNormal];
    }
    else if([validProduct.productIdentifier isEqual: @"1000LJ"]){
        [_storebuy3 setTitle:currencyString forState:UIControlStateNormal];
    }
    else if([validProduct.productIdentifier isEqual: @"5000LJ"]){
        [_storebuy4 setTitle:currencyString forState:UIControlStateNormal];
    }
    else if([validProduct.productIdentifier isEqual: @"10000LJ"]){
        [_storebuy5 setTitle:currencyString forState:UIControlStateNormal];
    }
    else if([validProduct.productIdentifier isEqual: @"50000LJ"]){
        [_storebuy6 setTitle:currencyString forState:UIControlStateNormal];
    }
    else if([validProduct.productIdentifier isEqual: @"100000LJ"]){
        [_storebuy7 setTitle:currencyString forState:UIControlStateNormal];
    }
}
}

I have 7 buttons to buy IAP items. This is my button to buy tier 1 IAP item:

- (IBAction)storebuy1:(UIButton *)sender{
_activityView=[[UIActivityIndicatorView alloc]     initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];

[_activityView.layer setBackgroundColor:[[UIColor colorWithWhite: 0.0 alpha:0.30] CGColor]];

_activityView.center=self.view.center;

_activityView.hidesWhenStopped = YES;

[_activityView startAnimating];

[self.view addSubview:_activityView];


SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet setWithObject:@"100LJ"]];

request.delegate = self;
[request start];

if ([SKPaymentQueue canMakePayments]) {

    SKPayment *payment = [SKPayment paymentWithProduct:validProduct];
    [[SKPaymentQueue defaultQueue] addTransactionObserver:self];
    [[SKPaymentQueue defaultQueue] addPayment:payment];

}

else {

    UIAlertView *tmp = [[UIAlertView alloc]

                        initWithTitle:@"Prohibited"

                        message:@"Parental Control is enabled!"

                        delegate:self

                        cancelButtonTitle:nil

                        otherButtonTitles:@"Ok", nil];

    [tmp show];
}
}

Hope you can help me.

Best Regards, Taha

1
Can you be more specific about the problem you're having?Stonz2

1 Answers

0
votes

Because validProduct is set to whatever it was last set to when productsRequest:didReceiveResponse: was called, and that is unlikely to be what you want.

In general, your approach is wrong. You should be making one SKProductsRequest for all of your product identifiers and then storing all of the products that you get back. You can loop over the products to update your button titles (sort the products first). When a button is pressed you should then find the product with the appropriate identifier and create your SKPayment from that.

So, get rid of SKProduct *validProduct; and store the products in an array or a dictionary instead.