Inspiration

Digital nomads land in Canggu, Chiang Mai, Da Nang or Lisbon with a laptop and a two-month visa. The Airbnb "desk" is a dining table, and by day three their neck hurts. Buying a standing desk, a chair and a monitor makes no sense for a stay that short, and selling it all again before the next flight is worse.

Meanwhile, coworking spaces, villa managers and rental shops in the same towns have gear sitting idle.

We also noticed that more and more people run their lives from Claude, ChatGPT or Cursor. They don't want to browse a catalog. They want to say "set me up in Bali under $400/month, make it cozy" and have it handled. PayPal is the payment method that travelers already trust across borders.

What it does

Async rents workspace equipment (standing desks, ergonomic chairs, monitors, monitor arms, keyboards, lamps, plants) by the week in digital nomad hubs. Gear is delivered and set up, then billed weekly until it's returned.

There are two ways in:

  • Storefront: a rental e-commerce site. Visitors browse by city and category, compare weekly prices, pick ready-made setups or single pieces, keep a weekly cart, confirm delivery details and pay with PayPal. When they come back from PayPal they see a confirmation, or a way to retry if the payment didn't go through.
  • MCP server: any MCP-capable AI assistant can connect to Async over OAuth and use it as a set of tools: list locations and categories, search products, get a product, quote a rental, rent, start a payment, confirm it, check a rental, list payments and cancel. The assistant gets a PayPal approval link that the customer opens and approves themselves. The assistant never touches money without the customer's approval.

On the payment side:

  • The first payment (first week, refundable deposit and one-time delivery fee) goes through a PayPal order that the customer approves.
  • With the customer's approval, PayPal saves their account in its vault, so later weeks are charged automatically without asking again.
  • A billing run charges every rental that is due. A declined week is retried after 24 hours, and a plan pauses after 3 declines in a row.
  • Payments can be refunded, and rentals can be cancelled.

How we built it

Async is a monorepo, with strict package boundaries:

  • packages/db: the Drizzle schema for Cloudflare D1 (catalog, carts, rentals, payments, billing agreements) and the migrations generated from it. No logic.
  • packages/core: all business logic and the only data access. Each domain (catalog, cart, pricing, rental, payment, billing) is a service built from a factory, and every result is a zod-typed success or failure union. Apps get everything through one createAsync({ db, paymentProviders }) composition root.
  • packages/payment: the PayPal adapter. It implements core's PaymentProviderAdapter interface against PayPal's REST APIs: OAuth tokens, Orders v2 (create, approve, capture), vaulting with store_in_vault: ON_SUCCESS for merchant-initiated weekly charges, and refunds on captures. It is the only place PayPal code lives, so core stays provider-neutral.
  • apps/storefront: TanStack Start (React 19) on Cloudflare Workers, Clerk for sign-in, Tailwind CSS and a shared shadcn/Base UI component library in packages/ui.
  • tools/mcp: a Hono Worker running the Model Context Protocol SDK, protected with OAuth through Clerk's MCP tools. Every tool's input and output is a zod schema with field descriptions written for the model reading them.
  • apps/api: a Hono HTTP API on the same core.

All the apps bind the same D1 database per environment (default, dev, staging), and the migrations are applied from one root Wrangler config.

We built it with T3 Code, guided by architecture and workflow rules in AGENTS.md. Each GitHub issue became one branch and one PR, shipped as stacked PRs with gh stack, and every layer had to pass vp check and vp test (Vite+, with Vitest and Oxlint) on its own.

Challenges we ran into

  • Renting is harder to charge for than buying. A one-off checkout is easy. Weekly billing until return meant modelling deposits, delivery fees, the first charge, recurring charges, retries, pauses and refunds, and making sure a week is never charged twice.
  • Charging later without the customer present. PayPal's vault only saves the account if the app has vaulting enabled and the order asks for it with the right usage type. We had to read the vault status back from each captured order and only trust it once PayPal reports it as VAULTED.
  • Letting an AI take payments safely. The assistant must never approve a payment itself. We split the flow into start_payment, which returns an approval link the customer opens, and confirm_payment, which checks with PayPal that it was really approved. The return pages are static and take no money.
  • Keeping PayPal out of the domain. Designing a provider interface general enough for future providers, but specific enough to support vaulted recurring charges, took several iterations.
  • Tool descriptions are a user interface. The model only knows what the schema tells it, so every field needed a clear description of what it means and when it is missing.

Accomplishments that we're proud of

  • A real end-to-end flow in the PayPal sandbox: browse, cart, checkout, PayPal approval, confirmation, then automatic weekly charges.
  • The same rental and payment logic serves a website, an HTTP API and an AI assistant, with no duplicated rules.
  • An AI assistant can go from "I need a desk in Bali" to a paid, confirmed rental in one conversation, while the customer stays in control of every payment.
  • Core and the PayPal adapter are covered by unit tests for every service, including billing retries and PayPal response parsing.
  • The whole project was built in small, reviewable stacked PRs, and each one stands on its own.

What we learned

  • PayPal's Orders v2 and vault APIs cover recurring, merchant-initiated charges well, without a separate subscriptions product, as long as the vault is requested on the first order.
  • MCP with OAuth turns a backend into something any assistant can use. Most of the work is in naming, describing and limiting the tools, not in the protocol.
  • Clear package boundaries and written architecture rules make AI coding agents much more reliable. The rules in AGENTS.md did more for code quality than any single prompt.
  • Typed result unions with zod make failures part of the contract, which matters when the caller is a model that has to explain an error to a person.

What's next for Async

  • Studio: an interactive isometric room designer where people compose their dream setup, watch the weekly price add up live and hit Rent.
  • Supply side: let coworking spaces, villa managers and rental shops list their idle gear and earn most of the rent.
  • Delivery tracking and returns scheduling, through both the storefront and the assistant.
  • More cities beyond Bali, Chiang Mai, Da Nang and Lisbon, and PayPal payouts for gear owners.

Built With

Share this project:

Updates

Submission history