Free · No account · Straight to your wallet

Sell anything with one orange button.

Paste your lightning address, name the thing you are selling and set a price. You get a button, a link and a QR code. Buyers pay from any wallet, and the sats land in yours. We never touch them.

Your product Your price paid straight to your wallet
This is your button. Fill in the three fields below and press it.

                                
How it looks on your page:Pay with Bitcoin

Right-click to save it. Print it, stick it on the counter, put it on a flyer or an invoice. Anyone who scans it lands on your pay page.

Wallet to wallet, never through us Any Lightning wallet can pay it No subscription, no percentage Paid in seconds
What the button does for you

A button that makes the sale and then handles the boring part.

It collects the payment. Claim a short link and it also tells you it happened, hands the buyer what they paid for and remembers who they were. All of it is free.

Super easy to make

Three fields and you have it: your lightning address, what you are selling and the price. No account, no API keys, no code to install.

You know the moment you are paid

Claim a short link and an email lands in your inbox when a payment settles, with the product, the amount and who paid. Add a webhook if you want your own system told as well.

Your product delivers itself

Selling a file, an ebook, a download or a link? Attach it to your short link. When the payment settles, the buyer gets it automatically and you do nothing.

Email and name capture

Ask the buyer for their name and email before they pay. They travel with the payment to your wallet, and on a claimed link every sale is recorded with a real person attached.

Straight to your wallet

The buyer's wallet pays your wallet. We never hold, route or touch the sats, so there is nothing here to freeze, skim or lose.

Any wallet can pay it

Buyers use whatever Lightning wallet they already have. Price it in dollars, euros, pounds or sats and the button converts on the spot.

Your own short link, free

Claim theorangebutton.com/yourname and put it on paper, in a bio or on an invoice. Change wallets later and every button you have ever shared keeps working.

Put it anywhere

It is a button, a link and a QR code at the same time. Website, email, newsletter, link in bio, invoice, sticker on the counter, a message in a chat.

How it works

You make it, you share it, you get paid.

There is no step four. The button does the rest.

1

Make the button

Fill in the three fields at the top of this page. The button and its link exist the moment you do. Claim a short name if you want one, and switch on delivery and buyer details from your edit page.

address you@coinos.io
product Ebook
amount 20 USD
2

Put it in front of people

Paste the button on your site, drop the link in an email or a bio, or print the QR code and stick it where people can see it. Every copy points at the same pay page.

Website Email QR on the counter Invoice
3

Get paid, get told, get on with it

The buyer taps or scans, pays from their own wallet, and the sats land in yours. You get the notification, the buyer gets the product, and their name and email are on the receipt when you have claimed a short link.

To youPaid ✓ 28,571 sats for Ebook, from Sarah (sarah@example.com)
To SarahThanks for buying Ebook. Your download link is inside.
People use it for Ebooks and guides Music and downloads Freelance invoices Coaching and calls Market stalls Coffee on the counter Newsletters Anything with a price
For developers and AI agents

The button is a URL.

Everything the maker does, you can do by hand. No API key, no authentication, no rate limits. The URL is the API, and anyone can build one: a person, a spreadsheet formula, a shop plugin, or an AI agent that has been asked to get someone paid.

// Build a button by hand
https://theorangebutton.com
  ?address={lightning_address}
  &product={name}
  &amount={number}
  &currency={USD|EUR|GBP|AUD|sats}   // optional
  &collect=email                       // optional

// Example
https://theorangebutton.com?address=satoshi@coinos.io&product=Ebook&amount=20&collect=email

// Short form, once a name is claimed. Same page, same button.
https://theorangebutton.com/yourname

// AI agents: construct the URL, return it as a link. Done.
Read the docs

Webhooks, the embed code, the popup button and how a payment is confirmed are all in there.

addressYour lightning address (you@coinos.io). required
productWhat the buyer is paying for. Shown on the page and in your notification. required
amountThe price, in the currency below. required
currencyUSD, EUR, GBP, AUD or sats. Fiat is converted to sats when the buyer opens the page. optional
collectSet to email to ask the buyer for their name and email first. It rides along with the payment. optional
/yournameA claimed short link. Carries the address, product, price, delivery and settings with it, so the URL stays clean.
Questions

