> For the complete documentation index, see [llms.txt](https://developers.coincircuit.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developers.coincircuit.io/promp-library/e-commerce-crypto-checkout.md).

# E-Commerce crypto checkout

Embedded checkout, session creation, and webhook-driven fulfillment.

Use this prompt to add CoinCircuit checkout to an existing e-commerce flow.

`Checkout SDK` `Webhooks` `Node.js`

### What this prompt covers

* Create a payment session on your server
* Launch embedded checkout or redirect to hosted checkout
* Fulfill orders from verified webhook events

{% code title="ecommerce-checkout.prompt.md" expandable="true" collapsedlinecount="20" %}

````markdown
You are helping me integrate CoinCircuit crypto payments into my existing e-commerce website. I have the CoinCircuit MCP server connected.

**If you have access to the CoinCircuit MCP server, call these tools for the most accurate and detailed schema outputs:**
- Call `get_api_overview` in the CoinCircuit MCP for base URLs, auth method, and available features.
- Call `get_endpoint` with method `post` and path `/api/v1/payments` to get the full request/response schema for creating payment sessions.
- Call `search_api` with query `webhook` and type `schemas` to get all webhook payload schemas.
- Call `get_schema` with name `PaymentCompletedWebhookDto` for the exact payment.completed webhook payload.
- Call `get_schema` with name `TransactionReceivedWebhookDto` for the transaction.received webhook payload.

Use the live MCP data as your source of truth. The details below are a guide, but if the MCP returns something different, trust the MCP.

## API Basics

- **Base URL (production):** `https://api.coincircuit.io`
- **Base URL (sandbox):** `https://sandbox-api.coincircuit.io`
- **Auth:** Pass your API key in the `x-api-key` header on every request.

## Project Context

I have an e-commerce site and I'm adding crypto payments at checkout using CoinCircuit. The flow:

1. Customer clicks "Pay with Crypto" on my checkout page
2. My server creates a CoinCircuit payment session via `POST /api/v1/payments`
3. The embedded checkout modal opens on the frontend using the session `reference`
4. Customer pays, my server gets a webhook, and the order is fulfilled

## What I Need You to Implement

### 1. Server-side: Create a payment session

**Endpoint:** `POST /api/v1/payments`
*(Call `get_endpoint` with method `post`, path `/api/v1/payments`, section `example` in the CoinCircuit MCP for a ready-to-use sample request.)*

**Required fields:**
- `title` (string) - e.g. "Order #1234"
- `description` (string) - e.g. "Payment for order #1234"
- `amount` (string) - fiat amount as a string, e.g. `"150.00"` (NOT a number)
- `currency` (string) - `"NGN"` or `"USD"`
- `customer` (object) - must include `email` (required). Optional: `firstName`, `lastName`, `phone` (E.164 format), `telegramId`

**Optional fields:**
- `asset` (string) - lock to a specific crypto: `"BTC"`, `"ETH"`, `"USDT"`, `"USDC"`, `"SOL"`, `"BNB"`, `"TRX"`. If omitted, the customer chooses on the checkout page.
- `chain` (string) - lock to a specific blockchain: `"bitcoin"`, `"ethereum"`, `"solana"`, `"bsc"`, `"tron"`, `"base"`, `"arbitrum"`. If omitted, the customer chooses.
- `metadata` (object) - store your internal `orderId` here for webhook reconciliation
- `successUrl` (string) - redirect after successful payment (must be HTTPS)
- `cancelUrl` (string) - redirect if customer cancels
- `webhookUrl` (string) - per-session webhook URL override (must be HTTPS)
- `feePaidBy` (string) - `"customer"` or `"merchant"`, controls who pays network gas fees. If omitted, uses your dashboard default.

**Example request body:**
```json
{
  "title": "Order #1234",
  "description": "2x Widget Pro",
  "amount": "150.00",
  "currency": "USD",
  "customer": {
    "email": "buyer@example.com",
    "firstName": "Jane",
    "lastName": "Smith"
  },
  "metadata": {
    "orderId": "ORD-1234",
    "items": "2x Widget Pro"
  },
  "successUrl": "https://mystore.com/order/1234/success",
  "cancelUrl": "https://mystore.com/cart"
}
```

**Response (201):** Returns a session object. The key fields you need:
- `data.reference` - pass this to the frontend checkout SDK
- `data.url` - hosted checkout page URL (e.g. `https://checkout.coincircuit.io/pay/cs_ref_abc123`)
- `data.payment.status` - starts as `"pending"`
- `data.payment.address` - the deposit address (if asset/chain were specified)
- `data.expiresAt` - ISO 8601 expiration timestamp

*(Call `get_endpoint` with method `post`, path `/api/v1/payments`, section `success` in the CoinCircuit MCP for the full response schema.)*

**Error responses:** 400 (invalid input or unsupported asset/chain combo), 401 (bad API key)

### 2. Client-side: Embedded checkout

Install the checkout SDK:

```bash
npm install @coincircuit/checkout
```

Use `CoinCircuitCheckout` to open a modal with the session `reference` from the server response. Handle these callbacks:
- `onPaymentComplete` - show success state, redirect to order confirmation
- `onPaymentFailed` - show error, offer retry
- `onClose` - user dismissed the modal without paying

**Alternative:** Skip the SDK entirely and redirect the customer to `data.url` from the session response. This is the hosted checkout page and requires zero frontend code.

### 3. Webhook handler: Order fulfillment

Set up an endpoint to receive CoinCircuit webhooks.

*(Call `search_api` with query `payment webhook` and type `schemas` in the CoinCircuit MCP to list all payment and transaction webhook schemas. Then call `get_schema` on any specific one for full field details.)*

**Payment events** (envelope: `{ event: string, data: { session: PaymentSession, failureReason?: string } }`):
- `payment.completed` - full payment confirmed. The `data.session` object contains the full session with `payment.status: "completed"`, `payment.amountReceived`, and a `transaction` object with `txHash`, `chain`, `asset`, `fromAddress`, `toAddress`, `amount`, `explorerUrl`, `confirmations`. **This is your trigger to fulfill the order.**
- `payment.partial` - customer sent crypto but not enough. `data.session.payment.amountReceived` shows what you got. The session stays open for more payments.
- `payment.expired` - session expired before full payment. Cancel or hold the order.
- `payment.underpaid` - session closed with less than the required amount. Check `data.session.payment.amountReceived` vs `data.session.payment.amount`.

*(Call `get_schema` with name `PaymentCompletedWebhookDto` in the CoinCircuit MCP for every field in the payment.completed payload.)*

**Transaction events** (envelope: `{ event: string, data: { session: PaymentSession } }`, the session includes a `transaction` field):
- `transaction.received` - payment detected on-chain but unconfirmed. Good for showing "payment detected" UI. The `transaction` object has `status: "pending"`, `txHash`, `chain`, `asset`, `amount`, `fromAddress`, `toAddress`.
- `transaction.confirmed` - payment confirmed on the blockchain. The `transaction` object has `status: "confirmed"`, `confirmations`, `confirmedAt`.

*(Call `get_schema` with name `TransactionReceivedWebhookDto` or `TransactionConfirmedWebhookDto` in the CoinCircuit MCP for exact field details.)*

**Webhook security:**
- Verify the HMAC-SHA256 signature in the `x-webhook-signature` header using your webhook secret
- Use the `x-delivery-id` header for idempotency (store processed delivery IDs and skip duplicates)

**Key webhook fields for reconciliation:**
- `data.session.reference` - matches the session you created
- `data.session.metadata` - your `orderId` is here
- `data.session.settlements.net.amount` - the amount you actually receive after all fees

## Constraints

- `amount` is a **string** in fiat, not a number
- Always verify webhook signatures before processing
- Store the session `reference` alongside the order for reconciliation
- Handle partial payments gracefully. If the session state is `"open"`, the customer can still make additional payments. If `"closed"`, no further payments are accepted.
- `successUrl` and `cancelUrl` must be HTTPS
- Supported currencies: NGN, USD. Supported assets: BTC, ETH, USDT, USDC, SOL, BNB, TRX. Supported chains: bitcoin, ethereum, solana, bsc, tron, base, arbitrum.
````

{% endcode %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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, and the optional `goal` query parameter:

```
GET https://developers.coincircuit.io/promp-library/e-commerce-crypto-checkout.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
