آموزش راه اندازی درگاه بانک ملت
بسم الله الرحمن الرحیم
بخش سوم
برنامه نویسی درگاه پرداخت آنلاین
بخش اول (اتصال سایت به درگاه بانک)
بخش دوم (برنامه نویسی درگاه پرداخت آنلاین)
بخش سوم (آموزش راه اندازی درگاه بانک ملت)
بخش چهارم (برنامه نویسی درگاه بانک)
در بخش قبل متد bpPayRequest را پیاده سازی کردیم و همچنین مقادیر بازگشتی این متد را نیز بررسی کردیم. در این بخش این متد را در پروژه Site خود فراخوانی خواهیم کرد.
برای انجام این کار می بایست بر روی پوشه Controller در پروژه Site راست کلیک کنیم و سپس در پنجره باز شده گزینه Empty Controller را انتخاب کنید:
نام Controller خود را PaymentController قرار دهید.
در کنترلر مربوطه یک Action به صورت زیر اضافه کنید.
public ActionResult Index()
{
long orderID = 0; //شماره تراکنش که باید منحصر به فرد باشد
long priceAmount = 20000; // هزینه ایی که کاربر در صفحه پرداخت باید آن را بپردازد
string additionalText = "خرید یک محصول "; // توضیحات شما برای این تراکنش
BankMellatImplement bankMellatImplement = new BankMellatImplement();
string resultRequest = bankMellatImplement.bpPayRequest(orderID, priceAmount, additionalText);
string[] StatusSendRequest = resultRequest.Split(',');
return View();
}
همانطور که مشاهده می کنید ما متد bpPayRequest را در Action این کنترلر فراخوانی کرده ایم. برای اینکه به کلاس های پروژه BankMellatLibrary دسترسی داشته باشید. باید در پروژه Site بر روی گزینه Refrence کلیک راست کنید و سپس گزینه Add Refrence را انتخاب کنید.
سپس در پنجره باز شده از قسمت سمت چپ گزینه Projects را انتخاب کنید، درنهایت از سمت راست بر روی گزینه BankMellatLibrary کلیک کنید و سپس Ok کنید.
حال می توانید از کدهای درون پروژه BankMellatLibrary در پروژه Site استفاده کنید.
همانطور که مشاهده می کنید متد bpPayReques یک مقدار string به عنوان نتیجه به ما باز می گرداند. این مقدار بازگشتی به صورت زیر خواهد بود:
0 ,AF82041a2Bf6989c7fF9
همانطور که قبلا نیز گفتم عدد اول ، مشخص کننده اتفاقی است که برای تراکنش شما افتاده است و عدد دوم، عدد (RefID (Refrence ID یا شماره پیگیری تراکنش شما است.
برای اینکه مشخص کنیم آیا تراکنش ما تا این مرحله موفق بوده و یا خیر، می بایست این string به یک آرایه دو بعدی تقسیم کنیم. این کار را با استفاده از کد زیر انجام داده ایم.
string[] StatusSendRequest = resultRequest.Split(',');
حال مقدار خانه اول این آرایه را بررسی می کنیم، در صورتی که مقدار خانه اول این آریه برابر صفر در نتیجه می بایست کاربر را به صفحه پرداخت هدایت کنیم. در غیر این صورت خطایی ایجاد شده است.
طبیعتا این خطا مربوط به ما می باشد زیرا تا این مرحله کاربر هیچ دخالتی نداشته است، مثلا ممکن است نام کاربری و کلمه عبور را اشتباه نوشته باشیم و...
در نهایت در این بخش از کد دو حالت رخ خواهد داد، یا مقدار بازگشتی متد bpPayRequest برابر صفر خواهد بود و یا غیر از صفر، در صورتی که این مقدار صفر باشد ما باید اطلاعات را برای درگاه پرداخت بانک ملت به صورت POST ارسال کنیم، اما در صورتی که این مقدار صفر نباشد، یعنی خطایی رخ داده است پس باید خطای ایجاد شده را به کاربر نمایش دهیم.
متد زیر را به کلاس BankMellatImplement اضافه کنید:
public String DesribtionStatusCode(int statusCode)
{
switch (statusCode)
{
case 0:
return MellatBankReturnCode.ﺗﺮاﻛﻨﺶ_ﺑﺎ_ﻣﻮﻓﻘﻴﺖ_اﻧﺠﺎم_ﺷﺪ.ToString();
case 11:
return MellatBankReturnCode.ﺷﻤﺎره_ﻛﺎرت_ﻧﺎﻣﻌﺘﺒﺮ_اﺳﺖ.ToString();
case 12:
return MellatBankReturnCode.ﻣﻮﺟﻮدی_ﻛﺎﻓﻲ_ﻧﻴﺴﺖ.ToString();
case 13:
return MellatBankReturnCode.رﻣﺰ_ﻧﺎدرﺳﺖ_اﺳﺖ.ToString();
case 14:
return MellatBankReturnCode.ﺗﻌﺪاد_دﻓﻌﺎت_وارد_ﻛﺮدن_رﻣﺰ_ﺑﻴﺶ_از_ﺣﺪ_ﻣﺠﺎز_اﺳﺖ.ToString();
case 15:
return MellatBankReturnCode.ﻛﺎرت_ﻧﺎﻣﻌﺘﺒﺮ_اﺳﺖ.ToString();
case 16:
return MellatBankReturnCode.دﻓﻌﺎت_ﺑﺮداﺷﺖ_وﺟﻪ_ﺑﻴﺶ_از_ﺣﺪ_ﻣﺠﺎز_اﺳﺖ.ToString();
case 17:
return MellatBankReturnCode.ﻛﺎرﺑﺮ_از_اﻧﺠﺎم_ﺗﺮاﻛﻨﺶ_ﻣﻨﺼﺮف_ﺷﺪه_اﺳﺖ.ToString();
case 18:
return MellatBankReturnCode.ﺗﺎرﻳﺦ_اﻧﻘﻀﺎی_ﻛﺎرت_ﮔﺬﺷﺘﻪ_اﺳﺖ.ToString();
case 19:
return MellatBankReturnCode.ﻣﺒﻠﻎ_ﺑﺮداﺷﺖ_وﺟﻪ_ﺑﻴﺶ_از_ﺣﺪ_ﻣﺠﺎز_اﺳﺖ.ToString();
case 111:
return MellatBankReturnCode.ﺻﺎدر_ﻛﻨﻨﺪه_ﻛﺎرت_ﻧﺎﻣﻌﺘﺒﺮ_اﺳﺖ.ToString();
case 112:
return MellatBankReturnCode.ﺧﻄﺎی_ﺳﻮﻳﻴﭻ_ﺻﺎدر_ﻛﻨﻨﺪه_ﻛﺎرت.ToString();
case 113:
return MellatBankReturnCode.ﭘﺎﺳﺨﻲ_از_ﺻﺎدر_ﻛﻨﻨﺪه_ﻛﺎرت_درﻳﺎﻓﺖ_ﻧﺸﺪ.ToString();
case 114:
return MellatBankReturnCode.دارﻧﺪه_ﻛﺎرت_ﻣﺠﺎز_ﺑﻪ_اﻧﺠﺎم_اﻳﻦ_ﺗﺮاﻛﻨﺶ_ﻧﻴﺴﺖ.ToString();
case 21:
return MellatBankReturnCode.ﭘﺬﻳﺮﻧﺪه_ﻧﺎﻣﻌﺘﺒﺮ_اﺳﺖ.ToString();
case 23:
return MellatBankReturnCode.ﺧﻄﺎی_اﻣﻨﻴﺘﻲ_رخ_داده_اﺳﺖ.ToString();
case 24:
return MellatBankReturnCode.اﻃﻼﻋﺎت_ﻛﺎرﺑﺮی_ﭘﺬﻳﺮﻧﺪه_ﻧﺎﻣﻌﺘﺒﺮ_اﺳﺖ.ToString();
case 25:
return MellatBankReturnCode.ﻣﺒﻠﻎ_ﻧﺎﻣﻌﺘﺒﺮ_اﺳﺖ.ToString();
case 31:
return MellatBankReturnCode.ﭘﺎﺳﺦ_ﻧﺎﻣﻌﺘﺒﺮ_اﺳﺖ.ToString();
case 32:
return MellatBankReturnCode.ﻓﺮﻣﺖ_اﻃﻼﻋﺎت_وارد_ﺷﺪه_ﺻﺤﻴﺢ_ﻧﻤﻲ_ﺑﺎﺷﺪ.ToString();
case 33:
return MellatBankReturnCode.ﺣﺴﺎب_ﻧﺎﻣﻌﺘﺒﺮ_اﺳﺖ.ToString();
case 34:
return MellatBankReturnCode.ﺧﻄﺎی_ﺳﻴﺴﺘﻤﻲ.ToString();
case 35:
return MellatBankReturnCode.ﺗﺎرﻳﺦ_ﻧﺎﻣﻌﺘﺒﺮ_اﺳﺖ.ToString();
case 41:
return MellatBankReturnCode.ﺷﻤﺎره_درﺧﻮاﺳﺖ_ﺗﻜﺮاری_اﺳﺖ.ToString();
case 42:
return MellatBankReturnCode.ﺗﺮاﻛﻨﺶ_Sale_یافت_نشد_.ToString();
case 43:
return MellatBankReturnCode.ﻗﺒﻼ_Verify_درﺧﻮاﺳﺖ_داده_ﺷﺪه_اﺳﺖ.ToString();
case 44:
return MellatBankReturnCode.درخواست_verify_یافت_نشد.ToString();
case 45:
return MellatBankReturnCode.ﺗﺮاﻛﻨﺶ_Settle_ﺷﺪه_اﺳﺖ.ToString();
case 46:
return MellatBankReturnCode.ﺗﺮاﻛﻨﺶ_Settle_نشده_اﺳﺖ.ToString();
case 47:
return MellatBankReturnCode.ﺗﺮاﻛﻨﺶ_Settle_یافت_نشد.ToString();
case 48:
return MellatBankReturnCode.تراکنش_Reverse_شده_است.ToString();
case 49:
return MellatBankReturnCode.تراکنش_Refund_یافت_نشد.ToString();
case 412:
return MellatBankReturnCode.شناسه_قبض_نادرست_است.ToString();
case 413:
return MellatBankReturnCode.ﺷﻨﺎﺳﻪ_ﭘﺮداﺧﺖ_ﻧﺎدرﺳﺖ_اﺳﺖ.ToString();
case 414:
return MellatBankReturnCode.سازﻣﺎن_ﺻﺎدر_ﻛﻨﻨﺪه_ﻗﺒﺾ_ﻧﺎﻣﻌﺘﺒﺮ_اﺳﺖ.ToString();
case 415:
return MellatBankReturnCode.زﻣﺎن_ﺟﻠﺴﻪ_ﻛﺎری_ﺑﻪ_ﭘﺎﻳﺎن_رسیده_است.ToString();
case 416:
return MellatBankReturnCode.ﺧﻄﺎ_در_ﺛﺒﺖ_اﻃﻼﻋﺎت.ToString();
case 417:
return MellatBankReturnCode.ﺷﻨﺎﺳﻪ_ﭘﺮداﺧﺖ_ﻛﻨﻨﺪه_ﻧﺎﻣﻌﺘﺒﺮ_اﺳﺖ.ToString();
case 418:
return MellatBankReturnCode.اﺷﻜﺎل_در_ﺗﻌﺮﻳﻒ_اﻃﻼﻋﺎت_ﻣﺸﺘﺮی.ToString();
case 419:
return MellatBankReturnCode.ﺗﻌﺪاد_دﻓﻌﺎت_ورود_اﻃﻼﻋﺎت_از_ﺣﺪ_ﻣﺠﺎز_ﮔﺬﺷﺘﻪ_اﺳﺖ.ToString();
case 421:
return MellatBankReturnCode.IP_نامعتبر_است.ToString();
case 51:
return MellatBankReturnCode.ﺗﺮاﻛﻨﺶ_ﺗﻜﺮاری_اﺳﺖ.ToString();
case 54:
return MellatBankReturnCode.ﺗﺮاﻛﻨﺶ_ﻣﺮﺟﻊ_ﻣﻮﺟﻮد_ﻧﻴﺴﺖ.ToString();
case 55:
return MellatBankReturnCode.ﺗﺮاﻛﻨﺶ_ﻧﺎﻣﻌﺘﺒﺮ_اﺳﺖ.ToString();
case 61:
return MellatBankReturnCode.ﺧﻄﺎ_در_واریز.ToString();
}
return "";
}
این متد شماره خطا را دریافت می کند و متن خطا را بر اساس جدول بانک ملت بر می گرداند.
حال برای هدایت کاربر به صفحه پرداخت و یا نمایش خطا باید چند خط کد زیر را به Action خود (Index) اضافه کنیم.
if (int.Parse(StatusSendRequest[0]) == (int)BankMellatImplement.MellatBankReturnCode.ﺗﺮاﻛﻨﺶ_ﺑﺎ_ﻣﻮﻓﻘﻴﺖ_اﻧﺠﺎم_ﺷﺪ)
{
return RedirectToAction("RedirectVPOS", "Payment", new { id = StatusSendRequest[1] });
}
TempData["Message"] = bankMellatImplement.DesribtionStatusCode(int.Parse(StatusSendRequest[0].Replace("_", " ")));
return RedirectToAction("ShowError","Payment");
در کد بالا اگر تراکنش با موفقیت انجام شده باشد کاربر را به Action ایی با نام RedirectVPOS می فرستیم و اگر خطایی رخ داده باشد متن خطا را در ["TempData["Message ذخیره می کنیم و سپس کاربر را به Action ایی با نام ShowError هدایت می کنیم.
کد Action نمایش خطا (ShowError) به صورت زیر خواهد بود:
public ActionResult ShowError()
{
return View();
}
حال برای این Action باید یک View ایجاد کنیم و سپس کد زیر را در آن قرار دهیم.
میان کدهای Action مربوط به ShowError کلیک راست کنید و گزینه Add View را انتخاب کنید، در پنجره باز شده تنظیمات پیش فرض را تایید و بر روی گزینه Ok کلیک کنید.
<h2>ShowError</h2>
@{
if (TempData.Peek("Message") != null)
{
<p>@TempData.Peek("Message")</p>
}
}
در نظر می گیریم که مقدار خانه اول آرایه برابر صفر است، برای هدایت کاربر به صفحه پرداخت بانک ملت می بایست ابتدا اطلاعات لازم را برای وب سرویس بانک ملت به صورت POST ارسال کنیم.
برای این کار درون Controller جاری (Payment)، یک Action با نام RedirectVPOS ایجاد می کنیم و کد زیر را در آن قرار می دهیم.
public ActionResult RedirectVPOS(string id)
{
try
{
if (id == null)
{
TempData["Message"] = "هیچ شماره پیگیری برای پرداخت از سمت بانک ارسال نشده است!";
return RedirectToAction("ShowError", "Payment");
}
else
{
ViewBag.id = id;
return View();
}
}
catch (Exception error)
{
TempData["Message"] = error + "متاسفانه خطایی رخ داده است، لطفا مجددا عملیات خود را انجام دهید در صورت تکرار این مشکل را به بخش پشتیبانی اطلاع دهید";
return RedirectToAction("ShowError", "Payment");
}
}
در کد بالا همه چیز بسیار ساده و مشخص می باشد ما ID را که از طریق کد Action Index ارسال کرده ایم؛ در اینجا درون ViewBag ذخیره می کنیم و سپس View مربوط به RedirectVPOS را به کاربر نمایش می دهیم. سایر کدهای این Action فقط برای جلوگیری از خطاهای رایج می باشد.
میان کدهای Action مربوط به RedirectVPOS کلیک راست کنید و گزینه Add View را انتخاب کنید، در پنجره باز شده تنظیمات پیش فرض را تایید و بر روی گزینه Ok کلیک کنید.
حال کدهای زیر به View ایجاد شده (RedirectVPOS) اضافه کنید
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>پرداخت آنلاین</title>
<style>
body {
background-image: url("../../Content/images/BankMellat/bg.jpg");
}
.ContentWrapper {
margin: 70px auto;
width: 652px;
background-color: white;
border: 1px solid black;
text-align: center;
padding-bottom: 30px;
}
.header {
height: 130px;
background-image: url("../../Content/images/BankMellat/Header.jpg");
width: 100%;
}
.TextDescription {
font-family: Tahoma;
font-size: small;
padding-top: 80px;
padding-bottom: 30px;
}
input {
cursor: pointer;
font-family: Tahoma;
font-size: small;
}
</style>
</head>
<body>
<div class="ContentWrapper">
<div class="header">
</div>
<form method="post" name="formBank" id="formBank" action='@BankMellatLibrary.BankMellatImplement.PgwSite'>
<input type="hidden" value='@ViewBag.id' id="RefId" name="RefId">
<div class="TextDescription">
در صورتی که اطلاعات ثبت شده را مورد تایید است جهت تکمیل فرایند خرید بر روی گزینه
پرداخت کلیک نمایید
</div>
<input type="submit" value="پرداخت" />
</form>
</div>
</body>
</html>
دو خط در کدهای بالا بسیار مهم می باشد :
<form method="post" name="formBank" id="formBank" action='@BankMellatLibrary.BankMellatImplement.PgwSite'>
در کد بالا نحوه ارسال اطلاعات باید به صورت POST باشد به همین دلیل "method="post است، همچنین action این فرم باید آدرس صفحه پرداخت بانک ملت بر روی سرور شاپرک باشد، اگر خاطرتان باشد این آدرس را در کلاس BankMellatImplement به صورت زیر ذخیره کردیم:
public static readonly string PgwSite = "https://bpm.shaparak.ir/pgwchannel/startpay.mellat";
پس در اینجا کافی است تنها این آدرس را فراخوانی کنیم.
کد دومی که اهمیت دارد، خط زیر می باشد، اگر کد Action RedirectVPOS را بررسی کنید، مشاهده خواهید کرد که ما ID تراکنش را درون ViewBag ذخیره کردیم، در اینجا ما این ID را به کنترل خود انتساب داده ایم. نام و ID این کنترل باید حتما RefId باشد.
<input type="hidden" value='@ViewBag.id' id="RefId" name="RefId">
در صورتی که کاربر بر روی Button "پرداخت" کلیک کند، به صفحه پرداخت بانک هدایت می شود شماره تراکنشی که درون ViewBag بود توسط کنترل input به بانک ملت ارسال می شود.
حال کاربر می بایست اطلاعات لازم را تکمیل کند، پس از تکمیل اطلاعات و انجام تراکنش، بانک ملت کاربر را مجددا به سایت شما بر می گرداند اولین صفحه ای که کاربر پس از صفحه بانک مشاهده خواهد کرد، همان آدرسی است که با نام callBackUrl در متد bpPayRequest مشخص کردیم.
آدرس callBackUrl ما به صورت زیر بود:
static readonly string callBackUrl = "http://www.Ably.ir/Payment/BankCallback";
پس باید در کنترلر Payment خود یک Action با نام BankCallback به صورت ژیر ایجاد کنیم:
[HttpPost]
public ActionResult BankCallback()
{
return View();
}
در این Action باید اطلاعات ارسالی بانک ملت را بررسی کنیم تا بدانیم که کاربر در صفحه پرداخت چه فعالیتی انجام داده است (بر روی انصراف کلیک کرده و یا گزینه پرداخت را انتخاب کرده) ممکن است هر یک از حالت های جدول وضعیت پرداخت اتفاق افتاده باشد، مثلا کاربر در حسابش به اندازه کافی موجودی نداشته باشد، تاریخ کارتش به اتمام رسیده باشد یا با موفقیت مبلغ را پرداخت کرده باشد و...
تمام این موارد را در بخش بعد بررسی خواهیم کرد.