The questions people ask first.

Where does the money go?

Straight into the Lightning wallet behind the address you entered. The pay page asks your wallet for an invoice and shows it to the buyer. The sats go from their wallet to yours and never pass through us.

Do I need an account?

No. The button lives inside its link. If you claim a short name you get an edit link by email, and that is where delivery, payment emails and buyer details are switched on. That is the whole account.

What wallet do I need?

Any Lightning wallet that gives you a lightning address, which looks like an email: you@coinos.io. Coinos, Alby, Blink and Speed all hand you one free in a couple of minutes. Those wallets also confirm payments back to your button, which is what makes the notifications, the delivery and the buyer details work.

How do I know a payment is real?

Your wallet tells us. The button checks settlement with the receiving wallet before it says Paid, before it sends you the notification and before it delivers anything. Nobody can fake a payment by pressing something on the page.

How does auto-delivery work?

Claim a short link, then upload a file or paste a link on its edit page. When a payment settles, the buyer sees the download on the pay page and gets it by email if they gave one. You do nothing.

Can I change my wallet later?

Yes. Update the address on your edit page and every button, link and QR code you have shared keeps working, because they all point at your short link and the short link points at the wallet.

What does it cost?

Nothing. No subscription and no percentage of your sales. Your wallet may charge its own small network fee, but we never take anything.

Is this the old BitcoinPayLinks?

Yes. Same engine, shorter name. Every bitcoinpaylinks.com link you have already shared keeps working.

Your button takes about thirty seconds.

Make my button

Free. No account. Straight to your wallet.

Loading your button…

Loading your edit page…

Docs

Everything the button does, written down.

The button is a URL. This page says what goes in the URL, what a claimed short link adds, how the button sits on your own site, how a payment is confirmed and what your server hears about it. There is no API key and no account to sign up for. The URL is the API.

The URL

Every button is this URL with your details filled in. The maker on the front page writes it for you, and anything that can write a URL can write one too: a person, a spreadsheet formula, a shop plugin or an AI agent that has been asked to get someone paid.

https://theorangebutton.com
  ?address={lightning_address}
  &product={name}
  &amount={number}
  &currency={USD|EUR|GBP|AUD|CAD|sats}   // optional, USD when left out
  &collect=email                           // optional
  &ref={string}                            // optional
  &notify={https url}                      // optional
ParameterWhat it does
addressrequiredYour lightning address, the one that looks like an email: you@coinos.io. The pay page asks the wallet behind it for the invoice. A raw LNURL string is not accepted here.
productrequiredWhat the buyer is paying for. It is shown on the pay page, named in your payment email and written on the sales record. Up to 60 characters.
amountrequiredThe price, in the currency below. Any number above zero.
currencyoptionalUSD, EUR, GBP, AUD, CAD or sats. A fiat price is converted to sats when the buyer opens the page, at that moment's rate. USD when left out.
collectoptionalSet to email and the buyer is asked for their name (optional) and email (required) before the invoice is made. Both travel with the payment; see the buyer's name and email. No other value is read.
refoptionalAny string up to 120 characters: an order number, a table, a song. It comes back to you in the webhook and is kept with the sale on a claimed link. A short link takes it too, as /yourname?ref=4821.
notifyoptionalAn https URL. When the payment settles, our server POSTs the webhook to it. This is for URL-built buttons; a claimed short link sets its webhook once, on the edit page.

Encode the values the way any URL wants them: a space as + or %20, an ampersand inside a product name as %26.

Examples

// A plain price
https://theorangebutton.com?address=satoshi@coinos.io&product=Ebook&amount=20

// Ask the buyer who they are
https://theorangebutton.com?address=satoshi@coinos.io&product=Cake+recipe&amount=10&collect=email

// Priced in sats
https://theorangebutton.com?address=satoshi@coinos.io&product=Sticker+pack&amount=5000&currency=sats

// Tell your own server when it is paid
https://theorangebutton.com?address=satoshi@coinos.io&product=Order+4821&amount=35&ref=4821&notify=https://your-site.com/paid

