TL;DR: pwa.cash is a point of sale and pay link for Lightning, Monero, USDT and USDC. It installs from a link, with no app store, no card reader and no merchant account. There's no sign-up form either: a passkey instead of email and password, and alerts through ntfy instead of a phone number. Every payment goes straight to a wallet you control, and pwa.cash can watch the money arrive but can never move it. It costs 0.5% per paid sale, and a new shop gets $2 of credit to start.
What pwa.cash used to be#
pwa.cash started as a tool that turned websites into installable apps, no Apple or Google permission needed. The idea of "installs from a link, nobody can delist it" was right; the product around it wasn't, so I retired it and rebuilt pwa.cash from a clean repo around something merchants actually need.
Why the change of direction#
Two things kept coming up.
1. People who accept crypto keep running into gatekeepers. Payment apps get pulled from app stores. Custodial processors ask for company documents, hold your balance and can freeze it. The non-custodial route usually means running your own server. That's fine if you're technical, but it's a lot to ask of a coffee stand or someone selling on Telegram.
2. The hard parts already existed, just not in one place. The foundation is infrastructure shipped and tested in production over the past year: a swap aggregator, a USDT/USDC payment gateway, Monero light-wallet servers and Tron energy rails, each running as its own service. Every one of them solved a piece of "let a merchant get paid in crypto". None of them was something a café owner could open and use.
Put those together and the old idea fits: "installs from a link, nobody can delist it." It just belonged on a cash register, not on a website-to-app converter.
So pwa.cash v2 is that cash register. It's the front counter that ties the rest together.
How the pieces connect#
pwa.cash itself is fairly thin. Most of what happens behind a sale is done by services that were already in production, each running on its own:

- uPay.rip detects USDT and USDC payments on Tron and Ethereum. It started as a standalone gateway for merchants, and its "platform mode" lets pwa.cash create payments on it for each shop. Each payment goes to the shop's own address, the exact amount identifies it, and uPay sends pwa.cash a signed notice when it lands.
- The Monero stack. A Monero node with a light-wallet server (monero-lws) beside it, already serving other kyc.rip products. A shop's view key is registered there and every sale gets a fresh subaddress. The scanner notifies pwa.cash the moment a payment to that subaddress is broadcast, and pwa.cash keeps checking on its own as a backup. Monero top-ups for pwa.cash's own fee balance go through the same pipe.
- kyc.rip, the swap aggregator, does two jobs. It provides the exchange rates that lock each price. It also powers "pay with another coin": the customer picks what they hold, kyc.rip finds a swap whose output goes straight to that sale's Monero subaddress, and the normal Monero watcher sees it arrive like any other payment. pwa.cash never touches the swap money.
- jiayou.rip, the Tron energy service, is built into checkout. A customer paying USDT on Tron can rent energy for a fraction of the TRX they'd otherwise burn on fees.
- Lightning has no service of ours in the middle. pwa.cash talks directly to the merchant's own Lightning address or wallet (through NWC) and only ever asks it for an invoice.
- The old pwa.cash wasn't thrown away entirely. Its install logic for iPhone and Android, the per-app install manifests and the web-push code were rewritten into the new app. That's why each shop's pay link can be installed to a customer's home screen like its own app.
Each of these was handling real payments on its own before pwa.cash existed, and each is monitored: if the Monero scanner falls behind or a background job goes quiet, an alert fires. pwa.cash adds the counter, the shop page, the receipts and the security around wallet changes on top.
What it does#
Open pwa.cash on any phone, tablet or laptop and you get three things.
A register for the counter. Type an amount on the keypad, or tap item tiles from your catalog. The customer gets a full-screen QR code. When the payment lands you get a "Paid ✓" and a receipt.

A pay link for online sales. Your shop gets its own page, pwa.cash/s/xbtoshi:
- Customers pick items or type an amount and pay from their own phone.
- Add a logo, a banner, photos, your brand colour and a note with your address, a thank-you or your refund policy.
- Customers can install it to their home screen like an app.
- Print it as a QR poster for the wall, or drop the link in your Instagram bio or a Telegram channel.

A checkout that takes several coins. One payment request can be paid in any of:
- ⚡ Lightning, through your Lightning address or a receive-only NWC connection
- ɱ Monero, with a fresh subaddress for every sale, watched with your view key
- 💵 USDT on Tron or Ethereum, and USDC on Ethereum, paid to your own address
- 🔁 Almost any other coin, through a kyc.rip swap. The customer pays in what they hold, and your shop receives the full amount in Monero. Swaps start at $10.

