Bitcoin checkout on Lovable

Lovable builds TanStack Start apps that run on Cloudflare Workers, with Supabase as their database. OpenReceive runs in your app’s own server code: it creates each Lightning invoice, the payment goes straight to your wallet, and payment attempts are stored in your app’s Supabase database. There is no OpenReceive account, no API key and no background worker.

Optional swaps let customers pay with USDT, USDC, SOL, and ETH. A swap provider you configure converts the payment to BTC over Lightning, and it settles into the same wallet. Available assets and networks depend on the provider.

Use @openreceive/* 0.4.23 or newer. The payment route this guide sets up runs in OpenReceive’s CI as a Cloudflare Worker against Supabase’s own database and API server, and it was checked on an app built with Lovable’s build setup. Lovable’s own agent has not run these directions in our tests yet.

Before you start

Add checkout to your Lovable app

  1. Open More → Cloud → Secrets → Add secret. Add NWC_URI with your wallet code, then, for swaps, LSC_URI_PRIMARY with your swap provider code. Secrets reach your app’s server code and never the browser. Lovable already gives server code SUPABASE_URL and SUPABASE_SERVICE_ROLE_KEY.
  2. Send Lovable this prompt:
Add Bitcoin Lightning checkout to this app with OpenReceive. Fetch https://openreceive.org/agent-directions/lovable/full.md and follow it exactly: it has the migration, the server route and the checkout page. NWC_URI and LSC_URI_PRIMARY are already saved as this project's secrets, so do not ask me for them. Use @openreceive packages 0.4.23 or newer.
  1. Lovable writes two Supabase migrations and asks you to apply them. The first is OpenReceive’s: its two tables, locked away from your app’s browser key, and the functions that write them. The second is yours: openreceive_on_paid, which marks an order paid. Apply both.
  2. Lovable ends with “Setup is finished” and tells you where to place an order.

Bitcoin only, with no swap provider? Then in the prompt, replace NWC_URI and LSC_URI_PRIMARY are already saved with I want Bitcoin only, with no swaps. NWC_URI is already saved.

Rather paste the codes in the chat? Leave out the sentence about secrets. Lovable then asks for each code with its secure secret input, one at a time.

Check it

In the preview, place an order. Its checkout shows the payment methods. Pick Bitcoin to see a Lightning invoice. Each swap has a minimum amount set by the provider, so on a small order some coins are greyed out and show their minimum.

If the checkout cannot load and its requests answer 503, the server log names the fix. Usually a migration was not applied, or openreceive_on_paid is still the placeholder, which refuses every payment until it is replaced.

Pay a small order from your wallet to see it settle: the checkout shows the payment as received, and openreceive_on_paid marks the order paid.

How it runs on Lovable

Each payment request makes several calls to Supabase’s API, one after another: 4 to 8 to create a checkout. That is the slower part of a checkout on Lovable, not the wallet.

Keep it intact: AGENTS.md

Lovable reads AGENTS.md at the root of your project on every change. Add this to it, so later edits keep the payment setup safe:

## Payments (OpenReceive)

- The payment routes are src/routes/openreceive.$.ts and
  src/lib/openreceive.server.ts. Fulfillment is the SQL function
  public.openreceive_on_paid. There is no JavaScript onPaid.
- NWC_URI and LSC_URI_PRIMARY are secrets. Never put them in .env, code or a
  VITE_ variable.
- Never grant anon or authenticated anything on openreceive_* tables or
  functions, and never edit OpenReceive's migration.
- Full directions: https://openreceive.org/agent-directions/lovable/full.md

Next