Skip to main content

Products and Checkout

This section covers the core Hilt payment surface: merchant-managed products, hosted checkout, identity connect, payment confirmation, and public payment state.

Vocabulary bridge:

  • dashboard wording: templates
  • API and CLI wording: products

They are the same merchant object.

Product object model

The create and update routes use the same main fields:

  • product_type
  • title
  • description
  • image_url
  • fixed_amount_lamports
  • token_mint
  • merchant_wallet
  • delivery_type
  • delivery_value
  • tip_presets_lamports
  • max_payments
  • membership_config

Important note:

  • fixed_amount_lamports is a legacy field name
  • Hilt interprets it using the selected asset’s minor unit
  • for SOL, that means lamports
  • for USDC, that means base units with 6 decimals

Merchant product routes

Create a product

POST /v1/products
X-Hilt-Key: hk_live_...
Content-Type: application/json

Example: Telegram membership product

{
"product_type": "PAYMENT_LINK",
"title": "Telegram Inner Circle",
"description": "Monthly paid access",
"image_url": "https://cdn.example.com/cover.png",
"fixed_amount_lamports": 29000000,
"token_mint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
"merchant_wallet": "So1anaMerchantWallet1111111111111111111111111",
"delivery_type": "TELEGRAM_INVITE",
"delivery_value": "https://t.me/+privateinvite",
"max_payments": 500,
"membership_config": {
"enabled": true,
"platform": "TELEGRAM",
"access_mode": "INVITE_LINK",
"identity_type": "TELEGRAM_USER_ID",
"identity_label": "Telegram username or user ID",
"identity_required": true,
"billing_interval_days": 30,
"grace_period_days": 3,
"renewal_reminder_offsets_days": [7, 2, 1],
"platform_target_label": "Private Telegram Group"
}
}

Common failures:

  • 400 unsupported product_type or missing fixed amount for PAYMENT_LINK
  • 422 invalid wallet address or invalid membership settings
  • 503 feature disabled or pricing/oracle dependency unavailable

List products

GET /v1/products?status=ACTIVE&product_type=PAYMENT_LINK&limit=20&offset=0

Get a product

GET /v1/products/{product_id}

Update a product

PATCH /v1/products/{product_id}
Content-Type: application/json
{
"title": "Telegram Inner Circle",
"description": "Updated description",
"image_url": "https://cdn.example.com/new-cover.png",
"delivery_value": "https://t.me/+updatedinvite",
"membership_config": {
"billing_interval_days": 30,
"grace_period_days": 5
}
}

Archive a product

DELETE /v1/products/{product_id}

Product payments and analytics

GET /v1/products/{product_id}/payments
GET /v1/products/{product_id}/analytics

Use these to inspect payment history and product-level performance without going through the dashboard.

Public hosted checkout routes

Get a public checkout payload

GET /v1/products/p/{slug}

Representative response:

{
"id": "uuid",
"slug": "telegram01",
"title": "Telegram Inner Circle",
"description": "Monthly paid access",
"image_url": "https://cdn.example.com/cover.png",
"fixed_amount_lamports": 29000000,
"token_mint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
"merchant_wallet": "So1anaMerchantWallet1111111111111111111111111",
"delivery_type": "TELEGRAM_INVITE",
"payment_count": 12,
"checkout_config": {
"default_route": "phantom",
"payment_asset": "USDC",
"payment_chain": "SOLANA",
"branding": {
"merchant_name": "Example Merchant",
"logo_url": "https://cdn.example.com/logo.png",
"hero_image_url": "https://cdn.example.com/hero.png",
"success_button_label": "Join Telegram",
"accent_hex": "#1d4ed8"
},
"identity_connect": {
"telegram_bot_username": "HiltConnectBot",
"discord_connect_url": "https://api.hilt.so/v1/products/p/telegram01/discord-connect/start"
}
}
}

Start a checkout session

POST /v1/products/p/{slug}/connect
Content-Type: application/json

Minimal request:

{
"payer_wallet": "BuyerWallet1111111111111111111111111111111111"
}

Request with buyer reference:

{
"payer_wallet": "BuyerWallet1111111111111111111111111111111111",
"customer_reference_type": "TELEGRAM_USER_ID",
"customer_reference_value": "728255790",
"customer_reference_display": "@crzypeas"
}

Representative response:

{
"payment_id": "uuid",
"nonce": "hex_nonce",
"amount_minor_units": 200000,
"merchant_amount_minor_units": 199800,
"fee_minor_units": 200,
"fee_wallet": "HiltTreasuryWallet11111111111111111111111111",
"token_mint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
"asset_symbol": "USDC",
"asset_decimals": 6,
"merchant_wallet": "So1anaMerchantWallet1111111111111111111111111",
"expires_at": "2026-04-14T12:30:00+00:00",
"status": "PENDING_SIGNATURE",
"phantom_mobile": {
"connect_url": "https://phantom.app/ul/...",
"dapp_public_key": "..."
}
}

