معرفی
API میومیو هر چیزی را که در داشبورد میتوانید انجام دهید · ثبت سفارش، بررسی وضعیت، فهرست سرویسها و خواندن موجودی کیف پول · بهصورت یک REST API تمیز در اختیار قرار میدهد. همهٔ درخواستها و پاسخها JSON روی HTTPS هستند. آدرس پایه: https://api.followbank.io
احراز هویت
با کلید API خود بهعنوان Bearer token در هدر Authorization احراز هویت کنید. کلیدها را از داشبورد بسازید، برچسب بزنید و بازتولید کنید. هر درخواست شمارندهٔ محدودیت نرخ مخصوص آن کلید را نیز افزایش میدهد (به محدودیت نرخ مراجعه کنید).
سه روش پذیرفتهشده برای ارسال کلید
Authorization: Bearer fb_live_… (توصیهشده)، X-Api-Key: fb_live_… (هدر جایگزین)، یا key=fb_live_… بهعنوان فیلد form یا query برای کلاینتهای سازگار با Perfect Panel. هر کدام را که با stack شما جور است انتخاب کنید · سرور هر سه را یکسان رفتار میکند.
curl https://api.followbank.io/v1/reseller/balance \
-H "Authorization: Bearer fb_live_a1b2c3..."فهرست سرویسها
GET/v1/reseller/servicesکاتالوگ کامل سرویسهایی که caller میتواند سفارش دهد را با نرخهای زندهٔ بهازای هر هزار، حداقل/حداکثر تعداد، پرچم جبران ریزش و شناسهٔ پلتفرم برمیگرداند. پاسخها را تا ۵ دقیقه cache کنید · نرخها وقتی مسیریابی پروایدر تغییر کند، تغییر میکنند.
curl https://api.followbank.io/v1/reseller/services \
-H "Authorization: Bearer fb_live_•••••"دریافت موجودی
GET/v1/reseller/balanceموجودی فعلی کیف پول، ارز و هرگونه بلوکهٔ در حال بررسی را برمیگرداند. بهعنوان guard پیش از ثبت یک batch سفارش مفید است تا fail-fast سمت کلاینت اتفاق بیفتد به جای دیدن INSUFFICIENT_BALANCE بعد از اولین درخواست.
curl https://api.followbank.io/v1/reseller/balance \
-H "Authorization: Bearer fb_live_•••••"ثبت سفارش
POST/v1/reseller/ordersیک سفارش جدید میسازد. هزینه در زمان درخواست بهعنوان HOLD از کیف پول کسر میشود؛ پس از ارسال به پروایدر به DEBIT تبدیل میشود. هدر Idempotency-Key بفرستید تا retry امن باشد.
curl -X POST https://api.followbank.io/v1/reseller/orders \
-H "Authorization: Bearer fb_live_•••••" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"serviceId": "svc_01ABCDE...",
"link": "https://instagram.com/yourbrand",
"quantity": 1000
}'دریافت یک سفارش
GET/v1/reseller/orders/{id}وضعیت فعلی یک سفارش را برمیگرداند: status, start count, remains, charge, شناسهٔ سفارش پروایدر و timestampها. این endpoint را poll کنید یا به وبهوکها subscribe شوید · وبهوکها بهتر scale میشوند.
| وضعیت | معنی |
|---|---|
| PENDING | هزینه کسر و در صف ارسال قرار گرفت. |
| WAITING_PROVIDER | در حال حاضر هیچ مپینگ پروایدر مناسبی وجود ندارد · تلاش مجدد. |
| IN_PROGRESS | توسط پروایدر پذیرفته شد و در حال انجام است. |
| PARTIAL | پروایدر بخشی را تحویل داد نه همه؛ بازپرداخت برای بخش انجامنشده در صف. |
| COMPLETED | کاملاً تحویل داده شد. پایانی. |
| CANCELED | پیش از ارسال لغو شد؛ HOLD آزاد شد. پایانی. |
| REFUNDED | بازپرداخت بعد از واقعه صادر شد (دستی یا خودکار). پایانی. |
| FAILED | قابل انجام نبود (خطای پروایدر، لینک نامعتبر). پایانی. |
curl https://api.followbank.io/v1/reseller/orders/ord_01ABC... \
-H "Authorization: Bearer fb_live_•••••"دریافت چند سفارش
GET/v1/reseller/orders?ids=...جستجوی وضعیت برای تا ۵۰ سفارش در یک بار. برای refresh یک صفحه از سفارشهای در حال انجام در یک round-trip مفید است. لیست comma-separated از شناسههای سفارش را در query parameter `ids` ارسال کنید.
curl 'https://api.followbank.io/v1/reseller/orders?ids=ord_01A,ord_01B,ord_01C' \
-H "Authorization: Bearer fb_live_•••••"لغو سفارش
POST/v1/reseller/orders/{id}/cancelسفارشی که هنوز شروع نشده را لغو میکند. فقط در حالی معتبر است که سفارش در PENDING یا WAITING_PROVIDER باشد · بعد از پذیرش توسط پروایدر، لغو وابسته به پروایدر است و ممکن است رد شود.
curl -X POST https://api.followbank.io/v1/reseller/orders/ord_01ABC.../cancel \
-H "Authorization: Bearer fb_live_•••••"وبهوکها
میومیو هر رویداد را یکبار به URL وبهوک تنظیمشدهٔ شما POST میکند. هر بدنه یک امضای HMAC-SHA256 مشتقشده از secret وبهوک کلید شما در هدر X-MIUMIU-Signature دارد. پیش از عمل روی payload، امضا را تأیید کنید · هر کسی میتواند به endpoint شما POST کند، اما فقط ما میتوانیم امضا کنیم.
| رویداد | زمان شلیک |
|---|---|
| order.placed | یک سفارش ساخته میشود (از طریق API یا داشبورد). |
| order.status_changed | یک سفارش بین وضعیتهای غیرپایانی منتقل میشود. |
| order.completed | یک سفارش به COMPLETED میرسد · تحویل کامل تأیید میشود. |
| order.refunded | بازپرداختی به کیف پول شما صادر میشود. |
| wallet.credited | یک شارژ تأیید میشود؛ موجودی اکنون در دسترس است. |
import { createHmac, timingSafeEqual } from 'node:crypto';
/** Verifies an inbound MIUMIU webhook. Reject anything that fails. */
function verifySignature(rawBody, signatureHeader, secret) {
const expected = createHmac('sha256', secret).update(rawBody).digest('hex');
const got = Buffer.from(signatureHeader, 'hex');
const exp = Buffer.from(expected, 'hex');
return got.length === exp.length && timingSafeEqual(got, exp);
}
// Express-style handler - read raw body (not parsed JSON) for the HMAC.
app.post('/webhooks/MIUMIU', (req, res) => {
const sig = req.header('x-miumiu-signature');
if (!verifySignature(req.rawBody, sig, process.env.FB_WEBHOOK_SECRET)) {
return res.status(401).end();
}
const evt = JSON.parse(req.rawBody.toString('utf8'));
// ... handle evt.event, evt.data ...
res.status(204).end();
});خطاها
همهٔ خطاها یک پوشش JSON برمیگردانند: { error: { code, message, details? } }. وضعیت HTTP از قراردادهای REST پیروی میکند · 4xx برای خطاهای کلاینت، 429 برای محدودیت نرخ، 5xx برای سمت ما. کد `code` پایدار است؛ پیام `message` متن قابل خواندن انسان است و میتواند تغییر کند.
| کد | HTTP | معنی |
|---|---|---|
| BAD_REQUEST | 400 | بدنه از اعتبارسنجی schema رد شد. `details.fields` فیلدها را فهرست میکند. |
| UNAUTHORIZED | 401 | کلید API ندارد، نامعتبر یا revoke شده است. |
| FORBIDDEN | 403 | کلید معتبر است اما scope لازم را ندارد. |
| NOT_FOUND | 404 | سفارش، سرویس یا منبع برای این caller وجود ندارد. |
| CONFLICT | 409 | عملیات در وضعیت فعلی معتبر نیست (مثلاً لغو سفارش IN_PROGRESS). |
| INSUFFICIENT_BALANCE | 409 | موجودی کیف پول کمتر از هزینهٔ سفارش است. شارژ کنید و دوباره امتحان کنید. |
| RATE_LIMITED | 429 | درخواستهای زیاد روی این کلید. عقب بنشینید · `details.retryAfterSec` میگوید چقدر. |
| UPSTREAM | 502 | یک پروایدر downstream شکست خورد؛ خود درخواست معتبر بود. retry امن است. |
# Example: insufficient funds at order placement
{
"error": {
"code": "INSUFFICIENT_BALANCE",
"message": "موجودی کیف پول کافی نیست"
}
}Idempotency
هدر Idempotency-Key (هر رشتهٔ opaque تا ۱۲۸ کاراکتر) را روی هر POST که state میسازد ارسال کنید. ما پاسخ اول را به مدت ۲۴ ساعت cache میکنیم · درخواستهای تکراری با همان کلید، بدنهٔ اصلی، status code و headerها را برمیگردانند. برای هر عملیات منطقی، یک UUID تازه بسازید.
curl -X POST https://api.followbank.io/v1/reseller/orders \
-H "Authorization: Bearer fb_live_•••••" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 7c9a1f-2026-05-31" \
-d '{"serviceId":"svc_01ABC...","link":"https://x.com/y","quantity":500}'
# Re-running the same command returns the original order, not a new one.محدودیت نرخ
هر کلید API یک سهمیهٔ درخواست در دقیقه دارد (پیشفرض ۶۰۰ در دقیقه، روی پلن Pro به بالا قابل تنظیم برای هر کلید). تجاوز از آن 429 RATE_LIMITED با retryAfterSec در `details` برمیگرداند. پنجره sliding است · وقتی یک درخواست از پنجرهٔ ۶۰ ثانیهای خارج میشود دیگر شمرده نمیشود.
Retry امن در burst
روی 429، `retryAfterSec` ثانیه قبل از فراخوانی بعدی به همان endpoint بخوابید. هدر پاسخ X-RateLimit-Remaining (وقتی موجود است) bucket فعلی را منعکس میکند · از آن برای throttle پیشگیرانه به جای واکنشی استفاده کنید.
در یکپارچهسازی به کمک نیاز دارید؟
روی تأیید HMAC یا 409 ناآشنا گیر کردهاید؟ از داشبورد یک تیکت با delivery ID باز کنید · تیکتهای API را ابتدا triage میکنیم.