Tổng Kho eSIM
Self-Integration

Self-Integration

There is no official package to install. The three things below do exactly what one used to do: sign requests correctly, give you a runnable example, and hand you a ready-to-click test collection — no need to write a line of code before you know what the API returns.

OpenAPI for members

Integrate directly with a member account, without creating an organization or a Vietnamese legal-entity profile.

An administrator grants OpenAPI per member. Open API Keys in the main sidebar, select Live or Test, then create a key; the secret appears once. Both modes share the key limit. Disabling access blocks both modes while still allowing revocation.

Live uses the member’s real VND wallet, without credit. Test uses a separate virtual wallet and simulated eSIMs; add test funds, seed or reset samples in Test Mode. Test orders do not appear in live purchase history.

A member’s private package price is final, with no additional tier discount. Without a private package price, the current list price and tier discount apply. The server fixes the price when placing the order.

Invoices follow the member flow: consumer sale by default. When creating an order, you may supply invoice_buyer with valid individual details under the current validation rules. A Vietnamese legal-entity profile is not required for OpenAPI access.

Authentication and duplicate prevention

Live: https://api.tongkhoesim.com with tke_member_live_. Test: https://api-testing.tongkhoesim.com with tke_member_test_. Both use HMAC-SHA256 and X-TKE-Key, X-TKE-Timestamp, X-TKE-Nonce, X-TKE-Signature. Sign the exact method, path/query and raw-body hash; never put secrets in browser code.

POST requests to create orders, change plans, cancel or request refunds require Idempotency-Key. Keep the same key and body when retrying one intent; deduplication is scoped to the API key, so do not switch API keys to retry a pending transaction. Member test seed and reset also require Idempotency-Key; reset must include a {reason} body.

Include lpa in include to receive installation codes; the normal cancellation window closes when codes are actually returned. qr only adds a QR image alongside lpa and is ignored on list endpoints. Request codes only when ready to deliver; omit include to avoid disclosure. Refund requests still follow business eligibility and are not an unrestricted cancellation route after code disclosure.

Member API endpoints

API route: GET /v1/catalog/packages
Required scope: catalog:read
API route: GET /v1/catalog/packages/{code}
Required scope: catalog:read
API route: GET /v1/orders
Required scope: orders:read
API route: POST /v1/orders
Required scope: orders:write
API route: GET /v1/orders/{id}
Required scope: orders:read
API route: POST /v1/orders/{id}/resend
Required scope: orders:write
API route: GET /v1/esims
Required scope: esims:read
API route: GET /v1/esims/{id}
Required scope: esims:read
API route: GET /v1/esims/{id}/usage
Required scope: esims:read
API route: GET /v1/esims/{id}/plan-options
Required scope: esims:read
API route: POST /v1/esims/{id}/change-plan
Required scope: esims:write
API route: POST /v1/esims/{id}/cancel
Required scope: esims:write
API route: GET /v1/esims/{id}/refund-requests
Required scope: esims:read
API route: POST /v1/esims/{id}/refund-requests
Required scope: esims:write
API route: GET /v1/wallet/balance
Required scope: wallet:read

Test Mode

GET /v1/testmode/status
esims:read
POST /v1/testmode/seed
orders:write
POST /v1/testmode/reset
orders:write
POST /v1/testmode/esims/{id}/simulate
esims:write

The console accepts partner tke_test_ and member tke_member_test_ keys on the api-testing host only. All live keys are blocked. Secrets remain in page memory and are never saved to storage or logs.

Sign requests

The full HMAC-SHA256 formula, snippets in 5 languages (bash/Node/Python/PHP/Go), and real backend-generated test vectors live entirely on the HMAC Signing page — nothing is duplicated here.

bash
#!/usr/bin/env bash
# Yeu cau: openssl. Ky POST /v1/orders.
KEY_ID="tke_test_ab12cd34..."
SECRET="tke_secret_test_0123456789abcdef"
METHOD="POST"
PATH_Q="/v1/orders"
BODY='{"items":[{"package_code":"THAY-BANG-MA-GOI-CUA-BAN","quantity":2}]}'
TS="$(date +%s000)"                 # epoch milliseconds
NONCE="$(uuidgen)"

BODY_HASH="$(printf '%s' "$BODY" | openssl dgst -sha256 -hex | awk '{print $NF}')"
SIGNING="$METHOD"$'
'"$PATH_Q"$'
'"$TS"$'
'"$NONCE"$'
'"$BODY_HASH"
SIG="$(printf '%s' "$SIGNING" | openssl dgst -sha256 -hmac "$SECRET" -hex | awk '{print $NF}')"

curl -sS "https://api.tongkhoesim.com$PATH_Q"   -H "X-TKE-Key: $KEY_ID"   -H "X-TKE-Timestamp: $TS"   -H "X-TKE-Nonce: $NONCE"   -H "X-TKE-Signature: $SIG"   -H "Idempotency-Key: $(uuidgen)"   -H "Content-Type: application/json"   --data-raw "$BODY"

Runnable example files

Two files at the repository root (examples/sign.mjs, examples/sign.py) run immediately with the language's standard runtime, no package to install. Both read the /hmac-test-vectors.json test vectors, compute the signature for each one, compare it against the expected result, and print PASS/FAIL per line.

bash
node examples/sign.mjs      # plain Node (node:crypto), nothing to install
python examples/sign.py     # plain Python (hmac/hashlib), nothing to install

Ready-to-run collections

Two collections generated DIRECTLY from openapi.json at build time, always matching the live spec: one for Postman, one for editors that support .http files (VS Code REST Client, JetBrains HTTP Client). One request per endpoint, with the 4 signing headers pre-filled — just add your key and compute the signature.

Using the .http collection
  1. Open tongkhoesim.http in VS Code (REST Client extension) or JetBrains HTTP Client.
  2. Fill in @key_id and @secret at the top with your tke_test_ key — @base_url already points at the api-testing.tongkhoesim.com host.
  3. Compute timestamp/nonce/signature using the snippets on the HMAC Signing page or by running examples/sign.*, then paste them into the matching variables.
  4. Send any request right inside your editor — no Postman, no code required.

Still want an SDK?

Generate one from openapi.json with openapi-generator — a machine-generated client never drifts from the spec, unlike a handwritten one:

bash
npx @openapitools/openapi-generator-cli generate \
  -i https://docs.tongkhoesim.com/openapi.json \
  -g typescript-fetch \
  -o ./tke-sdk