Purchase Automation Guide

This guide shows you how to automatically grant audiobook access when customers payβ€”no manual work required!

🎯 How It Works

Customer Pays β†’ Webhook Fires β†’ User Created β†’ Access Granted β†’ Email Sent
     β”‚              β”‚                β”‚               β”‚              β”‚
   Stripe      Your Worker      Find/Create    Purchase      Welcome to
  Gumroad      Receives         Account        Recorded      Library!
LemonSqueezy   Webhook

βœ… Supported Payment Providers

ProviderBest ForFee
StripeFull control, subscriptions2.9% + $0.30
LemonSqueezySimple, EU VAT handled5% + $0.50
GumroadAudience already there10%

Step 1: Create Products in Stripe

Stripe Dashboard β†’ Products β†’ Add Product

Product 1:
  Name: "WILDFLOWER Audiobook"
  Price: $14.99
  Metadata: book=wildflower

Product 2:
  Name: "TALLY Audiobook"
  Price: $14.99
  Metadata: book=tally

Product 3 (Bundle):
  Name: "The Inverter Cycle - Complete"
  Price: $24.99
  Metadata: book=wildflower,tally

Step 2: Set Up Webhook

Stripe Dashboard β†’ Developers β†’ Webhooks β†’ Add Endpoint

Endpoint URL: https://audio.kbird.ai/webhooks/stripe

Select Events:
  β˜‘οΈ checkout.session.completed
  β˜‘οΈ payment_intent.succeeded

Signing Secret: (copy this, you'll need it for verification)

Step 3: Test Purchase

# Use Stripe CLI to test
curl -X POST https://audio.kbird.ai/webhooks/stripe \
  -H "Content-Type: application/json" \
  -d '{
    "type": "checkout.session.completed",
    "data": {
      "object": {
        "id": "test_session_123",
        "customer_email": "[email protected]",
        "amount_total": 1499,
        "metadata": { "book": "wildflower" }
      }
    }
  }'

Step 4: Add Stripe Secret (Optional Verification)

# Add webhook signing secret for verification
npx wrangler secret put STRIPE_WEBHOOK_SECRET
# Paste your Stripe webhook signing secret

πŸ‹ Option 2: LemonSqueezy

Step 1: Create Products

LemonSqueezy Dashboard β†’ Products β†’ Create Product

Product:
  Name: WILDFLOWER Audiobook
  Price: $14.99
  File: (optional - just a README with link to audio.kbird.ai)

Step 2: Configure Webhook

Settings β†’ Webhooks β†’ Add Webhook

Webhook URL: https://audio.kbird.ai/webhooks/lemonsqueezy

Events:
  β˜‘οΈ order_created

Signing Secret: (copy from webhook details)

Step 3: Add Secret

npx wrangler secret put LEMONSQUEEZY_WEBHOOK_SECRET

πŸ“¦ Option 3: Gumroad

Step 1: Create Products

Gumroad β†’ Products β†’ Add Product

Product:
  Name: WILDFLOWER Audiobook
  Price: $14.99
  File: (optional, or just description with instructions)

Step 2: Enable Webhook

Settings β†’ Advanced β†’ Webhooks

Payload URL: https://audio.kbird.ai/webhooks/gumroad

Secret: (generate random string, save it)

Step 3: Add Secret

npx wrangler secret put GUMROAD_WEBHOOK_SECRET

πŸ“§ Customer Email Flow

After purchase, customers should receive:

Immediate (Payment Confirmation)

From: Payment provider (Stripe/Gumroad/etc) Subject: β€œYour receipt for WILDFLOWER Audiobook”

Follow-up (Access Instructions) - YOU SEND THIS

From: [email protected] Subject: β€œYour WILDFLOWER Audiobook is ready!”

Hi [Name],

Thank you for purchasing WILDFLOWER!

🎧 Access Your Audiobook:
https://audio.kbird.ai

πŸ“§ Your Login Email: [[email protected]]
πŸ”‘ Set Your Password:
https://audio.kbird.ai/auth/forgot-password

