> ## Documentation Index
> Fetch the complete documentation index at: https://helium-figma-import-quickguide.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Set Up Revenue Tracking

> Set up webhooks to track your app's revenue and subscription events. This is important if you want Helium to display subscription, revenue, and other metrics!

<Note>
  Revenue tracking is not yet fully supported for Android (expected mid-November). This guide only covers setup for iOS.
</Note>

Go to your dashboard's revenue settings to configure webhooks.

<img src="https://mintcdn.com/helium-figma-import-quickguide/yEwh2R39np7dJz0e/images/rev-reporting.png?fit=max&auto=format&n=yEwh2R39np7dJz0e&q=85&s=b55109d4d4baf22abee9449c96353b5e" alt="Rev Reporting Pn" width="3002" height="939" data-path="images/rev-reporting.png" />

You have 3 options (only do one of them):

## 1) App Store Server Notifications

<Tip>
  This option is recommended if you are using StoreKit to handle your purchases.
</Tip>

Send purchase events direct from Apple to Helium. Follow the instructions shown under **App Store Connect Configuration**. If you already consume these events on your own server, then consider the **Forward** option below.

## 2) RevenueCat Webhooks

<Tip>
  This option is recommended if you are using RevenueCat to handle your purchases.
</Tip>

Use RevenueCat webhooks to send purchase events to Helium. Follow the instructions shown in the web app under **RevenueCat Webhook Configuration**.

In your SDK integration, make sure to provide a `revenueCatAppUserId` when you call the Helium `initialize` function.

## 3) Forward App Store Server Notifications

<Tip>
  This option is recommended if you are using StoreKit to handle your purchases but want to consume App Store Server Notifications on your own server and forward those events to Helium.
</Tip>

In your dashboard's revenue settings under the section **App Store Connect Configuration** grab the **Webhook URL** and use that value in your forwarding code.

Wherever you consume webhook events for App Store Server Notifications, you'll want to add a snippet of code that forwards the exact, unmodified ASSN payload to Helium.

Here is some example forwarding code. Reach out to Helium support if you have any questions.

<CodeGroup>
  ```javascript Node/Express theme={null}
  const express = require('express');
  const axios = require('axios');
  const app = express();

  app.use(express.json());

  app.post('/assn-webhook', async (req, res) => {
    try {
      const response = await axios.post(
        'your-helium-webhook-url-here',
        req.body,
        {
          headers: { 'Content-Type': 'application/json' },
          timeout: 5000
        }
      );
      
      console.log('Successfully forwarded webhook');
      res.status(200).json({ success: true });
    } catch (error) {
      console.error('Failed to forward webhook:', error.message);
      res.status(500).json({ error: 'Failed to forward webhook' });
    }
  });
  ```

  ```javascript Next.js Pages Router theme={null}
  export default async function handler(req, res) {
    if (req.method !== 'POST') {
      return res.status(405).json({ error: 'Method not allowed' });
    }

    try {
      const response = await fetch(
        'your-helium-webhook-url-here',
        {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(req.body),
          signal: AbortSignal.timeout(5000)
        }
      );

      if (response.ok) {
        console.log('Successfully forwarded webhook');
        return res.status(200).json({ success: true });
      } else {
        throw new Error(`HTTP ${response.status}`);
      }
    } catch (error) {
      console.error('Failed to forward webhook:', error);
      return res.status(500).json({ error: 'Failed to forward webhook' });
    }
  }
  ```

  ```javascript Next.js App Router theme={null}
  import { NextResponse } from 'next/server';

  export async function POST(request) {
    try {
      const body = await request.json();
      
      const response = await fetch(
        'your-helium-webhook-url-here',
        {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(body),
          signal: AbortSignal.timeout(5000)
        }
      );

      if (response.ok) {
        console.log('Successfully forwarded webhook');
        return NextResponse.json({ success: true });
      } else {
        throw new Error(`HTTP ${response.status}`);
      }
    } catch (error) {
      console.error('Failed to forward webhook:', error);
      return NextResponse.json(
        { error: 'Failed to forward webhook' },
        { status: 500 }
      );
    }
  }
  ```

  ```python Python w/ Flask theme={null}
  @app.route('/webhook', methods=['POST'])
  def forward_webhook():
      try:
          response = requests.post(
              'your-helium-webhook-url-here',
              json=request.json,
              headers={'Content-Type': 'application/json'},
              timeout=5
          )
          response.raise_for_status()
          
          print('Successfully forwarded webhook')
          return jsonify({'success': True}), 200
          
      except requests.exceptions.RequestException as e:
          print(f'Failed to forward webhook: {e}')
          return jsonify({'error': 'Failed to forward webhook'}), 500
  ```

  ```python Python w/ FastAPI theme={null}
  @app.post('/webhook')
  async def forward_webhook(request: Request):
      try:
          body = await request.json()
          
          async with httpx.AsyncClient(timeout=5.0) as client:
              response = await client.post(
                  'your-helium-webhook-url-here',
                  json=body,
                  headers={'Content-Type': 'application/json'}
              )
              response.raise_for_status()
          
          print('Successfully forwarded webhook')
          return {'success': True}
          
      except (httpx.RequestError, httpx.HTTPStatusError) as e:
          print(f'Failed to forward webhook: {e}')
          raise HTTPException(
              status_code=500,
              detail='Failed to forward webhook'
          )
  ```
</CodeGroup>

<Tip>
  You may want to extract the pk value from the Webhook URL as an environment variable to avoid storing in version control.
</Tip>
