برای هر فاکتور یک مبلغ یکتا ساخته میشود. مشتری همان مبلغ را کارتبهکارت میکند، پیامک بانک به سرور میرسد و پرداخت بدون دخالت انسان تأیید میشود — بعد وبهوک امضاشده به فروشگاه شما میرود.
همین مبلغ، همین پسوند، فقط برای همین فاکتور. تا وقتی فاکتور باز است هیچ پذیرنده دیگری این عدد را نمیگیرد.
این ترتیب مهم است: مبلغ یکتا پیش از پرداخت ساخته میشود، پیامک شاهد است نه ادعا، و وبهوک بعد از قطعیشدن پول میرود. اگر جایی گیر کردید، همین ترتیب را دنبال کنید تا بفهمید کدام مرحله انجام نشده.
یک درخواست به POST /api/v1/payments میفرستید. کارمزد اضافه میشود و یک پسوند یکتا روی مبلغ مینشیند تا هیچ دو فاکتور فعالی مبلغ یکسان نداشته باشند.
صفحه پرداخت شماره کارت، مبلغ دقیق به تومان و ریال، و زمان باقیمانده را نشان میدهد. کم یا زیاد واریز کردن، پرداخت را ناموفق میکند — و همین است که تطبیق را ممکن میسازد.
برنامه فورواردر روی گوشی، پیامک بانک را به POST /sms میفرستد. احراز هویت با همان کلید API انجام میشود و پیامک تکراری پیش از هر پردازشی رد میشود.
مبلغ، شماره پیگیری، کارت مبدأ و مقصد و زمان پیامک استخراج میشوند و با فاکتورهای فعال همان پذیرنده مقایسه میشوند. ارقام فارسی و عربی و جداکنندههای هزار پیش از خواندن مبلغ یکسانسازی میشوند.
اگر مبلغ یکتا، پنجره زمانی و شماره پیگیری کنار هم بنشینند، فاکتور PAID میشود و کارمزد از کیف پول کسر میگردد. هر نشانه مشکوک، پرداخت را به صف بررسی دستی میفرستد و پول تا تصمیم مدیر معلق میماند.
رویداد payment.success با امضای HMAC-SHA256 به آدرس شما میرود، با تلاش مجدد پلهای و لاگ تحویل. اگر سرور شما پایین باشد، پرداخت برنمیگردد؛ فقط تحویل دوباره تلاش میشود.
مبلغ یکتا در پاسخ برمیگردد چون خودش بخشی از نتیجه است: همان عددی است که باید در تلفن بانک ببینید. وبهوک هم امضا دارد تا مطمئن شوید از طرف ما آمده.
curl -X POST https://steve-gate.ir/api/v1/payments \ -H "X-API-Key: sk_live_\ -H "Idempotency-Key: order-1234" \ -H "Content-Type: application/json" \ -d '{ "amount": 359000, "description": "سفارش ۱۲۳۴", "customCallback": "https://shop.example.com/pay/callback", "metadata": { "orderId": "1234" } }' "
{
"success": true,
"invoiceId": "inv_01J8XK4M2Q",
"amount": 365706, // تومان — مبلغ دقیق پرداخت
"amountRial": 3657060, // ریال
"uniqueSuffix": 3706,
"paymentUrl": "https://steve-gate.ir/pay/inv_01J8XK4M2Q",
"status": "pending",
"expiresAt": "2026-09-22T09:41:07.000Z"
}
// سرور شما، هنگام تأیید پرداخت POST /pay/callback X-StevePay-Signature: t=1758534120,v1=8f2c… X-StevePay-Event: payment.success X-StevePay-Delivery: whd_01J8XK9Q7A { "event": "payment.success", "invoiceId": "inv_01J8XK4M2Q", "status": "paid", "amount": 365706, "originalAmount": 359000, "fee": 3000, "paidAt": "2026-09-22T09:38:52.000Z" }
این تفاوت را در پیام خطاها میبینید: حالتی که باید رد شود، رد میشود و به جای امیدواری، علتش را میگوید.
بعد از ثبتنام، مدیر حساب را بررسی و تأیید میکند. پس از تأیید کلید API ساخته میشود و میتوانید مسیر کامل را با یک تراکنش آزمایشی امتحان کنید.
REGISTER → ADMIN APPROVAL → API KEY → FIRST PAYMENT