Crypto Payments for Digital Products, Software and Licenses
How to accept crypto payments for digital products. A guide for software, license key and e-book sellers to automate delivery with USDT and TRX on TRON.

Crypto payments for digital products are an increasingly attractive option for businesses that sell software licenses, e-books, templates, plugins or online courses. Digital goods can be delivered instantly, which fits nicely with fast TRC20 payments: the customer pays, the payment is final in about a minute, and the license key goes out automatically.
This guide covers why digital sellers accept crypto, how to build a fully automated delivery flow, and what to watch out for.
Why digital sellers accept crypto payments
Digital products have particular needs, and crypto answers many of them well:
- Global customers. Software and digital content sell worldwide. USDT (TRC20) lets customers in different countries pay the same way.
- Fast finality. On TRON, a payment is credited after 20 block confirmations, usually about a minute, which is ideal for instant delivery.
- Irreversible transfers. A blockchain payment can't be pulled back unilaterally by the customer, which is a different model from card chargebacks. You should still publish a clear refund policy.
- Low cost. MercanPay commission starts from 0.4%, and on USDT invoices the customer pays the 1 USDT network fee.
- Built for automation. The API and signed webhooks mean no human needs to sit between payment and delivery.
Who is it a good fit for?
| Product type | Typical flow | Fit |
|---|---|---|
| Software license | Payment → key generated → email | Excellent, fully automated |
| SaaS subscription | Invoice per period → account extended | Good, with a per-period invoice |
| E-book / template / theme | Payment → download link | Excellent |
| Online course | Payment → course access unlocked | Excellent |
| In-game digital items | Payment → credited to account | Good, for legitimate use |
For subscription-style services, we cover per-period billing in crypto payments for gaming, VPN and hosting.
Automated license delivery, end to end
The real strength of crypto payments for digital products is automation. A typical flow:
- The customer picks a product and chooses "Pay with crypto".
- Your server creates an invoice through the MercanPay API and redirects the customer to
payment_url. - The customer scans the QR code or copies the address and sends the payment. The page shows "payment detected · confirming" as soon as the transaction appears on-chain.
- After 20 block confirmations your server receives a signed
invoice.paidwebhook. - Your server verifies the signature, generates the license key and emails it.
- The customer's browser is sent to your
success_url, where the thank-you page shows the license.
Important: deliver the license from the verified webhook, not the browser redirect. A redirect URL can be faked. A signed webhook can't.
Creating the invoice (PHP)
<?php
require 'vendor/autoload.php'; // composer require mercanpay/mercanpay-php
$zp = new \MercanPay\MercanPay('https://mercanpay.com', getenv('MERCANPAY_API_KEY'));
$invoice = $zp->createUsdInvoice('29.00', [
'order_id' => 'lic-10482',
'description' => 'Pro License (1 year)',
'success_url' => 'https://myshop.com/order/lic-10482/thanks',
'metadata' => ['product' => 'pro-yearly', 'customer_id' => 731],
]);
header('Location: ' . $invoice['payment_url']);
The metadata field is never shown to the customer and comes back unchanged in the webhook, which makes it a handy place to carry the product or customer reference.
Delivering the license from the webhook (PHP)
<?php
use MercanPay\MercanPay;
$body = file_get_contents('php://input');
if (!MercanPay::verifyWebhook(getenv('MERCANPAY_WEBHOOK_SECRET'), $body, $_SERVER['HTTP_X_MERCANPAY_SIGNATURE'] ?? '')) {
http_response_code(401);
exit;
}
$event = json_decode($body, true);
if (in_array($event['type'], ['invoice.paid', 'invoice.overpaid'], true)) {
$inv = $event['data']['invoice'];
// The same event can arrive more than once: don't issue a second key for this order
deliverLicenseOnce($inv['order_id'], $inv['metadata']['product']);
}
http_response_code(200);
deliverLicenseOnce is your own application function. What matters is that it never issues a second key for the same order_id, because webhooks may be delivered more than once due to retries. For the details of signature checks, see how to verify a webhook signature, and for the full library, our PHP crypto payment integration guide.
Using WooCommerce or another platform?
MercanPay does not currently offer a ready-made WooCommerce or similar e-commerce plugin. Integration is done through the REST API or the official PHP and Python libraries. The PHP library is a solid foundation for building your own plugin or a payment module tailored to your existing system. In most cases the two files above are the bulk of the integration.
Things to watch out for
- Underpayments. If a customer sends too little, the invoice becomes "partial" and they get extra time to send the rest. Deliver only on
invoice.paidorinvoice.overpaid. You can optionally set an underpayment tolerance between 0 and 20%. More in underpayments, overpayments and late payments. - Pricing. Keeping catalogue prices in USD and letting the customer choose TRX or USDT is the most practical setup for most sellers. We explain the rate lock in crypto payment exchange rate risk.
- Minimum amount. The minimum invoice is 10 USD, so consider bundling cheaper items.
- Refund policy. On-chain payments can't be reversed. If you issue a refund, it's a separate transfer. State your policy clearly before purchase.
- API key hygiene. Keep the key on the server in an environment variable, and give the key that creates invoices only the
invoicesscope.
FAQ
How soon does the customer get their license?
After the payment appears on-chain it needs 20 block confirmations, which usually takes about a minute. Then the webhook fires and your automated delivery runs.
How do I avoid issuing two licenses for one order?
Webhooks can be delivered more than once because of retries. Store the event id or the order_id and skip anything already processed. Also, creating an invoice with an order_id that already exists returns the existing invoice instead of a new one.
Is there a ready-made WooCommerce plugin?
Not currently. Integration is via the API or the PHP library, and a plugin can be built on top of that library.
Which coins can I accept?
TRX and USDT (TRC20) on the TRON network. Other networks are not supported at the moment.
Get started with MercanPay
Sell your digital products for TRX and USDT and deliver licenses automatically from signed webhooks. Apply for a merchant account and read the documentation to create your first invoice.


