Dành cho nhà phát triển

API cho reseller

Bán lại dịch vụ của chúng tôi trên website của bạn. Một endpoint duy nhất, POST form-urlencoded, không cần SDK.

Tổng quan

Mọi lời gọi đều là POST tới một endpoint duy nhất, body dạng form-urlencoded. Xác thực bằng tham số key trong body — không dùng header, không OAuth. Chỉ nhận POST.

POST https://api.metatik.net/api/v2
Content-Type: application/x-www-form-urlencoded

key=YOUR_KEY&action=services

Mỗi tài khoản API chốt một tiền tệ khi bật và không đổi được, không tự quy đổi.

Quy ước lỗi — đọc trước khi viết code

Lỗi được trả về với HTTP 200 kèm trường error trong body. Hãy kiểm tra trường error, ĐỪNG dựa vào HTTP status code. Nếu bạn viết theo kiểu REST thông thường (chỉ xử lý khi status là lỗi), bạn sẽ bỏ sót toàn bộ lỗi nghiệp vụ và coi đơn thất bại là thành công.

HTTP/1.1 200 OK

{"error": "Incorrect API key"}

Thông báo lỗi luôn bằng tiếng Anh, không phụ thuộc header Accept-Language, để bạn so khớp chuỗi ổn định.

Chống trùng đơn — chỗ dễ mất tiền nhất

API không có trường idempotency mặc định. Nếu script của bạn tự thử lại khi timeout, mỗi lần thử lại là một đơn thật và một lần trừ tiền thật. Chúng tôi bảo vệ bạn bằng hai lớp:

  1. Gửi client_order_id (khuyến nghị mạnh): chuỗi tuỳ ý tối đa 128 ký tự do bạn sinh, nên dùng chính id đơn trong hệ thống của bạn. Gửi lại cùng một giá trị sẽ không bao giờ tạo đơn thứ hai — trả về đúng kết quả của lần đầu, kể cả khi lần đầu là lỗi.
  2. Nếu không gửi client_order_id: hai lời gọi add giống hệt nhau (cùng dịch vụ, link hoặc username, số lượng) trong vòng 60 giây được coi là một đơn.

Đánh đổi của lớp thứ hai: nó cũng chặn khi bạn thật sự muốn đặt hai đơn giống hệt nhau liền nhau. Muốn đặt được thì phải gửi client_order_id khác nhau cho từng đơn.

Danh sách action

ActionTham sốMô tả
servicesLấy toàn bộ danh mục kèm giá của bạn
addservice, link | username, quantity, comments, client_order_idĐặt đơn mới, trừ tiền từ ví của bạn
statusorderTrạng thái một đơn
statusorders (≤100)Trạng thái nhiều đơn
refillorder | orders (≤100)Yêu cầu bảo hành tụt
cancelorders (≤100)Huỷ đơn — chỉ nhận orders, kể cả khi huỷ một đơn
balanceSố dư ví của bạn

Các lời gọi nhiều đơn giới hạn 100 id mỗi lần. Vượt quá sẽ trả lỗi rõ ràng, chúng tôi không âm thầm cắt bớt danh sách.

Tham số của add theo loại dịch vụ

typeBắt buộc
Defaultservice, link, quantity
Packageservice, link
Custom Commentsservice, link, comments
Subscriptionsservice, username

Response mẫu

service là id dịch vụ dùng cho action add — hãy lưu lại, id này ổn định. rate là giá trên 1000 đơn vị, tính bằng tiền tệ của tài khoản bạn. type quyết định tham số của add. refill và cancel là năng lực riêng của từng dịch vụ.

action=services
[
  { "service": 142, "name": "Instagram Followers", "type": "Default",
    "category": "Instagram Followers", "rate": "1.12", "min": "100",
    "max": "100000", "refill": true, "cancel": true }
]
action=add
{ "order": 90512 }
action=status (order)
{ "charge": "1.12", "start_count": "1200", "status": "In progress",
  "remains": "400", "currency": "USD" }
action=status (orders)
{
  "90512": { "charge": "1.12", "start_count": "1200", "status": "In progress", "remains": "400", "currency": "USD" },
  "90513": { "error": "Incorrect order ID" }
}
action=refill
{ "refill": 1 }

[ { "order": 90512, "refill": 1 },
  { "order": 90513, "refill": { "error": "This service does not support refill." } } ]
action=cancel
[ { "order": 90512, "cancel": 1 },
  { "order": 90513, "cancel": { "error": "Only an order that is still running can be cancelled." } } ]
action=balance
{ "balance": "497.76", "currency": "USD" }

Lưu ý shape của lời gọi nhiều đơn không đồng nhất: thành công là giá trị đơn, thất bại là một object lồng chứa error. Hãy kiểm tra kiểu dữ liệu từng phần tử, đừng giả định đồng nhất.

cancel trả về 1 nghĩa là yêu cầu huỷ đã được ghi nhận, KHÔNG phải tiền đã hoàn. Chúng tôi hoàn phần chưa giao sau khi việc huỷ được xác nhận — theo dõi bằng action status.

Chỉ dùng được khi dịch vụ có refill là true, đơn ở trạng thái Completed hoặc Partial, và chưa có yêu cầu bảo hành nào đang chờ.

Trạng thái đơn

Trạng tháiÝ nghĩa
PendingĐã nhận, chưa bắt đầu chạy
In progressĐang chạy
PartialGiao một phần — phần chưa giao đã được hoàn vào ví của bạn
CompletedĐã hoàn thành
CanceledHuỷ hoặc không giao được — xem lưu ý bên dưới

