feat(adapters): forward customer IP address on checkout creation

Merged
PI
25d ago
+272-7

Summary

Related Issue: Plain thread th_01M3ZN8RAM580Z4Z2H3GVCQ3KP (Strats.gg)

The Better Auth, Next.js, Nuxt and TanStack Start adapters now send customer_ip_address on checkout creation, so Polar can show the visitor's local currency. Until now they always got the default currency.

What

  • Better Auth: sends the IP from Better Auth's getIP, which follows the app's advanced.ipAddress settings.
  • Next.js / Nuxt / TanStack Start: send the first valid IP from x-forwarded-for, x-real-ip or cf-connecting-ip, unless a customer_ip_address query param is passed.
  • New customerIpAddress option on every adapter: a function to resolve the IP yourself, or false to not send it.
  • @polar-sh/adapter-utils: the shared getCustomerIpAddress and resolveCustomerIpAddress helpers. zod is added as a catalog: dependency.

No SDK bump needed: @polar-sh/sdk 1.0.2 already has the field.

Why

The API uses customer_ip_address to find the visitor's country (_get_ip_country in checkout/service.py) and pick the presentment currency.

How

The API rejects an invalid IP with a 422, which fails the checkout, so the default lookups only send valid IPs. Better Auth's getIP validates on its own; the header lookup uses zod's ipv4/ipv6. The query param and a custom function's result are passed through as given.

Clients can fake these headers unless the host or proxy sets them. Since the IP only picks the currency the checkout opens in, that's an acceptable default.

Checklist

  • This PR addresses a single concern (one bug fix, one feature, one refactor)
  • The diff is reasonably sized and easy to review
  • New functionality is covered by tests
  • Linting and type checking pass (vitest run, tsc/vue-tsc and oxfmt --check in each adapter package)
  • No unrelated changes or drive-by fixes are included

๐Ÿค– Generated with Claude Code

https://claude.ai/code/session_01UfdcmK78gnrYR1QrPnrLNj