/api/v1وثيقة الاكتشاف
تعيد النطاقات، الحصص، أحداث الويب هوكس، وكatalog العمليات الكامل. أي مفتاح واجهة برمجة تطبيقات صالح يعمل.
واجهة برمجة التطبيقات المفتوحة للبائعين مخصصة للبائعين الذين يرغبون في تنبيهات Discord، مزامنة المخزون، أتمتة على طراز Zapier، أو مكتب خلفي مخصص فوق RMT.GG.
قم بإنشاء مفتاح API في إعدادات المطور، ثم استخدم الاستكشاف لطباعة الكتالوج المباشر.
/api/v1تعيد النطاقات، الحصص، أحداث الويب هوكس، وكatalog العمليات الكامل. أي مفتاح واجهة برمجة تطبيقات صالح يعمل.
أرسل مفتاحك السري المباشر في كل طلب /api/v1. يفضل استخدام HTTPS فقط. لا تقم أبدًا بتضمين المفاتيح في العملاء العامة أو حزم المتصفح.
الرأس المفضل
Authorization: Bearer rmt_sk_live_<prefix>_<secret>رأس بديل
X-Api-Key: rmt_sk_live_<prefix>_<secret>عميل TypeScript قابل لإعادة الاستخدام (مصادقة Bearer، أخطاء محددة، إعادة المحاولة 429)
const API_BASE = "https://rmt.gg/api/v1";
const API_KEY = process.env.RMT_API_KEY!; // rmt_sk_live_…
export class RmtApiError extends Error {
constructor(
readonly status: number,
readonly code: string | undefined,
message: string,
readonly retryAfterSec?: number,
) {
super(message);
this.name = "RmtApiError";
}
}
type RmtFetchInit = RequestInit & { idempotencyKey?: string };
export async function rmtFetch<T>(path: string, init: RmtFetchInit = {}): Promise<T> {
const headers = new Headers(init.headers);
headers.set("Authorization", `Bearer ${API_KEY}`);
// Alternate: headers.set("X-Api-Key", API_KEY);
headers.set("Accept", "application/json");
if (init.body && !headers.has("Content-Type")) {
headers.set("Content-Type", "application/json");
}
if (init.idempotencyKey) headers.set("Idempotency-Key", init.idempotencyKey);
const res = await fetch(`${API_BASE}${path}`, { ...init, headers });
const retryAfter = Number(res.headers.get("Retry-After") ?? "");
const body = (await res.json().catch(() => ({}))) as {
error?: string;
code?: string;
retryAfter?: number;
};
if (res.status === 429) {
throw new RmtApiError(
429,
body.code ?? "RATE_LIMITED",
body.error ?? "Rate limited",
Number.isFinite(retryAfter) ? retryAfter : body.retryAfter,
);
}
if (!res.ok) {
throw new RmtApiError(res.status, body.code, body.error ?? res.statusText);
}
return body as T;
}
export async function withRetry<T>(fn: () => Promise<T>, maxAttempts = 4): Promise<T> {
let attempt = 0;
for (;;) {
try {
return await fn();
} catch (err) {
attempt += 1;
if (!(err instanceof RmtApiError) || err.status !== 429 || attempt >= maxAttempts) {
throw err;
}
const waitSec = Math.max(1, err.retryAfterSec ?? 1);
await new Promise((r) => setTimeout(r, waitSec * 1000));
}
}
}
قم بتدوير عند التسرب
إذا تسرب مفتاح، قم بإلغائه في إعدادات المطور وأنشئ واحدًا جديدًا. قم بتحديث الأتمتة الخاصة بك قبل الإلغاء إذا كنت مباشرًا.
كل مفتاح واجهة برمجة التطبيقات يحمل نطاقات تحدد نقاط النهاية. النطاق المفقود يعيد 403 SCOPE_MISSING.
offers:read: قائمة والحصول على عروضك.offers:write: إنشاء، تحديث، نشر، وحذف العروض.orders:read: قائمة والحصول على طلبات البائع.orders:write: تحديد الطلبات كتم التسليم.webhooks:manage: محجوز لإدارة واجهة برمجة التطبيقات المفتوحة المستقبلية. قم بتكوين Discord/Telegram في الإشعارات و JSON webhooks في إعدادات المطور اليوم.checkout:write: إنشاء وقراءة جلسات الدفع المستضاف. يتطلب موافقة الإدارة على شراكة الدفع.نطاقات المفتاح الافتراضية
تتلقى المفاتيح الجديدة offers:read، offers:write، orders:read، وorders:write. تظل CRUD الويب هوكس الخارجة في واجهة إعدادات (مصادقة الجلسة).
معرفات العروض تقبل شريحة URL العامة أو المعرف الرقمي. تستبعد الاستجابات المعرف الداخلي وsellerId.
ما لا يمكن تغييره بعد باستخدام PATCH
تُدار صفوف المخزون، أسعار الخيارات، الوسائط، والسمات في محرر البائع (أو نقاط النهاية المستقبلية)، وليس عبر PATCH اليوم.
/api/v1/offersقم بتصفية باستخدام archive=active (افتراضي)، archived، أو الكل.
الطلب
archive| الاسم | في | النوع | مطلوب | الوصف |
|---|---|---|---|---|
archive | query | string | اختياري | One of "active" (default), "archived", or "all". |
/api/v1/offersينشئ مسودة فارغة مملوكة للبائع المعتمد. لا يتطلب جسم.
/api/v1/offers/:urlOrIdقم بالتحميل بواسطة شريحة URL العامة أو المعرف الرقمي. قد يتم تضمين العلاقات (الخيارات)؛ العناصر المخزنة ليست كذلك.
الطلب
urlOrId| الاسم | في | النوع | مطلوب | الوصف |
|---|---|---|---|---|
urlOrId | path | string | مطلوب | Offer.url slug or Offer.id. |
/api/v1/offers/:urlOrIdقم بتحديث مجموعة آمنة من حقول الإدراج. يصدر offer.updated عند تكوين الويب هوكس الخارجة.
الطلب
urlOrIdtitledescriptionvisibilitycategoryIdofferingIdthumbnailofferTypelistingMode| الاسم | في | النوع | مطلوب | الوصف |
|---|---|---|---|---|
urlOrId | path | string | مطلوب | Offer.url slug or Offer.id. |
title | body | string | اختياري | Listing title. |
description | body | string | اختياري | Listing description. |
visibility | body | string | اختياري | PUBLIC | PRIVATE | UNPUBLISHED. |
categoryId | body | number | اختياري | Catalog category id. |
offeringId | body | number | اختياري | Catalog offering id. |
thumbnail | body | string | اختياري | Thumbnail URL or asset reference. |
offerType | body | string | اختياري | Offer type string used by the listing. |
listingMode | body | string | اختياري | Listing mode (for example STANDARD, RANK_BOOST, SESSION). |
/api/v1/offers/:urlOrIdنفس قواعد الحذف / الأرشفة مثل واجهة مستخدم البائع.
الطلب
urlOrId| الاسم | في | النوع | مطلوب | الوصف |
|---|---|---|---|---|
urlOrId | path | string | مطلوب | Offer.url slug or Offer.id. |
/api/v1/offers/:urlOrId/publishينشر مسودة (أو يغير الرؤية). يفشل مع 400 إذا كانت حقول الإدراج المطلوبة غير مكتملة.
الطلب
urlOrIdvisibility| الاسم | في | النوع | مطلوب | الوصف |
|---|---|---|---|---|
urlOrId | path | string | مطلوب | Offer.url slug or Offer.id. |
visibility | body | string | اختياري | Optional. PUBLIC (default), PRIVATE, or UNPUBLISHED. |
شاهد الكميات القابلة للشراء لكل مستوى، ووافق أسماء حقول التسليم مع القائمة الصحيحة، ثم أعد تعبئة الكمية أو المفاتيح والحسابات المحفوظة.
كيف يعمل المطابقة
GET /api/v1/stock?fields=username,password يعثر على القوائم التي تحتوي على تلك الحقول. أعد التعبئة باستخدام أسماء الخيارات (أو optionId) وأسماء الحقول. لا تحتاج إلى معرفات الحقول الداخلية. لا تتضمن الاستجابات أبداً قيم الاعتماد.
/api/v1/stockيعود بعدد الكميات لكل مستوى وأسماء حقول التسليم حتى تتمكن من مطابقة المفاتيح والحسابات مع العرض الصحيح. قم بالتصفية باستخدام q و fields و stockMode و lowStock. لا تعيد أبداً قيم الاعتماد.
الطلب
qfieldsstockModelowStockarchive| الاسم | في | النوع | مطلوب | الحدود | الوصف |
|---|---|---|---|---|---|
q | query | string | اختياري | Max 80 | Filter by listing title or url slug. |
fields | query | string | اختياري | Comma-separated delivery field names. The listing must have all of them (Username,Password). Names match case-insensitively. | |
stockMode | query | string | اختياري | QUANTITY or COMPLEX. Listing must have at least one option in that mode. | |
lowStock | query | number | اختياري | Keep listings that have a finite tier with available less than or equal to this number. | |
archive | query | string | اختياري | One of "active" (default), "archived", or "all". |
/api/v1/offers/:urlOrId/stockنفس شكل StockOffer كما في الفهرس، لعنوان URL واحد أو معرف رقمي. العد فقط.
الطلب
urlOrId| الاسم | في | النوع | مطلوب | الوصف |
|---|---|---|---|---|
urlOrId | path | string | مطلوب | Offer.url slug or Offer.id. |
/api/v1/offers/:urlOrId/stockمستويات الكمية: إضافة، إزالة، أو تعيين. مستويات العناصر المحفوظة: كائنات العناصر حسب اسم الحقل، keys[] عندما يكون هناك حقل واحد، أو نص مفصول. عدة مستويات في مكالمة واحدة عبر options[]. التشغيل التجريبي يعرض المطابقة. onDuplicate الافتراضي هو التخطي.
{
"option": "1 Month",
"add": 50
}الطلب
urlOrIdoptionoptionIdaddremovesetitemskeystextdelimiterheadersoptionsdryRunonDuplicate| الاسم | في | النوع | مطلوب | الحدود | الوصف |
|---|---|---|---|---|---|
urlOrId | path | string | مطلوب | Offer.url slug or Offer.id. | |
option | body | string | شرط | Pricing option name (case-insensitive). Omit when the listing has a single tier. | |
optionId | body | number | شرط | Pricing option id from GET stock. Wins over option when both are sent. Ambiguous names return 409 OPTION_AMBIGUOUS. | |
add | body | number | شرط | 1-1,000,000 | QUANTITY: add this many units. Fails with 400 UNLIMITED_STOCK if the tier is unlimited. |
remove | body | number | شرط | 1-1,000,000 | QUANTITY: withdraw this many units. Fails with 400 INSUFFICIENT_STOCK when there is not enough. |
set | body | number | null | شرط | QUANTITY: set an absolute count. null means unlimited. Cannot go below units held in checkout. | |
items | body | object[] | شرط | Max 1,000 | COMPLEX: objects keyed by delivery field name, for example { "Username": "a", "Password": "b" }. Names match case-insensitively. |
keys | body | string[] | شرط | Max 1,000 | COMPLEX: license keys when the listing has exactly one delivery field. Otherwise 400 FIELD_MAPPING_AMBIGUOUS. |
text | body | string | شرط | Max 1,000 rows | COMPLEX: delimited paste. A header row that matches field names is detected automatically. Otherwise columns map in field sort order when the column count matches. |
delimiter | body | string | اختياري | Default : | Delimiter for text. Ignored unless text is sent. |
headers | body | string[] | اختياري | Optional column headers for text when the first line is data, not names. | |
options | body | object[] | شرط | Restock several tiers in one call. Each element is the same shape as a single-option body (option, add, items, …). | |
dryRun | body | boolean | اختياري | Preview matching and counts without writing. Default false. | |
onDuplicate | body | string | اختياري | skip (default) or error | COMPLEX: skip existing unsold fingerprints, or fail the request with 409 DUPLICATE_ITEMS. |
استخدم POST /api/v1/offers/:url/stock مع items[] للحسابات أو keys[] لرموز الترخيص ذات الحقل الواحد. قسم إلى 1,000 صف لكل طلب.
اختر الحمولة التي تتطابق مع العرض
قم باستدعاء GET stock أولاً. إذا كان fields[] يحتوي على أكثر من اسم واحد، أرسل كائنات items مفاتيحها تلك الأسماء (اسم المستخدم، كلمة المرور، البريد الإلكتروني). إذا كان هناك حقل واحد بالضبط، فإن keys[] تكفي. قوائم الكمية تستخدم add، وليس items.
1,000 صف لكل طلب. 5,000 عنصر غير مبيع لكل مستوى. 300 طلب في الدقيقة. يتم تخطي التكرارات بشكل افتراضي.
accounts.json (كائن واحد لكل حساب)
[
{ "Username": "player1", "Password": "secret1", "E-Mail": "[email protected]" },
{ "Username": "player2", "Password": "secret2", "E-Mail": "[email protected]" }
]accounts.csv
Username,Password,E-Mail
player1,secret1,p1@example.com
player2,secret2,p2@example.comkeys.txt (مفتاح ترخيص واحد لكل سطر)
AAAA-BBBB-CCCC
DDDD-EEEE-FFFF
GGGG-HHHH-IIIIcURL
# Inspect field names and stockMode
curl -s -H "Authorization: Bearer rmt_sk_live_…" \
-H "Accept: application/json" \
https://rmt.gg/api/v1/offers/YOUR_OFFER_URL/stock
# Preview (no write)
curl -s -X POST \
-H "Authorization: Bearer rmt_sk_live_…" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
https://rmt.gg/api/v1/offers/YOUR_OFFER_URL/stock \
-d '{"dryRun":true,"onDuplicate":"skip","option":"Premium","items":[{"Username":"player1","Password":"secret1","E-Mail":"[email protected]"}]}'
# Apply accounts
curl -s -X POST \
-H "Authorization: Bearer rmt_sk_live_…" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
https://rmt.gg/api/v1/offers/YOUR_OFFER_URL/stock \
-d '{"onDuplicate":"skip","option":"Premium","items":[{"Username":"player1","Password":"secret1","E-Mail":"[email protected]"}]}'
# Apply license keys (listing must have exactly one delivery field)
curl -s -X POST \
-H "Authorization: Bearer rmt_sk_live_…" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
https://rmt.gg/api/v1/offers/YOUR_OFFER_URL/stock \
-d '{"option":"Steam","keys":["AAAA-BBBB-CCCC","DDDD-EEEE-FFFF"]}'
# Or paste CSV / colon-separated rows in text
curl -s -X POST \
-H "Authorization: Bearer rmt_sk_live_…" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
https://rmt.gg/api/v1/offers/YOUR_OFFER_URL/stock \
-d '{"option":"Premium","delimiter":",","text":"Username,Password,E-Mail\nplayer1,secret1,[email protected]"}'استيراد دفعة TypeScript (1,000 صف لكل طلب)
// Paste rmtFetch and withRetry from the Auth section first.
const CHUNK = 1000;
async function importRows(offerUrl: string, option: string, rows: Array<Record<string, string>>) {
for (let i = 0; i < rows.length; i += CHUNK) {
const items = rows.slice(i, i + CHUNK);
const preview = await rmtFetch<{
results: Array<{ wouldImport: number; skippedDuplicates: number; errors: string[] }>;
}>(`/offers/${offerUrl}/stock`, {
method: "POST",
body: JSON.stringify({ dryRun: true, onDuplicate: "skip", option, items }),
});
const row = preview.results[0];
if ((row?.errors?.length ?? 0) > 0) {
throw new Error(row.errors.join("; "));
}
await withRetry(() =>
rmtFetch(`/offers/${offerUrl}/stock`, {
method: "POST",
body: JSON.stringify({ onDuplicate: "skip", option, items }),
}),
);
}
}
// License keys: only when GET stock.fields has exactly one name
async function importKeys(offerUrl: string, option: string, keys: string[]) {
for (let i = 0; i < keys.length; i += CHUNK) {
await withRetry(() =>
rmtFetch(`/offers/${offerUrl}/stock`, {
method: "POST",
body: JSON.stringify({ option, keys: keys.slice(i, i + CHUNK) }),
}),
);
}
}
ما تحميه هذه الواجهة البرمجية
تحتاج المفاتيح إلى offers:write، وهي محدودة بمعدل، ويمكنها فقط إعادة تخزين عروضك الخاصة. GET لا تعيد أبدًا بيانات الاعتماد المحفوظة. استجابات POST لا تعكس قيم اسم المستخدم، كلمة المرور، أو المفاتيح. أرسل الجسم عبر HTTPS في الإنتاج واحتفظ بمفتاح الواجهة البرمجية في متغير بيئي.
على نظام ويندوز، استخدم curl.exe (ليس بديل curl). اقتبس -d JSON حتى لا يقوم PowerShell بتقسيمه.
الطلبات محددة لحساب البائع الخاص بك. قد يتم حذف تفاصيل فواتير المشتري بموجب قواعد خصوصية سوق السجلات.
/api/v1/ordersيدعم limit، offset، status، q، وsort (الأحدث، الأقدم، total_high، total_low).
الطلب
limitoffsetstatusqsort| الاسم | في | النوع | مطلوب | الحدود | الوصف |
|---|---|---|---|---|---|
limit | query | number | اختياري | 1-100, default 20 | Page size. |
offset | query | number | اختياري | >= 0, default 0 | Skip this many rows. |
status | query | string | اختياري | Max 32 | Filter by order status (for example PAID, DELIVERED, COMPLETED). |
q | query | string | اختياري | Max 80 | Search reference or related text. |
sort | query | string | اختياري | newest (default) | newest | oldest | total_high | total_low. |
/api/v1/orders/:uidتعيد الطلب مع عناصر الخط. استخدم uid الطلب العام.
الطلب
uid| الاسم | في | النوع | مطلوب | الوصف |
|---|---|---|---|---|
uid | path | string | مطلوب | Order.uid. |
/api/v1/orders/:uid/deliverتنفيذ يدوي. يجب أن تكون خطوط COMPLEX مرتبطة بالكامل عند الطلب. يصدر order.delivered.
الطلب
uidevidence| الاسم | في | النوع | مطلوب | الحدود | الوصف |
|---|---|---|---|---|---|
uid | path | string | مطلوب | Order.uid. | |
evidence | body | string[] | اختياري | HTTPS, max 10 | Optional screenshot or transfer-proof URLs. |
يمكن لأي متجر معتمد أو نظام خلفي إرسال المشترين إلى صفحة الدفع الخاصة بـ RMT.GG. نحن نبقى التاجر المسجل ونأخذ 4% من المبلغ المقفل.
القائمة المسموح بها والتنفيذ
قم بالتطبيق تحت الإعدادات، الدفع المستضاف، ثم أنشئ مفتاح API وويب هوك JSON هناك. بعد الدفع، نقوم بإصدار checkout.completed. تبقى قيم التسليم على تأكيد RMT.GG؛ فهي ليست في GET البائع أو الويب هوكس.
/api/v1/checkout/sessionsقم بإرسال المشترين إلى صفحة دفع مؤمنة على RMT.GG. عنصر واحد: المبلغ و itemName. السلة: items[] مع الاسم والمبلغ في كل سطر. العملة الافتراضية هي الدولار الأمريكي. بعد الدفع، يبقى المشتري على RMT.GG عندما تكون هناك حقول تسليم للنسخ. returnUrl يستمر إلى المتجر؛ بدون تسليم، نعيدهم بعد عد تنازلي قصير. المبلغ، الأطوال، والحدود الأخرى موجودة في عمود الحدود.
{
amount: 10, // what the buyer pays
itemName: "Gold pack", // pay page heading
}الطلب
amountcurrencyitemNametitledescriptionimageUrlitemsitems[].nameitems[].titleitems[].descriptionitems[].amountitems[].quantityitems[].imageUrlitems[].deliveryitems[].delivery[].nameitems[].delivery[].typeitems[].delivery[].valueemailreturnUrlcancelUrlinvoiceIdcategorySlugofferingmetadataIdempotency-Key| الاسم | في | النوع | مطلوب | الحدود | الوصف |
|---|---|---|---|---|---|
amount | body | number | شرط | > 0, max 1,000,000 | What the buyer pays. Required for a single item. With items[], omit it or send the line sum. Mismatch: 400 AMOUNT_MISMATCH. |
currency | body | string | اختياري | Default USD | ISO 4217 code such as USD or EUR. |
itemName | body | string | شرط | Max 120 | Pay page heading. Required for a single item. Alias: title. With items[], defaults to the first line name. Missing: 400 ITEM_NAME_REQUIRED. |
title | body | string | اختياري | Alias of itemName. If both are sent, itemName wins. | |
description | body | string | اختياري | Max 200 | Copy under the heading. If omitted, the heading is reused. |
imageUrl | body | string | اختياري | HTTPS, max 2048 | Product image, or fallback for lines without imageUrl. Invalid: 400 INVALID_IMAGE_URL. |
items | body | object[] | شرط | 1-20 lines, JSON max 48,000 | Locked cart. Required when amount is omitted. Buyers cannot change lines. Empty: 400 INVALID_ITEMS. |
items[].name | body | string | مطلوب | Max 120 | Line title. Alias: title. |
items[].title | body | string | اختياري | Alias of items[].name. If both are sent, name wins. | |
items[].description | body | string | اختياري | Max 200 | Line copy under the name. |
items[].amount | body | number | مطلوب | > 0, max 1,000,000 | Unit price. Session total is sum(amount * quantity). |
items[].quantity | body | number | اختياري | 1-99, default 1 | Locked on the pay page. |
items[].imageUrl | body | string | اختياري | HTTPS, max 2048 | Line image. Falls back to top-level imageUrl. |
items[].delivery | body | object[] | اختياري | Max 16 fields | Shown after payment on RMT.GG. Seller GET and webhooks omit values. |
items[].delivery[].name | body | string | مطلوب | Max 80 | Field label, for example Code or Password. |
items[].delivery[].type | body | string | اختياري | text, password, textarea | password is blurred until the buyer reveals it. Default text. |
items[].delivery[].value | body | string | مطلوب | Max 2048 | Field value. Numbers are stored as strings. Empty: 400 INVALID_DELIVERY. |
email | body | string | اختياري | Invalid values ignored | Prefills the pay page. The buyer still confirms email before paying. |
returnUrl | body | string | اختياري | HTTPS, max 2048 | Continue-to-shop after payment. Delivery fields keep the buyer on RMT.GG with a button. No delivery: we send them back after a short countdown. If omitted, there is no shop button. http://localhost is allowed for local shops. |
cancelUrl | body | string | اختياري | HTTPS, max 2048 | Redirect if the buyer cancels or the session expires. If omitted, they stay on the pay page. |
invoiceId | body | string | اختياري | Max 128 | Your shop id. Same payload returns the existing session. A different payload: 409 INVOICE_CONFLICT. |
categorySlug | body | string | شرط | With offering, or omit both | Public root slug such as games. Used for card, PayPal, and crypto labels, not the pay page title. Wrong pair: 400 INVALID_PSP_CATEGORY. |
offering | body | string | شرط | With categorySlug, or omit both | Catalog offering such as Mods. Mapped to labels like Games · Add-ons. |
metadata | body | object | اختياري | Object, max 4096 chars | Stored on the session. Not returned on seller GET. |
Idempotency-Key | header | string | اختياري | Max 128 | Replay header. Same key and payload returns the existing session. A different payload: 409 IDEMPOTENCY_CONFLICT. |
الاستجابة
uidstatuspaidamountcurrencyitemNamedescriptionemaillangreturnUrlcancelUrlinvoiceIdexternalInvoiceIdsourceexpiresAthostedUrlorderUiditemshosted_urlexpires_at| الاسم | في | النوع | الوصف |
|---|---|---|---|
uid | response | string | Session id. Same value as in hostedUrl / hosted_url. |
status | response | string | created | pending_payment | paid | canceled | expired | refunded | error. Unpaid sessions expire after 24 hours. |
paid | response | boolean | true only when status is paid. false for refunded, expired, canceled, and unpaid states. |
amount | response | number | Locked buyer total in major units. |
currency | response | string | ISO currency code stored on the session (for example USD). |
itemName | response | string | null | Pay page heading. |
description | response | string | Longer copy under the heading. |
email | response | string | null | Prefill or confirmed buyer email. Guest checkout placeholders are returned as null. |
lang | response | string | null | Buyer locale when known. Not a create-session field. |
returnUrl | response | string | null | Continue-to-shop URL stored on the session, or null. |
cancelUrl | response | string | null | Cancel/expiry redirect, or null. |
invoiceId | response | string | null | Your invoice id. Same value as externalInvoiceId. |
externalInvoiceId | response | string | null | Same as invoiceId (legacy alias). |
source | response | string | How the session was created. API sessions are "api". |
expiresAt | response | string | ISO timestamp. Unpaid checkouts cannot be completed after this time. |
hostedUrl | response | string | Pay page URL (same target as top-level hosted_url on create). |
orderUid | response | string | null | Marketplace order uid after payment. null until the session is paid. |
items | response | object[] | Locked lines: name, description, amount, quantity, imageUrl. Seller GET never includes delivery values. |
hosted_url | response | string | Pay page URL. Send the buyer here. Same target as hostedUrl. |
expires_at | response | string | ISO timestamp. Same value as expiresAt. |
/api/v1/checkout/sessions/:uidيُرجع الجلسة التي أنشأتها. استخدم هذا إذا تم تأخير checkout.completed. paid يكون صحيحًا فقط عندما تكون الحالة مدفوعة. العناصر لا تتضمن أبدًا قيم التسليم.
الطلب
uid| الاسم | في | النوع | مطلوب | الوصف |
|---|---|---|---|---|
uid | path | string | مطلوب | Session uid returned at create time. |
الاستجابة
uidstatuspaidamountcurrencyitemNamedescriptionemaillangreturnUrlcancelUrlinvoiceIdexternalInvoiceIdsourceexpiresAthostedUrlorderUiditems| الاسم | في | النوع | الوصف |
|---|---|---|---|
uid | response | string | Session id. Same value as in hostedUrl / hosted_url. |
status | response | string | created | pending_payment | paid | canceled | expired | refunded | error. Unpaid sessions expire after 24 hours. |
paid | response | boolean | true only when status is paid. false for refunded, expired, canceled, and unpaid states. |
amount | response | number | Locked buyer total in major units. |
currency | response | string | ISO currency code stored on the session (for example USD). |
itemName | response | string | null | Pay page heading. |
description | response | string | Longer copy under the heading. |
email | response | string | null | Prefill or confirmed buyer email. Guest checkout placeholders are returned as null. |
lang | response | string | null | Buyer locale when known. Not a create-session field. |
returnUrl | response | string | null | Continue-to-shop URL stored on the session, or null. |
cancelUrl | response | string | null | Cancel/expiry redirect, or null. |
invoiceId | response | string | null | Your invoice id. Same value as externalInvoiceId. |
externalInvoiceId | response | string | null | Same as invoiceId (legacy alias). |
source | response | string | How the session was created. API sessions are "api". |
expiresAt | response | string | ISO timestamp. Unpaid checkouts cannot be completed after this time. |
hostedUrl | response | string | Pay page URL (same target as top-level hosted_url on create). |
orderUid | response | string | null | Marketplace order uid after payment. null until the session is paid. |
items | response | object[] | Locked lines: name, description, amount, quantity, imageUrl. Seller GET never includes delivery values. |
/api/v1/checkout/sessionsنفس كائن الجلسة كما في GET بواسطة uid. مرر invoiceId الذي أرسلته عند الإنشاء. مفقود: 400 INVOICE_ID_REQUIRED. غير معروف: 404 NOT_FOUND.
الطلب
invoiceId| الاسم | في | النوع | مطلوب | الحدود | الوصف |
|---|---|---|---|---|---|
invoiceId | query | string | مطلوب | Max 128 | invoiceId from create. Missing: 400 INVOICE_ID_REQUIRED. Too long: 400 INVALID_INVOICE_ID. |
الاستجابة
uidstatuspaidamountcurrencyitemNamedescriptionemaillangreturnUrlcancelUrlinvoiceIdexternalInvoiceIdsourceexpiresAthostedUrlorderUiditems| الاسم | في | النوع | الوصف |
|---|---|---|---|
uid | response | string | Session id. Same value as in hostedUrl / hosted_url. |
status | response | string | created | pending_payment | paid | canceled | expired | refunded | error. Unpaid sessions expire after 24 hours. |
paid | response | boolean | true only when status is paid. false for refunded, expired, canceled, and unpaid states. |
amount | response | number | Locked buyer total in major units. |
currency | response | string | ISO currency code stored on the session (for example USD). |
itemName | response | string | null | Pay page heading. |
description | response | string | Longer copy under the heading. |
email | response | string | null | Prefill or confirmed buyer email. Guest checkout placeholders are returned as null. |
lang | response | string | null | Buyer locale when known. Not a create-session field. |
returnUrl | response | string | null | Continue-to-shop URL stored on the session, or null. |
cancelUrl | response | string | null | Cancel/expiry redirect, or null. |
invoiceId | response | string | null | Your invoice id. Same value as externalInvoiceId. |
externalInvoiceId | response | string | null | Same as invoiceId (legacy alias). |
source | response | string | How the session was created. API sessions are "api". |
expiresAt | response | string | ISO timestamp. Unpaid checkouts cannot be completed after this time. |
hostedUrl | response | string | Pay page URL (same target as top-level hosted_url on create). |
orderUid | response | string | null | Marketplace order uid after payment. null until the session is paid. |
items | response | object[] | Locked lines: name, description, amount, quantity, imageUrl. Seller GET never includes delivery values. |
قم بتكوين نقاط النهاية HTTPS (أو الويب هوكس Discord) في الإعدادات → المطور. يقوم RMT بإرسال POST عند تشغيل الأحداث المشترك فيها.
ظرف تسليم JSON
{
"id": "whd_…",
"type": "order.paid",
"created": "2026-07-23T12:00:00.000Z",
"data": {
"order": {
"uid": "ord_…",
"reference": "RMT-…",
"status": "PAID",
"url": "https://rmt.gg/orders/ord_…",
"items": [ /* line items with offer names */ ]
}
}
}رؤوس تسليم موقعة
{
"X-RMT-Event": "order.paid",
"X-RMT-Delivery": "whd_…",
"X-RMT-Timestamp": "1710000000",
"X-RMT-Signature": "v1=abc123…"
}حمولة إتمام الدفع
{
"id": "whd_…",
"type": "checkout.completed",
"created": "2026-08-14T12:00:00.000Z",
"data": {
"checkout": {
"uid": "pcs_…",
"status": "paid",
"amount": 10,
"currency": "USD",
"itemName": "Gold pack",
"description": "1000 gold for account example",
"invoiceId": "inv-12345",
"source": "api",
"orderUid": "ord_…",
"hostedUrl": "https://rmt.gg/pay/pcs_…",
"email": "[email protected]",
"paidAt": "2026-08-14T12:01:00.000Z",
"expiresAt": "2026-08-15T12:00:00.000Z",
"createdAt": "2026-08-14T12:00:00.000Z",
"reason": null,
"items": [
{
"name": "Gold pack",
"description": "1000 gold for account example",
"amount": 10,
"quantity": 1,
"imageUrl": "https://cdn.shop.example/gold.png"
}
]
}
}
}حمولة checkout.canceled
{
"id": "whd_…",
"type": "checkout.canceled",
"created": "2026-08-14T12:20:00.000Z",
"data": {
"checkout": {
"uid": "pcs_…",
"status": "canceled",
"amount": 10,
"currency": "USD",
"itemName": "Gold pack",
"description": "1000 gold for account example",
"invoiceId": "inv-12345",
"source": "api",
"orderUid": null,
"hostedUrl": "https://rmt.gg/pay/pcs_…",
"email": "[email protected]",
"paidAt": null,
"expiresAt": "2026-08-15T12:00:00.000Z",
"createdAt": "2026-08-14T12:00:00.000Z",
"reason": "buyer_canceled",
"items": [
{
"name": "Gold pack",
"description": "1000 gold for account example",
"amount": 10,
"quantity": 1,
"imageUrl": "https://cdn.shop.example/gold.png"
}
]
}
}
}عند تعيين سر التوقيع، احسب HMAC-SHA256 على timestamp + '.' + rawBody وقارنه بالهيكس بعد v1=.
تظل السرية على RMT. يتضمن كل POST موقع X-RMT-Timestamp (ثواني Unix) و X-RMT-Signature (v1= بالإضافة إلى hex). احسب HMAC-SHA256 على السلسلة timestamp + '.' + rawBody باستخدام سرك، ثم قارن مع hex بعد v1=. ارفض الطوابع الزمنية التي تزيد عن 5 دقائق.
تحقق TypeScript (مقارنة آمنة زمنياً ونافذة إعادة تشغيل مدتها 5 دقائق)
import { createHmac, timingSafeEqual } from "node:crypto";
const MAX_AGE_SEC = 5 * 60; // reject replays older than 5 minutes
export function verifyRmtSignature(opts: {
secret: string;
timestamp: string | null | undefined;
signatureHeader: string | null | undefined;
rawBody: string; // exact POST bytes. Do not JSON.parse then re-stringify.
nowSec?: number;
}): boolean {
const secret = opts.secret.trim();
const timestamp = String(opts.timestamp ?? "").trim();
const provided = String(opts.signatureHeader ?? "").trim().replace(/^v1=/i, "");
if (!secret || !timestamp || !provided) return false;
const ts = Number(timestamp);
if (!Number.isInteger(ts) || ts <= 0) return false;
const nowSec = opts.nowSec ?? Math.floor(Date.now() / 1000);
if (Math.abs(nowSec - ts) > MAX_AGE_SEC) return false;
const expected = createHmac("sha256", secret)
.update(`${timestamp}.${opts.rawBody}`)
.digest("hex");
const a = Buffer.from(expected, "utf8");
const b = Buffer.from(provided.toLowerCase(), "utf8");
if (a.length !== b.length) return false;
return timingSafeEqual(a, b);
}
// Express / Node HTTP example:
// const rawBody = (req as { rawBody?: string }).rawBody
// ?? JSON.stringify(req.body); // only if you captured the raw string first
// const ok = verifyRmtSignature({
// secret: process.env.RMT_WEBHOOK_SECRET!,
// timestamp: req.headers["x-rmt-timestamp"] as string,
// signatureHeader: req.headers["x-rmt-signature"] as string,
// rawBody,
// });
// if (!ok) return res.status(401).end();
معالج webhook TypeScript
type CheckoutCompleted = {
id: string;
type: "checkout.completed";
created: string;
data: {
checkout: {
uid: string;
status: "paid";
amount: number;
currency: string;
itemName: string | null;
description: string;
invoiceId: string | null;
source: string | null;
orderUid: string | null;
hostedUrl: string;
email: string | null;
paidAt: string | null;
expiresAt: string | null;
createdAt: string | null;
reason: null;
items: Array<{
name: string;
description: string | null;
amount: number;
quantity: number;
imageUrl: string | null;
}>;
};
};
};
type CheckoutCanceled = {
type: "checkout.canceled";
data: {
checkout: {
uid: string;
status: "canceled" | "expired";
invoiceId: string | null;
reason: "buyer_canceled" | "expired";
};
};
};
export async function handleRmtWebhook(rawBody: string, headers: Headers) {
const ok = verifyRmtSignature({
secret: process.env.RMT_WEBHOOK_SECRET!,
timestamp: headers.get("x-rmt-timestamp"),
signatureHeader: headers.get("x-rmt-signature"),
rawBody,
});
if (!ok) throw new Response("Unauthorized", { status: 401 });
const event = JSON.parse(rawBody) as { type: string; data: Record<string, unknown> };
switch (event.type) {
case "checkout.completed": {
const checkout = (event as CheckoutCompleted).data.checkout;
if (!checkout.invoiceId || !checkout.paidAt) break;
await fulfillShopOrder(checkout.invoiceId, checkout.orderUid);
break;
}
case "checkout.canceled": {
const checkout = (event as CheckoutCanceled).data.checkout;
await markShopOrderCanceled(checkout.invoiceId, checkout.reason);
break;
}
case "checkout.refunded":
case "order.paid":
case "order.delivered":
break;
default:
break;
}
}
للعروض COMPLEX (وحدات فريدة)، يمكن لـ RMT إرسال POST إلى نقطة النهاية HTTPS الخاصة بك بعد الدفع لصنع الترخيص التالي، الحساب، أو المفتاح عندما يكون المخزون المحلي قليل.
فشل آمن للدفع
إذا انتهى وقت نقطة النهاية الخاصة بك أو أعادت بيانات غير صالحة، يبقى الطلب مدفوعًا. يتم تحصيل رسوم من المشتري؛ ترى خطأ في الطلب ويمكنك إعادة محاولة الاحتياطي أو إرفاق المفاتيح يدويًا.
جسم POST القياسي (مقصوص)
{
"id": "rsv_…",
"type": "reserve.item",
"order": { "uid": "ord_…", "reference": "RMT-…", "url": "https://rmt.gg/orders/ord_…" },
"offer": { "url": "my-offer", "title": "Game key", "pageUrl": "https://rmt.gg/offers/my-offer" },
"option": { "id": 1, "name": "Standard" },
"fields": [{ "id": 10, "name": "License", "type": "text", "required": true }],
"quantity": 1
}رؤوس الطلبات (عند تعيين سر التوقيع)
{
"Content-Type": "application/json",
"X-RMT-Event": "reserve.item",
"X-RMT-Delivery": "rsv_…",
"X-RMT-Timestamp": "1710000000",
"X-RMT-Signature": "v1=abc123…"
}استجابة ملائمة
{
"entries": [
{ "name": "License", "value": "AAAA-BBBB-CCCC" }
]
}حقول JSON المرسومة (مع مسارات responseMap مثل $.license)
{
"license": "AAAA-BBBB-CCCC",
"email": "[email protected]",
"password": "temporary-pass"
}إذا قمت بتعيين سر على العرض، فإن كل POST احتياطي يتم توقيعه. أعد حساب HMAC-SHA256(secret, timestamp + '.' + rawBody) وقارن مع X-RMT-Signature بعد إزالة بادئة v1=. السر نفسه لا يتم تضمينه أبدًا في الطلب.
انظر مثال التحقق الكاملمعالج reserve TypeScript (تحقق، ثم أعد الإدخالات)
type ReserveRequest = {
id: string;
type: "reserve.item";
dryRun?: boolean;
quantity: number;
fields: Array<{ name: string; required?: boolean }>;
};
export async function handleReserve(rawBody: string, headers: Headers) {
const ok = verifyRmtSignature({
secret: process.env.RMT_RESERVE_SECRET!,
timestamp: headers.get("x-rmt-timestamp"),
signatureHeader: headers.get("x-rmt-signature"),
rawBody,
});
if (!ok) return new Response("Unauthorized", { status: 401 });
const body = JSON.parse(rawBody) as ReserveRequest;
if (body.type !== "reserve.item") {
return Response.json({ error: "Unexpected event" }, { status: 400 });
}
const qty = Number(body.quantity);
if (!Number.isInteger(qty) || qty < 1) {
return Response.json({ error: "Invalid quantity" }, { status: 400 });
}
if (body.dryRun) {
return Response.json({
entries: [{ name: "License", value: "TEST-AAAA-BBBB" }],
});
}
const license = await mintLicense(); // your inventory
return Response.json({
entries: [{ name: "License", value: license }],
});
}
لا تتصل بالاحتياطي قبل الدفع
RMT يتصل بنقطة النهاية الخاصة بك فقط بعد نجاح الدفع، لذا فإن عمليات الخروج المهجورة لا تحرق التراخيص.
تعود الأخطاء بصيغة JSON { error, code? }. يتم تحديد حركة مرور واجهة برمجة التطبيقات المفتوحة إلى 300 طلبات في الدقيقة لكل مفتاح واجهة برمجة التطبيقات.
API_KEY_REQUIREDمفقود Authorization أو X-Api-Key header.
API_KEY_INVALIDالمفتاح غير معروف، تم إلغاؤه، انتهت صلاحيته، أو تم تعليق وصول المطور.
SCOPE_MISSINGالمفتاح يفتقر إلى النطاق المطلوب من قبل نقطة النهاية.
RATE_LIMITEDعدد كبير جدًا من الطلبات. احترم Retry-After وX-RateLimit-Reset.
CHECKOUT_PARTNER_NOT_APPROVEDهذا البائع غير معتمد للخروج المستضاف.
INVALID_JSONيجب أن يكون جسم الطلب JSON.
INVALID_AMOUNTيجب أن تكون القيمة أكبر من 0 وأقصى حد 1,000,000.
UNSUPPORTED_CURRENCYالعملة ليست رمز ISO مدعوم.
INVALID_RETURN_URLيجب أن يكون returnUrl و cancelUrl https (http://localhost مسموح به للمتاجر المحلية).
INVALID_PSP_CATEGORYيجب إرسال categorySlug و offering معًا ومطابقة زوج من الكتالوج.
INVALID_INVOICE_IDinvoiceId أطول من 128 حرفًا.
INVOICE_ID_REQUIREDGET /checkout/sessions يتطلب invoiceId كمعامل استعلام.
INVALID_IDEMPOTENCY_KEYIdempotency-Key أطول من 128 حرفًا.
INVALID_METADATAيجب أن تكون metadata كائن JSON، وليس مصفوفة أو قيمة بدائية.
METADATA_TOO_LARGEالبيانات الوصفية المتسلسلة أكبر من 4096 حرفًا.
IDEMPOTENCY_CONFLICTتم إعادة استخدام Idempotency-Key مع مبلغ مختلف أو عملة أو عنصر.
INVOICE_CONFLICTتم إعادة استخدام invoiceId مع مبلغ مختلف أو عملة أو عنصر.
INVALID_IMAGE_URLيجب أن يكون imageUrl رابط https.
ITEM_NAME_REQUIREDاسم العنصر (أو العنوان) مطلوب عند عدم وجود عناصر.
INVALID_ITEMSيجب أن تكون items مصفوفة غير فارغة من العناصر المقفلة (بحد أقصى 20). يحتاج كل عنصر إلى اسم ومبلغ.
TOO_MANY_ITEMSلا يمكن أن تحتوي items على أكثر من 20 عنصر.
AMOUNT_MISMATCHيجب أن يساوي المبلغ مجموع كل مبلغ عنصر مضروبًا في الكمية.
INVALID_DELIVERYحقول التسليم غير صالحة. يحتاج كل حقل إلى اسم (بحد أقصى 80) وقيمة (بحد أقصى 2048). يجب أن يكون النوع نصًا، كلمة مرور، أو منطقة نصية (النص الافتراضي). الحد الأقصى 16 حقلًا لكل سطر.
ITEMS_TOO_LARGEJSON العناصر المتسلسلة أكبر من 48,000 حرف.
NOT_FOUNDلا توجد جلسة دفع مستضافة تتطابق مع uid أو invoiceId لهذا البائع.
RESERVE_FAILEDانتهى وقت الويب هوك الاحتياطي، أعاد بيانات غير صالحة، أو فاته حقول مطلوبة.
OPTION_AMBIGUOUSهناك أكثر من خيار تسعير واحد يتطابق مع ذلك الاسم. مرر optionId من GET stock.
OPTION_NOT_FOUNDلا يوجد خيار تسعير يتطابق مع ذلك المعرف أو الاسم في هذه القائمة.
OPTION_REQUIREDتحتوي هذه القائمة على خيارات تسعير متعددة. مرر الخيار أو optionId.
UNKNOWN_FIELDاسم الحقل لا يتطابق مع مخطط تسليم هذه القائمة.
FIELD_MAPPING_AMBIGUOUSلم يتمكن من مطابقة الأعمدة أو المفاتيح مع حقول التسليم. أرسل رؤوس، أو استخدم كائنات العناصر المفاتيح حسب اسم الحقل.
STOCK_MODE_MISMATCHلا يتطابق هذا الحمولة مع وضع مخزون الخيار (الكمية مقابل العناصر المحفوظة).
IMPORT_TOO_LARGEقد تستورد طلب إعادة التعبئة في أقصى حد 1,000 عنصر محفوظ لكل خيار.
OPTION_ITEM_CAPACITYهذا الخيار لديه بالفعل الحد الأقصى من 5,000 عنصر محفوظ غير مبيع.
DUPLICATE_ITEMSonDuplicate=error و يوجد عنصر واحد على الأقل موجود بالفعل في هذا الخيار.
UNLIMITED_STOCKهذا الخيار لديه كمية غير محدودة. استخدم set للتبديل إلى عدد محدود أولاً.
INSUFFICIENT_STOCKلا يوجد كمية كافية من المخزون للإزالة.
STOCK_HELD_IN_CHECKOUTلا يمكن تقليل الكمية تحت الوحدات المحجوزة حاليًا في عملية الدفع.
INVALID_RESTOCKجسم إعادة التعبئة يفتقر إلى إجراء مطلوب، أو يجمع بين add/items في خيار واحد.
| الكود | HTTP | الوصف |
|---|---|---|
| API_KEY_REQUIRED | 401 | مفقود Authorization أو X-Api-Key header. |
| API_KEY_INVALID | 401 | المفتاح غير معروف، تم إلغاؤه، انتهت صلاحيته، أو تم تعليق وصول المطور. |
| SCOPE_MISSING | 403 | المفتاح يفتقر إلى النطاق المطلوب من قبل نقطة النهاية. |
| RATE_LIMITED | 429 | عدد كبير جدًا من الطلبات. احترم Retry-After وX-RateLimit-Reset. |
| CHECKOUT_PARTNER_NOT_APPROVED | 403 | هذا البائع غير معتمد للخروج المستضاف. |
| INVALID_JSON | 400 | يجب أن يكون جسم الطلب JSON. |
| INVALID_AMOUNT | 400 | يجب أن تكون القيمة أكبر من 0 وأقصى حد 1,000,000. |
| UNSUPPORTED_CURRENCY | 400 | العملة ليست رمز ISO مدعوم. |
| INVALID_RETURN_URL | 400 | يجب أن يكون returnUrl و cancelUrl https (http://localhost مسموح به للمتاجر المحلية). |
| INVALID_PSP_CATEGORY | 400 | يجب إرسال categorySlug و offering معًا ومطابقة زوج من الكتالوج. |
| INVALID_INVOICE_ID | 400 | invoiceId أطول من 128 حرفًا. |
| INVOICE_ID_REQUIRED | 400 | GET /checkout/sessions يتطلب invoiceId كمعامل استعلام. |
| INVALID_IDEMPOTENCY_KEY | 400 | Idempotency-Key أطول من 128 حرفًا. |
| INVALID_METADATA | 400 | يجب أن تكون metadata كائن JSON، وليس مصفوفة أو قيمة بدائية. |
| METADATA_TOO_LARGE | 400 | البيانات الوصفية المتسلسلة أكبر من 4096 حرفًا. |
| IDEMPOTENCY_CONFLICT | 409 | تم إعادة استخدام Idempotency-Key مع مبلغ مختلف أو عملة أو عنصر. |
| INVOICE_CONFLICT | 409 | تم إعادة استخدام invoiceId مع مبلغ مختلف أو عملة أو عنصر. |
| INVALID_IMAGE_URL | 400 | يجب أن يكون imageUrl رابط https. |
| ITEM_NAME_REQUIRED | 400 | اسم العنصر (أو العنوان) مطلوب عند عدم وجود عناصر. |
| INVALID_ITEMS | 400 | يجب أن تكون items مصفوفة غير فارغة من العناصر المقفلة (بحد أقصى 20). يحتاج كل عنصر إلى اسم ومبلغ. |
| TOO_MANY_ITEMS | 400 | لا يمكن أن تحتوي items على أكثر من 20 عنصر. |
| AMOUNT_MISMATCH | 400 | يجب أن يساوي المبلغ مجموع كل مبلغ عنصر مضروبًا في الكمية. |
| INVALID_DELIVERY | 400 | حقول التسليم غير صالحة. يحتاج كل حقل إلى اسم (بحد أقصى 80) وقيمة (بحد أقصى 2048). يجب أن يكون النوع نصًا، كلمة مرور، أو منطقة نصية (النص الافتراضي). الحد الأقصى 16 حقلًا لكل سطر. |
| ITEMS_TOO_LARGE | 400 | JSON العناصر المتسلسلة أكبر من 48,000 حرف. |
| NOT_FOUND | 404 | لا توجد جلسة دفع مستضافة تتطابق مع uid أو invoiceId لهذا البائع. |
| RESERVE_FAILED | 400 | انتهى وقت الويب هوك الاحتياطي، أعاد بيانات غير صالحة، أو فاته حقول مطلوبة. |
| OPTION_AMBIGUOUS | 409 | هناك أكثر من خيار تسعير واحد يتطابق مع ذلك الاسم. مرر optionId من GET stock. |
| OPTION_NOT_FOUND | 404 | لا يوجد خيار تسعير يتطابق مع ذلك المعرف أو الاسم في هذه القائمة. |
| OPTION_REQUIRED | 400 | تحتوي هذه القائمة على خيارات تسعير متعددة. مرر الخيار أو optionId. |
| UNKNOWN_FIELD | 400 | اسم الحقل لا يتطابق مع مخطط تسليم هذه القائمة. |
| FIELD_MAPPING_AMBIGUOUS | 400 | لم يتمكن من مطابقة الأعمدة أو المفاتيح مع حقول التسليم. أرسل رؤوس، أو استخدم كائنات العناصر المفاتيح حسب اسم الحقل. |
| STOCK_MODE_MISMATCH | 400 | لا يتطابق هذا الحمولة مع وضع مخزون الخيار (الكمية مقابل العناصر المحفوظة). |
| IMPORT_TOO_LARGE | 400 | قد تستورد طلب إعادة التعبئة في أقصى حد 1,000 عنصر محفوظ لكل خيار. |
| OPTION_ITEM_CAPACITY | 400 | هذا الخيار لديه بالفعل الحد الأقصى من 5,000 عنصر محفوظ غير مبيع. |
| DUPLICATE_ITEMS | 409 | onDuplicate=error و يوجد عنصر واحد على الأقل موجود بالفعل في هذا الخيار. |
| UNLIMITED_STOCK | 400 | هذا الخيار لديه كمية غير محدودة. استخدم set للتبديل إلى عدد محدود أولاً. |
| INSUFFICIENT_STOCK | 400 | لا يوجد كمية كافية من المخزون للإزالة. |
| STOCK_HELD_IN_CHECKOUT | 400 | لا يمكن تقليل الكمية تحت الوحدات المحجوزة حاليًا في عملية الدفع. |
| INVALID_RESTOCK | 400 | جسم إعادة التعبئة يفتقر إلى إجراء مطلوب، أو يجمع بين add/items في خيار واحد. |
تعامل مع 429
تراجع باستخدام Retry-After seconds. لا تقم بتدوير المفاتيح لتجاوز الحدود؛ الحد هو لكل مفتاح وثابت لجميع البائعين.
تتضمن الاستجابات الناجحة X-RateLimit-Limit، X-RateLimit-Remaining، وX-RateLimit-Reset.
قم بإنشاء مفتاح في إعدادات المطور، ووصّل Discord أو Telegram تحت الإشعارات.