Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Polar.sh Integration
POLAR_ACCESS_TOKEN=your_polar_access_token_here
POLAR_30SEC_PRODUCT_ID=your_30sec_product_id_here
POLAR_60SEC_PRODUCT_ID=your_60sec_product_id_here
POLAR_SUCCESS_URL=https://whiskey.fm/sponsor/success

# Optional: Set to "sandbox" for testing, "production" for live (defaults to production)
PUBLIC_POLAR_SERVER=production
35 changes: 35 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,3 +110,38 @@ see fit.

We use Turso and Astro DB to setup guests per episode. If you would also like to
do this, you will need a Turso account.

## Polar.sh Checkout Integration

This site uses Polar.sh for sponsor checkout. To set it up:

1. **Get your Polar credentials:**
- Log in to your [Polar dashboard](https://polar.sh)
- Go to Settings → API to get your access token
- Create two products for your sponsorship packages (30-second and 60-second ads)
- Note the product IDs from each product's page

2. **Configure environment variables:**
Create a `.env` file in the root directory with:
```env
POLAR_ACCESS_TOKEN=your_polar_access_token_here
POLAR_30SEC_PRODUCT_ID=your_30sec_product_id_here
POLAR_60SEC_PRODUCT_ID=your_60sec_product_id_here
POLAR_SUCCESS_URL=https://whiskey.fm/sponsor/success
```

3. **Test the integration:**
- For testing, you can set `PUBLIC_POLAR_SERVER=sandbox` in your `.env`
- Visit `/sponsor` and click on either sponsorship option
- You'll be redirected to Polar's checkout page
- After successful payment, users return to `/sponsor/success`

4. **Go live:**
- Remove `PUBLIC_POLAR_SERVER` or set it to `production`
- Ensure your product IDs are for production products
- Test with a real payment to confirm everything works

The integration uses the `@polar-sh/astro` package which provides:
- Server-side checkout session creation at `/api/checkout`
- Automatic tax compliance through Polar's Merchant of Record service
- Support for multiple products and dynamic pricing
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"@astrojs/preact": "^4.1.1",
"@astrojs/sitemap": "^3.6.0",
"@astrojs/vercel": "^8.2.8",
"@polar-sh/astro": "^0.4.9",
"@preact/signals": "^2.3.1",
"@vercel/analytics": "^1.5.0",
"@vercel/speed-insights": "^1.2.0",
Expand All @@ -31,7 +32,8 @@
"preact": "^10.27.2",
"rss-to-json": "^2.1.1",
"schema-dts": "^1.1.5",
"valibot": "^0.31.1"
"valibot": "^0.31.1",
"zod": "^4.1.12"
},
"devDependencies": {
"@playwright/test": "^1.55.1",
Expand Down
66 changes: 66 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions src/components/AdPackageCard.astro
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ export interface Props {
bullets: Array<string>;
heading: string;
price: string;
productId: string;
}

const { bullets, heading, price } = Astro.props;
const { bullets, heading, price, productId } = Astro.props;
---

<div class="dark:bg-dark-background relative z-10 mb-6 rounded-lg bg-white p-1">
Expand Down Expand Up @@ -37,7 +38,7 @@ const { bullets, heading, price } = Astro.props;
</h3>

<div class="flex w-full">
<a class="btn mb-8 w-full justify-center" href="/contact">
<a class="btn mb-8 w-full justify-center" href={`/api/checkout?products=${productId}`}>
<span
class="text-light-text-heading rounded-full px-8 py-3 text-center text-sm dark:text-white"
>
Expand Down
10 changes: 10 additions & 0 deletions src/pages/api/checkout.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Checkout } from "@polar-sh/astro";

export const prerender = false;

export const GET = Checkout({
accessToken: import.meta.env.POLAR_ACCESS_TOKEN,
successUrl: import.meta.env.POLAR_SUCCESS_URL || 'https://whiskey.fm/sponsor/success',
// Use sandbox for testing, production for live
server: import.meta.env.PUBLIC_POLAR_SERVER || "production",
});
2 changes: 2 additions & 0 deletions src/pages/sponsor.astro
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,13 @@ const countries = [
bullets={['Host read ad', '10% off for 3+', '20% off for 6+']}
heading="30 second ad"
price="$500"
productId={import.meta.env.POLAR_30SEC_PRODUCT_ID || 'YOUR_30SEC_PRODUCT_ID'}
/>
<AdPackageCard
bullets={['Host read ad', '10% off for 3+', '20% off for 6+']}
heading="60 second ad"
price="$1,000"
productId={import.meta.env.POLAR_60SEC_PRODUCT_ID || 'YOUR_60SEC_PRODUCT_ID'}
/>
</div>

Expand Down
36 changes: 36 additions & 0 deletions src/pages/sponsor/success.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
import Layout from '../../layouts/Layout.astro';
---

<Layout title="Thank You!">
<div class="relative z-10 px-8 lg:px-18">
<h1
class="mb-4 text-2xl font-bold text-light-text-heading lg:mb-6 lg:text-5xl dark:text-white"
>
Thank You for Sponsoring!
</h1>

<p class="mb-5 text-light-text-body dark:text-dark-text-body">
Your sponsorship has been successfully processed. We'll be in touch shortly
to coordinate your ad placement and get you set up.
</p>

<p class="mb-5 text-light-text-body dark:text-dark-text-body">
Check your email for confirmation and next steps. If you have any questions,
feel free to <a href="/contact" class="underline hover:text-light-text-heading dark:hover:text-white">contact us</a>.
</p>

<div class="mt-8 flex gap-4">
<a href="/" class="btn">
<span class="text-light-text-heading rounded-full px-8 py-3 text-center text-sm dark:text-white">
Back to Home
</span>
</a>
<a href="/sponsor" class="btn">
<span class="text-light-text-heading rounded-full px-8 py-3 text-center text-sm dark:text-white">
View Sponsor Options
</span>
</a>
</div>
</div>
</Layout>