/*
         * CreatePaymentObject Ödeme nesnesi oluşturmak için kullanılır.
         * Papara sunucularında yeni bir payment oluşturur ve geri döndürür.
         * Her sepet sonucuna gidildiğinde oluşturulmalıdır. /Home/Checkout/ sayfası gibi.
         * Bir PaymentGet nesnesi döndürür
         *
         */
        public static PaymentGet CreatePaymentObject(Payment payment)
        {
            PaymentGet newPayment = new PaymentGet();

            try
            {
                var httpWebRequest = (HttpWebRequest)WebRequest.Create("https://merchantapi-test-master.papara.com/payments");
                httpWebRequest.ContentType = "application/json";
                httpWebRequest.Method      = "POST";
                httpWebRequest.Headers.Add("ApiKey", paparaApiKey);

                using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
                {
                    string json = JsonConvert.SerializeObject(payment, Formatting.Indented);
                    streamWriter.Write(json);
                }
                var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
                using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
                {
                    var responseText = streamReader.ReadToEnd();

                    newPayment = JsonConvert.DeserializeObject <PaymentGet>(responseText);
                    return(newPayment);
                }
            }
            catch (Exception e)
            {
                newPayment.data = new PaymentData
                {
                    amount                   = 0,
                    createdAt                = "",
                    currency                 = "",
                    id                       = "",
                    merchantId               = "",
                    merchantSecretKey        = "",
                    notificationDone         = false,
                    notificationUrl          = "",
                    orderDescription         = "",
                    paymentMethod            = 0,
                    paymentMethodDescription = "",
                    paymentUrl               = "",
                    redirectUrl              = "",
                    referenceId              = "",
                    returningRedirectUrl     = "",
                    status                   = 0,
                    statusDescription        = "",
                    userId                   = ""
                };
                newPayment.succeeded = false;
                newPayment.error     = new PaymentError
                {
                    message = e.Message,
                    code    = 401
                };
                return(newPayment);
            }
        }
        /*
         * GetPaymentObject, Ödeme nesnesi getirmek için kullanılır.
         * Papara sunucularından id (ödeme numarası) parametresiyle istenerek getirilir.
         * Bir PaymentGet nesnesi döndürür.
         * İçerisinde ödeme verisi, başarı durumu ve hata açıklaması bulunur.
         */
        public static PaymentGet GetPaymentObject(string id)
        {
            PaymentGet paymentGet = new PaymentGet();

            try
            {
                var httpWebRequest = (HttpWebRequest)WebRequest.Create("https://merchantapi-test-master.papara.com/payments?id=" + id);
                httpWebRequest.ContentType = "application/json";
                httpWebRequest.Method      = "GET";
                httpWebRequest.Headers.Add("ApiKey", paparaApiKey);
                httpWebRequest.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;



                //JavaScriptSerializer js = new JavaScriptSerializer();
                using (HttpWebResponse response = (HttpWebResponse)httpWebRequest.GetResponse())
                    using (Stream stream = response.GetResponseStream())
                        using (StreamReader reader = new StreamReader(stream))
                        {
                            var responseText = reader.ReadToEnd();
                            paymentGet = JsonConvert.DeserializeObject <PaymentGet>(responseText);
                            return(paymentGet);
                        }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                paymentGet.data = new PaymentData {
                    id = id
                };
                paymentGet.error = new PaymentError {
                    code = 0, message = e.Message
                };
                paymentGet.succeeded = false;
                return(paymentGet);
            }
        }
        public IActionResult BuyRedirect(string paymentId, int status, double amount)
        {
            PaymentGet payment = GetPaymentObject(paymentId); //Papara sunucusundan ödeme bilgisini getir.

            //ÖDEME BAŞARILI
            if (payment.succeeded == true)
            {
                int invoiceId = Convert.ToInt32(payment.data.referenceId.Split('_')[1]);

                //invoiceId ile faturaya gidilir ve faturada yazan miktar totalAmount'a yazılır.

                double totalAmount = 1234.56;

                //Sitemiz üzerinde çıkan tutarla eş ödeme yapılmıştır. Fatura kontrolüne geçebiliriz.
                if (payment.data.amount == totalAmount)
                {
                    //Gelen ödeme bildiriminde bahsi geçen invoiceId'si veritabanımızda bulunmamakta
                    if (false /*dbModel.Invoice.Where(x => x.invoiceId == invoiceId).Count()==0*/)
                    {
                        //Sitemizi ilgilendirmeyen kısım.
                    }
                    //Gelen ödeme bildiriminde bahsi geçen invoiceId'si veritabanımızda bulunuyor.
                    else
                    {
                        /*
                         *  Invoice invoice = dbModel.Invoice.Where(x => x.invoiceId == invoiceId).First();
                         */

                        //Veritabanımızdaki eşleşmeyle bulduğumuz invoice'nin henüz ödenmemiş olduğunu varsayalım.
                        //Yukarıda Invoice tipinde bir invoice değişkeni tanımlıyorsanız, demo açısından dynamic invoice yapmamıza gerek yoktur.
                        dynamic invoice = new { isPaid = false };


                        //Gelen ödeme bildiriminde bahsi geçen invoice zaten ödenmiştir.
                        if (invoice.isPaid == true)
                        {
                            HttpContext.Session.SetString("cart", null);

                            ViewBag.message = "Faturanız ödenmiştir. Yönetim panelinden satın almış olduğunuz ürünlerle ilgili işlem yapabilirsiniz.";
                        }
                        //Gelen ödeme bildiriminde bahsi geçen invoice henüz ödenmemiştir. Veritabanında ödendi olarak gösterilmeli ve ürünler tayin edilmeli
                        else
                        {
                            HttpContext.Session.SetString("cart", null);

                            ViewBag.message = "Faturanız ödenmiştir. Yönetim panelinden satın almış olduğunuz lisanslarla ilgili işlem yapabilirsiniz.";
                        }
                    }
                }
                //Sitemiz üzerinde çıkan tutardan fazla ödeme yapılmıştır. Ödenmiş olan ücret geri iade edilecek. Ve satın almış olduğunuz ürünler iptal edilecek.
                else if (payment.data.amount > totalAmount)
                {
                    ViewBag.message = "Sitemiz üzerinde çıkan tutardan fazla ödeme yapılmıştır. Ödenmiş olan ücret geri iade edilecek";
                    bool refundStatus = RefundPayment(payment.data.id);

                    //EĞER GERİ ÖDEME BAŞARILIYSA
                    if (refundStatus == true)
                    {
                        ViewBag.message = "Sitemiz üzerinde çıkan tutardan fazla ödeme yapılmıştır. Sepetiniz iptal edildi. Ödenmiş olan ücret PAPARA'ya geri iade edildi.";
                        HttpContext.Session.SetString("cart", null);
                    }
                    //EĞER GERİ ÖDEME BAŞARISIZSA
                    else
                    {
                        ViewBag.message = "Sitemiz üzerinde çıkan tutardan fazla ödeme yapılmıştır. Sepetiniz iptal edildi. Ve bir hatadan ötürü ödenmiş olan ücret PAPARA'ya geri iade edilemedi. Lütfen bizimle irtibata geçin.";
                        HttpContext.Session.SetString("cart", null);
                    }
                }
                //Sitemiz üzerinde çıkan tutardan az ödeme yapılmıştır. Ödenmiş olan ücret geri iade edilecek. Ve satın almış olduğunuz ürünler iptal edilecek.
                else
                {
                    ViewBag.message = "Sitemiz üzerinde çıkan tutardan az ödeme yapılmıştır. Ücret geri iade edilecek.";
                    bool refundStatus = RefundPayment(payment.data.id);
                    //EĞER GERİ ÖDEME BAŞARILIYSA
                    if (refundStatus == true)
                    {
                        ViewBag.message = "Sitemiz üzerinde çıkan tutardan az ödeme yapılmıştır. Sepetiniz iptal edildi. Ve ödenmiş olan ücret PAPARA'ya geri iade edildi. Yönetim panelinizden ödenmemiş faturalarınıza göz atıp";
                        HttpContext.Session.SetString("cart", null);
                    }
                    //EĞER GERİ ÖDEME BAŞARISIZSA
                    else
                    {
                        ViewBag.message = "Sitemiz üzerinde çıkan tutardan az ödeme yapılmıştır. Sepetiniz iptal edildi. Ve bir hatadan ötürü ödenmiş olan ücret PAPARA'ya geri iade edilemedi. Lütfen bizimle irtibata geçin.";
                        HttpContext.Session.SetString("cart", null);
                    }
                }
            }
            //ÖDEME BAŞARISIZ
            else
            {
                int invoiceId = Convert.ToInt32(payment.data.referenceId.Split('_')[1]);
                try
                {
                    ViewBag.message = "Ödeme başarısız. Faturanız ve ona bağlı olan tüm ürünler veritabanımızdan silindi. Lütfen sepetinizi yeniden oluşturup ödeme yapınız.";
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                }
            }
            return(View("CheckoutFinished"));
        }
        //Checkout sayfasından sonra 'satın al' butonuyla çağrılacak metotdur.
        public IActionResult Buy()
        {
            try
            {
                //Sepet oluşturulmamış, sepete geri dön.
                if (HttpContext.Session.GetString("cart") == null)
                {
                    return(RedirectToAction("Cart", "Home"));
                }
                //Sepet var
                else
                {
                    //Papara için ödeme alt yapısı oluşturulur
                    Payment payment;

                    //FATURA OLUŞTURULDU
                    try
                    {
                        //Invoice newInvoice = new Invoice();
                        //BUrada newInvoice içerisi doldurulur. İçine sepetteki ürünler eklenir en son subtotal hesaplanır.

                        double totalAmount = 1234.56;

                        payment = new Payment()
                        {
                            amount           = totalAmount,
                            notificationUrl  = "http://" + Request.Host.Host + ':' + Request.Host.Port + "/Home/BuyNotification",
                            orderDescription = "Satın alınan şeylerin listesi",
                            redirectUrl      = "http://" + Request.Host.Host + ':' + Request.Host.Port + "/Home/BuyRedirect",
                            referenceId      = "invoiceId_" + "987654"
                        };
                    }
                    //FATURA OLUŞTURULAMADI
                    catch (Exception e)
                    {
                        ViewBag.message = e.Message;
                        return(View("Error404"));
                    }
                    //FATURA OLUŞTURULDUĞU VARSAYILDIĞINDA ÖDEME OLUŞTURULABİLECEK Mİ
                    try
                    {
                        PaymentGet paymentResponse = CreatePaymentObject(payment);

                        //FATURA OLUŞTURULDU VE ÖDEME İSTEĞİ OLUŞTURULDU, SEPETTEKİ ÜRÜNLER FATURAYA AİT FATURAÜRÜNLERİ TABLONUZA AKTARILABİLİR VE ÖDEMEYE YÖNLENDİRİLEBİLİR
                        if (paymentResponse.succeeded == true)
                        {
                            /*
                             *
                             */
                            return(Redirect(paymentResponse.data.paymentUrl));
                        }
                        else
                        {//FATURA OLUŞTURULDU ANCAK ÖDEME İSTEĞİ OLUŞTURULAMADI İSE
                         //OLUŞTURULAN FATURAYI BURADA VERİTABANINDAN SİLEBİLİRSİNİZ

                            ViewBag.message = "Papara'da invoice oluştururken bir hata oluştu | " + paymentResponse.error.message;
                            return(View("Error404"));
                        }
                    }
                    catch (Exception e)
                    {//FATURA OLUŞTURULDUĞU VARSAYILDI ANCA ÖDEME OLUŞTURULAMADI
                        ViewBag.message = e.Message;
                        //return RedirectToAction("Lisanslar","SirketYonetim",new PaymentError {code=0, message=e.Message});
                        return(View("Error404"));
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                ViewBag.message = e.Message;
                return(View("Error404"));
            }
        }
 public async Task<PaymentGet.response> PaymentGet(PaymentGet.request request, CancellationToken? token = null)
 {
     return await SendAsync<PaymentGet.response>(request.ToXmlString(), token.GetValueOrDefault(CancellationToken.None));
 }