Creem
How to set up and use Creem to handle payments and subscriptions
ShipSaaS uses Creem for payment management, supporting both one-time payments and subscription payments.
Setup
The ShipSaaS template provides three pricing plans by default: a free plan, a pro subscription plan (monthly/yearly), and a lifetime plan (one-time payment). Follow these steps to configure them:
Create Creem Account
Create a Creem account at creem.io. No credit card is required to register.
Get API Keys
Obtain your API keys from the Creem Dashboard:
- Navigate to Creem Dashboard >
Developers>API & Webhooks, and create a new API Key. - Copy the API key (Note: Test mode starts with
creem_test_, while live mode starts withcreem_live_). - Save it in your environment variable file as
CREEM_API_KEY.
Configure Webhook
Set up a Webhook and obtain your Webhook signing secret:
- Navigate to Creem Dashboard >
Developers>API & Webhooks, and create a new Webhook. - Add your Webhook URL:
https://YOUR-DOMAIN.com/api/webhooks/creem - Creem automatically listens to all payment and subscription-related events, including:
checkout.completedsubscription.activesubscription.paidsubscription.updatesubscription.canceledsubscription.scheduled_cancelsubscription.expiredsubscription.past_duesubscription.pausedsubscription.trialing
- Save the Webhook settings and copy the newly created Webhook signing secret.
- Save it in your environment variable file as
CREEM_WEBHOOK_SECRET.
Create Products and Pricing Plans
Create products and configure pricing plans in Creem:
- Navigate to Creem Dashboard >
Commerce>Products - Create a product for the Pro Subscription Plan:
- Click to create a product.
- Name:
Pro Plan - Description:
Premium features with subscription pricing - Add Monthly Subscription Price:
- Price:
9.90(Select currencyUSD) - Billing Type:
recurring - Billing Interval:
every-month - Save and copy the Product ID (starts with
prod_), which will be used forVITE_CREEM_PRODUCT_PRO_MONTHLY
- Price:
- Copy the monthly subscription product, and this time add a yearly subscription price:
- Price:
99.00(Select currencyUSD) - Billing Type:
recurring - Billing Interval:
every-year - Save and copy the Product ID (starts with
prod_), which will be used forVITE_CREEM_PRODUCT_PRO_YEARLY
- Price:
- Create a product for the Lifetime Plan:
- Click to create a product.
- Name:
Lifetime Plan - Description:
One-time payment for lifetime access - Add Price:
- Price:
199.00(Select currencyUSD) - Billing Type:
one_time - Save and copy the Product ID (starts with
prod_), which will be used forVITE_CREEM_PRODUCT_LIFETIME
- Price:
Configure Environment Variables
Add the following environment variables:
.env
# Payment Provider
VITE_PAYMENT_PROVIDER=creem
# Set to 'true' to use the Creem test API; omit or set to 'false' to use the production environment
# CREEM_DEBUG=true
# API Key and Webhook Secret
CREEM_API_KEY=creem_test_...
CREEM_WEBHOOK_SECRET=...
# Product IDs
VITE_CREEM_PRODUCT_PRO_MONTHLY=prod_...
VITE_CREEM_PRODUCT_PRO_YEARLY=prod_...
VITE_CREEM_PRODUCT_LIFETIME=prod_...Update Website Configuration
Update the payment section in src/config/website.ts to configure your pricing plans—amount, currency, intervals, and plan metadata. The enable, provider, and priceId fields are automatically resolved based on the environment variables (VITE_PAYMENT_PROVIDER and VITE_CREEM_PRODUCT_*), so no hardcoding is needed.
You must configure this section to match the products you created in Creem:
src/config/website.ts
payment: {
enable: isPaymentEnabled, // ← Auto: true when VITE_PAYMENT_PROVIDER is set
provider: isPaymentEnabled ? paymentProvider : undefined, // ← Auto: 'creem'
price: {
plans: {
free: {
id: 'free',
prices: [],
isFree: true,
isLifetime: false,
},
pro: {
id: 'pro',
prices: [
{
type: 'subscription',
priceId: priceIds.proMonthly, // ← Auto: from VITE_CREEM_PRODUCT_PRO_MONTHLY
amount: 990, // Amount in cents ($9.90)
currency: 'USD',
interval: 'month',
},
{
type: 'subscription',
priceId: priceIds.proYearly, // ← Auto: from VITE_CREEM_PRODUCT_PRO_YEARLY
amount: 9900, // Amount in cents ($99.00)
currency: 'USD',
interval: 'year',
},
],
isFree: false,
isLifetime: false,
popular: true,
},
lifetime: {
id: 'lifetime',
prices: [
{
type: 'one_time',
priceId: priceIds.lifetime, // ← Auto: from VITE_CREEM_PRODUCT_LIFETIME
amount: 19900, // Amount in cents ($199.00)
currency: 'USD',
allowPromotionCode: true,
},
],
isFree: false,
isLifetime: true,
},
},
},
},If you are setting up your environment, you can now return to the Environment Configuration document and continue. The remainder of this document can be read later.
Environment configuration set environment variables
Development Environment
For local development, it is recommended to use hostc to expose your local server to the internet so that Creem can send Webhook events to your machine:
npx hostchostc will generate a temporary domain for you (e.g., https://xxxx.hostc.dev). Because Creem needs to communicate with your local server via Webhooks, you will need to update this temporary domain in three places:
Update .env Environment Variables
Edit your .env file to add or update the following variable:
.env
# Add your temporary domain to the environment variables
APP_URL=https://xxxx.hostc.devUpdate Google OAuth Credentials Settings
If your application uses Google OAuth login, you need to update your authorized redirect URIs in the Google Cloud Console:
- Navigate to
APIs & Services>Credentials - Edit your OAuth client
- Add to
Authorized JavaScript origins:https://xxxx.hostc.dev - Add to
Authorized redirect URIs:https://xxxx.hostc.dev/api/auth/callback/google
Update Creem Webhook URL
Set the Webhook URL in your Creem Dashboard to your temporary domain:
- Navigate to Creem Dashboard >
Developers>API & Webhooks - Add Webhook URL:
https://xxxx.hostc.dev/api/webhooks/creem
After completing the above configurations, you can initiate payments on your website to test whether the event handling workflow behaves as expected.
Creem provides a full testing environment. When using API keys starting with creem_test_, all operations are performed in a sandbox, and no real transactions will occur.
Production Environment
- Navigate to Creem Dashboard >
Developers>API & Webhooks - Add your production Webhook URL:
https://YOUR-DOMAIN.com/api/webhooks/creem - Switch your API key from the test key (
creem_test_) to the production key (creem_live_) - Ensure your environment variables are updated with production keys and product IDs
Webhook Events
Creem supports the following Webhook events:
| Event | Description |
|---|---|
checkout.completed | Checkout session completed |
subscription.active | New subscription created (used only for synchronization) |
subscription.paid | Subscription payment successful (used to activate access) |
subscription.update | Subscription updated (plan changes, billing renewal) |
subscription.canceled | Subscription canceled |
subscription.scheduled_cancel | Subscription scheduled to cancel at the end of the current billing cycle |
subscription.past_due | Payment failed; subscription is retrying payment |
subscription.expired | Billing cycle ended and no payment was received |
subscription.trialing | Subscription entered a trial period |
subscription.paused | Subscription was paused |
Creem recommends using the subscription.paid event to activate user access instead of the subscription.active event. The subscription.active event is only intended for data synchronization.
Customer Portal
After every successful payment, your customer will receive an email containing a link to their Customer Portal. The Customer Portal allows them to:
- View subscription details
- Manage subscriptions (upgrade, pause, cancel)
- View payment history
- Update payment methods
Test Cards
To test your Creem integration, use Creem's test mode and test credit cards:
4242 4242 4242 4242- Successful payment4000 0000 0000 0002- Failed payment
When using test mode (API keys starting with creem_test_), all transactions occur in a sandbox environment and will not incur real charges.
Best Practices
- Secure API Keys: Never expose your Creem API keys in client-side code.
- Verify Webhook Signatures: Always verify the
creem-signatureof incoming Webhook events. - Handle Errors Gracefully: Provide user-friendly error messages when a payment fails.
- Test Webhooks Thoroughly: Ensure that all Webhook events are processed correctly.