آموزش ساخت درگاه پرداخت در PHP با زرین پال – قسمت سوم

20 آبان 1397
php-payment-3

با سلام دوباره به تمام دوستان عزیز و علاقه مند به دنیای php. در این جلسه به ادامه فعالیتهایی که در جلسه قبلی پیرامون درگاه پرداخت زرین پال انجام دادیم، خواهیم پرداخت. انشاالله که فیلم های آموزشی و فایل راهنمای زرین پال را مطالعه کرده باشد، با فرض این امر، شما به راحتی مطالبی که در ادامه خواهم آورد را درک خواهید کرد. گر چه من هم با زبانی ساده و عملیاتی مطالب را بیان خواهم نمود.

لطفا چنانچه قسمت اول این آموزش را مطالعه نکرده اید از طریق زیر اطلاعات خود را تکمیل کرده و سپس به ادامه آموزش بپردازید:

پس از مطالعه لینک فوق به توضیحات مربوط به فایل request در مجموعه فایل های درگاه پرداخت زرین پال می پردازیم.

راه اندازی درگاه زرین پال در فروشگاه اینترنتی با PHP

در جلسه قبل فاکتور فروش را ایجاد نمودیم. اول از همه به باید به سراغ کتابچه راهنمای زرین پال برویم. به تصاویر زیر دقت نمایید.

باز کردن فایل کتابچه زرین پال

باز کردن فایل کتابچه زرین پال قسمت دوم

باز کردن فایل کتابچه زرین پال قسمت سوم

راهنما را به صورت کامل مطالعه بفرمایید. فقط وقتی که به نحوی دسترسی سامانه می رسید در آنجا قید شده است که آدرس WSDL (یا همان وب سرویس)  به صورت زیر است. تصویر از دفترچه راهنما را در زیر مشاهده می نمایید.

نحوی دسترسی به سامانه زرین پال

خب ما اکنون در localhost هستیم. زرین پال یک امکان جالب ارائه داده است در واقع امکان تست را برای ما فراهم کرده است. این سایت دو آدرس زیر را برای تست به ما داده که باید به جای آدرس هایی که در تصویر بالا مشاهده می نمایید از این آدرس ها استفاده کنیم.

https://sandbox.zarinpal.com/pg/services/WebGate/wsdl
https://sandbox.zarinpal.com/pg/StartPay/

پس دقت کنید اگر در این آموزش از این دو آدرس استفاده می کنم، شما در یک هاست واقعی (در واقع خارج از فضای localhost و در یک وب سرویس واقعی) از همان آدرس های کتابچه راهنما که در تصویری آن را نشان دادم استفاده نمایید.

دوستان عزیز، من قصد دارم وقتی کاربر محصولی را خریداری کرده بود و دکمه تسویه حساب را فشار داد و در سایت ثبت نام کرد، ابتدا یک رکورد به جدول داده ایی order اضافه شود و اطلاعات سفارش در آن ثبت گردد. سپس کاربر را به سمت بانک بفرستد؛ البته وقتی که کاربر را به بانک می فرستد همراه با آن درخواست، مقدار فیلد order_id رکوردی که ایجاد شده نیز ارسال گردد.

دقت کنید که جدول داده ایی order که ما قبلا ایجاد نمودیم خیلی مختصر می باشد، شما می توانید order کاملتر را ایجاد کنید.

در رکوردی که ابتدای کار (و قبل از ارسال درخواست کاربر به بانک ) ساخته می شود فیلد order_is_verified، را با مقدار false مقداردهی خواهیم کرد.

ضمنا همانطور که خدمت شما گفتم با درخواست اولیه باید order_id را حتما ارسال نماییم تا از بانک بخواهیم که موقع برگشت این order_id را بازگرداند، تا بدانیم که کدام کاربر را به بانک فرستاده ایم ( order_id همان شماره فاکتور است).

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

فایلهای زرین پال را از حالت فشرده خارج کنید

وقتی هر کدام از آنها را باز می کنیم در دل خود دو فایل به نام های request.php و verify.php را دارند.

بررسی فایل request.php در زرین پال

حالا اگر request.php را با استفاده از Notepad++ باز کنیم. ساختاری شبیه به زیر دارد.

