Sina-Soltani / Parbad

A free, open-source, integrated and extensible library which connects your web applications to online payment gateways. Gateways can be added or developed by you.
GNU Lesser General Public License v3.0
371 stars 81 forks source link

درگاه بانک ملی (سداد) #22

Closed RezaAVS closed 5 years ago

RezaAVS commented 5 years ago

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

محتوای مورد نظر یافت نشد لطفاً صحت درخواست را بررسی نمایید و دوباره سعی کنید

و اینکه Url به این شکل می باشد https://sadad.shaparak.ir/VPG/Purchase/Index?token= مشکل از چیه؟

Sina-Soltani commented 5 years ago

درود

بررسی میکنم. ممنون برای اطلاع رسانی

RezaAVS commented 5 years ago

براساس مستندات رسمی ازمایش کردم مشکل در تابع PostJsonAsync می باشد

این بخش رو ببینید ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Ssl3; using (var client = new HttpClient()) {

            client.BaseAddress = new Uri(apiUrl);
            client.DefaultRequestHeaders.Accept.Clear();

            var json = JsonConvert.SerializeObject(value, Formatting.None);
            var xxx = await  client.PostAsync(apiUrl, new StringContent(json, Encoding.UTF8, "application/json"));

            HttpResponseMessage response = xxx;
            if (response.IsSuccessStatusCode)
            {
                var result = await response.Content.ReadAsStringAsync();
                var x = JsonConvert.DeserializeObject<T>(result);
                return JsonConvert.DeserializeObject<T>(result);
            }
            return default(T);
        }

اینجا در لوکال خطای مشخصی نمایش داده می شود اما زمانی که در پروژه شما فراخوانی میکنم در بخش Header request این متن نمایش داده می شود Headers = {Pragma: no-cache X-Frame-Options: SERVER-RemoveRule: X-ASPNETMVC-VERSION: Cache-Control: no-cache Date: Sun, 26 May 2019 10:59:36 GMT X-AspNet-Version: X-Powered-By: }

Sina-Soltani commented 5 years ago

مشکلی که وجود داره چیز دیگه ای هست که البته باید حل بشه. اما در مورد مشکل شما فکر میکنم تنظیمات بانک ملی رو اشتباه انجام دادید. یعنی اینکه احتمالا اطلاعات تنظیمات صحیح نیست TerminalId MerchantId TerminalKey

این موارد رو کنترل کنید شاید جابجا وارد کردید

RezaAVS commented 5 years ago

در پروژه mvc تست کردم همان موارد و جواب داد اما الان در پروژه net core خطای Scurity not supported ارسال می شود این بخش رو ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Ssl3

RezaAVS commented 5 years ago

جناب سلطانی مشکل رو پیدا کردم باید بخش بالا رو تغییر بدید به این صورت مشکل برطرف میشه ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.SystemDefault; منتظر نسخه جدید هستم

Sina-Soltani commented 5 years ago

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

RezaAVS commented 5 years ago

من این تابع رو به این شکل تغییر دادم مشکل کاملا برطرف شد public virtual async Task RequestAsync(Invoice invoice, CancellationToken cancellationToken = default) { if (invoice == null) throw new ArgumentNullException(nameof(invoice));

        var dataBytes = Encoding.UTF8.GetBytes($"{_options.Value.TerminalId};{invoice.TrackingNumber.ToString()};{(long)invoice.Amount}");
        var symmetric = SymmetricAlgorithm.Create("TripleDes");
        symmetric.Mode = CipherMode.ECB;
        symmetric.Padding = PaddingMode.PKCS7;
        var encryptor = symmetric.CreateEncryptor(Convert.FromBase64String(_options.Value.TerminalKey), new byte[8]);
        var signData = Convert.ToBase64String(encryptor.TransformFinalBlock(dataBytes, 0, dataBytes.Length));

        var apiUrl = $"{MelliHelper.BaseServiceUrl}{MelliHelper.ServiceRequestUrl}";
        var data = new
        {
            _options.Value.TerminalId,
            _options.Value.MerchantId,
            Amount = (long)invoice.Amount,
            SignData = signData,
            ReturnUrl = invoice.CallbackUrl,
            LocalDateTime = DateTime.Now,
            OrderId = invoice.TrackingNumber.ToString(),
        };
        ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
        var client = new HttpClient {BaseAddress = new Uri(apiUrl)};
        client.DefaultRequestHeaders.Accept.Clear();

        var json = JsonConvert.SerializeObject(data, Formatting.None);
        var responseMessage = await client.PostAsync(apiUrl, new StringContent(json, Encoding.UTF8, "application/json"), CancellationToken.None);

        var response = responseMessage;
        var result = await response.Content.ReadAsStringAsync();
        var request = JsonConvert.DeserializeObject<MelliApiRequestResult>(result);
        return MelliHelper.CreateRequestResult(request, _httpContextAccessor, _messageOptions.Value);
    }
RezaAVS commented 5 years ago

جناب سلطانی بعد از ساعت ها بررسی سورس شما (البته با اجاز شما) مشکل از 3 بخش می باشد: بخش اول : SecurityProtocol هست که باید براساس ساختار زیر باشد ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls; بخش دوم: تابع SignRequestData این بخش باید OrderId به صورت string fhan var dataBytes = Encoding.UTF8.GetBytes($"{terminalId};{orderId.ToString()};{amount}"); بخش سوم: مهم ترین قسمت این بخش هست که باید ساختار به این شکل باشد return new { options.TerminalId, options.MerchantId, Amount = (long)invoice.Amount, SignData = signedData, ReturnUrl = invoice.CallbackUrl.ToString(), LocalDateTime = DateTime.Now, OrderId = invoice.TrackingNumber.ToString() }; callbackurl به صورت ToString باید باشد این موارد رو من اصلاح کردم و تست کردم و درگاه نمایش داده شد

