پرش به محتوا
مستندات مهراد

ثبت سفارش و پرداخت

سوپر اپلیکیشن مهراد

این سند فرآیند کامل ایجاد سفارش، پرداخت توسط کاربر، تأیید پرداخت و عملیات بعدی سفارش (ارسال، تحویل، اصلاح و لغو) را برای جریان آنلاین توضیح می‌دهد. جریان حالتی که مشتری به صورت فیزیکی در فروشگاه پذیرنده حاضر است، در مستندات خرید حضوری توضیح داده شده است.


نمای کلی

کاربری که با ورود یکپارچه وارد سایت پذیرنده شده، سبد خریدش را می‌بندد و به جای درگاه بانکی، با دارایی‌های مهراد پرداخت می‌کند. نقش پذیرنده در این جریان:

1

پذیرندهایجاد پرداخت

POST/gateway/order/payment/request
2

پذیرندههدایت کاربر به payment_url که API برگردانده است

3

کاربرپرداخت در اپلیکیشن مهراد

4

کاربربازگشت به callback_url پذیرنده

این بازگشت تضمین‌شده نیست.

5

پذیرندهتأیید پرداخت

POST/gateway/order/payment/verify

الزامی؛ حداکثر تا ۳۰ دقیقه پس از ایجاد پرداخت.

6

پذیرندهتحویل کالا/خدمت و در ادامه ارسال، تحویل، اصلاح یا لغو سفارش

مرحلهاقدامendpoint
۱ایجاد سفارش و تلاش پرداختPOST /gateway/order/payment/request
۲هدایت کاربر به صفحهٔ پرداختآدرس payment_url از response مرحلهٔ ۱
۳دریافت بازگشت کاربرcallback_url پذیرنده
۴استعلام وضعیت (در صورت نیاز)GET /gateway/order/payment/{authority}/status
۵تأیید پرداختPOST /gateway/order/payment/verify
۶عملیات بعدی سفارشshipped / deliver / update / cancel

پیش‌نیازها

موردتوضیح
Access Token از SSOبرای ایجاد پرداخت لازم است؛ نحوهٔ دریافت در مستندات SSO
scope orderبرای ایجاد پرداخت باید این scope برای پذیرنده فعال باشد
token اپلیکیشن پذیرندهبرای تأیید پرداخت و عملیات بعدی سفارش؛ مستندات ارتباط پذیرندگان
callback_urlآدرسی در سایت پذیرنده برای بازگشت کاربر پس از پرداخت
ID یکتای سفارشexternal_order_id در سیستم پذیرنده

فهرست endpoint‌ها

endpointکاربردauthentication
POST /gateway/order/payment/requestایجاد سفارش و تلاش پرداختAccess Token از SSO + scope order
POST /gateway/order/payment/verifyتأیید پرداختtoken اپلیکیشن پذیرنده یا Access Token از SSO
GET /gateway/order/payment/{authority}/statusاستعلام وضعیت پرداختtoken اپلیکیشن پذیرنده یا Access Token از SSO
POST /gateway/order/{order_id}/shippedثبت ارسال سفارشtoken اپلیکیشن پذیرنده
POST /gateway/order/{order_id}/deliverثبت تحویل سفارشtoken اپلیکیشن پذیرنده
POST /gateway/order/{order_id}/updateاصلاح کاهشی سفارشtoken اپلیکیشن پذیرنده
GET /gateway/order/{order_id}دریافت جزئیات و تاریخچهٔ سفارشtoken اپلیکیشن پذیرنده
POST /gateway/order/{order_id}/cancelلغو سفارش و بازگشت کامل وجهtoken اپلیکیشن پذیرنده

برای endpoint‌هایی که هر دو روش را می‌پذیرند، استفاده از token اپلیکیشن پذیرنده توصیه می‌شود؛ این token به کاربر خاصی وابسته نیست و از سمت سرور پذیرنده مدیریت می‌شود.


مرحله ۱ — ایجاد پرداخت

POST/gateway/order/payment/request

Authentication: Access Token دریافت‌شده از SSO در header Authorization.

Scope لازم: این endpoint علاوه بر token معتبر، به scope order نیاز دارد. این scope باید برای ترکیب پذیرنده و سرویس فعال شده باشد. اگر token این scope را نداشته باشد، response آن با کد ۴۰۳ و خطای SSO_INSUFFICIENT_SCOPE بازگردانده می‌شود.

Authorization: Bearer <access_token>

ID کاربر، پذیرنده و سرویس از همین token استخراج می‌شود و نباید در body ارسال شود.

ورودی

پارامترهای ورودی9 فیلد
amountintegerالزامی
مبلغ نهایی سفارش به ریال؛ باید با اقلام، هزینهٔ ارسال مرسوله‌ها، خدمات و تخفیف هم‌خوان باشد.
external_order_idstringالزامی
ID سفارش در سیستم پذیرنده (حداکثر ۲۵۵ کاراکتر)؛ در سطح هر پذیرنده یکتاست. برای ثبت مجدد یک سفارش پرداخت‌نشده، همین مقدار دوباره ارسال می‌شود.
callback_urlstringالزامی
آدرس بازگشت کاربر پس از پرداخت؛ باید یک آدرس مطلق http یا https و حداکثر ۲۰۴۸ کاراکتر باشد. مهراد parameterهای authority و status (success یا failed) را به انتهای آن اضافه می‌کند.
shipmentsarray of objects
اقلام سفارش به‌تفکیک مرسوله؛ در صورت‌حساب کاربر نمایش داده می‌شود. ارسال اقلام اکیداً توصیه می‌شود، زیرا دسته‌بندی کالاها و تقسیم مبلغ بین حساب‌های کاربر بر اساس اقلام سفارش انجام می‌شود. تکرار یک کالا با ID و تنوع یکسان در کل سفارش مجاز نیست.
فیلدهای هر عضو لیست shipments3 فیلد
idstringالزامی
ID مرسوله در سیستم پذیرنده (حداکثر ۲۵۵ کاراکتر)؛ در یک سفارش یکتاست. برای ثبت ارسال و تحویل همین مرسوله و برای اصلاح سفارش به همین مقدار نیاز است.
shipping_feeinteger
هزینهٔ ارسال همین مرسوله به ریال (حداقل صفر)؛ به مبلغ سفارش اضافه می‌شود.

پیش‌فرض: 0

itemsarray of objectsالزامی
اقلام این مرسوله (با `product` و `variant`).
فیلدهای هر عضو لیست items5 فیلد
productobjectالزامی
اطلاعات کالا.
فیلدهای product6 فیلد
idstringالزامی
ID کالا در سیستم پذیرنده (حداکثر ۲۵۵ کاراکتر)؛ همراه با ID تنوع، کلید یکتای کالا در سفارش است. برای اصلاح سفارش در مرحلهٔ بعد به همین مقدار نیاز است.
titlestringالزامی
عنوان کالا (حداکثر ۵۱۱ کاراکتر).
urlstringالزامی
لینک صفحهٔ کالا در سیستم پذیرنده (حداکثر ۵۱۱ کاراکتر).
is_domesticboolean
مشخص می‌کند کالا تولید داخل است یا خارجی؛ جایگزین فیلد منسوخ `brand_origin`.
imageobjectالزامی
تصویر کالا.
فیلدهای image2 فیلد
urlstringالزامی
آدرس تصویر اصلی کالا (حداکثر ۵۱۱ کاراکتر)؛ در صورت‌حساب کاربر نمایش داده می‌شود.
thumbnail_urlstringالزامی
آدرس تصویر کوچک کالا (حداکثر ۵۱۱ کاراکتر).
variantobjectالزامی
تنوع انتخاب‌شدهٔ کالا (مانند رنگ یا سایز).
فیلدهای variant2 فیلد
idstringالزامی
ID تنوع در سیستم پذیرنده (حداکثر ۲۵۵ کاراکتر)، مثلاً ID رنگ یا سایز مشخص.
titlestringالزامی
عنوان تنوع (حداکثر ۲۵۵ کاراکتر)، مثلاً «قرمز - سایز ۴۲».
priceintegerالزامی
قیمت واحد کالا به ریال؛ باید بزرگ‌تر از صفر باشد.
quantityinteger
تعداد کالا؛ حداقل ۱.

پیش‌فرض: 1

categorystringالزامی
دسته‌بندی کالا در سیستم پذیرنده (حداکثر ۵۱۱ کاراکتر)؛ سلسله‌مراتب دسته‌ها با ویرگول از هم جدا می‌شود، مثلاً «لوازم خانگی برقی,یخچال و فریزر». این مقدار با category_id سیستم که در response‌ها می‌آید یکی نیست.
extra_dataobject
داده‌ای آزاد در قالب JSON برای اطلاعات تکمیلی کالا که در سایر فیلدها پیش‌بینی نشده است؛ ساختار آن توسط پذیرنده تعیین می‌شود و بدون تغییر در response‌های سفارش بازگردانده می‌شود.
servicesarray of objects
هزینه‌های جانبی مانند ارسال یا بسته‌بندی.
فیلدهای هر عضو لیست services2 فیلد
titlestringالزامی
عنوان هزینه، مثلاً هزینهٔ ارسال.
amountintegerالزامی
مبلغ هزینه به ریال؛ باید بزرگ‌تر از صفر باشد.
discount_amountinteger
مبلغ تخفیف کل سفارش؛ نباید منفی باشد.
descriptionstring
توضیح سفارش.
order_urlstring
آدرس پیگیری سفارش در سیستم پذیرنده.
external_payment_idstring
ID پرداخت در سیستم پذیرنده (حداکثر ۲۵۵ کاراکتر)؛ روی تلاش پرداخت ثبت می‌شود.

