Skip to content

Commit a9c68b1

Browse files
chuckcarpenterRobbieTheWagner
authored andcommitted
✨ Add Polar package and checkout flow (#6)
* ✨ Add Polar package and checkout flow * 🔥 Remove slack webhook example * ♻️ Fix conflict in package file * ♻️ Update to have build time deps in devdependencies * ♻️ Update lock file
1 parent 512ad91 commit a9c68b1

9 files changed

Lines changed: 181 additions & 18 deletions

File tree

.env.example

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Polar.sh Integration
2+
POLAR_ACCESS_TOKEN=your_polar_access_token_here
3+
POLAR_30SEC_PRODUCT_ID=your_30sec_product_id_here
4+
POLAR_60SEC_PRODUCT_ID=your_60sec_product_id_here
5+
POLAR_SUCCESS_URL=https://whiskey.fm/sponsor/success
6+
7+
# Optional: Set to "sandbox" for testing, "production" for live (defaults to production)
8+
PUBLIC_POLAR_SERVER=production

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,6 @@ test-results/
2727

2828
# macOS-specific files
2929
.DS_Store
30-
package-lock.json
30+
31+
# AI settings
32+
AGENTS.md

README.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,3 +169,38 @@ your `starpod.config.ts` and RSS feed:
169169
- `/{episode-number}.html.md` - Alternative episode URL
170170

171171
No configuration needed - it just works!
172+
173+
## Polar.sh Checkout Integration
174+
175+
This site uses Polar.sh for sponsor checkout. To set it up:
176+
177+
1. **Get your Polar credentials:**
178+
- Log in to your [Polar dashboard](https://polar.sh)
179+
- Go to Settings → API to get your access token
180+
- Create two products for your sponsorship packages (30-second and 60-second ads)
181+
- Note the product IDs from each product's page
182+
183+
2. **Configure environment variables:**
184+
Create a `.env` file in the root directory with:
185+
```env
186+
POLAR_ACCESS_TOKEN=your_polar_access_token_here
187+
POLAR_30SEC_PRODUCT_ID=your_30sec_product_id_here
188+
POLAR_60SEC_PRODUCT_ID=your_60sec_product_id_here
189+
POLAR_SUCCESS_URL=https://whiskey.fm/sponsor/success
190+
```
191+
192+
3. **Test the integration:**
193+
- For testing, you can set `PUBLIC_POLAR_SERVER=sandbox` in your `.env`
194+
- Visit `/sponsor` and click on either sponsorship option
195+
- You'll be redirected to Polar's checkout page
196+
- After successful payment, users return to `/sponsor/success`
197+
198+
4. **Go live:**
199+
- Remove `PUBLIC_POLAR_SERVER` or set it to `production`
200+
- Ensure your product IDs are for production products
201+
- Test with a real payment to confirm everything works
202+
203+
The integration uses the `@polar-sh/astro` package which provides:
204+
- Server-side checkout session creation at `/api/checkout`
205+
- Automatic tax compliance through Polar's Merchant of Record service
206+
- Support for multiple products and dynamic pricing

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
"@astrojs/preact": "^5.0.0",
2727
"@astrojs/vercel": "^10.0.0",
2828
"@libsql/client": "^0.17.2",
29+
"@polar-sh/astro": "^0.4.9",
2930
"@preact/signals": "^2.8.2",
3031
"@vercel/analytics": "^1.6.1",
3132
"@vercel/speed-insights": "^1.3.1",
@@ -36,7 +37,8 @@
3637
"preact": "^10.28.4",
3738
"rss-to-json": "^2.1.1",
3839
"schema-dts": "^1.1.5",
39-
"valibot": "^1.2.0"
40+
"valibot": "^1.2.0",
41+
"zod": "^4.1.12"
4042
},
4143
"devDependencies": {
4244
"@astrojs/check": "^0.9.7",

pnpm-lock.yaml

Lines changed: 81 additions & 14 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/components/AdPackageCard.astro

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@ export interface Props {
33
bullets: Array<string>;
44
heading: string;
55
price: string;
6+
productId: string;
67
}
78
8-
const { bullets, heading, price } = Astro.props;
9+
const { bullets, heading, price, productId } = Astro.props;
910
---
1011

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

3940
<div class="flex w-full">
40-
<a class="btn mb-8 w-full justify-center" href="/contact">
41+
<a class="btn mb-8 w-full justify-center" href={`/api/checkout?products=${productId}`}>
4142
<span
4243
class="text-light-text-heading rounded-full px-8 py-3 text-center text-sm dark:text-white"
4344
>

src/pages/api/checkout.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { Checkout } from "@polar-sh/astro";
2+
3+
export const prerender = false;
4+
5+
export const GET = Checkout({
6+
accessToken: import.meta.env.POLAR_ACCESS_TOKEN,
7+
successUrl: import.meta.env.POLAR_SUCCESS_URL || 'https://whiskey.fm/sponsor/success',
8+
// Use sandbox for testing, production for live
9+
server: import.meta.env.PUBLIC_POLAR_SERVER || "production",
10+
});

src/pages/sponsor.astro

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,13 @@ const countries = [
4141
bullets={['Host read ad', '10% off for 3+', '20% off for 6+']}
4242
heading="30 second ad"
4343
price="$500"
44+
productId={import.meta.env.POLAR_30SEC_PRODUCT_ID || 'YOUR_30SEC_PRODUCT_ID'}
4445
/>
4546
<AdPackageCard
4647
bullets={['Host read ad', '10% off for 3+', '20% off for 6+']}
4748
heading="60 second ad"
4849
price="$1,000"
50+
productId={import.meta.env.POLAR_60SEC_PRODUCT_ID || 'YOUR_60SEC_PRODUCT_ID'}
4951
/>
5052
</div>
5153

0 commit comments

Comments
 (0)