<?php

    $MerchantID = 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX';  //Required
    $Amount = 1000; //Amount will be based on Toman  - Required
    $Description = 'توضیحات تراکنش تستی';  // Required
    $Email = 'UserEmail@Mail.Com'; // Optional
    $Mobile = '09123456789'; // Optional
    $CallbackURL = 'http://www.m0b.ir/verify.php';  // Required

    // URL also can be ir.zarinpal.com or de.zarinpal.com
    $client = new SoapClient('https://www.zarinpal.com/pg/services/WebGate/wsdl', ['encoding' => 'UTF-8']);

    $result = $client->PaymentRequest([
        'MerchantID'     => $MerchantID,
        'Amount'         => $Amount,
        'Description'    => $Description,
        'Email'          => $Email,
        'Mobile'         => $Mobile,
        'CallbackURL'    => $CallbackURL,
    ]);

    //Redirect to URL You can do it also by creating a form
    if ($result->Status == 100) {
        header('Location: https://www.zarinpal.com/pg/StartPay/'.$result->Authority);
    } else {
        echo'ERR: '.$result->Status;
    }

در فایل requset.php اصل ماجرا در خطهای زیر اتفاق می افتد.

    $client = new SoapClient('https://www.zarinpal.com/pg/services/WebGate/wsdl', ['encoding' => 'UTF-8']);

    $result = $client->PaymentRequest([
        'MerchantID'     => $MerchantID,
        'Amount'         => $Amount,
        'Description'    => $Description,
        'Email'          => $Email,
        'Mobile'         => $Mobile,
        'CallbackURL'    => $CallbackURL,
    ]);

وقتی کد به این خط برسد کاربر به بانک هدایت می شود به آدرس https://www.zarinpal.com/pg/services/WebGate/wsdl دقت نمایید. در اینجا بانک یک سری اطلاعات از ما می خواهد.

پارامتر اول MerchantID می باشد که قبلا در مورد آن برای شما توضیح داده ام (وقتی شما در زرین پال یا بانک ثبت نام می کنید و آدرس سایت خود را می دهید، زرین پال یا بانک رسمی برای شما یک MerchantID می سازد و به شما آن را می دهد). این MerchantID یک رشته 32 بیتی است که شما باید آن را در این قسمت قرار دهید (دقت کنید که ما در حالت localhost با یک MerchantID فرضی کار خواهیم کرد که فاقد مقدار خاصی است و در واقع آن را از ما نمی خواهند ).

پارامتر دوم این متد $Amount می باشد که مبلغ مورد نظر شما است. ( همان جمع کل مبلغی که باید مشتری آن را بپردازد).

پارامتر سوم ($Description) مربوط توضیحات است. اگر این پرداخت توضیحاتی دارد، در صفحه پرداخت زرین پال، توضیحات به کاربر نشان داده می شود.

پارامتر چهارم ($Email) یک ایمیل از شما می خواهد که جهت ارائه پشتیبانی های بعدی باید آن ارائه بدهید.

پارامتر پنجم ($Mobile) یک شماره موبایل است که از مشتری می توان دریافت کرد تا برای پیگیری های بعدی با او در ارتباط باشیم. ولی الزامی نیست.

پارامتر ششم ($CallbackUrl) می گوید که اگر کاربر کارش با بانک تمام شد، آن را به کجا بفرستم. شما باید آدرس یک صفحه از سایت خودتان را بدهید که وقتی کار کاربر در بانک تمام شد، کاربر را به این آدرس بفرستد که در واقع همان verify می باشد. شما باید در فایل verify.php کاربر را بگیرید و از دوباره به بانک اطلاع بدهید که کاربر را گرفتم، تا بانک مبلغ پرداخت را نهایی کند، در غیر اینصورت تا 24 ساعت بعد مبلغ به حساب کاربر بر می گردد. که در قسمت های بعدی به ایجاد این فایل می پردازیم.

ایجاد فایل request.php در میان فایل های ecommerce

در ادامه کاری که خواهیم کرد این است که فایلی تحت عنوان request.php در آدرس C:\wamp\www\ecommerce ایجاد می کنیم و پارامترها را با مقادیر درست پر می کنیم.

برای همین ابتدا به آدرس C:\wamp\www\ecommerce بروید و فایلی تحت عنوان request.php بسازید. به تصویر زیر نگاه کنید.

ایجاد فایل request در Ecommerce

دقت کنید قبل از اینکه به کدنویسی فایل request.php بپردازیم لازم است تغییراتی در فایل payment.php بدهیم.