روش‌های ثبت اقلام

اقلام سفارش به دو روش قابل ثبت است. ثبت در قالب مرسوله (shipments) ساختار فعلی است. items منسوخ است و در نسخه‌های آینده حذف خواهد شد.

روشفیلد requestوضعیت
۱. اقلام به‌تفکیک مرسولهshipments✅ روش فعلی
۲. اقلام بدون مرسوله (ساختار پیشین)items⚠️ منسوخ (deprecated)؛ در نسخه‌های آینده حذف خواهد شد

در یک request باید یا shipments یا items ارسال شود؛ اگر هر دو با هم ارسال شوند، response آن با کد ۴۲۲ و خطای VALIDATION_ERROR برگردانده می‌شود.

روش فعلی: shipments

در این روش، اقلام سفارش در یک یا چند مرسوله گروه‌بندی می‌شوند. هر مرسوله شناسه (id)، هزینهٔ ارسال (shipping_fee) و فهرست اقلام مختص به خود را دارد و وضعیت ارسال و تحویل آن به‌صورت مستقل ثبت می‌شود؛ از این رو، سفارش‌هایی که در چند بسته یا از چند انبار ارسال می‌شوند، به‌درستی قابل نمایش هستند. هر قلم مرسوله شامل اطلاعات کامل کالا (product)، تنوع (variant) و تصویر کالاست.

  • id هر مرسوله در یک سفارش یکتاست؛ اگر تکرار شود، response آن با کد ۴۲۲ و خطای VALIDATION_ERROR برگردانده می‌شود.
  • shipping_fee به مبلغ سفارش افزوده می‌شود و نباید منفی باشد. در صورت نبود هزینهٔ ارسال، این فیلد می‌تواند صفر باشد یا ارسال نشود.
  • مرسوله‌ای که تنها هزینهٔ ارسال دارد، می‌تواند با items خالی ارسال شود.
  • quantity اگر نیاید ۱ است و حداقل مقدار آن ۱ است.
  • مجموع هزینهٔ ارسال مرسوله‌ها همراه با services در فیلد service_fee سفارش گزارش می‌شود.
  • ثبت ارسال و تحویل (مرحلهٔ ۶) برای هر مرسوله جداگانه و با id همان مرسوله انجام می‌شود.

تفاوت کالا (product) و تنوع (variant): product.id معرف کالا به‌طور کلی است (مانند «کفش مدل X») و variant گونهٔ خریداری‌شدهٔ آن کالا را مشخص می‌کند (مانند رنگ یا سایز معین). در صورت خرید چند تنوع از یک کالا، هر تنوع باید به‌عنوان قلمی جداگانه با product.id یکسان و variant.id متفاوت ارسال شود. اگر کالا تنوعی ندارد، ارسال variant با id و title باز هم الزامی است.

روش منسوخ: items

این روش، ساختار پیشین ثبت اقلام است و صرفاً برای حفظ سازگاری با یکپارچه‌سازی‌های موجود پشتیبانی می‌شود؛ این ساختار در نسخه‌های آینده حذف خواهد شد. پیاده‌سازی‌های جدید باید از روش اصلی (shipments) استفاده کنند و پیاده‌سازی‌های موجود نیز لازم است به این روش منتقل شوند.

ساختار هر قلم در items

در این روش، اقلام بدون مرسوله و هر قلم تنها با عنوان، قیمت و اطلاعات پایهٔ کالا (بدون product و variant) ارسال می‌شود. سفارش در مهراد با یک مرسولهٔ بدون شناسه و بدون هزینهٔ ارسال شامل همهٔ اقلام ثبت می‌شود؛ هزینهٔ ارسال در این روش از طریق services اعلام می‌شود. این فیلد تنها ساختار زیر را می‌پذیرد و اقلام با ساختار shipments[].items (دارای product) در آن معتبر نیستند.

پارامترهای ورودی7 فیلد
titlestringالزامی
عنوان کالا.
priceintegerالزامی
قیمت واحد کالا به ریال؛ باید بزرگ‌تر از صفر باشد.
quantityinteger
تعداد کالا؛ حداقل ۱.

پیش‌فرض: 1

product_idstring
ID کالا در سیستم پذیرنده؛ برای اصلاح سفارش در مرحلهٔ بعد به همین مقدار نیاز است.
categorystring
دسته‌بندی کالا در سیستم پذیرنده (حداکثر ۵۱۱ کاراکتر)؛ سلسله‌مراتب دسته‌ها با ویرگول از هم جدا می‌شود، مثلاً «لوازم خانگی برقی,یخچال و فریزر».
urlstring
لینک کالا.
image_urlstring
تصویر کالا؛ در صورت‌حساب کاربر نمایش داده می‌شود.

فیلد brand_origin دیگر پذیرفته نمی‌شود؛ در صورت ارسال، نادیده گرفته می‌شود و در سفارش ذخیره نخواهد شد. معادل آن در shipments، product.is_domestic است.

برای مهاجرت به shipments، فیلدهای items به این صورت متناظرند:

items[]shipments[].items[]
titleproduct.title
product_idproduct.id
urlproduct.url
image_urlproduct.image.url
category (اختیاری)category

در items، فیلدهای is_domestic، image.thumbnail_url، variant و extra_data وجود ندارند و category اختیاری است.

نمونهٔ یک قلم در items:

{
  "title": "یخچال ساید بای ساید",
  "product_id": "p-1234",
  "url": "https://shop.example.com/product/1234",
  "image_url": "https://shop.example.com/media/1234.webp",
  "price": 10000000,
  "quantity": 1
}

کالاهای تکراری

اگر دو قلم با همان product_id/product.id و همان variant_id (یا هر دو بدون تنوع) در یک request بیایند، حتی اگر در مرسوله‌های متفاوت باشند، کل request با خطای DUPLICATE_ORDER_ITEM رد می‌شود. دو قلم از یک کالا با تنوع‌های متفاوت مجازند و دو قلم جداگانه محسوب می‌شوند. اقلامی که هیچ ID کالایی ندارند (نه product_id و نه product.id) هرگز برای تکراری بودن بررسی نمی‌شوند، حتی اگر عنوان یکسانی داشته باشند.

قاعدهٔ مبلغ

مقدار amount باید دقیقاً با مجموع اقلام، هزینهٔ ارسال مرسوله‌ها و خدمات منهای تخفیف برابر باشد:

amount = SUM(price × quantity همهٔ اقلام) + SUM(shipments.shipping_fee) + SUM(services.amount) - discount_amount

در صورت عدم تساوی، خطای INVALID_ORDER_AMOUNT و در صورتی که حاصل صفر یا منفی شود، خطای ORDER_AMOUNT_NOT_POSITIVE برگردانده می‌شود.

قیمت هر قلم و مبلغ هر خدمت باید بزرگ‌تر از صفر باشد و تخفیف نباید منفی باشد؛ در غیر این صورت response آن با کد ۴۲۲ و خطای VALIDATION_ERROR برگردانده می‌شود.

نمونه request

نمونه ایجاد پرداخت با shipments
{
  "amount": 13800000,
  "external_order_id": "SHOP-2026-0918-4471",
  "external_payment_id": "PAY-4471-1",
  "callback_url": "https://shop.example.com/payment/callback",
  "order_url": "https://shop.example.com/orders/4471",
  "description": "خرید کالا از فروشگاه",
  "shipments": [
    {
      "id": "S1",
      "shipping_fee": 1000000,
      "items": [
        {
          "product": {
            "id": "p-1234",
            "title": "یخچال ساید بای ساید",
            "url": "https://shop.example.com/product/1234",
            "is_domestic": false,
            "image": {
              "url": "https://shop.example.com/media/1234.webp",
              "thumbnail_url": "https://shop.example.com/media/1234-thumb.webp"
            },
            "variant": {
              "id": "p-1234-white",
              "title": "سفید"
            }
          },
          "price": 10000000,
          "quantity": 1,
          "category": "لوازم خانگی برقی,یخچال و فریزر"
        }
      ]
    },
    {
      "id": "S2",
      "shipping_fee": 500000,
      "items": [
        {
          "product": {
            "id": "p-5678",
            "title": "کتری برقی",
            "url": "https://shop.example.com/product/5678",
            "is_domestic": true,
            "image": {
              "url": "https://shop.example.com/media/5678.webp",
              "thumbnail_url": "https://shop.example.com/media/5678-thumb.webp"
            },
            "variant": {
              "id": "p-5678-steel",
              "title": "استیل"
            }
          },
          "price": 2000000,
          "quantity": 1,
          "category": "لوازم خانگی برقی,کتری"
        }
      ]
    }
  ],
  "services": [
    {
      "title": "هزینه بسته‌بندی",
      "amount": 800000
    }
  ],
  "discount_amount": 500000
}

محاسبهٔ مبلغ این نمونه:

(10000000 × 1) + (2000000 × 1) + (1000000 + 500000) + 800000 - 500000 = 13800000

Response

