PDA

View Full Version : اتصال به وبسرویس بانک سامان



rezaonline.net
چهارشنبه 16 اردیبهشت 1394, 02:04 صبح
وبسرویس بانک سامان یکی از ساده ترین وبسرویس هاست و به راحتی هر برنامه نویس آماتوری میتواند نحوه اتصال به این سیستم را پیاده سازی کند
حتی دیده شده بسیاری از سایتهای درگاه واسط با الگو گیری از این روش اقدام به ارائه وبسرویس به مشتری هاشون شده اند .
این وبسرویس ساده بانک سامان متاسفانه مشکلات زیادی به همراه دارد و امکان سواستفاده فراوانی میدهد
اما اگر همه چیز اصولی باشد ، جز یک پرداخت موفق و مطمئن ، شاهد هیچ کاری نخواهیم بود !


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

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



id,amount,ip,time,status,user_id,ref_num

(ref_num رسید دیجیتال یا کد پیگیری تراکنش هست که در برگشت ذخیره میشود)
(status در هنگام پرداخت عدد 0 میگیرد و در صورتیکه پرداخت موفقیت آمیز بود به 1 تغییر داده میشود)
(user_id شناسه کاربر جاری سیستم ، شاید لازم شد )

که باید با مقادیر موجود ثبت گردد و شناسه id رکورد مورد نظر استخراج گردد فرض میکنیم رکورد شماره 1 ثبت میشود .
از این پس به عدد 1 شماره فاکتور یا order_id میگوییم .

خب مرحله ارسال مشتری به درگاه برای پرداخت بسیار بسیار ساده و مبتدیانه هست .
فرض بگیریم شماره مشتری یا MerchantID ما 123456 هست
مبلغ پرداختی 1000 ریال
شماره فاکتور عدد 1
و آدرس بازگشت به فروشگاه
http://example.ir/callback.php

حال باید یک فرم html ساده را بصورت زیر تولید کنیم .



<form action='https://sep.shaparak.ir/Payment.aspx' method='POST'>
<input type='hidden' id='Amount' name='Amount' value='1000'> <!-- مبلغ -->
<input type='hidden' id='MID' name='MID' value='23456'> <!-- شماره مشتری بانک سامان -->
<input type='hidden' id='ResNum' name='ResNum' value='1'> <!-- شماره فاکتور -->
<input type='hidden' id='RedirectURL' name='RedirectURL' value='http://example.ir/callback.php'> <!-- آدرس بازگشت -->
<input type=submit value='pay'>
</form>



خب با مشاهده این فرم ، مشتری برروی دکمه pay کلیک میکند و به صفحه پرداخت اینترنتی بانک ارجاع داده میشود جهت پرداخت مبلغ و در نهایت به آدرس کال بک برگشت داده میشود

خب بعد از پرداخت مشتری به آدرس http://example.ir/callback.php می آید ما در این فایل callback.php باید چند تا کار انجام بدهیم .
اول اینکه چک کنیم مقادیر POST شده از سمت بانک موجود باشند .



if( ! isset($_POST['State']) or $_POST['State']!='OK')
{
echo "پرداخت ناموفق";
die;
}


پارامتر دیگر پارامتر $_POST['ResNum'] میباشد که مقدار order_id ارسالی در فرم قبل هست . با استفاده از این باید رکورد مورد نظر در دیتابیس را استخراج کنیم
و آی پی پرداخت کننده را مطابقت دهیم همچنین بررسی کنیم تراکنش قبلا انجام گرفته یا خیر



$order_id = (int) $_POST['ResNum'];

$data = $db->query("SELECT * FROM tbl WHERE id={$order_id}")->row();
if(empty($data))
{
echo "چنین تراکنشی موجود نیست";
die;
}

if($data->ip != $_SERVER['REMOTE_ADDR'])
{
echo "آی پی پرداخت کننده مطابقت ندارد";
die;
}


if($data->status=='1')
{
echo "تراکنش قبلا وریفای شده است !";
die;
}

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



if( ! isset($_POST['RefNum']))
{
echo "رسید دیجیتال ست نشده است";
die;
}
$ref_num = $_POST['RefNum'];
$check = $db->query("SELECT id FROM tbl WHERE ref_num=?")->row(array($ref_num));
if( ! empty($check))
{
echo "رسید دیجیتال قبلا ثبت شده است ";
die;
}