همانطور که در قسمت قبل خدمت شما عرض کردم، وقتی که به فایل payment.php می رسیم؛ در جدول داده ایی order یک رکورد از مشتری ایجاد می شود . این رکورد یک فیلد order_id دارد که ما در ادامه با آن کارهای زیادی داریم. باید به شکلی این order_id و همچنین مبلغ کل خریدهای مشتری را به فایل request.php بیاوریم به همین خاطر به فایل payment.php بروید و آن را با Notepad++ باز کنیم. کدهای زیر را در آن بیابید.

$query = "INSERT INTO `order`(`order_total_price`, `order_is_verified`, `order_email_customer`) VALUES ($order_total_price,'false','$order_email')";
$run_order = mysqli_query($con, $query);

آنها را پاک کنید و کدهای زیر را به جای آنها قرار دهید.

		$query = "INSERT INTO `order`(`order_total_price`, `order_is_verified`, `order_email_customer`) VALUES ($order_total_price,'false','$order_email')";
	$run_order = mysqli_query($con, $query);
	
	//Last id based on customer email
	$query_sql="SELECT `order_id` FROM `order` WHERE `order_email_customer`='$order_email'";
	$run_myqurey = mysqli_query($con, $query_sql);
	$array_order_id=array();
	while($myqurey_array=mysqli_fetch_array($run_myqurey))
	{
		array_push($array_order_id,$myqurey_array['order_id']);
	}
	;
	$Last_id_based_customer_email=end($array_order_id);
	
	//Gaining last id
	$_SESSION["order_id"]=$Last_id_based_customer_email;
	
	// Set session variables
	$_SESSION["order_total_price"] = $order_total_price;	
	
	if($run_order){
		echo "<script>window.open('request.php','_self')</script>";
	}

در کدهای بالا با استفاده از متغییر های سراسری SESSION["order_total_price"] و SESSION["order_id"] می توانیم مبلغ کل خریدهای مشتری به همراه شماره فاکتور فروش (order_id) را به صفحه request.php ببریم از طرف دیگر می توانیم با استفاده از <script>window.open('request.php','_self') به صفحه request.php منتقل شویم.

حالا فایل request.php را با استفاده از Notepad++  باز می کنیم و کدهای زیر را در آن قرار می دهیم.

<?php
// We connect to the database	
include("includes/db.php");

//We start the session
session_start();

//Initialization to variables
$order_id_for_zarinpal=$_SESSION["order_id"];
$Amount=$_SESSION["order_total_price"]; //Amount will be based on Toman - Required
$MerchantID = 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'; //Required
$Description = " تست درگاه زرین پال توسط جهانگیر پچکم"; // Required
$Email = "jahangirpachkam@gmail.com"; // Optional
$Mobile = '09123456789'; // Optional
$CallbackURL = "آدرسی که از برنامه ngrok دریافت می کنید/ecommerce/verify.php?Amount=$Amount&order_id_for_verify=$order_id_for_zarinpal"; // Required

$client = new SoapClient('https://sandbox.zarinpal.com/pg/services/WebGate/wsdl', ['encoding' => 'UTF-8']);

$result = $client->PaymentRequest(
[
'MerchantID' => $MerchantID,
'Amount' => $Amount,
'Description' => $Description,
'Email' => $Email,
'Mobile' => $Mobile,
'CallbackURL' => $CallbackURL,
]
);

//Enter the Authority field value in the order table
$au=$result->Authority;	
$sql="UPDATE `order` SET `authority`='zarinpal_$au' WHERE `order_id`=$order_id_for_zarinpal";
mysqli_query($con,$sql);

//Redirect to URL You can do it also by creating a form
if ($result->Status == 100) {
Header('Location: https://sandbox.zarinpal.com/pg/StartPay/'.$result->Authority);
} else {
echo'ERR: '.$result->Status;
}?>

در کدهای بالا ابتدا با پایگاه داده ارتباط برقرار می کنیم. سپس با استفاده از تابع session_start()، مقدمات را برای استفاده از مقدار $_SESSION هایی که از فایل payment.php بدست می آید، فراهم می کنیم.

در ادامه همانطور که مشاهده می نمایید order_id را که از فایل payment.php با استفاده از متغییر $_SESSION آورده بودیم به عنوان مقدار به $order_id_for_zarinpal می دهیم و در ادامه آن را به همراه درخواست اولیه برای زرین پال ارسال می کنیم.

به طور مشابه مقدار $Amount را نیز با استفاده از متغییر $_SESSION که از فایل payment.php آورده شده است، مقدار دهی می کنیم.

$MerchantID باید با همین مقدار، مقداردهی شود چرا که در localhost قرار داریم (اما در هاست واقعی باید MerchantID را که زرین پال به ما داده در این جا قرار دهیم).

