Payment processors

OpenReceive + Stripe

Keep Stripe for cards and add Bitcoin and stablecoins next to it, with card plans and prepaid crypto passes on one design.

Tested in production since September 2026

A subscription software business sells card plans through Stripe and prepaid crypto passes through OpenReceive on this design, side by side. The agent directions below build the same design into your app.

Get agent directions

Add to my Stripe app

This app already takes card payments through Stripe.

Start a new app with both

No payments yet. Build card and crypto checkout together.

On WordPress with WooCommerce? Install the OpenReceive plugin and it appears next to the Stripe gateway at checkout. Automatic subscription renewals stay card-only. OpenReceive for WooCommerce.

Java, Go or .NET? Not supported yet, so get in touch. Selling through Payment Links or a site builder with no server of its own? Start from a platform instead. See platforms.

Keep Stripe for cards. Add Bitcoin over Lightning, plus USDT, USDC, ETH and SOL through a swap provider that converts them to Bitcoin, paid straight into a wallet you control. This page is the design we run in production next to Stripe, and agent directions that build it into your app.

Tested in production

This is not a sketch. Since September 2026 this design has run a subscription software business, with Stripe and OpenReceive side by side on one pricing page:

Everything on this page comes from running it, including the mistakes we fixed. The agent directions below build the same design into your app.

What changes, and what doesn’t

Stripe stays as it is. Checkout, subscriptions, the customer portal, webhooks, receipts and tax settings keep working exactly as they do today. Your customers who pay by card see no difference.

OpenReceive adds a second way to pay. Next to “Pay with card” your pricing page gets “Pay with crypto”. The invoice comes from your own Lightning wallet through a receive-only connection code, so there is no account to open, no payout to wait for and no one holding your money. A configured swap provider turns stablecoin, ETH and SOL payments into Bitcoin on the way in.

Both end in the same place. A card payment and a crypto payment run the same piece of your code: the one that grants what was bought. Everything after that (access, credits, features) doesn’t care how the customer paid.

Why a crypto subscription works differently

A card subscription works because Stripe keeps the card on file and charges it every month. Nobody can pull money out of a crypto wallet. Each payment is one the customer sends, so there is nothing to bill next month.

So the two payment methods sell time differently:

  Card (Stripe) Crypto (OpenReceive)
Plans Monthly or yearly, renews automatically A prepaid pass of 60, 180 or 365 days, never renews
Paid Every period Once, up front
Credits Each month The whole pass’s worth, at purchase
Credit packs Same price Same price
Chargebacks Possible None

Pricing a crypto pass

Start from the card price. A pass costs the monthly price times the months it covers, less a discount for paying up front: about 10% for 60 days, 20% for 180 days and 26% for 365 days. Count 365 days as 365/30 months, and round to whole dollars.

Plan Card, per month 60-day pass 180-day pass 365-day pass
Basic $19 $34 $91 $171
Plus $39 $70 $187 $351
Business $99 $178 $475 $891

The discount is fair, not a giveaway. You get the money up front, with no card fees, no failed renewals and no chargebacks.

Credit packs

If you sell usage, credit packs cost the same in dollars by card or by crypto, and they never expire. When a customer has both, spend the plan’s or pass’s credits first, since those expire, and pack credits last.

When a customer has both

These rules come straight from production, where getting them wrong cost us a customer’s paid time.

The design

This is what the agent directions build. It fits any framework OpenReceive supports.

Stripe webhook ─────────┐
                        ├──▶ settle(order) ──▶ grant plan time, credits or the product
OpenReceive on_paid ────┘
  1. One order table for both. Every purchase is an order row. It records which payment method it used, what kind of purchase it is (a card plan period, a crypto pass, a credit pack or a product), and the price in dollars. Revenue reports read dollars for both, never satoshis.
  2. One settle function. The Stripe webhook and OpenReceive’s on_paid hook both call it. It locks the order, does nothing if the order is already paid, and grants what the order bought. Every grant has a unique key, so a replayed event can never grant twice.
  3. Separate access records. A card plan’s access lives on its Stripe subscription record, which only the Stripe sync updates. A crypto pass lives on its own record, with a paid-until date. One helper reads both and decides what the customer can do.
  4. The crypto order comes first. When the customer clicks “Pay with crypto”, the app creates the order with its dollar price and an opaque, never-reused reference. OpenReceive’s amount_for returns that saved price, and authorize checks that the order belongs to the signed-in customer. OpenReceive converts dollars to Bitcoin at checkout and refuses when the exchange rate is stale.
  5. Stripe is store-then-process. Verify the signature, save the event, and answer 200. Then process it, re-reading the subscription from Stripe, because events arrive out of order. Nothing is granted on the success redirect.
  6. Crypto needs no webhook. The checkout polls, every OpenReceive request checks for payments first, and an optional worker makes it instant when no browser is open. on_paid runs inside OpenReceive’s database transaction, so emails and live updates go out after it commits.
  7. The checkout link is the refund link. If a stablecoin deposit arrives short or late, the swap provider refunds it, and the customer claims it on the same checkout page. Keep that page reachable from the order.

Get the agent directions

Pick your situation and your framework at the top of this page, and copy the directions into Claude Code, Codex, Cursor or another coding agent. There are two sets:

Either way, the agent first asks for two codes from your wallet and swap provider, one at a time. Then it asks one question about your crypto prices, where the defaults above are a fine answer.

A coding agent reading this page can fetch the directions itself: https://openreceive.org/agent-directions/stripe/add/<stack>/full.md to add to an app that already uses Stripe, or …/stripe/new/<stack>/full.md for a new app. <stack> is node (Express), fastify, next, rails, django, fastapi, laravel or php.

What the agent won’t touch

Questions

Can I refund a crypto payment? Not automatically. The connection code can receive but never send, which is what keeps your wallet safe. Refund from your wallet by hand if you need to. Stablecoin deposits that arrive short or late are refunded to the payer by the swap provider. The customer claims the refund on the checkout page.

Receipts? Stripe emails card receipts. For crypto orders, show the order on the customer’s account page or send your own email after on_paid commits.

Where does the money go? To the Lightning wallet you connected. Stablecoin, ETH and SOL payments arrive there as Bitcoin, converted by the swap provider. Which coins and networks are available depends on the provider.

Which frameworks? Express, Fastify, Next.js, Rails, Django, FastAPI, Laravel and plain PHP. On WordPress with WooCommerce, install the OpenReceive plugin, and it appears next to the Stripe gateway at checkout. Java, Go and .NET servers aren’t supported yet. If you sell through Stripe Payment Links or a site builder with no server of your own, start from a platform instead.