The important fields are:

  • payment_id
  • merchant_amount_minor_units
  • fee_minor_units
  • merchant_wallet
  • fee_wallet
  • expires_at

Resolve a signed buyer handoff

POST /v1/products/p/{slug}/resolve-handoff
Content-Type: application/json
{
"handoff_token": "SIGNED_HANDOFF_TOKEN"
}

This is used when a Telegram bot, Discord OAuth flow, or merchant backend already knows who the buyer is before checkout loads.

Create a signed buyer handoff from the merchant API

POST /v1/products/{product_id}/handoff-link
X-Hilt-Key: hk_live_...
Content-Type: application/json
{
"identity_value": "728255790",
"identity_display": "@crzypeas",
"identity_type": "TELEGRAM_USER_ID",
"expires_in_minutes": 30
}

Successful response:

{
"handoff_token": "SIGNED_TOKEN",
"expires_at": "2026-04-14T12:45:00+00:00",
"checkout_url": "https://www.hilt.so/p/telegram01?handoff=SIGNED_TOKEN",
"product_id": "uuid",
"slug": "telegram01"
}

Checkout identity routes

These are used when the buyer must prove that a wallet is paying for a specific Telegram, Discord, or merchant-defined identity.

Start identity handshake

POST /v1/pay/identity/start
Content-Type: application/json
{
"slug": "telegram01",
"wallet_address": "BuyerWallet1111111111111111111111111111111111",
"wallet_source": "EXTERNAL_PHANTOM",
"customer_reference_type": "TELEGRAM_USER_ID",
"customer_reference_value": "728255790",
"customer_reference_display": "@crzypeas"
}

Successful response:

{
"session_id": "uuid",
"status": "PENDING",
"wallet_address": "BuyerWallet1111111111111111111111111111111111",
"wallet_source": "EXTERNAL_PHANTOM",
"identity_type": "TELEGRAM_USER_ID",
"identity_value": "728255790",
"identity_display": "@crzypeas",
"challenge_message": "Sign this message to verify your wallet...",
"expires_at": "2026-04-14T12:10:00+00:00"
}

Complete identity handshake

POST /v1/pay/identity/complete
Content-Type: application/json
{
"session_id": "uuid",
"wallet_address": "BuyerWallet1111111111111111111111111111111111",
"signed_message_b64": "BASE64_SIGNATURE"
}

Payment execution routes

Record a broadcast transaction

POST /v1/pay/broadcast
Content-Type: application/json
{
"payment_id": "uuid",
"tx_signature": "5zLCm5rz1gJaGgEU97UtWDxPmk4uuhoVQETQ4ukdzEqxYuM2igczQ6JbdZeZSeT9opxjqDWnni47KTPrttQ2epkz",
"payer_wallet": "BuyerWallet1111111111111111111111111111111111",
"wallet_source": "EXTERNAL_PHANTOM"
}

Successful response:

{
"payment_id": "uuid",
"status": "PENDING_CONFIRMATION",
"tx_signature": "5zLCm5..."
}

Confirm a payment

POST /v1/pay/confirm
Content-Type: application/json
{
"payment_id": "uuid",
"slug": "telegram01",
"tx_signature": "5zLCm5...",
"payer_wallet": "BuyerWallet1111111111111111111111111111111111",
"identity_session_id": "uuid",
"customer_reference_type": "TELEGRAM_USER_ID",
"customer_reference_value": "728255790",
"customer_reference_display": "@crzypeas"
}

Successful response:

{
"status": "confirmed",
"payment_id": "uuid",
"delivery_type": "TELEGRAM_INVITE",
"delivery_value": "https://t.me/+privateinvite",
"amount_lamports": 200000,
"delivery_status": "SENT",
"membership_id": "uuid",
"membership_status": "ACTIVE",
"membership_period_end_at": "2026-05-14T12:00:00+00:00"
}

Common failures:

  • 408 transaction not yet confirmed on-chain
  • 410 payment session expired
  • 422 payer wallet mismatch or missing identity verification
  • 409 session already linked to a different transaction

Poll payment status

GET /v1/payments/{payment_id}

Safe public fields include:

  • status
  • tx_signature
  • confirmed_at
  • failed_at
  • failure_reason
  • delivery_status
  • membership_id

Mobile Phantom routes

The hosted checkout also exposes advanced Phantom mobile routes:

  • POST /v1/pay/phantom/connect/callback
  • POST /v1/pay/phantom/message-url
  • POST /v1/pay/phantom/message/callback
  • POST /v1/pay/phantom/transaction-url
  • POST /v1/pay/phantom/transaction/callback

If you are using the hosted Hilt checkout, these are already handled for you.

For a custom merchant backend:

  1. create and manage products through /v1/products
  2. send buyers to the hosted checkout slug
  3. optionally create signed handoff links for pre-known buyers
  4. use GET /v1/payments/{payment_id} for runtime status
  5. use memberships, receipts, and support routes for the post-payment operating trail