مقدمه

وب‌سرویس (API) پِی زیتو برای اتصال به یک سایت که دارای افزونه پرداخت پِی زیتو است طراحی شده است.

به این مفهوم که شما می‌توانید در سایتی که بر روی آن افزونه پِی زیتو را دارید، با فعال‌سازی سرویس ویژه وب‌سرویس (API)، آن سایت را تبدیل به یک درگاه پرداخت واسط یا همان میزبان وب‌سرویس پرداخت کنید.

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

سایتی که قرار است میزبان وب‌سرویس باشد باید یک سایت وردپرسی یا جوملایی باشد، نسخه حرفه‌ای پِی زیتو روی آن نصب باشد و سرویس ویژه وب‌سرویس (API) را نیز خریداری و فعال‌سازی نموده باشد.

اگر فروشگاهی که قرار است به سایت میزبان وب‌سرویس وصل شود جوملا یا وردپرس است، فعالسازی بسیار ساده است. روی آن سایت هم پِی زیتو حرفه‌ای نصب و فعال‌سازی شود و سرویس ویژه وب‌سرویس (API) را نیز خریداری و فعال شده باشد؛ سپس با نصب و تنظیم درگاه وب‌سرویس در بخش درگاه‌ها، سایت خود را به سایت میزبان وب‌سرویس متصل کنید.

اما اگر فروشگاه سایتی غیر از جوملا و وردپرس باشد، می‌توانید از این API برای اتصال سایت خود به سایت میزبان وب‌سرویس استفاده نمایید.

APIها بر اساس استاندارد REST هستند؛ درخواست و پاسخ JSON و فقط HTTPS.

مفاهیم

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

سایتی که افزونه پِی زیتو روی آن نصب است و سرویس وب‌سرویس (API) در آن فعال شده. این سایت درگاه‌های پرداخت خود را از طریق API به دیگر فروشگاه‌ها ارائه می‌دهد.

فروشگاه

سایت، اسکریپت، ربات و… که می‌خواهد پرداخت‌هایش را از طریق میزبان وب‌سرویس انجام دهد.

BASE URL

آدرس پایه وب‌سرویس میزبان وب‌سرویس که از پنل پِی زیتو در مسیر سایت میزبان / منوی امکانات / گزینه وب‌سرویس (API) می‌توانید دریافت کنید.

مثال: https://domain.com

ساختار پاسخ API

پاسخ‌های موفق همیشه این شکل را دارند:

{ "success": true, "data": { ... } }
  • success — آیا خود درخواست API با موفقیت پردازش شد (امضا، پارامترها، یافتن رکورد و…). در تأیید پرداخت، success: true به‌معنی موفقیت مالی پرداخت نیست.
  • data — نتیجهٔ واقعی endpoint — فیلدهای هر بخش در مستندات همان endpoint توضیح داده شده است.

پاسخ خطا:

{ "success": false, "error": 1004, "error_message": "امضای درخواست (HMAC) با سرور میزبان مطابقت ندارد..." }

راه‌اندازی

  1. در میزبان وب‌سرویس وارد مدیریت ← افزونه پِی زیتو ← امکانات ← وب‌سرویس (API) شوید.
  2. یک وب‌سرویس بسازید و این سه مقدار را کپی کنید:
    • آدرس پایه وب‌سرویس — مثلاً https://domain.com
    • کلید عمومی — pz_pub_…
    • کلید خصوصی — pz_scr_…
  3. اگر فروشگاه وردپرس یا جوملا است، پِی زیتو حرفه‌ای را برای فروشگاه تهیه نموده و نصب کنید، سرویس ویژه وب‌سرویس (API) را هم خریداری نموده. سپس از طریق درگاه‌ها، درگاه وب‌سرویس را نصب، فعالسازی و تنظیم کنید.

    اگر فروشگاه وردپرس و جوملا نیست، از طریق این API می‌توانید اتصال را انجام دهید.

