Payment
Learn how to set up and use Stripe for handling payments and subscriptions
MkSaaS uses Stripe for payment management, handling both one-time payments and recurring subscriptions.
Setup
MkSaaS boilerplate uses three price plans by default: Free plan, Pro subscription plan (monthly/yearly), and Lifetime plan (one-time payment), follow these steps to set up Stripe integration:
Create Stripe Account
Create a Stripe account at stripe.com.
Get API Keys
Get your API keys from the Stripe dashboard:
- Go to the Stripe Dashboard >
Developers>API keys - Copy your Secret key (note: starts with
sk_test_for test mode orsk_live_for live mode) - Save it to your environment variables file as
STRIPE_SECRET_KEY
Set Up Webhook
Set up Webhook and get your Webhook Secret:
- Go to the Stripe Dashboard >
Developers>Webhooks - Click
Add endpoint - Enter Webhook URL:
https://=YOUR-DOMAIN.com/api/webhooks/stripe - Select the events to listen for:
invoice.paidcheckout.session.completedcustomer.subscription.createdcustomer.subscription.updatedcustomer.subscription.deleted
- Click
Revealto view Webhook Signing Secret (starts withwhsec_) - Save it to your environment variables file as
STRIPE_WEBHOOK_SECRET
You can find more information in Webhooks section if you want to test payment in development environment.
Create Products and Pricing Plans
Create products and pricing plans in Stripe:
- Go to the Stripe Dashboard >
Product Catalog - Create Pro subscription product:
- Click
Add product - Name:
Pro Plan - Description:
Advanced features with subscription pricing - Add monthly price:
- Click
Add price - Price: $9.90 (currency select USD)
- Recurring: Monthly
- Save and copy the Price ID (starts with
price_), this will be used forNEXT_PUBLIC_STRIPE_PRICE_PRO_MONTHLY
- Click
- Add yearly price:
- Click
Add price - Price: $99.00 (currency select USD)
- Recurring: Yearly
- Save and copy the Price ID (starts with
price_), this will be used forNEXT_PUBLIC_STRIPE_PRICE_PRO_YEARLY
- Click
- Click
- Create Lifetime product:
- Click
Add product - Name:
Lifetime Plan - Description:
One-time payment for lifetime access - Add a price:
- Price: $199.00 (currency select USD)
- Type: One-off
- Save and copy the Price ID (starts with
price_), this will be used forNEXT_PUBLIC_STRIPE_PRICE_LIFETIME
- Click

Add Environment Variables
Add the following environment variables:
STRIPE_SECRET_KEY=sk_test_...
STRIPE_WEBHOOK_SECRET=whsec_...
# Price plans
NEXT_PUBLIC_STRIPE_PRICE_PRO_MONTHLY=price_...
NEXT_PUBLIC_STRIPE_PRICE_PRO_YEARLY=price_...
NEXT_PUBLIC_STRIPE_PRICE_LIFETIME=price_...Set Up Customer Portal
Set up the Stripe Customer Portal:
- Go to the Stripe Dashboard >
Settings>Billing>Customer Portal - Customize the content of the customer portal, for example, you can add a custom logo and title
- Click
Save changesto save the portal configuration

