Developer docs
How selling works
What a buyer receives, how they pay, how subscriptions renew and how to test it all without paying.
Delivery types
Every product has a delivery type that decides what the buyer receives when an order is paid. Delivery runs automatically once the network confirms; nothing is revealed for pending, expired or cancelled orders.
Files
deliveryType: "file"
Signed download link.
Text and credentials
deliveryType: "text"
Revealed after payment.
License and serial keys
deliveryType: "keys"
One unique key or account per order.
Private links
deliveryType: "link"
URL unlocked on payment.
Discord roles
deliveryType: "discord"
Granted by the bot on payment.
Dynamic delivery
deliveryType: "dynamic"
Your webhook decides.
| Type | Configured with | Description |
|---|---|---|
| file | Configured with: upload | Buyer gets a signed download link, refreshed on every visit to the order page. |
| text | Configured with: text | The text, on the order page and in the receipt email. |
| keys | Configured with: pool | Exactly one unused key per unit; stock counts down with the pool. |
| link | Configured with: URL | The URL, on the order page and in the receipt email. |
| discord | Configured with: server + role | Role granted by the Hidden bot on payment and revoked when the term ends (Pro and Enterprise). |
| dynamic | Configured with: webhook URL | Whatever your endpoint returns; see Dynamic delivery. |
Buyer accounts and payments
Buyers never create a password. On any storefront they can sign in with their email and a 6-digit one-time code (valid 10 minutes), which unlocks an account page with their orders, reviews (editable for 24 hours), support tickets and a store balance. The session is a per-store cookie that lasts 30 days.
Crypto
- invoice
- paid on chain
- delivered
Store balance
- one click
- balance debited
- delivered
Manual
- buyer sends proof
- you verify
- delivered
| Flow | Type | Description |
|---|---|---|
| Crypto | Type: hosted invoice | Default. The buyer is sent to a hosted invoice where the network and processing fee is added; the order is delivered when the network confirms. Pending invoices expire after 2 hours. |
| Store balance | Type: prepaid | Buyers top up in crypto (fee taken at top-up) and pay later from the balance, which needs a signed-in session. Balance orders are delivered instantly and carry no further fee. |
| Manual | Type: off-platform | Methods you set up yourself, paid outside Hidden (bank transfer, gift cards and others). The buyer submits proof and the order waits in "awaiting verification" until you mark it paid or reject it (7-day window). No platform fee is taken. |
| Display currency | Type: informational | Storefronts can show prices in the buyer's local currency (browser locale) with a switcher; every charge is still made in USD and the order records the currency the buyer saw. |
Orders exposed through the API carry kind (product or topup), payment.method (crypto, balance, manual or free) and, for manual rails, the claim and verification timestamps, so integrations can tell a settled crypto order from one still awaiting the seller.
Subscriptions and cart recovery
Any variation can be billed per period (weekly, monthly, every 3 months or yearly) with an optional free trial. Crypto cannot be charged again by itself, so a renewal is a fresh order for the same variation, created before the period ends and paid with one click from the renewal email, from the order page, or automatically from the buyer's store balance when they turn that on. Available on every plan.
| Step | Type | Description |
|---|---|---|
| Reminder | Type: 3 days before, by default | The renewal order is created and the buyer is emailed; subscription.expiring carries renewalOrderId and renewalUrl. The number of days is a store setting. |
| Renewal | Type: any payment method | Paying the renewal order moves the period forward from the old end (nothing is lost) and sends subscription.renewed. The variation decides whether delivery runs again (a new key, a fresh link) or only extends access. |
| Grace | Type: 1 day after the end, by default (up to 3) | Access stays while the buyer can still renew; one "days left" email goes out at the period end. |
| Expiry | Type: subscription.expired | After the grace period the subscription ends: Discord roles granted by it are removed and the event lists every license key it delivered (keys) so you can disable them in your own systems. |
| Cancel | Type: buyer or seller | Cancelling keeps access until the period end (subscription.cancelled); the seller can also end a subscription at once or extend it by one period from the dashboard. |
Abandoned cart recovery: a checkout that carries an email and is not paid gets up to two reminder emails (1 hour and 24 hours after it started, by default) with a link back to a fresh checkout for the same cart and, if you set a percentage, a single-use coupon. One address is never emailed about the same cart twice, nor more than once every 6 hours; a store sends at most 100 reminders an hour; every email has a one-click unsubscribe link; a payment stops everything. The Abandoned carts page shows what was recovered.
Moving from another platform
Moving from another platform? Bring everything in one click. In your dashboard, open Settings, then Import and export, pick the platform you are leaving (SellAuth, Sell.app, Komerza, SellHub or Shoppy) and paste its Store ID and API key. Products, serial keys, categories, coupons, customers, order history, reviews and policies come over in one run; re-running it never duplicates a record. The key is used only while the migration runs, is never stored and never appears in logs. Anything a platform's API does not share can be uploaded from the CSV tab.
Past orders arrive as read-only history: nothing is delivered again, nothing is credited and no fee is charged. Stores that move can claim 3 months of Pro free from Billing; see the switch offer.
Testing
$0 product
Test checkout, the order page and delivery without paying.
Send test event
Press it on a webhook endpoint to receive a signed
webhook.testdelivery.Test order
Create one from the dashboard: it sends the same events with
"test": true, and nothing is paid.
To test webhooks with a real payment, use a low-priced product and pay a small crypto amount. There is no platform fee; the buyer pays only the network fee. Any order can be redelivered from its order page, which sends its events again with the same delivery id.
Get help
Send us the endpoint, the request or delivery id and the response you got. Security findings go through responsible disclosure. Live platform status is on the support page.
See also