### Install the SDK Source: https://docs.coinvoyage.io/quickstart Install @coin-voyage/paykit and its required peer dependency @tanstack/react-query. ```bash npm i @coin-voyage/paykit @tanstack/react-query@^5.90.6 ``` ```bash pnpm add @coin-voyage/paykit @tanstack/react-query@^5.90.6 ``` ```bash yarn add @coin-voyage/paykit @tanstack/react-query@^5.90.6 ``` ```bash bun add @coin-voyage/paykit @tanstack/react-query@^5.90.6 ``` -------------------------------- ### Render a PayButton Source: https://docs.coinvoyage.io/quickstart Add anywhere in your app to launch the CoinVoyage payment modal. The example below creates a deposit button that settles 10 SUI to your specified wallet. ```tsx "use client"; import { PayButton } from "@coin-voyage/paykit"; import { ChainId } from "@coin-voyage/paykit/server"; export function DepositButton() { return ( console.log("Payment started")} onPaymentCompleted={() => console.log("Payment completed")} /> ); } ``` -------------------------------- ### Add the providers Source: https://docs.coinvoyage.io/quickstart Wrap your app with QueryClientProvider, WalletProvider, and PayKitProvider. In a Next.js app, create a providers.tsx file. ```tsx "use client"; import { PayKitProvider, WalletProvider } from "@coin-voyage/paykit"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; const queryClient = new QueryClient(); export function Providers({ children }: { children: React.ReactNode }) { if (!process.env.NEXT_PUBLIC_COIN_VOYAGE_API_KEY) { throw new Error("NEXT_PUBLIC_COIN_VOYAGE_API_KEY is required"); } return ( {children} ); } ``` ```tsx import { Providers } from "./providers"; export default function RootLayout({ children }: { children: React.ReactNode }) { return ( {children} ); } ``` -------------------------------- ### Recommended provider setup Source: https://docs.coinvoyage.io/sdk/overview A typical provider tree looks like this. ```tsx "use client"; import { PayKitProvider, WalletProvider } from "@coin-voyage/paykit"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; const queryClient = new QueryClient(); export function Providers({ children }: { children: React.ReactNode }) { return ( {children} ); } ``` -------------------------------- ### Install the SDK Source: https://docs.coinvoyage.io/ Install the CoinVoyage paykit SDK for React applications. ```bash npm install @coin-voyage/paykit ``` -------------------------------- ### PayKitProvider Setup Source: https://docs.coinvoyage.io/sdk/paykitprovider Example of setting up PayKitProvider within WalletProvider and QueryClientProvider, including essential configuration like apiKey, debugMode, mode, onConnect, and environment. ```tsx "use client"; import { PayKitProvider, WalletProvider } from "@coin-voyage/paykit"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; const queryClient = new QueryClient(); export function Providers({ children }: { children: React.ReactNode }) { return ( { console.log( `Connected to ${chainId} with ${connectorId} (${type}) at ${address}` ); }} environment="production" > {children} ); } ``` -------------------------------- ### Example with options Source: https://docs.coinvoyage.io/sdk/paykitprovider An example demonstrating how to use the PayKitProvider with various options configured. ```tsx { console.log(`Wallet ${address} connected on chain ${chainId}`); }} onDisconnect={() => { console.log("Wallet disconnected"); }} > {children} ``` -------------------------------- ### Full example Source: https://docs.coinvoyage.io/sdk/paybutton This example demonstrates how to use the PayButton component with various props to configure payment details, appearance, and event handlers. ```tsx import { PayButton } from "@coin-voyage/paykit"; import { ChainId } from "@coin-voyage/paykit/server"; { console.log("Modal Opened"); }} onClose={() => { console.log("Modal Closed"); }} closeOnSuccess={true} onPaymentCreationError={(event) => { console.log(event.errorMessage); }} onPaymentStarted={() => { console.log("Payment Started"); }} onPaymentCompleted={() => { console.log("Payment Complete"); }} onPaymentBounced={() => { console.error("Payment Bounced"); }} /> ``` -------------------------------- ### Error Response Example Source: https://docs.coinvoyage.io/api-reference/websocket/order-status-websocket Example of an error response structure from the API. ```json { "code": 400, "error": "Bad Request", "message": "Invalid request parameters" } ``` -------------------------------- ### PayOrder Metadata Example: Items Source: https://docs.coinvoyage.io/concepts/pay-orders An example of how to structure the 'items' array within the PayOrder metadata to describe products or services being paid for. ```typescript metadata: { items: [ { name: "Annual subscription", description: "Pro plan — 12 months", quantity: 1, unit_price: 199, currency: "USD", }, ], } ``` -------------------------------- ### PayOrder Metadata Example: Refund Details Source: https://docs.coinvoyage.io/concepts/pay-orders An example of how to populate the 'refund' object in PayOrder metadata for refund transactions. ```typescript metadata: { refund: { reason: "Item damaged in shipping", refund_amount: 49.99, currency: "USD", }, } ``` -------------------------------- ### Minimal setup Source: https://docs.coinvoyage.io/sdk/walletprovider Use WalletProvider with no configuration when the SDK defaults are sufficient. ```tsx {children} ``` -------------------------------- ### PayButton.Custom Usage Example Source: https://docs.coinvoyage.io/sdk/paybutton This example demonstrates how to use PayButton.Custom with a render prop to control the payment modal's visibility from a custom button. ```tsx import { PayButton } from "@coin-voyage/paykit"; { console.log("Payment started", event); }} onPaymentCompleted={(event) => { console.log("Payment completed", event); }} > {({ show, hide }) => ( )} ``` -------------------------------- ### PayOrder Metadata Example: Custom Fields Source: https://docs.coinvoyage.io/concepts/pay-orders An example demonstrating the use of custom top-level fields within PayOrder metadata for additional data like customer IDs or order references. ```typescript metadata: { items: [{ name: "Premium plan" }], customer_id: "cust_12345", order_reference: "ORD-2024-001", campaign: "summer_sale", } ``` -------------------------------- ### Create Sale PayOrder (Settling to Dashboard Currency) Source: https://docs.coinvoyage.io/concepts/pay-orders Example of creating a SALE PayOrder for merchant payments. This example settles to the organization's configured settlement currency in the dashboard. ```typescript const apiSecret = process.env.COIN_VOYAGE_API_SECRET!; // Settle to your dashboard settlement currency const { data, error } = await apiClient.createSalePayOrder( { intent: { amount: { fiat: { amount: 200, unit: "USD", }, }, }, metadata: { items: [ { name: "t-shirt", description: "A nice t-shirt", image: "https://example.com/tshirt.jpg", quantity: 1, unit_price: 200, currency: "USD", }, ], }, }, apiSecret ); ``` -------------------------------- ### OpenAPI Specification Source: https://docs.coinvoyage.io/api-reference/fees/get-fee-balances OpenAPI specification for the Get Fee Balances endpoint. ```yaml openapi: 3.1.0 info: title: CoinVoyage API description: Cryptocurrency payment processing API version: 2.2.0 servers: - url: http://localhost:8000/v2 security: [] paths: /fees/balance: get: tags: - fees summary: Get Fee Balances description: Retrieve the claimable fee balances for the authenticated organization operationId: getFeeBalances parameters: - description: >- Authorization header format: 'APIKey=,signature=,timestamp=' in: header name: Authorization-Signature required: true schema: type: string responses: '200': content: application/json: schema: $ref: '#/components/schemas/GetFeeBalancesResponse' description: Fee balances retrieved successfully '401': content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' description: Unauthorized - Authentication required '500': content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' description: Internal Server Error security: - Authorization: [] components: schemas: GetFeeBalancesResponse: example: amount_cents: 150 fiat: USD properties: fiat: $ref: '#/components/schemas/Fiat' example: USD amount_cents: example: 150 format: int64 type: integer required: - fiat - amount_cents type: object ErrorResponse: example: code: 400 error: Bad Request message: Invalid request parameters properties: error: example: Bad Request type: string message: example: Invalid request parameters type: string code: example: 400 format: int64 type: integer details: anyOf: - type: string - type: number - type: object required: - error - message - code type: object Fiat: enum: - USD - EUR type: string ``` -------------------------------- ### Get PayOrder OpenAPI Specification Source: https://docs.coinvoyage.io/api-reference/pay-orders/get-payorder This OpenAPI 3.1.0 specification details the GET /pay-orders/{payorder_id} endpoint, including request parameters, authentication, and response schemas for PayOrder details, errors, and component schemas. ```yaml openapi: 3.1.0 info: title: CoinVoyage API description: Cryptocurrency payment processing API version: 2.2.0 servers: - url: http://localhost:8000/v2 security: [] paths: /pay-orders/{payorder_id}: get: tags: - pay-orders summary: Get PayOrder description: Retrieve details of a specific PayOrder operationId: getPayOrder parameters: - description: API key for authentication in: header name: X-API-KEY required: true schema: type: string - in: path name: payorder_id required: true schema: type: string responses: '200': content: application/json: schema: $ref: '#/components/schemas/PayOrderResponse' description: PayOrder details '401': content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' description: Unauthorized - Authentication required '404': content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' description: Not Found - PayOrder not found '500': content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' description: Internal Server Error security: - APIKeyHeader: [] components: schemas: PayOrderResponse: example: created_at: '2023-01-01T00:00:00Z' fulfillment: amount: raw_amount: '2400000' ui_amount: 2.4 ui_amount_display: '2.4' value_usd: 123.45 asset: address: EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v chain_id: 30000000000001 decimals: 6 id: EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v image_uri: >- https://raw.githubusercontent.com/solana-labs/token-list/main/assets/mainnet/EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v/logo.png name: USD Coin price_usd: 1 ticker: USDC swap: requested_destination_currency: address: EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v chain_id: 30000000000001 requested_source_currency: address: EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v chain_id: 30000000000001 hosted_url: https://pay.coinvoyage.io/pay/cuidjkhg3e289y74u5t6v id: cuidjkhg3e289y74u5t6v metadata: items: - currency: USD description: High-quality widget with extra features image: https://example.com/images/widget.png name: Premium Widget quantity: 2 unit_price: 49.99 refund: additional_info: Item was never shipped currency: USD name: Order Cancellation reason: Customer requested refund refund_amount: 99.98 mode: DEPOSIT organization_id: org_1234567890abcdef payment: destination_tx_hash: 0x5678...efgh dst: address: EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v chain_id: 30000000000001 currency_amount: raw_amount: '2400000' ui_amount: 2.4 ui_amount_display: '2.4' value_usd: 123.45 decimals: 6 id: EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v image_uri: >- https://raw.githubusercontent.com/solana-labs/token-list/main/assets/mainnet/EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v/logo.png name: USD Coin price_usd: 1 ticker: USDC expires_at: '2025-11-03T12:30:00Z' fee_tx_hash: 0xfee1...fee2 payment_rail: CRYPTO receiving_address: 9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM refund_address: 7xVt9ovu6g6E4gvz9K9eV4kxY7yQZ8h3kZ2vY8xZ7xVt refund_tx_hash: 0x9abc...ijkl refunded_reason: 'execution failed: provider error' source_tx_hash: 0x1234...abcd src: address: EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v base: raw_amount: '2400000' ui_amount: 2.4 ui_amount_display: '2.4' value_usd: 123.45 chain_id: 30000000000001 currency_amount: raw_amount: '2400000' ui_amount: 2.4 ui_amount_display: '2.4' value_usd: 123.45 decimals: 6 fees: custom_fee: raw_amount: '2400000' ui_amount: 2.4 ui_amount_display: '2.4' ``` -------------------------------- ### Generate Authorization Signature using CoinVoyage PayKit SDK Source: https://docs.coinvoyage.io/resources/faqs Example of generating an Authorization signature using the CoinVoyage PayKit SDK. ```typescript const signature = apiClient.generateAuthorizationSignature( process.env.COIN_VOYAGE_API_SECRET!, "POST", "/pay-orders" ); ``` -------------------------------- ### WalletProvider Setup Source: https://docs.coinvoyage.io/sdk/walletprovider Configure WalletProvider with chain-specific settings for EVM, Solana, Sui, and UTXO wallets including RPC URLs, adapters, and connectors. ```tsx "use client"; import { PayKitProvider, WalletProvider } from "@coin-voyage/paykit"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; const queryClient = new QueryClient(); export function Providers({ children }: { children: React.ReactNode }) { return ( {children} ); } ``` -------------------------------- ### Manual Authorization Signature Generation Source: https://docs.coinvoyage.io/resources/faqs Manual implementation for generating an Authorization signature using Node.js crypto module. ```typescript import { createHmac } from "crypto"; function generateAuthorizationSignature( apiKey: string, apiSecret: string, method: string, path: string ): string { const timestamp = Math.floor(Date.now() / 1000).toString(); const data = `${method}${path}${timestamp}`; const signature = createHmac("sha256", apiSecret).update(data).digest("hex"); return `APIKey=${apiKey},signature=${signature},timestamp=${timestamp}`; } ``` -------------------------------- ### Get Swap Quote OpenAPI Specification Source: https://docs.coinvoyage.io/api-reference/swap/get-swap-quote The OpenAPI 3.1.0 specification for the POST /swap/quote endpoint, detailing parameters, request body, and responses. ```yaml openapi: 3.1.0 info: title: CoinVoyage API description: Cryptocurrency payment processing API version: 2.2.0 servers: - url: http://localhost:8000/v2 security: [] paths: /swap/quote: post: tags: - swap summary: Get Swap Quote description: Get a quote for swapping between two currencies operationId: swapQuote parameters: - description: API key for authentication in: header name: X-API-KEY required: true schema: type: string requestBody: content: application/json: schema: $ref: '#/components/schemas/SwapQuoteRequest' required: true responses: '200': content: application/json: schema: $ref: '#/components/schemas/SwapQuoteResponse' description: Swap quote retrieved successfully '401': content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' description: Unauthorized - Authentication required '403': content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' description: Forbidden - Card payments are not enabled '422': content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' description: >- Unprocessable Entity - Invalid request body format, missing source currency, or unsupported Stripe onramp region '500': content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' description: Internal Server Error security: - APIKeyHeader: [] components: schemas: SwapQuoteRequest: example: intent: amount: '100.0' crypto: sender_address: 0x1234...abcd slippage_bps: 50 source_currency: address: EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v chain_id: 30000000000001 destination_currency: address: EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v chain_id: 30000000000001 payment_rail: CRYPTO receiving_address: 9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM source_currency: address: EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v chain_id: 30000000000001 swap_mode: ExactIn metadata: items: - currency: USD description: High-quality widget with extra features image: https://example.com/images/widget.png name: Premium Widget quantity: 2 unit_price: 49.99 refund: additional_info: Item was never shipped currency: USD name: Order Cancellation reason: Customer requested refund refund_amount: 99.98 properties: metadata: anyOf: - $ref: '#/components/schemas/OrderMetadata' - type: 'null' intent: $ref: '#/components/schemas/SwapIntent' required: - intent type: object SwapQuoteResponse: example: input: address: EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v balance: raw_amount: '2400000' ui_amount: 2.4 ui_amount_display: '2.4' value_usd: 123.45 base: raw_amount: '2400000' ui_amount: 2.4 ui_amount_display: '2.4' value_usd: 123.45 chain_id: 30000000000001 currency_amount: raw_amount: '2400000' ui_amount: 2.4 ui_amount_display: '2.4' value_usd: 123.45 decimals: 6 fees: custom_fee: raw_amount: '2400000' ui_amount: 2.4 ui_amount_display: '2.4' value_usd: 123.45 protocol_fee: raw_amount: '2400000' ui_amount: 2.4 ui_amount_display: '2.4' value_usd: 123.45 relayer_fee: raw_amount: '2400000' ui_amount: 2.4 ui_amount_display: '2.4' value_usd: 123.45 total_fee: raw_amount: '2400000' ui_amount: 2.4 ui_amount_display: '2.4' value_usd: 123.45 gas: raw_amount: '2400000' ui_amount: 2.4 ui_amount_display: '2.4' value_usd: 123.45 id: EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v image_uri: >- ``` -------------------------------- ### Create Deposit PayOrder Source: https://docs.coinvoyage.io/concepts/how-it-works Example of creating a deposit PayOrder using the CoinVoyage SDK, specifying the destination chain, asset, and amount. ```typescript const payOrder = await apiClient.createDepositPayOrder({ intent: { asset: { chain_id: ChainId.SUI, address: null, // null = native token (SUI) }, amount: { token_amount: 10, // 10 SUI }, receiving_address: "0xYourWalletAddress", }, }); ``` -------------------------------- ### PaymentData Structure Example Source: https://docs.coinvoyage.io/webhooks/events An example JSON object representing the PaymentData structure, detailing source and destination amounts, addresses, transaction hashes, and execution information. ```json { "src": { "total": { }, "base": { }, "fees": { }, "gas": { } }, "dst": { "currency": { }, "currency_amount": { } }, "deposit_address": "0x...", "receiving_address": "0x...", "refund_address": "0x...", "source_tx_hash": "0x...", "destination_tx_hash": "0x...", "refund_tx_hash": "0x...", "execution": [ { "provider": "...", "status": "..." } ], "expires_at": "2025-01-15T11:00:00Z" } ``` -------------------------------- ### Provider Chaining Example Source: https://docs.coinvoyage.io/concepts/how-it-works Illustrates a multi-step process where CoinVoyage chains providers to convert ETH on Ethereum to SUI on Sui. ```text Step 1: User pays ETH on Ethereum | Step 2: Uniswap swaps ETH → USDC (on Ethereum) | Step 3: CCTP transfers USDC from Ethereum → Sui | Step 4: Sui DEX swaps USDC → SUI | Step 5: SUI delivered to your wallet ``` -------------------------------- ### OpenAPI Specification for Get Payment Details Source: https://docs.coinvoyage.io/api-reference/pay-orders/get-payment-details This OpenAPI 3.1.0 specification defines the POST /pay-orders/{payorder_id}/payment-details endpoint, including request parameters, request body schema, and possible responses with their schemas. ```yaml openapi: 3.1.0 info: title: CoinVoyage API description: Cryptocurrency payment processing API version: 2.2.0 servers: - url: http://localhost:8000/v2 security: [] paths: /pay-orders/{payorder_id}/payment-details: post: tags: - pay-orders summary: Get Payment Details description: Get payment details for a PayOrder operationId: payOrder-paymentDetails parameters: - description: API key for authentication in: header name: X-API-KEY required: true schema: type: string - in: path name: payorder_id required: true schema: type: string requestBody: content: application/json: schema: $ref: '#/components/schemas/PaymentDetailsRequest' required: true responses: '200': content: application/json: schema: $ref: '#/components/schemas/PaymentDetailsResponse' description: Payment details '400': content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' description: >- Bad Request - Invalid request body format or quote ID not found or expired '401': content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' description: Unauthorized - Authentication required '403': content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' description: Forbidden - Card payments are not enabled '404': content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' description: Not Found - PayOrder not found '422': content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' description: >- Unprocessable Entity - Invalid pay order status, request validation failed, or source currency could not be determined '500': content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' description: Internal Server Error security: - APIKeyHeader: [] components: schemas: PaymentDetailsRequest: example: payment_rail: FIAT source_currency: address: EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v chain_id: 30000000000001 properties: source_currency: anyOf: - $ref: '#/components/schemas/CurrencyBase' - type: 'null' refund_address: type: - string - 'null' quote_id: type: - string - 'null' payment_rail: $ref: '#/components/schemas/PaymentRail' example: FIAT type: object PaymentDetailsResponse: example: data: destination_tx_hash: 0x5678...efgh dst: address: EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v chain_id: 30000000000001 currency_amount: raw_amount: '2400000' ui_amount: 2.4 ui_amount_display: '2.4' value_usd: 123.45 decimals: 6 id: EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v image_uri: >- https://raw.githubusercontent.com/solana-labs/token-list/main/assets/mainnet/EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v/logo.png name: USD Coin price_usd: 1 ticker: USDC expires_at: '2025-11-03T12:30:00Z' fee_tx_hash: 0xfee1...fee2 payment_rail: CRYPTO receiving_address: 9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM refund_address: 7xVt9ovu6g6E4gvz9K9eV4kxY7yQZ8h3kZ2vY8xZ7xVt refund_tx_hash: 0x9abc...ijkl refunded_reason: 'execution failed: provider error' source_tx_hash: 0x1234...abcd src: address: EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v base: raw_amount: '2400000' ui_amount: 2.4 ui_amount_display: '2.4' value_usd: 123.45 chain_id: 30000000000001 currency_amount: raw_amount: '2400000' ui_amount: 2.4 ui_amount_display: '2.4' value_usd: 123.45 decimals: 6 fees: custom_fee: raw_amount: '2400000' ui_amount: 2.4 ui_amount_display: '2.4' ```