اگه فروشگاه ووکامرسی دارید، دیر یا زود باید درگاه پرداخت ایرانی بهش وصل کنید. توی این راهنما با زرینپال، یکی از پرکاربردترین درگاههای ایران، جریان کامل پرداخت رو با PHP خام پیادهسازی میکنیم و در انتها میبینیم این جریان چطور به معماری ووکامرس وصل میشه.
فهرست مطالب
- چرا اتصال مستقیم، نه فقط یک افزونهی آماده؟
- پیشنیازها
- جریان کلی پرداخت در زرینپال
- مرحله ۱: درخواست پرداخت
- مرحله ۲: هدایت کاربر به درگاه
- مرحله ۳: تأیید تراکنش
- اتصال این جریان به معماری ووکامرس
- جدول کدهای رایج خطا
- اشتباهات رایج
- سوالات متداول
چرا اتصال مستقیم، نه فقط یک افزونهی آماده؟
افزونههای رایگان زیادی برای اتصال زرینپال به ووکامرس وجود دارن و برای اکثر فروشگاههای ساده کاملاً کافیان. اما اگه نیاز به منطق سفارشی دارید — مثلاً چند درگاه همزمان با شرایط انتخاب متفاوت، اتصال پرداخت به یک سیستم اشتراک یا کیفپول داخلی، یا گزارشگیری اختصاصی از تراکنشها — باید بدونید زیر پوستِ این افزونهها چطور کار میکنن. این راهنما دقیقاً همون لایهی زیرینه.
پیشنیازها
- یک حساب پذیرندگی در زرینپال و دریافت merchant_id
- آشنایی پایه با PHP و cURL
- یک سایت با آدرس HTTPS معتبر (زرینپال آدرس بازگشت HTTP ساده رو نمیپذیره)
جریان کلی پرداخت در زرینپال
هر پرداخت زرینپالی سه مرحله داره:
- درخواست پرداخت: به زرینپال میگید مبلغ و توضیحات چیه؛ در ازاش یک کد یکتا (Authority) میگیرید.
- هدایت کاربر: کاربر رو با همون Authority به صفحهی پرداخت زرینپال میفرستید.
- تأیید تراکنش: بعد از پرداخت، کاربر به سایت شما برمیگرده؛ شما باید مبلغ رو با زرینپال «تأیید» کنید تا واقعاً تراکنش نهایی بشه.
مرحله ۱: درخواست پرداخت
<?php
$data = [
"merchant_id" => "YOUR_MERCHANT_ID",
"amount" => 150000, // به ریال؛ حداقل مبلغ مجاز ۱۰,۰۰۰ ریال
"description" => "پرداخت سفارش شماره ۱۲۳۴۵",
"callback_url" => "https://yoursite.com/verify.php",
];
$jsonData = json_encode($data);
$ch = curl_init('https://api.zarinpal.com/pg/v4/payment/request.json');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonData);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Content-Length: ' . strlen($jsonData)
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);
if ($result['data']['code'] == 100) {
$authority = $result['data']['authority'];
// ذخیرهی $authority همراه با مبلغ سفارش در دیتابیس، برای مرحلهی تأیید
} else {
// خطا در ثبت درخواست — جزئیات کد خطا پایینتر آمده
}نکتهی مهم: مقدار amount رو در همین مرحله، همراه شمارهی سفارش، توی دیتابیس ذخیره کنید — چون در مرحلهی تأیید دوباره بهش نیاز دارید و نباید فقط به دادهی برگشتی از کاربر اعتماد کنید.
مرحله ۲: هدایت کاربر به درگاه
header('Location: https://www.zarinpal.com/pg/StartPay/' . $authority);
exit;مرحله ۳: تأیید تراکنش
بعد از پرداخت، زرینپال کاربر رو به همون callback_url با دو پارامتر Authority و Status برمیگردونه. در verify.php:
<?php
$authority = $_GET['Authority'];
$status = $_GET['Status'];
if ($status === 'OK') {
// مبلغ رو از دیتابیس خودتون بخونید، نه از ورودی کاربر
$amount = getAmountFromDatabase($authority);
$data = [
"merchant_id" => "YOUR_MERCHANT_ID",
"amount" => $amount,
"authority" => $authority,
];
$jsonData = json_encode($data);
$ch = curl_init('https://api.zarinpal.com/pg/v4/payment/verify.json');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonData);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Content-Length: ' . strlen($jsonData)
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);
if ($result['data']['code'] == 100) {
$refId = $result['data']['ref_id'];
// پرداخت موفق — سفارش رو تکمیل کنید
} elseif ($result['data']['code'] == 101) {
// این تراکنش قبلاً تأیید شده — از پردازش دوباره جلوگیری کنید
} else {
// پرداخت ناموفق
}
} else {
// کاربر پرداخت رو لغو کرده
}اتصال این جریان به معماری ووکامرس
برای اینکه این جریان بهعنوان یک روش پرداخت واقعی در ووکامرس ظاهر بشه، باید کلاس WC_Payment_Gateway رو گسترش (Extend) بدید. سه بخش اصلی معماری:
- متد
process_payment($order_id): دقیقاً همون کد «مرحله ۱» رو اینجا صدا میزنید و بهجایheader('Location: ...')ساده، آدرس رو در قالب استاندارد ووکامرس (array('result' => 'success', 'redirect' => $payUrl)) برمیگردونید. - Endpoint بازگشتی: بهجای یک فایل جدا مثل
verify.php، معمولاً از هوکwoocommerce_api_{gateway_id}استفاده میکنید تا ووکامرس خودش این URL رو مدیریت کنه. - بهروزرسانی وضعیت سفارش: پس از تأیید موفق، با
$order->payment_complete($refId)سفارش رو تکمیلشده علامت میزنید؛ در صورت شکست، با$order->update_status('failed').
نوشتن کامل این کلاس (شامل تنظیمات ادمین، آیکون درگاه، و مدیریت چند درگاه همزمان) از حوصلهی این مقاله خارجه؛ اگه فروشگاهتون به این سطح از یکپارچگی نیاز داره، دقیقاً همین کاریه که تیم توسعهی ما انجام میده.
جدول کدهای رایج خطا
| کد | معنی |
|---|---|
| 100 | عملیات موفق |
| 101 | تراکنش قبلاً تأیید شده |
| سایر کدهای منفی | خطاهای مختلف (merchant_id نامعتبر، مبلغ کمتر از حداقل، عدم تطابق مبلغ در تأیید و...) |
برای پروژهی واقعی، همیشه پیام دقیق خطا رو هم از فیلد errors پاسخ بخونید، نه فقط کد عددی.
اشتباهات رایج
- اعتماد به مبلغ ارسالی از کاربر در مرحلهی تأیید: همیشه مبلغ رو از دیتابیس خودتون (که در مرحلهی درخواست ذخیره کردید) بخونید، نه از پارامترهای URL.
- عدم بررسی تراکنش تکراری: اگه کاربر صفحهی بازگشتی رو رفرش کنه، بدون چککردن کد ۱۰۱، ممکنه سفارش دوبار پردازش بشه.
- فراموشکردن HTTPS در callback_url: زرینپال آدرس بازگشتی نامعتبر رو نمیپذیره.
- عدم تست در حالت Sandbox: قبل از رفتن به حالت واقعی، تراکنشها رو در محیط آزمایشی زرینپال تست کنید.
سوالات متداول
حداقل مبلغ قابلپرداخت در زرینپال چقدره؟
۱۰,۰۰۰ ریال (۱۰۰۰ تومان).
آیا نیازی به نوشتن این کد از صفر هست؟
برای اکثر فروشگاههای ساده، افزونههای رایگان موجود کافیان. این راهنما بیشتر برای زمانیه که نیاز به منطق سفارشی یا چند درگاه همزمان دارید.
چطور بفهمم پرداخت واقعاً انجام شده، نه فقط ادعای کاربر؟
فقط با فراخوانی موفق مرحلهی «تأیید تراکنش» (نه صرفاً بازگشت کاربر به سایت) میتونید مطمئن بشید پرداخت واقعاً ثبت شده.
اگه چند درگاه پرداخت همزمان لازم دارم چیکار کنم؟
تیم ما میتونه یک افزونهی اختصاصی با پشتیبانی از چند درگاه و منطق انتخاب سفارشی براتون پیادهسازی کنه.
جمعبندی
حالا جریان کامل درخواست، هدایت و تأیید پرداخت در زرینپال رو میشناسید و میدونید این جریان چطور به معماری ووکامرس وصل میشه. اگه برای پیادهسازی یک درگاه پرداخت اختصاصی یا یکپارچهسازی چند درگاه به کمک نیاز دارید، تیم ما آمادهی همراهیه.
نظرات کاربران
فقط نظرات تاییدشده مدیر نمایش داده میشود.