You set prices in your own currency (EUR, USD and others). The exchange rate is locked when each payment request is created.
Swaps use fixed-rate orders only, from exchanges that guarantee the exact Monero amount out. The customer sees the full cost, exchange fees included, before sending, and gives a refund address in their own coin. If an exchange can't complete the order, the refund goes back to the customer under that exchange's rules, and the shop's payment request simply stays unpaid.
"Why not Monero-only?"#
Anyone who follows me knows I'm a Monero maxi, and I am. Monero is the only one of these coins that is private by default, and it's the rail I care about most. So some people would expect pwa.cash to accept XMR and nothing else.
I didn't build it that way, on purpose. Being a maxi is about what I believe. Building a tool for merchants is about what helps them.
A merchant's job is to get paid. The customer at the counter holds what they hold:
- USDT, in much of the world
- sats on a Lightning wallet
- something else entirely
A register that turns those people away doesn't win anyone over to Monero. It just loses the sale, and the merchant goes back to a processor that takes everything and asks for their passport.
What I wanted instead:
- Monero is a first-class option, not a checkbox. It's listed first at checkout. Every sale gets its own subaddress, watched through your view key. Small sales can count as paid the moment they're broadcast, and bigger ones wait for more confirmations.
- Every other coin can flow into Monero. "Pay with another coin" swaps the customer's coin, whatever it is, into XMR for the shop.
- The merchant decides. You choose which wallets to add, and you can put another method first if your customers mostly pay with it. If you want a Monero-only shop, add only a Monero wallet and that's exactly what you get.
- Every shop that takes USDT today also has a Monero button next to it. That's one more place where XMR is accepted, shown to customers who might never have tried it otherwise.
Monero adoption doesn't grow by refusing everything else. It grows by being there, working well, every time someone pays.
Non-custodial, meaning what it says#
This is the core of the product, so here is exactly what pwa.cash holds:

No spend keys, no seed phrases, and sales never pass through pwa.cash's addresses. If pwa.cash went offline tomorrow, your money would still be in your wallets, because it was never anywhere else.

The only balance pwa.cash holds is your prepaid fee credit, and it's labelled as exactly that.
No account to make, nothing about you to leak#
Most merchant tools start with a form: name, email, phone, company, maybe a passport scan. pwa.cash starts with nothing.

- No account in the usual sense. You sign in with a passkey, the same Face ID / fingerprint / device PIN you already use to unlock your phone. There's no email, no password and no phone number. pwa.cash never learns who you are, so there's no personal data to store, sell or lose in a breach.
- Recovery without an email. When you sign up you get one-time recovery codes. If you lose the phone, a code gets you back in, with no "forgot password" email involved.
- No CAPTCHA. Sign-up and public pay links are protected by a small proof-of-work your browser solves in the background. Nobody has to click traffic lights, and no Google or Cloudflare CAPTCHA script tracks your visitors.
- Notifications without giving out a contact. Alerts go through ntfy, a free, open-source push app for Android, iOS and desktop. You subscribe to a random private topic, and that's it: no phone number, no email, no Telegram handle. You can also use the installed app's own push notifications, which arrive even when it's closed.
You get the alerts that matter, delivered instantly:
- 💰 "Kafe Lumen: €12.50 received" on every paid sale
- 🔐 a new wallet added or changed, a new sign-in, a cashier paired
- ⏰ a payment that arrived late
- 🪫 a fee balance running low
An alert channel is required before your first sale, on purpose. If anyone ever tries to change your wallet, you hear about it immediately, outside the app.
Built so a stolen login can't redirect your sales#
If a POS doesn't hold your money, the worst attack on it is someone quietly swapping your wallet for theirs. pwa.cash is designed against that specifically:
- Passkey sign-in. There's no password, so there's nothing to phish, guess or reuse from another site's leak.
- A 24-hour wait on wallet changes. While you're setting up, wallets work at once, and before your first charge the register lists your wallets and asks you to confirm. After that, a new or changed wallet waits 24 hours before it can receive anything. You're alerted the moment the change happens, and you can cancel it. Removing a wallet is always instant; only adding one waits.
- Alerts outside the app (see above), so a change can't happen quietly.
- Cashier devices. Staff phones pair with a one-time QR code. They can take payments and see sales, but they can't touch wallets or settings, and you can sign any device out remotely.
The little things that matter at a real counter#
- Installs like an app on iOS, Android and desktop, and opens instantly. When there's a new version you get a "New version ready" notice instead of a surprise mid-sale.
- "Open in wallet" buttons for Lightning, Monero and the common Ethereum and Tron wallets, on the customer's own page and on the register, so nobody has to screenshot a QR code and scan it from their gallery. Customers can also pay from a browser wallet or through WalletConnect.
- Cheaper Tron USDT with a built-in energy saver, so the customer doesn't burn TRX on fees.
- Instant Monero for small sales. Turn it on in Wallets and choose a limit: 25 by default, 100 at most. Monero sales up to that limit count as paid the moment the payment is broadcast, usually within seconds, before it's in a block. Before marking the sale paid, pwa.cash checks with its own Monero node that the transaction is in the mempool and that no double-spend has been seen. The sale carries an "Unconfirmed" tag until its block arrives and pwa.cash has checked that the money reached that sale's address. If it never does, you get one alert. It's a small, capped risk you choose to take for a faster line, so it's off until you switch it on.
- Confirmations sized to the sale. A coffee shouldn't wait for the same certainty as a laptop. Small payments clear fast, and bigger ones wait for more blocks before they count as paid:Sale sizeMoneroTron USDT/USDCEthereum USDT/USDCUp to your instant limit0 (if switched on)11Under $100111100 – 9991033$1,000 and up10312 (Numbers are confirmations needed.) The checkout switches to "Confirming" the moment the transaction appears, then shows a live "2 of 10 confirmations" count, so nobody stands at the counter wondering. One block is about 3 seconds on Tron, 12 seconds on Ethereum and 2 minutes on Monero. For a busy coffee line there are two instant options: instant Monero for small sales, and Lightning, which is final the moment it's paid.

