# Logging Revenue with StoreKit 1

ContextSDK supports logging revenue from both StoreKit 1 and StoreKit 2 purchases. This guide covers StoreKit 1 integration, which is essential for apps that need to support iOS 14 and earlier, or are migrating from legacy StoreKit implementations.

## Basic StoreKit 1 Integration

### Using SKProduct

For basic product information logging, use the `SKProduct` directly:

{% code title="Example" %}

```swift
// When a purchase completes successfully
func userDidPurchase(product: SKProduct) {
    if let context = ContextManager.recentContext(flowName: "upsell_premium") {
        context.logStoreKit1RevenueOutcome(from: product)
    }
}
```

{% endcode %}

### Using SKPaymentTransaction

For more detailed transaction tracking, including transaction state and dates:

{% code title="SKPaymentTransactionObserver" %}

```swift
// In your SKPaymentTransactionObserver
func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
    for transaction in transactions {
        switch transaction.transactionState {
        case .purchased:
            handlePurchasedTransaction(transaction)
            queue.finishTransaction(transaction)
        case .restored:
            handleRestoredTransaction(transaction)
            queue.finishTransaction(transaction)
        case .failed:
            handleFailedTransaction(transaction)
            queue.finishTransaction(transaction)
        default:
            break
        }
    }
}

private func handlePurchasedTransaction(_ transaction: SKPaymentTransaction) {
    if let context = ContextManager.recentContext(flowName: "upsell_premium") {
        // Get the product information if available
        let productId = transaction.payment.productIdentifier
        if let product = loadedProducts[productId] {
            // Log with both transaction and product context
            context.logStoreKit1RevenueOutcome(from: transaction, product: product)
        } else {
            // Log with transaction only
            context.logStoreKit1RevenueOutcome(from: transaction)
        }
    }
}

private func handleFailedTransaction(_ transaction: SKPaymentTransaction) {
    if let context = ContextManager.recentContext(flowName: "upsell_premium") {
        context.log(.negative)
    }
}
```

{% endcode %}

To emphasize the transaction outcome handling, here are the steps for common transaction states:

{% stepper %}
{% step %}

#### Purchased

* Call your purchased handler (e.g., `handlePurchasedTransaction`).
* Log revenue using `context.logStoreKit1RevenueOutcome(from: transaction, product: product)` if you have product info, otherwise `context.logStoreKit1RevenueOutcome(from: transaction)`.
* Finish the transaction with `queue.finishTransaction(transaction)`.
  {% endstep %}

{% step %}

#### Restored

* Call your restored handler (e.g., `handleRestoredTransaction`).
* Log appropriate outcomes (similar to purchased if you want to attribute restored purchases).
* Finish the transaction with `queue.finishTransaction(transaction)`.
  {% endstep %}

{% step %}

#### Failed

* Call your failed handler (e.g., `handleFailedTransaction`).
* Log a negative outcome with `context.log(.negative)` if appropriate.
* Finish the transaction with `queue.finishTransaction(transaction)`.
  {% endstep %}
  {% endstepper %}

## Metadata Extracted from StoreKit 1

When using StoreKit 1 products and transactions, ContextSDK automatically extracts the following metadata:

### From SKProduct

* Revenue: `product.price`
* Currency: `product.priceLocale.currencyCode` (defaults to "USD" if unavailable)
* Revenue Source: Always set to "in\_app\_purchase"
* Family Sharing: `product.isFamilyShareable` (iOS 14.0+ only)
* Recurrence: "recurring" for subscriptions, "one\_time\_purchase" for others
* Subscription Period: Period unit and interval (for subscriptions)
* Introductory Offers: Price, period, and duration (iOS 11.2+ only)

### From SKPaymentTransaction (additional)

* Transaction ID: `transaction.transactionIdentifier`
* Transaction State: "purchased", "failed", "restored", etc.
* Transaction Date: ISO8601 formatted transaction date
* Original Transaction ID: For subscription renewals and restores

{% hint style="info" %}
StoreKit 1 provides less metadata than StoreKit 2, particularly around subscription details and family sharing (which requires iOS 14.0+). The SDK handles these differences automatically and provides sensible defaults.
{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.contextsdk.com/context-decision/revenue-outcomes/logging-revenue-with-storekit-1.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
