Coder Social home page Coder Social logo

Comments (25)

Sina-Soltani avatar Sina-Soltani commented on May 26, 2024

(اگر در خواندن متن مشکل چپ چین راست چین، دارید لطفا داخل برنامه ای مثل ورد کپی کنید)

۱. مقدار Already Verified در اینام VerifyResultStatus به معنای این هست که اگر شما بنا به دلایلی بیش از یکبار، درخواست تأیید رو به بانک ارسال کنید، این مقدار به شما بازگشت داده خواهد شد.
علت آینه که درخواستی که قبلاً تأیید شده، اگر بار دیگه آنجام بشه، نباید Success رو برگردونه. چون فروشنده ممکن هست بیش از یکبار عملیات خرید رو برای مشتری انجام بده. برای مثال ممکنه کاربر صفحه رو رفرش کنه و این عملیات دو مرتبه تکرار بشه.

۲. در مورد ذخیره در دیتابیس، قرار هست نسخه جدیدی آماده بشه که بسیار کامل‌تر از نسخه فعلی هست.

۳. TransactionID فقط در صورتی ذخیره میشه که پرداخت موفقیت آمیز بوده باشه. در‌واقع به پرداختی که انجام نگرفته، هیچ TransactionID هم اختصاص داده نمیشه از جانب بانک.

from parbad.

aradalvand avatar aradalvand commented on May 26, 2024

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

from parbad.

aradalvand avatar aradalvand commented on May 26, 2024

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

from parbad.

Sina-Soltani avatar Sina-Soltani commented on May 26, 2024

زمانیکه که کاربر از درگاه بانک به سایت شما برمیگرده، فقط ۲ حالت بیشتر وجود نداره
۱. پرداخت شد Success
۲. پرداخت نشد Failed

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

در‌واقع این مورد توسط خود سیستم بانکی طراحی شده و ما چیزی رو اختراع نکردیم. زمانیکه شما به درگاه بانکی بیش از یکبار درخواست تأیید بفرستید، بانک به شما اعلام میکنه که عملیات قبلاً تأیید شده.

در مورد دیتابیس، من سعی میکنم در همین نسخه فعلی که نسخه بتا هست این مورد رو اصلاح کنم.
فکر میکنم بین یک تا حداکثر سه روز زمان ببره.

اجازه بدید کد شما رو نگاه کنم.

from parbad.

aradalvand avatar aradalvand commented on May 26, 2024
بله متوجه مفهوم و کاربرد AlreadyVerified شدم، اما نکته اینجاست که حتی وقتی اون اکشن متد تنها یکبار صدا زده میشه، همون بار اول هم نتیجه AlreadyVerified هست.

from parbad.

aradalvand avatar aradalvand commented on May 26, 2024
و همینطور TransactionID هم همیشه null هست حتی وقتی پرداخت با موفقیت انجام میگیره.

from parbad.

Sina-Soltani avatar Sina-Soltani commented on May 26, 2024

شما با درگاه تست ParbadVirtualGateway هم تست کردید؟

from parbad.

aradalvand avatar aradalvand commented on May 26, 2024
بله، با هر دو درگاه (مجازی پرباد و درگاه بانک پاسارگاد) چک کردیم و همین مشکل وجود داره.

from parbad.

aradalvand avatar aradalvand commented on May 26, 2024
فکر می کنم باگ باشه، چون بعد از زدن دکمه Pay در درگاه مجازی پرباد و همینطور بانک پاسارگاد، پیغام موفقیت آمیز بودن پرداخت در هر دو درگاه نمایش داده میشه، اما در دیتابیس TransactionID ذخیره نمیشه.

from parbad.

aradalvand avatar aradalvand commented on May 26, 2024

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

from parbad.

aradalvand avatar aradalvand commented on May 26, 2024

این صفحه قبل از عکس بالا هست

from parbad.

Sina-Soltani avatar Sina-Soltani commented on May 26, 2024

