مقدمه
وبسرویس (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) با سرور میزبان مطابقت ندارد..." }
راهاندازی
- در میزبان وبسرویس وارد مدیریت ← افزونه پِی زیتو ← امکانات ← وبسرویس (API) شوید.
- یک وبسرویس بسازید و این سه مقدار را کپی کنید:
- آدرس پایه وبسرویس — مثلاً
https://domain.com - کلید عمومی —
pz_pub_… - کلید خصوصی —
pz_scr_…
- آدرس پایه وبسرویس — مثلاً
- اگر فروشگاه وردپرس یا جوملا است، پِی زیتو حرفهای را برای فروشگاه تهیه نموده و نصب کنید، سرویس ویژه وبسرویس (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 در بخش بعد توضیح داده شده است.
کلید عمومی (pz_pub_…) از تب وبسرویس (API) در میزبان وبسرویس
Unix timestamp — اختلاف با سرور حداکثر ۳۰۰ ثانیه
رشته یکتا — برای هر درخواست مقدار جدید تولید کنید؛ هر nonce فقط یکبار قابل استفاده است و استفادهٔ مجدد با خطای replay_nonce پاسخ داده میشود
خروجی 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— آدرس هدایت کاربر به صفحهٔ پرداخت میزبان
پارامترها
مبلغ تراکنش به ریال
شمارهٔ سفارش در فروشگاه — روی میزبان در ستون «شماره سفارش» ذخیره میشود. شمارهٔ صورتحساب میزبان جداگانه و طبق قوانین خود سایت میزبان ساخته میشود.
آدرس بازگشت کاربر پس از پرداخت (HTTPS)
آدرس اعلان سروربهسرور در فروشگاه
آدرس بازگشت در صورت لغو پرداخت (HTTPS)
توضیح تراکنش — در صورتحساب میزبان در فیلد توضیحات
اطلاعات خریدار — روی صورتحساب میزبان ثبت میشود:
name·email·phoneaddress·national_code·birthdate(شمسی)user_id— اگر کاربر ثبتنامشده در فروشگاه باشد
دادهٔ اضافه — هر کلید بهصورت ot_* در صورتحساب میزبان ذخیره میشود (مثلاً {"source":"custom_shop"})
فاکتور فروشگاه — اختیاری. اگر ارسال نشود، میزبان یک آیتم پیشفرض با نام پروفایل وبسرویس میسازد. اگر ارسال شود، داخلش items حداقل یک ردیف لازم است و fees اختیاری است. جمع فاکتور (مجموع amount × count برای آیتمها، با اضافه/کسر fees) باید دقیقاً برابر amount پرداخت باشد.
لیست محصولات/خدمات — فقط وقتی factor را میفرستید الزامی است (حداقل یک آیتم). بدون factor نیازی به ارسال ندارید.
name— عنوان آیتمcount— تعداد (عدد صحیح ≥ ۱)amount— مبلغ هر واحد به ریالimage— آدرس تصویر (اختیاری)
"items": [{ "name": "محصول الف", "count": 1, "amount": 120000 }]
ردیفهای اضافه فاکتور — تخفیف، مالیات، ارسال و…
method— نوع:discount·tax·shipment·payment·anyname— عنوان ردیف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"
}
}
شناسهٔ داخلی پرداخت روی میزبان وبسرویس — همان شناسهٔ رکورد صورتحساب در پنل میزبان. برای start_url، Verify و Inquiry استفاده میشود. شماره صورتحساب میزبان نیست (مثلاً TP-493 جدا از این فیلد است).
همان trans_id ارسالی از فروشگاه — تأیید میکند شمارهٔ سفارش شما ثبت شده است. در Verify باید دوباره همان مقدار ارسال شود.
شمارهٔ صورتحساب روی میزبان وبسرویس — طبق قوانین خود میزبان ساخته شده (مثلاً TP-493). در فروشگاه در جزئیات لاگ تراکنش ثبت میشود.
آدرس هدایت کاربر به صفحهٔ پرداخت میزبان — در مرحلهٔ بعد کاربر را به این 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 است.
پارامترها
شناسه پرداخت دریافتی از مرحلهٔ ایجاد پرداخت
همان شناسه سفارش ارسالشده در مرحلهٔ ایجاد پرداخت
پاسخ موفق (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"
}
}
همیشه true — یعنی درخواست Verify با موفقیت پردازش شد (امضا معتبر، payment_id و trans_id پیدا شد). موفقیت مالی پرداخت را نشان نمیدهد — برای نتیجهٔ پرداخت فیلد data.verified را بررسی کنید.
نتیجهٔ تأیید — فیلدهای زیر داخل این آبجکت هستند.
1 = پرداخت شده · 0 = هنوز پرداخت نشده
1 = قبلاً verify شده (فراخوانی مجدد idempotent)
کد وضعیت داخلی صورتحساب روی میزبان
مبلغ به ریال
شماره مرجع درگاه — اگر پرداخت نشده خالی است
شناسهٔ درگاه استفادهشده روی میزبان — قبل از پرداخت 0
نام درگاه — قبل از پرداخت خالی است
اگر پرداخت در وضعیت معلق (on hold) باشد، پاسخ کوتاهتر است: verified: 0 · status · message: "on_hold"
استعلام پرداخت
وضعیت فعلی یک پرداخت را فقط میخواند — recheck درگاه انجام نمیشود. برای تأیید نهایی و بهروزرسانی از درگاه، از تایید پرداخت (Verify) استفاده کنید.
درخواست
متد GET — شناسهٔ پرداخت در مسیر URL است؛ بدنهٔ HTTP خالی است.
شناسهٔ دریافتی از ایجاد پرداخت — در 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"
}
}
همیشه true — درخواست API با موفقیت پردازش شد. موفقیت مالی را از data.status بخوانید (مثلاً 10 = پرداخت شده).
اطلاعات فعلی پرداخت روی میزبان.
شناسهٔ داخلی پرداخت روی میزبان — همان مقدار ارسالی در URL.
شمارهٔ سفارش فروشگاه — همان مقدار ثبتشده در ایجاد پرداخت.
کد وضعیت صورتحساب روی میزبان — مثلاً 1 در انتظار پرداخت · 10 پرداخت شده · 3 لغو شده · 5 معلق · 6 منقضی
مبلغ تراکنش به ریال.
شماره مرجع درگاه — قبل از پرداخت موفق خالی است.
آدرس ادامهٔ پرداخت — اگر هنوز پرداخت نشده، کاربر را به این URL هدایت کنید.
تفاوت با Verify: استعلام فقط وضعیت ذخیرهشده را برمیگرداند؛ Verify در صورت نیاز recheck درگاه انجام میدهد و فیلدهای verified · gateway_id · gateway_name را هم میدهد.
Webhook
اگر 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 | پروفایل وبسرویس در میزبان غیرفعال است. از پنل میزبان آن را فعال کنید. |
2002 | IP سرور فروشگاه در فهرست مجاز میزبان نیست. 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 ارسال نشده یا خالی است. |
5003 | trans_id با payment_id ارسالی همخوان نیست؛ همان شناسهٔ ایجاد پرداخت را بفرستید. |
سری ۶ — پرداخت (HTTP 404 · 409)
| کد | HTTP | شرح |
|---|---|---|
6001 | 404 | پرداختی با این payment_id پیدا نشد یا از طریق API ثبت نشده است. |
6002 | 404 | شناسهٔ عددی در مسیر Start نامعتبر است. |
6004 | 404 | مسیر API اشتباه است؛ آدرس endpoint را با مستندات مقایسه کنید. |
6003 | 409 | این پرداخت در وضعیت «قابل پرداخت» نیست؛ ممکن است قبلاً پرداخت یا لغو شده باشد. |
سری ۹ — سرور (HTTP 400 · 500 · 503)
| کد | HTTP | شرح |
|---|---|---|
9001 | 400 | بدنهٔ درخواست POST خالی است؛ JSON معتبر ارسال کنید. |
9002 | 500 | میزبان هنگام ساخت صورتحساب با خطای داخلی مواجه شد. دوباره تلاش کنید یا با پشتیبانی تماس بگیرید. |
9003 | 503 | افزونهٔ وبسرویس (API) روی میزبان نصب یا فعال نیست. |
9099 | 500 | خطای ناشناخته در سرور میزبان رخ داده است. |