Documentation

A non-custodial gateway. You hold the keys; we derive deposit addresses, watch the chain, and notify your store.

1. Create an account

Sign up at /auth, create a store, and add at least one chain config.

2. Add an xpub or receive address

We support BIP32 extended public keys for UTXO chains (BTC, TXC, DOGE, ISK, ZCU) and a single receive address for account-based chains (ETH, Base, Tron, Solana). Your private keys never leave your wallet.

New to xpubs? Step-by-step wallet setup guide for every supported chain →

3. Get your API key

Each store has its own secret API key (sk_live_…). It's shown once — store it securely.

4. Create invoices

POST /api/public/v1/invoices
Authorization: Bearer sk_live_...
Content-Type: application/json

{
  "chain": "btc",
  "amount": 49.00,
  "currency": "USD",
  "order_id": "ORDER_1234",
  "redirect_url": "https://store.example.com/thanks"
}

Response includes the unique deposit address and the hosted payment page URL.

5. Receive webhooks

We POST to your configured webhook URL on every status change. Each request is signed:

X-TXCPay-Signature: t=1729000000,v1=hex-hmac-sha256

# verify in node:
const sig = req.headers["x-txcpay-signature"];
const [, t] = sig.match(/t=(\d+)/);
const [, v1] = sig.match(/v1=([a-f0-9]+)/);
const expected = crypto
  .createHmac("sha256", WEBHOOK_SECRET)
  .update(`${t}.${rawBody}`)
  .digest("hex");
if (!crypto.timingSafeEqual(Buffer.from(v1), Buffer.from(expected))) reject();

Drop-in JS button

One <script> tag and a button — crypto checkout opens in a modal, no redirect, works on any site.

<script src="https://pay.honest.money/sdk/payhme.js" defer></script>

<button
  data-payhme
  data-api-key="sk_live_..."
  data-chain="btc"
  data-amount="49.00"
  data-currency="USD"
  data-order-id="ORDER_1234"
>Pay $49 with Bitcoin</button>

Or call it programmatically:

PayHME.checkout({
  apiKey: "sk_live_...",
  chain: "base", amount: 49, currency: "USD",
  orderId: "ORDER_1234",
}).then(result => {
  // result.status: "paid" | "closed" | "expired"
  if (result.status === "paid") console.log("Got it:", result.tx);
});
Live demo

Click below — this is the actual SDK, opening a real (test-mode) checkout in a modal. No payment will be processed; close the modal at any time.

Tip: open your browser console to see the payhme:result event payload when the modal closes.

WooCommerce

See the WooCommerce integration guide to install our plugin in under five minutes.

Don't trust us? Good.

We get it. The whole point of crypto is don't trust, verify. A payment processor asking you to take its word for it is the exact thing we built Nectar.Pay to replace. We don't hold your keys — and you don't have to take our word for that either.

Read the source. Run it yourself. Or fork the whole thing and run a competing gateway — we honestly don't mind. The bees do better when the hive is bigger.

Prefer to self-host the GitHub source? Go for it — no license fee, no phone-home. The $999 remix is just the shortcut.