فیلدهای پاسخ7 فیلد
authoritystring
ID تلاش پرداخت؛ برای استعلام وضعیت و تأیید پرداخت لازم است.
order_iduuid
ID سفارش در مهراد؛ برای ارسال، تحویل، اصلاح و لغو سفارش استفاده می‌شود.
payment_urlstring
آدرس صفحهٔ پرداخت؛ کاربر باید دقیقاً به همین آدرس هدایت شود.
tracking_codestring
کد پیگیری ۸ رقمی سفارش در مهراد؛ برای نمایش به کاربر و پیگیری پشتیبانی.
amountinteger
مبلغ ثبت‌شدهٔ تلاش پرداخت (برابر amount در request).
descriptionstring | null
توضیح سفارش؛ در حال حاضر مقدار آن همواره null است.
created_atdatetime
زمان ایجاد تلاش پرداخت (قالب ISO 8601)؛ مهلت ۳۰ دقیقه‌ای تأیید از این لحظه شروع می‌شود.
نمونه پاسخ
{
  "success": true,
  "data": {
    "authority": "8cdb1c8c-bd3c-4f0f-9c8b-9c72c1f2e41c",
    "order_id": "1f9d3c47-6a20-4bd1-8f5e-77c0ab93e412",
    "payment_url": "https://pwa.mehrad.app/payment/?authority=8cdb1c8c-bd3c-4f0f-9c8b-9c72c1f2e41c&amount=13800000",
    "tracking_code": "20463158",
    "description": null,
    "amount": 13800000,
    "created_at": "2026-09-18T11:34:21.482000+00:00"
  },
  "meta": null
}

پردازش response

  • authority و order_id باید کنار سفارش پذیرنده ذخیره شوند؛ authority برای استعلام و تأیید پرداخت و order_id برای عملیات بعدی سفارش لازم است.
  • payment_url باید همان‌طور که برگشته استفاده شود. ساختار این آدرس بخشی از قرارداد نیست؛ نباید ساخته یا تغییر داده شود و هیچ parameter دیگری نیز نباید به آن اضافه شود.
  • tracking_code باید برای پشتیبانی و پیگیری نگه‌داری شود.

نکتهٔ مهم دربارهٔ external_order_id

این مقدار باید برای هر سفارش یکتا باشد. اگر برای مقداری که به یک سفارش پرداخت‌شده تعلق دارد دوباره request پرداخت ارسال شود، خطای ORDER_ALREADY_PAID برگردانده می‌شود. اگر این مقدار به سفارشی پرداخت‌نشده تعلق داشته باشد، سفارش تازه‌ای ساخته نمی‌شود؛ همان سفارش قبلی از روی request جدید (مبلغ، اقلام، خدمات و تخفیف) بازتعریف و یک تلاش پرداخت جدید برای آن ساخته می‌شود. در غیر این صورت، سفارش جدید ایجاد می‌شود. سفارشی که متعلق به کاربر دیگری باشد با خطای ORDER_USER_NOT_MATCHED رد می‌شود.

این رفتار برای «تلاش مجدد پرداخت روی همان سفارش» طراحی شده است؛ اما استفادهٔ ناخواسته از آن موجب ادغام سفارش‌های متفاوت پذیرنده در مهراد و جایگزینی محتوای سفارش قبلی با request جدید می‌شود.


مرحله ۲ — هدایت کاربر به صفحهٔ پرداخت

کاربر باید به payment_url هدایت شود. در ادامه:

  • کاربر باید در اپلیکیشن مهراد وارد حساب خود باشد؛ در غیر این صورت ابتدا وارد می‌شود و سپس صفحهٔ پرداخت را می‌بیند.
  • کاربر حساب‌های خود را انتخاب و پرداخت را انجام می‌دهد. اگر موجودی کافی نباشد، ممکن است ابتدا از درگاه بانکی کیف پولش را شارژ کند و سپس برگردد؛ این کار زمان کل فرآیند را طولانی‌تر می‌کند.
  • کاربر می‌تواند پرداخت را لغو کند.

مرحله ۳ — بازگشت کاربر به سایت پذیرنده

پس از پایان کار، کاربر به callback_url پذیرنده هدایت می‌شود و این parameterها به آدرس اضافه می‌شوند (parameterهای خودِ آدرس پذیرنده حفظ می‌شوند):

parameterمقدار
authorityID تلاش پرداخت
statussuccess یا failed

نمونه:

https://shop.example.com/payment/callback?authority=8cdb1c8c-bd3c-4f0f-9c8b-9c72c1f2e41c&status=success

این بازگشت سند پرداخت نیست

status=success در آدرس بازگشت فقط یک نشانه برای بهبود تجربهٔ کاربر است و نباید مبنای تحویل کالا یا ثبت پرداخت موفق قرار گیرد. دلایل:

  • ممکن است کاربر اصلاً به سایت پذیرنده بازنگردد؛ بستن مرورگر، قطع اینترنت یا رها کردن صفحه کاملاً ممکن است.
  • بازگشت بلافاصله انجام نمی‌شود: کاربر ابتدا رسید پرداخت را در اپلیکیشن می‌بیند و انتقال خودکار با تأخیری حدود ۱۰ ثانیه انجام می‌شود (کاربر می‌تواند دکمهٔ بازگشت را هم بزند). این زمان رفتار مشاهده‌شدهٔ اپلیکیشن است، نه تعهد زمانی API.
  • آدرس بازگشت در مرورگر کاربر است و قابل دستکاری است.

قاعدهٔ درست: با دریافت بازگشت کاربر، وضعیت باید از API دریافت شود (مرحلهٔ ۴) و تنها پس از تأیید موفق (مرحلهٔ ۵) سفارش پرداخت‌شده در نظر گرفته شود. اگر کاربر بازنگشت، همین بررسی باید از سمت سرور و بر اساس authority ذخیره‌شده انجام شود.


مرحله ۴ — استعلام وضعیت پرداخت

GET/gateway/order/payment/{authority}/status

Authentication: token اپلیکیشن پذیرنده یا Access Token از SSO.

نمونه پاسخ
{
  "success": true,
  "data": {
    "ref_id": "5f7d1a30-1c77-4a2b-b6d1-0f3f41f9c5e2",
    "status": "PAID",
    "fee": 15500
  },
  "meta": null
}
  • status: وضعیت فعلی تلاش پرداخت (جدول وضعیت‌ها در ادامه).
  • ref_id: ID تراکنش سفارش؛ تا وقتی تراکنشی ثبت نشده باشد رشتهٔ خالی برمی‌گردد.
  • fee: کارمزد سامانه برای این تلاش پرداخت.

اگر status برابر PAID باشد، سفارش پرداخت شده و منتظر تأیید پذیرنده است؛ ادامه در مرحلهٔ ۵.


مرحله ۵ — تأیید پرداخت

POST/gateway/order/payment/verify

Authentication: token اپلیکیشن پذیرنده یا Access Token از SSO. استفاده از token اپلیکیشن پذیرنده توصیه می‌شود.

تأیید پرداخت الزامی است. تا زمانی که تأیید انجام نشود، مبلغ برای پذیرنده قطعی نمی‌شود.

ورودی

پارامترهای ورودی2 فیلد
authoritystringالزامی
ID تلاش پرداخت از مرحلهٔ ۱. (در [خرید حضوری](/docs/in-person) به‌جای آن `order_id` ارسال می‌شود؛ ارسال هر دو با هم مجاز نیست.)
amountintegerالزامی
مبلغ سفارش؛ باید دقیقاً برابر مبلغ ثبت‌شدهٔ تلاش پرداخت باشد.
{
  "authority": "8cdb1c8c-bd3c-4f0f-9c8b-9c72c1f2e41c",
  "amount": 13800000
}

Response

نمونه پاسخ
{
  "success": true,
  "data": {
    "ref_id": "5f7d1a30-1c77-4a2b-b6d1-0f3f41f9c5e2",
    "status": "VERIFY_OK",
    "fee": 15500
  },
  "meta": null
}

status برابر VERIFY_OK یعنی پرداخت نهایی شده است. ref_id، ID تراکنش است و برای تطبیق حساب باید ذخیره شود.

مهلت ۳۰ دقیقه‌ای

تأیید باید حداکثر تا ۳۰ دقیقه پس از ایجاد تلاش پرداخت انجام شود. پس از آن پرداخت به صورت خودکار بسته می‌شود: مبلغ به حساب کاربر بازمی‌گردد و وضعیت تلاش پرداخت VERIFY_TIMEOUT می‌شود. تلاش پرداختی که هنوز پرداخت نشده باشد، پس از همین مهلت CANCELED می‌شود.

هشدار دربارهٔ مبلغ

اگر مبلغ ارسالی با مبلغ ثبت‌شدهٔ تلاش پرداخت برابر نباشد، تأیید رد می‌شود، تلاش پرداخت باطل می‌شود (VERIFY_FAILED) و وجه به کاربر بازمی‌گردد؛ امکان تأیید دوبارهٔ همان پرداخت وجود ندارد. اگر سفارش متعلق به پذیرندهٔ دیگری باشد، request با ORDER_MERCHANT_NOT_MATCHED رد می‌شود و وضعیت پرداخت تغییر نمی‌کند. مبلغ ارسالی همواره باید همان مبلغی باشد که در response مرحلهٔ ۱ یا استعلام وضعیت آمده است.

تلاش مجدد

  • اگر request تأیید با خطای شبکه مواجه شود یا response آن کد ۵xx داشته باشد، ارسال مجدد آن با همان authority و همان مبلغ مجاز است.
  • دریافت خطای ORDER_ALREADY_PAID به این معناست که این پرداخت قبلاً تأیید شده است؛ در این حالت پرداخت موفق در نظر گرفته می‌شود و تأیید نباید تکرار شود.
  • دریافت خطای ORDER_ATTEMPT_NOT_PAID به این معناست که کاربر هنوز پرداخت را کامل نکرده است؛ در این حالت request نباید بلافاصله تکرار شود و وضعیت باید از طریق endpoint استعلام پیگیری شود.

