> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mycryptoserver.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Payment Providers

> Offer hosted payment options — crypto checkout (Binance Pay, Coinbase Commerce, NOWPayments, CoinGate) and card on-ramps (Transak, Ramp Network, MoonPay, Mercuryo, Banxa) — alongside on-chain checkout

Besides native on-chain payments, MyCryptoServer can offer **hosted payment providers** at checkout. The customer pays in an embedded widget or on the provider's hosted page, and the session is marked paid from a provider webhook — reusing the same session state machine and webhook events as on-chain payments.

Two kinds of provider are supported:

| Kind                | Providers                                             | Customer pays with               | You receive                                  |
| ------------------- | ----------------------------------------------------- | -------------------------------- | -------------------------------------------- |
| **Crypto checkout** | Binance Pay, Coinbase Commerce, NOWPayments, CoinGate | Existing crypto balance / wallet | Settled by the provider                      |
| **Card on-ramp**    | Transak, Ramp Network, MoonPay, Mercuryo, Banxa       | **Card**, Apple/Google Pay, bank | **Crypto on-chain, straight to your wallet** |

<Note>
  Card on-ramps deliver crypto **on-chain to a wallet address you specify** — typically your payout wallet — so funds land directly with you. The customer completes the provider's KYC the first time, which adds friction versus a plain card checkout.
</Note>

<Info>
  **Availability.** Only **MoonPay** and **Transak** are generally available (verified end-to-end). The other providers are in **Beta** — implemented and type-checked but not yet fully verified — and appear with a *Beta* badge in the dashboard. Test them in sandbox before enabling them in production.
</Info>

Each provider is a single definition in **Dashboard → Integrations**: drop in the credentials, toggle it on, and it appears as an option at checkout for USD-denominated payment links. No database changes.

## Enabling a provider

<Steps>
  <Step title="Add credentials in the dashboard">
    Go to **Dashboard → Integrations**, open the provider tile, paste its credentials, and enable it. Each provider's fields are listed below.

    Providers with separate test and production environments show a **Sandbox mode** toggle. Turn it on while testing with the provider's test API keys — the checkout then points the widget (and webhook re-queries) at the provider's sandbox host. Turn it off and enter live keys to go to production.
  </Step>

  <Step title="Point the provider's webhook at MyCryptoServer">
    Hosted providers confirm payment by webhook. Set the provider's webhook URL (in the provider's own dashboard, where applicable) to:

    ```
    https://your-instance.com/api/providers/{provider}/webhook
    ```

    where `{provider}` is `binance_pay`, `coinbase_commerce`, `transak`, `ramp_network`, `moonpay`, `mercuryo`, `banxa`, `nowpayments`, or `coingate`.

    Some providers (NOWPayments, CoinGate) take the callback URL per order, so MyCryptoServer sets it automatically and no dashboard step is needed.
  </Step>

  <Step title="Offer it at checkout">
    Once enabled, the provider shows up as a payment option on the hosted checkout for USD payment links. Selecting it mints a session and either embeds the provider's widget inline (embeddable on-ramps) or redirects the customer to the provider.

    The order these methods appear in — including the native on-chain "Crypto" option — is configurable under **Settings → Checkout**; the method at the top is presented first.
  </Step>
</Steps>

## Card on-ramps

Card on-ramps deliver crypto **on-chain to the settlement wallet you configure**, so funds land directly with you. Ramp, MoonPay, and Mercuryo build a cryptographically **signed widget URL** with no server call. Transak and Banxa create a session/order **server-side first** — Transak via its Create Widget URL API, Banxa via its order API — then embed the returned URL. All confirm settlement from the provider's webhook.

<Note>
  **Embedded checkout.** All five card on-ramps are **embeddable** — at checkout the customer selects one inline and the widget expands in an `<iframe>` on your page instead of redirecting away. The iframe loads the provider's hosted widget URL: a signed URL (MoonPay, Mercuryo, Ramp) or a server-generated session URL (Transak, via its Create Widget URL API, and Banxa). Completion flows through the provider webhook, surfaced to the open checkout over the live status stream. Each widget includes an "open in a new tab" fallback. The crypto-checkout providers remain redirect-only. Note that on-ramps gate embedding on a registered **referrer domain** — allowlist your checkout domain (and matching sandbox/live keys) in each provider's dashboard, or the provider will refuse to be framed.
</Note>

### Transak

