Reseller API
Programmatic access to products, wallet balance, orders and instant delivery.
Base URL
https://tgcenter.mediacraftshop.com/api/public/v2Every response is JSON and always contains an ok boolean. Errors add error: { code, message }.
Authentication
v2 uses a key + secret pair. The key identifies the credential, the secret proves ownership.
X-API-Key: rk_live_xxxxxxxx
X-API-Secret: rs_xxxxxxxxxxxxxxxx
# The key may also be sent as a bearer token:
Authorization: Bearer rk_live_xxxxxxxx
X-API-Secret: rs_xxxxxxxxxxxxxxxxSigned requests (optional, recommended)
Credentials with require_signature enabled must send an HMAC-SHA256 signature over <timestamp>.<nonce>.<rawBody> using your API secret. Timestamps must be within 5 minutes and every nonce may only be used once (replay protection).
X-API-Key: rk_live_xxxxxxxx
X-Timestamp: 1780000000
X-Nonce: 6f1c1b6e-1b3f-4a4e-9f0e-2b7d9c1a5e77
X-Signature: hmac_sha256(secret, "1780000000.<nonce>.<rawBody>")// Node.js
import { createHmac, randomUUID } from "crypto";
const body = JSON.stringify({ product_id: PRODUCT_ID, quantity: 1 });
const ts = Math.floor(Date.now() / 1000);
const nonce = randomUUID();
const signature = createHmac("sha256", API_SECRET)
.update(`${ts}.${nonce}.${body}`)
.digest("hex");Idempotency
Send Idempotency-Key (or client_request_id in the body) on order creation. Repeating the same value returns the original order instead of charging twice.
Endpoints
1. Service index
GET https://tgcenter.mediacraftshop.com/api/public/v2{
"ok": true,
"version": "v2",
"endpoints": ["/me", "/balance", "/products", "/products/{id}", "/orders", "/orders/{id}"]
}2. Account profile
GET https://tgcenter.mediacraftshop.com/api/public/v2/me{
"ok": true,
"reseller": {
"id": "RESELLER_UUID",
"display_name": "Acme Digital",
"email": "you@example.com",
"status": "active",
"discount_percent": 10
},
"credential": { "key_prefix": "rk_live_ab12", "rate_limit_per_minute": 120 },
"wallet": { "balance": 125.5, "currency": "BDT" }
}3. Wallet balance
GET https://tgcenter.mediacraftshop.com/api/public/v2/balance{
"ok": true,
"balance": 125.5,
"lifetime_credited": 900,
"lifetime_debited": 774.5,
"discount_percent": 10
}4. List products
Prices already include your discount. Products with options expose a variants array — order the variant, not the parent product.
GET https://tgcenter.mediacraftshop.com/api/public/v2/products
GET https://tgcenter.mediacraftshop.com/api/public/v2/products?category_id=<uuid>&in_stock=true&limit=100{
"ok": true,
"count": 1,
"discount_percent": 10,
"products": [
{
"id": "PRODUCT_UUID",
"name": "Product name",
"category_id": "CATEGORY_UUID",
"auto_deliver": true,
"stock": 25,
"list_price": 10,
"your_price": 9,
"variants": [
{ "id": "VARIANT_UUID", "name": "12 months", "stock": 8, "list_price": 20, "your_price": 18 }
]
}
]
}5. Single product
GET https://tgcenter.mediacraftshop.com/api/public/v2/products/{id}6. Place an order
POST https://tgcenter.mediacraftshop.com/api/public/v2/orders
X-API-Key: rk_live_xxxxxxxx
X-API-Secret: rs_xxxxxxxxxxxxxxxx
Idempotency-Key: your-unique-id
Content-Type: application/json
{
"product_id": "PRODUCT_UUID",
"variant_id": "VARIANT_UUID",
"quantity": 1,
"external_ref": "your-internal-order-id",
"custom_data": {}
}{
"ok": true,
"duplicate": false,
"order": {
"id": "ORDER_UUID",
"status": "delivered",
"quantity": 1,
"unit_price": 18,
"total": 18,
"delivered": true,
"delivery": { "text": "Activation data", "image_url": null, "video_url": null, "note": null }
},
"balance": 107.5
}The wallet is debited and stock is reserved in a single atomic transaction — a failed delivery never loses your balance, and a successful debit never oversells stock.
7. Order history & status
GET https://tgcenter.mediacraftshop.com/api/public/v2/orders?limit=50&status=delivered
GET https://tgcenter.mediacraftshop.com/api/public/v2/orders/{id}{
"ok": true,
"order": {
"id": "ORDER_UUID",
"product_name": "Product name",
"variant_name": "12 months",
"quantity": 1,
"price": 18,
"status": "delivered",
"created_at": "2026-06-20T10:00:00.000Z",
"delivered_at": "2026-06-20T10:00:03.000Z"
}
}cURL examples
curl -s "https://tgcenter.mediacraftshop.com/api/public/v2/me" \
-H "X-API-Key: $API_KEY" \
-H "X-API-Secret: $API_SECRET"curl -s -X POST "https://tgcenter.mediacraftshop.com/api/public/v2/orders" \
-H "X-API-Key: $API_KEY" \
-H "X-API-Secret: $API_SECRET" \
-H "Idempotency-Key: order-1001" \
-H "Content-Type: application/json" \
-d '{"product_id":"PRODUCT_UUID","quantity":1,"external_ref":"order-1001"}'Webhooks
Register HTTPS endpoints in the Reseller Portal → Webhooks. We POST signed JSON for order.created, order.delivered, wallet.credited and wallet.debited. Reply with any 2xx status within 10 seconds. Non-2xx responses are retried up to 5 times with exponential backoff (1m, 2m, 4m, 8m, 16m).
POST /your/endpoint
X-TGC-Event: order.delivered
X-TGC-Event-Id: evt_9f21...
X-TGC-Timestamp: 1730000000
X-TGC-Signature: t=1730000000,v1=<hex>
{
"id": "evt_9f21...",
"event": "order.delivered",
"api_version": "v2",
"created": 1730000000,
"reseller_id": "<uuid>",
"data": { "order_id": "<uuid>", "total": 120, "delivery": { "text": "..." } }
}Verify with HMAC_SHA256(secret, "<timestamp>.<raw body>") and compare against v1 using a timing-safe comparison. Reject timestamps older than 5 minutes and treat X-TGC-Event-Id as the idempotency key.
Error codes
missing_credentials/invalid_api_key— 401invalid_signature/stale_request/replay_detected— 401credential_revoked,reseller_suspended,reseller_pending— 403insufficient_balance— 402product_unavailable/variant_unavailable— 404insufficient_stock— 409rate_limited— 429
Store the key and secret in server-side environment variables only. Rotate them from the reseller portal at any time — old credentials stop working immediately.