من الان یکبار دیگه سیستم رو تست کردم و هیچ مشکلی وجود نداره.
آیا شما خودتون دارید در دیتابیس ذخیره میکنید و یا اینکه از SQLServer خود این کتابخونه دارید استفاده میکنید؟

from parbad.

aradalvand avatar aradalvand commented on May 26, 2024
عزیز پس لطف کنید به سورس کد من یه نگاهی بندازید. اینطور که شما می فرمایید پس نباید اشکال از سمت شما باشه. اما خب من هم هیچ اشکالی در سورس کد خودم نمی بینم. در مورد سوالتون درباره نحوه ذخیره سازی هم باید عرض کنم که به شکل دلخواه دارم ذخیره می کنم. ضمنا دارم از نسخه beta استفاده می کنم. شما این نسخه رو تست کردید؟

from parbad.

Sina-Soltani avatar Sina-Soltani commented on May 26, 2024

اگر ممکنه کد مربوط به ذخیره سازی رو همینجا در گیت هاب قرار بدید تا ببینم

from parbad.

aradalvand avatar aradalvand commented on May 26, 2024

کد ذخیره سازی:

namespace Abarbazar.Models.DomainModels
{
    public class ParbadStorage : Storage
    {
        private readonly AbarbazarDatabaseContext dbContext;
        public ParbadStorage() => dbContext = new AbarbazarDatabaseContext();

        protected override void Insert(PaymentData paymentData)
        {
            dbContext.Payments.Add(new Payment
            {
                UserId = (HttpContext.Current.User as AbarbazarPrincipal).UserId,
                PaymentId = paymentData.Id,
                OrderNumber = paymentData.OrderNumber,
                Amount = paymentData.Amount,
                CreatedOn = paymentData.CreatedOn,
                ReferenceId = paymentData.ReferenceId,
                TransactionId = paymentData.TransactionId,
                AdditionalData = paymentData.AdditionalData,
                GatewayId = paymentData.Gateway == Parbad.Providers.Gateway.ParbadVirtualGateway ? PaymentGateway.ParbadVirtualId : PaymentGateway.PasargadId,
                StatusId = paymentData.Status == PaymentDataStatus.Verified ? PaymentStatus.VerifiedId : paymentData.Status == PaymentDataStatus.Failed ? PaymentStatus.FailedId : paymentData.Status == PaymentDataStatus.Refunded ? PaymentStatus.RefundedId : PaymentStatus.RequestedId,
            });
            dbContext.SaveChanges();
        }

        protected override Task InsertAsync(PaymentData paymentData)
        {
            dbContext.Payments.Add(new Payment
            {
                UserId = (HttpContext.Current.User as AbarbazarPrincipal).UserId,
                PaymentId = paymentData.Id,
                OrderNumber = paymentData.OrderNumber,
                Amount = paymentData.Amount,
                CreatedOn = paymentData.CreatedOn,
                ReferenceId = paymentData.ReferenceId,
                TransactionId = paymentData.TransactionId,
                AdditionalData = paymentData.AdditionalData,
                GatewayId = paymentData.Gateway == Parbad.Providers.Gateway.ParbadVirtualGateway ? PaymentGateway.ParbadVirtualId : PaymentGateway.PasargadId,
                StatusId = paymentData.Status == PaymentDataStatus.Verified ? PaymentStatus.VerifiedId : paymentData.Status == PaymentDataStatus.Failed ? PaymentStatus.FailedId : paymentData.Status == PaymentDataStatus.Refunded ? PaymentStatus.RefundedId : PaymentStatus.RequestedId,
            });
            return dbContext.SaveChangesAsync();
        }

        protected override PaymentData SelectById(Guid id)
        {
            return dbContext.Payments.Where(p => p.PaymentId == id).Select(p => new PaymentData
            {
                Id = p.PaymentId,
                OrderNumber = p.OrderNumber,
                Amount = (long)p.Amount,
                CreatedOn = p.CreatedOn,
                ReferenceId = p.ReferenceId,
                TransactionId = p.TransactionId,
                AdditionalData = p.AdditionalData,
                Gateway = p.GatewayId == PaymentGateway.ParbadVirtualId ? Parbad.Providers.Gateway.ParbadVirtualGateway : Parbad.Providers.Gateway.Pasargad,
                Status = p.StatusId == PaymentStatus.VerifiedId ? PaymentDataStatus.Verified : p.StatusId == PaymentStatus.FailedId ? PaymentDataStatus.Failed : p.StatusId == PaymentStatus.RefundedId ? PaymentDataStatus.Refunded : PaymentDataStatus.Requested,
            }).SingleOrDefault();
        }

