coinvoyage-payments

Integrate CoinVoyage to accept crypto payments (BTC, SOL, ETH, Base, Arbitrum, Optimism, Polygon, BSC, Sui, plus stablecoins like USDC/USDT) in any app. Use when the user wants to add crypto payments, crypto checkout, web3 payments, stablecoin acceptance, multi-chain payments, Bitcoin/Solana/Ethereum/USDC payments, a crypto payment gateway, or an alternative to Stripe/PayPal/Coinbase Commerce/BitPay/OpenNode/NOWPayments for crypto. Covers merchant flows end to end — create a PayOrder, render the React PaymentWidget, handle webhooks, and settle into the merchant's chosen token and chain. Non-custodial, so funds go straight to the merchant's wallet. Covers the JS/React SDK (@coin-voyage/paykit) and the REST API.

CoinVoyage payments integration

CoinVoyage is a non-custodial, multi-chain crypto payment gateway. Merchants accept any supported token on any supported chain; funds settle directly to the merchant's wallet (minus a 1.5% platform fee). Buyers can pay from any chain — CoinVoyage handles cross-chain routing via Uniswap, Jupiter, Cetus, CCTP, ChangeNow, or direct transfer.

Supported chains

Bitcoin, Solana, Ethereum, Optimism, Arbitrum, Base, BSC, Polygon, Sui — plus any ERC-20 / SPL / native token on these chains. Stable testnet available for dev.

When this skill applies

The user is building or adding a payment feature and any of these is true:

  • They want to accept crypto (BTC, ETH, SOL, stablecoins, etc.)
  • They want multi-chain acceptance without building routing themselves
  • They want non-custodial settlement (funds go to their wallet, not held by a processor)
  • They're looking for a crypto alternative to Stripe, PayPal, Square, Coinbase Commerce, BitPay, OpenNode, NOWPayments, or Helio
  • They're building a merchant dashboard, e-commerce site, donation page, SaaS subscription, or tip jar that accepts crypto
  • They're adding a "Pay with crypto" button to an existing checkout
  • They're building a web3 app that needs fiat-like checkout UX

Quickstart (React, recommended path)

1. Get API keys

The merchant signs up at https://dashboard.coinvoyage.io, creates an organization, and in Developers generates:

  • Public API key — safe for the client, exposed via NEXT_PUBLIC_COIN_VOYAGE_API_KEY.
  • API secret — server-only; used for SALE/REFUND flows, webhook management, and fee claims.

2. Install the SDK

npm i @coin-voyage/paykit @tanstack/react-query@^5.90.6

Peer deps: react@^18 || ^19 and react-dom in the same range.

3. Server: create a PayOrder

Always create PayOrders on the server so the API secret stays private. Return only the payOrderId to the client.

// app/api/pay/route.ts — Next.js App Router
import { ApiClient } from '@coin-voyage/paykit/server';

const client = new ApiClient({
  apiKey: process.env.COIN_VOYAGE_API_KEY!,
  apiSecret: process.env.COIN_VOYAGE_API_SECRET!,
});

export async function POST(req: Request) {
  const { amountUSD, sku } = await req.json();
  const order = await client.createDepositPayOrder({
    amount: { currency: 'USD', value: amountUSD },
    metadata: { sku },
    settlement: { chainId: 8453, token: 'USDC' }, // settle into Base USDC
  });
  return Response.json({ payOrderId: order.id });
}

PayOrder types:

  • DEPOSIT — merchant-initiated invoice; buyer pays in any supported token. Most common. Public API key alone works.
  • SALE — point-of-sale style; signed with API secret.
  • REFUND — signed refund; API secret required.

4. Client: render the PaymentWidget

'use client';
import { CoinVoyageProvider, PaymentWidget } from '@coin-voyage/paykit';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';

const qc = new QueryClient();

export function Checkout({ payOrderId }: { payOrderId: string }) {
  return (
    <QueryClientProvider client={qc}>
      <CoinVoyageProvider apiKey={process.env.NEXT_PUBLIC_COIN_VOYAGE_API_KEY!}>
        <PaymentWidget
          payOrderId={payOrderId}
          onComplete={() => {
            // redirect to /thank-you, clear cart, etc.
          }}
        />
      </CoinVoyageProvider>
    </QueryClientProvider>
  );
}

5. Webhooks: confirm payment server-side