مرحله ۶ — عملیات بعدی سفارش

پس از تأیید پرداخت، چرخهٔ عمر سفارش با این عملیات ادامه پیدا می‌کند. همهٔ آن‌ها فقط با token اپلیکیشن پذیرنده کار می‌کنند و روی order_id (نه authority) عمل می‌کنند.

ارسال و تحویل

ارسال و تحویل برای هر مرسوله جداگانه ثبت می‌شود. وضعیت کل سفارش از وضعیت مرسوله‌ها نتیجه می‌شود: shipped_at سفارش زمانی مقدار می‌گیرد که آخرین مرسوله‌اش ارسال شده باشد، و delivered_at سفارش زمانی که آخرین مرسوله‌اش تحویل شده باشد. مرسوله‌ها به هر ترتیبی می‌توانند ارسال و تحویل شوند.

هر دو endpoint یک body اختیاری می‌گیرند که مرسوله را مشخص می‌کند:

پارامترهای ورودی1 فیلد
shipment_idstring
ID مرسوله (همان `id` که هنگام ایجاد پرداخت ارسال شده بود). برای سفارشی که با `shipments` ثبت شده الزامی است. برای سفارشی که با `items` (روش منسوخ) ثبت شده، یا اصلاً مرسوله ندارد، ارسال نشود.
  • سفارشی که با shipments ثبت شده است: shipment_id الزامی است. ارسال نکردن آن یا ارسال شناسه‌ای که در سفارش نیست، خطای ORDER_SHIPMENT_NOT_FOUND می‌دهد.
  • سفارشی که با items ثبت شده است: body ارسال نمی‌شود و عملیات روی همان مرسولهٔ بدون شناسه انجام می‌شود. ارسال shipment_id برای آن، ORDER_SHIPMENT_NOT_FOUND است.
  • سفارشی که هیچ مرسوله‌ای ندارد: body ارسال نمی‌شود و ارسال و تحویل روی خود سفارش ثبت می‌شود.
  • مرسوله‌ای که در یک اصلاح کاهشی از سفارش حذف شده باشد دیگر قابل ارسال یا تحویل نیست و ORDER_SHIPMENT_NOT_FOUND می‌گیرد.
  • اگر در یک اصلاح کاهشی، آخرین مرسولهٔ ارسال‌نشده (یا تحویل‌نشده) حذف شود و مرسوله‌های باقی‌مانده همه ارسال (یا تحویل) شده باشند، سفارش به‌طور خودکار ارسال‌شده (یا تحویل‌شده) محسوب می‌شود.

ثبت ارسال

POST/gateway/order/{order_id}/shipped
{
  "shipment_id": "S1"
}

برای مرسوله‌ای که قبلاً ارسال شده باشد، خطای ORDER_ALREADY_SHIPPED برگردانده می‌شود. response، جزئیات سفارش است (ساختار آن در بخش «جزئیات و تاریخچهٔ سفارش» آمده)؛ زمان ارسال هر مرسوله در versions[].shipments[].shipped_at و زمان ارسال کل سفارش در shipped_at است.

نمونه پاسخ
{
  "success": true,
  "data": {
    "id": "1f9d3c47-6a20-4bd1-8f5e-77c0ab93e412",
    "external_order_id": "SHOP-2026-0918-4471",
    "status": "SUCCESS",
    "amount": 13800000,
    "version": 1,
    "is_shipped": false,
    "shipped_at": null,
    "is_delivered": false,
    "delivered_at": null,
    "versions": [
      {
        "version": 1,
        "shipments": [
          { "external_id": "S1", "shipping_fee": 1000000, "shipped_at": "2026-09-19T08:05:44.120000+00:00", "delivered_at": null },
          { "external_id": "S2", "shipping_fee": 500000, "shipped_at": null, "delivered_at": null }
        ]
      }
    ]
  },
  "meta": null
}

در این نمونه فقط مرسولهٔ S1 ارسال شده است؛ تا زمانی که S2 هم ارسال نشود، is_shipped و shipped_at سفارش مقدار ندارند. (برای کوتاه‌شدن، بیشتر فیلدهای response در نمونه حذف شده است.)

ثبت تحویل

POST/gateway/order/{order_id}/deliver

body مانند ارسال است (shipment_id). پیش‌نیاز: همان مرسوله باید قبلاً ارسال شده باشد؛ در غیر این صورت خطای ORDER_NOT_SHIPPED_YET برگردانده می‌شود. برای مرسوله‌ای که قبلاً تحویل شده باشد، خطای ORDER_ALREADY_DELIVERED برگردانده می‌شود. ساختار response مانند ارسال است و delivered_at مقدار می‌گیرد.

بازگشت وجه

وجه سفارش پرداخت‌شده به دو روش به کاربر بازمی‌گردد:

بازگشت بخشی (اصلاح کاهشی)بازگشت کامل (لغو)
endpointPOST /gateway/order/{order_id}/updatePOST /gateway/order/{order_id}/cancel
کاربردمرجوعی، حذف قلم یا مرسوله، یا کاهش هزینهٔ ارسال و خدماتلغو کل سفارش
مبلغ بازگشتیتفاوت ارزش سفارش پیش و پس از اصلاحتمام وجه سفارش
تکرارچند بار؛ هر بار نسبت به آخرین نسخه—
وضعیت پس از عملیاتسفارش با ارزش کمتر باقی می‌ماندسفارش با ارزش صفر باقی می‌ماند

بازگشت بخشی از وجه (اصلاح کاهشی)

POST/gateway/order/{order_id}/update

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

پیش‌نیازها

  • سفارش باید تلاش پرداخت تأییدشده (VERIFY_OK) داشته باشد، در غیر این صورت ORDER_ATTEMPT_NOT_PAID.
  • ارزش سفارش پس از اصلاح باید اکیداً کمتر از مقدار فعلی باشد؛ اصلاحِ بدون تغییر ارزش با ORDER_UPDATE_NO_CHANGE رد می‌شود.
  • مقادیر فقط می‌توانند کاهش یابند.

بدنهٔ request: این body وضعیت کامل سفارش پس از اصلاح را توصیف می‌کند، نه تغییرات را؛ هر مرسوله یا قلمی که در فهرست نیاید حذف می‌شود. services اگر نیاید هیچ هزینهٔ جانبی باقی نمی‌ماند. discount_amount اگر نیاید صفر است؛ صفر شدن تخفیفِ موجود ارزش سفارش را بالا می‌برد و درخواست رد می‌شود، مگر کاهش اقلام یا خدمات این افزایش را جبران کند و حاصل همچنان کمتر از ارزش فعلی باشد. ساختار body باید با روش ثبت سفارش یکی باشد: سفارشی که با shipments ثبت شده با shipments و سفارشی که با items ثبت شده با items اصلاح می‌شود؛ ترکیب غیرمنطبق با ORDER_UPDATE_VALUE_INCREASED رد می‌شود. نفرستادن هر دو فهرست، همهٔ مرسوله‌ها را حذف می‌کند.

پارامترهای ورودی5 فیلد
shipmentsarray of objects
فهرست کامل مرسوله‌هایی که پس از اصلاح باقی می‌مانند، هر کدام با اقلام و هزینهٔ ارسال باقی‌ماندهٔ خود.
فیلدهای هر عضو لیست shipments3 فیلد
idstringالزامی
ID مرسوله در سیستم پذیرنده (حداکثر ۲۵۵ کاراکتر)؛ در یک سفارش یکتاست. برای ثبت ارسال و تحویل همین مرسوله و برای اصلاح سفارش به همین مقدار نیاز است.
shipping_feeinteger
هزینهٔ ارسال همین مرسوله به ریال (حداقل صفر)؛ به مبلغ سفارش اضافه می‌شود.

پیش‌فرض: 0

itemsarray of objectsالزامی
اقلام این مرسوله (با `product` و `variant`).
فیلدهای هر عضو لیست items5 فیلد
productobjectالزامی
اطلاعات کالا.
فیلدهای product6 فیلد
idstringالزامی
ID کالا در سیستم پذیرنده (حداکثر ۲۵۵ کاراکتر)؛ همراه با ID تنوع، کلید یکتای کالا در سفارش است. برای اصلاح سفارش در مرحلهٔ بعد به همین مقدار نیاز است.
titlestringالزامی
عنوان کالا (حداکثر ۵۱۱ کاراکتر).
urlstringالزامی
لینک صفحهٔ کالا در سیستم پذیرنده (حداکثر ۵۱۱ کاراکتر).
is_domesticboolean
مشخص می‌کند کالا تولید داخل است یا خارجی؛ جایگزین فیلد منسوخ `brand_origin`.
imageobjectالزامی
تصویر کالا.
فیلدهای image2 فیلد
urlstringالزامی
آدرس تصویر اصلی کالا (حداکثر ۵۱۱ کاراکتر)؛ در صورت‌حساب کاربر نمایش داده می‌شود.
thumbnail_urlstringالزامی
آدرس تصویر کوچک کالا (حداکثر ۵۱۱ کاراکتر).
variantobjectالزامی
تنوع انتخاب‌شدهٔ کالا (مانند رنگ یا سایز).
فیلدهای variant2 فیلد
idstringالزامی
ID تنوع در سیستم پذیرنده (حداکثر ۲۵۵ کاراکتر)، مثلاً ID رنگ یا سایز مشخص.
titlestringالزامی
عنوان تنوع (حداکثر ۲۵۵ کاراکتر)، مثلاً «قرمز - سایز ۴۲».
priceintegerالزامی
قیمت واحد کالا به ریال؛ باید بزرگ‌تر از صفر باشد.
quantityinteger
تعداد کالا؛ حداقل ۱.

