Skip to content

Get provider keys ​

This page tells you how to get the keys and settings that each adapter needs. For each provider, it gives:

  • the access type,
  • where to sign up, and the path to the keys in the dashboard,
  • which values to copy, the adapter option for each value, and a suggested environment variable,
  • how to change from sandbox to production,
  • the webhook setup,
  • the gotchas.

The facts on this page come from setting up the accounts on 9 Oct 2026. Dashboards change. When this page says "check in the dashboard", we did not confirm that detail.

You do not need any key to start. The mock adapter moves no money and needs no account. Add real providers one at a time.

Summary ​

The times are estimates for the first sandbox key. Production access can take longer.

AdapterAccess typeKeys neededTime to get started
RelaySelf-serveAPI keyAbout 5 minutes
LI.FISelf-serveAPI key, integrator stringAbout 5 minutes
MoonPaySelf-serve sandbox; review (KYB) for livePublishable key, secret key, webhook keyAbout 10 minutes
TransakSelf-serve sandbox; business profile for liveAPI key, API secret, referrer domainAbout 10 minutes
XenditSelf-serve test modeSecret key, webhook verification tokenAbout 10 minutes
OnramperSelf-serve sandbox after an onboarding form; paid plan and KYB for liveAPI key, Ed25519 signing key, webhook secretAbout 15 minutes
CoinbaseSelf-serve limited test access; application for full accessCDP Secret API key (id and secret), webhook secretAbout 15 minutes
StripeApplication and reviewSecret key, publishable key, webhook signing secretDays (Stripe reviews the application)
Stripe LinkPrivate preview; Stripe onboards the accountSecret key, publishable key, Link OAuth client id, webhook signing secret, optional token keyDays to weeks (Stripe onboarding)
SwappedApplication (business onboarding)Public key, secret keyDays
BanxaPartner onboarding (sandbox first; production after Banxa approves the integration)Partner reference, v2 API key, HMAC key pairDays
PayTrieEmail support@paytrie.com for a developer API key; no documented sandboxAPI key, webhook signing secret, optional token keyDays (estimate; PayTrie answers email within 24 hours)
FlashnetSelf-serve dashboard; Flashnet reviews the account before the API works; no sandboxServer key (fn_), webhook secretDays (account review)
MeldSales (contact form)API key, webhook secretDays to weeks
BridgeSalesAPI key, webhook public keyDays to weeks
BinancePartner approval; no sandboxAPI URL, client id, access token, RSA key pair, Binance public keyWeeks
PeerNot recommended for productionAPI key, webhook secretNot recommended
Reown (WalletConnect)Self-serveProject id (public)About 5 minutes

Before you start ​

The webhook URL ​

The server receives provider webhooks at one route per adapter:

POST {baseUrl}/webhooks/{adapterId}

baseUrl is the baseUrl that you give to createOpenRamp. adapterId is the id of the adapter, for example moonpay. Example: https://app.example.com/api/openramp/webhooks/moonpay. The adapter verifies each webhook with the secret or public key that you copy from the provider.

A provider cannot send a webhook to localhost. To test webhooks on your computer, use a tunnel to a public HTTPS URL. Set baseUrl to that URL.

Sandbox and production ​

Every adapter takes the same option: env: 'sandbox' | 'production'. For Stripe and Xendit, the key prefix gives the default. Binance, LI.FI and Relay have no sandbox switch: their env comes from the host. The sections below give the details for each adapter. Each adapter shows its environment as the read-only adapter.env.

Also set livemode: true on createOpenRamp in production. Events then carry livemode. The server checks each adapter.env against livemode when it starts:

livemodeAdapter envResult
truesandboxThe server does not start. A test payment must never complete a live session.
falseproductionOne warning: test sessions call a provider that moves real money.
Anynot set (Coinbase without env)No check. The adapter follows each session's livemode.

The mock adapter is sandbox, so a server with livemode: true does not start with it.

Old options still work, with a one-time deprecation warning: env: 'staging' (Transak) is env: 'sandbox', env: 'live' (Peer) is env: 'production', and sandbox: true or false (Coinbase) is env: 'sandbox' or 'production'.

Sandboxes do not have all the assets and methods of production. Known limits (Checked on 9 Oct 2026.):

ProviderSandbox limit
MoonPayTest mode has USDC only as usdc on Ethereum. No usdc_base, usdc_arbitrum, usdc_optimism or usdc_polygon.
RelayThe testnets host knows ETH on Base Sepolia and Sepolia, but not USDC on Base Sepolia.
TransakStaging has 26 fiat currencies and no INR. You cannot test UPI on staging.
OnramperStaging for the US shows card only.
LI.FINo sandbox host (staging.li.quest returns 403). Test with small quotes on mainnet, and never send.