Update Website Configuration
Update the website.tsx file to use Stripe as the payment provider in the payment configuration, and configure your pricing plans in the price configuration:
import { PaymentTypes, PlanIntervals } from '@/payment/types';
export const websiteConfig = {
// ...other config
payment: {
provider: 'stripe', // Payment provider to use
},
price: {
plans: {
free: {
id: 'free',
prices: [],
isFree: true,
isLifetime: false,
credits: {
enable: true,
amount: 50,
expireDays: 30,
},
},
pro: {
id: 'pro',
prices: [
{
type: PaymentTypes.SUBSCRIPTION,
priceId: process.env.NEXT_PUBLIC_STRIPE_PRICE_PRO_MONTHLY!,
amount: 990,
currency: 'USD',
interval: PlanIntervals.MONTH,
},
{
type: PaymentTypes.SUBSCRIPTION,
priceId: process.env.NEXT_PUBLIC_STRIPE_PRICE_PRO_YEARLY!,
amount: 9900,
currency: 'USD',
interval: PlanIntervals.YEAR,
},
],
isFree: false,
isLifetime: false,
popular: true,
credits: {
enable: true,
amount: 1000,
expireDays: 30,
},
},
lifetime: {
id: 'lifetime',
prices: [
{
type: PaymentTypes.ONE_TIME,
priceId: process.env.NEXT_PUBLIC_STRIPE_PRICE_LIFETIME!,
amount: 19900,
currency: 'USD',
allowPromotionCode: true,
},
],
isFree: false,
isLifetime: true,
credits: {
enable: true,
amount: 1000,
expireDays: 30,
},
},
},
},
// ...other config
}If you are setting up the environment, now you can go back to the Environment Setup guide and continue. The rest of this guide can be read later.
Environment Setup
Set up environment variables
Webhooks
Stripe Webhooks are essential for handling asynchronous events like successful payments and subscription updates.
Development
For local development, use the Stripe CLI to forward events to your local server:
pnpm install -g stripe/stripe-cliLogin to Stripe:
stripe loginForward events to your local server:
stripe listen --forward-to localhost:3000/api/webhooks/stripeThe Webhook secret is printed in the terminal. Copy it and add it to your environment variables file:
STRIPE_WEBHOOK_SECRET=whsec_...You can trigger test events using the Stripe CLI, or test events on the website:
stripe trigger invoice.paid
stripe trigger checkout.session.completed
stripe trigger customer.subscription.created
stripe trigger customer.subscription.updated
stripe trigger customer.subscription.deletedProduction
- Go to the Stripe Dashboard > Developers > Webhooks
- Click
Add endpoint - Enter Webhook URL:
https://=YOUR-DOMAIN.com/api/webhooks/stripe - Select the events to listen for:
invoice.paidcheckout.session.completedcustomer.subscription.createdcustomer.subscription.updatedcustomer.subscription.deleted
- After creating, click
Revealto view your Webhook Signing Secret - Copy the Webhook secret (starts with
whsec_) and add it to your environment variables
UI Components
MkSaaS includes pre-built React components for handling payments:
Extending New Payment Providers
MkSaaS supports extending with new payment providers:
- Create a new file in the
src/payment/providerdirectory - Implement the
PaymentProviderinterface fromtypes.ts - Update the payment provider selection logic in
index.ts
Example implementation:
import {
PaymentProvider,
CreateCheckoutParams,
CheckoutResult,
CreatePortalParams,
PortalResult,
Subscription,
getSubscriptionsParams
} from '@/payment/types';
export class MyProvider implements PaymentProvider {
constructor() {
// Initialize your payment provider
}
public async createCheckout(params: CreateCheckoutParams): Promise<CheckoutResult> {
// Implementation for creating a checkout session
}
public async createCustomerPortal(params: CreatePortalParams): Promise<PortalResult> {
// Implementation for creating a customer portal
}
public async handleWebhookEvent(payload: string, signature: string): Promise<void> {
// Implementation for handling webhook events
}
}Then update the payment provider selection in index.ts:
import { MyProvider } from './provider/my-provider';
export const initializePaymentProvider = (): PaymentProvider => {
if (!paymentProvider) {
if (websiteConfig.payment.provider === 'stripe') {
paymentProvider = new StripeProvider();
} else if (websiteConfig.payment.provider === 'my-provider') {
paymentProvider = new MyProvider();
} else {
throw new Error(
`Unsupported payment provider: ${websiteConfig.payment.provider}`
);
}
}
return paymentProvider;
};Testing Cards
For testing Stripe integration, use Stripe's test mode and test credit cards:
- 4242 4242 4242 4242 - Successful payment
- 4000 0000 0000 3220 - 3D Secure authentication required
- 4000 0000 0000 9995 - Insufficient funds failure
You can find more information about Stripe test cards in the Stripe documentation.
Invoices
MkSaaS has already configured the invoice creation for one-time payments.
// Automatically create an invoice for the one-time payment
checkoutParams.invoice_creation = {
enabled: true,
};If you want to automatically send paid invoices, you can enable it in your Customer emails settings, under Email customers about, select Successful payments. After that, you can access the invoices in the Stripe Dashboard > Invoices.

You can find more information about Automatically send paid invoices in the Stripe documentation.
Diagram
This is the diagram of the payment process, you can watch the video tutorial for more details.

FAQ
How to activate WeChatPay and Alipay?
You can activate WeChatPay and Alipay in the Stripe Dashboard > Settings > Payment methods. You can find more information about WeChat Pay and Alipay in the Stripe documentation.

How to limit users to only one subscription?
You can enable Limit customers to 1 subscription in the Stripe Dashboard > Settings > Checkout and Payment Links > Subscriptions. You can find more information about Limit customers to one subscription in the Stripe documentation.

MkSaaS Docs