برای برنامه‌نویس‌ها

مستندات API

ساخت پرداخت، گرفتن وضعیت و وب‌هوک امضاشده با یک کلید. تازه شروع کرده‌اید؟ راهنمای قدم‌به‌قدم اتصال را بخوانید.

همهٔ درخواست‌ها با هدر Authorization: Bearer <کلید>. کلید یک رشتهٔ ۶۴ کاراکتری (مثل 9f2c…e41a) است که از پنل ← «اتصال و API» می‌سازید. کلیدی که در حالت «آزمایشی» ساخته شود فقط پرداخت آزمایشی می‌سازد و پول واقعی ندارد.

۱. API ساده برای ربات‌ها (مبلغ به تومان)

ساده‌ترین راه اتصال ربات فروش: یک درخواست برای ساخت لینک پرداخت و یک وب‌هوک برای خبر پرداخت. برای سازندگان ربات: آدرس پایه را در کد ثابت بگذارید تا فروشنده فقط کلید API را وارد کند.

ساخت لینک پرداخت (مبلغ به تومان)

POST https://api.residino.com/api/v1/pay
{"amount": 250000, "return_url": "https://example.com/back?order=7", "title": "سفارش ۷", "expires_in": "1h"}
200 OK
{"slug":"3b72…","pay_url":"https://api.residino.com/p/3b72…","amount":250000,"payable_amount":249900,
 "currency":"IRT","card":{"number":"6104…","last4":"6650","holder":"…","bank_code":"mellat","bank_name":"ملت"},
 "expires_in":3600,"status":"pending", …}

شمارهٔ کامل کارت فقط در پاسخِ ساختِ پرداخت می‌آید (همان که به خریدار نشان می‌دهید). در استعلام وضعیت و فهرست، فقط چهار رقم آخر (last4) برمی‌گردد تا شمارهٔ کارت بی‌دلیل در لاگ‌های شما تکرار نشود؛ اگر باز هم لازم شد، خریدار را به pay_url بفرستید.

payable_amount مبلغ یکتایی است که مشتری باید دقیقاً واریز کند. وضعیت: GET /api/v1/pay/{slug}.

۲. API اختصاصی (مبلغ به ریال)

درخواستکار
POST /v1/paymentsساخت پرداخت؛ بدنه: amount_rial، اختیاری order_ref (تکرار با همان مقدار همان پرداخت را برمی‌گرداند)، title، return_url، ttl_seconds
GET /v1/payments/{id}وضعیت یک پرداخت
GET /v1/payments?status=&limit=&before=فهرست با صفحه‌بندی
POST /v1/payments/{id}/cancelلغو پرداخت باز
GET /v1/events?after=فید رویدادها برای کسانی که وب‌هوک ندارند
curl -X POST https://api.residino.com/v1/payments \
  -H "Authorization: Bearer 9f2c…e41a" -H "Content-Type: application/json" \
  -d '{"amount_rial": 2500000, "order_ref": "order-1001"}'

۳. وب‌هوک

پس از هر رویداد، بدنهٔ JSON با هدر X-Webhook-Signature: sha256=<HMAC> فرستاده می‌شود؛ HMAC-SHA256 روی بدنهٔ خام با رمز امضای پنل. هر پاسخ غیر ۲xx تا حدود ۱٫۵ روز دوباره ارسال می‌شود؛ گیرنده باید با event_id یا slug تکرار را کنار بگذارد.

{"event":"payment.paid","event_id":"…","mode":"live","slug":"3b72…","payment_id":"3b72…",
 "order_ref":"order-1001","amount":250000,"amount_rial":2500000,"payable_amount_rial":2499000,
 "status":"paid","paid_at":"2026-10-06T06:05:00Z","via":"auto"}

رویدادهای ناشناخته را نادیده بگیرید و فقط به payment.paid سفارش تحویل دهید؛ رویدادهای تازه ممکن است بعداً اضافه شوند.

amount همیشه مبلغ سفارش (تومان) است، نه مبلغ یکتا؛ پس مقایسهٔ «مبلغ دریافتی ≥ مبلغ فاکتور» در ربات درست کار می‌کند.

رویدادمعنی
payment.paidپرداخت تأیید شد (خودکار، دستی یا دیرهنگام — در via)
payment.expiredمهلت پرداخت گذشت؛ واریز دیرهنگام هنوز قابل تأیید دستی است
deposit.reviewواریزی رسید که خودکار تأیید نشد؛ با فهرست سفارش‌های احتمالی (candidates)
payment.claimedمشتری در صفحهٔ پرداخت گفته «واریز کردم ولی تأیید نشد» (چهار رقم آخر کارت، ساعت یا شمارهٔ پیگیری). فقط خبر است؛ پرداخت را تأیید نمی‌کند
device.silent / device.recoveredگوشی فروشنده ساکت شد / دوباره وصل شد
// PHP: بررسی امضا
$raw = file_get_contents('php://input');
$sig = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? '';
if (!hash_equals('sha256=' . hash_hmac('sha256', $raw, $secret), $sig)) { http_response_code(400); exit; }

۴. خطاها

پاسخ خطا: {"ok":false,"error":"<کد>"}. کدهای رایج: unauthorized (۴۰۱)، invalid_amount، amount_out_of_range (۴۲۲)، subscription_inactive، plan_quota_reached (۴۰۲)، no_card_available، amount_slots_exhausted (۵۰۳)، rate_limited (۴۲۹).

۵. ورودی پیامک برای اپ‌های فوروارد و آیفون

از پنل ← «گوشی‌ها» یک کلید دستگاه بگیرید و پیامک را بفرستید: POST /device/v1/raw با Authorization: Bearer dev_… و بدنهٔ {"sender":"…","text":"…"}. متن پس از خواندن نگه داشته نمی‌شود.