احراز هویت

برای endpointهای محافظت‌شده از الگوریتم HMAC-SHA256 استفاده می‌شود. به‌جای ارسال رمز یا توکن روی شبکه، فروشگاه هر درخواست را با Secret امضا می‌کند و میزبان وب‌سرویس امضا را بررسی می‌کند.

کلیدهای API — Public Key و Secret

هر پروفایل وب‌سرویس در میزبان وب‌سرویس دو مقدار دارد:

نامپیشوندنقشارسال روی شبکه؟
کلید عمومی (Public Key) pz_pub_ شناسایی پروفایل وب‌سرویس — در header X-Payzito-Key بله
کلید خصوصی (Secret) pz_scr_ کلید امضای HMAC — فقط روی سرور فروشگاه نگه‌داری می‌شود خیر — هرگز

نحوه استفاده در هر درخواست

چهار header زیر برای هر درخواست API الزامی است. X-Payzito-Key ثابت می‌ماند؛ اما X-Payzito-Timestamp، X-Payzito-Nonce و X-Payzito-Signature را برای هر درخواست از نو بسازید — کپی‌کردن مقادیر از درخواست قبلی معتبر نیست.

مقدار X-Payzito-Signature از اتصال timestamp + nonce + bodyRaw با Secret و الگوریتم HMAC-SHA256 ساخته می‌شود — bodyRaw در بخش بعد توضیح داده شده است.

X-Payzito-Key REQUIRED string

کلید عمومی (pz_pub_…) از تب وب‌سرویس (API) در میزبان وب‌سرویس

X-Payzito-Timestamp REQUIRED string

Unix timestamp — اختلاف با سرور حداکثر ۳۰۰ ثانیه

X-Payzito-Nonce REQUIRED string

رشته یکتا — برای هر درخواست مقدار جدید تولید کنید؛ هر nonce فقط یک‌بار قابل استفاده است و استفادهٔ مجدد با خطای replay_nonce پاسخ داده می‌شود

X-Payzito-Signature REQUIRED string

خروجی HMAC-SHA256:

HMAC-SHA256(timestamp + nonce + bodyRaw, secret)

Secret همان کلید خصوصی pz_scr_… است که فقط روی سرور شما استفاده می‌شود

bodyRaw — بدنهٔ خام درخواست

bodyRaw همان متن خام (raw) بدنهٔ HTTP است — نه آبجکت parse‌شده، بلکه دقیقاً همان رشته‌ای که در body درخواست ارسال می‌شود.

  • POST با JSON: خروجی json_encode(...) (یا معادل آن) قبل از ارسال — همان رشته را هم در body بفرستید و هم در امضا به‌کار ببرید.
  • GET بدون body: رشتهٔ خالی ""

امضا روی همان bodyRaw محاسبه می‌شود که واقعاً ارسال شده است. اگر بعد از امضا بدنه را دوباره encode کنید یا فاصله/ترتیب کلیدها عوض شود، سرور میزبان خطای 1004 برمی‌گرداند.

ایجاد پرداخت

با متد POST و پارامترهای زیر یک پرداخت روی میزبان وب‌سرویس ثبت می‌کنید. در پاسخ موفق (HTTP 201) داخل data این فیلدها برمی‌گردد:

  • payment_id — شناسهٔ داخلی پرداخت روی میزبان (برای Start، Verify و Inquiry)
  • trans_id — همان شمارهٔ سفارش ارسالی از فروشگاه
  • invoice_code — شمارهٔ صورتحساب روی میزبان (طبق قوانین خود میزبان)
  • start_url — آدرس هدایت کاربر به صفحهٔ پرداخت میزبان

پارامترها

amount REQUIRED number

مبلغ تراکنش به ریال

trans_id REQUIRED string

شمارهٔ سفارش در فروشگاه — روی میزبان در ستون «شماره سفارش» ذخیره می‌شود. شمارهٔ صورتحساب میزبان جداگانه و طبق قوانین خود سایت میزبان ساخته می‌شود.