این هم کد 200 {StatusCode: 200, ReasonPhrase: 'OK', Version: 1.1, Content: System.Net.Http.StreamContent, Headers: { Pragma: no-cache X-Frame-Options: SERVER-RemoveRule: X-ASPNETMVC-VERSION: Cache-Control: no-cache Date: Sun, 26 May 2019 13:57:22 GMT Server: Microsoft-IIS/8.5 X-AspNet-Version: X-Powered-By: Content-Length: 258 Content-Type: application/json; charset=utf-8 Expires: -1 }}

RezaAVS commented 5 years ago

در بخش Verify مقدار Responce خالی می باشد

PostJsonAsync url : /VPG/api/v0/Request/PaymentRequest data : { TerminalId = 24052347, MerchantId = 000000140331685, Amount = 10120, SignData = kTkei8mT0S5cfzLUHQ1ZD2oIj3nX+txB, ReturnUrl = https://www.foolad.com/Checkout/GatewayCallback?paymentToken=fde074166b324a5f961805dce43c71d0, LocalDateTime = 5/26/2019 11:04:11 PM, OrderId = 1008 } T : Parbad.GatewayProviders.Melli.Models.MelliApiRequestResult responseMessage : StatusCode: 200, ReasonPhrase: 'OK', Version: 1.1, Content: System.Net.Http.StreamContent, Headers: { Pragma: no-cache X-Frame-Options: SERVER-RemoveRule: X-ASPNETMVC-VERSION: Cache-Control: no-cache Date: Sun, 26 May 2019 18:34:12 GMT Server: Microsoft-IIS/8.5 X-AspNet-Version: X-Powered-By: Content-Length: 141 Content-Type: application/json; charset=utf-8 Expires: -1 } response : {"ResCode":"0","Token":"00012A0AB89E2D80BFD9A83C494BB740418D9B7AA85A247D9DF4","Description":"عملیات با موفقیت انجام شد"} PostJsonAsync url : /VPG/api/v0/Advice/Verify data : { token = 00012A0AB89E2D80BFD9A83C494BB740418D9B7AA85A247D9DF4, SignData = U1fJHmWxhjZihHQWTB9l4RZJkUv9zciaNvQ4b7dgjWBPf72O+J0LN0xTSnHiMPyyKuoNL1UkFNY= } T : Parbad.GatewayProviders.Melli.Models.MelliApiVerifyResult responseMessage : StatusCode: 500, ReasonPhrase: 'Internal Server Error', Version: 1.1, Content: System.Net.Http.StreamContent, Headers: { Pragma: no-cache X-Frame-Options: SERVER-RemoveRule: X-ASPNETMVC-VERSION: Cache-Control: no-cache Date: Sun, 26 May 2019 18:34:53 GMT X-AspNet-Version: X-Powered-By: Content-Length: 0 Expires: -1 } response :

RezaAVS commented 5 years ago

سلام جناب سلطانی مشکل تابع Verify رو هم برطرف کردم جایی که نقدار data داره ارسال میشه از نوع json نیست که این بخش رو تبدیل به json کردم از طریق تایع زیر که فعلا کارم راه بیافتد

internal static string ToJson(this object data) { var jsonStringBuilder = new StringBuilder();

        var dataString = data.ToString().Split(',');
        for (var index = 0; index < dataString.Length; index++)
        {
            var temp = dataString[index].Replace("{ token = ", $"{{ {'"'}token{'"'} : {'"'}").Replace("SignData = ", $"{'"'}SignData{'"'} : {'"'}");
            temp = index == 0 ? $"{temp}{'"'}," : temp.Replace(" }", $"{'"'} }}");
            jsonStringBuilder.Append(temp);
        }

        return jsonStringBuilder.ToString();
    }

همچنین تابع PostAsync رو هم تغییر دادم public static Task PostJsonAsync(this HttpClient httpClient, string requestUri, object data, CancellationToken cancellationToken = default, bool isJson = true) پارامتر isJson رو اضافه کردم

پوزش میخوام که کدهای شما رو بررسی کردم چون باید بانک ملی امروز راه اندازی می شد

Sina-Soltani commented 5 years ago

سلام جناب سلطانی

مشکل تابع Verify رو هم برطرف کردم جایی که نقدار data داره ارسال میشه از نوع json نیست که این بخش رو

سلام ممنون دوست عزیز نیازی به عذرخواهی نیست چون این ابزار اوپن سورس هست و همه اجازه دیدن، کار کردن و تست کردن این ابزار رو دارن و همچنین ممنون از شما برای پیگیری و پیدا کردن مشکلات

به زودی اصلاح میشه و نسخه جدید آماده میشه

Sina-Soltani commented 5 years ago

@RezaAVS با توجه به تغییر تنظیم ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls; و عدم مشکل در دات نت کور لطفا اگر براتون مقدور هست یکبار هم یک تست در پروژه MVC انجام بدید و ببینید آیا مشکلی وجود نداره

تشکر

RezaAVS commented 5 years ago

بله حتما تست MVC رو انجام میدم خبرشو بهتون میدم با تشکر

RezaAVS commented 5 years ago

سلام جناب سلطانی با عرض پوژش که دیر شد تست کردن مشکل خاصی نبود و جواب گرفتم

Sina-Soltani commented 5 years ago

ممنون از شما