        protected override Task<PaymentData> SelectByIdAsync(Guid id)
        {
            return dbContext.Payments.Where(p => p.PaymentId == id).Select(p => new PaymentData
            {
                Id = p.PaymentId,
                OrderNumber = p.OrderNumber,
                Amount = (long)p.Amount,
                CreatedOn = p.CreatedOn,
                ReferenceId = p.ReferenceId,
                TransactionId = p.TransactionId,
                AdditionalData = p.AdditionalData,
                Gateway = p.GatewayId == PaymentGateway.ParbadVirtualId ? Parbad.Providers.Gateway.ParbadVirtualGateway : Parbad.Providers.Gateway.Pasargad,
                Status = p.StatusId == PaymentStatus.VerifiedId ? PaymentDataStatus.Verified : p.StatusId == PaymentStatus.FailedId ? PaymentDataStatus.Failed : p.StatusId == PaymentStatus.RefundedId ? PaymentDataStatus.Refunded : PaymentDataStatus.Requested,
            }).SingleOrDefaultAsync();
        }

        protected override PaymentData SelectByOrderNumber(long orderNumber)
        {

            return dbContext.Payments.Where(p => p.OrderNumber == orderNumber).Select(p => new PaymentData
            {
                Id = p.PaymentId,
                OrderNumber = p.OrderNumber,
                Amount = (long)p.Amount,
                CreatedOn = p.CreatedOn,
                ReferenceId = p.ReferenceId,
                TransactionId = p.TransactionId,
                AdditionalData = p.AdditionalData,
                Gateway = p.GatewayId == PaymentGateway.ParbadVirtualId ? Parbad.Providers.Gateway.ParbadVirtualGateway : Parbad.Providers.Gateway.Pasargad,
                Status = p.StatusId == PaymentStatus.VerifiedId ? PaymentDataStatus.Verified : p.StatusId == PaymentStatus.FailedId ? PaymentDataStatus.Failed : p.StatusId == PaymentStatus.RefundedId ? PaymentDataStatus.Refunded : PaymentDataStatus.Requested,
            }).SingleOrDefault();
        }

        protected override Task<PaymentData> SelectByOrderNumberAsync(long orderNumber)
        {
            return dbContext.Payments.Where(p => p.OrderNumber == orderNumber).Select(p => new PaymentData
            {
                Id = p.PaymentId,
                OrderNumber = p.OrderNumber,
                Amount = (long)p.Amount,
                CreatedOn = p.CreatedOn,
                ReferenceId = p.ReferenceId,
                TransactionId = p.TransactionId,
                AdditionalData = p.AdditionalData,
                Gateway = p.GatewayId == PaymentGateway.ParbadVirtualId ? Parbad.Providers.Gateway.ParbadVirtualGateway : Parbad.Providers.Gateway.Pasargad,
                Status = p.StatusId == PaymentStatus.VerifiedId ? PaymentDataStatus.Verified : p.StatusId == PaymentStatus.FailedId ? PaymentDataStatus.Failed : p.StatusId == PaymentStatus.RefundedId ? PaymentDataStatus.Refunded : PaymentDataStatus.Requested,
            }).SingleOrDefaultAsync();
        }

