SDK reference

@arcora/sdk and @arcora/sdk-react — installation, types, and method-by-method walkthrough.

Packages

PackageUse it forVersion
@arcora/sdkBrowser or server-side invoice creation, hosted-checkout redirect, escrow listing1.2.0
@arcora/sdk-reactReact hook and one-click button that wrap the SDK for embedded checkout1.2.0

Webhook verification is signature-only and stays out of the SDK on purpose — three lines of crypto.createHmac work in any runtime; see /docs/webhooks for the snippet.

Two key types — publishable vs secret

KeyPrefixWhere it goesCapability
Publishablepk_live_…Browser / client code — safe to embedCreate a checkout from one of your allowlisted origins
Secretak_live_…Server-side only — never ship to the browserEverything: create invoices, list escrows, read private invoice data

Anyone who loads your page can read a key embedded in it. Embed only the publishable key in browser code; keep the secretkey on your server. Privileged reads like escrows() require the secret key and only work server-side. Both keys are shown in /m/settings; set your allowed origins there so publishable-key checkouts are accepted.

@arcora/sdk

new Arcora(options)

import { Arcora } from '@arcora/sdk';

const arcora = new Arcora({
  apiKey:      string,                     // required — publishable pk_live_… in the browser, secret ak_live_… on a server
  environment?: 'testnet' | 'mainnet',    // default 'testnet'; selects the base URL
  baseUrl?:    string,                     // override for self-hosted deployments
});

The legacy Arcora.init(...) / Arcora.createInvoice(...) singleton API is still exported for the CDN bundle but tagged @deprecated — use the instance API for any new code so multiple merchants in one process can't cross-contaminate state.

arcora.createInvoice(params)

const invoice = await arcora.createInvoice({
  amountUsdc: number,                      // gross amount in USD-equivalent (1 = $1.00)
  payInToken: 'USDC' | 'EURC',             // what the customer will pay with
  successUrl:  string,                     // required — http(s) where to send the customer after payment
  cancelUrl?:  string,                     // http(s) — same allowlist + SSRF guard
  metadata?:   Record<string, string>,     // attached to invoice + webhook payloads
});

// Returns:
// { invoiceId: '0x…',
//   url:       'https://arcorapay.xyz/i/0x…',
//   claimableAt?: '2026-05-20T…' }       // custody escrow — populated once the invoice is paid

Throws ArcoraError with a typed code on validation, network, server, or auth failures. Invalid amountUsdc (non-finite, ≤0) is rejected client-side before the request fires. A missing or non-http(s) successUrl is likewise rejected client-side with INVALID_URL.

Note: the SDK requires successUrl. Standalone invoices (no redirect — the invoice page just shows the paid status) are possible only by calling the raw REST endpoint POST /api/invoices directly, where successUrl is optional.

arcora.openCheckout(invoice)

arcora.openCheckout(invoice);
// equivalent to window.location.href = invoice.url
// browser-only; throws in Node

arcora.escrows()

const { pending, matured, claimed } = await arcora.escrows();
// pending: paid invoices still within the 7-day refund window
// matured: paid, window elapsed, ready to claim()
// claimed: already withdrawn to the merchant payout wallet

Server-side only — requires your secret ak_live_ key. Calling escrows() with a publishable key throws PUBLISHABLE_KEY_FORBIDDEN without making a request. Authenticated against the merchant whose apiKey the instance was constructed with. Three buckets cap at 200 rows each; a truncated flag tells the caller when to narrow filters.

Errors

import { Arcora, ArcoraError } from '@arcora/sdk';

try {
  await arcora.createInvoice({ amountUsdc: 49.99, payInToken: 'EURC', successUrl: '...' });
} catch (e) {
  if (e instanceof ArcoraError) {
    // e.code is one of: 'INVALID_API_KEY' | 'NETWORK' | 'SERVER_ERROR'
    //                   | 'INVALID_URL'    | 'TIMEOUT' | 'NO_SECURE_RANDOM'
    //                   | 'PUBLISHABLE_KEY_FORBIDDEN' | 'UNKNOWN'
    // e.retryAfter (seconds) is set on SERVER_ERROR when the server returned Retry-After
  }
}

@arcora/sdk-react

useCheckout(options)

import { useCheckout } from '@arcora/sdk-react';

function PayButton() {
  const { checkout, loading, error, refundEndsAt } = useCheckout({
    apiKey: process.env.NEXT_PUBLIC_ARCORA_PUBLISHABLE_KEY!, // pk_live_… — safe to inline in the browser
    environment: 'testnet',
  });

  return (
    <button onClick={() => checkout({
      amountUsdc: 4.50,
      payInToken: 'EURC',
      successUrl: window.location.origin + '/orders/done',
    })} disabled={loading}>
      {loading ? 'Loading…' : 'Pay €4.50'}
    </button>
  );
}

checkout(params) creates the invoice and immediately redirects via window.location.href.refundEndsAt populates once the invoice is paid — useful for showing the customer when the refund window closes.

<CheckoutButton />

import { CheckoutButton } from '@arcora/sdk-react';

<CheckoutButton
  apiKey={process.env.NEXT_PUBLIC_ARCORA_PUBLISHABLE_KEY!}
  environment="testnet"
  invoice={{ amountUsdc: 49.99, payInToken: 'EURC', successUrl: '...' }}
  className="btn-primary"
>
  Pay $49.99
</CheckoutButton>

Thin wrapper around useCheckout. Renders a native <button>; bring your own styling. The button auto-disables while the invoice is being created.

Types

Full type definitions ship in the package's dist/index.d.ts: Arcora,ArcoraError, CreateInvoiceParams, Invoice, EscrowSummary,InitOptions, Environment, PayInToken. The contract ABI is also re-exported as gatewayAbi / GATEWAY_ABI for callers building their own viem clients.