Paddle payment integration + Claude-powered auto build log pipeline
What I built
Added Paddle as a first-class payment provider alongside the existing Stripe/Toss setup, with a single runtime env var controlling which provider activates. Ran Playwright smoke tests across all 8 locales. Then wired up a pipeline where every git push triggers Claude CLI to generate a build log — which is exactly what you’re reading right now.
How it came together
The Paddle integration had one hard constraint: don’t touch the existing Stripe/Toss code. The solution was an effectiveProvider runtime flag in paywall/page.tsx. Set NEXT_PUBLIC_PAYMENT_PROVIDER=paddle and all non-KR traffic routes to Paddle. Unset it and you get the country-default behavior. Two new API routes — /api/checkout/paddle/create and /api/checkout/paddle/webhook — handle the Paddle-side flow. Passed typecheck and next build clean.
The more interesting story is the automation pipeline. The prompt that drove it:
“Set up a husky pre-push hook that calls
claude -pto generate build logs, then use GitHub Actions to auto-sync them to the portfolio repo and open a PR with blog drafts when there are 5+ commits.”
The key design decision was gtimeout 60 wrapping the Claude CLI call. If it hangs, the push shouldn’t block. Failure exits gracefully with || echo "⚠️ skip". Two bugs burned time: macOS doesn’t have timeout (had to install coreutils for gtimeout), and the Claude CLI path failed with a relative reference (hardcoded to /Users/jidong/.local/bin/claude).
On the Vercel side: five consecutive fix commits just to get the deployment working. The monorepo root needed to point at apps/web, the framework preset had to be nextjs explicitly in vercel.json, and env vars had to be set before the build could succeed. Classic deploy thrash, but at least each commit is cleanly labeled fix(deploy):.
The launch readiness audit was prompted with: “No guessing — every claim needs a file path or an actual HTTP response.” Claude ran pnpm dev:web, hit every API endpoint, tested rate limits to exhaustion (confirmed 429 on the 5th request), and checked all 8 locales on desktop and iPhone 12 viewport. Zero P0 issues found.
Commit log
82e29d8chore: add automation setup (Paddle API routes, Husky hook, GitHub Actions, E2E suite, audit docs)a6379edfix(deploy): set Next.js framework in vercel.json7feb33ffix(deps): add three and @types/three to web package2e10679fix: use gtimeout for macOSbb714cefix: use full path for claude CLIe659c9bfix(deploy): ignore husky failure in CI environment3789e6dfix(deploy): remove .env.local from git tracking5c7cecechore: trigger rebuild with env vars configured
Results
| Before | After | |
|---|---|---|
| Payment providers | Stripe + Toss | Stripe + Toss + Paddle (env-var switchable) |
| Rate limiting | None | 5 req/day on LLM endpoints |
| E2E coverage | 0 | 8 locales × core user flow |
| Build log creation | Manual | Auto-generated by Claude CLI on every push |
| Vercel deploy | Broken | Stable after framework preset fix |