        protected override void Update(PaymentData paymentData)
        {
            Payment payment = dbContext.Payments.SingleOrDefault(p => p.PaymentId == paymentData.Id);
            payment.OrderNumber = payment.OrderNumber;
            payment.Amount = payment.Amount;
            payment.ReferenceId = payment.ReferenceId;
            payment.TransactionId = payment.TransactionId;
            payment.AdditionalData = payment.AdditionalData;
            payment.StatusId = paymentData.Status == PaymentDataStatus.Verified ? PaymentStatus.VerifiedId : paymentData.Status == PaymentDataStatus.Failed ? PaymentStatus.FailedId : paymentData.Status == PaymentDataStatus.Refunded ? PaymentStatus.RefundedId : PaymentStatus.RequestedId;
            payment.AdditionalData = paymentData.AdditionalData;
            dbContext.SaveChanges();
        }

        protected override Task UpdateAsync(PaymentData paymentData)
        {
            Payment payment = dbContext.Payments.SingleOrDefault(p => p.PaymentId == paymentData.Id);
            payment.OrderNumber = payment.OrderNumber;
            payment.Amount = payment.Amount;
            payment.ReferenceId = payment.ReferenceId;
            payment.TransactionId = payment.TransactionId;
            payment.AdditionalData = payment.AdditionalData;
            payment.StatusId = paymentData.Status == PaymentDataStatus.Verified ? PaymentStatus.VerifiedId : paymentData.Status == PaymentDataStatus.Failed ? PaymentStatus.FailedId : paymentData.Status == PaymentDataStatus.Refunded ? PaymentStatus.RefundedId : PaymentStatus.RequestedId;
            payment.AdditionalData = paymentData.AdditionalData;
            return dbContext.SaveChangesAsync();
        }
    }
}

from parbad.

aradalvand avatar aradalvand commented on May 26, 2024

این کد اکشن متد ها رو هم ممنون میشم اگر یه بررسی کوچیک بفرمایید:
`

    [AbarbazarMVCAuthorize(Roles = "ShopOwner")]
    [Route("Shop/Plan")]
    [Route("Shop/Plan/{shopPlanTermId:int}")]
    public ActionResult ShopPlan(int? shopPlanTermId, string couponCode)
    {
        if (shopPlanTermId.HasValue)
        {
            int shopId = (User as AbarbazarPrincipal).ShopId;
            ShopPlanService service = new ShopPlanService();
            if (service.IsPurchaseValid(shopId, shopPlanTermId.Value, couponCode))
            {
                decimal finalPrice = service.GetShopPlanPurchaseFinalPrice(shopPlanTermId.Value, couponCode);
                if (finalPrice > 0)
                {
                    var invoice = new Invoice(service.GenerateUniqueOrderNumber(),
                        (long)finalPrice,
                        Request.Url.GetLeftPart(System.UriPartial.Authority) + $"/Panel/Shop/Plan/{shopPlanTermId}/Verify{(!string.IsNullOrEmpty(couponCode) ? "?couponCode=" + couponCode : string.Empty)}");
                    var reqResult = Parbad.Payment.Request(Parbad.Providers.Gateway.ParbadVirtualGateway, invoice);

                    if (reqResult.Status == RequestResultStatus.Success)
                        return reqResult.ToActionResult();
                    else
                        ViewBag.PurchaseErrorMessage = Presentation.Resources.Messages.ExceptionWasThrown;
                }
                else
                {
                    bool purchaseResult = service.CompleteShopPlanPurchase(shopId, new CreateOrUpgradeShopPlan
                    {
                        ShopPlanTermId = shopPlanTermId.Value,
                        CouponCode = couponCode
                    });
                    if (purchaseResult)
                        return Redirect("/Panel/Shop/Plan");
                }
            }
            ViewBag.PurchaseErrorMessage = Presentation.Resources.Messages.ShopPlanPurchaseIsNotValid;
        }
        return View(new ShopService().GetShopPlanInfo());
    }

    [AbarbazarMVCAuthorize(Roles = "ShopOwner")]
    [Route("Shop/Plan/{shopPlanTermId:int}/Verify")]
    public ActionResult ShopPlanPurchaseFinalize(int shopPlanTermId, string couponCode, string paymentID)
    {
        ShopPlanService service = new ShopPlanService();
        long orderNumber = 0;
        int shopId = (User as AbarbazarPrincipal).ShopId;

        var paymentResult = Parbad.Payment.Verify(HttpContext, invoice =>
        {
            orderNumber = invoice.OrderNumber;
            if (!service.IsPurchaseValid(shopId, shopPlanTermId, couponCode))
                invoice.Cancel();
        });
        if (paymentResult.Status == VerifyResultStatus.Success/* || paymentResult.Status == VerifyResultStatus.AlreadyVerified*/)
        {
            bool purchaseResult = service.CompleteShopPlanPurchase(shopId, new CreateOrUpgradeShopPlan
            {
                ShopPlanTermId = shopPlanTermId,
                PaymentGuid = paymentID,
                CouponCode = couponCode
            });
            if (!purchaseResult)
            {
                Parbad.Payment.Refund(new RefundInvoice(orderNumber));
                ViewBag.PurchaseErrorMessage = Presentation.Resources.Messages.ShopPlanPurchaseIsNotValid;
            }
        }
        return RedirectToAction("ShopPlan");
    }`