$Description و $Email و $Mobile را نیز با مقادیر دلخواه خودتان پر کنید.

در ادامه متغییر $CallbackURL را داریم که همان آدرس برگشت (پاسخ بانک) است. خیلی دقت کنید من در همین آدرس برگشت، order_id و مقدار پولی که مشتری باید بدهد را قرار داده ام. به کد زیر دقت نمایید.

$CallbackURL = "آدرسی که از برنامه ngrok دریافت می کنید/ecommerce/verify.php?Amount=$Amount&order_id_for_verify=$order_id_for_zarinpal"; // Required

من در فایل verify.php (که در قسمت بعدی آن را خواهم ساخت) با استفاده از $_GET هر دو مقدار را به دست می آورم.

فقط به این نکته دقت نمایید که متغییر های $Amount و $MerchantID و $Description و $CallbackURL الزاما باید مقدار دهی شوند (در غیر اینصورت زرین پال در پاسخ خطا برای شما ارسال می کند).

بعد از مقدار دهی به متغییر های مورد نیاز ؛ درخواست اولیه ساخته می شود و برای زرین پال فرستاده می شود.

بعد از اینکه اطلاعات به زرین پال فرستاده شدند، زرین پال یک Authority در اختیار ما قرار می دهد که یک مقدار منحصر به فرد unique هست.

از طرف دیگر هنگام برگشت به فایل verify.php، به ما Refid را نیز میدهد (Refid را برای پیگیری های بعدی از زرین پال نیاز داریم و در قسمت بعدی بهتر با آن آشنا می شوید).

ما باید این مقادیر را در دیتابیس خودمان و در جدول داده ایی order ذخیره نماییم . اما این دو فیلد را هنوز نساخته ایم بنابراین بهتر است به PhpMyAdmin بروید سپس بر روی order فشار دهیم و با توجه به تصاویر زیر، این دو فیلد را بسازید.

ابندا از گوشه سمت راست دسکتاب بر روی برنامه WAMP بروید و PhpMyAdmin را انتخاب کنید.

باز کردن phpMyAdmin

بعد از باز شدن PhpMyAdmin ، حالا باید به جدول داده ایی order بروید.

انتخاب جدول order

بعد از انجام کار بالا حالا دو فیلد authority و refid را با توجه به ویژگی هایی که زیر آنها خط قرمز کشیده ام بسازید.

افزودن دو فیلد authority و refid به phpMyAdmin

حالا که ابن دو فیلد را ساختیم به ادامه توضیحات کدها در پایین دقت نمایید.

بنابراین باید مقدار authority بازگشت داده شده را به جدول داده ایی اضافه کنیم. کدهای زیر این نکته را نشان می دهند.

$au=$result->Authority;	
$sql="UPDATE `order` SET `authority`='zarinpal_$au' WHERE `order_id`=$order_id_for_zarinpal";
mysqli_query($con,$sql);

در ادامه به کدهای زیر می رسیم.

//Redirect to URL You can do it also by creating a form
if ($result->Status == 100) {
Header('Location: https://sandbox.zarinpal.com/pg/StartPay/'.$result->Authority);
} else {
echo'ERR: '.$result->Status;
}?>

تعریف این کدها به صورت زیر است:

در صورتیکه  Status برگشت داده شده 100 باشد ما به درگاه پرداخت زرین پال متصل می شویم. یعنی بانک ما را تایید اولیه کرده و اتصال بین سایت و درگاه برقرار است.

الان هر درخواستی که انجام بدهیم یک رکورد با مقدار authority به جدول داده ایی دیتابیس اضافه می شود، دقت نمایید که refid در این مرحله فاقد مقدار است.

خب دوستان عزیزم به پایان این قسمت رسیدیم . در قسمت آینده در مورد فایل verify.php و اقداماتی که باید در آن انجام شود خواهیم پرداخت و در نهایت به صورت عملی یک خرید را تا درگاه پرداخت زرین پال به اجرا درخواهیم آورد.

قسمت آینده فوق العاده عملی و مهم است. آن را حتما مطالعه بفرمایید. ضمنا فایل نهایی، فایل هایی که در این مرحله با آنها کار کردیم و کدهای آنها را تغییر دادیم در پایین برای شما قرار داده ام. کدهای قبلی موجود در این فایل ها را پاک کنید و کدهای موجود در فایل های زیر را به جای آنها قرار دهید.

فایل های نهایی

فایل نهایی payment.php

