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

29 آبان 1397
php-zarinpal-part4

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

اگر یادتان باشد در قسمت قبل و در فایل request.php، ما در متغییر $CallbackURL یک آدرس برگشت تعیین نمودیم و به همراه این آدرس برگشت orderid و amount را نیز برای بانک ارسال کردیم. حالا فرض کنیم که از سمت بانک پاسخ تراکنش بازگشته است، حال ما با استفاده از متغییر سراسری $_GET باید این دو مقدار را از پاسخ بانک دریافت نماییم. تا بفهمیم که مشتری چه کسی بوده و با کدام فاکتور به بانک فرستاده شده است.

تایید اطلاعات ارسالی توسط بانک

دقت کنید، ابتدا فایل verify.php را در آدرس C:\wamp\www\ecommerce ایجاد نمایید. به تصویر زیر نگاه کنید.

ایجاد فایل verify

سپس فایل verify.php را با Notepad++ باز کنید و کدهای زیر را در آن قرار دهید.

<!-- start of Header -->
<?php	include('includes/Header.php');	?>
<!-- end of Header -->

<!-- start of content -->   
<div id="templatemo_content">

<?php
	
// We connect to the database	
include("includes/db.php");
	
    $order_id=	$_GET['order_id_for_verify'];
	if ($_GET['Status'] == 'OK') {
		$MerchantID = 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX';
		$Amount = $_GET['Amount']; //Amount will be based on Toman
		$Authority = $_GET['Authority'];
		
		$client = new SoapClient('https://sandbox.zarinpal.com/pg/services/WebGate/wsdl', ['encoding' => 'UTF-8']);
		
		$result = $client->PaymentVerification(
		[
		'MerchantID' => $MerchantID,
		'Authority' => $Authority,
		'Amount' => $Amount,
		]
		);
		
		if ($result->Status == 100) {
			
			echo "<p style='background:green; padding: 27px;	font-size: 20px; border-radius: 15px;border: 5px dashed white;'>از خرید شما متشکریم کد RefID برای پیگیری های بعدی شما :".$result->RefID."می باشد.</p>";
			$RefID=$result->RefID;
			mysqli_query($con,"UPDATE `order` SET `order_is_verified`='true', `refid`=$RefID WHERE `order_id`=$order_id ");			
			
			} else {
			
			echo "<p style='background:red; padding: 27px;	font-size: 20px; border-radius: 15px;border: 5px dashed white;'> تراکنش انجام نشد : 
		  :".$result->Status."</p>";
			
		}
		} else {
		echo "<p style='background:red; padding: 27px;	font-size: 20px; border-radius: 15px;border: 5px dashed white;'> تراکنش توسط کاربر انجام نشد </p>";
	}			
?>	
</div>
<!-- end of content -->

<!-- start of footer -->
<?php include('includes/Footer.php');	?>
<!-- end of footer -->

در ادامه به صورت خط به خط کدهای بالا را شرح می دهم.

همانطور که مشاهده می نمایید در ابتدا ما باید هدر سایت را فراخوانی نماییم؛ در این کدها چیز به ظاهر سختی دیده نمیشود. کدهای زیر را نگاه کنید.

<!-- start of Header -->
<?php	include('includes/Header.php');	?>
<!-- end of Header -->

<!-- start of content -->   
<div id="templatemo_content">

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

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

