Why Use BTCPay Server with Zcash#
Online commerce increasingly accepts cryptocurrency. It is fast, global, and operates without banks. These traits benefit both merchants and customers.
The catch: most blockchains are public. During checkout, customers usually provide personal details such as name, shipping address, and phone number. If their payment goes over a transparent chain (Bitcoin, Ethereum, or stablecoins), the transaction becomes permanently visible and linkable.
As a result, anyone can:
- see when and how much was paid,
- trace where funds came from and where they go,
- and link an address to a person if any correlating data leaks.
This exposure also affects merchants: once an address appears on-chain, competitors and data brokers can estimate revenue, map counterparties, and infer business flows.
BTCPay Server + Zcash solves this. BTCPay is a free self-hosted payment processor. It does not custody funds. Payments go straight to the merchant’s wallet (single user or multisig).
BTCPay coordinates the flow:
- generates a unique address per order,
- monitors for payment and links it to the order,
- issues receipts/notifications,
- and provides the customer checkout UI.
Zcash uses zero-knowledge proofs to support private transactions. With shielded addresses, sender, recipient, and amounts are not revealed on-chain.
For stores, this means:
- buyers pay without exposing financial history,
- sellers receive funds without revealing sales volume,
- and outsiders cannot link the payment to the order.
Practical Example
With Bitcoin or USDT, the site shows a payment address. Once paid, that address becomes public forever and may be tied to a customer.
With Zcash, BTCPay provides a shielded address. The buyer pays, the server detects it, and the order completes—without public metadata to analyze.
How BTCPay Server Works#
- Customer places an order on your site.
- Your store requests an invoice from BTCPay (amount, timer, Zcash address).
- Customer pays the provided ZEC address.
- BTCPay monitors the chain and validates the payment.
- Once confirmed, BTCPay notifies your store.
- Customer sees confirmation (optionally receives a receipt).
This is fully automated. BTCPay never holds private keys or funds.
Where Are Funds Stored? Who Controls the Private Keys?#
BTCPay Server is not a wallet and does not require private keys. Funds go directly to your wallet, while BTCPay operates with a viewing key.
How It Works
- Create your wallet in advance. Recommended: YWallet or Zingo! Wallet. See ZecHub Wallets.
- Provide BTCPay a read-only viewing key. It derives new receiving addresses and detects incoming funds but cannot spend.
- BTCPay queries a
lightwalletd
endpoint (public likehttps://zec.rocks
or your own Zebra + lightwalletd). - Each invoice gets a unique address (no reuse; easy tracking).
- Compromise of the server cannot move funds.
How to Set Up BTCPay Server for Accepting Zcash#
You can deploy from scratch, add ZEC to an existing instance, use a public lightwalletd
, or run your own full node. We’ll cover all paths below.
Deploying BTCPay Server with Zcash Support#
Already running BTCPay? Just install the ZEC plugin. Docs: btcpayserver-zcash-plugin.
Recommended VPS Configuration
- Ubuntu 22.04+, domain → server IP via DNS
git
,docker
,docker compose
, SSH access
Preparing Your Server (click to expand)
1) VPS: 2 CPU / 4 GB RAM / 40 GB disk (more if full node).
2) DNS: Create an A record (e.g. btcpay.example.com
).
3) SSH: ssh root@YOUR_SERVER_IP
sudo apt update && sudo apt upgrade -y
sudo apt install git curl docker.io docker-compose-plugin -y
sudo systemctl enable docker
Step 1: Clone the Repository
Create a working directory and download the BTCPay Server Docker deployment:
mkdir BTCPayServer
cd BTCPayServer
git clone https://github.com/btcpayserver/btcpayserver-docker
cd btcpayserver-docker
Step 2: Export Environment Variables
Replace btcpay.example.com
with your actual domain:
export BTCPAY_HOST="btcpay.example.com"
export NBITCOIN_NETWORK="mainnet"
export BTCPAYGEN_CRYPTO1="btc"
export BTCPAYGEN_CRYPTO2="zec"
export BTCPAYGEN_REVERSEPROXY="nginx"
export BTCPAYGEN_LIGHTNING="none"
Step 3: Run the Installer
. ./btcpay-setup.sh -i
When finished, visit https://btcpay.example.com
.
Running Your Own Zcash Full Node (Zebra + Lightwalletd)#
Ensure you have ample disk (≥400 GB recommended for payments-only). Sync time can be lengthy on small VPSes.
export BTCPAYGEN_EXCLUDE_FRAGMENTS="zcash"
export BTCPAYGEN_ADDITIONAL_FRAGMENTS="zcash-fullnode"
. ./btcpay-setup.sh -i
Connecting to an External lightwalletd
Node (Custom Configuration)#
Use an external endpoint (default is https://zec.rocks:443
) or your own hosted service.
Step 1: Custom Docker Fragment
# docker-compose-generator/docker-fragments/zcash-lightwalletd.custom.yml
exclusive:
- zcash
Step 2: Environment
export BTCPAYGEN_EXCLUDE_FRAGMENTS="$BTCPAYGEN_EXCLUDE_FRAGMENTS;zcash"
export BTCPAYGEN_ADDITIONAL_FRAGMENTS="$BTCPAYGEN_ADDITIONAL_FRAGMENTS;zcash-lightwalletd.custom"
Step 3: .env
ZCASH_LIGHTWALLETD=https://lightwalletd.example:443
Step 4: Apply
. ./btcpay-setup.sh -i
Hosting BTCPay Server at Home with Cloudflare Tunnel#
- Install and authenticate:
cloudflared tunnel login
- Create tunnel:
cloudflared tunnel create btcpay
- Config file (
/etc/cloudflared/config.yml
):
tunnel: btcpay
credentials-file: /root/.cloudflared/btcpay.json
ingress:
- hostname: btcpay.example.com
service: http://127.0.0.1:80
- service: http_status:404
Add the CNAME in Cloudflare DNS and enable proxy (orange cloud).
sudo cloudflared service install
sudo systemctl enable --now cloudflared
Set BTCPAY_HOST
and rerun setup to finalize domain/SSL.
Configuring the Zcash Plugin in the BTCPay Server Web Interface#
- Log in to your instance.
- Plugins → Browse Plugins → install Zcash (ZEC) → restart.
- Zcash → Settings → paste your viewing key and current block height → Save.
Recommended wallets for viewing keys: YWallet and Zingo! Wallet. See ZecHub Wallets.
Test Your ZEC Payment Flow
- Invoices → Create New → small ZEC amount.
- Pay from a different wallet.
- Invoice should switch to Paid.
Integrating BTCPay Server with Your Website#
Pick the approach that fits your stack:
- API Integration — full control for custom sites.
- CMS Plugins — quickest path (e.g., WooCommerce).
- Payment Button/Iframe — simplest for static pages.
API Integration#
Generate an API key and use the Greenfield API for invoices, tracking, and webhooks.
Generating an API Key#
- User menu → API Keys → Create.
- Grant:
Can create invoice
,Can view invoice
. - Copy the token and store it securely.
Example: Creating an Invoice via API#
POST /api/v1/stores/{storeId}/invoices
Authorization: token {apiKey}
Content-Type: application/json
{
"amount": 5,
"currency": "ZEC",
"checkout": {
"speedPolicy": "HighSpeed",
"paymentMethods": ["Zcash"]
}
}
Setting Up a Webhook (Optional)#
- Store → Webhooks → add your endpoint.
- Receive POST callbacks on invoice state changes.
CMS Integration#
WordPress + WooCommerce has first-class support via the BTCPay plugin.
Payment Button or Iframe (No CMS or API Needed)#
Payment Button
<a href="https://btcpay.example.com/i/abc123" target="_blank">Pay with ZEC</a>
Embedded Invoice (Iframe)
<iframe src="https://btcpay.example.com/i/abc123" width="600" height="350" frameborder="0"></iframe>
Conclusion#
BTCPay gives you private ZEC payments without intermediaries. Host multiple stores, assign roles, customize checkout, and automate with webhooks—all under your control.
Resources#
- BTCPay Server Official Website
- BTCPay FAQ
- BTCPay Server GitHub Repository
- BTCPay Server Mainnet Demo
- Zcash Plugin for BTCPay (GitHub)
- Zcash Plugin Installation Guide
- Custom zcash-lightwalletd.custom.yml Example
- Lightwalletd Docker Compose File (Zebra)
- BTCPay API Key Docs (Greenfield API)
- Create a Cloudflare Tunnel
- Zcash Wallet Compatibility List (ZecHub)
- Zebra + Lightwalletd on Raspberry Pi 5 (ZecHub)