Skip to content

Charge monthly

Say "charge $29 a month" and get a monthly plan, checkout on your domain, a billing portal, retries for failed cards, sales tax and up-to-date books.

For developers

Charge a monthly Price for an Offer: each Customer holds a Subscription that Stripe renews and collects.

For developers

Needs Startup

What you get

  • 1Offer with a $29 monthly PriceOffer
  • 1monthly price set up on StripePrice
  • 1checkout on your domainOffer
  • 1Subscription per Customer who checks out, renewed each monthSubscription
  • 1Invoice each month, paid by the saved cardInvoice
  • 1billing portal to change card, plan or cancelPortal
  • 1retry plan for failed payments, before access pausesProcess
  • 1sales tax on every chargeInvoice
  • 2lines in your books per charge: cash in, and revenue counted as each month is earnedEntry

Your agent does

Offer.create → Offer.publish
You, to your agent

Charge $29 a month.

Make Leaseline Pro a $29 monthly subscription.

Bill customers every month and let them cancel on their own.

# 1. Offer.create
OFFER=$(curl -X POST https://api.sb/leaseline.app/offers \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"price":{"amount":29,"currency":"USD"},"interval":"month","terms":"Monthly, billed in advance. Cancel any time from the billing portal."}' | jq -r '.offer["$id"] | split("/") | last')

# 2. Offer.publish
curl -X POST https://api.sb/leaseline.app/offers/$OFFER/publish \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY"
import { $ } from 'startup-builder'

const offer = await $.Offer.create({ price: { amount: 29, currency: 'USD' }, interval: 'month', terms: 'Monthly, billed in advance. Cancel any time from the billing portal.' })
await $.Offer.publish({ offer: offer.$id })
OFFER=$(npx startup-builder do Offer.create --json '{"price":{"amount":29,"currency":"USD"},"interval":"month","terms":"Monthly, billed in advance. Cancel any time from the billing portal."}' | jq -r '.offer["$id"] | split("/") | last')
npx startup-builder do Offer.publish --json '{"offer":"'"$OFFER"'"}'
{
  "name": "do",
  "arguments": {
    "code": "const offer = await $.Offer.create({ price: { amount: 29, currency: 'USD' }, interval: 'month', terms: 'Monthly, billed in advance. Cancel any time from the billing portal.' })\nreturn await $.Offer.publish({ offer: offer.$id })"
  }
}

Change it

  • Add a $290 annual plan.
  • Give a 14-day free trial.
  • Raise the price for new customers only.

Under the hood

Systems
Billing, Ledger, Tax
Nouns
Offer, Price, Subscription, Invoice, Entry
Events
Offer.created, Offer.published, Offer.subscribed, Subscription.renewed
Stripe objects
Product, Price, Checkout Session, Subscription, Invoice, Customer Portal, Tax Calculation

Each Customer then subscribes at checkout, which runs Offer.subscribe. Revenue posts as deferred and moves to earned as each month passes. A failed renewal retries on the dunning schedule, then pauses the Customer's Entitlements.