> ## Documentation Index
> Fetch the complete documentation index at: https://docs.spendowl.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Purchase Tracking

> Automatic StoreKit 2 purchase observation

## Overview

SpendOwl automatically observes StoreKit 2 transactions to track revenue for ROAS calculation. This works passively alongside other subscription SDKs like RevenueCat or Adapty.

## Automatic Tracking

Purchase tracking starts automatically when you call `configure()`:

```swift theme={null}
SpendOwl.configure(apiKey: "your-api-key")
// Purchase tracking is now active
```

<Note>
  No additional code required. SpendOwl observes all StoreKit 2 transactions automatically.
</Note>

## How It Works

```mermaid theme={null}
sequenceDiagram
    participant User
    participant StoreKit
    participant SpendOwl
    participant SpendOwl API

    User->>StoreKit: Complete purchase
    StoreKit->>SpendOwl: Transaction update
    SpendOwl->>SpendOwl: Extract transaction data
    SpendOwl->>SpendOwl API: Send revenue event
    SpendOwl API->>SpendOwl API: Calculate ROAS
```

1. User completes a purchase through StoreKit 2
2. SpendOwl receives the transaction notification
3. Transaction data (product ID, price, currency) is extracted
4. Revenue event is sent to SpendOwl servers
5. ROAS is calculated and displayed in your dashboard

## Tracked Transaction Types

| Type                         | Tracked | Notes                  |
| ---------------------------- | ------- | ---------------------- |
| Consumables                  | Yes     | One-time purchases     |
| Non-consumables              | Yes     | Lifetime purchases     |
| Auto-renewable subscriptions | Yes     | Initial and renewals   |
| Non-renewing subscriptions   | Yes     | One-time subscriptions |
| Refunds                      | Yes     | Negative revenue       |
| Family Sharing               | Yes     | Shared purchases       |

## Currency Handling

SpendOwl handles currency conversion automatically:

* Prices are captured in the user's local currency
* Converted to USD using current exchange rates
* ROAS is always displayed in USD for consistency

<Info>
  Exchange rates are updated daily from European Central Bank data.
</Info>

## Works with Other SDKs

SpendOwl uses passive observation and doesn't interfere with:

* **RevenueCat** — Both can observe the same transactions
* **Adapty** — No conflicts
* **Qonversion** — Works alongside
* **Custom StoreKit code** — No changes needed

```swift theme={null}
// Your existing purchase flow
let result = try await product.purchase()

// SpendOwl automatically observes this
// RevenueCat/Adapty also work normally
```

## Revenue Attribution

Purchases are attributed to campaigns:

1. **User installs** from an Apple Search Ads campaign
2. **Attribution is captured** by SpendOwl
3. **User makes a purchase** (days or weeks later)
4. **Revenue is linked** to the original campaign

This enables accurate ROAS calculation: `Revenue / Ad Spend = ROAS`

## User ID Linking

When a user ID is set, purchases are linked to that user:

```swift theme={null}
// User logs in
SpendOwl.setUserId("user-123")

// Any purchase is now attributed to "user-123"
let result = try await product.purchase()
```

See [User Identity](/sdk/user-identity) for more details.

## Server-Side Validation

All transactions are validated server-side:

* Transaction receipts are verified with Apple
* Fraudulent transactions are filtered
* Only valid revenue counts toward ROAS

## Debugging Purchases

Enable logging to see purchase events:

```swift theme={null}
SpendOwl.enableLogging = true

// Purchase logs will appear in console:
// [SpendOwl] Purchase tracked: com.app.premium ($9.99 USD)
```

See [Debugging](/sdk/debugging) for more logging options.

## FAQ

<AccordionGroup>
  <Accordion title="Do I need to call any method after a purchase?">
    No. SpendOwl observes transactions automatically. Just ensure the SDK is configured before purchases occur.
  </Accordion>

  <Accordion title="Are test purchases tracked?">
    Sandbox purchases are tracked separately and don't affect production ROAS. Use a test API key in development.
  </Accordion>

  <Accordion title="What about StoreKit 1?">
    SpendOwl uses StoreKit 2 only. If your app uses StoreKit 1, transactions are not tracked. Consider migrating to StoreKit 2.
  </Accordion>

  <Accordion title="How are renewals handled?">
    Auto-renewal transactions are tracked just like initial purchases. Each renewal adds to the user's LTV.
  </Accordion>

  <Accordion title="Are refunds tracked?">
    Yes. Refunds are recorded as negative revenue and reduce the ROAS for the associated campaign.
  </Accordion>
</AccordionGroup>

## Next Steps

<CardGroup cols={2}>
  <Card title="Debugging" icon="bug" href="/sdk/debugging">
    Enable logging and troubleshoot issues
  </Card>

  <Card title="Dashboard" icon="chart-line" href="https://spendowl.io/dashboard">
    View your ROAS data
  </Card>
</CardGroup>
