مستندات API میندراپی

API ساده و REST است: یک فاکتور می‌سازید، خریدار را به صفحه پرداخت می‌فرستید (یا شماره کارت و مبلغ را خودتان نشان می‌دهید)، و بعد از واریز یک وبهوک امضاشده می‌گیرید.

آدرس پایه: https://pay.mindraco.ir/api/v1
قالب: JSON، مبالغ به تومان (فیلد payable_amount_rial به ریال هم برمی‌گردد)، زمان‌ها ISO 8601.

احراز هویت

کلیدها را از «تنظیمات و API» بسازید. کلید mp_test_… فاکتور تست می‌سازد که با شبیه‌ساز پرداخت می‌شود و پولی جابه‌جا نمی‌شود؛ کلید mp_live_… واقعی است.

Authorization: Bearer mp_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

ساخت فاکتور

POST /api/v1/invoices
فیلدالزامیتوضیح
amountبلهمبلغ به تومان؛ مبلغ یکتای واریزی کمی بیشتر می‌شود
order_idخیرشماره سفارش شما؛ اگر فاکتور باز با همین سفارش و مبلغ باشد همان برمی‌گردد
callback_urlخیربعد از پرداخت خریدار به این آدرس برمی‌گردد
descriptionخیرروی صفحه پرداخت نمایش داده می‌شود
customer_name، customer_mobileخیربرای نمایش در پنل و صف بررسی
expires_inخیرمهلت پرداخت به دقیقه (۵ تا ۱۴۴۰)
metadataخیرشیء دلخواه تا ۲۰ کلید؛ در وبهوک برمی‌گردد
curl -X POST https://pay.mindraco.ir/api/v1/invoices \
  -H "Authorization: Bearer mp_test_..." \
  -H "Content-Type: application/json" \
  -d '{"amount": 250000, "order_id": "1042", "callback_url": "https://shop.ir/checkout/done"}'

پاسخ 201:

{
  "id": "01JAB3K9Z8WQ6T4N2XKQ6S1M7C",
  "object": "invoice",
  "status": "pending",
  "test": true,
  "order_id": "1042",
  "amount": 250000,
  "payable_amount": 250013,
  "payable_amount_rial": 2500130,
  "currency": "IRT",
  "card": { "number": "6037991122334455", "holder": "آرش ماهر", "bank": "ملی" },
  "pay_url": "https://pay.mindraco.ir/pay/01JAB3K9Z8WQ6T4N2XKQ6S1M7C",
  "expires_at": "2026-10-19T16:40:00+03:30",
  "paid_at": null,
  "matched_by": null,
  "metadata": null
}

ساده‌ترین راه: خریدار را به pay_url بفرستید. اگر می‌خواهید صفحه خودتان را داشته باشید، payable_amount و card را نمایش دهید و تأکید کنید مبلغ دقیق واریز شود.

دریافت، فهرست و لغو

GET  /api/v1/invoices/{id}
GET  /api/v1/invoices?status=paid&order_id=1042&per_page=20
POST /api/v1/invoices/{id}/cancel
GET  /api/v1/me

وضعیت‌ها

pendingمنتظر واریز
reviewواریزی رسیده ولی تطبیق قطعی نبود؛ فروشنده دستی تأیید می‌کند
paidپرداخت شد (matched_by: auto، manual یا sandbox)
expiredمهلت تمام شد. اگر واریز دیرهنگام برسد ممکن است بعداً paid شود؛ به وبهوک تکیه کنید
cancelledلغو شده

شبیه‌سازی پرداخت (فقط کلید تست)

POST /api/v1/invoices/{id}/simulate-payment

فاکتور تست را پرداخت‌شده می‌کند و وبهوک invoice.paid را واقعاً می‌فرستد؛ برای تست کامل افزونه یا سایت.

وبهوک‌ها

رویدادها: invoice.paid، invoice.expired، invoice.cancelled. هر رویداد یک POST با بدنه JSON است:

{
  "id": "evt_01JAB3..._a1b2c3d4",
  "type": "invoice.paid",
  "created_at": "2026-10-19T16:31:12+03:30",
  "data": { ...همان شیء فاکتور... }
}

هدر X-MindraPay-Signature به شکل t=1760880672,v1=… است؛ v1 برابر HMAC-SHA256 رشته t + "." + body با «رمز امضای وبهوک» شماست. هر پاسخ غیر 2xx تا ۶ بار با فاصله‌های ۱۰ ثانیه تا ۲ ساعت دوباره ارسال می‌شود. رویداد ممکن است تکراری برسد؛ با data.id یکتا کنید.

