# Metered URL: /docs/features/payments/metered Learn how to setup and use metered payments in your project. ## Payment Structure If you're using the [Cloudflare Monorepo](/docs/picking-a-template/cloudflare-monorepo) template, the `@workspace-apps/web` app defines a metered subscription plan out of the box. Payments are structured as follows: 1. Free tier with low usage limits * e.g. 20K tokens per month for $0 2. Pro tier with higher usage limits, with some limits that can be exceeded for a usage-based fee * e.g. 10M tokens per month for $29. $3.5/1M tokens over 10M Note that if you need to change the pricing structure (e.g. add another tier), you will need to make revisions to the `@workspace-apps/web` app in the following locations: 1. `/apps/web/src/server/router/payment/router.ts`. 2. `/apps/web/src/server/router/plans/router.ts`. ## Setup Create a new Stripe account and activate payments. ### Business settings Set up your business details so that you can start accepting payments. 1. Go to the [Settings](https://dashboard.stripe.com/settings) of the Stripe dashboard 2. Click on the [Business](https://dashboard.stripe.com/settings/account) section. 3. Click on the [Account details](https://dashboard.stripe.com/settings/account) tab and fill out the form as needed. 4. Click on the [Business details](https://dashboard.stripe.com/settings/business-details) tab and fill out the form as needed. * You can do this later when you need to start accepting payments (i.e. are ready to switch off Stripe's test mode). 5. Click on the [Branding](https://dashboard.stripe.com/settings/branding) tab, and add your icon, logo, and colors. 6. Click on the [Customer emails](https://dashboard.stripe.com/settings/emails) tab and enable emails "Successful payments" and "Refunds". ### Payment settings Recommendations to avoid potential abuse and fraud. 1. Go back to the [Settings](https://dashboard.stripe.com/settings) page. 2. Click on the [Payments](https://dashboard.stripe.com/settings/payments) section. 3. Click on the [Checkout and Payment Links](https://dashboard.stripe.com/settings/checkout) tab, and enable "Limit customers to 1 subscription". * This will help prevent potential race conditions, where users might subscribe multiple times on accident. 4. Click on the [Payment methods](https://dashboard.stripe.com/settings/payment_methods) tab, and enable only the payment methods you want to offer. * We recommend disabling "Cash App Pay" to mitigate abuse and fraud. Many customers using it tend to cancel transactions. ### Billing settings Recommendations for avoiding failed payments. 1. Go back to the [Settings](https://dashboard.stripe.com/settings) page. 2. Click on the [Billing](https://dashboard.stripe.com/settings/billing/automatic) section. 3. Click on the [Subscriptions and emails](https://dashboard.stripe.com/settings/billing/automatic) tab. 4. Enable the following Customer emails: * Send a reminder email 7 days before a free trial ends * Send emails about upcoming renewals * Send emails about expiring cards * Send emails when card payments fail * Send emails when bank debit payments fail 5. Within the "Payment method updates" section, select "Link to a Stripe-hosted page" 6. Within the "Subscription management" section, select "Include a link for customers to manage their subscriptions" 7. In the "Manage free trial messaging" section, enable the "Statement descriptor" option. ### API keys Connect your Stripe account to your project. 1. Go to the [API keys](https://dashboard.stripe.com/apikeys) page. You can find this by clicking on the "Developers" link at the bottom of the left sidebar. 2. Create a "Secret key", and copy values for `STRIPE_SECRET_KEY` and `STRIPE_PUBLISHABLE_KEY`. 3. Add these values to your `.dev.vars` file in the following locations: * `/apps/meter/.dev.vars` * `/apps/web/.dev.vars` ```txt title=".dev.vars" STRIPE_SECRET_KEY="sk_test_..." STRIPE_PUBLISHABLE_KEY="pk_test_..." ``` 4. Go to the [Webhooks](https://dashboard.stripe.com/workbench/webhooks) page. You can find this by clicking on the "Developers" link at the bottom of the left sidebar. 5. Click on "Add destination" and set the "Endpoint URL" to point to a URL that you want to receive webhooks from Stripe. * Note that if you are running the project locally, you will need to tunnel your selected Endpoint URL to your local machine. This is because Stripe is unable to access localhost origins. 6. Enable the following events: * `checkout.session.completed` * `customer.subscription.created` * `customer.subscription.deleted` * `customer.subscription.paused` * `customer.subscription.pending_update_applied` * `customer.subscription.pending_update_expired` * `customer.subscription.resumed` * `customer.subscription.trial_will_end` * `customer.subscription.updated` * `invoice.marked_uncollectible` * `invoice.paid` * `invoice.payment_failed` * `invoice.payment_succeeded` 7. Click on "Create destination", and copy the "Signing secret" value. 8. Add this value to your `.dev.vars` file in `/apps/web/.dev.vars` as `STRIPE_WEBHOOK_SECRET`. ```txt title=".dev.vars" STRIPE_WEBHOOK_SECRET="whsec_..." ``` ### Product and prices Create your product and prices to offer to your customers. 1. Go to the [Products catalog](https://dashboard.stripe.com/products) page. 2. Click on "Create product" and fill out the name, description and image. 3. In the pricing section of the product, select "More pricing options". * Ensure "Recurring" is selected. * Select the "Flat rate" pricing model, a "Monthly" billing period, and set the price to your desired price. * This is your flat price before applying usage-based overage fees. * Click "Next" to create the flat rate price. 4. Click on "Add another price" * Ensure "Recurring" is selected. * Select the "Usage-based" pricing model, with "per tier" and "Graduated" selected. * Set the price of the first tier to $0 for both "Per unit" and "Flat fee", up to the amount of usage included in the flat rate price. * e.g. If you have a flat rate price of $29/month for 10M tokens, set the first tier to $0 for 10M "Last units". * Add another tier, and set the "Flat fee" price to $0, and the Per unit price to the usage-based fee. * e.g. If you have a unit price of $3.5/1M tokens, set the Per unit price to $0.0000035. 5. Click on the "+" button next in the "Meter" section to create a new billing meter. This will track the usage of the product for billing purposes. * Set the "Event name" to something like "token\_meter", and set the "Aggregation method" to "Sum". * Save your "Event name" to the "STRIPE\_METER\_NAME" in your wrangler.jsonc file at `/apps/meter/.wrangler.jsonc` for both "staging" and "production" environments. ```json title="/apps/meter/.wrangler.jsonc" { // ... "vars": { "STRIPE_METER_NAME": "token_meter" }, // ... } ``` 6. Copy the "Product ID" and "Price ID" (for both the flat rate and usage-based price) and add them to your `wrangler.jsonc` file at `/apps/web/.wrangler.jsonc` for both "staging" and "production" environments (note that staging should use IDs from your Stripe test account). ```json title="/apps/web/.wrangler.jsonc" { // ... "vars": { "STRIPE_FLAT_PRICE_ID": "price_...", "STRIPE_METERED_PRICE_ID": "price_...", "STRIPE_PRODUCT_ID": "prod_...", }, // ... } ``` ### Set Product metadata We assume that you may want to potentially use the same Stripe business account for multiple products, each with different Stripe webhooks and settings. Unfortunately, Stripe does not allow partitioning webhooks by product, so we use Stripe metadata to differentiate between products. 1. On your newly created product, click on the "Edit" button within the "Metadata" section. * Create a key-value pair with the key `appId` and the value of your `appId` that you have chosen for your project in `/packages/configs/appConfig.js` under `stripe.appId`. 2. Click on your flat-rate price, and add the same `appId` key-value pair to the "Metadata" section. 3. Click on your usage-based price, and add the same `appId` key-value pair to the "Metadata" section.