| Credential            | Description                                                        |
| --------------------- | ------------------------------------------------------------------ |
| **API Key**           | Transak partner API key                                            |
| **API Secret**        | Used to verify inbound webhook JWT signatures                      |
| **Settlement Wallet** | Destination wallet that receives the crypto (your payout address)  |
| **Crypto Currency**   | Asset Transak settles in, e.g. `USDC`                              |
| **Network**           | Transak network id, e.g. `ethereum`, `base`, `polygon`, `arbitrum` |

The widget is launched via Transak's **Create Widget URL** API (`POST /api/v2/auth/session`): MyCryptoServer mints the partner access token, sends your `referrerDomain` (your checkout host) and the end-user IP, and embeds the returned single-use session URL. **Allowlist your checkout domain and server IP in the Transak dashboard** (for the staging environment when Sandbox mode is on) — otherwise Transak refuses to be framed.

Each webhook's `webhookData` is a JWT signed (HS256) with a partner **access token** — minted from Transak's `POST /partners/api/v2/refresh-token` endpoint (using your API secret, valid 7 days, cached automatically). MyCryptoServer verifies the signature and marks the session paid on order status `COMPLETED`. Configure the webhook URL in the Transak partner dashboard.

### Ramp Network

| Credential                   | Description                                                                                                                                 |
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| **Host API Key**             | Ramp host (client) API key                                                                                                                  |
| **Settlement Wallet**        | Destination wallet that receives the crypto (your payout address)                                                                           |
| **Asset**                    | Ramp asset id in `CHAIN_SYMBOL` form, e.g. `ETH_USDC`, `BASE_USDC`, `MATIC_USDC` (the prefix is Ramp's short chain code, not the full name) |
| **Webhook Public Key (PEM)** | Optional — leave blank to use Ramp's built-in production/demo keys; set only if Ramp rotates them                                           |

Ramp signs each webhook body with ECDSA (secp256k1 / SHA-256) and sends the signature in the `X-Body-Signature` header; MyCryptoServer verifies it against Ramp's published public keys. A purchase event of `RELEASED` (crypto delivered on-chain) marks the session paid. Ramp echoes the order reference via a query param on the registered webhook URL rather than in the body.

### MoonPay

| Credential            | Description                                                                      |
| --------------------- | -------------------------------------------------------------------------------- |
| **Publishable Key**   | MoonPay publishable key (`pk_…`), embedded in the widget URL                     |
| **Secret Key**        | MoonPay secret key (`sk_…`), used to sign the widget URL — never sent to MoonPay |
| **Webhook Key**       | Separate secret from the Developers page; verifies inbound webhooks              |
| **Settlement Wallet** | Destination wallet that receives the crypto (your payout address)                |
| **Currency Code**     | MoonPay currency code, e.g. `usdc`, `usdc_polygon`, `eth` (lowercase)            |

Because a wallet address is passed, MoonPay **requires the widget URL to be signed** — MyCryptoServer HMAC-SHA256s the query string with your secret key and appends `&signature=…`. Each webhook carries a `Moonpay-Signature-V2` header (`t=<timestamp>,s=<signature>`) verified as HMAC-SHA256 of `<timestamp>.<body>` keyed by your webhook key; a transaction status of `completed` marks the session paid. Correlation is via `externalTransactionId`, which MyCryptoServer sets to the session id. Configure the webhook URL in the MoonPay dashboard.

<Warning>
  MoonPay's documented webhook examples show `externalTransactionId` as `null`. Confirm in sandbox that it is actually echoed on buy webhooks before relying on it in production — without it, deliveries cannot be correlated back to a session.
</Warning>

### Mercuryo

| Credential            | Description                                                         |
| --------------------- | ------------------------------------------------------------------- |
| **Widget ID**         | Public Mercuryo widget id, embedded in the widget URL               |
| **Widget Secret**     | Used to sign the wallet address (`SHA-512(address + secret)`)       |
| **Sign Key**          | Separate secret (from your integration manager); verifies callbacks |
| **Settlement Wallet** | Destination wallet that receives the crypto (your payout address)   |
| **Currency**          | Crypto Mercuryo settles in, e.g. `USDC`, `USDT`, `ETH`              |
| **Network**           | Optional Mercuryo network override, e.g. `POLYGON`, `BASE`          |

The destination address is protected by a signature = `SHA-512(address + secret)` (a plain hash, **not** an HMAC) appended to the widget URL. Callbacks carry an `X-Signature` header = HMAC-SHA256 of the body keyed by your **Sign Key** (a separate secret from the Widget Secret); a buy status of `paid` marks the session paid. Correlation is via `merchant_transaction_id`, set to the session id. Set the Callback URL in the Mercuryo dashboard.

### Banxa

| Credential            | Description                                                       |
| --------------------- | ----------------------------------------------------------------- |
| **API Key**           | Banxa partner API key (the public half of the HMAC pair)          |
| **API Secret**        | Keys the HMAC for both API calls and inbound webhooks             |
| **API Base URL**      | Per-partner Banxa subdomain, e.g. `https://yourco.banxa.com`      |
| **Settlement Wallet** | Destination wallet that receives the crypto (your payout address) |
| **Coin**              | Coin Banxa settles in, e.g. `USDC`, `USDT`, `ETH`                 |
| **Blockchain**        | Banxa blockchain code, e.g. `ETH`, `MATIC`, `BASE`                |

Unlike the signed-URL on-ramps, Banxa creates the order **server-side** (`POST /api/orders`) and returns a hosted `checkout_url`. Both the outbound API call and inbound webhooks authenticate with the same HMAC scheme: an `Authorization: Bearer <key>:<signature>:<nonce>` header, where the signature is HMAC-SHA256 of `<METHOD>\n<PATH>\n<nonce>\n<body>` keyed by your API secret. An order status of `complete` marks the session paid. Banxa's API base is per-partner, so it's entered as a credential rather than a global setting. Configure the webhook URL in the Banxa dashboard.

## Crypto checkout providers

### Binance Pay

| Credential              | Description                                                       |
| ----------------------- | ----------------------------------------------------------------- |
| **API Key**             | Binance Pay API key (certificate SN)                              |
| **Secret Key**          | Binance Pay secret, used to sign API calls                        |
| **Settlement Currency** | Crypto Binance Pay settles in, e.g. `USDT` (treated 1:1 with USD) |

The order carries a per-order webhook URL, and MyCryptoServer authoritatively re-queries order status before marking a session paid.

### Coinbase Commerce

| Credential                | Description                                                                          |
| ------------------------- | ------------------------------------------------------------------------------------ |
| **API Key**               | Coinbase Commerce API key                                                            |
| **Webhook Shared Secret** | From the Commerce dashboard → Webhooks; verifies the `X-CC-Webhook-Signature` header |

Configure one webhook endpoint in the Coinbase Commerce dashboard pointing at `…/api/providers/coinbase_commerce/webhook`. MyCryptoServer verifies the signature, then re-queries the charge to confirm settlement.

### NOWPayments

| Credential     | Description                                                 |
| -------------- | ----------------------------------------------------------- |
| **API Key**    | NOWPayments API key, sent as `x-api-key` to create invoices |
| **IPN Secret** | From Payment Settings → IPN; verifies inbound callbacks     |

An invoice is created **server-side** (`POST /v1/invoice`) and the customer is redirected to its `invoice_url`. The IPN callback URL is set automatically per invoice, so there's no dashboard webhook step. Each IPN carries an `x-nowpayments-sig` header = HMAC-SHA512 over the **key-sorted** JSON body keyed by your IPN secret. A payment status of `finished` marks the session paid; `partially_paid` is intentionally left for manual reconciliation. Correlation is via `order_id`, set to the session id.

### CoinGate

| Credential           | Description                                                                |
| -------------------- | -------------------------------------------------------------------------- |
| **API Token**        | CoinGate Auth Token, sent as a Bearer token                                |
| **Receive Currency** | What CoinGate settles into, e.g. `USDT`, `EUR`, `BTC`, or `DO_NOT_CONVERT` |

An order is created **server-side** (`POST /v2/orders`) and the customer is redirected to its `payment_url`. The callback URL is set per order, so there's no dashboard webhook step. CoinGate callbacks are **not signed**, so MyCryptoServer treats the callback only as a trigger and authoritatively re-queries `GET /v2/orders/:id`, trusting only the API's status — an order status of `paid` marks the session paid. Correlation is via `order_id`.

## Notes & limitations

* **USD only (v1).** Hosted providers are offered for USD-denominated payment links.
* **Card on-ramp KYC.** First-time buyers complete the provider's identity verification; expect higher friction and longer first payments than a normal card checkout.
* **Amounts.** Card → crypto goes through a live quote, so the exact crypto amount delivered depends on the rate at purchase time; the fiat value of the order is what's enforced.
* **Idempotent confirmation.** Provider webhooks flow through the same idempotent session state machine as on-chain payments, so duplicate deliveries won't double-complete an order.
