13

I would like to track in-app purchases with the Google Analytics SDK for iOS v2, as indicated in their Ecommerce Tracking guide.

I'm currently doing the following after receiving a SKPaymentTransactionStatePurchased transaction update:

- (void) trackTransaction:(SKPaymentTransaction*)transaction
{
    NSString *transactionIdentifier = transaction.transactionIdentifier;
    GAITransaction *gaiTransaction = [GAITransaction transactionWithId:transactionIdentifier withAffiliation:@"App Store"];

    SKPayment *payment = transaction.payment;
    NSString *productIdentifier = payment.productIdentifier;
    SKProduct *product = [self productForIdentifier:productIdentifier];
    NSString *productTitle = product.localizedTitle;
    int64_t priceInMicros = product.price.floatValue * 1000000; // FIXME: Doesn't consider different currencies
    [gaiTransaction addItemWithCode:productIdentifier name:productTitle category:nil priceMicros:priceInMicros quantity:payment.quantity];

    gaiTransaction.revenueMicros = priceInMicros * payment.quantity; // FIXME: doesn't consider Apple's cut

    id<GAITracker> tracker = [GAI sharedInstance].defaultTracker;
    [tracker trackTransaction:gaiTransaction];
}

Is the above the right way of tracking in-app purchases? I detect two problems at the very least:

  1. SKProduct returns a localized price and if I track it as-is revenue aggregation will be incorrect. Is there a way to normalize the price?
  2. The revenue returned doesn't take Apple's cut into account, which is not always 30%. Is it possible to obtain the net revenue within the app?
hpique
  • 119,096
  • 131
  • 338
  • 476

2 Answers2

11

SKProduct returns a localized price and if I track it as-is revenue aggregation will be incorrect. Is there a way to normalize the price?

Google Analytics SKD for iOS v3 added support for currencies. Tracking a transaction looks like this:

- (void)storePaymentTransactionFinished:(NSNotification *)notification
{
    SKPaymentTransaction *paymentTransaction = notification.transaction;
    if (paymentTransaction.transactionState == SKPaymentTransactionStateRestored) return;

    SKPayment *payment = paymentTransaction.payment;
    NSString *sku = payment.productIdentifier;
    SKProduct *product = [[RMStore defaultStore] productForIdentifier:sku];
    NSLocale *priceLocale = product.priceLocale;
    NSString *currencyCode = [priceLocale objectForKey:NSLocaleCurrencyCode];
    NSString *transactionId = paymentTransaction.transactionIdentifier;
    NSNumber *productPrice = product.price;
    {
        NSNumber *revenue = @(productPrice.floatValue * payment.quantity);
        GAIDictionaryBuilder *builder = [GAIDictionaryBuilder createTransactionWithId:transactionId
                                                                          affiliation:@"App Store"
                                                                              revenue:revenue
                                                                                  tax:0
                                                                             shipping:0
                                                                         currencyCode:currencyCode];
        NSDictionary *parameters = [builder build];
        [_tracker send:parameters];
    }
    {
        GAIDictionaryBuilder *builder = [GAIDictionaryBuilder createItemWithTransactionId:transactionId
                                                                                     name:product.localizedTitle
                                                                                      sku:sku
                                                                                 category:@"In-App Purchase"
                                                                                    price:productPrice
                                                                                 quantity:@(payment.quantity)
                                                                             currencyCode:currencyCode];
        NSDictionary *parameters = [builder build];
        [_tracker send:parameters];
    }
}

The above code uses RMStore for convenience.

The revenue returned doesn't take Apple's cut into account, which is not always 30%. Is it possible to obtain the net revenue within the app?

No.

hpique
  • 119,096
  • 131
  • 338
  • 476
2

Good question, shame you've got no answers to this as I've just come up against the same issue.

So to stimulate discussion on this topic I'd like to suggest this "workaround".

NSString *affiliation = [product.priceLocale objectForKey:NSLocaleCurrencyCode];  
GAITransaction *gaiTransaction = [GAITransaction transactionWithId:transactionIdentifier withAffiliation:affiliation];

The idea being that you can't do anything about different currencies in-App. Instead you need to move the problem to Analytics and use it's filtering to work out earnings per national App Store.

So if it's a US transaction the affiliate will be "USD".

As for

take Apple's cut into account, which is not always 30%

this is news to me. I was of the impression the 30% was set in stone by Apple. So I'm just multiplying revenue by 0.7

Seoras
  • 1,286
  • 13
  • 21
  • It's not always exactly 30%. It depends on App Store Region and Currency. So I would leave revenue as is for reports and just keep in my mind ~30%... – oleynikd Apr 23 '15 at 12:14
  • True. 2 Years later, now having some experience under my belt, I can point at Japan as a good example of not getting the full 70% cut. Japan keeps 20% of your earnings. Unless you submit, via Apple, a tax exemption form which might as well be in ancient Egyptian hieroglyphs its so obfuscated. – Seoras Apr 23 '15 at 22:55