Dynamic URL Fulfillment for Digital Products
Most digital products can be delivered with a static file URL or a pre-generated batch of codes. But some products — per-customer license keys, signed download links, personalised PDFs, third-party SaaS tokens — need something generated at the moment of purchase. That's what the dynamicurl delivery type is for.
How digital fulfillment works on LaunchMyStore
Before diving into Dynamic URL, here's the full picture. A digital product on LaunchMyStore has one of four delivery types (set on the product detail page):
- FILE — you paste an external URL where the file is hosted (S3, R2, Drive, your CDN). After payment, the buyer receives that exact URL by email. LaunchMyStore does not host the file itself.
- CODES — you paste a list of license keys / activation codes / vouchers. After payment, one code is popped from the list per ordered quantity and sent to the buyer.
- DYNAMICURL — you paste a URL of your own endpoint. After payment, LaunchMyStore
POSTs to that endpoint and forwards whatever it returns to the buyer. - SERVICE — manual fulfillment. You handle delivery yourself (consultation booking, custom design, etc.).
This article covers DYNAMICURL.
When to use Dynamic URL
- SaaS or software with per-buyer license keys (you generate them on your billing/licensing service).
- Signed time-limited download URLs (e.g. an S3 presigned URL that expires in 24 hours).
- Per-buyer personalised content (PDF with the buyer's name pre-printed, custom watermark).
- Third-party platforms where you provision an account/seat via API.
Setting it up
Step 1: Configure your product
- In admin, open the product detail page.
- Set Type to Digital.
- Set Digital type to Dynamic URL.
- In the Product URL field, paste the URL of your own server (e.g.
https://api.your-domain.com/generate). - Save the product.
Step 2: Build your endpoint
Your endpoint will receive a POST with the product ID in the query string. A minimal Node.js / Express example:
app.post('/generate', (req, res) => {
const productId = req.query.id;
// your logic: look up productId, generate a key, etc.
const licenseKey = generateLicenseFor(productId);
res.json({
status: 200,
message: 'License generated successfully',
data: licenseKey,
});
});
Step 3: Return the right JSON shape
LaunchMyStore reads the data field of your JSON response and forwards it to the buyer. The string in data is what shows up on the order page as the fulfillment data, and gets included in the digital-delivery email.
{
"status": 200,
"message": "License generated successfully",
"data": "LICENSE-KEY-12345"
}
You can also return a URL string in data (e.g. a signed S3 link). The buyer email will render it as a clickable link.
Security recommendations
- Validate the incoming
productIdagainst your own catalog. Don't generate licenses for IDs you don't recognise. - Use HTTPS only.
- Whitelist the LaunchMyStore platform IPs on your endpoint if you want belt-and-braces protection.
- Rate-limit your endpoint to prevent abuse if the URL leaks.
- If you generate codes from a finite pool, monitor capacity and alert before exhaustion.
Finding your product ID
The product ID is shown in the product detail URL in admin (e.g. /products/edit/<your-product-uuid>). That UUID is what arrives in the ?id= query parameter on your endpoint.
What the customer gets
The string returned in your data field is rendered:
- On the order detail page they see when logged into their account.
- In the digital-delivery email sent right after payment.
- On the order webhook (so you can build downstream integrations).
Common use cases
- License key generation for SaaS or software.
- Dynamic file generation (e.g. personalised PDFs).
- Subscription token creation.
- Third-party integration with licensing or fulfilment platforms.
FAQ
Does LaunchMyStore host the file?
No. With Dynamic URL, your endpoint returns the data (a key, a link, a token). LaunchMyStore doesn't store the file — it relays your endpoint's response.
What if my endpoint times out or errors?
The order is still placed and payment is captured. If your endpoint fails to respond (or doesn't return a data field), the error is logged and that item's automatic digital delivery is skipped — no key or link is emailed for it. There is no automatic retry, so make sure your endpoint is reliable and responds quickly (aim for well under 10 seconds). If a delivery is missed, fix your endpoint and follow up with the buyer manually (for example, generate the value yourself and send it from the order page).
Can I use Dynamic URL for a product with variants?
Yes, you can sell a product with variants this way. Note that the POST to your endpoint includes only the product ID (?id=<productId>) — the specific variant is not sent — so your endpoint returns the same data regardless of which variant was purchased. If you need genuinely different data per variant (e.g. separate license tiers), set those up as separate products, each with its own Dynamic URL endpoint.
Can I send multiple values back (e.g. key + activation URL)?
The data field is a single string. You can put HTML or a JSON-encoded blob in there if you need multiple values. For richer delivery (PDF attachments, multiple files), use Dynamic URL to return a signed URL to your own download page that lists everything.
How do I test the endpoint without placing real orders?
POST to your endpoint manually with curl or Postman, passing a ?id= query parameter. You should get back the same JSON shape as a real order.
Is Dynamic URL the same as a webhook?
It's a synchronous request-response (LaunchMyStore waits for your reply before completing fulfilment), so it's stricter than a fire-and-forget webhook. If you also want fire-and-forget notifications, subscribe to the orders/paid webhook separately.