این داده ها از سمت بانک برگشت داده میشوند اما دقت داشته باشید هر شخصی میتواند این پارامترها را به کال بک شما ارسال کند
همانطور که دقت کرده اید در هنگام ارسال کاربر به درگاه چون فرم ساده html هست ، مستقیما آدرس کال بک و شماره فاکتور و شماره مشتری را در اختیار کاربر قرار میدهیم به سادگی میتوان از این اطلاعات سو استفاده کرد ، باید هشیار بود همچنین مواظب sql injection باشید .

خب بعد از بررسی این موارد باید به وبسرویس بانک وصل شد جهت وریفای تراکنش
در این مرحله باید رسید دیجیتال و شماره مشتری را به متد VerifyTransaction ارسال کنیم و نتیجه را بررسی کنیم
نتیجه این متد اگر عدد مثبتی بود باید دقیقا برابر مبلغ پرداختی باشد در غیر اینصورت کاربر در هنگام رفت در فرم html تغییرات داده و مبلغ را دستکاری کرده است که بهتر هست مبلغ را برگشت بزنیم به حسابش (یا نزنید ، بذارید تنبیه بشه :دی ) اگر نتیجه عدد منفی بود نشانه خطا هست که معمولا به دلیل مغایرت آی پی اعلامی شما به بانک سامان با آی پی ثبت شده است .



try
{
$soapclient = new nusoap_client('https://sep.shaparak.ir/payments/referencepayment.asmx?WSDL','wsdl');
$soapProxy = $soapclient->getProxy() ;

$mid = 123456; // شماره مشتری بانک سامان
$pass = 11111; // پسورد بانک سامان
$result = $soapProxy->VerifyTransaction($ref_num,$mid);

}
catch(Exception $e)
{
echo "خطا در اتصال به وبسرویس ";
die;
}

if($result != ($data->amount))
{
// مغایرت مبلغ پرداختی

if($result<0)
{
echo "کد خطای بانک سامان $result ";
die;
}

// مغایرت و برگشت دادن وجه به حساب مشتری
if($result>0)
{
echo "شما باید مبلغ {$data->amount} ریال را پرداخت میکردید در صورتیکه مبلغ {$result}ریال را پرداخت کردید ! مبلغ شما به حسابتان برگشت داده شد آخرین بارتان باشد !!!";
$soapProxy->ReverseTransaction($ref_num,$mid,$pass,$result);
}
}

if($result == ($data->amount))
{
// تراکنش موفق و ثبت شماره رسید دیجیتال

$aff = $db->query("UPDATE tbl SET ref_num=?,status=1 WHERE id=$order_id")->execute(array($ref_num));
if( ! $aff)
die('خطا در ثبت اطلاعات');

echo "تراکنش با موفقیت انجام شد ، رسید دیجیتال $ref_num و شماره فاکتور $order_id";

}


و اما چند نکته فنی !!

1. در فرآیند پرداخت اینترنتی بانک سامان ، برخلاف بانک ملت و ملی ، فقط در برگشت نیاز هست به وبسرویس متصل شد و در رفت نیازی نیست لذا این کار را ساده میکند اما اطلاعات را دو دستی تقدیم هر شخصی میکند ، پس برروی آی پی شخص پرداخت کننده حساس باشید !!

2. ترجیحال یک پارامتر عدد رندم به آدرس کال بک اضافه کنید و در سشن کاربر ذخیره کنید تا در برگشت چک کنید این برای یکتایی تولید آدرس کال بک خیلی مناسب است .

3. در هنگام برگشت حتما مبلغ تراکنش را بررسی کنید در سال های اخیر خیلی ها این اشتباه را کرده اند .

4. در هنگام برگشت حتما چک کنید ابتدا رسید دیجیتال قبلا استفاده شده است یا خیر ، به جرات میتوان گفت 99 درصد فروشگاهای فعلی
این مساله را رعایت نکرده اند و آسیب پذیر هستند !!! (اینو از من نشنیده بگیرید :دی )

5. ترجیحا آی پی اشخاصی که در برگشت دچار خطا میشوند را ذخیره کنید ، لازم میشود .

6. و توصیه آخر حتما از دیتابیس جهت ذخیره سازی اطلاعات استفاده کنید

سوالی بود در خدمتم .
ارادتمند شما ، رضا شیخله (http://www.rezaonline.net/blog/sep-payment-gateway.html)

لینک منبع : http://www.rezaonline.net/blog/sep-payment-gateway.html

under22
شنبه 19 اردیبهشت 1394, 16:00 عصر
چرا برای verify از soap خود php استفاده نکردید و از Nusoap استفاده کردید وقتی خود php داره

MMSHFE
یک شنبه 20 اردیبهشت 1394, 09:06 صبح
چون توی همه هاستها فعال نیست.