callback_url REQUIRED string

آدرس بازگشت کاربر پس از پرداخت (HTTPS)

webhook_url OPTIONAL string

آدرس اعلان سروربه‌سرور در فروشگاه

cancel_url OPTIONAL string

آدرس بازگشت در صورت لغو پرداخت (HTTPS)

description OPTIONAL string

توضیح تراکنش — در صورتحساب میزبان در فیلد توضیحات

customer OPTIONAL object

اطلاعات خریدار — روی صورتحساب میزبان ثبت می‌شود:

  • name · email · phone
  • address · national_code · birthdate (شمسی)
  • user_id — اگر کاربر ثبت‌نام‌شده در فروشگاه باشد
metadata OPTIONAL object

دادهٔ اضافه — هر کلید به‌صورت ot_* در صورتحساب میزبان ذخیره می‌شود (مثلاً {"source":"custom_shop"})

factor OPTIONAL object

فاکتور فروشگاه — اختیاری. اگر ارسال نشود، میزبان یک آیتم پیش‌فرض با نام پروفایل وب‌سرویس می‌سازد. اگر ارسال شود، داخلش items حداقل یک ردیف لازم است و fees اختیاری است. جمع فاکتور (مجموع amount × count برای آیتم‌ها، با اضافه/کسر fees) باید دقیقاً برابر amount پرداخت باشد.

factor.items[] با factor array

لیست محصولات/خدمات — فقط وقتی factor را می‌فرستید الزامی است (حداقل یک آیتم). بدون factor نیازی به ارسال ندارید.

  • name — عنوان آیتم
  • count — تعداد (عدد صحیح ≥ ۱)
  • amount — مبلغ هر واحد به ریال
  • image — آدرس تصویر (اختیاری)
"items": [{ "name": "محصول الف", "count": 1, "amount": 120000 }]
factor.fees[] OPTIONAL array

ردیف‌های اضافه فاکتور — تخفیف، مالیات، ارسال و…

  • method — نوع: discount · tax · shipment · payment · any
  • name — عنوان ردیف
  • amount — مبلغ به ریال
  • type — + افزایش · - کاهش (برای discount پیش‌فرض -)
"fees": [{ "method": "shipment", "name": "هزینه ارسال", "amount": 15000, "type": "+" }]

پاسخ موفق (HTTP 201)

در صورت ثبت موفق پرداخت روی میزبان وب‌سرویس، پاسخ JSON با success: true برمی‌گردد:

{
  "success": true,
  "data": {
    "payment_id": 12345,
    "trans_id": "TP-000491",
    "invoice_code": "TP-493",
    "start_url": "{BASE_URL}/index.php/pa-api/v1/payments/12345/start"
  }
}
payment_id REQUIRED integer

شناسهٔ داخلی پرداخت روی میزبان وب‌سرویس — همان شناسهٔ رکورد صورتحساب در پنل میزبان. برای start_url، Verify و Inquiry استفاده می‌شود. شماره صورتحساب میزبان نیست (مثلاً TP-493 جدا از این فیلد است).

trans_id REQUIRED string

همان trans_id ارسالی از فروشگاه — تأیید می‌کند شمارهٔ سفارش شما ثبت شده است. در Verify باید دوباره همان مقدار ارسال شود.

invoice_code REQUIRED string

شمارهٔ صورتحساب روی میزبان وب‌سرویس — طبق قوانین خود میزبان ساخته شده (مثلاً TP-493). در فروشگاه در جزئیات لاگ تراکنش ثبت می‌شود.

start_url REQUIRED string

آدرس هدایت کاربر به صفحهٔ پرداخت میزبان — در مرحلهٔ بعد کاربر را به این URL بفرستید.

trans_id تکراری (HTTP 200)

