---
url: https://saas.dev/docs/stripe
md: https://saas.dev/docs/stripe.md
---

# Stripe

Connect your Stripe account once. SaaS.Dev creates the product and monthly price for Leaseclock Pro, serves the checkout, keeps subscriptions in sync and gives each customer a billing portal. Buy it in Test with card `4242 4242 4242 4242`, then switch to Live.

## In short

[Stripe Checkout in Leaseclock teal: Subscribe to Leaseclock Pro, $29.00 per month](https://leaseclock.com/pricing)

[Northgate Rentals' billing portal: Leaseclock Pro, the card on file and paid invoices](https://leaseclock.com/app/billing)

You write the plan in one file. SaaS.Dev turns it into a Stripe product and price, a pricing card on your site, a checkout, a subscription record in each customer's workspace, a billing portal and a limit the API enforces. Customers pay you through your own Stripe account, and Stripe pays out to your bank. SaaS.Dev takes no share of what your customers pay.

```mdx title="Offer/pro.mdx"
---
name: Leaseclock Pro
price: { amount: 29, currency: USD, unit: month }
limits: { Unit: 200 }
personas: Property manager, Leasing coordinator
status: Live
---
```

| In the Offer | What it becomes |
| --- | --- |
| `name: Leaseclock Pro` | The Stripe product, the title on the pricing card and the line item at checkout |
| `price: { amount: 29, currency: USD, unit: month }` | A Stripe price of $29.00 a month, "$29 a month" on the pricing page, and a charge on the same day each month |
| `limits: { Unit: 200 }` | Room for 200 Units in each workspace. The 201st returns an error that names the plan and its limit |
| `personas: Property manager, Leasing coordinator` | "For property managers and leasing coordinators" on the pricing card |

## Leaseclock Pro on leaseclock.com

Priya Shah, the leasing coordinator at Northgate Rentals, opens [leaseclock.com/pricing](https://leaseclock.com/pricing) and presses Subscribe on Leaseclock Pro. Stripe Checkout opens in Leaseclock's teal, headed "Subscribe to Leaseclock Pro" at $29.00 per month, billed monthly, for up to 200 units. She pays with the company card and lands in Northgate Rentals' new workspace, on its Leases list. The receipt comes from Leaseclock.

Northgate Rentals' 24 units fit inside the plan. A month later Priya opens Billing from the account menu and lands in Stripe's billing portal, also in teal, where she replaces the card on file and downloads the first invoice. Nothing on the way names SaaS.Dev.

## Get paid

### Connect your Stripe account

Run [`npx saas.dev stripe connect`](https://saas.dev/docs/saas-dev-cli.md), or press Connect Stripe on the Billing screen in your admin, and sign in to Stripe. The account stays yours, and you can revoke the connection from Stripe's dashboard at any time. One connection covers Test and Live.

Then push the Offer. SaaS.Dev creates the Stripe product and its monthly price, so you create neither by hand.

```console title="Terminal"
$ npx saas.dev stripe connect
Opening Stripe to connect leaseclock.com
Connected to the Stripe account Leaseclock, in Test and Live

$ npx saas.dev push Offer/pro.mdx
Checked Offer/pro.mdx
Created the Stripe product Leaseclock Pro
Created the Stripe price $29.00 USD a month
Pushed to Test
```

### Check the price

Open [leaseclock.com/pricing](https://leaseclock.com/pricing). The card reads "Leaseclock Pro, $29 a month", rendered from `amount`, `currency` and `unit`, so the page and the charge always agree.

### Buy it in Test

On the Billing screen, press Buy in Test, and subscribe with Stripe's test card `4242 4242 4242 4242`, any future expiry date and any CVC. SaaS.Dev checks the signature on Stripe's event and records the subscription once, however many times Stripe delivers it.

With a Test key in `LEASECLOCK_TOKEN`, the CLI reads the Test copy:

```console title="Terminal"
$ npx leaseclock show subscriptions
WORKSPACE           OFFER           STATUS   PRICE          RENEWS
Northgate Rentals   Leaseclock Pro  active   $29.00 / month 2026-11-21
```

To see how Leaseclock handles a card that fails, buy again with one of Stripe's other test cards.

| Card | What happens |
| --- | --- |
| `4000 0025 0000 3155` | The bank asks for authentication, and Checkout shows the challenge |
| `4000 0000 0000 9995` | The card is declined for insufficient funds, and Checkout asks for another card |
| `4000 0000 0000 0341` | The first payment succeeds and the next renewal fails, so the subscription reads `past_due` |

### Go live

```console title="Terminal"
$ npx saas.dev push --live
Checked Noun/Unit.mdx, Noun/Lease.mdx and Offer/pro.mdx
Created the live Stripe product Leaseclock Pro
Created the live Stripe price $29.00 USD a month
Pushed to Live: https://leaseclock.com
```

A property manager such as Northgate Rentals picks Leaseclock Pro, pays through Stripe Checkout and becomes your customer. `unit: month` renews the subscription every month. Customers change their card or cancel in Stripe's billing portal.

### Money in your account

The money lands in your own Stripe account, and Stripe pays it out to your bank on your payout schedule.

To change the price, edit `amount` and push the Offer again. The next checkout sells the new price, and every subscription keeps the price it bought.

```diff title="Offer/pro.mdx"
- price: { amount: 29, currency: USD, unit: month }
+ price: { amount: 39, currency: USD, unit: month }
```

```console title="Terminal"
$ npx saas.dev push Offer/pro.mdx --live
Created the live Stripe price $39.00 USD a month
New checkouts sell $39.00. Northgate Rentals keeps $29.00.
```

## Read billing from code

A subscription is a record in Leaseclock like a Lease or a Unit, so your team and your scripts read it from every generated surface. Each customer's agent reads its own workspace's subscription, and nobody else's.

**API**

```bash title="Terminal"
curl https://leaseclock.com/api/subscriptions/northgate-rentals \
  -H "Authorization: Bearer $LEASECLOCK_TOKEN"
```

```json title="200 OK"
{
  "$id": "https://leaseclock.com/api/subscriptions/northgate-rentals",
  "$type": "Subscription",
  "workspace": "northgate-rentals",
  "offer": "pro",
  "status": "active",
  "price": { "amount": 29, "currency": "USD", "unit": "month" },
  "renewsOn": "2026-11-21",
  "portal": "https://leaseclock.com/app/billing"
}
```

**CLI**

```console title="Terminal"
$ npx leaseclock show subscriptions/northgate-rentals
Northgate Rentals · Leaseclock Pro · active
$29.00 / month, renews 2026-11-21
Billing portal: https://leaseclock.com/app/billing
```

**SDK**

```ts title="billing.ts"
import { Leaseclock } from 'leaseclock'

const $ = new Leaseclock({ token: process.env.LEASECLOCK_TOKEN })

const sub = await $.Subscription.get('northgate-rentals')

sub.status     // 'active'
sub.renewsOn   // '2026-11-21'
```

Your own account at SaaS.Dev answers at `api.saas.dev`. Check the Stripe connection and what each Offer sells from a script, with the token `npx saas.dev login` stores, issued by id.org.ai:

```bash title="Terminal"
curl https://api.saas.dev/products/leaseclock.com/stripe \
  -H "Authorization: Bearer $SAAS_DEV_TOKEN"
```

```json title="200 OK"
{
  "connected": true,
  "account": "Leaseclock",
  "modes": ["test", "live"],
  "offers": [
    { "offer": "pro", "product": "Leaseclock Pro", "price": { "amount": 29, "currency": "USD", "unit": "month" } }
  ]
}
```

## Questions

### Does SaaS.Dev take a share of each payment?

No. Stripe charges its standard fee on each payment, and the rest is yours. SaaS.Dev bills you separately: your first product is free, and each one after it is $49 a month.

### Do I set up webhooks or API keys?

No. Connecting your account registers Stripe's events with SaaS.Dev, which checks each signature and applies each event once. No Stripe key appears in your files or your code.

### Can I use the Stripe account I already have?

Yes. Connect it, and SaaS.Dev adds one product for each Offer. Your existing products, customers and payouts stay as they are.

### Can I sell more than one plan, or bill yearly?

Yes. Add a second Offer file, such as `Offer/team.mdx`, and the pricing page shows both cards, each with its own checkout. Set `unit: year` and Stripe gets a yearly price.

### What happens when a renewal fails?

Stripe retries the card on your Stripe retry schedule and emails the customer a link to update it. The subscription reads `past_due` in your admin until a retry succeeds, the customer updates the card in the billing portal, or the subscription ends.

### What happens to billing if I leave SaaS.Dev?

Your Stripe account, its customers and their subscriptions stay in Stripe, where they always were. One call exports your definition files and every record.