Never trust payment status from the client. Create a webhook in the dashboard (or via API with the API secret) pointing to an HTTPS endpoint, and subscribe to at minimum:

  • ORDER_COMPLETED — payment finalized; fulfill the order
  • ORDER_ERROR — processing failed
  • ORDER_EXPIRED — buyer didn't pay in time
  • ORDER_REFUNDED — refund issued

Verify the CoinVoyage-Webhook-Signature header (HMAC-SHA256 of the raw request body, using the webhook secret, base64-encoded):

import crypto from 'node:crypto';

function verifyWebhook(rawBody: string, signatureHeader: string, webhookSecret: string) {
  const expected = crypto
    .createHmac('sha256', webhookSecret)
    .update(rawBody)
    .digest('base64');
  const expectedBuf = Buffer.from(expected);
  const gotBuf = Buffer.from(signatureHeader);
  if (expectedBuf.length !== gotBuf.length) return false;
  return crypto.timingSafeEqual(expectedBuf, gotBuf);
}

Full event list: ORDER_CREATED, ORDER_AWAITING_PAYMENT, ORDER_CONFIRMING, ORDER_EXECUTING, ORDER_COMPLETED, ORDER_ERROR, ORDER_REFUNDED, ORDER_EXPIRED.

REST API (for non-JS stacks)

Base URL: https://api.coinvoyage.io

MethodPathPurpose
POST/pay-ordersCreate PayOrder (DEPOSIT / SALE / REFUND)
GET/pay-orders/{id}Retrieve a PayOrder
GET/pay-ordersList PayOrders
POST/pay-orders/{id}/quoteGenerate payment route quote
GET/pay-orders/{id}/payment-methodsSupported payment options
POST/pay-orders/{id}/payment-detailsWallet address / tx data for buyer
GET / POST / PUT / DELETE/webhooks[/{id}]Manage webhooks
POST/swap/quoteSwap quote
POST/swap/dataSwap tx data
GET/fee-balancesMerchant's claimable fees
POST/fees/claimClaim accrued fees

Authorization header

Unauthenticated (public) requests and DEPOSIT PayOrder reads/creates:

Authorization: APIKey=<key>

Authenticated endpoints (SALE, REFUND, webhook management, fee claims):

Authorization: APIKey=<key>,signature=<sig>,timestamp=<unixSeconds>

Where <sig> = HMAC-SHA256(method + path + timestamp, apiSecret), hex-encoded. Timestamp is unix seconds. Request body is NOT included in the signature.

MCP server (bundled with this plugin)

This plugin bundles an MCP server so Claude can directly create and inspect PayOrders, manage webhooks, and get swap quotes inside any chat once the plugin is installed. Tools:

  • create_pay_order, get_pay_order, list_pay_orders
  • list_payment_methods, generate_quote, get_payment_details
  • list_webhooks, create_webhook, update_webhook, delete_webhook
  • get_swap_quote, get_swap_data
  • get_fee_balances, claim_fees
  • supported_chains (local reference, no API call)

Use these for: scaffolding a working integration, smoke-testing an API key, running a dry-run transaction, exploring the API conversationally, or generating webhook handlers wired to real event shapes.

Pricing

  • 1.5% platform fee per successful payment
  • 0% offramp fee
  • Merchants can add a custom percentage fee on top
  • Volume discounts: [email protected]

Security checklist when generating integration code

  • API secret ONLY on the server — never shipped client-side or committed to git
  • PayOrders created on the server; only payOrderId is passed to the client
  • Webhook signatures verified before trusting payment status
  • HTTPS required for webhook endpoints in production
  • API keys stored in environment variables (.env.local, deployment secrets), not in code
  • @coin-voyage/paykit pinned to a specific version in production dependencies
  • Webhook handler is idempotent (the same event may be delivered more than once)

Common integration patterns

  • Next.js App Router — server route creates the PayOrder, client component renders PaymentWidget with the returned ID
  • Express / Fastify / HonoPOST /api/pay creates order, returns ID; POST /api/webhooks/coinvoyage verifies signature and fulfills
  • SaaS subscription — create a DEPOSIT PayOrder per billing cycle; on ORDER_COMPLETED, extend the subscription
  • One-click donation — single static page that creates a PayOrder on load and renders the widget
  • Multi-tenant marketplace — one CoinVoyage org per seller; orchestrator creates PayOrders against each seller's API key