پیش‌فرض: 1

categorystringالزامی
دسته‌بندی کالا در سیستم پذیرنده (حداکثر ۵۱۱ کاراکتر)؛ سلسله‌مراتب دسته‌ها با ویرگول از هم جدا می‌شود، مثلاً «لوازم خانگی برقی,یخچال و فریزر». این مقدار با category_id سیستم که در response‌ها می‌آید یکی نیست.
extra_dataobject
داده‌ای آزاد در قالب JSON برای اطلاعات تکمیلی کالا که در سایر فیلدها پیش‌بینی نشده است؛ ساختار آن توسط پذیرنده تعیین می‌شود و بدون تغییر در response‌های سفارش بازگردانده می‌شود.
servicesarray of objects
فهرست کامل هزینه‌های جانبی باقی‌مانده (به‌جز هزینهٔ ارسال مرسوله‌ها). اگر ارسال نشود هیچ هزینه‌ای باقی نمی‌ماند. مجموع آن نباید از مقدار فعلی بیشتر شود.
فیلدهای هر عضو لیست services2 فیلد
titlestringالزامی
عنوان هزینه، مثلاً هزینهٔ ارسال.
amountintegerالزامی
مبلغ هزینه به ریال؛ باید بزرگ‌تر از صفر باشد.
discount_amountinteger
تخفیف باقی‌مانده. اگر ارسال نشود صفر است. از تخفیف فعلی بیشتر نباشد؛ صفر کردن تخفیف موجود، مگر با کاهش اقلام یا خدمات جبران شود، اصلاح را رد می‌کند.

پیش‌فرض: 0

external_version_idstring
ID این اصلاح در سیستم پذیرنده؛ اختیاری، حداکثر ۲۵۵ کاراکتر و در سطح هر پذیرنده یکتا.
reasonstring
علت اصلاح (حداکثر ۲۵۵ کاراکتر)؛ در سوابق سفارش ثبت می‌شود.

تطبیق مرسوله‌ها و اقلام (روش shipments): هر مرسوله با id به مرسولهٔ فعلی سفارش تطبیق داده می‌شود و هر قلم داخل آن با ID کالا (product.id) و ID تنوع (variant.id) با اقلام فعلی همان مرسوله. به این ترتیب:

  • مرسوله‌ای که باید در سفارش باقی بماند، با همان id ارسال می‌شود؛ مرسوله‌ای که در فهرست نیاید حذف و مبلغ اقلام و هزینهٔ ارسال آن بازگردانده می‌شود.
  • برای حذف یک قلم، آن قلم در items مرسولهٔ مربوط ارسال نمی‌شود. مرسوله‌ای که همهٔ اقلام آن حذف شده اما همچنان shipping_fee دارد، با items خالی حفظ می‌شود؛ در صورتی که نه قلمی و نه هزینه‌ای برای آن باقی بماند، از سفارش حذف می‌شود.
  • shipping_fee فقط می‌تواند کاهش یابد.
  • ارسال شناسهٔ مرسولهٔ ناشناخته، انتقال قلم به مرسوله‌ای دیگر یا تکرار یک ترکیب (کالا + تنوع) در دو مرسوله، با خطای ORDER_UPDATE_VALUE_INCREASED رد می‌شود.
  • وضعیت ارسال و تحویل مرسوله‌های باقی‌مانده در نسخهٔ جدید حفظ می‌شود.

تطبیق اقلام (items): هر قلم در items با ساختار روش منسوخ (product_id، title، price و …) ارسال و بر اساس product_id با اقلام فعلی سفارش تطبیق داده می‌شود؛ قلم فاقد product_id قابل تطبیق نیست و با خطای ORDER_UPDATE_VALUE_INCREASED رد می‌شود.

در هر دو روش، مقدار price باید دقیقاً برابر قیمت واحد ثبت‌شده روی سفارش باشد (ORDER_ITEM_PRICE_MISMATCH) و quantity باید بین ۱ و تعداد فعلی باشد. افزودن قلم جدید، افزایش تعداد یا هزینهٔ ارسال یا خدمات، یا ارسال یک جفت (ID کالا + تنوع) تکراری یا ناشناخته، با ORDER_UPDATE_VALUE_INCREASED رد می‌شود. برای حذف کامل یک قلم، کافی است آن قلم در فهرست ارسال نشود.

دربارهٔ external_version_id: این مقدار ID اصلاح در سیستم پذیرنده است. اختیاری است، روی نسخهٔ جدید سفارش ثبت و در response عیناً برگردانده می‌شود و برای تطبیق سوابق اصلاحات میان دو سیستم به کار می‌رود. این مقدار در سطح هر پذیرنده یکتا است: اگر مقداری که قبلاً برای هر یک از سفارش‌های همین پذیرنده ثبت شده دوباره ارسال شود، request با خطای DUPLICATE_EXTERNAL_VERSION_ID رد می‌شود و اصلاحی انجام نمی‌گیرد؛ بنابراین برای هر اصلاح باید ID جدیدی تولید شود. در صورت ارسال مجدد request به‌دلیل خطای شبکه، دریافت همین خطا نشان‌دهندهٔ ثبت قبلی اصلاح است. حداکثر طول مقدار ۲۵۵ کاراکتر است.

نمونه اصلاح سفارش با shipments
{
  "shipments": [
    {
      "id": "S1",
      "shipping_fee": 600000,
      "items": [
        {
          "product": {
            "id": "p-1234",
            "title": "یخچال ساید بای ساید",
            "url": "https://shop.example.com/product/1234",
            "is_domestic": false,
            "image": {
              "url": "https://shop.example.com/media/1234.webp",
              "thumbnail_url": "https://shop.example.com/media/1234-thumb.webp"
            },
            "variant": {
              "id": "p-1234-white",
              "title": "سفید"
            }
          },
          "price": 10000000,
          "quantity": 1,
          "category": "لوازم خانگی برقی,یخچال و فریزر"
        }
      ]
    }
  ],
  "discount_amount": 500000,
  "external_version_id": "RET-2026-0919-11",
  "reason": "مرجوعی کتری، حذف هزینه بسته‌بندی و کاهش هزینه ارسال یخچال"
}

در این نمونه مرسولهٔ S2 (کتری و هزینهٔ ارسالش) و هزینهٔ بسته‌بندی حذف شده و هزینهٔ ارسال S1 کاهش یافته است. مبلغ کاهش‌یافتهٔ این نمونه:

ارزش سفارش پیش از اصلاح
۱۳٬۸۰۰٬۰۰۰ ریال
ارزش سفارش پس از اصلاح
۱۰٬۱۰۰٬۰۰۰ ریال
بازگشت به کاربر
۳٬۷۰۰٬۰۰۰ ریال
(10000000 + 2000000 + 1500000 + 800000 - 500000) - (10000000 + 600000 - 500000) = 3700000

Response

نمونه پاسخ
{
  "success": true,
  "data": {
    "id": "9c2f1a7e-3b44-4d90-8f11-2ac4d1e77b05",
    "order_id": "1f9d3c47-6a20-4bd1-8f5e-77c0ab93e412",
    "version": 2,
    "external_version_id": "RET-2026-0919-11",
    "deducted_amount": 3700000,
    "remaining_amount": 10100000,
    "reason": "مرجوعی کتری، حذف هزینه بسته‌بندی و کاهش هزینه ارسال یخچال",
    "ref_id": "3a1b9c0d-7e8f-4a2b-9c1d-0e2f3a4b5c6d",
    "is_empty": false
  },
  "meta": null
}
  • deducted_amount: مبلغی که در همین اصلاح به کاربر بازگردانده شد.
  • remaining_amount: ارزش باقی‌ماندهٔ سفارش.
  • ref_id: ID تراکنش بازگشت وجه.
  • is_empty: اگر ارزش سفارش به صفر رسیده باشد true است.

سفارش می‌تواند طی چند مرحله اصلاح شود؛ هر بار فقط تفاوت نسبت به آخرین نسخه بازگردانده می‌شود.

لغو کامل سفارش

POST/gateway/order/{order_id}/cancel

کل سفارش لغو و تمام وجه به حساب کاربر بازگردانده می‌شود. سفارش باید تلاش پرداخت تأییدشده (VERIFY_OK) داشته باشد، در غیر این صورت ORDER_ATTEMPT_NOT_PAID. لغو سفارشی که ارزش آن صفر شده است با ORDER_UPDATE_NO_CHANGE رد می‌شود.

نمونه پاسخ
{
  "success": true,
  "data": {
    "ref_id": "5f7d1a30-1c77-4a2b-b6d1-0f3f41f9c5e2",
    "status": "VERIFY_OK",
    "fee": 15500
  },
  "meta": null
}

اگر تمام مبلغ سفارش پیش‌تر بازگردانده شده باشد، response لغو با کد ۴۰۰ و خطای ORDER_UPDATE_NO_CHANGE برگردانده می‌شود:

نمونه پاسخ
{
  "success": false,
  "error": {
    "code": "ORDER_UPDATE_NO_CHANGE",
    "message": "وضعیت جدید اعلام‌شده برای سفارش با وضعیت فعلی آن تفاوتی ندارد.",
    "details": null
  }
}

سایر خطاهای این endpoint در بخش «فهرست خطاها» (لغو سفارش) آمده است.

جزئیات و تاریخچهٔ سفارش

GET/gateway/order/{order_id}

