همهٔ درخواستها با هدر 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":"…"}. متن پس از خواندن نگه داشته نمیشود.