اگر trans_id قبلاً برای این پروفایل وب‌سرویس ثبت شده باشد، همان پاسخ قبلی با HTTP 200 برمی‌گردد — پرداخت جدیدی ساخته نمی‌شود. فیلد duplicate: true به data اضافه می‌شود؛ بقیهٔ فیلدها مثل پاسخ 201 است:

{
  "success": true,
  "data": {
    "payment_id": 12345,
    "trans_id": "TP-000491",
    "invoice_code": "TP-493",
    "start_url": "{BASE_URL}/index.php/pa-api/v1/payments/12345/start",
    "duplicate": true
  }
}

شروع پرداخت

کاربر را به start_url دریافتی از ایجاد پرداخت هدایت کنید تا به صفحهٔ پرداخت میزبان وب‌سرویس منتقل شود.

این endpoint به header احراز هویت نیاز ندارد.

Callback

پس از انجام تراکنش، کاربر به callback_url ارسال‌شده در ایجاد پرداخت برمی‌گردد. Callback فقط اطلاع‌رسانی است؛ برای نهایی شدن تراکنش حتماً endpoint تایید پرداخت را فراخوانی کنید.

تایید پرداخت

آخرین مرحله چرخه پرداخت، تایید تراکنش از میزبان وب‌سرویس است. این endpoint idempotent است.

پارامترها

payment_id REQUIRED integer

شناسه پرداخت دریافتی از مرحلهٔ ایجاد پرداخت

trans_id REQUIRED string

همان شناسه سفارش ارسال‌شده در مرحلهٔ ایجاد پرداخت

پاسخ موفق (HTTP 200)

{
  "success": true,
  "data": {
    "verified": 1,
    "already_verified": 0,
    "payment_id": 12345,
    "trans_id": "TP-000491",
    "status": 10,
    "amount": 150000,
    "ref_number": "REF-98765",
    "gateway_id": 12,
    "gateway_name": "zarinpal"
  }
}
success REQUIRED boolean

همیشه true — یعنی درخواست Verify با موفقیت پردازش شد (امضا معتبر، payment_id و trans_id پیدا شد). موفقیت مالی پرداخت را نشان نمی‌دهد — برای نتیجهٔ پرداخت فیلد data.verified را بررسی کنید.

data REQUIRED object

نتیجهٔ تأیید — فیلدهای زیر داخل این آبجکت هستند.

verified REQUIRED integer

1 = پرداخت شده · 0 = هنوز پرداخت نشده

already_verified REQUIRED integer

1 = قبلاً verify شده (فراخوانی مجدد idempotent)

payment_id REQUIRED integer
trans_id REQUIRED string
status REQUIRED integer

کد وضعیت داخلی صورتحساب روی میزبان

amount REQUIRED number

مبلغ به ریال

ref_number REQUIRED string

شماره مرجع درگاه — اگر پرداخت نشده خالی است

gateway_id REQUIRED integer

شناسهٔ درگاه استفاده‌شده روی میزبان — قبل از پرداخت 0

gateway_name REQUIRED string

نام درگاه — قبل از پرداخت خالی است

اگر پرداخت در وضعیت معلق (on hold) باشد، پاسخ کوتاه‌تر است: verified: 0 · status · message: "on_hold"

استعلام پرداخت

وضعیت فعلی یک پرداخت را فقط می‌خواند — recheck درگاه انجام نمی‌شود. برای تأیید نهایی و به‌روزرسانی از درگاه، از تایید پرداخت (Verify) استفاده کنید.

درخواست

متد GET — شناسهٔ پرداخت در مسیر URL است؛ بدنهٔ HTTP خالی است.

payment_id REQUIRED integer · path

شناسهٔ دریافتی از ایجاد پرداخت — در URL به‌جای 12345 قرار می‌گیرد: /payments/{payment_id}

headerهای احراز هویت HMAC الزامی است. چون بدنه خالی است، برای امضا bodyRaw = رشتهٔ خالی "" است.

پاسخ موفق (HTTP 200)