Keep keys safe ​

  • Keep secret keys on the server only. Never put a secret key in a NEXT_PUBLIC_ variable or in your client bundle.
  • Put keys in an env file that git ignores. The repo ignores .env, .env.local and .dev.vars. In production, use your platform's secrets (for example wrangler secret put or the Vercel environment variables).
  • Never paste keys into a chat, an issue, a pull request or a log.
  • If a key was exposed, rotate it in the provider dashboard at once. Then update your env file and your platform secrets.
  • Use a different key for each environment (local, staging, production). Then you can rotate one key and the other environments continue to work.
  • The examples on this page show no real key values. The prefixes (for example pk_test_) only help you find the correct key.

Relay ​

Access type: self-serve.

Sign up: dashboard.relay.link.

Get the key:

  1. Create an organization.
  2. Open API keys. Click Create an API Key.
  3. Give the key a name, for example staging. Copy the key.
ValueAdapter optionEnv var
API keyapiKeyRELAY_API_KEY
ts
relay({ apiKey: process.env.RELAY_API_KEY })

The adapter sends the key in the x-api-key header.

Sandbox and production: the default API is https://api.relay.link (mainnets). For testnets, set baseUrl: 'https://api.testnets.relay.link'. The adapter env is then sandbox; else it is production. Make one key for each environment. Check in the dashboard if a testnet key is different from a mainnet key.

