Skip to Content
Dirly 2.0 is released šŸŽ‰
InstallationStripe Integration

Stripe Setup

Dirly uses Stripe to handle subscription payments and credit purchases. All plan‑specific settings, including Stripe Price IDs, are managed directly from the Admin Panel → Settings page. This guide walks you through the complete Stripe integration – from creating products to configuring webhooks – without ever needing to edit code manually.


Prerequisites

  • A Stripe account (sign up at stripe.comĀ )
  • Your Dirly application already installed and running
  • Admin access to the Dirly admin panel

Step‑by‑Step Integration

1. Create a Stripe Account and Get API Keys

  1. Go to the Stripe DashboardĀ  and log in (or create a new account).
  2. If you haven’t already, activate your account by providing business details (you can use test mode first).
  3. Navigate to Developers → API keys.
  4. Copy the following keys:
    • Publishable key (starts with pk_test_)
    • Secret key (starts with sk_test_)

Use test keys during development. Switch to live keys only when you are ready to go live.

2. Add Stripe Environment Variables

Add the keys to your .env.local file:

STRIPE_SECRET_KEY=sk_test_... NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_... STRIPE_WEBHOOK_SECRET= # You will fill this later after creating the webhook CONVEX_FEATURED_PRICE=4900 # Price for featured status (in cents, $49.00)
  • STRIPE_SECRET_KEY – your secret key (keep it safe, never expose it client‑side).

  • NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY – your publishable key (safe to use on the frontend).

  • STRIPE_WEBHOOK_SECRET – will be set after configuring the webhook (step 5).

  • CONVEX_FEATURED_PRICE – price for featuring a tool for 30 days (default: 4900 = $49). You can change it later by running npx convex env set CONVEX_FEATURED_PRICE 4900.

3. Create Products for Ad Placements in Stripe

Dirly allows users to purchase ad placements. Each placement is a one‑time payment (not a subscription) that activates a 30‑day campaign. In Stripe, you need to create products with a one‑time price.

  1. In the Stripe Dashboard, go to Products → Add Product.

  2. Create three separate products with the following details:

Pricing

Product NamePrice (one-time)Example Price ID
Top Banner Ad$69price_1TBBre0nFlRU9YFbzdUE5BmM
Catalog Ad Card$39price_1TBBu00nFlRU9YFb8NDbtBhI
Project Page Ad Card$19price_1TBBva0nFlRU9YFb3Ffyieu7

For each product:

  • Set the Pricing model to One‑time.

  • After creation, copy the Price ID (starts with price_). You will need these IDs later to configure ad placements in the admin panel.

These Price IDs must be entered into the database via the admin panel or a seed script. Do not hardcode them in environment variables.

4. Manage Ad Placements via Admin Panel

Dirly includes a full admin interface for managing ad placements. You can create, edit, delete, or load default placements without touching the database directly.

  1. Log in to your Dirly admin panel (you need admin privileges).

  2. Navigate to /admin/placements.

  3. You will see a list of existing placements (if any).

  4. Use the Load Default Placements button to automatically insert the three default ad placements (Top Banner, Catalog Card, Project Page Ad Card) with predefined slugs, descriptions, and prices.

  5. To edit a placement, click the Edit icon (pencil). You can modify:

  • Name – display name.

  • Slug – URL‑friendly identifier (used in code).

  • Description – shown to users.

  • Price (one‑time) – in cents (e.g., 6900 for $69).

  • Stripe Price ID – the price_... you copied from Stripe.

  • Available – whether the placement is active.

  1. To create a new placement, click New Placement.

  2. To delete a placement, use the Delete icon (trash).

The Stripe Price ID must match exactly the ID of a one‑time product in Stripe. If it is incorrect or missing, users will not be able to purchase that placement.

5. Configure the Webhook in Stripe Dashboard

The webhook listens for successful payments (payment_intent.succeeded) and updates your database accordingly (activates ad campaigns, grants featured status).

For Local Development

You need to expose your local server to the internet so Stripe can reach it. Use Stripe CLI (recommended) or ngrok.

A. Using Stripe CLI:

Install the Stripe CLI from stripe.com/docs/stripe-cli.

Run:

stripe login stripe listen --forward-to localhost:3000/api/stripe-webhook

The CLI will output a webhook signing secret. Copy it and add to your .env.local:

STRIPE_WEBHOOK_SECRET=whsec_...

B. Using ngrok:

  1. Start your Next.js app (npm run dev).

  2. In another terminal, run:

ngrok http 3000
  1. Copy the generated HTTPS URL (e.g., https://abc123.ngrok.io).

  2. In Stripe Dashboard, go to Developers → Webhooks → Add endpoint.

  3. Enter your ngrok URL + /api/stripe-webhook (e.g., https://abc123.ngrok.io/api/stripe-webhook).

  4. Select Events to send – choose payment_intent.succeeded (this is the event that fires after a successful one‑time payment).

  5. Click Add endpoint.

  6. After creation, click Click to reveal in the Signing secret section and copy the secret. Add it to your .env.local as STRIPE_WEBHOOK_SECRET.

For Production

When your app is live on Vercel (or another platform), create a new webhook endpoint pointing to:

https://yourdomain.com/api/stripe-webhook

Subscribe to payment_intent.succeeded, copy the signing secret, and set it as STRIPE_WEBHOOK_SECRET in your hosting environment (e.g., Vercel Environment Variables).

6. Payment Flow (Already Implemented)

Your application includes the following API routes to create Payment Intents and handle the webhook:

  • Ad placements: app/api/create-payment-intent/route.ts – creates a Payment Intent for a selected ad placement, using the price from the adPlacements table.

  • Featured tool: app/api/create-featured-payment-intent/route.ts – creates a Payment Intent for featuring a tool, using the price stored in the CONVEX_FEATURED_PRICE environment variable.

  • Webhook handler: app/api/stripe-webhook/route.ts – listens for payment_intent.succeeded events. When received, it:

    • For ad placements: creates a new campaign record in the adCampaigns table, active for 30 days.

    • For featured tool: sets the tool’s featured field to true with an expiration date (30 days from payment).

No code changes are required – everything is already wired up.

7. Test the Integration

  1. Make sure your app is running and the webhook is listening (Stripe CLI or ngrok active).

  2. Go to your /advertise page, select an ad placement, fill in the creative details, and click Subscribe (or the payment button).

  3. You will be redirected to Stripe’s Checkout page (or use a Payment Element if integrated). Use the test card:

  • Card number: 4242 4242 4242 4242

  • Expiry: any future date

  • CVC: any 3 digits

  1. After successful payment, you should be redirected back to your app.

  2. Check that the ad campaign appears in the admin panel (/admin/campaigns) and on the frontend (if approved).

  3. For featured tool: go to a tool’s page (you must be the owner of an approved tool), click Feature for $49, complete the payment, and verify that the tool now displays a ā€œFeaturedā€ badge.

  4. In Stripe Dashboard, navigate to Events to confirm that the payment_intent.succeeded event was sent and received successfully.

All test payments appear in Stripe Dashboard with a ā€œTestā€ label. No real money is moved.

Admin Panel Settings Reference

Dirly does not require editing environment variables for prices of ad placements – all placements are managed via the /admin/placements interface. The only Stripe‑related setting stored in the database is the adPlacements table.

Ad Placements Table

After running the default seed or creating placements manually, your adPlacements table will contain records like this:

Ad Placement Schema

FieldExampleDescription
nameTop Banner AdDisplay name
slugtop-bannerURL-friendly unique identifier
descriptionHorizontal banner below the site header on every pageUser-facing description
priceMonthly6900Price in smallest currency unit (cents) – $69 one-time
availabletrueIs this placement currently purchasable
stripePriceIdprice_1TBBre0nFlRU9YFbzdUE5BmMCorresponding Stripe Price ID for one-time payment

You can add, edit, or delete placements directly from the admin panel – changes take effect immediately.

The price for featuring a tool is stored as a Convex environment variable, not in the database. To change it:

npx convex env set CONVEX_FEATURED_PRICE <price_in_cents>

For example, to set the price to $49:

npx convex env set CONVEX_FEATURED_PRICE 4900

After changing the variable, restart your Next.js server to apply the new value.


šŸ†˜ Troubleshooting

ProblemSolution
Checkout session not created (500 error)Check that STRIPE_SECRET_KEY is set correctly. For ad placements, verify that the selected placement has a valid stripePriceId in the database. For featured tool, ensure CONVEX_FEATURED_PRICE is set and is a positive integer.
Webhook returns 400 (signature mismatch)Ensure the STRIPE_WEBHOOK_SECRET in your environment matches the signing secret shown in the Stripe Dashboard for your endpoint.
Ad campaign not activated after paymentCheck the webhook logs in Stripe Dashboard. Make sure your endpoint is reachable and that the event checkout.session.completed is being sent. Verify that the webhook handler correctly updates the adCampaigns table.
Featured status not grantedConfirm that the webhook received the payment event and that the toolId was passed in metadata. Check the Convex database for errors during the mutation.
Default placements not loadingRun the seed script manually from the admin panel (/admin/placements → Load Default Placements). If the button is missing, ensure you have admin privileges and the seed mutation is defined.
Stripe CLI not forwardingMake sure you are running stripe listen in the correct directory and that your Next.js app is running on port 3000.

Conclusion

You have now fully integrated Stripe payments into Dirly without writing any code. All ad placement configurations are managed through the /admin/placements panel, and featured tool pricing can be changed via a Convex environment variable. Users can purchase recurring ad campaigns and one‑time featured upgrades; upon successful payment, the webhook automatically activates the corresponding features.

For further customization, refer to the Stripe API documentationĀ  and the Dirly source code.

Last updated on