What to expect:
β€’ Chapter 18 is FREE (no login needed)
β€’ Chapters 1-17 are in your library
β€’ Stream anytime, forever
β€’ Works on all devices

Questions? Reply to this email.

β€” Kristopher Richards

πŸ§ͺ Testing Webhooks Locally

Using Stripe CLI

# Install Stripe CLI
brew install stripe/stripe-cli/stripe
 
# Login
stripe login
 
# Forward webhooks to local dev
stripe listen --forward-to localhost:8787/webhooks/stripe
 
# Trigger test event
stripe trigger checkout.session.completed

Using ngrok

# If webhooks need public URL
npx ngrok http 8787
 
# Use the ngrok URL in Stripe webhook settings:
# https://abc123.ngrok.io/webhooks/stripe

πŸ” Security Checklist

  • Webhook endpoints verify signatures
  • HTTPS only (Cloudflare handles this)
  • Duplicate event handling (idempotent)
  • Customer email validation
  • Rate limiting on endpoints (Cloudflare WAF)

πŸ› Troubleshooting

Webhook not firing?

# Check Cloudflare logs
npx wrangler tail
 
# Check if endpoint is reachable
curl -X POST https://audio.kbird.ai/webhooks/stripe \
  -H "Content-Type: application/json" \
  -d '{"type":"test"}'

Customer didn’t get access?

  1. Check purchases table in D1:
SELECT * FROM purchases 
WHERE payment_id = 'pi_xxx' 
ORDER BY purchased_at DESC;
  1. Check users table:
SELECT * FROM users 
WHERE email = '[email protected]';
  1. Check worker logs in Cloudflare dashboard

Duplicate purchases?

The webhook handler is idempotentβ€”same payment_id won’t create duplicate purchases because of unique constraints. But you should still handle this:

// Check if purchase already exists
const existing = await env.DB.prepare(
  'SELECT id FROM purchases WHERE payment_id = ?'
).bind(session.id).first();
 
if (existing) {
  return jsonResponse({ success: true, message: 'Already processed' });
}

πŸ’‘ Advanced: Custom Payment Flow

Example: Buy Button on Your Site

<!-- On kbird.ai -->
<button id="buy-wildflower">Buy WILDFLOWER - $14.99</button>
 
<script>
document.getElementById('buy-wildflower').addEventListener('click', async () => {
  // Create Stripe Checkout Session
  const response = await fetch('https://api.kbird.ai/create-checkout', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      book: 'wildflower',
      success_url: 'https://kbird.ai/thanks',
      cancel_url: 'https://kbird.ai/cancel'
    })
  });
  
  const { url } = await response.json();
  window.location = url;
});
</script>

Backend (Optional)

If you want a custom checkout server:

// api.kbird.ai/create-checkout
app.post('/create-checkout', async (req, res) => {
  const session = await stripe.checkout.sessions.create({
    line_items: [{
      price_data: {
        currency: 'usd',
        product_data: { name: 'WILDFLOWER Audiobook' },
        unit_amount: 1499,
      },
      quantity: 1,
    }],
    mode: 'payment',
    success_url: req.body.success_url,
    cancel_url: req.body.cancel_url,
    metadata: { book: req.body.book }
  });
  
  res.json({ url: session.url });
});

πŸ“Š Monitoring

Set up alerts for:

  1. Failed webhooks (check Cloudflare Workers analytics)
  2. Unusually high refund rates
  3. Customers without purchases trying to access (could indicate sharing)
-- Find users with high download counts
SELECT user_id, COUNT(*) as downloads 
FROM downloads 
WHERE access_type = 'purchase'
GROUP BY user_id 
HAVING downloads > 100;

πŸŽ‰ You’re Done!

Once configured:

  1. Customer clicks β€œBuy” on your site or payment provider
  2. Pays with credit card/PayPal
  3. Webhook automatically fires
  4. Account created (if new) or existing found
  5. Purchase recorded in database
  6. Customer receives email
  7. They log in at audio.kbird.ai and listen!

No manual work required! 🎧


Need Help?