{
  "success": true,
  "data": {
    "payment_id": 12345,
    "trans_id": "TP-000491",
    "status": 1,
    "amount": 150000,
    "ref_number": "",
    "start_url": "{BASE_URL}/index.php/pa-api/v1/payments/12345/start"
  }
}
success REQUIRED boolean

همیشه true — درخواست API با موفقیت پردازش شد. موفقیت مالی را از data.status بخوانید (مثلاً 10 = پرداخت شده).

data REQUIRED object

اطلاعات فعلی پرداخت روی میزبان.

payment_id REQUIRED integer

شناسهٔ داخلی پرداخت روی میزبان — همان مقدار ارسالی در URL.

trans_id REQUIRED string

شمارهٔ سفارش فروشگاه — همان مقدار ثبت‌شده در ایجاد پرداخت.

status REQUIRED integer

کد وضعیت صورتحساب روی میزبان — مثلاً 1 در انتظار پرداخت · 10 پرداخت شده · 3 لغو شده · 5 معلق · 6 منقضی

amount REQUIRED number

مبلغ تراکنش به ریال.

ref_number REQUIRED string

شماره مرجع درگاه — قبل از پرداخت موفق خالی است.

start_url REQUIRED string

آدرس ادامهٔ پرداخت — اگر هنوز پرداخت نشده، کاربر را به این URL هدایت کنید.

تفاوت با Verify: استعلام فقط وضعیت ذخیره‌شده را برمی‌گرداند؛ Verify در صورت نیاز recheck درگاه انجام می‌دهد و فیلدهای verified · gateway_id · gateway_name را هم می‌دهد.

Webhook

POSTwebhook_url

اگر webhook_url در ایجاد پرداخت ارسال شود، میزبان وب‌سرویس پس از تغییر وضعیت یک POST امضاشده به فروشگاه می‌فرستد.

فیلدهای بدنه: event · payment_id · trans_id · status · amount · ref_number · gateway_name

رویدادها: payment.paid و payment.failed

خطاها

در پاسخ خطا ساختار یکسان است — کد عددی در error و متن خطا در error_message برمی‌گردد. فروشگاه باید برای نمایش به کاربر از error_message میزبان استفاده کند تا با به‌روزرسانی کدها، پیام اشتباه نشان داده نشود.

{
  "success": false,
  "error": 1004,
  "error_message": "امضای درخواست (HMAC) با سرور میزبان مطابقت ندارد. Secret، بدنهٔ خام (bodyRaw) و نحوهٔ encode JSON را بررسی کنید."
}

نمونهٔ خطای عدم تطابق جمع فاکتور (کد 4004) — وقتی جمع items و fees با amount یکی نباشد:

{
  "success": false,
  "error": 4004,
  "error_message": "جمع فاکتور (items و fees) برابر 135000 است اما مبلغ پرداخت (amount) برابر 150000 است. این دو مقدار باید یکسان باشند."
}

دسته‌بندی: رقم هزارگان کد، مجموعهٔ خطا را مشخص می‌کند — هر کد فقط یک معنی دارد.

سریبازهموضوع
۱1001–1099احراز هویت (HMAC، کلید، nonce)
۲2001–2099دسترسی و پروفایل
۳3001–3099اعتبارسنجی ایجاد پرداخت
۴4001–4099فاکتور (factor)
۵5001–5099تأیید و استعلام
۶6001–6099وضعیت پرداخت و مسیر
۹9001–9099سیستم و خطای داخلی

سری ۱ — احراز هویت (HTTP 401)

