How to Sell Digital Goods for Crypto
A practical guide to selling license keys, downloads, courses and other digital products for crypto, with automatic delivery and fewer support tickets.

To sell digital products for crypto, you need three things: a place to take the order (a website, a Telegram bot or a simple invoice link), a crypto payment gateway that creates an invoice and confirms the payment, and automatic delivery that sends the key, file or access the moment the payment is confirmed. Price in USD, let customers pay in USDT or another coin, and deliver only on a verified webhook.
Digital goods and crypto fit well together. Delivery is instant and global, the customer often already holds crypto, and there are no chargebacks months after a license key has been used. The hard part is not taking the payment. It is delivering reliably and handling customers who pay too little, too late or on the wrong network.
This guide walks through the setup for license keys, downloads, courses, accounts, game items and other digital products.
Which digital products you can sell for crypto
Typical digital goods sold for crypto:
software licenses and activation keys
downloadable files: templates, presets, e-books, audio, fonts
online courses and membership access
game items, in-game currency and top-ups
gift cards and vouchers
API credits and SaaS plans (see renewals below)
Before you start, check two things. First, you need the right to sell what you sell: resold keys and accounts often break the publisher's terms. Second, check the tax rules in your country and your customers' countries. Digital goods are often subject to VAT or sales tax wherever the buyer is, regardless of the payment method. This is general information, not tax advice.
Step 1: choose where customers place the order
| Channel | Best for | How payment works |
|---|---|---|
| Website on a CMS (WooCommerce and others) | A catalog with many products | A plugin adds crypto as a payment method at checkout |
| Custom website or app | Your own checkout and delivery logic | Your backend creates invoices through the API |
| Telegram bot | Audiences that live in Telegram | The bot creates an invoice and sends the payment link |
| Invoice link | A few products, or sales over chat and social media | You create an invoice and send the link |
If you already run WooCommerce, the quickest route is a plugin; our WooCommerce crypto payments guide covers setup. For a bot, see how to accept crypto payments in a Telegram bot. For a custom site, the general flow is in how to accept USDT payments on your website.
Step 2: price in USD and choose coins
Price your products in USD, not in a coin. A $19 course stays $19, and the customer picks the coin and network on the hosted payment page.
For digital goods, a good starting set:
USDT on TRC20, BEP20, TON and Solana: stable value, cheap networks for small baskets
USDC for customers who prefer it
BTC and LTC for customers who hold them
ETH on Base or Arbitrum, where fees are lower than on Ethereum mainnet
Small baskets need cheap networks. If your average order is $5–15, the customer's network fee and exchange withdrawal fee can be a noticeable share of the price on expensive networks. Supported coins and networks are listed on the accept USDT page.
Step 3: deliver automatically on a verified webhook
This is the core of selling digital goods. The goal: the customer pays, and within a minute they have what they bought, without you touching anything.
The flow
The customer clicks "Buy". Your backend creates an order with status
pendingand creates an invoice with the gateway, passing your order ID.The customer pays on the hosted payment page, which shows a QR code, the amount and a countdown.
After the required network confirmations, the gateway sends a webhook
invoice.paidwithdata.statusofPAIDorOVERPAID.Your server verifies the signature, finds the order, marks it paid and delivers: it reserves a license key, generates a download link or grants course access.
The customer is redirected to your success page, which shows the result and says it was sent by email too.
Creating the invoice
Zypher invoices are created with POST /api/v1/invoice. The request is signed: X-API-Sign is the hex HMAC-SHA256 of the exact JSON body, using your API secret. In Python:
import hashlib, hmac, json, os, requests
API_KEY = os.environ["ZYPHER_API_KEY"]
API_SECRET = os.environ["ZYPHER_API_SECRET"]
body = json.dumps({
"fiatAmount": "19.00",
"fiatCurrency": "USD",
"orderId": "order-10452",
}, separators=(",", ":"))
sign = hmac.new(API_SECRET.encode(), body.encode(), hashlib.sha256).hexdigest()
resp = requests.post(
"https://zypher.exchange/api/v1/invoice",
data=body, # send exactly the bytes you signed
headers={"Content-Type": "application/json",
"X-API-Key": API_KEY, "X-API-Sign": sign},
)
invoice = resp.json()
# store invoice id next to your order, then redirect the customer to the payment pageSend exactly the string you signed. If you sign one JSON string and let your HTTP library re-serialize the object, the signature will not match. The response format and field reference are in the API docs.
Verifying the webhook and delivering
The webhook carries X-Webhook-Signature, the hex HMAC-SHA256 of the raw request body with your API secret. Verify it on the raw bytes before parsing:
import hashlib, hmac, json
def handle_webhook(raw_body: bytes, signature: str):
expected = hmac.new(API_SECRET.encode(), raw_body, hashlib.sha256).hexdigest()
if not hmac.compare_digest(expected, signature or ""):
return 401
payload = json.loads(raw_body)
if payload["event"] != "invoice.paid":
return 200
data = payload["data"]
if data["status"] in ("PAID", "OVERPAID"):
deliver_once(data) # idempotent: does nothing if this invoice was already delivered
return 200Make delivery idempotent
Failed webhook deliveries are retried, up to five attempts, so your handler may see the same invoice twice. Your deliver_once function should:
look up the order by invoice ID in a database transaction
exit if the order is already delivered
reserve the key (mark it as sold to that order) in the same transaction
send the email after the transaction commits
This also protects your key stock: two parallel webhook calls cannot hand out two keys for one order.
Delivery patterns by product type
License keys
Keep a pool of keys per product in your database with a status: available, reserved, sold. Reserve on payment, show the key on the success page and send it by email. Alert yourself when stock falls below a threshold, so you do not sell a key you do not have. If the pool is empty when payment arrives, mark the order as "paid, awaiting key" and email the customer a realistic time frame.
Downloads
Do not email a permanent public link. Generate a signed, expiring download URL (for example valid 24–72 hours, with a limited number of downloads) and let the customer re-generate it from their order page.
Courses and memberships
Grant access to the account rather than sending a file. If the customer has no account yet, create one from the email on the order and send a login link.
Game items and top-ups
Ask for the in-game ID before payment and validate it, because a top-up to the wrong player ID is hard to reverse. Show the ID again on the payment confirmation page.
Edge cases that cost money
Underpayment
Customers paying from an exchange often lose the withdrawal fee from the amount. On Zypher, 98% or more of the invoice amount counts as paid. Below that, the invoice is UNDERPAID, the customer can send the remainder to the same address, and partial payments add up. Do not deliver on UNDERPAID. Do tell the customer how much is missing.
Late payment
A coin-priced invoice expires after 30 minutes. A USD-priced one gives the customer 60 minutes to pick a coin and then 30 minutes to pay. A payment that arrives up to 30 minutes after expiry can still be matched. Beyond that, handle it manually: find the transaction, confirm the amount and deliver or refund.
Overpayment
Anything above 102% is marked OVERPAID. The webhook still arrives, so deliver the product. Then decide on a policy for the extra: refund it if it is large, or offer store credit.
Wrong network or wrong coin
These payments do not reach the invoice. Your support team should know what can and cannot be recovered; the details depend on the networks involved.
Refunds
Crypto payments have no chargebacks, but you will still need refunds for broken keys, duplicate purchases or goodwill. Write a refund policy for digital goods and show it at checkout. Then:
Ask the customer for a refund address and network in writing.
Refund in the coin they paid, or in USDT at the USD value. State which in your policy.
Refund from your balance with a normal withdrawal, which pays the network fee.
Revoke or blacklist the key or access you delivered.
Fees and margins
Digital goods often have thin per-unit costs but small tickets, so the processing fee matters. Zypher charges 1% per paid invoice on the Start tier, falling to 0.75% from $10k of 30-day volume and lower above that, with no setup or monthly fees. Other gateways charge from about 0.4% to 3%; we compared them in crypto payment gateway fees compared.
Launch checklist
Products priced in USD; coins and cheap networks enabled
Invoice created server-side with your order ID
Webhook signature verified on the raw body
Delivery only on PAID or OVERPAID, never on redirect
Delivery idempotent, key reservation in a transaction
Low-stock alert for key pools
Expiring download links
Refund policy visible at checkout
One real low-value purchase tested end to end
Zypher has a dedicated digital goods solution page with an overview of this setup. Opening a store takes about a minute and needs no documents: sign up.
FAQ
- Can I sell digital products for crypto without a website?
Yes. You can create an invoice for each order and send the payment link in a chat, by email or on social media. A Telegram bot is another option if your audience is there. Automatic delivery still needs a small backend that receives the payment webhook.
- How do I deliver license keys automatically after a crypto payment?
Keep keys in a database, and reserve one when a signed
invoice.paidwebhook arrives with status PAID or OVERPAID. Show the key on the success page and send it by email. Make the handler idempotent so a repeated webhook does not hand out a second key.- What happens if a customer underpays for a digital product?
On Zypher, a payment of at least 98% of the amount counts as paid. Below that, the invoice is marked underpaid, and the customer can send the remainder to the same address. Deliver only once the invoice is paid.
- Can customers get a chargeback on a crypto purchase?
No. A confirmed crypto payment cannot be reversed by the customer's bank. You still need a refund policy for broken keys or mistakes, and you send refunds as a normal withdrawal.
- Which crypto should I accept for digital goods?
USDT is a good default because its value is stable. Offer it on cheap networks such as TRC20, BEP20, TON or Solana, especially for small orders. Add BTC, LTC and USDC for customers who prefer them.
- Do I have to pay tax on digital goods sold for crypto?
Usually the same rules apply as for any other sale, and digital goods often carry VAT or sales tax based on the buyer's location. Rules differ by country. Check with a local accountant.