در اینجا ما اتصال به پایگاه داده را برقرار کرده ایم، چرا که در ادامه همانطور که در قسمت قبل خدمت شما عرض کردم، باید مقدار refid را از پاسخ بانک برداشت کنیم و در جدول داده ایی order ذخیره نماییم. در ضمن اگر تراکنش به درستی انجام شده بود باید مقدار فیلد order_is_verified را از false به true تغییر دهیم.

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

    $order_id=	$_GET['order_id_for_verify'];

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

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

	if ($_GET['Status'] == 'OK') {
		$MerchantID = 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX';
		$Amount = $_GET['Amount']; //Amount will be based on Toman
		$Authority = $_GET['Authority'];
		
		$client = new SoapClient('https://sandbox.zarinpal.com/pg/services/WebGate/wsdl', ['encoding' => 'UTF-8']);
		
		$result = $client->PaymentVerification(
		[
		'MerchantID' => $MerchantID,
		'Authority' => $Authority,
		'Amount' => $Amount,
		]
		);

حالا به این نکته دقت نمایید، زمانی که مشتری از بانک برمی گردد، یک سری پارامتر به صورت GET برای ما می آورد، که ما باید آنها را دریافت کنیم و بر اساس آنها متوجه شویم که آیا تراکنش موفقیت آمیز بوده است یا خیر؟

به دستور if در بالا دقت نمایید. اگر پارامترهای برگشتی را ملاحظه کنید؛ چک می شود اگر Status برابر ok بود (یعنی بانک به ما ok داده است و پرداخت انجام شده است.) حالا کارهایی که در بلوک if قرار داد را به نوبت انجام بده.

حالا در بلوک if چه می گذرد؟ در بلوک if ابتدا متغییر هایی که در پاسخ برگشتی از بانک قرار دارند با استفاده از متغییر سراسری $_GET برداشته می شوند (به $Amount و $Authority دقت نمایید. فقط به این نکته توجه کنید که در اینجا شما باید $MerchantID را خودتان داده باشید؛ چرا که در لینک برگشتی چیزی در مورد مقدار $MerchantID قرار داده نشده است.)

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

برای اینکه بتوانیم جواب بانک را بدهیم، دوباره باید همان اطلاعات را که در request.php برای بانک ارسال کرده بودیم؛ به بانک پس بدهیم. مثلا در فایل request.php ما اطلاعاتی مانند مبلغ و کد  MerchantID را داده بودیم، حالا در فایل verify.php باز باید همان اطلاعات را به بانک پس بدهیم تا پرداخت را نهایی کند.

دقت نمایید که من مبلغ (متغییر $Amount) را با استفاده از متغییر سراسری $_GET به دست آورده ام، بنابراین همان مقداری که داده بودم را از دوباره به بانک خواهم داد.

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

		if ($result->Status == 100) {
			
			echo "<p style='background:green; padding: 27px;	font-size: 20px; border-radius: 15px;border: 5px dashed white;'>از خرید شما متشکریم کد RefID برای پیگیری های بعدی شما :".$result->RefID."می باشد.</p>";
			$RefID=$result->RefID;
			mysqli_query($con,"UPDATE `order` SET `order_is_verified`='true', `refid`=$RefID WHERE `order_id`=$order_id ");			
			
			} else {
			
			echo "<p style='background:red; padding: 27px;	font-size: 20px; border-radius: 15px;border: 5px dashed white;'> تراکنش انجام نشد : 
		  :".$result->Status."</p>";
			
		}

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

جدول کدهای خطای زرین پال

با مطالعه این جدول متوجه خواهید شد که مقدار 100 یعنی اینکه "عملیات با موفقیت انجام شده است".

در کدهای بالا دستور if می گوید که اگر Status برابر با 100 بود حالا باید پیام مناسب به کاربر را نمایش دهیم و در طرف دیگر در پایگاه داده و در جدول order باید مقدار refid را قرار دهیم.

دقت کنید با استفاده از همین refid می توانیم پیگیری های بعدی را از زرین پال انجام دهیم. توجه نمایید که اگر دستور if اجرا نشد، آنگاه باید به کاربر پیام Status مناسب را نمایش دهید. شما می توانید Status مختلف را با عبارت ساده switch و case مدیریت کنید و پیام مناسب را هم در پایگاه داده خودتان و هم به عنوان پیام به کاربر نمایش دهید.

بررسی عملی کدهای نوشته شده

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

ابتدا wamp را روشن می کنیم.

ابتدا wamp را روشن می کنیم

حالا وارد محیط PhpMyAdmin می شویم.

حالا وارد محیط PhpMyAdmin می شویم.

دقت کنید اگر رکوردی در جدول داده های ecommerce وجود دارد باید آنها را حذف نماییم. منظور من در اینجا جداول داده ایی order و total ،cart ،customers می باشد.

دقت کنید اگر رکوردی در جدول داده های ecommerce وجود دارد باید آنها را حذف نماییم.

به عنوان مثال من برای پاک کردن رکوردهای جدول داده ایی cart ابتدا آن را انتخاب کردم و بعد تیک گزینه Check All را زدم و سپس بر روی Delete فشار دادم، تا تمامی رکوردهای موجود پاک شوند. شما به طور مشابه، همین کار را برای جداولی که در تصویر بالا مشخص نموده ام، انجام دهید .

مثلا رکوردهای موجود در جدول داده ایی cart را حذف نموده ایم.

حالا به سراغ برنامه ngrok بروید و آن را باز می کنیم.

حالا برنامه ngrok را روشن می کنیم.

فرمان مورد نظر برنامه ngrok را می نویسیم (ngrok http 80) و بر روی اینتر فشار می دهیم. با انجام اینکار برنامه ngrok برای localhost آدرس اینترنتی ایجاد می کند.

فرمان مورد نظر برنامه ngrok را می نویسیم و بر روی اینتر فشار می دهیم

حالا برنامه ngrok به ما آدرس های اینترنتی لازم را می دهد.

حالا برنامه ngrok به ما آدرس های اینترنتی لازم را می دهد.

حالا آدرس اینترنتی برنامه ngrok را، در فایل server.php و در متغییر $message قرار می دهیم. به تصویر زیر نگاه کنید.

حالا آدرس ngrok را در فایلserver قرار می دهیم.حالا از دوباره ولی این بار آدرس اینترنتی برنامه ngrok را در فایل request.php و در متغییر $CallbackURL قرار می دهیم. به تصویر زیر نگاه کنید.

قرار دادن آدرس ngork‌ در متغییر CallbackURL

سپس باید آدرس اینترنتی برنامه ngrok در مرورگر خود وارد نماییم و به فولدر ecommerce و فایل index.php برویم. به تصویر زیر نگاه کنید.

حالا به صفحه اول سایت خودمان می رویم

چند محصول را برای خریدن انتخاب می کنیم.

انتخاب محصولات برای خرید

حالا بر روی دکمه تایید خرید فشار می دهیم.

حالا بر روی دکمه تایید خرید فشار می دهیم

حالابه محیط PhpMyAdmin بروید اگر به جدول داده ایی cart نگاه کنید، محصولات ما اضافه شده است.

حالا به جدول داده ایی cart نگاه کنید که محصولات ما اضافه شده است

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

حالا بر روی دکمه تسویه حساب فشار می دهیم

حالا به محیط PhpMyAdmin باز می گردیم و این بار به جدول داده ایی total یک رکورد جدید اضافه می شود. همان جمع کل را مشاهده می نمایید.

حالا به جدول داده ایی total یک رکورد جدید اضافه می شود

در صفحه جدید باز شده بر روی لینک "جدیدی؟ خب از اینجا ثبت نام کن" فشار می دهیم.

حالا باید ثبت نام جدیدی را انجام دهیم

حالا اطلاعات درست را وارد نمایید و بر روی ایجاد نام کاربری فشار دهید.

حالا اطلاعات درست را وارد نمایید و بر روی ایجاد نام کاربری فشار دهید

بعد از زدن بر روی "ایجاد نام کاربری" یک پیام جدید را مشاهده می نمایید، بر روی ok کلیک می کنیم. بعد از آن باید به gmail که با آن ثبت نام کردید مراجعه کنید.

حالا بر روی ok کلیک می کنیم

حالا باز به محیط PhpMyAdmin می رویم و به جدول داده ایی customers نگاه می کنیم..

حالا به phpmyadmin می رویم و در جدول داده ایی customers را باز می کنیم

حالا به طور دقیق به فیلدهای مشخص شده نگاه کنید. دقت کنید قبل از اینکه مشتری ایمیل خودش را تایید کند فیلد confirmed مقدار صفر دارد و فیلد confirm_code یک عدد تصادفی به خودش می گیرد.

حالا به طور خاص به فیلدهای مشخص شده نگاه کنید

حالا به gmail خودمان مراجعه می کنیم و بر روی لینک داده شده کلیک می کنیم.

حالا به gmail خودمان مراجعه می کنیم و بر روی لینک داده شده کلیک می کنیم.

حالا باید پیام تایید ایمیل خود را ببینید و بر روی ok کلیک کنید. با انجام اینکار چند اتفاق رخ می دهد ابتدا فیلد confirm_code مقدار صفر را می گیرد و فیلد confirmed با مقدار 1 به روزرسانی می شود که نشان دهنده ی تایید و تکمیل شدن ثبت نام کاربر می باشد و از طرف دیگر یک رکورد جدید به جدول داده ایی order اضافه می شود؛ که در واقع یک فاکتور فروش صادر می شود.

حالا باید پیام تایید ایمیل خود را ببینید

حالا به درگاه زرین پال هدایت می شویم.

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

حالا به پایگاه داده بروید و بر روی جدول داده ایی customers بزنید و تغییرات را نگاه کنید.

حالا اگر به پایگاه داده برویم و بر روی جدول داده ایی customers بزنیم تغییرات را نگاه می کنیم

حالا اگر به جدول داده ایی order برویم نیز تغییرات را مشاهده خواهیم کرد.

حالا اگر به جدول داده ایی order برویم نیز تغییرات را مشاهده خواهیم کرد.

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

تصویر اول از رکورد اضافه شده به order

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

تصویر دوم از رکورد اضافه شده به order

حالا بر روی " پرداخت موفق " فشار دهید.

حالا بر روی پرداخت موفق فشار دهید

اگر تراکنش موفق باشد. به برگه زیر هدایت خواهید شد.

اگر تراکنش موفق باشد

حالا تغییرات را در جدول داده ایی order مشاهده نمایید.

حالا تغییرات را در جدول داده ایی order مشاهده نمایید.

حالا اگر بر روی "پرداخت ناموفق" فشار دهیم.

حالا اگر تراکنش نا موفق باشد

ما به برگه زیر هدایت می شویم.

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

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

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

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

sh
11 اسفند 1398
سلام من همون ادرس سایت زرین پال که شما نوشتید رو در کد هام نوشتم ولی وقتی میره صفحه request.php سایت زرین پال نمیاد و ارور میده مشکل چیه؟ با تشکر

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

جهانگیر پچکم
12 اسفند 1398
سلام عزیزم یک سوال دارم آیا مراحل تا قبل از رفتن به صفحه request.php به درستی انجام میشه؟ دقت کن که آدرس هایی که از برنامه ngrok داری به درستی سر جاشون قرار دادی (باید به درستی به جای آدرس های ngrok کدهای بالا قرار بدی)، این نکته فوق العاده مهم هست. ضمنا برای اینکه برنامه ngrok بهتر کار کنه از فیلتر شکن استفاده بشه بهتره.

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

علی پناهی
10 اردیبهشت 1398
سلام خسته نباشید میخاستم بدونم اگر ما بخاهیم به فرض مثال خریدار پس از پرداخت پول بتونه یک فایل رو دانلود کنه (در واقع ما یک فایل ویدویی رو بفروشیم) چجوری برنامه نویسی کنیم ؟

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

جهانگیر پچکم
11 اردیبهشت 1398
سلام به شما آقای علی پناهی عزیز دقت کنید اگر درس های قبلی (مخصوصا درس 30 ام یعنی "آموزش ارسال لینک فعال سازی به ایمیل در PHP – قسمت اول" و درس 31 ام یعنی "آموزش ارسال لینک فعال سازی به ایمیل در PHP – قسمت دوم" همچنین 4 قسمت مربوط به آموزش ساخت درگاه پرداخت در PHP با زرین پال) را با دقت مطالعه کنید، جواب سوال شما در این درسها نهفته است. برای اینکه بتونید یک محصول را به فروش برسانید کافی است یک عدد تصادفی رو قبل از پرداخت ایجاد کنید و این عدد رو با سایر اطلاعات فرد به سمت درگاه بفرستید. اگر پرداخت انجام شد، اون عدد تصادفی با سایر اطلاعات به سایت برگشت داده میشه، اگر هم پرداخت انجام نشد، صد در صد اون عدد هم برگشت داده نمیشه. خب فرض کنید که عدد برگشت داده شده باید چک کنید که آیا همون عددی هست که فرستادید یا خیر؟ اگر جواب مثبت بود فایل رو برای ایمیل کاربر ارسال کنید و پیام مناسب رو بهش بدید. انشاالله موفق باشید، جهانگیر پچکم

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

علی پناهی آزاد
18 اردیبهشت 1398
ممنونم از پاسختون راجع به ایمیل که گفتید دستور mail در php تمام پیامهارو به اسپم منتقل میکنه متاسفانه و اکثرا از کلاس phpmail استفاده میکنند منتهی من تنظیمات ارسالی این کلاس رو کمی متوجه نشدم اگه امکانش هست یک آموزش در خصوص ارسال ایمیل با این کلاس تهیه کنید در انتها تشکر کنم از دقت تهیه فایلهای اموزشیتون که خیلی جامع و ساده توضیح دادین واقعا با اموزشهای شما یک بار دیگ من به php علاقه مند شدم و دیدم اونقدرها هم که فکر میکردم پیچیده نیست.

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

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

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

جهانگیر پچکم
15 بهمن 1397
سلام به شما دوست عزیز ، ممنون از لطف شما خدمت شما باید عرض کنم که در واقع این عملیات سمت بانک صورت می گیرد و تا حد قابل ملاحظه ایی غیرقابل نفوذ هست در ضمن من یک سوال داشتم، آیا مقدار Authority به سادگی قابل دسترسی هست؟ و هکر چطور میتونه به اون دسترسی پیدا کنه؟ دسترسی پیدا کردن به این مقدار فوق العاده سخت هست، اگر هم به فرض اونو به دست بیاره مقدار refid رو نمی تونه بدست بیاره. اگر هم می خواهید بسیار محکم کاری کنید می تونید یک عدد تصادفی رو در صفحه request ایجاد کنید و اون رو با استفاده از متغییر سراسری $_POST به صفحه ی verify بفرستید (دقت کنید می تونید همه اطلاعات رو به جای استفاده از متغییر سراسری $_GET با متغییر سراسری $_POST ارسال کنید). با تشکر از شما، جهانگیر پچکم

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

علی سرلک
13 بهمن 1397
سلام و خسته نباشید خدمت آقای پچکم ممنون از آموزش بسیار خوب و روانتون سوالی که بنده داشتم این بود که وقتی مشتری به درگاه میره و برمیگرده مقداری رو می تونم باهاش برگردونم که مطمعن بشم مشتری واقعا پرداخت رو انجام داده ؟ در اصل بخوام واضح بگم نقطه ابهام بنده در اینجاست که مثلا کسی که قراره نفوذ بکنه در این قسمت به فایل verify.php من مقادیر Authority و Status رو خودش جعلی بفرسته و تایید پرداخت جعلی درست کنه ، این راه حلی وجود داره یا بنده کلا در اشتباه هستم

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