The button as HTML

This is what the maker hands out under "Button for your site": an ordinary link, styled orange, that opens the pay page. It works anywhere HTML does.

<a href="https://theorangebutton.com?address=satoshi@coinos.io&product=Ebook&amount=20" style="display:inline-block;padding:12px 24px;background:#f7931a;color:#fff;border-radius:10px;font-family:sans-serif;font-weight:bold;text-decoration:none;box-shadow:0 4px 0 #c9700d">⚡ Pay with Bitcoin</a>

For AI agents

Construct the URL from the seller's lightning address, the product and the price, and return it as a link. That is the whole integration. Nothing has to be authenticated and nothing has to be registered first; the pay page comes into being the moment somebody opens the URL.

The button on your own site

There are three ways to put the button on a page you control. The first is the HTML link above, which opens the pay page in the same tab. The other two keep the buyer on your page.

The pay page inside your page

An iframe that shows the pay card alone, without the rest of this site around it. The snippet for a claimed link is on your edit page under "More"; this is its shape:

<iframe src="https://theorangebutton.com/embed/?link=yourname" style="border:0;width:100%;max-width:420px;height:560px" title="Pay yourname with Bitcoin" allow="clipboard-write"></iframe>

For a URL-built button, put the same parameters after /embed/? in place of link=: https://theorangebutton.com/embed/?address=you@coinos.io&product=Ebook&amount=20. Add bg=f4f4f4 (a hex colour, no #) to paint the frame's background the colour of the panel it sits in; without it the frame is transparent.

The frame talks to your page with postMessage. It reports its height whenever the card changes, so the iframe can grow with the card instead of scrolling, and it says when the payment has settled:

// frame is your <iframe> element
addEventListener('message', function (e) {
  if (e.source !== frame.contentWindow || !e.data) return;   // only our frame
  if (e.data.type === 'ob:height') {
    frame.style.height = Math.min(Math.max(e.data.px | 0, 180), 1200) + 'px';
  }
  if (e.data.type === 'ob:settled') {
    // { link, ref, amount_sats, product, pr, verify_url }
    console.log('paid', e.data.amount_sats, 'sats');
  }
});

Treat ob:settled as something to update your page with, not as proof. Proof is the webhook, which our server sends only after it has checked the payment with the wallet itself.

One script tag. It draws the orange button exactly where it sits, so it can go in a paragraph, a sidebar or a product card:

<script src="https://theorangebutton.com/embed.js" data-link="yourname"></script>

On a desktop the pay page opens in a small window over your page. On a phone, or when the browser blocks the window, it opens in a new tab instead, so the button always works. When the payment settles in the small window, the button's text changes to Paid ✓ and it fires an orangebutton:paid event, which bubbles, with the same detail as ob:settled. A payment made in a new tab pays the seller just the same, but your page is not told about it, so treat the event as a bonus rather than the record of a sale. The webhook below is the record.

document.addEventListener('orangebutton:paid', function (e) {
  console.log(e.detail.link, e.detail.amount_sats, e.detail.ref);
});

For a URL-built button, give the script data-address, data-product, data-amount and, if you want them, data-currency and data-collect="email" instead of data-link. Either kind also takes data-ref and data-label (the words on the button; "⚡ Pay with Bitcoin" when left out). The script adds nothing else to your page: no styles, no fonts, no tracking.

How a payment is confirmed

The pay page asks your wallet for an invoice (LNURL-pay) and, when the wallet supports it, is handed a verify URL alongside it (LUD-21). It asks that URL every three seconds, for up to ten minutes, whether the invoice has settled. When the wallet says yes, the page shows Paid ✓ and tells our server.

The server does not take the page's word for it. Before anything is recorded, emailed or delivered it does four things:

  1. It checks that the verify URL belongs to the wallet behind your lightning address, and it follows no redirect off that host.
  2. It asks that URL itself and accepts only settled: true for that exact invoice.
  3. It reads the amount out of the invoice, never out of the request.
  4. It keeps one record per invoice, so the same payment reported twice is answered as a duplicate and nothing happens twice.