کدشرح
1001هدرهای احراز هویت کامل نیست. هر چهار مقدار X-Payzito-Key، Timestamp، Nonce و Signature باید در درخواست باشد.
1002زمان درخواست با ساعت سرور میزبان بیش از ۳۰۰ ثانیه اختلاف دارد. ساعت سرور فروشگاه را با میزبان هم‌سان کنید.
1003کلید عمومی ارسالی در میزبان شناخته نشده است. مقدار X-Payzito-Key را از تب وب‌سرویس (API) میزبان دوباره کپی کنید.
1004امضای درخواست (HMAC) با سرور میزبان مطابقت ندارد. Secret، بدنهٔ خام (bodyRaw) و نحوهٔ encode JSON را بررسی کنید.
1005این Nonce قبلاً استفاده شده است. برای هر درخواست یک مقدار یکتا بسازید.

سری ۲ — دسترسی (HTTP 403)

کدشرح
2001پروفایل وب‌سرویس در میزبان غیرفعال است. از پنل میزبان آن را فعال کنید.
2002IP سرور فروشگاه در فهرست مجاز میزبان نیست. IP را در تنظیمات پروفایل API میزبان اضافه کنید.
2003این payment_id به پروفایل API دیگری تعلق دارد. شناسه پرداخت یا کلید API را بررسی کنید.

سری ۳ — ایجاد پرداخت (HTTP 422)

کدشرح
3001مبلغ (amount) معتبر نیست؛ باید عددی مثبت ارسال شود.
3002شناسه تراکنش فروشگاه (trans_id) ارسال نشده یا خالی است.
3003آدرس بازگشت (callback_url) ارسال نشده یا خالی است.
3004آدرس callback_url نامعتبر است؛ باید یک URL کامل با HTTPS باشد.
3005آدرس webhook_url نامعتبر است؛ باید یک URL کامل با HTTPS باشد.
3006آدرس cancel_url نامعتبر است؛ باید یک URL کامل با HTTPS باشد.
3007دامنهٔ callback_url در فهرست مجاز این پروفایل API نیست.
3008دامنهٔ webhook_url در فهرست مجاز این پروفایل API نیست.
3009دامنهٔ cancel_url در فهرست مجاز این پروفایل API نیست.

سری ۴ — فاکتور (factor) (HTTP 422)

کدشرح
4001ساختار factor نادرست است؛ باید آبجکت باشد و فیلد items آرایهٔ معتبر داشته باشد.
4002آرایهٔ items در factor خالی است؛ حداقل یک آیتم لازم است.
4003یکی از آیتم‌های factor نامعتبر است؛ count باید حداقل ۱ و amount باید بزرگ‌تر از ۰ باشد.
4004جمع فاکتور (items و fees) با amount پرداخت یکسان نیست؛ پیام خطا هر دو مبلغ را نشان می‌دهد.

سری ۵ — تأیید / استعلام (HTTP 422)

کدشرح
5001شناسه پرداخت (payment_id) در Verify ارسال نشده یا صفر است.
5002شناسه تراکنش (trans_id) در Verify ارسال نشده یا خالی است.
5003trans_id با payment_id ارسالی هم‌خوان نیست؛ همان شناسهٔ ایجاد پرداخت را بفرستید.

سری ۶ — پرداخت (HTTP 404 · 409)

کدHTTPشرح
6001404پرداختی با این payment_id پیدا نشد یا از طریق API ثبت نشده است.
6002404شناسهٔ عددی در مسیر Start نامعتبر است.
6004404مسیر API اشتباه است؛ آدرس endpoint را با مستندات مقایسه کنید.
6003409این پرداخت در وضعیت «قابل پرداخت» نیست؛ ممکن است قبلاً پرداخت یا لغو شده باشد.

سری ۹ — سرور (HTTP 400 · 500 · 503)

کدHTTPشرح
9001400بدنهٔ درخواست POST خالی است؛ JSON معتبر ارسال کنید.
9002500میزبان هنگام ساخت صورتحساب با خطای داخلی مواجه شد. دوباره تلاش کنید یا با پشتیبانی تماس بگیرید.
9003503افزونهٔ وب‌سرویس (API) روی میزبان نصب یا فعال نیست.
9099500خطای ناشناخته در سرور میزبان رخ داده است.