احراز هویت: token اپلیکیشن پذیرنده. order_id همان ID سفارش در مهراد است و سفارش باید متعلق به همین پذیرنده باشد (در غیر این صورت ORDER_NOT_FOUND).

این endpoint وضعیت فعلی سفارش، مبالغ و تاریخچهٔ کامل نسخه‌ها (ایجاد اولیه و هر اصلاح کاهشی) را برمی‌گرداند. نسخهٔ ۱ همان سفارش اولیه است و هر اصلاح یک نسخهٔ جدید می‌سازد. اقلام سفارش در هر نسخه داخل shipments همان نسخه قرار دارند؛ آخرین نسخه، مرسوله‌ها و اقلام فعلی سفارش را نشان می‌دهد. سفارشی که با items (روش منسوخ) ثبت شده، یک مرسولهٔ بدون شناسه (external_id برابر null) دارد.

فیلدهای response

فیلدهای پاسخ21 فیلد
iduuid
ID سفارش در مهراد.
external_order_idstring
ID سفارش در سیستم پذیرنده.
tracking_codestring
کد پیگیری سفارش.
channelstring
کانال ثبت سفارش.
statusstring
وضعیت سفارش (بخش «وضعیت‌ها»).
ref_idstring | null
شناسهٔ مرجع پرداخت که در verify برگردانده شده است.
feeinteger | null
کارمزد سیستم روی پرداخت تأییدشده.
created_atstring
زمان ایجاد سفارش (ISO 8601).
serviceobject | null
سرویس پذیرنده که سفارش روی آن ثبت شده است.
فیلدهای service3 فیلد
iduuid
ID سرویس.
namestring
نام سرویس.
slugstring
slug سرویس.
is_shippedboolean
آیا همهٔ مرسوله‌ها ارسال شده‌اند.
shipped_atstring | null
زمان ارسال آخرین مرسوله؛ تا ارسال همهٔ مرسوله‌ها null است.
is_deliveredboolean
آیا همهٔ مرسوله‌ها تحویل شده‌اند.
delivered_atstring | null
زمان تحویل آخرین مرسوله؛ تا تحویل همهٔ مرسوله‌ها null است.
versioninteger
شمارهٔ نسخهٔ فعلی سفارش (تعداد نسخه‌ها).
external_version_idstring | null
external_version_id آخرین اصلاح.
amountinteger
ارزش باقی‌ماندهٔ سفارش در نسخهٔ فعلی.
paid_amountinteger
مبلغی که کاربر برای نسخهٔ اول سفارش پرداخت کرده است.
refunded_amountinteger
مجموع مبالغ بازگردانده‌شده به کاربر در همهٔ اصلاح‌ها.
service_feeinteger
مجموع هزینهٔ ارسال مرسوله‌ها و خدمات (`services`) باقی‌ماندهٔ نسخهٔ فعلی.
discount_amountinteger
تخفیف باقی‌ماندهٔ نسخهٔ فعلی.
versionsarray of objects
تاریخچهٔ کامل نسخه‌ها (ایجاد اولیه و هر اصلاح)، از قدیمی به جدید.
فیلدهای هر عضو لیست versions13 فیلد
iduuid
ID نسخه.
versioninteger
شمارهٔ نسخه.
external_version_idstring | null
external_version_id این اصلاح؛ برای نسخهٔ ۱ null است.
amountinteger
ارزش سفارش در این نسخه.
service_feeinteger
مجموع هزینهٔ ارسال مرسوله‌ها و خدمات در این نسخه.
discount_amountinteger
تخفیف در این نسخه.
reasonstring
علت اصلاح؛ برای نسخهٔ ۱ برابر initial است.
deducted_amountinteger
مبلغ کاهش‌یافته نسبت به نسخهٔ قبل؛ برای نسخهٔ ۱ صفر است.
ref_iduuid | null
ID تراکنش بازگشت وجه این اصلاح.
is_emptyboolean
اگر ارزش سفارش در این نسخه صفر باشد true است.
created_atstring
زمان ثبت نسخه (ISO 8601).
detailsobject
دادهٔ اضافی همان نسخه، مثل services و order_url.
shipmentsarray of objects
مرسوله‌های سفارش در این نسخه، هر کدام با اقلام و وضعیت ارسال و تحویل خودش.
فیلدهای هر عضو لیست shipments6 فیلد
iduuid
ID این مرسوله در مهراد.
external_idstring | null
ID مرسوله در سیستم پذیرنده؛ برای سفارشی که با `items` ثبت شده null است.
shipping_feeinteger
هزینهٔ ارسال این مرسوله.
shipped_atstring | null
زمان ثبت ارسال همین مرسوله.
delivered_atstring | null
زمان ثبت تحویل همین مرسوله.
itemsarray of objects
اقلام این مرسوله.
فیلدهای هر عضو لیست items12 فیلد
iduuid
ID این قلم در مهراد.
titlestring
عنوان کالا.
priceinteger
قیمت واحد کالا.
quantityinteger
تعداد.
external_idstring | null
همان ID کالا که در request ارسال شده بود (product_id یا product.id).
variant_idstring | null
ID تنوع؛ برای اقلامی که با `items` ثبت شده‌اند null است.
variant_titlestring | null
عنوان تنوع؛ برای اقلامی که با `items` ثبت شده‌اند null است.
product_urlstring | null
همان لینک کالا که در request ارسال شده بود.
is_domesticboolean | null
تولید داخل بودن کالا؛ اگر ارسال نشده باشد یا قلم با `items` ثبت شده باشد null است.
image_urlstring | null
تصویر کالا.
thumbnail_urlstring | null
تصویر کوچک کالا؛ برای اقلامی که با `items` ثبت شده‌اند null است.
extra_dataobject | null
همان دادهٔ آزادی که در extra_data ارسال شده بود.

نمونه response

سفارشی با دو مرسوله که مرسولهٔ S1 آن ارسال شده و در یک اصلاح، مرسولهٔ S2 از آن حذف شده است:

نمونه پاسخ
{
  "success": true,
  "data": {
    "id": "e03c6ea8-4617-423b-89cb-67b8388480eb",
    "external_order_id": "ord-a700fcb49e",
    "tracking_code": "27136245",
    "channel": "ONLINE",
    "status": "SUCCESS",
    "ref_id": "98c73b03-087e-4fbd-97e9-637e73ce719b",
    "fee": 900,
    "created_at": "2026-10-06T07:25:13.498346+00:00",
    "service": {
      "id": "2f1b7d6e-2f4e-4a1a-9c22-6f0c0a1d5b31",
      "name": "فروشگاه اینترنتی",
      "slug": "online-shop"
    },
    "is_shipped": true,
    "shipped_at": "2026-10-07T09:10:42.120554+00:00",
    "is_delivered": false,
    "delivered_at": null,
    "version": 2,
    "external_version_id": "RET-2026-1006-1",
    "amount": 50000,
    "paid_amount": 75000,
    "refunded_amount": 25000,
    "service_fee": 5000,
    "discount_amount": 0,
    "versions": [
      {
        "id": "cbdaaab6-e654-4830-988b-b63e404a10a5",
        "version": 1,
        "external_version_id": null,
        "amount": 75000,
        "service_fee": 10000,
        "discount_amount": 0,
        "reason": "initial",
        "deducted_amount": 0,
        "ref_id": null,
        "is_empty": false,
        "created_at": "2026-10-06T07:25:13.498346+00:00",
        "shipments": [
          {
            "id": "7b2f6c1e-0a49-4e7c-9a53-2f1d84c0e1aa",
            "external_id": "S1",
            "shipping_fee": 5000,
            "shipped_at": "2026-10-07T09:10:42.120554+00:00",
            "delivered_at": null,
            "items": [
              {
                "id": "ea7cf730-9310-4093-ad18-0e4b012f08b3",
                "title": "یخچال فریزر ساید بای ساید هیمالیا مدل HI-M900",
                "price": 45000,
                "quantity": 1,
                "external_id": "12acae-A",
                "variant_id": "A-silver",
                "variant_title": "نقره‌ای",
                "product_url": "https://shop.example.com/products/12acae-A",
                "is_domestic": true,
                "image_url": "https://shop.example.com/images/12acae-A.png",
                "thumbnail_url": "https://shop.example.com/images/12acae-A-thumb.png",
                "extra_data": { "warranty_months": 18 }
              }
            ]
          },
          {
            "id": "c1d9e5f3-6a77-4b0c-8e2d-93a1b7f40c52",
            "external_id": "S2",
            "shipping_fee": 5000,
            "shipped_at": null,
            "delivered_at": null,
            "items": [
              {
                "id": "54d8c9f4-76a8-4a71-8b75-fdcdf5211049",
                "title": "برنج ایرانی هاشمی درجه یک گیلان ۱۰ کیلوگرمی",
                "price": 20000,
                "quantity": 1,
                "external_id": "12acae-B",
                "variant_id": "B-10kg",
                "variant_title": "۱۰ کیلوگرمی",
                "product_url": "https://shop.example.com/products/12acae-B",
                "is_domestic": true,
                "image_url": "https://shop.example.com/images/12acae-B.png",
                "thumbnail_url": "https://shop.example.com/images/12acae-B-thumb.png",
                "extra_data": null
              }
            ]
          }
        ],
        "details": {
          "order_url": "https://shop.example.com/orders/ord-a700fcb49e"
        }
      },
      {
        "id": "5d7bf1a9-0166-446d-8b7b-e832d3f703b8",
        "version": 2,
        "external_version_id": "RET-2026-1006-1",
        "amount": 50000,
        "service_fee": 5000,
        "discount_amount": 0,
        "reason": "مرجوعی برنج",
        "deducted_amount": 25000,
        "ref_id": "3a1b9c0d-7e8f-4a2b-9c1d-0e2f3a4b5c6d",
        "is_empty": false,
        "created_at": "2026-10-06T07:25:13.973359+00:00",
        "shipments": [
          {
            "id": "0753e4e5-5f9a-43a6-a4af-64a76b9d5c3a",
            "external_id": "S1",
            "shipping_fee": 5000,
            "shipped_at": "2026-10-07T09:10:42.120554+00:00",
            "delivered_at": null,
            "items": [
              {
                "id": "70a60588-2dc5-4e71-bae6-1ab4fa15cfe9",
                "title": "یخچال فریزر ساید بای ساید هیمالیا مدل HI-M900",
                "price": 45000,
                "quantity": 1,
                "external_id": "12acae-A",
                "variant_id": "A-silver",
                "variant_title": "نقره‌ای",
                "product_url": "https://shop.example.com/products/12acae-A",
                "is_domestic": true,
                "image_url": "https://shop.example.com/images/12acae-A.png",
                "thumbnail_url": "https://shop.example.com/images/12acae-A-thumb.png",
                "extra_data": { "warranty_months": 18 }
              }
            ]
          }
        ],
        "details": {
          "order_url": "https://shop.example.com/orders/ord-a700fcb49e"
        }
      }
    ]
  },
  "meta": null
}