Canceled cũng bao gồm đơn không nhận được vì không có trạng thái riêng cho trường hợp này. Phần lớn được hoàn tiền tự động; một số ít cần đối soát thủ công — liên hệ hỗ trợ nếu số dư không khớp.

Mã lỗi

errorÝ nghĩa
Incorrect API keyKey sai, hoặc tài khoản API đang tạm dừng
Rate limit exceededVượt quá số request mỗi phút của tài khoản
Invalid actionGiá trị action không hợp lệ
Incorrect service IDDịch vụ không tồn tại hoặc hiện không bán
Incorrect order IDKhông tìm thấy đơn, hoặc đơn không thuộc tài khoản của bạn
Order rejectedĐơn bị từ chối
Insufficient balance.Số dư ví không đủ
Quantity is out of the allowed range for this service.Số lượng ngoài khoảng cho phép của dịch vụ
Request failed, please try again laterLỗi tạm thời — thử lại sau
Too many ids in one request. The limit is 100.Quá nhiều id trong một lời gọi

Code mẫu

Mỗi mẫu đều truyền client_order_id lấy từ id đơn trong hệ thống của bạn — đó là cách chống trùng đơn khi bạn thử lại.

PHP
<?php
function apiCall(array $params) {
    $ch = curl_init('https://api.metatik.net/api/v2');
    curl_setopt_array($ch, [
        CURLOPT_POST           => true,
        CURLOPT_POSTFIELDS     => http_build_query($params),
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT        => 60,
    ]);
    $body = curl_exec($ch);
    curl_close($ch);
    return json_decode($body, true);
}

// Đặt đơn. client_order_id = id đơn trong hệ thống của bạn -> retry không tạo đơn trùng.
$result = apiCall([
    'key'             => $API_KEY,
    'action'          => 'add',
    'service'         => 142,
    'link'            => 'https://instagram.com/example',
    'quantity'        => 1000,
    'client_order_id' => $myOrder->id,
]);

// Lỗi trả về HTTP 200 -> phải kiểm tra field 'error', không kiểm tra status code.
if (isset($result['error'])) {
    throw new RuntimeException($result['error']);
}
$providerOrderId = $result['order'];
Node.js
const API_URL = 'https://api.metatik.net/api/v2';

async function apiCall(params) {
  const res = await fetch(API_URL, {
    method: 'POST',
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
    body: new URLSearchParams(params),
  });
  const data = await res.json();
  // Lỗi đi kèm HTTP 200 -> KHÔNG dùng res.ok để phát hiện lỗi.
  if (data && data.error) throw new Error(data.error);
  return data;
}

const { order } = await apiCall({
  key: process.env.RESELLER_API_KEY,
  action: 'add',
  service: 142,
  link: 'https://instagram.com/example',
  quantity: 1000,
  client_order_id: myOrder.id,
});
Python
import os
import requests

API_URL = "https://api.metatik.net/api/v2"

def api_call(**params):
    res = requests.post(API_URL, data=params, timeout=60)
    data = res.json()
    # Lỗi đi kèm HTTP 200 -> không dùng raise_for_status() để bắt lỗi nghiệp vụ.
    if isinstance(data, dict) and "error" in data:
        raise RuntimeError(data["error"])
    return data

result = api_call(
    key=os.environ["RESELLER_API_KEY"],
    action="add",
    service=142,
    link="https://instagram.com/example",
    quantity=1000,
    client_order_id=str(my_order.id),
)
provider_order_id = result["order"]

Tự kiểm tra bằng curl

Chạy các lệnh dưới đây để xác nhận key hoạt động và xem response thật trước khi viết integration.

curl
KEY=your_api_key
URL=https://api.metatik.net/api/v2

# Danh mục + giá của bạn
curl -s -X POST $URL -d "key=$KEY&action=services"

# Số dư
curl -s -X POST $URL -d "key=$KEY&action=balance"

# Đặt đơn (nên luôn gửi client_order_id)
curl -s -X POST $URL \
  -d "key=$KEY&action=add&service=142&link=https://instagram.com/example&quantity=1000&client_order_id=my-order-1"

# Trạng thái: một đơn / nhiều đơn (tối đa 100)
curl -s -X POST $URL -d "key=$KEY&action=status&order=90512"
curl -s -X POST $URL -d "key=$KEY&action=status&orders=90512,90513"

# Bảo hành tụt / huỷ đơn
curl -s -X POST $URL -d "key=$KEY&action=refill&order=90512"
curl -s -X POST $URL -d "key=$KEY&action=cancel&orders=90512,90513"

Trên Windows dùng Git Bash: curl -d gửi chữ có dấu dưới bảng mã Windows-1252 khiến máy chủ trả lỗi. Nếu tham số có chữ có dấu, hãy test bằng công cụ gửi UTF-8 thật (Postman, hoặc Python requests).

Thử ngay

Dán API key của bạn để gọi thật và xem response. Không có gì được lưu lại.

Chỉ mở các action chỉ đọc. add, cancel và refill bị loại có chủ đích vì chúng đặt đơn thật tốn tiền và huỷ đơn thật — hãy test chúng bằng curl khi bạn đã sẵn sàng.

Sẵn sàng bắt đầu?

Bật API trong trang tài khoản để nhận key. Key hiển thị đúng một lần.