# Developer Quickstart

Use the PayChainHQ SDK or REST API from a trusted backend. Never expose API keys in browsers, mobile apps, static sites, or public client code.

{% hint style="danger" %}
**Important note:** PayChain API keys are backend secrets. Do not put them in frontend JavaScript, mobile apps, public GitHub repos, support screenshots, logs, or analytics tools.
{% endhint %}

{% hint style="info" %}
**Docs positioning:** The SDK is the fastest path for Node.js and TypeScript. REST examples are available in REST API guide and Payment flows.
{% endhint %}

### Install the SDK

```bash
npm install @paychainhq/sdk
```

```ts
import { PayChain } from '@paychainhq/sdk';

const paychain = new PayChain({
  apiKey: process.env.PAYCHAIN_API_KEY!,
  businessId: process.env.PAYCHAIN_BUSINESS_ID!,
  environment: 'live'
});
```

### Create a customer

```ts
const customer = await paychain.customers.create({
  externalRef: 'customer_123',
  email: 'payer@example.com'
});
```

### Create an invoice

{% hint style="info" %}
**Flow note:** This is the fixed amount invoice flow. For auto-detected payments, payout route invoices, dynamic payout recipients, and programmatic withdrawals, see Payment flows.
{% endhint %}

```ts
const invoice = await paychain.invoices.create(
  {
    amount: '100.00',
    token: 'USDC',
    chain: 'evm',
    networkId: 'base-mainnet',
    customerId: customer.id
  },
  { idempotencyKey: 'order_123_invoice' }
);
```

### Attach a payout route

```ts
await paychain.invoices.create(
  {
    amount: '100.00',
    token: 'USDC',
    chain: 'evm',
    networkId: 'base-mainnet',
    payoutRouteId: 'route_123'
  },
  { idempotencyKey: 'order_124_invoice' }
);
```

### Dynamic payout recipients

Dynamic recipients are for trusted backend payout automation, usually with a payout API key. The SDK accepts percentages and converts them to basis points for the API.

{% hint style="warning" %}
**Payout key note:** Dynamic payout recipients can move money after invoice settlement. Use a payout API key and apply your own order-level validation before sending destination addresses to PayChain.
{% endhint %}

```ts
await paychain.invoices.create(
  {
    amount: '100.00',
    token: 'USDC',
    chain: 'evm',
    networkId: 'base-mainnet',
    payoutRecipients: [
      { label: 'Seller', destinationAddress: '0x0000000000000000000000000000000000000000', percentage: 90 },
      { label: 'Platform', destinationAddress: '0x0000000000000000000000000000000000000000', percentage: 10 }
    ]
  },
  { idempotencyKey: 'order_125_invoice' }
);
```

### Verify webhooks

PayChain sends webhooks when an invoice, withdrawal, or routing event changes state. Your backend should verify every webhook before acting on it. Verification must use the raw request body, not parsed and re-stringified JSON. After verification, fetch the canonical invoice or withdrawal record before crediting a user, releasing an order, or marking a payout complete.

{% hint style="info" %}
**Webhook note:** A valid webhook tells you PayChain sent the event. Your fulfillment system should still fetch the canonical invoice or withdrawal before releasing value.
{% endhint %}

```ts
import { verifyWebhookSignature } from '@paychainhq/sdk';

const verified = verifyWebhookSignature({
  rawBody,
  signature: request.headers['x-webhook-signature'],
  secret: process.env.PAYCHAIN_WEBHOOK_SECRET!
});

if (!verified) {
  throw new Error('Invalid PayChain webhook signature');
}
```

### Read balances, transactions, networks, and tokens

Use balances to understand treasury availability, transactions to reconcile invoice and withdrawal activity, networks to discover supported rails, and tokens to confirm which assets can be accepted or withdrawn. Do not treat raw wallet balances as invoice truth. Invoice state and signed webhook events remain the source of truth for customer payments.

```ts
const balances = await paychain.balances.list();
const transactions = await paychain.transactions.list({ limit: 50 });
const networks = await paychain.networks.list();
const tokens = await paychain.tokens.list();
```

### Do not do this

* Do not ship API keys to browsers or mobile apps.
* Do not log SDK config, request headers, API keys, webhook secrets, or payout destination auth tokens.
* Do not disable webhook verification.
* Do not use standard API keys for withdrawals.
* Do not trust client-submitted payout destinations without your own validation.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.paychainhq.io/paychainhq-documentation-page/developer-quickstart.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