- Late payments are still caught. A payment request is open for 15 minutes. A payment that arrives later is still detected for 72 hours and marked "paid late", so nothing is lost silently.
- A "Paid" alert on your phone for every sale, even with the app closed.
- Reports with a chart, best sellers and a breakdown by payment method and sales channel, plus CSV export for your accountant.
- Four languages: English, Spanish, Traditional Chinese and Russian.
- For developers: API keys to create invoices from your own site or bot, and signed webhooks when they're paid.
Who it's for#
- Cafés, market stalls, food trucks and pop-ups that want to take crypto without a card terminal or a processor contract.
- People selling on Instagram, Telegram, X or Discord who need a pay link, not a whole website.
- Freelancers and service providers who want to send a payment request that the client can pay in whatever they hold.
- Merchants where payment processors don't serve you, or don't serve you well.
- Privacy-minded businesses that want Monero handled properly, with a subaddress per sale and no personal details asked.
- Developers who want a non-custodial checkout behind their own product without running payment servers.
How it compares#

- Custodial processors (the BitPay model) hold your coins, ask for KYC and can freeze your account. pwa.cash never touches the funds.
- Self-hosted BTCPay Server is great and fully sovereign, and if you want to run your own node and server, use it. pwa.cash is for people who want the non-custodial part without the server part.
- App-store POS apps can disappear in a policy update. pwa.cash is a link.
Pricing#
- 0.5% per paid sale, minimum $0.01.
- The fee comes from a prepaid balance, never from your sales. Your customers' money stays 100% yours.
- A new shop starts with $2 of credit, enough for hundreds of small sales. If a sale isn't paid, its fee is refunded.
- Running low: you get an alert when the balance drops under $1. When it runs out, the register stops creating new payment requests until you top up, but anything already open still completes, and top-ups land in minutes.
- Top up with Lightning, USDT or Monero. Credit is capped at $500 and isn't withdrawable. It's service credit, not a wallet.
- Referrals: bring another shop and earn 20% of its fees as credit for 12 months. The new shop gets $3 after its first sale.
What it isn't (yet)#
To be straight about the limits:
- pwa.cash is a hosted service. It doesn't hold your money, but it does see your sales records (amounts and items) so it can show you reports.
- Swaps from other coins go through third-party exchanges via kyc.rip, and they currently settle in Monero only.
- There's no card payment and no fiat payout. Payouts are crypto, to your own wallet.
Try it#
- Go to https://pwa.cash/ and sign in with a passkey.
- Name your shop and add one wallet: a Lightning address is the fastest start.
- Charge yourself $1.
That's the whole onboarding.
If you run a shop, a stall or a Telegram store and want to try it, my DMs are open. I read every bug report and feature request, and most of what shipped in the last two weeks came from exactly that.
Built by the same dev behind kyc.rip. Your keys, your sales, your shop. 🧾
if you'd like to support me, goto my shop: https://pwa.cash/s/xbtoshi


Comments
No comments yet. Start the conversation.