در این نمونه سفارش با دو مرسوله به مبلغ ۷۵٬۰۰۰ پرداخت شده و در یک اصلاح، مرسولهٔ S2 (کالا و هزینهٔ ارسالش، جمعاً ۲۵٬۰۰۰) از آن حذف شده است؛ refunded_amount مجموع deducted_amount نسخه‌هاست. پس از حذف S2، تنها مرسولهٔ باقی‌مانده (S1) ارسال شده است و به همین دلیل is_shipped سفارش true است. تا زمانی که ارسال یا تحویلی ثبت نشده باشد، is_shipped / is_delivered برابر false و shipped_at / delivered_at برابر null هستند.

ساختار مرسوله (OrderShipment) و کالا (OrderItem) در response‌های سفارش

اقلام یک سفارش در response همیشه داخل مرسوله می‌آیند (versions[].shipments[].items)، صرف نظر از این‌که سفارش با shipments یا items ثبت شده باشد. هر مرسوله با این ساختار می‌آید:

فیلدهای پاسخ6 فیلد
iduuid
ID این مرسوله در مهراد.
external_idstring | null
ID مرسوله در سیستم پذیرنده؛ برای سفارشی که با `items` ثبت شده null است.
shipping_feeinteger
هزینهٔ ارسال این مرسوله.
shipped_atstring | null
زمان ثبت ارسال همین مرسوله.
delivered_atstring | null
زمان ثبت تحویل همین مرسوله.
itemsarray of objects
اقلام این مرسوله.
فیلدهای هر عضو لیست items12 فیلد
iduuid
ID این قلم در مهراد.
titlestring
عنوان کالا.
priceinteger
قیمت واحد کالا.
quantityinteger
تعداد.
external_idstring | null
همان ID کالا که در request ارسال شده بود (product_id یا product.id).
variant_idstring | null
ID تنوع؛ برای اقلامی که با `items` ثبت شده‌اند null است.
variant_titlestring | null
عنوان تنوع؛ برای اقلامی که با `items` ثبت شده‌اند null است.
product_urlstring | null
همان لینک کالا که در request ارسال شده بود.
is_domesticboolean | null
تولید داخل بودن کالا؛ اگر ارسال نشده باشد یا قلم با `items` ثبت شده باشد null است.
image_urlstring | null
تصویر کالا.
thumbnail_urlstring | null
تصویر کوچک کالا؛ برای اقلامی که با `items` ثبت شده‌اند null است.
extra_dataobject | null
همان دادهٔ آزادی که در extra_data ارسال شده بود.

برای اقلامی که با items (روش منسوخ) ثبت شده‌اند، فیلدهای variant_id، variant_title، is_domestic، thumbnail_url و extra_data در response null خواهند بود.


وضعیت‌ها

وضعیت سفارش (status)

وضعیتمعنی
PENDINGسفارش ساخته شده و هنوز پرداخت تأییدشده ندارد
SUCCESSپرداخت تأیید شده است
FAILEDپرداخت انجام یا تأیید نشده و سفارش بسته شده است

وضعیت تلاش پرداخت

وضعیتمعنیاقدام لازم
PENDINGدر انتظار پرداخت کاربرانتظار
PAIDکاربر پرداخت کرده، در انتظار تأیید پذیرندهتأیید پرداخت (مرحلهٔ ۵)
VERIFY_OKپرداخت تأیید شدهنهایی‌سازی سفارش
VERIFY_FAILEDتأیید با مبلغ نادرست انجام شد و پرداخت باطل شدسفارش جدیدی لازم است
VERIFY_TIMEOUTمهلت ۳۰ دقیقه‌ای تأیید گذشت و وجه به کاربر بازگشتسفارش جدیدی لازم است
CANCELEDتلاش پرداختِ انجام‌نشده پس از انقضا توسط سامانه لغو شدسفارش جدیدی لازم است
USER_CANCELEDکاربر پرداخت را لغو کردسفارش جدیدی لازم است

یک سفارش می‌تواند چند تلاش پرداخت داشته باشد؛ برای مثال کاربر یک‌بار لغو کند و بار دوم پرداخت کند.


فهرست خطاها

اگر request با خطا مواجه شود، response آن کدی غیر از ۲xx دارد و success در آن false است. کد خطا در فیلد error.code و متن قابل نمایش در error.message برگردانده می‌شود. ساختار کامل خطا در بخش مقدمه آمده است. خطاهای مشترک همهٔ endpoint‌ها (VALIDATION_ERROR، FINANCIAL_OPERATIONS_FROZEN و نبود header Authorization) در همان بخش آمده‌اند.

خطاهای authentication

کد خطاHTTPendpointتوضیح و اقدام پیشنهادی
SSO_INVALID_ACCESS_TOKEN401ایجاد پرداختAccess Token نامعتبر یا منقضی است؛ کاربر باید دوباره وارد شود.
SSO_INSUFFICIENT_SCOPE403ایجاد پرداختtoken فاقد scope order است و details.required_scope برابر order است؛ فعال‌سازی آن نیازمند هماهنگی با مهراد است.
HTTP_EXCEPTION401تأیید پرداخت و استعلام وضعیتheader Authorization ارسال نشده، یا token نه token معتبر اپلیکیشن پذیرنده است و نه Access Token معتبر SSO. message در این حالت Unauthorized است. یک‌بار token تازه باید دریافت و request تکرار شود.
MERCHANT_APP_TOKEN_EXPIRED_OR_INVALID401سایر endpoint‌هاtoken اپلیکیشن پذیرنده نامعتبر یا منقضی است؛ جزئیات در مستندات ارتباط پذیرندگان.
MERCHANT_APP_IP_ADDRESS_NOT_ALLOWED403سایر endpoint‌هاآی‌پی request در لیست سفید اپلیکیشن پذیرنده نیست.
نمونه پاسخ
{
  "success": false,
  "error": {
    "code": "HTTP_EXCEPTION",
    "message": "Unauthorized",
    "details": null
  }
}

ایجاد پرداخت

POST/gateway/order/payment/request
کد خطاHTTPتوضیح و اقدام پیشنهادی
VALIDATION_ERROR422ساختار request نامعتبر است؛ برای مثال ارسال همزمان items و shipments یا ارسال نکردن هیچ‌کدام، id تکراری برای مرسوله‌ها، shipping_fee یا تخفیف منفی، قیمت یا مبلغ خدمت صفر یا منفی، تعداد کمتر از ۱، یا callback_url نامعتبر.
ORDER_AMOUNT_NOT_POSITIVE400مبلغ نهایی صفر یا منفی است.
DUPLICATE_ORDER_ITEM400یک کالا با همان ID و همان تنوع بیش از یک‌بار در سفارش (در items یا در مرسوله‌های مختلف shipments) آمده؛ اگر این موارد در واقع یک قلم هستند، باید quantity افزایش یابد؛ در غیر این صورت باید variant.id یا product_id/product.id متفاوتی ارسال شود.
INVALID_ORDER_AMOUNT400amount با اقلام، هزینهٔ ارسال مرسوله‌ها، خدمات و تخفیف هم‌خوان نیست.
ORDER_ALREADY_PAID400سفارشی که این external_order_id به آن تعلق دارد قبلاً پرداخت شده است.
ORDER_IS_NOT_PENDING400سفارشی که این external_order_id به آن تعلق دارد بسته شده است (FAILED)؛ برای خرید دوباره باید external_order_id جدیدی ارسال شود.
ORDER_USER_NOT_MATCHED400سفارشی با همین external_order_id قبلاً برای کاربر دیگری ثبت شده است.
نمونه پاسخ
{
  "success": false,
  "error": {
    "code": "INVALID_ORDER_AMOUNT",
    "message": "مبلغ ارسالی شما با مبلغ ثبت‌شده روی سفارش یکی نیست.",
    "details": null
  }
}

تأیید پرداخت