from parbad.

aradalvand avatar aradalvand commented on May 26, 2024
نکته دیگه ای رو هم که الان متوجه شدم اینه که متدی که به دلگیت پارامتر دوم متد Payment.Verify() ارسال می کنم کال نمیشه.

from parbad.

aradalvand avatar aradalvand commented on May 26, 2024
ممنون میشم اگر راهنمایی کنید. چون واقعا کارمون گیر همین موضوعه.

from parbad.

Sina-Soltani avatar Sina-Soltani commented on May 26, 2024

این مواردی که میگم رو لطفا دقیق انجام بدید و اطلاع بدید.

ابتدا سفارش رو انجام بدید و برید به درگاه تست ParbadVirtualGateway

قبل از اینکه کلید پرداخت رو بزنید، برید به پایگاه داده که اطلاعات رو ثبت کردید ببینید مقدار فیلد Status چی هست

from parbad.

Sina-Soltani avatar Sina-Soltani commented on May 26, 2024

این مواردی که میگم رو لطفا دقیق انجام بدید و اطلاع بدید.

ابتدا سفارش رو انجام بدید و برید به درگاه تست ParbadVirtualGateway

قبل از اینکه کلید پرداخت رو بزنید، برید به پایگاه داده که اطلاعات رو ثبت کردید ببینید مقدار فیلد Status چی هست

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

from parbad.

aradalvand avatar aradalvand commented on May 26, 2024

این مواردی که میگم رو لطفا دقیق انجام بدید و اطلاع بدید.
ابتدا سفارش رو انجام بدید و برید به درگاه تست ParbadVirtualGateway
قبل از اینکه کلید پرداخت رو بزنید، برید به پایگاه داده که اطلاعات رو ثبت کردید ببینید مقدار فیلد Status چی هست

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

بررسی انجام شد. در اون مرحله وضعیت Verified هست. طبیعتا باید Requested باشه نه Verified درسته؟

from parbad.

Sina-Soltani avatar Sina-Soltani commented on May 26, 2024

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

from parbad.

aradalvand avatar aradalvand commented on May 26, 2024

بله الان متوجه شدم اشتباه از من بوده. عذر خواهی می کنم.
بازهم خیلی ازتون متشکرم که وقتتون در اختیار من قرار دادید. لطف کردید. واقعا پشتیبانیتون خیلی خوب بود. امیدوارم موفق باشید.

from parbad.

Sina-Soltani avatar Sina-Soltani commented on May 26, 2024

bool purchaseResult = service.CompleteShopPlanPurchase(shopId, new CreateOrUpgradeShopPlan { ShopPlanTermId = shopPlanTermId, PaymentGuid = paymentID, CouponCode = couponCode }); if (!purchaseResult) { Parbad.Payment.Refund(new RefundInvoice(orderNumber)); ViewBag.PurchaseErrorMessage = Presentation.Resources.Messages.ShopPlanPurchaseIsNotValid; }

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

from parbad.

Sina-Soltani avatar Sina-Soltani commented on May 26, 2024

موفق باشید

from parbad.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.