> 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/telegram-bot-crypto-payments.md).

# Telegram bot crypto payments

Create payment links and webhook-driven bot actions.

Use this prompt to add CoinCircuit payments to Telegram bot commands, access gating, and renewals.

`Telegram` `Payments` `Webhooks` `Node.js`

### What this prompt covers

* Create payment sessions from bot actions
* Send hosted checkout links in chat
* Trigger bot behavior from payment webhooks

{% code title="telegram-bot-crypto-payments.prompt.md" expandable="true" collapsedlinecount="20" %}

````markdown
You are helping me integrate CoinCircuit crypto payments into my existing Telegram bot. 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` for the full payment session creation schema.
- Call `search_api` with query `webhook` and type `schemas` to list 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 existing Telegram bot and I want to add crypto payment support using CoinCircuit. The integration should:

1. Create a CoinCircuit payment session when a user wants to pay
2. Send the hosted checkout URL to the user in chat
3. Listen for payment confirmation via webhook
4. Trigger the appropriate action in my bot (grant access, deliver content, activate subscription, etc.)

This pattern works for any Telegram bot use case: subscription access, one-time purchases, premium features, tip jars, or pay-per-use commands.

## What I Need You to Implement

### 1. Create a payment session from a bot command

When a user triggers a payment (e.g. via a command or button callback), create a CoinCircuit payment session from your bot's backend:

**Endpoint:** `POST /api/v1/payments`
*(Call `get_endpoint` with method `post`, path `/api/v1/payments`, section `request` in the CoinCircuit MCP for the exact request body schema.)*

**Required fields:**
- `title` (string) - e.g. "Premium Channel - 30 Days"
- `description` (string) - e.g. "Subscription payment for premium access"
- `amount` (string) - subscription price as a string, e.g. `"9.99"`
- `currency` (string) - `"USD"` or `"NGN"`
- `customer` (object) - must include `email` (required). Include `telegramId` for linking.

**Optional fields:**
- `metadata` (object) - store `telegramUserId`, `telegramUsername`, `plan`, `channelId`, `subscriptionPeriodEnd` for webhook reconciliation
- `successUrl` (string) - redirect after payment (HTTPS)
- `cancelUrl` (string) - redirect if cancelled
- `webhookUrl` (string) - per-session webhook URL override (HTTPS)
- `asset` (string) - lock to a specific crypto: `"BTC"`, `"ETH"`, `"USDT"`, `"USDC"`, `"SOL"`, `"BNB"`, `"TRX"`
- `chain` (string) - lock to a specific blockchain: `"bitcoin"`, `"ethereum"`, `"solana"`, `"bsc"`, `"tron"`, `"base"`, `"arbitrum"`

**Example request body:**
```json
{
  "title": "Premium Channel - 30 Days",
  "description": "Subscription payment for premium Telegram access",
  "amount": "9.99",
  "currency": "USD",
  "customer": {
    "email": "user@example.com",
    "telegramId": "123456789"
  },
  "metadata": {
    "telegramUserId": "123456789",
    "telegramUsername": "johndoe",
    "plan": "premium-monthly",
    "channelId": "-1001234567890",
    "subscriptionPeriodEnd": "2026-04-30T23:59:59.000Z"
  },
  "successUrl": "https://mybot.com/subscription/success"
}
```

**Response (201):** Returns a session object. Key fields:
- `data.reference` - session reference (store this alongside the subscription)
- `data.url` - hosted checkout page URL. **Send this to the user via Telegram.**
- `data.payment.status` - starts as `"pending"`
- `data.expiresAt` - session expiration timestamp

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

### 2. Send checkout link to the user

After creating the session, send the `data.url` to the user in chat. The hosted checkout page handles crypto selection, address display, and payment detection automatically. No additional frontend work needed.

### 3. Webhook handler: process payment confirmation

Set up an endpoint to receive CoinCircuit webhooks. This is where your bot takes action after payment.

*(Call `get_schema` with name `PaymentCompletedWebhookDto` in the CoinCircuit MCP for the full payload.)*

**Payment events** (envelope: `{ event: string, data: { session: PaymentSession } }`):
- `payment.completed` - full payment confirmed. **This is your trigger to take action in your bot.**
  - Read `data.session.metadata.telegramUserId` to identify the user
  - Read `data.session.metadata` for any custom data you stored (plan, product, channel ID, etc.)
  - Execute your bot's logic: grant access, send a file, activate a feature, update a subscription, etc.
- `payment.expired` - session expired before payment. Optionally notify the user and offer a new session.
- `payment.partial` - customer sent crypto but not enough. The session stays open for more payments.
- `payment.underpaid` - session closed with less than the required amount. Check `data.session.payment.amountReceived` vs `data.session.payment.amount`. Handle accordingly (refund, manual review, etc.).

**Transaction events:**
- `transaction.received` - payment detected on-chain but unconfirmed. Optionally notify the user that payment was detected.
- `transaction.confirmed` - payment confirmed on the blockchain.

**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)

### 4. Track payment state

Store a record linking the CoinCircuit session to your bot's user:
- `telegramUserId`
- `sessionReference` - the CoinCircuit payment session reference
- `status` (`"pending"`, `"completed"`, `"expired"`)
- Any use-case-specific fields (subscription expiry, product ID, etc.)

This lets you look up payment status when a user asks, and lets your webhook handler find the right user to notify.

### 5. Recurring payments (if applicable)

For subscription-based flows, create a new payment session each billing cycle:

1. **Before expiry:** Send the user a renewal payment link
2. **On expiry:** If not renewed, revoke access or downgrade
3. **On renewal payment:** Update the subscription period

Store the `subscriptionPeriodEnd` in session metadata so your webhook handler knows the new expiry.

## Constraints

- Session `amount` is a **string** in fiat, not a number (e.g. `"9.99"`)
- Store the `telegramUserId` in both the session `metadata` and `customer.telegramId` for reconciliation
- Always verify webhook signatures before taking action
- Only act on `payment.completed`, not on partial or pending events
- `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/telegram-bot-crypto-payments.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.
