Skip to content

Take a deposit

Say "take a refundable deposit" and get a reserve page checkout that holds each deposit until you ship, then counts it as the first payment.

For developers

Take a refundable deposit on what you sell before it exists. Each deposit holds a place in line, and at ship it pays the first month.

For developers

Needs Startup

What you get

  • 1Offer with a refundable $29 deposit that pays the first monthOffer
  • 1checkout on your reserve page, card and walletsStripe's Checkout Session
  • 1Order per reserver, held until it shipsOrder
  • 1Customer per reserver, first in line at shipCustomer
  • 1refund to every reserver if it misses the ship dateOrder
  • 1Evidence per deposit, graded as commitmentEvidence

Every deposit comes with four promises the reserve page states:

PromiseWhat happens
Refund on requestIn full, any time before the ship date
Refund on a missAutomatic, to every reserver, if it does not ship by the date
ConversionAt ship, the deposit pays the first invoice or the first order
DisclosureThe page says the product is not built and names the ship date

Your agent does

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

Take a deposit.

Take a refundable deposit.

Take a $50 deposit.

# 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":"once","terms":"Refundable deposit. Refunded in full on request before Leaseline ships, and to everyone if it misses its ship date. At ship it pays the first month."}' | 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: 'once', terms: 'Refundable deposit. Refunded in full on request before Leaseline ships, and to everyone if it misses its ship date. At ship it pays the first month.' })
await $.Offer.publish({ offer: offer.$id })
OFFER=$(npx startup-builder do Offer.create --json '{"price":{"amount":29,"currency":"USD"},"interval":"once","terms":"Refundable deposit. Refunded in full on request before Leaseline ships, and to everyone if it misses its ship date. At ship it pays the first month."}' | 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: 'once', terms: 'Refundable deposit. Refunded in full on request before Leaseline ships, and to everyone if it misses its ship date. At ship it pays the first month.' })\nreturn await $.Offer.publish({ offer: offer.$id })"
  }
}
StateCallsAsks first
IdeaOffer.create, Offer.publishHow many deposits, from how many people reached, by what date?
BuildingOffer.create, Offer.publishShould the deposit pay the first month, or the whole first order?

Change it

  • Make it $49.
  • Make the deposit the whole first year.
  • Refund everyone and close it.
  • Find out if anyone wants this.

Under the hood

Systems
Billing, Ledger, Discovery
Nouns
Offer, Order, Customer, Evidence
Events
Offer.published, Offer.accepted, Order.placed, Order.refunded
Stripe objects
Product, Price, Checkout Session, PaymentIntent, Refund

A deposit accepts the Offer through Offer.accept, which records the reserver as a Customer and places an Order that ships later. The deposit is that Order's first payment, collected on the Startup's own Stripe account. To test whether anyone wants the product, with a bar set first, find out if anyone wants this.