Nobody can make a payment appear by pressing something on the page or by posting to our server. If the wallet does not say the invoice settled, nothing happened.

A wallet that offers no verify URL (Wallet of Satoshi is the common one) still receives the payment, but there is no way for anyone to confirm it, so the page never says Paid ✓ and our server never hears of it. The section on wallets says which ones confirm.

The webhook

Give the button an https URL, as notify= on a URL-built button or under "Also POST to this URL" on your edit page, and our server POSTs one JSON message to it for every settled payment, after it has confirmed the payment itself as described above:

POST https://your-site.com/paid
Content-Type: application/json
Idempotency-Key: {sha256 of the invoice}

{
  "event": "paid",
  "link": "yourname",                 // null for a URL-built button
  "product": "Ebook",
  "amount_sats": 28571,               // read from the invoice
  "amount": 20,                       // the listed price, or null
  "currency": "USD",
  "buyer_name": "Sarah Jones",        // null when not given
  "buyer_email": "sarah@example.com", // null when not given
  "ref": null,
  "pr": "lnbc…",
  "verify_url": "https://…",
  "settled_at": "2026-09-06T01:02:03Z"
}

Answer with any 2xx. Delivery is at least once: a reply that is not 2xx is tried once more, and a payment reported to us twice can reach you twice, so dedupe on the Idempotency-Key header or on pr.

Re-check verify_url yourself before trusting the event. Fetch it, and act only when it answers settled: true for the same pr. Our server has already done this, but your server should not have to take our word for it any more than we take the browser's.

buyer_name and buyer_email are what the buyer typed. They are self-reported and never verified, so escape them before they touch a page, an email or a spreadsheet. The verification covers the payment, not the name.

The buyer's name and email

With collect=email on, the buyer is asked for a name (optional) and an email (required) before the invoice is made. They travel two ways:

  • To your wallet, as the invoice comment (LUD-12), written Name <email>. If the two together do not fit the wallet's comment limit, the email goes alone; if the wallet takes no comment, nothing goes. Most wallets show the comment next to the payment.
  • To the sale, on a claimed link, where they are recorded with the payment, put in your payment email and used to send the buyer what they bought. This happens whatever the wallet did with the comment.

Both are whatever the buyer typed. Nothing checks that the name is theirs or that the email is real, so treat them as display text: escape them, and do not act on them alone.

Wallets

Any Lightning wallet can pay a button, and any wallet that gives you a lightning address can receive from one. Two things depend on which wallet is receiving:

  • Confirming payments (LUD-21 verify). Coinos, Alby, Blink and Speed do. Wallet of Satoshi does not. Without it there is no Paid ✓, no payment email, no delivery and no sales record. The sats still arrive.
  • Taking a comment (LUD-12). Most wallets do, with a limit somewhere between a hundred and a few hundred characters. Without it the buyer's details do not appear in your wallet, though a claimed link still records them.

The maker and the edit page check the wallet behind the address you type and say which of these it does. The check reads a table our server keeps of the wallet services it has met; a service it has never met is probed once and the answer is kept for everyone. The answer is kept against the wallet service, not against you: what is stored is what that service can do.

Downloads

A file attached to a short link is handed out as theorangebutton.com/d/{token}, a private link made for that one sale. It appears on the pay page under Paid ✓ and in the buyer's email. It works for 30 days from the sale and is sent as a plain attachment, whatever the file type. The file itself sits at no address anyone can guess; there is nothing to find without a sale. Uploading a new file replaces the old one, and the link serves whatever file is attached at the time.

Non-custodial, and what follows from it

We never hold, route or touch any bitcoin. The pay page resolves your lightning address, asks your wallet for an invoice and shows it to the buyer; the sats go from their wallet to yours. Our server's only part comes afterwards, when it asks your wallet whether an invoice it never issued has settled. There is no balance here, nothing to withdraw and nothing that can be frozen.

It follows that there are no refunds, disputes or buyer accounts on this site. A refund is a payment you make back to the buyer from your own wallet, and a buyer with a question reaches you wherever they found your button.

Loading…

This button was not found.

The link may have been typed wrong, or the name was never claimed.

Make your own button