Sandbox limits: The testnets host (https://api.testnets.relay.link) knows ETH on Base Sepolia and on Sepolia. It does not know USDC on Base Sepolia. To test on testnets, quote ETH, not USDC. Checked on 9 Oct 2026.

Webhooks: the Relay adapter has no webhook handler. Status comes from polling. You can configure webhooks per key in the Relay dashboard, but the adapter does not use them.

Gotchas:

  • Relay requires an API key for quotes (POST /quote/v2) under its announced policy from 2 Oct 2026. Some requests without a key may still work today, but Relay can refuse them at any time. Always set RELAY_API_KEY. A refused quote gets 401 UNAUTHORIZED_QUOTE. A quote that sets referrer without a key is refused now.
  • Without a key, status checks use /requests/v2. Relay retires it on 24 Nov 2026.

LI.FI ​

Access type: self-serve.

Sign up: portal.li.fi.

Get the key:

  1. Open Integrations. Click New integration.
  2. Give it a name.
  3. Set the integration string. It is lowercase and you cannot change it later. This is the adapter's integrator.
  4. Optional: add fee wallets. Skip this step if you charge no fee.
  5. Click Create API key. Copy the key at once. LI.FI shows it one time only.
ValueAdapter optionEnv var
API keyapiKeyLIFI_API_KEY
Integration stringintegratorLIFI_INTEGRATOR
ts
lifi({ apiKey: process.env.LIFI_API_KEY, integrator: process.env.LIFI_INTEGRATOR })

The adapter sends the key in the x-lifi-api-key header.

Sandbox and production: the adapter has no sandbox switch, and its env is always production. The API is https://li.quest/v1 (baseUrl). Quotes move no money. A wallet transaction moves real funds, so test with small amounts.

Sandbox limits: LI.FI has no sandbox host: staging.li.quest returns 403. Test with small quotes on the mainnet host only. Quotes move no money. Never send the transaction in a test. Checked on 9 Oct 2026.

Webhooks: the LI.FI adapter has no webhook handler. Status comes from polling.

Gotchas:

  • With a key, the quote limit is about 12,000 requests in 2 hours. Without a key, it is 75 requests in 2 hours. The server quotes on each amount change, so you reach the keyless limit fast.
  • A fee (feeBps) needs integrator and a fee wallet for that integration. Without a fee wallet, LI.FI refuses the quote (error code 1011).
  • If you lose the key, make a new one. You cannot see it again.

MoonPay ​

Access type: self-serve sandbox (Test mode). Live access needs a review (KYB).

Sign up: dashboard.moonpay.com. A new account starts in Test mode.

Get the keys: open Developers, then API Keys. The page shows four keys:

ValuePrefix in Test modeAdapter optionEnv var
Publishable Keypk_test_publishableKeyMOONPAY_PUBLISHABLE_KEY
Secret Keysk_test_secretKeyMOONPAY_SECRET_KEY
Webhook Keywk_test_webhookKeyMOONPAY_WEBHOOK_KEY
Public Keynot used
ts
moonpay({
  publishableKey: process.env.MOONPAY_PUBLISHABLE_KEY!,
  secretKey: process.env.MOONPAY_SECRET_KEY!,
  webhookKey: process.env.MOONPAY_WEBHOOK_KEY,
  env: 'sandbox',
})

Sandbox and production: set env: 'sandbox' with the _test_ keys. Set env: 'production' with the live keys. env is required. To go live, click Start review in the dashboard and complete KYB.

Sandbox limits: MoonPay test mode has USDC only as usdc (USDC on Ethereum). usdc_base, usdc_arbitrum, usdc_optimism and usdc_polygon are not in test mode. To test in test mode, quote USDC on Ethereum. A test mode quote for USDC on another chain fails. Base is first in the default deliverAssets, so set the destination to USDC on Ethereum for test mode. Checked on 9 Oct 2026.

Webhooks: register {baseUrl}/webhooks/moonpay in the dashboard (check in the dashboard for the exact page). Copy the Webhook Key to webhookKey. Without webhookKey, the adapter rejects every webhook.

Gotchas:

  • The "refresh" icon next to each key rotates that key. The old key stops at once. Do not click it unless you want a new key.
  • Test mode does not support every currency. For example, usdc_base returned "Currency not supported in test mode". Use deliverAssets to pick an asset that Test mode supports.
  • env must agree with the keys. A live key with env: 'sandbox' (or the reverse) does not work.

Transak ​

Access type: self-serve sandbox (Staging). Live access needs a business profile.

Sign up: dashboard.transak.com.

Get the keys:

  1. At the top of the dashboard, change the environment selector from Production to Staging.
  2. Open Developers. Copy the API Key.
  3. Click Generate to make the API Secret. Copy it.
  4. Register your web domain as the referrer domain (check in the dashboard for the exact page).
ValueAdapter optionEnv var
API KeyapiKeyTRANSAK_API_KEY
API SecretapiSecretTRANSAK_API_SECRET
Your domain, for example app.example.comreferrerDomainTRANSAK_REFERRER_DOMAIN
ts
transak({
  apiKey: process.env.TRANSAK_API_KEY!,
  apiSecret: process.env.TRANSAK_API_SECRET!,
  referrerDomain: process.env.TRANSAK_REFERRER_DOMAIN!,
  env: 'sandbox',
})

The adapter uses the secret to get an access token: POST https://api-stg.transak.com/partners/api/v2/refresh-token with the header api-secret and the body { apiKey }. It does this for you.

Sandbox and production: set env: 'sandbox' with Staging keys. The adapter then uses the Transak staging hosts. The default is 'production'. The old value 'staging' still works, with a deprecation warning. To go live, click Complete your business profile in the dashboard. Then copy the Production keys.

Sandbox limits: Transak staging has 26 fiat currencies. INR is not one of them, so you cannot test UPI on staging. Checked on 9 Oct 2026.

Webhooks: register {baseUrl}/webhooks/transak in the Transak dashboard (check in the dashboard for the exact page). There is no separate webhook secret: Transak signs webhooks with the access token, and the adapter keeps that token.

Gotchas:

  • If you forget env: 'sandbox', the adapter sends Staging keys to the production API, and every call fails.
  • Partners must make widget URLs on the server (Secure Widget URL). The adapter does this in start().
  • A new access token cancels the old token. Do not share one API key between two deployments (for example your computer and staging). Each deployment refreshes the token and stops the other one.
  • The adapter verifies a webhook with the cached access token. Before webhooks arrive, run at least one quote or start on the instance, or use a shared store.

Xendit ​

Access type: self-serve test mode.

Sign up: dashboard.xendit.co. Use Test mode.

Get the keys:

  1. Open Settings, then Developers, then API keys.
  2. Click Generate secret key. In Test mode, the key starts with xnd_development_.
  3. Set the permissions. The adapter calls the Payments API v3 (POST /v3/payment_requests and GET /v3/payment_requests/{id}). Give the key write permission for the money-in (payment request) products. Check in the dashboard for the exact permission names.
  4. Open Settings, then Webhooks. Copy the Webhook verification token.
  5. Activate each payment channel that you offer (for example QRIS, QR Ph, PayNow QR, DANA). Do this in Test mode first, and again in live mode. Check in the dashboard for the exact page name. A channel that is not active fails with 403 INVALID_MERCHANT_SETTINGS.
ValueAdapter optionEnv var
Secret keysecretKeyXENDIT_SECRET_KEY
Webhook verification tokenwebhookTokenXENDIT_WEBHOOK_TOKEN
ts
xendit({ secretKey: process.env.XENDIT_SECRET_KEY!, webhookToken: process.env.XENDIT_WEBHOOK_TOKEN! })

Sandbox and production: the key prefix sets the mode. xnd_development_ keys use test mode (env is sandbox). xnd_production_ keys move real money (env is production). You can also set env. A value that does not agree with the key throws when you build the adapter. The API URL is the same (apiUrl, default https://api.xendit.co). Copy the webhook token of the same mode as the key (check in the dashboard).

Webhooks: in Settings, then Webhooks, set the payment webhook URL to {baseUrl}/webhooks/xendit. The adapter compares the x-callback-token header with webhookToken.

Gotchas:

  • A key with no read permission on balance gets 403 on GET /balance. The adapter does not call /balance, so this is not a problem.
  • The webhook token has no signature or timestamp. Keep it as secret as the API key.
  • Xendit has no crypto. Use the adapter with a merchant destination.
  • Activate each payment channel before you use it. Do this in test mode and again in live mode. A channel that is not active gets 403 INVALID_MERCHANT_SETTINGS "payment channel has not been activated". On 2026-10-09, a new test mode account got this error for QRIS and QR Ph, while DANA worked. The adapter shows the user "This payment method is not set up for this app yet" and writes an error log that names the channel. See Xendit errors.
  • PayNow QR uses the channel code SGQR. The old code PAYNOW gets 400 API_VALIDATION_ERROR "API endpoint and method is not supported for 'PAYNOW' channel code with country 'SG'".

Onramper ​

Access type: self-serve sandbox after an onboarding form. Live access needs a paid subscription and KYB.

Sign up: dashboard.onramper.com/users/sign_up. Then complete the onboarding form: entity, project, industry, country, expected volume and go-live date.

Get the keys:

  1. After the form, the dashboard shows a Staging API Key (pk_test_...). Copy it.
  2. Find the signing key and the webhook secret in the dashboard settings. Check in the dashboard for the exact page.

The adapter option secretKey is an Ed25519 private key for "Signature V2". It accepts a PKCS#8 PEM, base64 PKCS#8 DER, or a 32-byte seed (base64 or hex). If you make the key pair yourself, give Onramper the public key:

sh
openssl genpkey -algorithm ed25519 -out onramper-private.pem   # secretKey
openssl pkey -in onramper-private.pem -pubout -out onramper-public.pem   # give to Onramper

Check in the dashboard if Onramper makes the key for you, or if you upload your public key.

ValueAdapter optionEnv var
API key (pk_test_... or pk_prod_...)apiKeyONRAMPER_API_KEY
Ed25519 private keysecretKeyONRAMPER_SIGNING_KEY
Webhook secretwebhookSecretONRAMPER_WEBHOOK_SECRET
ts
onramper({
  apiKey: process.env.ONRAMPER_API_KEY!,
  secretKey: process.env.ONRAMPER_SIGNING_KEY!,
  webhookSecret: process.env.ONRAMPER_WEBHOOK_SECRET,
  env: 'sandbox',
})

Sandbox and production: set env: 'sandbox' with the pk_test_ key (API https://api-stg.onramper.com). Set env: 'production' with the pk_prod_ key. env is required.

Sandbox limits: Onramper staging for the US shows card only. You cannot test other US methods (for example ACH or PayPal) on staging. Checked on 9 Oct 2026.

Webhooks: send {baseUrl}/webhooks/onramper to Onramper (in the dashboard or through your Onramper contact; check in the dashboard). Copy the webhook secret to webhookSecret.

Gotchas:

  • Without webhookSecret, the adapter cannot learn the transaction id, and status stays "still paying".
  • The checkout is bound to the user's IP. Without a client IP header, start fails.
  • Register the public key before the first start. Without it, start gets 401 {"errorId":4011,"message":"No V2 signing key is registered for this API key..."}. The Onramper key setup page says to send the public key (PEM) to your Onramper account manager or support. Use one key pair for staging and another for production. The adapter logs this as a setup error and does not retry.
  • Onramper also wants the server egress IPs and your domains on its allowlist. A server call from another IP gets 403.
  • The adapter does not accept a PEM with \n escapes. A PEM with real new lines works. For a one-line env var, use the base64 DER form: openssl pkey -in onramper-private.pem -outform DER | base64.

Coinbase ​

Access type: self-serve limited test access. Full access needs an application.

Sign up: sign in at portal.cdp.coinbase.com. Pick a project.

Get the keys:

  1. Open Payments, then Onramp & Offramp.
  2. In Configuration, set the Application display name. Add your domain to the Domain allowlist. The redirectUrl must be on this list.
  3. Open API keys. Create a Secret API key. Copy the key id and the secret at once. The portal shows the secret one time only.
  4. Create the Onramp webhook subscription and copy its secret (check in the portal for the exact page).
  5. For full access, click Apply for access.
ValueAdapter optionEnv var
Secret API key id (the key name or id)apiKeyIdCDP_API_KEY_ID
Secret API key secret (base64 Ed25519 or EC PEM)apiKeySecretCDP_API_KEY_SECRET
Onramp webhook secretwebhookSecretCDP_WEBHOOK_SECRET
Project id (optional, not used by the session API)appIdCDP_PROJECT_ID
ts
coinbase({
  apiKeyId: process.env.CDP_API_KEY_ID!,
  apiKeySecret: process.env.CDP_API_KEY_SECRET!,
  webhookSecret: process.env.CDP_WEBHOOK_SECRET,
})

Sandbox and production: set env: 'sandbox' or env: 'production'. Without env, each session's livemode decides: with livemode: true on createOpenRamp, the adapter leaves sandbox mode. The old sandbox option still works, with a deprecation warning. A new project has limited test access: 25 test transactions, at most 5 USD each.

Webhooks: subscribe to onramp.transaction.created, onramp.transaction.updated, onramp.transaction.success and onramp.transaction.failed with the URL {baseUrl}/webhooks/coinbase. Copy the subscription secret to webhookSecret. Without it, the adapter rejects every webhook.

Gotchas:

  • Guest Apple Pay (guestCheckout, the headless flow) needs extra approval from Coinbase. Its domain must be on the domain allowlist.
  • The hosted legs need a Coinbase account for each user.
  • Copy the secret when you create the key. If you lose it, make a new key.

Stripe ​

Access type: application and review.

Sign up: in the Stripe dashboard, open Crypto onramp, then Get started.

Apply:

  1. Update the domains where the onramp runs.
  2. Click Submit your Stripe application. Give your business details, a business description, the answer to the Terms of Service question (yes or no), and whether you fill in the wallet address for the user.
  3. Wait for approval. Check in the dashboard if the onramp works in test mode before approval.

Get the keys: the adapter uses the API keys of your Stripe account. Open Developers, then API keys (check in the dashboard). A restricted key with onramp access also works.

ValueAdapter optionEnv var
Secret key (sk_test_... in test mode)secretKeySTRIPE_SECRET_KEY
Publishable key (pk_test_... in test mode)publishableKeySTRIPE_PUBLISHABLE_KEY
Webhook signing secret (whsec_...)webhookSecretSTRIPE_WEBHOOK_SECRET
ts
stripe({
  secretKey: process.env.STRIPE_SECRET_KEY!,
  publishableKey: process.env.STRIPE_PUBLISHABLE_KEY!,
  webhookSecret: process.env.STRIPE_WEBHOOK_SECRET!,
})

Sandbox and production: the key prefix sets the mode. sk_test_ and pk_test_ keys use test mode. Live keys start with sk_live_ and pk_live_. The adapter reads env from the key prefix (sk_test_ or rk_test_ is sandbox). You can also set env. A value that does not agree with the key throws when you build the adapter.

Webhooks: open Developers, then Webhooks. Add an endpoint with the URL {baseUrl}/webhooks/stripe and the event crypto.onramp_session.updated. Copy its signing secret to webhookSecret. Test mode and live mode have different endpoints and secrets.

Gotchas:

  • The publishable key goes to the browser for the embedded onramp. That is safe. The secret key must stay on the server.
  • Set providerRenderers: { stripe: stripeOnrampRenderer() } on the modal, or surface: 'redirect' on the adapter. See Stripe.

Access type: private preview. No call works, also in a sandbox, until Stripe finishes your onboarding.

Sign up: submit the crypto onramp application. Then work with your Stripe contact to:

  • Turn on the feature gates for the Embedded Components onramp APIs and the Link OAuth APIs.
  • Turn on Link as a payment method in Settings, then Payment methods.
  • Get the Link OAuth client id. Stripe provisions it.

Where to find the keys: the secret key and the publishable key are on the API keys page. Stripe gives you the OAuth client id. The adapter does not need the OAuth client secret: it never refreshes a token.

Env var names:

ts
stripeLink({
  secretKey: process.env.STRIPE_SECRET_KEY!,
  publishableKey: process.env.STRIPE_PUBLISHABLE_KEY!,
  oauthClientId: process.env.STRIPE_LINK_OAUTH_CLIENT_ID!,
  webhookSecret: process.env.STRIPE_LINK_WEBHOOK_SECRET!,
  tokenKey: process.env.STRIPE_LINK_TOKEN_KEY, // optional, at least 32 characters
})

Webhooks: add an endpoint with the URL {baseUrl}/webhooks/stripe-link and the event crypto.onramp_session.updated. Copy its signing secret to webhookSecret.

Gotchas:

  • Test with the sandbox values in Stripe's guide: OTP 000000, SSN 000000000, card 4242 4242 4242 4242, and 100 USD or less.
  • See Stripe Link for the client part.

Swapped ​

Access type: application (business onboarding). We saw no self-serve sandbox.

Sign up: apply through Swapped business onboarding (see docs.swapped.com). Swapped gives you the keys after onboarding. Check in the dashboard for the path.

ValueAdapter optionEnv var
Public key (pk_...)publicKeySWAPPED_PUBLIC_KEY
Secret key (sk_...)secretKeySWAPPED_SECRET_KEY
ts
swapped({
  publicKey: process.env.SWAPPED_PUBLIC_KEY!,
  secretKey: process.env.SWAPPED_SECRET_KEY!,
  env: 'sandbox',
})

Sandbox and production: set env: 'sandbox' for https://sandbox.swapped.com. The default is 'production'. The sandbox has BTC and ETH testnets and test cards only.

Webhooks: you do not register a URL. The adapter puts {baseUrl}/webhooks/swapped in each widget URL as responseUrl. The adapter verifies notifications with secretKey.

Gotchas:

  • An empty secretKey makes the adapter refuse every notification.

Banxa ​

Access type: partner onboarding. Banxa issues sandbox credentials first. Production credentials come separately, after Banxa approves the integration. Banxa has no self-serve sign-up and no OAuth.

Get the keys: in the Banxa Partner Dashboard (per environment, switch with the toggle at the top):

ValueAdapter optionEnv var
Partner reference (the first segment of every API path)partnerRefBANXA_PARTNER_REF
v2 API key (x-api-key)apiKeyBANXA_API_KEY
HMAC API keyhmacKeyBANXA_HMAC_KEY
HMAC secrethmacSecretBANXA_HMAC_SECRET
ts
banxa({
  partnerRef: process.env.BANXA_PARTNER_REF!,
  apiKey: process.env.BANXA_API_KEY!,
  hmacKey: process.env.BANXA_HMAC_KEY,
  hmacSecret: process.env.BANXA_HMAC_SECRET,
  env: 'sandbox',
})

Sandbox and production: set env: 'sandbox' for https://api.banxa-sandbox.com with the sandbox keys, or env: 'production' for https://api.banxa.com. env is required. Sandbox keys work only on the sandbox host, and production keys only on the production host: the wrong pair gives 401.

Webhooks: set the webhook URL for each environment in the Partner Dashboard to {baseUrl}/webhooks/banxa. Banxa signs webhooks with the HMAC key pair, not with the v2 API key. With more than one active HMAC pair, Banxa signs with the oldest pair that is not revoked; the dashboard Webhooks page shows which one. Use Send test to check the URL.

Gotchas:

  • The signature covers the path of your webhook URL. If a proxy rewrites the path, set webhookPath to the path that Banxa calls.
  • If the dashboard shows only a v2 API key, ask your Banxa account manager for the HMAC key pair.
  • Sandbox allows 120 requests per minute per merchant. Prefer webhooks over polling.
  • Before go-live, Banxa requires a disclaimer that Banxa processes the payment as merchant of record (required disclaimer).

PayTrie ​

Access type: request by email. Register a PayTrie account at app.paytrie.com/SignupEmail, then email support@paytrie.com with your registered email, your use case and your expected volume, and ask for a developer API key (Using the Platform API).

Get the keys:

ValueWhereAdapter optionEnv var
Developer API key (x-api-key)From PayTrie supportapiKeyPAYTRIE_API_KEY
Webhook signing secret (whsec_...)The answer to the first PUT /v2/webhook-configurations (below)webhookSecretPAYTRIE_WEBHOOK_SECRET
Token key (32 characters or more, optional)You make it, for example openssl rand -base64 32tokenKeyPAYTRIE_TOKEN_KEY
ts
paytrie({
  apiKey: process.env.PAYTRIE_API_KEY!,
  webhookSecret: process.env.PAYTRIE_WEBHOOK_SECRET,
  tokenKey: process.env.PAYTRIE_TOKEN_KEY,
})

Sandbox and production: PayTrie documents only https://api.paytrie.com. The adapter defaults to env: 'production'. Ask PayTrie support for a test host; to use one, set env: 'sandbox' and apiUrl.

Webhooks: register your URL once with the API. The first call returns the signing secret, and only the first call:

bash
curl -X PUT "https://api.paytrie.com/v2/webhook-configurations" \
  -H "x-api-key: $PAYTRIE_API_KEY" -H "Content-Type: application/json" \
  -d '{ "url": "https://your-app.example/api/openramp/webhooks/paytrie" }'

To get a new secret later, call POST /v2/webhook-configurations/signing-secret/rotate. To send a test event, call POST /v2/webhook-configurations/test.

Gotchas:

  • PayTrie sends each webhook once and does not retry. The adapter also polls with the user's access token (1 hour). After that, only the webhook reports the result.
  • One webhook URL per integration: use one OpenRampKit server per API key.
  • The adapter never stores KYC data. Users sign up and do KYC on PayTrie pages.
  • If you had v1 webhooks, turn them off after v2 works (PATCH /webhooks with every flag false).

Flashnet ​

Access type: self-serve dashboard with an account review. Create the keys in the Orchestra dashboard. Flashnet reviews new accounts before it enables the API: until then, calls answer 403 (account_pending_approval). There is no sandbox.

ValueAdapter optionEnv var
Server key (fn_...; not a client key fnp_...)apiKeyFLASHNET_API_KEY
Webhook signing secretwebhookSecretFLASHNET_WEBHOOK_SECRET
Your Tron address for refunds (needed for Tron deposits)refundAddresses.tronFLASHNET_TRON_REFUND
ts
flashnet({
  apiKey: process.env.FLASHNET_API_KEY!,
  webhookSecret: process.env.FLASHNET_WEBHOOK_SECRET,
  refundAddresses: { tron: process.env.FLASHNET_TRON_REFUND },
})

Webhooks: register the URL with the server key. The answer has the signing secret, and Flashnet shows it only once:

bash
curl -X POST https://orchestration.flashnet.xyz/v1/webhooks \
  -H "Authorization: Bearer $FLASHNET_API_KEY" \
  -H "X-Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://your.app/api/openramp/webhooks/flashnet"}'

Gotchas:

  • No sandbox: test with a small real order (the USD minimum is 1.00).
  • order.recovery_required events need a separate subscription (POST /v1/webhooks/recovery). Without it, the adapter still learns the result from status checks.
  • Orchestra has rate limits (for example 60 requests per minute per IP for routes and limits, and 120 for estimates). Prefer webhooks over polling.

Meld ​

Access type: sales. We saw no self-serve sandbox: the sign-up sent us to a "Sandbox access" contact form.

Sign up: fill in the contact form on meld.io. Meld gives you a dashboard after the call. Check in the dashboard for the path to the API key.

ValueAdapter optionEnv var
API keyapiKeyMELD_API_KEY
Webhook profile secretwebhookSecretMELD_WEBHOOK_SECRET
ts
meld({
  apiKey: process.env.MELD_API_KEY!,
  env: 'sandbox',
  webhookSecret: process.env.MELD_WEBHOOK_SECRET,
})

Sandbox and production: set env: 'sandbox' for https://api-sb.meld.io, or env: 'production'. env is required.

Webhooks: create a webhook profile with the URL {baseUrl}/webhooks/meld. Copy its secret to webhookSecret.

Gotchas:

  • The signature covers the webhook URL. If a proxy rewrites the URL, set webhookUrl to the URL in the Meld profile.

Bridge ​

Access type: sales. Production needs KYB of your company.

Sign up: contact Bridge sales. For a sandbox key, write to support@bridge.xyz. Then make a sandbox key in the dashboard with the Sandbox toggle on. Only dashboard admins can make keys.

ValueAdapter optionEnv var
API key (sk-test-... in the sandbox)apiKeyBRIDGE_API_KEY
Webhook endpoint public key (PEM)webhookPublicKeyBRIDGE_WEBHOOK_PUBLIC_KEY
ts
bridge({
  apiKey: process.env.BRIDGE_API_KEY!,
  webhookPublicKey: process.env.BRIDGE_WEBHOOK_PUBLIC_KEY!,
  env: 'sandbox',
})

Sandbox and production: set env: 'sandbox' for https://api.sandbox.bridge.xyz. The default is 'production'. In the sandbox, KYC links do not work, no money moves, and Bridge sends no payment webhooks.

Webhooks: Bridge signs webhooks with an RSA key, one key for each endpoint.

  1. Create the endpoint with POST /v0/webhooks and the URL {baseUrl}/webhooks/bridge.
  2. Copy the public_key from the answer to webhookPublicKey.
  3. Turn the endpoint on with PUT /v0/webhooks/{id} and status: 'active'. A new endpoint is disabled.

See Bridge webhooks.

Gotchas:

  • A new webhook endpoint has a new public key. Update webhookPublicKey when you make a new endpoint.

Binance ​

Access type: partner approval. There is no sandbox.

Sign up: contact the Binance Pay Onchain team. See Binance access requirements.

You send to Binance:

  • your RSA public key (make the key pair with OpenSSL; see the adapter page),
  • the IP addresses of your server,
  • your webhook URL: {baseUrl}/webhooks/binance,
  • the domains of your redirect URLs,
  • a logo (80 x 80 pixel PNG).

Binance gives you:

ValueAdapter optionEnv var
API base URLapiUrlBINANCE_API_URL
Client idclientIdBINANCE_CLIENT_ID
Access tokenaccessTokenBINANCE_ACCESS_TOKEN
Webhook public keybinancePublicKeyBINANCE_WEBHOOK_PUBLIC_KEY
Partner codewebhookPartnerCode (optional)BINANCE_PARTNER_CODE
Your RSA private key (you keep it)privateKeyBINANCE_PRIVATE_KEY
ts
binance({
  apiUrl: process.env.BINANCE_API_URL!,
  clientId: process.env.BINANCE_CLIENT_ID!,
  accessToken: process.env.BINANCE_ACCESS_TOKEN!,
  privateKey: process.env.BINANCE_PRIVATE_KEY!,
  binancePublicKey: process.env.BINANCE_WEBHOOK_PUBLIC_KEY!,
})

Sandbox and production: there is no sandbox. Each call goes to the live API, and the adapter env is always production.

Webhooks: you give Binance the webhook URL during onboarding. The adapter verifies webhooks with binancePublicKey.

Gotchas:

  • Binance allows calls only from the server IPs that you sent. A platform with changing IPs needs a fixed outbound IP.
  • The adapter was not tested against the live API. Read the TO VERIFY notes on the Binance page.

Peer ​

Access type: not recommended for production. Peer is a peer-to-peer marketplace. It has legal risk, and paying strangers for crypto may breach the payment apps' terms. The adapter is off by default: the factory throws unless you pass enabled: true.

Sign up: see docs.pay.peer.xyz. The merchant API key is in Settings, then Developer (check in the dashboard). Sandbox and live keys are separate.

ValueAdapter optionEnv var
Merchant API keyapiKeyPEER_API_KEY
Webhook signing secretwebhookSecretPEER_WEBHOOK_SECRET
ts
peer({
  enabled: true,
  apiKey: process.env.PEER_API_KEY!,
  webhookSecret: process.env.PEER_WEBHOOK_SECRET!,
  env: 'sandbox',
})

Sandbox and production: set env: 'sandbox' with the sandbox key, or env: 'production' with the live key. env is required. The old value 'live' still works, with a deprecation warning.

Webhooks: register {baseUrl}/webhooks/peer with POST /api/v1/webhooks. Copy responseObject.secret from the answer to webhookSecret. Peer reports settlement only by webhook.

Gotchas: read the warning on the Peer page before you turn it on.

Reown (WalletConnect) ​

The wallet button in the Next.js example uses Reown (WalletConnect) for mobile wallets. Without a project id, only browser wallets work.

Access type: self-serve.

Sign up: dashboard.reown.com. Create a project. Copy the Project ID.

ValueWhere it goesEnv var
Project IDexamples/next-demo/lib/wagmi.tsNEXT_PUBLIC_WALLETCONNECT_PROJECT_ID
sh
# examples/next-demo/.env.local
NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID=your-project-id

Gotchas:

  • The project id is public by design. The browser needs it, so it is safe in a NEXT_PUBLIC_ variable. It is the only value on this page that is not a secret.
  • Check in the dashboard if you must add your domains to an allowlist for production.

Next steps ​

MIT licensed