---
name: tronow-connect
description: Integrate TRONow merchant OpenAPI v1 into a server-side application, including HMAC authentication, energy orders, address activation, status tracking and signed webhooks.
---

# TRONow merchant integration

Use the merchant's existing language and framework. Implement the integration rather than replacing the host application. Obtain OPENAPI_BASE_URL, LEASE_API_KEY and LEASE_API_SECRET through server-side environment configuration. Never put secrets in browser code, source control, screenshots or AI prompts.

## Access and units

The merchant must contact platform support for an assigned deposit address. Confirmed deposits must total at least 20 TRX before API service is unlocked; INITIAL_DEPOSIT_REQUIRED means onboarding is incomplete. Create an API key, retain its Secret at creation and configure allowed server egress IPs if an allowlist is enabled.

Use the Console's current Base URL ending in /openapi/v1. All monetary *_sun values are decimal strings; 1 TRX = 1000000 SUN. Use integers/BigInt, not floating-point money. Current energy offering is ENERGY with duration 1h; presets 65000 and 131000 and custom amounts remain subject to the merchant's live product limits. Never hardcode a sales price, quote lifetime, or a 24h offering.

## Request authentication

Every request requires X-API-Key, X-Timestamp (Unix milliseconds), X-Nonce (16-128 URL-safe ASCII characters), X-Signature (lowercase hex HMAC-SHA256). Generate an unpredictable new nonce per attempt, unique across the merchant, even across keys. Use API Secret's raw string bytes; do not Base64 decode.

Sign exactly seven lines joined with LF and no trailing LF:
1. Uppercase method.
2. Full escaped path, e.g. /openapi/v1/orders.
3. Canonical query equivalent to Go url.Values.Encode(): sort decoded keys, preserve repeated value order, form-encode keys/values with spaces as +.
4. Timestamp.
5. Nonce.
6. Trimmed Idempotency-Key; empty line for read requests.
7. Lowercase hex SHA256 of the exact transmitted body bytes; GET uses the empty string.

Creation requires a stable 8-128 visible ASCII Idempotency-Key. Serialize JSON once, sign those bytes and send the same bytes. Respect configured clock skew (default five minutes).

## Endpoints

All paths below append to the Base URL.
- GET /prices/quote?duration=1h&resource_amount=65000&resource_type=ENERGY returns quote_id, total_amount_sun, expires_at and product fields.
- POST /orders with client_order_id, quote_id, resource_type, receiver_address, resource_amount, duration. Product fields must match the quote. Receiver must pass TRON Base58Check.
- GET /orders/{order_id} or GET /orders?client_order_id=... tracks the order.
- POST /address-activations with client_activation_id and address. Service fee is 1500000 SUN; successful execution sends 10 SUN. This is a paid operation even for an already active address; deduplicate before calling.
- GET /address-activations/{activation_id} or GET /address-activations?client_activation_id=... tracks activation.
- GET /account/balance returns available_balance_sun, reserved_balance_sun and total_balance_sun.

Client order/activation identifiers are merchant-unique visible ASCII, 1-64 characters. Creation returns 201, idempotent replay 200, Location and Retry-After. Both indicate acceptance, not delivery. Parse the envelope code/message/request_id/data and stable error code, never human message text.

## Lifecycle and retries

Persist client identifier, idempotency key, exact request body and returned platform identifier before retrying. A timeout does not prove failure: first look up by client identifier, then retry the identical payload and idempotency key with a new timestamp/nonce/signature. Never silently create a new paid business request.

SUCCESS is the only successful final state. FAILED and REFUNDED are other final order states. PROCESSING, SUBMITTED, REFUNDING and MANUAL_REVIEW require continued tracking. Activation uses PROCESSING, SUBMITTED, SUCCESS and FAILED. Start polling after Retry-After (currently 2 seconds), then bounded exponential backoff with jitter. Stop foreground polling after a reasonable deadline and retain the job for later reconciliation.

QUOTE_EXPIRED requires a new quote for a new attempt only after resolving any previous ambiguous creation. Handle INSUFFICIENT_BALANCE, IDEMPOTENCY_CONFLICT, CLIENT_ORDER_ID_CONFLICT, INITIAL_DEPOSIT_REQUIRED, IP_NOT_ALLOWED and authentication errors explicitly. Do not automatically retry all 4xx responses.

## Webhooks

Order events: order.succeeded, order.failed, order.refunded. Activation must be tracked with its query endpoints; do not invent activation events.

Headers: X-Lease-Timestamp (Unix seconds), X-Lease-Delivery, X-Lease-Event (event ID), X-Lease-Signature. Sign timestamp + "." + delivery_id + "." + event_id + "." + exact_body_bytes using the separately configured Webhook secret. Header value is "v1=" + hex HMAC-SHA256. Bound raw body size, verify timestamp window and constant-time signature before JSON processing. Deduplicate delivery ID and make business handling idempotent by event/order identity. Return 2xx only after durable acceptance; deliveries may repeat. Retryable responses include 408, 425, 429 and 5xx.

## Deliver and verify

Provide the client, environment template without secrets, quote/create/query flow, durable retry handling, webhook verifier and tests. Verify signatures against deterministic vectors including reordered query keys, repeated keys, spaces and UTF-8. Test timeout recovery, duplicate callbacks, expired quote, insufficient balance and non-final states using mocks first.

A read-only authenticated balance request is the initial connection check. Do not place paid orders, activate addresses or send transfers as an unrequested test; obtain the merchant's explicit authorization before a real paid check.

For full field schemas, use the OpenAPI YAML downloadable beside this Skill in the Console. The downloadable client.mjs is a Node.js standard-library reference; adapt the same contract to other stacks.
