# Connect Polar (/en/docs/billing/polar/connect)

Do this once before configuring lifetime or subscription billing. You need a
Polar sandbox account and your app running locally from the
[Quickstart](/en/docs/quickstart). You finish with `POLAR_ORGANIZATION_ID`,
`POLAR_ACCESS_TOKEN` and `POLAR_WEBHOOK_SECRET` in `.env.local`, and a Polar CLI
listener forwarding sandbox events to your app.

<Steps>
  <Step>
    ### Open the sandbox dashboard

    Open the [Polar sandbox dashboard](https://sandbox.polar.sh). Sandbox uses a
    separate account and organization from production. Confirm the banner says
    **Changes you make here don't affect your live account**. See
    [Polar sandbox setup](https://polar.sh/docs/integrate/sandbox) if you do not
    have an organization yet.
  </Step>

  <Step>
    ### Copy the organization ID

    Select the intended organization, then open **Settings → Profile**. Under
    **Identifiers**, copy **Organization ID** into `POLAR_ORGANIZATION_ID` in
    ignored `.env.local`. Use the UUID, not the organization slug from the URL.
  </Step>

  <Step>
    ### Create the application token

    Open **Settings → Access Tokens** and choose **Create token**. Give it a
    descriptive name and an expiration, and avoid **Select all**. Select these
    runtime scopes:

    ```txt
    checkouts:write
    products:read
    orders:read
    subscriptions:read
    customer_sessions:write
    ```

    For the same development token to also serve the CLI steps below, add
    `organizations:read` and `webhooks:write`, plus `products:write` for CLI
    catalog creation. Other CLI scopes are in
    [Application and CLI permissions](/en/docs/billing/polar/environment-variables#application-and-cli-permissions).

    Choose **Create Token** and copy the generated value privately into
    `POLAR_ACCESS_TOKEN`. Keep it server-only and out of screenshots and source
    control. Keep production runtime tokens limited to runtime scopes.
  </Step>

  <Step>
    ### Install the Polar CLI

    This walkthrough pins [Polar CLI 3.0.0](https://github.com/polarsource/polar/releases/tag/%40polar-sh%2Fcli%403.0.0).
    Set `ASSET` to your platform's archive, then download and verify it:

    <Tabs items={['macOS', 'Linux']}>
      <Tab value="macOS">
        ```sh interactive=true
        ASSET=polar-darwin-arm64.zip   # Intel Macs: polar-darwin-x64.zip
        BASE=https://github.com/polarsource/polar/releases/download/%40polar-sh%2Fcli%403.0.0
        curl -fsSLO "$BASE/$ASSET"
        curl -fsSLO "$BASE/checksums.txt"
        grep " $ASSET\$" checksums.txt | shasum -a 256 -c
        unzip "$ASSET"
        ```
      </Tab>

      <Tab value="Linux">
        ```sh interactive=true
        ASSET=polar-linux-x64.tar.gz   # ARM: polar-linux-arm64.tar.gz
        BASE=https://github.com/polarsource/polar/releases/download/%40polar-sh%2Fcli%403.0.0
        curl -fsSLO "$BASE/$ASSET"
        curl -fsSLO "$BASE/checksums.txt"
        grep " $ASSET\$" checksums.txt | shasum -a 256 -c
        tar -xzf "$ASSET"
        ```
      </Tab>
    </Tabs>

    Continue only when the check prints `OK`. Move the `polar` binary to a folder
    on your `PATH`, such as `~/.local/bin`, and check the version:

    ```sh
    polar --version
    ```

    Continue only if it reports `polar v3.0.0`. Do not run `polar update`; it installs
    the latest release. On Windows, use `polar-windows-x64.zip` from the same
    release and the [official CLI guide](https://polar.sh/docs/integrate/cli/introduction).
  </Step>

  <Step>
    ### Point the CLI at your sandbox organization

    Enter the token privately in the CLI terminal, then inspect the organization:

    ```sh interactive=true
    printf 'Polar sandbox token: '
    stty -echo
    IFS= read -r POLAR_ACCESS_TOKEN
    stty echo
    printf '\n'
    export POLAR_ACCESS_TOKEN
    export POLAR_ENVIRONMENT=sandbox
    polar organizations get <sandbox-organization-id>
    ```

    Continue only when the returned ID/name match your intended sandbox
    organization. Stop before any product or payment operation if they differ.
    Keep the token out of arguments, shell history and shared output.

    In the CLI terminal, `POLAR_ACCESS_TOKEN` overrides saved OAuth
    authentication. See
    [CLI authentication](https://polar.sh/docs/integrate/cli/authentication).
  </Step>

  <Step>
    ### Forward events to your local app

    With your app running, start the listener in the same terminal, where the
    token and `POLAR_ENVIRONMENT=sandbox` are exported:

    ```bash interactive=true
    polar webhook listen http://localhost:3000/api/webhooks/polar --org <sandbox-organization-id>
    ```

    Save its displayed signing secret as `POLAR_WEBHOOK_SECRET` in ignored
    `.env.local`, then restart `bun run dev`. Keep the listener running while
    you test. Replace `3000` if your app uses another port. Keep the token and
    signing secret out of logs, screenshots and commits.

    Checkpoint: `polar webhook listen` prints a signing secret and keeps running.
  </Step>
</Steps>

## If setup fails

| Symptom                                                | Fix                                                                                                                                                    |
| ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `polar organizations get` returns another organization | Stop. Check the organization ID and that the token belongs to the sandbox organization.                                                                |
| CLI commands act on production                         | Token-mode CLI requests default to production while the app defaults to sandbox. Set `POLAR_ENVIRONMENT=sandbox` in that terminal before running them. |
| The listener cannot create a destination               | Add `webhooks:write` to the token.                                                                                                                     |

## What's next

<Cards>
  <Card title="Configure Polar Lifetime Billing" href="/en/docs/billing/polar/lifetime/configure" description="Create one-time offers and connect paid orders to access." />

  <Card title="Configure Polar Subscription Billing" href="/en/docs/billing/polar/subscription/configure" description="Create monthly and yearly offers and connect subscriptions." />
</Cards>