POST/gateway/order/payment/verify
کد خطاHTTPتوضیح و اقدام پیشنهادی
VALIDATION_ERROR422amount ارسال نشده، یا هیچ‌یک از authority و order_id ارسال نشده یا هر دو با هم ارسال شده‌اند.
ATTEMPT_NOT_FOUND404تلاش پرداختی با این authority وجود ندارد.
ORDER_NOT_FOUND404سفارشی با این order_id وجود ندارد.
ORDER_MERCHANT_NOT_MATCHED400سفارش متعلق به پذیرندهٔ دیگری است.
ORDER_ALREADY_PAID400این پرداخت قبلاً تأیید شده است؛ پرداخت موفق در نظر گرفته می‌شود و تأیید نباید تکرار شود.
ORDER_ATTEMPT_NOT_PAID400پرداختی برای تأیید وجود ندارد؛ کاربر هنوز پرداخت نکرده یا مهلت تأیید گذشته است. وضعیت باید استعلام شود.
ORDER_AMOUNT_NOT_MATCHED400مبلغ تأیید با مبلغ تلاش پرداخت برابر نیست؛ پرداخت باطل و مبلغ به کاربر بازگردانده شد.
نمونه پاسخ
{
  "success": false,
  "error": {
    "code": "ORDER_AMOUNT_NOT_MATCHED",
    "message": "مبلغ درخواستی با مبلغ مندرج در فاکتور سفارش متفاوت است.",
    "details": null
  }
}

استعلام وضعیت پرداخت

GET/gateway/order/payment/{authority}/status
کد خطاHTTPتوضیح و اقدام پیشنهادی
VALIDATION_ERROR422authority قالب UUID ندارد.
ATTEMPT_NOT_FOUND404تلاش پرداختی با این authority وجود ندارد.
ORDER_MERCHANT_NOT_MATCHED400تلاش پرداخت متعلق به پذیرندهٔ دیگری است.
نمونه پاسخ
{
  "success": false,
  "error": {
    "code": "ATTEMPT_NOT_FOUND",
    "message": "پرداخت مرتبط با این سفارش وجود ندارد.",
    "details": null
  }
}

ثبت ارسال و تحویل

POST/gateway/order/{order_id}/shipped
POST/gateway/order/{order_id}/deliver
کد خطاHTTPتوضیح و اقدام پیشنهادی
VALIDATION_ERROR422order_id قالب UUID ندارد.
ORDER_NOT_FOUND404سفارشی با این order_id وجود ندارد.
ORDER_MERCHANT_NOT_MATCHED400سفارش متعلق به پذیرندهٔ دیگری است.
ORDER_ATTEMPT_NOT_PAID400سفارش در وضعیت SUCCESS نیست؛ ارسال و تحویل فقط برای سفارش تأییدشده ثبت می‌شود.
ORDER_SHIPMENT_NOT_FOUND404مرسوله‌ای با این shipment_id در سفارش نیست؛ یا برای سفارشِ دارای مرسوله، shipment_id ارسال نشده، یا برای سفارشِ بدون شناسهٔ مرسوله ارسال شده است.
ORDER_ALREADY_SHIPPED400این مرسوله (یا سفارش) قبلاً ارسال شده است (فقط در ثبت ارسال).
ORDER_ALREADY_DELIVERED400این مرسوله (یا سفارش) قبلاً تحویل شده است (فقط در ثبت تحویل).
ORDER_NOT_SHIPPED_YET400پیش از ثبت تحویل، ارسال همان مرسوله باید ثبت شده باشد (فقط در ثبت تحویل).
نمونه پاسخ
{
  "success": false,
  "error": {
    "code": "ORDER_NOT_SHIPPED_YET",
    "message": "برای تحویل سفارش ابتدا باید سفارش ارسال شده باشد.",
    "details": null
  }
}

اصلاح کاهشی سفارش

POST/gateway/order/{order_id}/update
کد خطاHTTPتوضیح و اقدام پیشنهادی
VALIDATION_ERROR422ساختار request نامعتبر است؛ برای مثال ارسال همزمان items و shipments، id تکراری برای مرسوله‌ها، مقدار منفی، یا external_version_id بیش از ۲۵۵ کاراکتر.
ORDER_NOT_FOUND404سفارشی با این order_id وجود ندارد یا متعلق به این پذیرنده نیست.
ORDER_ATTEMPT_NOT_PAID400سفارش هنوز تأیید نشده است؛ اصلاح فقط برای سفارش تأییدشده ممکن است.
ORDER_UPDATE_VALUE_INCREASED400اصلاح باعث افزایش مقدار یا ارزش سفارش شده است؛ یا مرسوله یا قلمی آمده که در سفارش نیست، قلمی بدون ID کالا آمده، یا یک ترکیب (کالا + تنوع) تکرار شده است.
ORDER_ITEM_PRICE_MISMATCH400قیمت واحد ارسالی با قیمت ثبت‌شده روی سفارش یکی نیست.
INVALID_ORDER_AMOUNT400تخفیف ارسالی از مجموع اقلام و خدمات باقی‌مانده بیشتر است و مبلغ جدید منفی می‌شود.
ORDER_UPDATE_NO_CHANGE400اصلاح ارسالی با وضعیت فعلی سفارش تفاوتی ندارد.
DUPLICATE_EXTERNAL_VERSION_ID409external_version_id قبلاً برای یکی از سفارش‌های همین پذیرنده ثبت شده است؛ برای هر اصلاح باید ID جدیدی ارسال شود.
ORDER_REFUND_ALLOCATION_FAILED409مبلغ بازگشتی اصلاح بین حساب‌های پرداخت کاربر قابل تقسیم نیست؛ پیش از تلاش مجدد باید با مهراد هماهنگ شود.
ORDER_PAYMENT_SOURCE_NOT_FOUND404سوابق پرداخت سفارش برای بازگشت وجه یافت نشد؛ باید با مهراد هماهنگ شود.
MERCHANT_ACCOUNT_NOT_FOUND404حساب پذیرنده برای این سرویس تعریف نشده است؛ باید با مهراد هماهنگ شود.
نمونه پاسخ
{
  "success": false,
  "error": {
    "code": "ORDER_UPDATE_VALUE_INCREASED",
    "message": "در تغییر سفارش، مقادیر فقط می‌توانند کاهش پیدا کنند.",
    "details": null
  }
}

لغو سفارش

POST/gateway/order/{order_id}/cancel
کد خطاHTTPتوضیح و اقدام پیشنهادی
VALIDATION_ERROR422order_id قالب UUID ندارد.
ORDER_NOT_FOUND404سفارشی با این order_id وجود ندارد.
ORDER_MERCHANT_NOT_MATCHED400سفارش متعلق به پذیرندهٔ دیگری است.
ORDER_ATTEMPT_NOT_PAID400سفارش هنوز تأیید نشده است؛ پرداخت تأییدنشده پس از پایان مهلت خودکار به کاربر بازمی‌گردد.
ORDER_UPDATE_NO_CHANGE400تمام مبلغ سفارش پیش‌تر بازگردانده شده است؛ لغو دوباره لازم نیست.
ORDER_REFUND_ALLOCATION_FAILED409مبلغ بازگشتی بین حساب‌های پرداخت کاربر قابل تقسیم نیست؛ پیش از تلاش مجدد باید با مهراد هماهنگ شود.
ORDER_PAYMENT_SOURCE_NOT_FOUND404سوابق پرداخت سفارش برای بازگشت وجه یافت نشد؛ باید با مهراد هماهنگ شود.
MERCHANT_ACCOUNT_NOT_FOUND404حساب پذیرنده برای این سرویس تعریف نشده است؛ باید با مهراد هماهنگ شود.
نمونه پاسخ
{
  "success": false,
  "error": {
    "code": "ORDER_UPDATE_NO_CHANGE",
    "message": "وضعیت جدید اعلام‌شده برای سفارش با وضعیت فعلی آن تفاوتی ندارد.",
    "details": null
  }
}

جزئیات سفارش

GET/gateway/order/{order_id}
کد خطاHTTPتوضیح و اقدام پیشنهادی
VALIDATION_ERROR422order_id قالب UUID ندارد.
ORDER_NOT_FOUND404سفارشی با این order_id وجود ندارد یا متعلق به این پذیرنده نیست.
نمونه پاسخ
{
  "success": false,
  "error": {
    "code": "ORDER_NOT_FOUND",
    "message": "سفارشی با این مشخصات وجود ندارد.",
    "details": null
  }
}

چک‌لیست پیاده‌سازی

  • دریافت Access Token از SSO و اطمینان از فعال بودن scope order
  • تولید external_order_id یکتا برای هر سفارش
  • ثبت اقلام با shipments. items منسوخ است و در نسخه‌های آینده حذف می‌شود
  • محاسبهٔ amount طبق قاعدهٔ مبلغ (اقلام، shipping_fee مرسوله‌ها، services و discount_amount)
  • ذخیرهٔ authority، order_id و tracking_code کنار سفارش
  • هدایت کاربر به payment_url بدون هیچ تغییری در آدرس
  • پیاده‌سازی مسیر callback_url و خواندن authority و status
  • استعلام وضعیت از API و اتکا نکردن به parameterهای آدرس بازگشت
  • تأیید پرداخت با authority و مبلغ دقیق، داخل مهلت ۳۰ دقیقه
  • ذخیرهٔ ref_id برای تطبیق حساب
  • مدیریت حالتی که کاربر هرگز به سایت بازنمی‌گردد
  • مدیریت خطاهای ORDER_ALREADY_PAID، ORDER_ATTEMPT_NOT_PAID و ORDER_AMOUNT_NOT_MATCHED
  • پیاده‌سازی ارسال، تحویل (به‌ازای هر مرسوله و با shipment_id)، اصلاح و لغو سفارش در صورت نیاز کسب‌وکار
  • تولید external_version_id یکتا برای هر اصلاح سفارش

در این صفحه