πŸ’Έ Payments


Setting up payments takes a couple of steps, but it's a one-time set up and worth it to start making money from your apps πŸ˜ƒ.

6-Min Walkthrough


Setup

  1. Create a new account on Stripe. If you plan on accepting real payments, follow instructions to activate your account.

  2. Update your public information and branding according to the details of your app / business. Make sure to set the right website URL, statement descriptor, and logo. For Privacy Policy and Terms of Service pages, use the /tos and /privacy routes pre-built in your template.

  3. Optional: In communication preferences, turn on email notifications for Successful Payments.

  4. Turn on TEST MODE on the top right of the dashboard.

  5. Create a new product and set its pricing and billing period.

  6. Go to your new product's Details page and copy the price ID (under Pricing > API ID; starts with price_) into config/content.ts under pricingPlans[0].priceId. Then fill in the rest of the information about the plan: title, description, price, currency.

If you only have one product, remove the second pricing plan from the pricingPlans[] array. If you have more than one, repeat steps 4-5 for all your products, making sure to add a new pricing plan object in the pricingPlans array.

Your pricingPlans config should now look something like this:

export const pricingPlans: PricingPlan[] = [
  {
    title: 'My Product',
    description: 'My description',
    features: ['Simple', 'list', 'of', 'features'],
    price: '##/mo',
    originalPrice: '##/mo',
    currency: '$',
    isFeatured: true,
    priceId: 'price_xxxxxxx',
  },
];
  1. Go to the Developer API Keys page and copy the Publishable Key and Secret Key into your .env file.

  2. To test your Stripe webhook endpoint locally, first go to the Developer Webhooks page and enable [Test in Local Environment]. Then, install Stripe CLI and run the following command in a new shell:

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

Finally, copy the displayed webhook signing secret (starts with whsec_) into your .env file. You should now see logs in this shell window anytime your localhost app triggers a Stripe event.

Read the Webhooks section below to learn what happens when different Stripe events are triggered.

Production checklist
  1. Turn off TEST MODE

  2. Copy the live API Keys – Publishable Key and Secret Key ΒΊ from the API Keys page into your production environment variables

  3. Under Webhooks, click "Add Endpoint" and set the Endpoint URL as https://your-production-domain.com/api/webhooks/stripe. Click "Select events", toggle "Select all events", and click "Add events". Finally, copy the webhook signing secret and paste it into STRIPE_WEBHOOK_SECRET in your production environment variables

Handling Checkout

In your app, import and use the ButtonCheckout component. When clicked, this creates a Stripe checkout session for the user (either for a one-time payment or a subscription) and redirects them to the checkout URL.

Handling Billing

In your app, import and use the ButtonBilling component. When clicked, the component navigates users to the Stripe billing portal, where they can manage their subscription or payments, view invoices, etc.

Webhooks: Listening to Stripe events

StarterAI comes with a /api/webhooks/stripe route that listens to a set of Stripe events and takes action on them (for example, syncing new customers to the database).

This route also calls updateCustomerAccess() when a payment or subscription status for a user changes. updateCustomerAccess() turns a boolean hasAccess to true or false for a user, which can be used to control users' access to any paid resource (image generation by default).

The logic used for updating customer access is:

  • If a subscription is deleted or payment fails, revoke access
  • If a payment is made, checkout session is completed, or subscription is still active, grant access

You can edit the @/app/api/webhookes/stripe/route.ts file to create webhooks for other Stripe events or edit the logic for existing events. Make sure you followed the steps above to test the webhook locally and set it up in production.


Last Updated: March 5