Stripe Payments
This guide helps you set up Stripe payments for local testing and production. A webhook is already configured to handle successful and abandoned payments, refunds and storing transactions in your database.
Follow the steps below to complete the setup.
Testing Locally
Steps
- Login to https://dashboard.stripe.com/
- Enable
Test mode
top right corner - Click
Developers
bottom left corner - Select the
API keys
tab - Copy your
Secret Key
(starts withsk_test_
) - Paste it in
.env.local
->STRIPE_KEY=sk_test_***
- Install Stripe CLI Guide
- Enter these commands in the command line
Terminal
stripe login
stripe listen --forward-to http://localhost:3000/api/webhooks/stripe
- Now copy the webhook signing secret (starts with
whsec_
) - Paste it in
.env.local
->STRIPE_WEBHOOK_SECRET=whsec_***
# These are the required keys for stripe
STRIPE_KEY=******
STRIPE_WEBHOOK_SECRET=******
STRIPE_DASHBOARD_LINK=https://dashboard.stripe.com/test # use https://dashboard.stripe.com/ for deployment
🎉 Local testing settings are now ready!
Note
Webhook secrets on localhost
are valid for 90 days, so if it ever expires, just
run the same commands in step 8
Production
Steps
- Login to https://dashboard.stripe.com/
- Click
Developers
bottom left corner - Select the
API keys
tab - Copy your
Secret Key
(starts withsk_live_
) - Add it to your production environment variables ->
STRIPE_KEY=sk_live_***
- On the same page select the
Webhooks
tab - Click
+ Add Endpoint
- Enter
Endpoint URL
->https://your_app_domain/api/webhooks/stripe
- Click
Select events
and search and add these eventscheckout.session.completed
(successful payments)checkout.session.expired
(abandoned checkout)invoice.paid
(invoice payments)charge.refunded
(payment refunded/partially-refunded)charge.refund.updated
(refund cancelled e.g. canceled from stripe's dashboard/side)customer.subscription.updated
(subscription updates)customer.subscription.deleted
(subscription cancellation)customer.created
(customer creation)
- Click
Add Events
thenAdd endpoint
- Under
Signing secret
, clickReveal
and copy the value - Add it to your production environment variables ->
STRIPE_WEBHOOK_SECRET=whsec_***
🎉 Production settings are now ready!
Configure your stripe settings
/src/utils/config.ts
const config = {
// Stripe payment configuration.
stripe: {
currency: "usd", // Default currency for transactions.
// choose redirect url for production and development environments
// for successful or cancelled payments
redirect: {
// redirects that happen under /api/stripe/checkout
orders: {
successUrl: isProduction
? "https://example_domain.com/account/access"
: "http://localhost:3000/account/access",
cancelUrl: isProduction
? "https://example_domain.com/#pricing"
: "http://localhost:3000/#pricing",
},
// redirects that happen under /api/stripe/subscribe
subscriptions: {
successUrl: isProduction
? "https://example_domain.com/account/access"
: "http://localhost:3000/account/access",
cancelUrl: isProduction
? "https://example_domain.com/#pricing"
: "http://localhost:3000/#pricing",
},
},
},
//...
};
Update webhooks logic
You can skip this step until you decide what you want to do on successful purchases or refunds, you will still test purchases/refunds.
Stripe webhooks are located under src/app/api/webhooks/stripe/route.ts
But to keep things clean and readable I have created src/app/api/webhooks/stripe/_helpers/index.ts
to include all the logic.
Typically you would want to handle giving/revoke access to your products here in case of a successful checkout/refund
Search for TODO
in the same file to understand where to add or update your logic.
Your first test payment walkthrough
- Make sure you have a working dashboard
- Navigate to
/dashboard/products
, clickNew
and create a product - Copy the ID of the newly created product using the
Copy ID
button at the top - Add the product
ID
toconfig.ts
config.ts
const config = {
// ...
products: {
cta: {
id: isProduction
? "677020c8c7d53caf4573a757" // production product id
: "677020c8c7d53caf4573a757", // development product id
},
},
// ...
};
- If your CTA product is a subscription update the
CTAButton
component mode tosubscription
/src/components/CTAButton.tsx
const CTAButton: FC<OmitKeys<ButtonProps, "children">> = ({
className,
...rest
}) => {
const productId = config.products.cta.id;
return productId ? (
<BuyButton
size="lg"
mode="subscription" // update here
className={cn("w-full md:w-64", className)}
productId={productId}
aria-label={`Get ${config.app.name}`}
{...rest}
>
<ShipIcon className="mr-2" /> <span>Get {config.app.name}</span>
</BuyButton>
) : (
<ErrorMessage>CTA Product ID missing from ENV</ErrorMessage>
);
};
- Go to the home page and press the CTA button.
🎉 Payments are now ready!