Coinvex documentation
Coinvex — the self-hosted crypto checkout for serious merchants. Version 2.0.
Coinvex is a PHP/Laravel application you install on your own hosting (cPanel works) to accept cryptocurrency payments with a hosted checkout, invoices, payment links, a REST API, signed webhooks, e-commerce plugins, Lightning, chat bots and a merchant PWA.
| Guide | What it covers |
|---|---|
| Installation | Server requirements, the 9-step browser installer, cron |
| Configuration | Admin settings, .env keys, SMTP, explorer API keys, branding |
| Coins & networks | Supported chains/tokens, address pools, xpub wallets, confirmations |
| Lightning | LNbits / LND setup for instant BTC payments |
| Bots | Telegram and Discord payment bots |
| PWA | Installable merchant app, live sales feed, push alerts |
| API reference | Authentication, endpoints, webhooks, idempotency |
| Plugins | WooCommerce, EDD, PrestaShop, OpenCart, Magento 2, WHMCS, Blesta, ClientExec, PHP SDK |
| Updating & licence | One-click updates, manual updates, backups, licence grace period |
| FAQ | Common questions |
| Troubleshooting | Fixes for the usual hosting problems |
| Compliance | Your responsibilities as an operator |
Compliance notice. Coinvex is self-hosted software, not a payment processor, custodian or money transmitter. You operate it on your own server with your own wallets. You are solely responsible for any licences, registrations, KYC/AML, sanctions screening and tax obligations in your jurisdiction. See compliance.md.
Support: through your Aucip account (Purchases → Coinvex → Support).
Installation
Coinvex installs from your browser. No SSH, Composer or Node is needed: the release zip ships with production vendor/ and compiled assets.
Requirements
| Minimum | Recommended | |
|---|---|---|
| PHP | 8.2 | 8.3 |
| Database | MySQL 5.7 / MariaDB 10.4 | MySQL 8 / MariaDB 10.11 |
| PHP extensions | bcmath, ctype, curl, dom, fileinfo, json, mbstring, openssl, pdo_mysql, tokenizer, xml, zip | + intl, gd, sodium, gmp |
| Cron | one line, every minute | |
| Disk | 250 MB | 1 GB (backups) |
storage/ and bootstrap/cache/ must be writable by PHP. The installer checks all of this and shows a fix for each item (for example, cPanel → Select PHP Version → tick intl).
5-step quick start (cPanel)
- Create a database. cPanel → MySQL Databases. Create a database and a user, add the user to the database with ALL PRIVILEGES, and note the full names (they include your cPanel prefix, e.g.
myuser_coinvex). - Upload the zip. cPanel → File Manager.
- Recommended: upload
coinvex-2.1.1.zipto your home folder, extract it into a new foldercoinvex, then set the domain's document root tocoinvex/public(cPanel → Domains). - Quick: extract straight into
public_html. The bundled rootindex.phpand.htaccessforward requests to/publicand block.env,storage,vendor,appand every other private folder./.well-knownstays reachable for AutoSSL.
- Recommended: upload
- Pick PHP 8.3. cPanel → MultiPHP Manager, then tick the extensions above in Select PHP Version.
- Run the wizard. Open your domain. You are redirected to
/install. - Add the cron job shown on the last screen (cPanel → Cron Jobs → Once Per Minute).
The installer, step by step
- Welcome. Read and accept the licence terms and the compliance notice.
- Server check. PHP version, extensions and folder permissions, each with a fix hint.
- Licence. Paste the licence key from your Aucip purchase. It is activated for the domain you are installing on (
POST https://aucip.com/api/license/activatewith the key,product=coinvex, the domain and the version). Local and test domains (localhost, IP addresses,*.test,*.local) can skip this step and activate later. - Database. Host, port, name, user and password, with a live connection test. Clear messages explain wrong passwords, missing grants and unknown databases.
- Site. Site name, URL (auto-detected), timezone, default fiat currency and platform fee (default 1%).
- Admin & 2FA. Your admin email and a strong password (strength meter), then scan the QR code with an authenticator app and confirm a code. Save the recovery codes shown.
- Email (optional). SMTP host, port, encryption and credentials, with a test send. You can skip this and configure it later.
- Install. Writes
.env, generatesAPP_KEY, runs migrations and essential seeders (networks, coins, settings), optionally loads demo data, links storage (or copies it whensymlink()is disabled), caches config, routes and views, and generates the Web Push (VAPID) keys. A live log shows each task. - Finished. Shows the exact cron command for your server, e.g.
with a copy button, plus links to the admin panel and the site./opt/cpanel/ea-php83/root/usr/bin/php /home/USER/coinvex/artisan schedule:run >> /dev/null 2>&1
The installer then locks itself with storage/installed.lock. You do not need to delete anything. It also refuses to run again, is CSRF-protected and rate-limited, and never echoes secrets back to the browser.
After installing
- Sign in at
/admin/login(password + 2FA). - Coins & networks: enable the chains you want and import receiving addresses or an xpub (coins-networks.md).
- Settings → Explorer API keys: add free keys (Etherscan, TronGrid…) for faster, more reliable detection.
- Create a merchant account at
/register, or let merchants sign up themselves.
Re-installing
Delete storage/installed.lock and .env in File Manager (the database is not touched), then open /install.
Configuration
Most settings live in Admin → Settings and are stored in the database. Secrets (SMTP password, API keys, bot tokens, the licence key) are encrypted with your APP_KEY. The installer writes .env for you; edit it only for the advanced keys below.
Admin → Settings
| Section | What you set |
|---|---|
| General | Site name, support email, platform fee % (default 1), store auto-approval, testnet mode |
| Mail (SMTP) | Host, port, encryption, username/password, from name/address, with a test send |
| Explorer API keys | Etherscan v2, Blockscout, Alchemy, TronGrid, Toncenter, Blockcypher, Blockchair, CoinGecko, Tatum |
| Risk | Screening providers (OFAC SDN list import, Chainalysis free sanctions API), hold rules |
| SEO | Title, description and Open Graph image for public pages |
Other areas: Integrations (Lightning, Telegram, Discord, Web Push), Coins & networks, Address pool, Plans & growth, Content (CMS, blog, legal pages, menus), Translations, Status page, Updates and Licence.
Branding
- The site name you enter in the installer (or under Settings → General) is used in page titles, emails and PDFs.
- Merchants can white-label their checkout (logo, colours, custom domain via CNAME and TXT verification) from Dashboard → Stores → Branding. The CNAME target is your own domain (the host of
APP_URL). - No product domain is hard-coded. All links are built from
APP_URL.
.env reference
| Key | Default | Purpose |
|---|---|---|
APP_NAME |
Coinvex |
Fallback display name |
APP_URL |
detected | Public URL. Every absolute link, the checkout and webhooks use it |
APP_TIMEZONE |
from installer | Scheduler and report timezone |
DB_* |
from installer | MySQL connection |
MAIL_* |
from installer | SMTP (admin settings override these) |
COINVEX_BRAND |
Coinvex |
Internal brand label |
COINVEX_DOMAIN |
host of APP_URL |
Reserved domain merchants cannot claim as a custom domain |
AUCIP_ENVIRONMENT (alias LICENCE_ENV) |
auto | Optional: production forces production (except tunnel hosts, which are always staging). staging is only honoured on hosts that match Aucip's staging patterns (see Updating & licence); anything else, including local, is ignored. |
AUCIP_GRACE_DAYS |
14 | Days Admin → Settings, Integrations and Updates stay unlocked after the last successful licence check (or from the one first-public-request grace). Clamped to 1–14: it can only shorten the grace period, never extend it. Payments never lock. |
COINVEX_UPDATE_CHANNEL |
stable |
Update channel |
COINGECKO_API_KEY, TATUM_API_KEY, ETHERSCAN_API_KEY, … |
empty | Same as the admin explorer keys (admin values win) |
Since 2.1.1 the Ed25519 key that signs licence and update responses is pinned in code and can't be changed or switched off from .env (AUCIP_PUBLIC_KEY is ignored), and licence/update traffic always goes to https://aucip.com/api.
Pre-2.0 CRYPTAIN_* variables are still read as fallbacks.
Cron
One line runs everything: payment detection, invoice expiry, rate refresh, webhook retries, xpub top-ups, Lightning checks, the queue, licence re-verification and the update check.
* * * * * /path/to/php /path/to/coinvex/artisan schedule:run >> /dev/null 2>&1
Admin → Updates shows when the cron last ran.
Coins & networks
Coinvex ships with 15 networks and 29 assets, all enabled in the seed data. The homepage counts always come from the database.
| Network | Code | Assets |
|---|---|---|
| Bitcoin | BTC | BTC |
| Ethereum | ETH | ETH, USDT, USDC |
| Tron (TRC20) | TRON | USDT, TRX |
| BNB Smart Chain | BSC | USDT, USDC, BNB |
| Polygon | POL | USDT, USDC, POL |
| Litecoin | LTC | LTC |
| Dogecoin | DOGE | DOGE |
| Solana | SOL | SOL, USDT, USDC |
| Bitcoin Cash | BCH | BCH |
| XRP Ledger | XRP | XRP (destination tag) |
| TON | TON | TON (memo) |
| Arbitrum One | ARB | ETH, USDC, USDT |
| Base | BASE | ETH, USDC |
| Optimism | OP | ETH, USDC |
| Avalanche C-Chain | AVAX | AVAX, USDC |
| Bitcoin Lightning | LN | BTC (disabled until a node is configured, see lightning.md) |
How payments are detected
Coinvex is non-custodial. Customers pay straight to addresses you control. Every minute the scheduler asks free public explorers/RPCs (mempool.space/Blockstream, Etherscan v2/Blockscout, Alchemy, TronGrid, Solana RPC, XRPL, Toncenter, Blockcypher, Blockchair) for transfers to open invoice addresses. A backup provider takes over automatically if the primary fails. Confirmations per network are configurable under Coins & networks → Edit.
Receiving addresses
Each invoice needs a deposit address:
- Address pool: Admin → Address pool → Import (one address per line). Addresses are rotated and recycled after expiry:
- anything ever received or seen at the address → full cooldown (Settings → Address cooldown, default 72 h), so late payments still find their invoice;
- expired, nothing ever seen → fast release (Settings → Expired, nothing seen, default 60 min, minimum 30). The address is only released after the chain poller has checked it again during the cooldown without an error and no payment is recorded; otherwise it waits the full cooldown;
- cancelled before payment → 6 h.
- When a pool runs dry, checkout hides that coin (or explains that no address is free), the API returns
409 address_pool_exhausted, and admins see a red dashboard alert plus an email (hourly at most). Add-ons can watchGET /api/v1/pool-status.
- xpub wallets: merchants can add an extended public key (BTC, LTC, DOGE, BCH, EVM). Coinvex derives fresh addresses and keeps the pool topped up. Private keys never touch the server.
- Memo networks (XRP, TON) use one shared address plus a unique memo or destination tag per invoice.
Adding or editing assets
Admin → Coins & networks lets you enable or disable networks and tokens, edit contracts, decimals, minimum payment, confirmations, explorer URLs, icon and sort order. Stablecoins can be marked for auto-convert/settle per merchant (conversions are executed by an admin and recorded in the ledger).
Risk screening
Incoming payments can be screened against the OFAC SDN digital-currency address list (coinvex:ofac import job) and the Chainalysis free sanctions API. Hits put the payment on hold for review under Admin → Payment review.
Lightning Network
Coinvex can accept BTC over Lightning through your own node. It supports two backends:
| Backend | What you need |
|---|---|
| LNbits | Your LNbits URL and an invoice/read API key for a wallet |
| LND REST | Your LND REST URL (https://host:8080) and an invoice macaroon in hex |
Setup
- Admin → Integrations → Lightning: choose the backend, enter the URL and key, and choose whether to verify TLS (turn this off only for self-signed LND certificates on a private network).
- Press Test connection.
- Enable the Bitcoin Lightning (LN) network under Coins & networks.
When a customer picks BTC · Lightning, Coinvex creates a BOLT11 invoice for the exact amount and shows it as a QR code with a copy button. Payment is detected by:
- a webhook from the node to
https://YOUR-DOMAIN/api/hooks/lightning/{secret}(the URL is shown on the Lightning settings page), and - the
coinvex:lightningcron job as a fallback.
Settled invoices are credited to the merchant's BTC ledger like on-chain payments.
Lightning is disabled until it is configured. The node and its liquidity are yours to operate.
Telegram & Discord bots
Merchants can create invoices and payment links from chat and get "paid" notifications.
Commands
/invoice 25 USD Coffee beans create an invoice and get its checkout link
/link 49 EUR Pro plan create a reusable payment link
/balance balances per coin
/recent last 5 invoices
/alerts on|off paid notifications in this chat
/disconnect unlink this chat
On Discord, the same commands run as /coinvex invoice … and so on.
Telegram
- Create a bot with @BotFather and copy its token.
- Admin → Integrations → Telegram: paste the token, save, then press Register webhook (or run
php artisan coinvex:telegram-webhook). Telegram will call/api/hooks/telegram/{secret}. No long-running process is needed, so it works on shared hosting. - Merchants connect a chat from Dashboard → Apps → Telegram with a one-time code (valid 15 minutes).
Discord
- Create an application at discord.com/developers, add a bot, and copy the application ID, public key and bot token.
- Admin → Integrations → Discord: paste them. Set the application's Interactions Endpoint URL to
https://YOUR-DOMAIN/api/hooks/discord. Requests are verified with Ed25519 using the public key. - Register the slash command with the Register commands button or
php artisan coinvex:discord-commands. - Merchants link a channel from Dashboard → Apps → Discord.
Team roles apply: a member whose role cannot create invoices can't use /invoice either.
Merchant PWA
The merchant dashboard is an installable Progressive Web App:
- Install: open the dashboard on a phone, then use Add to Home Screen (iOS Safari) or Install app (Chrome/Edge/Android).
- Offline shell: the app opens instantly and shows a friendly offline page when there is no connection.
- Live sales feed: Dashboard → Live streams payments as they happen.
- Push alerts: Dashboard → Apps → Enable push alerts gets a notification for every paid invoice on that device, even when the app is closed.
Admin setup
Web Push uses VAPID keys, which the installer generates for you. To regenerate them, run php artisan coinvex:vapid --force (existing subscriptions then need to re-subscribe). Push needs HTTPS.
Shortcuts in the manifest: Live sales, Point of sale, New invoice.
API reference
Base URL: https://YOUR-DOMAIN/api/v1 (your APP_URL). All bodies are JSON.
Authentication
Create an API key under Dashboard → Stores → API keys. Each key has a public key and a secret, an optional read-only scope and an optional IP allowlist. Every request sends:
| Header | Value |
|---|---|
X-Api-Key |
public key |
X-Timestamp |
current unix time (seconds, ±5 minutes) |
X-Signature-Version |
2 (recommended) |
X-Signature |
lowercase hex HMAC-SHA256 (see below) |
v2 signature: HMAC_SHA256(secret, timestamp + "\n" + METHOD + "\n" + request_uri_with_query + "\n" + raw_body)
v1 (legacy): HMAC_SHA256(secret, timestamp + raw_body). It is accepted unless the key is set to require v2.
TS=$(date +%s); BODY='{"amount":"25","currency":"USD","order_id":"A-1001"}'
SIG=$(printf '%s\n%s\n%s\n%s' "$TS" POST /api/v1/invoices "$BODY" | openssl dgst -sha256 -hmac "$SECRET" | cut -d' ' -f2)
curl -X POST https://YOUR-DOMAIN/api/v1/invoices -H "X-Api-Key: $KEY" -H "X-Timestamp: $TS" \
-H "X-Signature-Version: 2" -H "X-Signature: $SIG" -H "Content-Type: application/json" \
-H "Idempotency-Key: order-A-1001" -d "$BODY"
Rate limit: 120 requests per minute per key.
Endpoints
| Method | Path | Description |
|---|---|---|
| GET | /ping |
Check credentials. Returns store_id and server time |
| POST | /invoices |
Create an invoice |
| GET | /invoices |
List invoices (status, order_id, per_page; paginated) |
| GET | /invoices/{id} |
Get one invoice |
| POST | /invoices/{id}/cancel |
Cancel an unpaid invoice |
| GET | /currencies |
Enabled coins and networks |
| GET | /rates |
Current exchange rates |
| GET | /balance |
Merchant balances per coin |
| GET | /pool-status |
Deposit-address pool health per accepted network (read-only, since 2.1.1) |
Create invoice
{
"amount": "25.00", "currency": "USD", "order_id": "A-1001", "description": "Order #1001",
"token": "USDT_TRON", "customer_email": "buyer@example.com",
"success_url": "https://shop.example/thanks", "cancel_url": "https://shop.example/cart",
"callback_url": "https://shop.example/coinvex/webhook", "metadata": {"cart": 77}
}
token is optional. Without it, the customer picks a coin on the hosted checkout.
expires_in is optional (since 2.1.0). It sets how many minutes an unpaid invoice stays open before a coin is chosen: a whole number from 10 to 43200 (30 days). Use it for pay links sent ahead of a due date, such as subscription renewals. It defaults to the store's invoice lifetime. When the customer chooses a coin, the rate is still locked for the store's invoice lifetime (as before). If that window passes, the invoice expires and you can create a new one. Invalid values return 422 invalid_expires_in. The due moment is returned as expires_at. The response (201) contains data with: id, status, amount, currency, pay_currency, network, pay_amount, paid_amount, rate, address, memo, fee_payer, customer_fee_amount, fee_amount, merchant_amount, checkout_url, transactions[], expires_at and more.
Idempotency: send Idempotency-Key (≤100 chars). Replays return the first response with Idempotent-Replayed: true. Reusing a key with a different body returns 422 idempotency_mismatch.
Address pool exhausted (since 2.1.1): if token is given and no deposit address is free on that network, the API returns 409 address_pool_exhausted (before 2.1.1 this was 422 pool_empty). Nothing is created. Retry later or let the customer choose another coin on the hosted checkout (coins without free addresses are hidden there). Admins get a dashboard alert and an email (at most hourly per network).
Pool status
GET /api/v1/pool-status (read-only keys allowed) lets plugins and add-ons warn merchants before checkouts fail:
{"data": {"store_id": "…", "pool": "platform", "xpub_derivation_configured": false, "checked_at": "2026-10-12T09:00:00+05:30",
"networks": [
{"network": "BTC", "network_name": "Bitcoin", "type": "pool", "free": 12, "in_use": 3, "cooldown": 5, "shared_memo": false, "xpub_active": false, "exhausted": false, "low": false},
{"network": "XRP", "network_name": "XRP Ledger", "type": "shared_memo", "free": 1, "in_use": 0, "cooldown": 0, "shared_memo": true, "xpub_active": false, "exhausted": false, "low": true},
{"network": "LN", "network_name": "Lightning", "type": "lightning", "free": null, "in_use": null, "cooldown": null, "shared_memo": false, "xpub_active": false, "exhausted": false, "low": false}
]}}
pool:platform(admin-imported addresses) ormerchant(store in own-wallet mode: the merchant's imported/xpub addresses).free/in_use/cooldown: addresses available now, assigned to open invoices, and resting before reuse. Memo networks share one address, sofreeis the number of usable shared addresses.xpub_active: an active merchant xpub wallet tops this pool up automatically (needs the derivation provider configured).exhausted:freeis 0 and nothing derives new addresses.low: below the admin's pool alert threshold.
Errors look like {"error": {"code": "invalid_signature", "message": "…"}}. Codes include missing_auth, timestamp_expired, invalid_api_key, ip_not_allowed, insufficient_scope, rate_limited, invalid_json and address_pool_exhausted (409).
Statuses
new (no coin chosen) → waiting → partially_paid → paid / paid_over / paid_late, or expired / cancelled. Risky payments can be held for admin review before they are credited.
Webhooks
Set the webhook URL and copy the signing secret under Dashboard → Stores → Webhooks. Coinvex POSTs JSON for each event:
invoice.paid, invoice.overpaid, invoice.partially_paid, invoice.expired, invoice.cancelled (plus test from the dashboard).
| Header | Value |
|---|---|
X-Coinvex-Event |
event name |
X-Coinvex-Timestamp |
unix time |
X-Coinvex-Signature |
hex HMAC_SHA256(webhook_secret, timestamp + "." + raw_body) |
X-Coinvex-Delivery |
delivery ID |
For backward compatibility the same values are also sent as X-Cryptain-* and X-Cryptomo-*. These legacy names are deprecated: read X-Coinvex-* (all bundled plugins and the PHP SDK do; the SDK still accepts X-Cryptomo-* as a fallback). They will be dropped in 3.0. Reply with any 2xx. Failed deliveries are retried with back-off (1 min, 5 min, 15 min, 1 h, 3 h, 6 h, 12 h, 24 h) and can be re-sent from the dashboard. Webhook URLs that resolve to private IPs are blocked.
$ok = hash_equals(hash_hmac('sha256', $_SERVER['HTTP_X_COINVEX_TIMESTAMP'].'.'.$raw, $secret), $_SERVER['HTTP_X_COINVEX_SIGNATURE']);
Plugins & PHP SDK
Merchants can download every plugin from Dashboard → Stores → (store) → Plugins (/downloads/plugins/…). Each plugin asks for the same four values, all found in Dashboard → Stores:
- Coinvex URL: your site, e.g.
https://pay.yourdomain.com - Public key and Secret key: an API key for the store
- Webhook secret: the store's signing secret
Set the store's webhook URL to the plugin's callback URL, which each plugin's settings screen shows. All plugins use v2 request signatures and verify X-Coinvex-Signature.
| Platform | Package | Install |
|---|---|---|
| WooCommerce (incl. Blocks checkout) | coinvex-woocommerce.zip |
Plugins → Add New → Upload → activate → WooCommerce → Settings → Payments → Coinvex |
| Easy Digital Downloads | coinvex-easy-digital-downloads.zip |
Plugins → Upload → Downloads → Settings → Payments |
| PrestaShop 1.7 / 8 | coinvex-prestashop.zip |
Modules → Upload a module |
| OpenCart 4 | coinvex-opencart4.ocmod.zip |
Extensions → Installer → Upload, then Extensions → Payments → Coinvex |
| Magento 2 | coinvex-magento2.zip |
Copy app/code/Coinvex/Payment, then bin/magento setup:upgrade |
| WHMCS | coinvex-whmcs.zip |
Upload modules/gateways/* → Setup → Payments → Payment Gateways |
| Blesta | coinvex-blesta.zip |
Upload components/gateways/nonmerchant/coinvex → Settings → Payment Gateways |
| ClientExec | coinvex-clientexec.zip |
Upload plugins/gateways/coinvex → Settings → Plugins → Payment Processors |
| PHP SDK | coinvex-php-sdk.zip |
require 'Coinvex.php'; |
PHP SDK
require 'Coinvex.php';
$cx = new Coinvex('https://pay.yourdomain.com', 'pk_live_…', 'sk_live_…');
$inv = $cx->createInvoice(['amount' => '25', 'currency' => 'USD', 'order_id' => 'A-1001'], 'order-A-1001');
header('Location: '.$inv['checkout_url']);
// webhook endpoint
$event = Coinvex::verifyWebhook(file_get_contents('php://input'), $_SERVER, 'whsec_…'); // null if the signature is bad
if ($event && Coinvex::isPaid($event['data'] ?? $event)) { /* fulfil the order */ }
Upgrading from the 1.x (Cryptain) plugins
In 2.0 the plugins were renamed: slugs, class names, text domains and option keys now use coinvex. Install the new plugin, re-enter the keys and deactivate the old one. Coinvex still sends the legacy X-Cryptain-* and X-Cryptomo-* webhook headers and accepts v1 signatures, so old plugins keep working until you switch.
Updating & licence
Your licence
Coinvex is licensed per domain through Aucip.com. The key is activated during installation, or later under Admin → Licence.
- The cron re-verifies the licence every 24 hours. Only the key,
product=coinvex, your domain, a random per-install ID (instance_id), the installed version and the environment (production/staging) are sent. - Admin → Licence shows the licence type, production activations used (x/y), staging (x/3) and local installs (free, counted separately), updates until and support until.
- If Aucip is busy (429), returns a server error or can't be reached, Coinvex keeps the licence as it is and retries with back-off (1 h, 2 h, 4 h … 24 h). These problems never invalidate a licence.
- If the licence server can't be reached, you get a 14-day grace period counted from the last successful (signed) check, and a banner in the admin shows how many days are left. A signed rejection (revoked, refunded, invalid key…) ends any grace immediately; not activated for this domain (e.g. after a host move) keeps the clock from the last successful check while Coinvex re-activates.
- Never-activated installs and missing licence data (rule G4): grace is never started locally. On a public host Coinvex asks aucip.com for the signed
first_seen_at(the first time aucip.com saw Coinvex on that domain) and counts the one 14-day grace from it — so a fresh install gets its 14 days from its first public use, even after any time spent on localhost, while a site that aucip.com has known for longer than 14 days gets none. If the local licence data is missing, deleted or unreadable, or the server can't be reached, or the answer isn't validly signed, the install stays locked until a signed answer arrives. Host changes (apex↔www, a new domain, a tunnel) never extend or restart grace. A deactivated install stays locked — even after re-entering the key — until aucip.com returns a signed valid answer. Local hosts are always free and staging hosts are exempt from the missing-data lock. - After the grace period, only Admin → Settings, Integrations and Updates lock. Checkout, invoices, the API, webhooks, payment detection, payouts and the merchant dashboard never stop.
- Moving domains: Admin → Licence → Deactivate on this domain, then activate on the new install.
- Local installs need no licence and make no licence calls. Local is decided by the hostname only:
localhost,::1(bare or[::1]),0.0.0.0,*.test,*.local,*.localhost,127.0.0.0/8,10.x,172.16–31.x,192.168.x(the same list Aucip uses). Public IPs and other domains are not local, and no.envsetting can make them local. - Served publicly with a local APP_URL? If an install whose APP_URL is local answers requests on a public host, Coinvex stores that host, logs a warning and the next cron run activates the licence for that public domain (as production, or staging if the host matches a staging pattern). Only
$request->getHost()is used (rawX-Forwarded-Hostis ignored unless you trust your proxy). If only local hosts are seen for 7 days (an old tunnel), it goes back to local. - Free local installs (localhost/.test) plus up to 3 staging installs on staging subdomains per licence; staging doesn't count against your production domain.
- Staging is decided by the host only. Aucip counts an install as staging only when the host matches its staging patterns:
staging.*,stage.*,dev.*,test.*,uat.*,preview.*,*-staging.*,*.staging.*, managed-host previews (*.wpengine.com,*.wpenginepowered.com,*.kinsta.cloud,*.cloudwaysapps.com,*.flywheelsites.com,*.pantheonsite.io,*.instawp.xyz) and tunnels (*.ngrok.io,*.ngrok-free.app,*.ngrok.app,*.expose.dev,*.loca.lt,*.trycloudflare.com,*.serveo.net). Coinvex sendsenvironment=stagingonly for those hosts; declaring staging on any other host counts as production. Tunnel staging seats expire after 7 days without a verify. A licence may have up to 3 staging installs on staging subdomains; a 4th is refused with “This licence already has 3 staging installs…” (409 staging_limit_reached). Deactivate an old staging install, or use a local host, which doesn't count.
Licence and update traffic always goes to https://aucip.com/api; the address can't be changed from .env or settings. Every licence and update response is verified with Aucip's Ed25519 key, pinned in code (it can't be changed or switched off from .env). Coinvex checks the exact signed_payload bytes and uses only the signed values (entitlements, download URL, SHA-256). It also rejects answers whose signed_at is more than 24 hours old. An unsigned, wrong-key, tampered or stale answer counts as a temporary failure: it never counts as a successful check, so the 14-day grace period keeps running (and admin settings lock when it ends), Coinvex retries with back-off, and it reports signature_invalid to Aucip.
Replay binding: every licence and update request (activate, verify, deactivate, report, update check and download) carries a fresh random nonce (32 hex chars), the domain and the product. Aucip echoes the normalised domain, product, key_hash (SHA-256 of the key, never the key; when a key was sent) and nonce inside the signed payload of every answer, errors included. Each of these must be present and equal to the request; if one is missing or doesn't match, Coinvex rejects the answer as replay_mismatch. It is handled like a bad signature: a temporary failure, never a successful check or a rejection of the licence, and it is reported to Aucip. If the check keeps failing, make sure the server clock is correct.
Updates entitlement: one-click updates need updates until to be today or later. When it has passed, Admin → Updates shows a Renew button instead of Install. Nothing else changes. See configuration.md.
One-click updates
Admin → Updates → Check for updates asks GET /api/updates/check?product=coinvex&version=…&channel=stable. If a newer release exists you'll see its version and changelog. Back up & install:
- requests a signed download URL that is valid for 10 minutes (
POST /api/updates/download), - downloads the zip and verifies its SHA-256,
- backs up the database (
.sql.gz) and current code (.zip) tostorage/app/backups, - enters maintenance mode, replaces the files (never
.envorstorage/), runs migrations and rebuilds caches, - comes back online and shows a log.
The cron also checks for updates daily, so the badge appears on its own.
Manual update (no licence server needed)
Download coinvex-x.y.z.zip from your Aucip account, then go to Admin → Updates → Upload a release zip. The same backup → maintenance → migrate steps run. If your host's upload limit is too small, upload the files with FTP or File Manager (keep .env and storage/) and press Back up & run migrations.
Backups & restore
Backups are listed on the Updates page and can be downloaded. To restore the database, import the .sql.gz in phpMyAdmin. To restore the code, extract the code zip over the install.
Upgrading from Cryptain 1.x
2.0 is a drop-in upgrade: upload the 2.0 zip in Admin → Updates. Old cryptain:* cron commands, CRYPTAIN_* env variables, config('cryptain.*') and the legacy webhook headers keep working. Activate your licence afterwards.
FAQ
Is Coinvex custodial? No. Customers pay straight to addresses or xpubs you (or your merchants) control. Coinvex watches the blockchains and keeps a double-entry ledger. It never holds private keys.
Do I need a node? No. Detection uses free public explorers and RPCs with automatic failover. Free API keys (Etherscan, TronGrid…) make it faster and more reliable. Lightning is the exception: it needs your own LNbits or LND.
Does it run on shared hosting? Yes. It needs PHP 8.2+, MySQL and one cron line. There are no daemons, websockets or Node.js. The bots use webhooks.
What does the fee setting do? It sets the platform fee your merchants pay you (default 1%). Merchants choose whether they absorb it or pass it to the customer. You can override fees per merchant or per plan.
Can merchants use their own brand and domain? Yes. Logo, colours and a custom checkout domain (CNAME and TXT verification) are available per store.
Which languages does the checkout support? English, Hindi, Spanish, Arabic (RTL), Turkish, Russian and Portuguese. You can edit any string in Admin → Translations.
What happens if my licence can't be verified? After a 14-day grace period, admin settings and updates lock. Payments never stop. See updating.md.
Regular or Extended licence?
Regular covers one end product (one production domain). Extended is required if end users are charged (for example a hosted gateway service, SaaS or paid merchant onboarding). Agencies buy one licence per client end product. Every licence includes free local installs plus up to 3 staging installs on staging subdomains. See LICENSE.md.
What support is included? 6 months of support via tickets, with a reply within 1–2 business days. Support is renewable on Aucip.
Will you install it for me? Installation is a paid add-on. The web installer is built so most buyers can do it themselves on cPanel without SSH (see installation.md).
Is Coinvex a licensed payment provider? No. It is software. You are the operator. Read compliance.md.
Troubleshooting
| Symptom | Fix |
|---|---|
| 500 error right after upload | Use PHP 8.2+ (cPanel → MultiPHP Manager). Make storage/ and bootstrap/cache/ writable (755 or 775). Check storage/logs/laravel.log. |
| Installer says an extension is missing | cPanel → Select PHP Version → Extensions → tick it → reload the installer. |
| "Access denied" in the database step | Use the full prefixed names (cpuser_db, cpuser_user), and in MySQL Databases add the user to the database with ALL PRIVILEGES. |
| Licence activation fails | Make sure the key belongs to Coinvex and isn't active on another domain (deactivate it there first). Outbound HTTPS to aucip.com must be allowed; ask your host if curl is blocked. |
| "Already active on the maximum number of domains" | Deactivate the licence on the old install (Admin → Licence), or buy another licence. |
| "…did not match this request (replay_mismatch)" | A proxy, cache or mirror returned an answer that belongs to another request. Coinvex ignores it and retries; grace keeps running. Disable caching for aucip.com. |
| "This licence already has 3 staging installs" | Each licence allows up to 3 staging installs on staging subdomains. Deactivate one (Admin → Licence on that copy), or run the copy on a local host (*.test, *.local, localhost) — local installs don't count and need no activation. |
| "Activation is paused while Aucip reviews this order" | Aucip is reviewing the order (the reason is shown). Wait for the review or contact Aucip support; payments keep working. |
| "Served on a public domain while APP_URL is local" | Set APP_URL to the real domain and activate the licence for it (or let the cron do it if a key is stored). |
API returns 409 address_pool_exhausted / checkout says no deposit address is available |
Import more addresses (Admin → Address pool) or connect an xpub wallet. GET /api/v1/pool-status shows free / in-use / cooldown counts per network. |
| "Update entitlement ended" | Renew updates on Aucip. Payments and settings are not affected. |
| "Licence could not be verified" banner | Admin → Licence → Re-check now. Payments keep working during the 14-day grace period. |
| Locked right after moving servers / restoring a database without licence settings | Expected (rule G4): missing licence data is never a fresh grace. Re-enter the key in Admin → Licence (always reachable) so aucip.com can confirm it with a signed answer. |
| Payments not detected | Check that the cron runs (Admin → Updates shows the last run). Add explorer API keys. Confirm the address pool isn't empty and the network is enabled. |
| "No deposit address is available" | Import more addresses or add an xpub (Admin → Address pool). |
| Emails not arriving | Admin → Settings → Mail → Send test. Use your host's SMTP with SSL/TLS and a from-address on your domain (SPF/DKIM). |
| Push alerts not showing | HTTPS is required. Re-enable push on the device. Regenerate keys with coinvex:vapid --force only if they are lost. |
| Telegram bot silent | Press Register webhook again after changing domain or SSL. |
| Update upload fails | Raise upload_max_filesize/post_max_size in MultiPHP INI Editor, or use one-click update / FTP upload + Run migrations. |
| Site shows the installer again | storage/installed.lock or .env was deleted. Restore .env from a backup or re-run the installer against the same database. |
Assets look unstyled when installed in public_html |
Make sure the root .htaccess was uploaded (hidden files must be shown in File Manager) and mod_rewrite is on. |
Still stuck? Open a ticket from your Aucip account with the PHP version, the last 50 lines of storage/logs/laravel.log (remove secrets) and the steps you took.
Compliance notice
Coinvex is self-hosted software. It is not a payment processor, payment institution, custodian, exchange or money transmitter, and neither the author nor Aucip.com operates any service on your behalf.
When you install Coinvex you become the operator of your installation. You alone are responsible for:
- determining whether accepting, processing, converting or settling crypto-asset payments for yourself or for third-party merchants requires a licence or registration where you or your merchants operate (for example MSB/VASP/CASP/EMI registrations);
- KYC/KYB and AML/CFT programmes, record keeping, transaction monitoring and suspicious-activity reporting;
- sanctions screening. The built-in OFAC list and Chainalysis integrations are aids, not guarantees;
- consumer protection, refunds, data protection (GDPR etc.) and the content of your terms and privacy policy;
- tax reporting for you and, where applicable, your merchants.
Coinvex includes tools that can help (KYC/KYB review, risk holds, blocklists, audit log, ledger exports), but configuring and using them correctly is your responsibility. Nothing in the software or its documentation is legal, tax or financial advice. If you are unsure, consult a qualified professional in your jurisdiction.