// PHP
$body = file_get_contents('php://input');
$hdr  = $_SERVER['HTTP_X_MINDRAPAY_SIGNATURE'] ?? '';
parse_str(str_replace(',', '&', $hdr), $p);
$ok = isset($p['t'], $p['v1'])
   && abs(time() - (int) $p['t']) < 600
   && hash_equals(hash_hmac('sha256', $p['t'].'.'.$body, $secret), $p['v1']);
if (! $ok) { http_response_code(401); exit; }
$event = json_decode($body, true);
if ($event['type'] === 'invoice.paid') { /* سفارش را پرداخت‌شده کنید */ }
http_response_code(200);
// Node.js (Express, raw body)
const crypto = require('crypto');
function verify(rawBody, header, secret) {
  const p = Object.fromEntries(header.split(',').map(x => x.split('=')));
  const mac = crypto.createHmac('sha256', secret).update(p.t + '.' + rawBody).digest('hex');
  return Math.abs(Date.now() / 1000 - Number(p.t)) < 600 &&
         crypto.timingSafeEqual(Buffer.from(mac), Buffer.from(p.v1 || ''));
}

بازگشت خریدار

بعد از پرداخت خریدار به callback_url با پارامترهای invoice_id، order_id، status و sig برمی‌گردد. sig برابر HMAC-SHA256(invoice_id|status|order_id) با همان رمز است. برای اطمینان کامل وضعیت را با GET /api/v1/invoices/{id} هم بخوانید.

خطاها

خطاهای اعتبارسنجی 422 با پیام فارسی برمی‌گردند (مثلاً نبودن کارت فعال یا تمام شدن سهمیه). کلید نامعتبر 401، پلن بدون API 402 و محدودیت نرخ 429 (۱۲۰ درخواست در دقیقه).

افزونه ووکامرس

  1. فایل mindrapay-woocommerce.zip را از افزونه‌ها › افزودن › بارگذاری نصب کنید.
  2. ووکامرس › تنظیمات › پرداخت‌ها › «کارت‌به‌کارت خودکار میندراپی» را باز کنید.
  3. کلید API و رمز امضای وبهوک را وارد کنید و «آزمایش اتصال» را بزنید.
  4. آدرس وبهوکی که افزونه نشان می‌دهد را در «تنظیمات و API» پنل وارد کنید.

اپ اندروید (فورواردر)

اپ را روی گوشی‌ای نصب کنید که سیم‌کارت پیامک بانک را دارد. آدرس سرور و کد جفت‌سازی را وارد کنید و اجازه خواندن پیامک بدهید. اپ فقط پیامک‌هایی را می‌فرستد که واژه‌های بانکی دارند و رمز پویا ندارند، هر کدام با امضای HMAC. ارسال‌های ناموفق در صف می‌مانند و دوباره فرستاده می‌شوند. بهینه‌سازی باتری را برای اپ خاموش کنید.

آیفون (میان‌بر Shortcuts)

آیفون اجازه خواندن پیامک به اپ نمی‌دهد، اما اتوماسیون «Message» در Shortcuts می‌تواند متن پیامک بانک را بفرستد:

  1. در پنل یک گوشی با سیستم‌عامل «آیفون» جفت کنید و «ساخت توکن آیفون» را بزنید.
  2. Shortcuts › Automation › New › Message › Sender: شماره پیامک بانک › Run Immediately.
  3. اکشن Get Contents of URL: آدرس https://pay.mindraco.ir/api/device/sms/simple، Method: POST، Header: X-Device-Token = توکن، Request Body: File › Shortcut Input (متن پیام).
  4. برای هر بانک یک اتوماسیون جدا بسازید.

API دستگاه (برای سازندگان اپ‌های دیگر)

POST /api/device/pair        {"code": "AB7KX9QP", "app_version": "1.0.0", "model": "Galaxy A54"}
POST /api/device/sms         {"messages": [{"sender": "+98...", "body": "...", "received_at": 1760880672000}]}
POST /api/device/heartbeat   {"battery": 82, "app_version": "1.0.0"}
headers: X-Device-Id: <device_id>
         X-MindraPay-Signature: t=<unix>,v1=hmac_sha256(secret, t + "." + body)