<?php
	include('includes/db.php');
	
	//creating or using cookie for ip customer
	if(isset($_COOKIE["ipUserEcommerce"]))
	{
		$ip	= $_COOKIE["ipUserEcommerce"];
		}else{
		$ip=getIp();
		setcookie('ipUserEcommerce',$ip,time()+1206900);
	}
	
	//Gaining the amount to be paid by the customer
	$sel_ip	=	"select * from total where ip='$ip'";
	$run_ip	=	mysqli_query($con,$sel_ip);
	while($p_ip = mysqli_fetch_array($run_ip))
	{
		$order_total_price = $p_ip['price_total_purchase'];
	}
	
	//Gaining customer email
	$sel_email	=	"select * from customers where customer_ip='$ip'";
	$run_email	=	mysqli_query($con,$sel_email);
	while($p_email = mysqli_fetch_array($run_email))
	{
		$order_email = $p_email['customer_email'];
	}
	
	//Submit the record in the order table
	$query = "INSERT INTO `order`(`order_total_price`, `order_is_verified`, `order_email_customer`) VALUES ($order_total_price,'false','$order_email')";
	$run_order = mysqli_query($con, $query);
	
	//Last id based on customer email
	$query_sql="SELECT `order_id` FROM `order` WHERE `order_email_customer`='$order_email'";
	$run_myqurey = mysqli_query($con, $query_sql);
	$array_order_id=array();
	while($myqurey_array=mysqli_fetch_array($run_myqurey))
	{
		array_push($array_order_id,$myqurey_array['order_id']);
	}
	;
	$Last_id_based_customer_email=end($array_order_id);
	
	//Gaining last id
	$_SESSION["order_id"]=$Last_id_based_customer_email;
	
	// Set session variables
	$_SESSION["order_total_price"] = $order_total_price;	
	
	if($run_order){
		echo "<script>window.open('request.php','_self')</script>";
	} 
	
?>

فایل نهایی request.php

<?php
// We connect to the database	
include("includes/db.php");

//We start the session
session_start();

//Initialization to variables
$order_id_for_zarinpal=$_SESSION["order_id"];
$Amount=$_SESSION["order_total_price"]; //Amount will be based on Toman - Required
$MerchantID = 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'; //Required
$Description = " تست درگاه زرین پال توسط جهانگیر پچکم"; // Required
$Email = "jahangirpachkam@gmail.com"; // Optional
$Mobile = '09123456789'; // Optional
$CallbackURL = "آدرسی که از برنامه ngrok دریافت می کنید/ecommerce/verify.php?Amount=$Amount&order_id_for_verify=$order_id_for_zarinpal"; // Required

$client = new SoapClient('https://sandbox.zarinpal.com/pg/services/WebGate/wsdl', ['encoding' => 'UTF-8']);

$result = $client->PaymentRequest(
[
'MerchantID' => $MerchantID,
'Amount' => $Amount,
'Description' => $Description,
'Email' => $Email,
'Mobile' => $Mobile,
'CallbackURL' => $CallbackURL,
]
);

//Enter the Authority field value in the order table
$au=$result->Authority;	
$sql="UPDATE `order` SET `authority`='zarinpal_$au' WHERE `order_id`=$order_id_for_zarinpal";
mysqli_query($con,$sql);

//Redirect to URL You can do it also by creating a form
if ($result->Status == 100) {
Header('Location: https://sandbox.zarinpal.com/pg/StartPay/'.$result->Authority);
} else {
echo'ERR: '.$result->Status;
}?>

 

تمام فصل‌های سری ترتیبی که روکسو برای مطالعه‌ی دروس سری فروشگاه اینترنتی با PHP توصیه می‌کند:
نویسنده شوید

دیدگاه‌های شما (3 دیدگاه)

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

محمود رنجبر
24 مهر 1399
سلام مهندس جهانگیر عزیز اگه ویدیو قرار بدید خیلی بهتره سایت خوبی دارید تشکر از آموزشهاتون

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

جهانگیر پچکم
05 اردیبهشت 1399
سلام دوست عزیز لطفا می تونید دقیق بگین که اروری که میده چیه؟

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

محمد رضا
01 اردیبهشت 1399
سلام من تازه این دوره رو دارم دنبال می کنم من تا قسمت 34 رفتم فقط وقتی به فایل PAYMENT میره یک خطا میگیره و اجرا نمیشه همین خط رو خطلا میگیره while($myqurey_array=mysqli_fetch_array($run_myqurey)) { array_push($array_order_id,$myqurey_array['order_id']); }

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.