Aracılığıyla paylaş


PayPal ile Kasa İşlemleri ve Ödeme

tarafından Erik Reitan

Wingtip Toys Örnek Proje (C#) veya E-kitabı İndir (PDF)

Bu öğretici serisi, web için ASP.NET 4.5 ve Microsoft Visual Studio Express 2013 kullanarak ASP.NET Web Forms uygulaması oluşturmanın temellerini öğretecektir. Bu öğretici serisine eşlik etmek için C# kaynak koduna sahip bir Visual Studio 2013 projesi kullanılabilir.

Bu öğreticide, Wingtip Toys örnek uygulamasının PayPal kullanılarak kullanıcı yetkilendirmesi, kayıt ve ödeme içerecek şekilde nasıl değiştirileceği açıklanmaktadır. Yalnızca oturum açmış kullanıcılar ürün satın alma yetkisine sahip olur. ASP.NET 4.5 Web Forms proje şablonunun yerleşik kullanıcı kaydı işlevi zaten ihtiyacınız olanın çoğunu içerir. PayPal Express Kullanıma Alma işlevselliğini ekleyebilirsiniz. Bu öğreticide PayPal geliştirici test ortamını kullanıyorsunuz, bu nedenle gerçek fonlar aktarılmayacak. Öğreticinin sonunda, alışveriş sepetine eklenecek ürünleri seçerek, kullanıma al düğmesine tıklayarak ve verileri PayPal test web sitesine aktararak uygulamayı test edeceksiniz. PayPal test web sitesinde, gönderim ve ödeme bilgilerinizi onaylayacak ve ardından satın alma işlemini onaylamak ve tamamlamak için yerel Wingtip Toys örnek uygulamasına döneceksiniz.

Ölçeklenebilirlik ve güvenliği ele alan çevrimiçi alışveriş konusunda uzmanlaşmış birçok deneyimli üçüncü taraf ödeme işlemcisi vardır. ASP.NET geliştiriciler, bir alışveriş ve satın alma çözümü uygulamadan önce üçüncü taraf ödeme çözümünü kullanmanın avantajlarını göz önünde bulundurmalıdır.

Not

Wingtip Toys örnek uygulaması, ASP.NET web geliştiricilerinin kullanabileceği belirli ASP.NET kavramlarını ve özelliklerini gösterecek şekilde tasarlanmıştır. Bu örnek uygulama, ölçeklenebilirlik ve güvenlik açısından olası tüm koşullar için iyileştirilmemiştir.

Öğrenecekleriniz:

  • Bir klasördeki belirli sayfalara erişimi kısıtlama.
  • Anonim bir alışveriş sepetinden bilinen bir alışveriş sepeti oluşturma.
  • Proje için SSL'yi etkinleştirme.
  • Projeye OAuth sağlayıcısı ekleme.
  • PayPal test ortamını kullanarak ürün satın almak için PayPal'ı kullanma.
  • DetailsView denetiminde PayPal'dan ayrıntıları görüntüleme.
  • Wingtip Toys uygulamasının veritabanını PayPal'dan alınan ayrıntılarla güncelleştirme.

Sipariş İzleme Ekleme

Bu öğreticide, verileri kullanıcının oluşturduğu sırayla izlemek için iki yeni sınıf oluşturacaksınız. Sınıflar sevkiyat bilgileri, satın alma toplamı ve ödeme onayı ile ilgili verileri izler.

Order ve OrderDetail Model Sınıflarını Ekleme

Bu öğretici serisinin önceki bölümlerinde, Modeller klasöründe , Productve sınıflarını oluşturarak Categorykategoriler, ürünler ve CartItem alışveriş sepeti öğeleri için şema tanımlamıştınız. Şimdi ürün siparişinin şemasını ve siparişin ayrıntılarını tanımlamak için iki yeni sınıf ekleyebilirsiniz.

  1. Models klasörüne Order.cs adlı yeni bir sınıf ekleyin.
    Yeni sınıf dosyası düzenleyicide görüntülenir.

  2. Varsayılan kodu aşağıdakilerle değiştirin:

    using System;
    using System.ComponentModel.DataAnnotations;
    using System.Collections.Generic;
    using System.ComponentModel;
    
    namespace WingtipToys.Models
    {
      public class Order
      {
        public int OrderId { get; set; }
    
        public DateTime OrderDate { get; set; }
    
        public string Username { get; set; }
    
        [Required(ErrorMessage = "First Name is required")]
        [DisplayName("First Name")]
        [StringLength(160)]
        public string FirstName { get; set; }
    
        [Required(ErrorMessage = "Last Name is required")]
        [DisplayName("Last Name")]
        [StringLength(160)]
        public string LastName { get; set; }
    
        [Required(ErrorMessage = "Address is required")]
        [StringLength(70)]
        public string Address { get; set; }
    
        [Required(ErrorMessage = "City is required")]
        [StringLength(40)]
        public string City { get; set; }
    
        [Required(ErrorMessage = "State is required")]
        [StringLength(40)]
        public string State { get; set; }
    
        [Required(ErrorMessage = "Postal Code is required")]
        [DisplayName("Postal Code")]
        [StringLength(10)]
        public string PostalCode { get; set; }
    
        [Required(ErrorMessage = "Country is required")]
        [StringLength(40)]
        public string Country { get; set; }
    
        [StringLength(24)]
        public string Phone { get; set; }
    
        [Required(ErrorMessage = "Email Address is required")]
        [DisplayName("Email Address")]
        [RegularExpression(@"[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}",
            ErrorMessage = "Email is is not valid.")]
        [DataType(DataType.EmailAddress)]
        public string Email { get; set; }
    
        [ScaffoldColumn(false)]
        public decimal Total { get; set; }
    
        [ScaffoldColumn(false)]
        public string PaymentTransactionId { get; set; }
    
        [ScaffoldColumn(false)]
        public bool HasBeenShipped { get; set; }
    
        public List<OrderDetail> OrderDetails { get; set; }
      }
    }
    
  3. Models klasörüne bir OrderDetail.cs sınıfı ekleyin.

  4. Varsayılan kodu aşağıdaki kodla değiştirin:

    using System.ComponentModel.DataAnnotations;
    
    namespace WingtipToys.Models
    {
        public class OrderDetail
        {
            public int OrderDetailId { get; set; }
    
            public int OrderId { get; set; }
    
            public string Username { get; set; }
    
            public int ProductId { get; set; }
    
            public int Quantity { get; set; }
    
            public double? UnitPrice { get; set; }
    
        }
    }
    

Order ve OrderDetail sınıfları, satın alma ve sevkiyat için kullanılan sipariş bilgilerini tanımlayan şemayı içerir.

Ayrıca, varlık sınıflarını yöneten ve veritabanına veri erişimi sağlayan veritabanı bağlam sınıfını güncelleştirmeniz gerekir. Bunu yapmak için sınıfa yeni oluşturulan Order ve OrderDetail model sınıflarını ProductContext ekleyebilirsiniz.

  1. Çözüm Gezgini'daProductContext.cs dosyasını bulun ve açın.

  2. Aşağıda gösterildiği gibi vurgulanan kodu ProductContext.cs dosyasına ekleyin:

    using System.Data.Entity;
    
    namespace WingtipToys.Models
    {
      public class ProductContext : DbContext
      {
        public ProductContext()
          : base("WingtipToys")
        {
        }
        public DbSet<Category> Categories { get; set; }
        public DbSet<Product> Products { get; set; }
        public DbSet<CartItem> ShoppingCartItems { get; set; }
        public DbSet<Order> Orders { get; set; }
        public DbSet<OrderDetail> OrderDetails { get; set; }
      }
    }
    

Bu öğretici serisinde daha önce belirtildiği gibi , ProductContext.cs dosyasındaki kod, Entity Framework'ün tüm temel işlevlerine erişebilmeniz için ad alanını ekler System.Data.Entity . Bu işlevsellik, kesin olarak yazılan nesnelerle çalışarak verileri sorgulama, ekleme, güncelleştirme ve silme özelliğini içerir. sınıfındaki ProductContext yukarıdaki kod, yeni eklenen Order ve OrderDetail sınıflarına Entity Framework erişimi ekler.

Kullanıma Alma Erişimi Ekleme

Wingtip Toys örnek uygulaması anonim kullanıcıların ürünleri gözden geçirmesine ve alışveriş sepetine eklemesine olanak tanır. Ancak anonim kullanıcılar alışveriş sepetine ekledikleri ürünleri satın almayı seçtiklerinde sitede oturum açmaları gerekir. Oturum açtıktan sonra, web uygulamasının kullanıma alma ve satın alma işlemini işleyen kısıtlı sayfalarına erişebilirler. Bu kısıtlı sayfalar uygulamanın Kullanıma Alma klasöründe bulunur.

Kullanıma Alma Klasörü ve Sayfaları Ekleme

Şimdi kullanıma alma işlemi sırasında müşterinin göreceği Kullanıma Alma klasörünü ve içindeki sayfaları oluşturacaksınız. Bu öğreticinin ilerleyen bölümlerinde bu sayfaları güncelleştireceğiz.

  1. Çözüm Gezgini proje adına (Wingtip Toys) sağ tıklayın ve Yeni Klasör Ekle'yi seçin.

    PayPal ile Ödeme ve Ödeme - Yeni Klasör

  2. Yeni klasöre Kullanıma Alma adını verin.

  3. Kullanıma Alma klasörüne sağ tıklayın ve ardından Yeni>Öğe Ekle'yi seçin.

    PayPal ile Ödeme ve Ödeme - Yeni Öğe

  4. Yeni Öğe Ekle iletişim kutusu görüntülenir.

  5. Soldaki Visual C# ->Web şablonları grubunu seçin. Ardından, orta bölmeden Ana Sayfalı Web Formu'nuseçin ve CheckoutStart.aspx olarak adlandırın.

    PayPal ile Ödeme ve Ödeme - Yeni Öğe Ekle İletişim Kutusu

  6. Daha önce olduğu gibi, ana sayfa olarak Site.Master dosyasını seçin.

  7. Yukarıdaki adımları kullanarak Aşağıdaki ek sayfaları Kullanıma Alma klasörüne ekleyin:

    • CheckoutReview.aspx
    • CheckoutComplete.aspx
    • CheckoutCancel.aspx
    • CheckoutError.aspx

Web.config Dosyası Ekleme

Kullanıma Alma klasörüne yeni bir Web.config dosyası ekleyerek, klasördeki tüm sayfalara erişimi kısıtlayabilirsiniz.

  1. Kullanıma Alma klasörüne sağ tıklayın ve Ekle ->Yeni Öğe'yi seçin.
    Yeni Öğe Ekle iletişim kutusu görüntülenir.

  2. Soldaki Visual C# ->Web şablonları grubunu seçin. Ardından, orta bölmeden Web Yapılandırma Dosyası'nı seçin, varsayılanWeb.configadını kabul edin ve ekle'yi seçin.

  3. Web.config dosyasındaki mevcut XML içeriğini aşağıdakilerle değiştirin:

    <?xml version="1.0"?>
    <configuration>
      <system.web>
        <authorization>
          <deny users="?"/>
        </authorization>
      </system.web>
    </configuration>
    
  4. Web.config dosyasını kaydedin.

Web.config dosyası, Web uygulamasının tüm bilinmeyen kullanıcılarının Kullanıma Alma klasöründeki sayfalara erişiminin reddedilmesi gerektiğini belirtir. Ancak, kullanıcı bir hesap kaydettiyse ve oturum açtıysa, bilinen bir kullanıcı olur ve Kullanıma Alma klasöründeki sayfalara erişebilir.

ASP.NET yapılandırmasının, her Web.config dosyasının içinde bulunduğu klasöre ve altındaki tüm alt dizinlere yapılandırma ayarlarını uyguladığı bir hiyerarşi izlediğini unutmayın.

Proje için SSL'yi etkinleştirme

Güvenli Yuva Katmanı (SSL), Web sunucularının ve Web istemcilerinin şifreleme kullanarak daha güvenli bir şekilde iletişim kurmasını sağlamak için tanımlanan bir protokoldür. SSL kullanılmadığında, istemci ve sunucu arasında gönderilen veriler, ağa fiziksel erişimi olan herkes tarafından paket algılamaya açıktır. Ayrıca, bazı yaygın kimlik doğrulama düzenleri düz HTTP üzerinden güvenli değildir. Özellikle, Temel kimlik doğrulaması ve form kimlik doğrulaması şifrelenmemiş kimlik bilgileri gönderir. Bu kimlik doğrulama düzenlerinin güvenli olması için SSL kullanması gerekir.

  1. Çözüm Gezgini'daWingtipToys projesine tıklayın, ardından Özellikler penceresini görüntülemek için F4 tuşuna basın.
  2. SSL Etkin ayarını olarak truedeğiştirin.
  3. DAHA sonra kullanabilmek için SSL URL'sini kopyalayın.
    SSL URL'si, daha önce SSL Web Siteleri oluşturmadığınız sürece (aşağıda gösterildiği gibi) olacaktır https://localhost:44300/ .
    Proje Özellikleri
  4. Çözüm Gezgini'daWingtipToys projesine sağ tıklayın ve Özellikler'e tıklayın.
  5. Sol sekmede Web'e tıklayın.
  6. Daha önce kaydettiğiniz SSL URL'sini kullanmak için Proje Url'sini değiştirin.
    Project Web Özellikleri
  7. CTRL+S tuşlarına basarak sayfayı kaydedin.
  8. Uygulamayı çalıştırmak için Ctrl+F5 tuşlarına basın. Visual Studio, SSL uyarılarından kaçınmanıza olanak sağlayan bir seçenek görüntüler.
  9. IIS Express SSL sertifikasına güvenmek ve devam etmek için Evet'e tıklayın.
    SSL sertifikası ayrıntılarını IIS Express
    Bir Güvenlik Uyarısı görüntülenir.
  10. Sertifikayı localhost'unuza yüklemek için Evet'e tıklayın.
    Güvenlik Uyarısı iletişim kutusu
    Tarayıcı penceresi görüntülenir.

Artık SSL kullanarak Web uygulamanızı kolayca yerel olarak test edebilirsiniz.

OAuth 2.0 Sağlayıcısı Ekleme

ASP.NET Web Forms üyelik ve kimlik doğrulaması için gelişmiş seçenekler sağlar. Bu geliştirmeler OAuth'u içerir. OAuth, web, mobil ve masaüstü uygulamalarından basit ve standart bir yöntemle güvenli yetkilendirmeye olanak tanıyan açık bir protokoldür. ASP.NET Web Forms şablonu kimlik doğrulama sağlayıcıları olarak Facebook, Twitter, Google ve Microsoft'u kullanıma açmak için OAuth kullanır. Bu öğreticide kimlik doğrulama sağlayıcısı olarak yalnızca Google kullanılıyor olsa da, kodu herhangi bir sağlayıcıyı kullanacak şekilde kolayca değiştirebilirsiniz. Diğer sağlayıcıları uygulama adımları, bu öğreticide göreceğiniz adımlara çok benzer.

Kimlik doğrulamasına ek olarak, öğretici yetkilendirmeyi uygulamak için rolleri de kullanır. Yalnızca role eklediğiniz canEdit kullanıcılar verileri değiştirebilir (kişi oluşturma, düzenleme veya silme).

Not

Windows Live uygulamaları yalnızca çalışan bir web sitesi için canlı URL kabul eder, bu nedenle oturum açma bilgilerini test etmek için yerel web sitesi URL'sini kullanamazsınız.

Aşağıdaki adımlar bir Google kimlik doğrulama sağlayıcısı eklemenize olanak sağlar.

  1. App_Start\Startup.Auth.cs dosyasını açın.

  2. Yöntemin aşağıdaki gibi görünmesi için yöntemden app.UseGoogleAuthentication() açıklama karakterlerini kaldırın:

    app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions()
    {
        ClientId = "",
        ClientSecret = ""
    });
    
  3. Google Developers Console'a gidin. Ayrıca Google geliştirici e-posta hesabınızla (gmail.com) oturum açmanız gerekir. Google hesabınız yoksa Hesap oluştur bağlantısını seçin.
    Ardından Google Developers Console'u göreceksiniz.
    Google Developers Console

  4. Proje Oluştur düğmesine tıklayın ve bir proje adı ve kimliği girin (varsayılan değerleri kullanabilirsiniz). Ardından sözleşme onay kutusuna ve Oluştur düğmesine tıklayın.

    Google - Yeni Proje

    Birkaç saniye içinde yeni proje oluşturulur ve tarayıcınız yeni projeler sayfasını görüntüler.

  5. Sol sekmede, kimlik doğrulaması & API'ler'e ve ardından Kimlik Bilgileri'ne tıklayın.

  6. OAuth altında Yeni İstemci Kimliği Oluştur'a tıklayın.
    İstemci Kimliği Oluştur iletişim kutusu görüntülenir.
    Google - İstemci Kimliği Oluşturma

  7. İstemci Kimliği Oluştur iletişim kutusunda, uygulama türü için varsayılan Web uygulamasını tutun.

  8. Yetkili JavaScript Kaynakları'nı bu öğreticide daha önce kullandığınız SSL URL'sine ayarlayın (https://localhost:44300/başka SSL projeleri oluşturmadıysanız).
    Bu URL, uygulamanızın kaynağıdır. Bu örnek için yalnızca localhost test URL'sini girersiniz. Ancak, localhost ve üretim için birden çok URL girebilirsiniz.

  9. Yetkili Yeniden Yönlendirme URI'sini aşağıdakine ayarlayın:

    https://localhost:44300/signin-google
    

    Bu değer, OAuth kullanıcılarının google OAuth sunucusuyla iletişim kurmasını ASP.NET URI'dir. Yukarıda kullandığınız SSL URL'sini unutmayın ( https://localhost:44300/ başka SSL projeleri oluşturmadıysanız).

  10. İstemci Kimliği Oluştur düğmesine tıklayın.

  11. Google Developers Console'un sol menüsünde Onay ekranı menü öğesine tıklayın, ardından e-posta adresinizi ve ürün adınızı ayarlayın. Formu tamamladığınızda Kaydet'e tıklayın.

  12. API'ler menü öğesine tıklayın, aşağı kaydırın ve Google+ API'sinin yanındaki kapalı düğmesine tıklayın.
    Bu seçeneği kabul etmek Google+ API'sini etkinleştirir.

  13. Ayrıca Microsoft.Owin NuGet paketini 3.0.0 sürümüne güncelleştirmeniz gerekir.
    Araçlar menüsünde NuGet Paket Yöneticisi'ni ve ardından Çözüm için NuGet Paketlerini Yönet'i seçin.
    NuGet Paketlerini Yönet penceresinde Microsoft.Owin paketini bulun ve sürüm 3.0.0'a güncelleştirin.

  14. Visual Studio'da, İstemci Kimliği ve İstemci Gizli Anahtarı'nı kopyalayıp yöntemine yapıştırarak Startup.Auth.cs sayfasının yöntemini güncelleştirinUseGoogleAuthentication. Aşağıda gösterilen İstemci Kimliği ve gizli anahtar değerleri örneklerdir ve çalışmaz.

    using System;
    using Microsoft.AspNet.Identity;
    using Microsoft.AspNet.Identity.EntityFramework;
    using Microsoft.AspNet.Identity.Owin;
    using Microsoft.Owin;
    using Microsoft.Owin.Security.Cookies;
    using Microsoft.Owin.Security.DataProtection;
    using Microsoft.Owin.Security.Google;
    using Owin;
    using WingtipToys.Models;
    
    namespace WingtipToys
    {
        public partial class Startup {
    
            // For more information on configuring authentication, please visit https://go.microsoft.com/fwlink/?LinkId=301883
            public void ConfigureAuth(IAppBuilder app)
            {
                // Configure the db context, user manager and signin manager to use a single instance per request
                app.CreatePerOwinContext(ApplicationDbContext.Create);
                app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
                app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);
    
                // Enable the application to use a cookie to store information for the signed in user
                // and to use a cookie to temporarily store information about a user logging in with a third party login provider
                // Configure the sign in cookie
                app.UseCookieAuthentication(new CookieAuthenticationOptions
                {
                    AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
                    LoginPath = new PathString("/Account/Login"),
                    Provider = new CookieAuthenticationProvider
                    {
                        OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
                            validateInterval: TimeSpan.FromMinutes(30),
                            regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
                    }
                });
                // Use a cookie to temporarily store information about a user logging in with a third party login provider
                app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
    
                // Enables the application to temporarily store user information when they are verifying the second factor in the two-factor authentication process.
                app.UseTwoFactorSignInCookie(DefaultAuthenticationTypes.TwoFactorCookie, TimeSpan.FromMinutes(5));
    
                // Enables the application to remember the second login verification factor such as phone or email.
                // Once you check this option, your second step of verification during the login process will be remembered on the device where you logged in from.
                // This is similar to the RememberMe option when you log in.
                app.UseTwoFactorRememberBrowserCookie(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie);
    
                // Uncomment the following lines to enable logging in with third party login providers
                //app.UseMicrosoftAccountAuthentication(
                //    clientId: "",
                //    clientSecret: "");
    
                //app.UseTwitterAuthentication(
                //   consumerKey: "",
                //   consumerSecret: "");
    
                //app.UseFacebookAuthentication(
                //   appId: "",
                //   appSecret: "");
    
                app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions()
                {
                  ClientId = "000000000000.apps.googleusercontent.com",
                  ClientSecret = "00000000000"
                });
            }
        }
    }
    
  15. Uygulamayı derlemek ve çalıştırmak için CTRL+F5 tuşlarına basın. Oturum aç bağlantısına tıklayın.

  16. Oturum açmak için başka bir hizmet kullan'ın altında Google'a tıklayın.
    Oturum aç

  17. Kimlik bilgilerinizi girmeniz gerekirse, kimlik bilgilerinizi gireceğiniz google sitesine yönlendirilirsiniz.
    Google - Oturum açma

  18. Kimlik bilgilerinizi girdikten sonra, yeni oluşturduğunuz web uygulamasına izin vermeniz istenir.
    Project Varsayılan Hizmet Hesabı

  19. Kabul et'e tıklayın. Artık Google hesabınızı kaydedebileceğiniz WingtipToys uygulamasının Kayıt sayfasına geri yönlendirilirsiniz.
    Google Hesabınıza kaydolun

  20. Gmail hesabınız için kullanılan yerel e-posta kayıt adını değiştirme seçeneğiniz vardır, ancak genellikle varsayılan e-posta diğer adını (kimlik doğrulaması için kullandığınız diğer ad) tutmak istersiniz. Yukarıda gösterildiği gibi oturum aç'a tıklayın.

Oturum Açma İşlevselliğini Değiştirme

Bu öğretici serisinde daha önce belirtildiği gibi, kullanıcı kaydı işlevlerinin çoğu varsayılan olarak ASP.NET Web Forms şablonuna dahil edilmiştir. Şimdi varsayılan Login.aspx ve Register.aspx sayfalarını yöntemini çağıracak MigrateCart şekilde değiştireceksiniz. yöntemi, MigrateCart yeni oturum açmış bir kullanıcıyı anonim bir alışveriş sepetiyle ilişkilendirir. Wingtip Toys örnek uygulaması, kullanıcıyla alışveriş sepetini ilişkilendirerek ziyaretler arasında kullanıcının alışveriş sepetini koruyabilir.

  1. Çözüm Gezgini'daHesap klasörünü bulun ve açın.

  2. Login.aspx.cs adlı arka planda kod sayfasını sarı renkle vurgulanan kodu içerecek şekilde değiştirin; böylece aşağıdaki gibi görünür:

    using System;
    using System.Web;
    using System.Web.UI;
    using Microsoft.AspNet.Identity;
    using Microsoft.AspNet.Identity.Owin;
    using Owin;
    using WingtipToys.Models;
    
    namespace WingtipToys.Account
    {
        public partial class Login : Page
        {
            protected void Page_Load(object sender, EventArgs e)
            {
                RegisterHyperLink.NavigateUrl = "Register";
                // Enable this once you have account confirmation enabled for password reset functionality
                //ForgotPasswordHyperLink.NavigateUrl = "Forgot";
                OpenAuthLogin.ReturnUrl = Request.QueryString["ReturnUrl"];
                var returnUrl = HttpUtility.UrlEncode(Request.QueryString["ReturnUrl"]);
                if (!String.IsNullOrEmpty(returnUrl))
                {
                    RegisterHyperLink.NavigateUrl += "?ReturnUrl=" + returnUrl;
                }
            }
    
            protected void LogIn(object sender, EventArgs e)
            {
                if (IsValid)
                {
                    // Validate the user password
                    var manager = Context.GetOwinContext().GetUserManager<ApplicationUserManager>();
                    var signinManager = Context.GetOwinContext().GetUserManager<ApplicationSignInManager>();
    
                    // This doen't count login failures towards account lockout
                    // To enable password failures to trigger lockout, change to shouldLockout: true
                    var result = signinManager.PasswordSignIn(Email.Text, Password.Text, RememberMe.Checked, shouldLockout: false);
    
                    switch (result)
                    {
                        case SignInStatus.Success:
                            WingtipToys.Logic.ShoppingCartActions usersShoppingCart = new WingtipToys.Logic.ShoppingCartActions();
                            String cartId = usersShoppingCart.GetCartId();
                            usersShoppingCart.MigrateCart(cartId, Email.Text);
    
                            IdentityHelper.RedirectToReturnUrl(Request.QueryString["ReturnUrl"], Response);
                            break;
                        case SignInStatus.LockedOut:
                            Response.Redirect("/Account/Lockout");
                            break;
                        case SignInStatus.RequiresVerification:
                            Response.Redirect(String.Format("/Account/TwoFactorAuthenticationSignIn?ReturnUrl={0}&RememberMe={1}", 
                                                            Request.QueryString["ReturnUrl"],
                                                            RememberMe.Checked),
                                              true);
                            break;
                        case SignInStatus.Failure:
                        default:
                            FailureText.Text = "Invalid login attempt";
                            ErrorMessage.Visible = true;
                            break;
                    }
                }
            }
        }
    }
    
  3. Login.aspx.cs dosyasını kaydedin.

Şimdilik, yöntemi için tanım olmadığına ilişkin uyarıyı MigrateCart yoksayabilirsiniz. Bu öğreticinin ilerleyen bölümlerinde ekleyebilirsiniz.

Login.aspx.cs arka planda kod dosyası LogIn yöntemini destekler. Login.aspx sayfasını inceleyerek, bu sayfada tıklandığında arka planda işleyiciyi LogIn tetikleyen bir "Oturum aç" düğmesi olduğunu görürsünüz.

Login.aspx.cs dosyasındaki Login yöntemi çağrıldığında adlı alışveriş sepetinin usersShoppingCart yeni bir örneği oluşturulur. Alışveriş sepetinin kimliği (GUID) alınır ve değişkenine cartId ayarlanır. Ardından yöntemi MigrateCart çağrılır ve hem hem de cartId oturum açmış kullanıcının adı bu yönteme geçirilir. Alışveriş sepeti geçirildiğinde, anonim alışveriş sepetini tanımlamak için kullanılan GUID kullanıcı adıyla değiştirilir.

Kullanıcı oturum açtığında alışveriş sepetini geçirmek için Login.aspx.cs arka planda kod dosyasını değiştirmenin yanı sıra, kullanıcı yeni bir hesap oluşturup oturum açtığında alışveriş sepetini geçirmek için Register.aspx.cs arka planda kod dosyasını da değiştirmeniz gerekir.

  1. Hesap klasöründe Register.aspx.cs adlı arka planda kod dosyasını açın.

  2. Kodu sarı renkle ekleyerek arka planda kod dosyasını değiştirin; böylece aşağıdaki gibi görünür:

    using System;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using Microsoft.AspNet.Identity;
    using Microsoft.AspNet.Identity.Owin;
    using Owin;
    using WingtipToys.Models;
    
    namespace WingtipToys.Account
    {
        public partial class Register : Page
        {
            protected void CreateUser_Click(object sender, EventArgs e)
            {
                var manager = Context.GetOwinContext().GetUserManager<ApplicationUserManager>();
                var user = new ApplicationUser() { UserName = Email.Text, Email = Email.Text };
                IdentityResult result = manager.Create(user, Password.Text);
                if (result.Succeeded)
                {
                    // For more information on how to enable account confirmation and password reset please visit https://go.microsoft.com/fwlink/?LinkID=320771
                    //string code = manager.GenerateEmailConfirmationToken(user.Id);
                    //string callbackUrl = IdentityHelper.GetUserConfirmationRedirectUrl(code, user.Id, Request);
                    //manager.SendEmail(user.Id, "Confirm your account", "Please confirm your account by clicking <a href=\"" + callbackUrl + "\">here</a>.");
    
                    IdentityHelper.SignIn(manager, user, isPersistent: false);
    
                    using (WingtipToys.Logic.ShoppingCartActions usersShoppingCart = new WingtipToys.Logic.ShoppingCartActions())
                    {
                      String cartId = usersShoppingCart.GetCartId();
                      usersShoppingCart.MigrateCart(cartId, user.Id);
                    }
    
                    IdentityHelper.RedirectToReturnUrl(Request.QueryString["ReturnUrl"], Response);
                }
                else 
                {
                    ErrorMessage.Text = result.Errors.FirstOrDefault();
                }
            }
        }
    }
    
  3. Register.aspx.cs dosyasını kaydedin. Bir kez daha yöntemle ilgili uyarıyı yoksayın MigrateCart .

Olay işleyicisinde kullandığınız kodun CreateUser_Click yönteminde LogIn kullandığınız koda çok benzer olduğuna dikkat edin. Kullanıcı siteye kaydolduğunda veya oturum açtığında, yöntemine MigrateCart bir çağrı yapılır.

Alışveriş Sepetini Geçirme

Artık oturum açma ve kayıt işlemini güncelleştirdiğinize göre, yöntemini kullanarak MigrateCart alışveriş sepetini geçirmek için kodu ekleyebilirsiniz.

  1. Çözüm Gezgini'daLogic klasörünü bulun ve ShoppingCartActions.cs sınıf dosyasını açın.

  2. ShoppingCartActions.cs dosyasındaki kodun aşağıdaki gibi görünmesi için ShoppingCartActions.cs dosyasındaki mevcut koda sarı renkle vurgulanan kodu ekleyin:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using WingtipToys.Models;
    
    namespace WingtipToys.Logic
    {
      public class ShoppingCartActions : IDisposable
      {
        public string ShoppingCartId { get; set; }
    
        private ProductContext _db = new ProductContext();
    
        public const string CartSessionKey = "CartId";
    
        public void AddToCart(int id)
        {
          // Retrieve the product from the database.           
          ShoppingCartId = GetCartId();
    
          var cartItem = _db.ShoppingCartItems.SingleOrDefault(
              c => c.CartId == ShoppingCartId
              && c.ProductId == id);
          if (cartItem == null)
          {
            // Create a new cart item if no cart item exists.                 
            cartItem = new CartItem
            {
              ItemId = Guid.NewGuid().ToString(),
              ProductId = id,
              CartId = ShoppingCartId,
              Product = _db.Products.SingleOrDefault(
               p => p.ProductID == id),
              Quantity = 1,
              DateCreated = DateTime.Now
            };
    
            _db.ShoppingCartItems.Add(cartItem);
          }
          else
          {
            // If the item does exist in the cart,                  
            // then add one to the quantity.                 
            cartItem.Quantity++;
          }
          _db.SaveChanges();
        }
    
        public void Dispose()
        {
          if (_db != null)
          {
            _db.Dispose();
            _db = null;
          }
        }
    
        public string GetCartId()
        {
          if (HttpContext.Current.Session[CartSessionKey] == null)
          {
            if (!string.IsNullOrWhiteSpace(HttpContext.Current.User.Identity.Name))
            {
              HttpContext.Current.Session[CartSessionKey] = HttpContext.Current.User.Identity.Name;
            }
            else
            {
              // Generate a new random GUID using System.Guid class.     
              Guid tempCartId = Guid.NewGuid();
              HttpContext.Current.Session[CartSessionKey] = tempCartId.ToString();
            }
          }
          return HttpContext.Current.Session[CartSessionKey].ToString();
        }
    
        public List<CartItem> GetCartItems()
        {
          ShoppingCartId = GetCartId();
    
          return _db.ShoppingCartItems.Where(
              c => c.CartId == ShoppingCartId).ToList();
        }
    
        public decimal GetTotal()
        {
          ShoppingCartId = GetCartId();
          // Multiply product price by quantity of that product to get        
          // the current price for each of those products in the cart.  
          // Sum all product price totals to get the cart total.   
          decimal? total = decimal.Zero;
          total = (decimal?)(from cartItems in _db.ShoppingCartItems
                             where cartItems.CartId == ShoppingCartId
                             select (int?)cartItems.Quantity *
                             cartItems.Product.UnitPrice).Sum();
          return total ?? decimal.Zero;
        }
    
        public ShoppingCartActions GetCart(HttpContext context)
        {
          using (var cart = new ShoppingCartActions())
          {
            cart.ShoppingCartId = cart.GetCartId();
            return cart;
          }
        }
    
        public void UpdateShoppingCartDatabase(String cartId, ShoppingCartUpdates[] CartItemUpdates)
        {
          using (var db = new WingtipToys.Models.ProductContext())
          {
            try
            {
              int CartItemCount = CartItemUpdates.Count();
              List<CartItem> myCart = GetCartItems();
              foreach (var cartItem in myCart)
              {
                // Iterate through all rows within shopping cart list
                for (int i = 0; i < CartItemCount; i++)
                {
                  if (cartItem.Product.ProductID == CartItemUpdates[i].ProductId)
                  {
                    if (CartItemUpdates[i].PurchaseQuantity < 1 || CartItemUpdates[i].RemoveItem == true)
                    {
                      RemoveItem(cartId, cartItem.ProductId);
                    }
                    else
                    {
                      UpdateItem(cartId, cartItem.ProductId, CartItemUpdates[i].PurchaseQuantity);
                    }
                  }
                }
              }
            }
            catch (Exception exp)
            {
              throw new Exception("ERROR: Unable to Update Cart Database - " + exp.Message.ToString(), exp);
            }
          }
        }
    
        public void RemoveItem(string removeCartID, int removeProductID)
        {
          using (var _db = new WingtipToys.Models.ProductContext())
          {
            try
            {
              var myItem = (from c in _db.ShoppingCartItems where c.CartId == removeCartID && c.Product.ProductID == removeProductID select c).FirstOrDefault();
              if (myItem != null)
              {
                // Remove Item.
                _db.ShoppingCartItems.Remove(myItem);
                _db.SaveChanges();
              }
            }
            catch (Exception exp)
            {
              throw new Exception("ERROR: Unable to Remove Cart Item - " + exp.Message.ToString(), exp);
            }
          }
        }
    
        public void UpdateItem(string updateCartID, int updateProductID, int quantity)
        {
          using (var _db = new WingtipToys.Models.ProductContext())
          {
            try
            {
              var myItem = (from c in _db.ShoppingCartItems where c.CartId == updateCartID && c.Product.ProductID == updateProductID select c).FirstOrDefault();
              if (myItem != null)
              {
                myItem.Quantity = quantity;
                _db.SaveChanges();
              }
            }
            catch (Exception exp)
            {
              throw new Exception("ERROR: Unable to Update Cart Item - " + exp.Message.ToString(), exp);
            }
          }
        }
    
        public void EmptyCart()
        {
          ShoppingCartId = GetCartId();
          var cartItems = _db.ShoppingCartItems.Where(
              c => c.CartId == ShoppingCartId);
          foreach (var cartItem in cartItems)
          {
            _db.ShoppingCartItems.Remove(cartItem);
          }
          // Save changes.             
          _db.SaveChanges();
        }
    
        public int GetCount()
        {
          ShoppingCartId = GetCartId();
    
          // Get the count of each item in the cart and sum them up          
          int? count = (from cartItems in _db.ShoppingCartItems
                        where cartItems.CartId == ShoppingCartId
                        select (int?)cartItems.Quantity).Sum();
          // Return 0 if all entries are null         
          return count ?? 0;
        }
    
        public struct ShoppingCartUpdates
        {
          public int ProductId;
          public int PurchaseQuantity;
          public bool RemoveItem;
        }
    
        public void MigrateCart(string cartId, string userName)
        {
          var shoppingCart = _db.ShoppingCartItems.Where(c => c.CartId == cartId);
          foreach (CartItem item in shoppingCart)
          {
            item.CartId = userName;
          }
          HttpContext.Current.Session[CartSessionKey] = userName;
          _db.SaveChanges();
        }
      }
    }
    

yöntemi, MigrateCart kullanıcının alışveriş sepetini bulmak için mevcut cartId değerini kullanır. Ardından, kod tüm alışveriş sepeti öğelerinde döngü oluşturur ve özelliğini (şema tarafından CartItem belirtildiği gibi) oturum açmış kullanıcı adıyla değiştirirCartId.

Veritabanı Bağlantısını Güncelleştirme

Önceden oluşturulmuş Wingtip Toys örnek uygulamasını kullanarak bu öğreticiyi takip ediyorsanız, varsayılan üyelik veritabanını yeniden oluşturmanız gerekir. Varsayılan bağlantı dizesi değiştirilerek, uygulama bir sonraki çalıştırıldığında üyelik veritabanı oluşturulur.

  1. Projenin kökündeki Web.config dosyasını açın.

  2. Varsayılan bağlantı dizesi aşağıdaki gibi görünecek şekilde güncelleştirin:

    <add name="DefaultConnection" connectionString="Data Source=(LocalDb)\MSSQLLocalDB;Initial Catalog=aspnet-WingtipToys;Integrated Security=True" providerName="System.Data.SqlClient" />
    

PayPal'i tümleştirme

PayPal, çevrimiçi satıcıların ödemelerini kabul eden web tabanlı bir faturalama platformudur. Bu öğreticide, PayPal'ın Express Checkout işlevini uygulamanızla tümleştirme işlemi açıklanır. Hızlı Ödeme, müşterilerinizin alışveriş sepetlerine ekledikleri ürünler için ödeme yapmak için PayPal kullanmasına olanak tanır.

PayPal Test Hesapları Oluşturma

PayPal test ortamını kullanmak için bir geliştirici test hesabı oluşturup doğrulamanız gerekir. Geliştirici test hesabını kullanarak bir alıcı test hesabı ve bir satıcı test hesabı oluşturacaksınız. Geliştirici test hesabı kimlik bilgileri, Wingtip Toys örnek uygulamasının PayPal test ortamına erişmesine de olanak tanır.

  1. Tarayıcıda PayPal geliştirici testi sitesine gidin:
    https://developer.paypal.com

  2. PayPal geliştirici hesabınız yoksa Kaydol'a tıklayıp kaydolmaadımlarını izleyerek yeni bir hesap oluşturun. Mevcut bir PayPal geliştirici hesabınız varsa Oturum Aç'a tıklayarak oturum açın. Bu öğreticinin devamında Wingtip Toys örnek uygulamasını test etmek için PayPal geliştirici hesabınıza ihtiyacınız olacaktır.

  3. PayPal geliştirici hesabınıza yeni kaydoldıysanız PayPal geliştirici hesabınızı PayPal ile doğrulamanız gerekebilir. PayPal'ın e-posta hesabınıza gönderdiği adımları izleyerek hesabınızı doğrulayabilirsiniz. PayPal geliştirici hesabınızı doğruladıktan sonra PayPal geliştirici testi sitesinde yeniden oturum açın.

  4. PayPal geliştirici hesabınızla PayPal geliştirici sitesinde oturum açtıktan sonra, henüz yoksa bir PayPal alıcı testi hesabı oluşturmanız gerekir. Alıcı test hesabı oluşturmak için PayPal sitesinde Uygulamalar sekmesine ve ardından Korumalı alan hesapları'na tıklayın.
    Korumalı alan test hesapları sayfası gösterilir.

    Not

    PayPal Geliştirici sitesi zaten bir satıcı test hesabı sağlar.

    Uygulamalar sekmesinin vurgulandığı Korumalı alan test hesapları sayfasını gösteren ekran görüntüsü.

  5. Korumalı alan test hesapları sayfasında Hesap Oluştur'a tıklayın.

  6. Test hesabı oluştur sayfasında, seçtiğiniz bir alıcı test hesabı e-postası ve parolası seçin.

    Not

    Bu öğreticinin sonunda Wingtip Toys örnek uygulamasını test etmek için alıcı e-posta adreslerine ve parolasına ihtiyacınız olacaktır.

    Oluşturulan hesabın alanlarını görüntüleyen Test hesabı oluştur sayfasının ekran görüntüsü.

  7. Hesap Oluştur düğmesine tıklayarak alıcı test hesabını oluşturun.
    Korumalı Alan Testi hesapları sayfası görüntülenir.

    PayPal ile Ödeme ve Ödeme - PayPal Hesapları

  8. Korumalı alan test hesapları sayfasında kolaylaştırıcı e-posta hesabına tıklayın.
    Profil ve Bildirim seçenekleri görüntülenir.

  9. Profil seçeneğini belirleyin, ardından satıcı test hesabına ilişkin API kimlik bilgilerinizi görüntülemek için API kimlik bilgileri'ne tıklayın.

  10. TEST API'sinin kimlik bilgilerini not defterine kopyalayın.

Wingtip Toys örnek uygulamasından PayPal test ortamına API çağrıları yapmak için görüntülenen Klasik TEST API'sinin kimlik bilgilerine (Kullanıcı adı, Parola ve İmza) ihtiyacınız olacaktır. Kimlik bilgilerini sonraki adımda ekleyebilirsiniz.

PayPal Sınıfı ve API Kimlik Bilgileri Ekleme

PayPal kodunun büyük bölümünü tek bir sınıfa yerleştirebilirsiniz. Bu sınıf PayPal ile iletişim kurmak için kullanılan yöntemleri içerir. Ayrıca PayPal kimlik bilgilerinizi de bu sınıfa ekleyebilirsiniz.

  1. Visual Studio'daki Wingtip Toys örnek uygulamasında Logic klasörüne sağ tıklayın ve ardından Ekle ->Yeni Öğe'yi seçin.
    Yeni Öğe Ekle iletişim kutusu görüntülenir.

  2. Soldaki Yüklü bölmesindeki Visual C# altında Kod'u seçin.

  3. Orta bölmeden Sınıf'ı seçin. Bu yeni sınıfa PayPalFunctions.cs adını verin.

  4. Ekle'ye tıklayın.
    Yeni sınıf dosyası düzenleyicide görüntülenir.

  5. Varsayılan kodu aşağıdaki kodla değiştirin:

    using System;
    using System.Collections;
    using System.Collections.Specialized;
    using System.IO;
    using System.Net;
    using System.Text;
    using System.Data;
    using System.Configuration;
    using System.Web;
    using WingtipToys;
    using WingtipToys.Models;
    using System.Collections.Generic;
    using System.Linq;
    
    public class NVPAPICaller
    {
      //Flag that determines the PayPal environment (live or sandbox)
      private const bool bSandbox = true;
      private const string CVV2 = "CVV2";
    
      // Live strings.
      private string pEndPointURL = "https://api-3t.paypal.com/nvp";
      private string host = "www.paypal.com";
    
      // Sandbox strings.
      private string pEndPointURL_SB = "https://api-3t.sandbox.paypal.com/nvp";
      private string host_SB = "www.sandbox.paypal.com";
    
      private const string SIGNATURE = "SIGNATURE";
      private const string PWD = "PWD";
      private const string ACCT = "ACCT";
    
      //Replace <Your API Username> with your API Username
      //Replace <Your API Password> with your API Password
      //Replace <Your Signature> with your Signature
      public string APIUsername = "<Your API Username>";
      private string APIPassword = "<Your API Password>";
      private string APISignature = "<Your Signature>";
      private string Subject = "";
      private string BNCode = "PP-ECWizard";
    
      //HttpWebRequest Timeout specified in milliseconds 
      private const int Timeout = 15000;
      private static readonly string[] SECURED_NVPS = new string[] { ACCT, CVV2, SIGNATURE, PWD };
    
      public void SetCredentials(string Userid, string Pwd, string Signature)
      {
        APIUsername = Userid;
        APIPassword = Pwd;
        APISignature = Signature;
      }
    
      public bool ShortcutExpressCheckout(string amt, ref string token, ref string retMsg)
      {
        if (bSandbox)
        {
          pEndPointURL = pEndPointURL_SB;
          host = host_SB;
        }
    
        string returnURL = "https://localhost:44300/Checkout/CheckoutReview.aspx";
        string cancelURL = "https://localhost:44300/Checkout/CheckoutCancel.aspx";
    
        NVPCodec encoder = new NVPCodec();
        encoder["METHOD"] = "SetExpressCheckout";
        encoder["RETURNURL"] = returnURL;
        encoder["CANCELURL"] = cancelURL;
        encoder["BRANDNAME"] = "Wingtip Toys Sample Application";
        encoder["PAYMENTREQUEST_0_AMT"] = amt;
        encoder["PAYMENTREQUEST_0_ITEMAMT"] = amt;
        encoder["PAYMENTREQUEST_0_PAYMENTACTION"] = "Sale";
        encoder["PAYMENTREQUEST_0_CURRENCYCODE"] = "USD";
    
        // Get the Shopping Cart Products
        using (WingtipToys.Logic.ShoppingCartActions myCartOrders = new WingtipToys.Logic.ShoppingCartActions())
        {
          List<CartItem> myOrderList = myCartOrders.GetCartItems();
    
          for (int i = 0; i < myOrderList.Count; i++)
          {
            encoder["L_PAYMENTREQUEST_0_NAME" + i] = myOrderList[i].Product.ProductName.ToString();
            encoder["L_PAYMENTREQUEST_0_AMT" + i] = myOrderList[i].Product.UnitPrice.ToString();
            encoder["L_PAYMENTREQUEST_0_QTY" + i] = myOrderList[i].Quantity.ToString();
          }
        }
    
        string pStrrequestforNvp = encoder.Encode();
        string pStresponsenvp = HttpCall(pStrrequestforNvp);
    
        NVPCodec decoder = new NVPCodec();
        decoder.Decode(pStresponsenvp);
    
        string strAck = decoder["ACK"].ToLower();
        if (strAck != null && (strAck == "success" || strAck == "successwithwarning"))
        {
          token = decoder["TOKEN"];
          string ECURL = "https://" + host + "/cgi-bin/webscr?cmd=_express-checkout" + "&token=" + token;
          retMsg = ECURL;
          return true;
        }
        else
        {
          retMsg = "ErrorCode=" + decoder["L_ERRORCODE0"] + "&" +
              "Desc=" + decoder["L_SHORTMESSAGE0"] + "&" +
              "Desc2=" + decoder["L_LONGMESSAGE0"];
          return false;
        }
      }
    
      public bool GetCheckoutDetails(string token, ref string PayerID, ref NVPCodec decoder, ref string retMsg)
      {
        if (bSandbox)
        {
          pEndPointURL = pEndPointURL_SB;
        }
    
        NVPCodec encoder = new NVPCodec();
        encoder["METHOD"] = "GetExpressCheckoutDetails";
        encoder["TOKEN"] = token;
    
        string pStrrequestforNvp = encoder.Encode();
        string pStresponsenvp = HttpCall(pStrrequestforNvp);
    
        decoder = new NVPCodec();
        decoder.Decode(pStresponsenvp);
    
        string strAck = decoder["ACK"].ToLower();
        if (strAck != null && (strAck == "success" || strAck == "successwithwarning"))
        {
          PayerID = decoder["PAYERID"];
          return true;
        }
        else
        {
          retMsg = "ErrorCode=" + decoder["L_ERRORCODE0"] + "&" +
              "Desc=" + decoder["L_SHORTMESSAGE0"] + "&" +
              "Desc2=" + decoder["L_LONGMESSAGE0"];
    
          return false;
        }
      }
    
      public bool DoCheckoutPayment(string finalPaymentAmount, string token, string PayerID, ref NVPCodec decoder, ref string retMsg)
      {
        if (bSandbox)
        {
          pEndPointURL = pEndPointURL_SB;
        }
    
        NVPCodec encoder = new NVPCodec();
        encoder["METHOD"] = "DoExpressCheckoutPayment";
        encoder["TOKEN"] = token;
        encoder["PAYERID"] = PayerID;
        encoder["PAYMENTREQUEST_0_AMT"] = finalPaymentAmount;
        encoder["PAYMENTREQUEST_0_CURRENCYCODE"] = "USD";
        encoder["PAYMENTREQUEST_0_PAYMENTACTION"] = "Sale";
    
        string pStrrequestforNvp = encoder.Encode();
        string pStresponsenvp = HttpCall(pStrrequestforNvp);
    
        decoder = new NVPCodec();
        decoder.Decode(pStresponsenvp);
    
        string strAck = decoder["ACK"].ToLower();
        if (strAck != null && (strAck == "success" || strAck == "successwithwarning"))
        {
          return true;
        }
        else
        {
          retMsg = "ErrorCode=" + decoder["L_ERRORCODE0"] + "&" +
              "Desc=" + decoder["L_SHORTMESSAGE0"] + "&" +
              "Desc2=" + decoder["L_LONGMESSAGE0"];
    
          return false;
        }
      }
    
      public string HttpCall(string NvpRequest)
      {
        string url = pEndPointURL;
    
        string strPost = NvpRequest + "&" + buildCredentialsNVPString();
        strPost = strPost + "&BUTTONSOURCE=" + HttpUtility.UrlEncode(BNCode);
    
        HttpWebRequest objRequest = (HttpWebRequest)WebRequest.Create(url);
        objRequest.Timeout = Timeout;
        objRequest.Method = "POST";
        objRequest.ContentLength = strPost.Length;
    
        try
        {
          using (StreamWriter myWriter = new StreamWriter(objRequest.GetRequestStream()))
          {
            myWriter.Write(strPost);
          }
        }
        catch (Exception)
        {
          // No logging for this tutorial.
        }
    
        //Retrieve the Response returned from the NVP API call to PayPal.
        HttpWebResponse objResponse = (HttpWebResponse)objRequest.GetResponse();
        string result;
        using (StreamReader sr = new StreamReader(objResponse.GetResponseStream()))
        {
          result = sr.ReadToEnd();
        }
    
        return result;
      }
    
      private string buildCredentialsNVPString()
      {
        NVPCodec codec = new NVPCodec();
    
        if (!IsEmpty(APIUsername))
          codec["USER"] = APIUsername;
    
        if (!IsEmpty(APIPassword))
          codec[PWD] = APIPassword;
    
        if (!IsEmpty(APISignature))
          codec[SIGNATURE] = APISignature;
    
        if (!IsEmpty(Subject))
          codec["SUBJECT"] = Subject;
    
        codec["VERSION"] = "88.0";
    
        return codec.Encode();
      }
    
      public static bool IsEmpty(string s)
      {
        return s == null || s.Trim() == string.Empty;
      }
    }
    
    public sealed class NVPCodec : NameValueCollection
    {
      private const string AMPERSAND = "&";
      private const string EQUALS = "=";
      private static readonly char[] AMPERSAND_CHAR_ARRAY = AMPERSAND.ToCharArray();
      private static readonly char[] EQUALS_CHAR_ARRAY = EQUALS.ToCharArray();
    
      public string Encode()
      {
        StringBuilder sb = new StringBuilder();
        bool firstPair = true;
        foreach (string kv in AllKeys)
        {
          string name = HttpUtility.UrlEncode(kv);
          string value = HttpUtility.UrlEncode(this[kv]);
          if (!firstPair)
          {
            sb.Append(AMPERSAND);
          }
          sb.Append(name).Append(EQUALS).Append(value);
          firstPair = false;
        }
        return sb.ToString();
      }
    
      public void Decode(string nvpstring)
      {
        Clear();
        foreach (string nvp in nvpstring.Split(AMPERSAND_CHAR_ARRAY))
        {
          string[] tokens = nvp.Split(EQUALS_CHAR_ARRAY);
          if (tokens.Length >= 2)
          {
            string name = HttpUtility.UrlDecode(tokens[0]);
            string value = HttpUtility.UrlDecode(tokens[1]);
            Add(name, value);
          }
        }
      }
    
      public void Add(string name, string value, int index)
      {
        this.Add(GetArrayName(index, name), value);
      }
    
      public void Remove(string arrayName, int index)
      {
        this.Remove(GetArrayName(index, arrayName));
      }
    
      public string this[string name, int index]
      {
        get
        {
          return this[GetArrayName(index, name)];
        }
        set
        {
          this[GetArrayName(index, name)] = value;
        }
      }
    
      private static string GetArrayName(int index, string name)
      {
        if (index < 0)
        {
          throw new ArgumentOutOfRangeException("index", "index cannot be negative : " + index);
        }
        return name + index;
      }
    }
    
  6. PayPal test ortamına işlev çağrıları yapabilmek için bu öğreticinin önceki bölümlerinde görüntülediğiniz Satıcı API'sinin kimlik bilgilerini (Kullanıcı Adı, Parola ve İmza) ekleyin.

    public string APIUsername = "<Your API Username>";
    private string APIPassword = "<Your API Password>";
    private string APISignature = "<Your Signature>";
    

Not

Bu örnek uygulamada, bir C# dosyasına (.cs) kimlik bilgileri eklemeniz yeterlidir. Ancak, uygulanan bir çözümde kimlik bilgilerinizi bir yapılandırma dosyasında şifrelemeyi göz önünde bulundurmalısınız.

NVPAPICaller sınıfı PayPal işlevinin çoğunu içerir. sınıfındaki kod, PayPal test ortamından test satın alma işlemi yapmak için gereken yöntemleri sağlar. Satın alma işlemleri yapmak için aşağıdaki üç PayPal işlevi kullanılır:

  • SetExpressCheckout işlevi
  • GetExpressCheckoutDetails işlevi
  • DoExpressCheckoutPayment işlevi

yöntemi, ShortcutExpressCheckout alışveriş sepetinden test satın alma bilgilerini ve ürün ayrıntılarını toplar ve PayPal işlevini çağırır SetExpressCheckout . yöntemi, GetCheckoutDetails satın alma ayrıntılarını onaylar ve test satın alma işlemini yapmadan önce PayPal işlevini çağırır GetExpressCheckoutDetails . yöntemi, DoCheckoutPayment PayPal işlevini çağırarak test ortamından test satın alma işlemini DoExpressCheckoutPayment tamamlar. Kalan kod, dizeleri kodlama, dizelerin kodunu çözme, dizileri işleme ve kimlik bilgilerini belirleme gibi PayPal yöntemlerini ve işlemini destekler.

Not

PayPal, PayPal'in API belirtimine göre isteğe bağlı satın alma ayrıntılarını eklemenize olanak tanır. Wingtip Toys örnek uygulamasındaki kodu genişleterek yerelleştirme ayrıntılarını, ürün açıklamalarını, vergileri, müşteri hizmetleri numarasını ve diğer birçok isteğe bağlı alanı ekleyebilirsiniz.

ShortcutExpressCheckout yönteminde belirtilen dönüş ve iptal URL'lerinin bir bağlantı noktası numarası kullandığına dikkat edin.

string returnURL = "https://localhost:44300/Checkout/CheckoutReview.aspx";
       string cancelURL = "https://localhost:44300/Checkout/CheckoutCancel.aspx";

Visual Web Developer SSL kullanarak bir web projesi çalıştırdığında, genellikle web sunucusu için 44300 bağlantı noktası kullanılır. Yukarıda gösterildiği gibi bağlantı noktası numarası 44300'dür. Uygulamayı çalıştırdığınızda farklı bir bağlantı noktası numarası görebilirsiniz. Bu öğreticinin sonunda Wingtip Toys örnek uygulamasını başarıyla çalıştırabilmeniz için bağlantı noktası numaranızın kodda doğru şekilde ayarlanması gerekir. Bu öğreticinin sonraki bölümünde yerel ana bilgisayar bağlantı noktası numarasının nasıl alınıp PayPal sınıfının nasıl güncelleştirilecekleri açıklanmaktadır.

PayPal Sınıfında LocalHost Bağlantı Noktası Numarasını Güncelleştirme

Wingtip Toys örnek uygulaması, PayPal test sitesine giderek ve Wingtip Toys örnek uygulamasının yerel örneğine dönerek ürünleri satın alır. PayPal'ın doğru URL'ye dönmesini sağlamak için, yukarıda belirtilen PayPal kodunda yerel olarak çalışan örnek uygulamanın bağlantı noktası numarasını belirtmeniz gerekir.

  1. Çözüm Gezgini proje adına (WingtipToys) sağ tıklayın ve Özellikler'i seçin.

  2. Sol sütunda Web sekmesini seçin.

  3. Proje Url'si kutusundan bağlantı noktası numarasını alın.

  4. Gerekirse, web uygulamanızın bağlantı noktası numarasını kullanmak için PayPalFunctions.cs dosyasındaki PayPal sınıfındaki (NVPAPICaller) ve cancelURL öğesini güncelleştirinreturnURL:

    string returnURL = "https://localhost:<Your Port Number>/Checkout/CheckoutReview.aspx";
    string cancelURL = "https://localhost:<Your Port Number>/Checkout/CheckoutCancel.aspx";
    

Artık eklediğiniz kod yerel Web uygulamanız için beklenen bağlantı noktasıyla eşleşecek. PayPal, yerel makinenizde doğru URL'ye geri dönebilir.

PayPal Ödeme Düğmesini Ekleme

Örnek uygulamaya birincil PayPal işlevleri eklendiğine göre, bu işlevleri çağırmak için gereken işaretlemeyi ve kodu eklemeye başlayabilirsiniz. İlk olarak, kullanıcının alışveriş sepeti sayfasında göreceği ödeme düğmesini eklemeniz gerekir.

  1. ShoppingCart.aspx dosyasını açın.

  2. Dosyanın en altına kaydırın ve açıklamayı <!--Checkout Placeholder --> bulun.

  3. Yukarı işaretinin aşağıdaki gibi değiştirilmesi için açıklamayı bir ImageButton denetimle değiştirin:

    <asp:ImageButton ID="CheckoutImageBtn" runat="server" 
                          ImageUrl="https://www.paypal.com/en_US/i/btn/btn_xpressCheckout.gif" 
                          Width="145" AlternateText="Check out with PayPal" 
                          OnClick="CheckoutBtn_Click" 
                          BackColor="Transparent" BorderWidth="0" />
    
  4. ShoppingCart.aspx.cs dosyasında, dosyanın sonuna yakın olay işleyiciden sonra UpdateBtn_Click olay işleyicisini CheckOutBtn_Click ekleyin:

    protected void CheckoutBtn_Click(object sender, ImageClickEventArgs e)
    {
        using (ShoppingCartActions usersShoppingCart = new ShoppingCartActions())
        {
            Session["payment_amt"] = usersShoppingCart.GetTotal();
        }
        Response.Redirect("Checkout/CheckoutStart.aspx");
    }
    
  5. Ayrıca ShoppingCart.aspx.cs dosyasında, yeni görüntü düğmesine aşağıdaki gibi başvurulabilmesi için CheckoutBtnöğesine bir başvuru ekleyin:

    protected void Page_Load(object sender, EventArgs e)
    {
        using (ShoppingCartActions usersShoppingCart = new ShoppingCartActions())
        {
            decimal cartTotal = 0;
            cartTotal = usersShoppingCart.GetTotal();
            if (cartTotal > 0)
            {
                // Display Total.
                lblTotal.Text = String.Format("{0:c}", cartTotal);
            }
            else
            {
                LabelTotalText.Text = "";
                lblTotal.Text = "";
                ShoppingCartTitle.InnerText = "Shopping Cart is Empty";
                UpdateBtn.Visible = false;
                CheckoutImageBtn.Visible = false;
            }
        }
    }
    
  6. Değişikliklerinizi hem ShoppingCart.aspx dosyasına hem de ShoppingCart.aspx.cs dosyasına kaydedin.

  7. Menüden Debug-Build>WingtipToys'ı seçin.
    Proje, yeni eklenen ImageButton denetimiyle yeniden oluşturulur.

Satın Alma Ayrıntılarını PayPal'a Gönder

Kullanıcı alışveriş sepeti sayfasındaki (ShoppingCart.aspx) Kullanıma Al düğmesine tıkladığında, satın alma işlemine başlar. Aşağıdaki kod, ürünleri satın almak için gereken ilk PayPal işlevini çağırır.

  1. Kullanıma Alma klasöründen CheckoutStart.aspx.cs adlı arka planda kod dosyasını açın.
    Arka planda kod dosyasını açtığınızdan emin olun.

  2. Mevcut kodu aşağıdakilerle değiştirin:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    
    namespace WingtipToys.Checkout
    {
        public partial class CheckoutStart : System.Web.UI.Page
        {
            protected void Page_Load(object sender, EventArgs e)
            {
                NVPAPICaller payPalCaller = new NVPAPICaller();
                string retMsg = "";
                string token = "";
    
                if (Session["payment_amt"] != null)
                {
                    string amt = Session["payment_amt"].ToString();
    
                    bool ret = payPalCaller.ShortcutExpressCheckout(amt, ref token, ref retMsg);
                    if (ret)
                    {
                        Session["token"] = token;
                        Response.Redirect(retMsg);
                    }
                    else
                    {
                        Response.Redirect("CheckoutError.aspx?" + retMsg);
                    }
                }
                else
                {
                    Response.Redirect("CheckoutError.aspx?ErrorCode=AmtMissing");
                }
            }
        }
    }
    

Uygulama kullanıcısı alışveriş sepeti sayfasındaki Kullanıma Al düğmesine tıkladığında, tarayıcı CheckoutStart.aspx sayfasına gider. CheckoutStart.aspx sayfası yüklendiğinde ShortcutExpressCheckout yöntemi çağrılır. Bu noktada kullanıcı PayPal test web sitesine aktarılır. PayPal sitesinde kullanıcı PayPal kimlik bilgilerini girer, satın alma ayrıntılarını inceler, PayPal sözleşmesini kabul eder ve yöntemin tamamlandığı Wingtip Toys örnek uygulamasına ShortcutExpressCheckout geri döner. ShortcutExpressCheckout Yöntem tamamlandığında, kullanıcıyı yönteminde ShortcutExpressCheckout belirtilen CheckoutReview.aspx sayfasına yönlendirir. Bu, kullanıcının Wingtip Toys örnek uygulamasının içinden sipariş ayrıntılarını gözden geçirmesine olanak tanır.

Sipariş Ayrıntılarını Gözden Geçir

PayPal'dan döndükten sonra Wingtip Toys örnek uygulamasının CheckoutReview.aspx sayfasında sipariş ayrıntıları görüntülenir. Bu sayfa, kullanıcının ürünleri satın almadan önce sipariş ayrıntılarını gözden geçirmesine olanak tanır. CheckoutReview.aspx sayfası aşağıdaki gibi oluşturulmalıdır:

  1. Kullanıma Alma klasöründe, CheckoutReview.aspx adlı sayfayı açın.

  2. Mevcut işaretlemeyi aşağıdakilerle değiştirin:

    <%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="CheckoutReview.aspx.cs" Inherits="WingtipToys.Checkout.CheckoutReview" %>
    <asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
        <h1>Order Review</h1>
        <p></p>
        <h3 style="padding-left: 33px">Products:</h3>
        <asp:GridView ID="OrderItemList" runat="server" AutoGenerateColumns="False" GridLines="Both" CellPadding="10" Width="500" BorderColor="#efeeef" BorderWidth="33">              
            <Columns>
                <asp:BoundField DataField="ProductId" HeaderText=" Product ID" />        
                <asp:BoundField DataField="Product.ProductName" HeaderText=" Product Name" />        
                <asp:BoundField DataField="Product.UnitPrice" HeaderText="Price (each)" DataFormatString="{0:c}"/>     
                <asp:BoundField DataField="Quantity" HeaderText="Quantity" />        
            </Columns>    
        </asp:GridView>
        <asp:DetailsView ID="ShipInfo" runat="server" AutoGenerateRows="false" GridLines="None" CellPadding="10" BorderStyle="None" CommandRowStyle-BorderStyle="None">
            <Fields>
            <asp:TemplateField>
                <ItemTemplate>
                    <h3>Shipping Address:</h3>
                    <br />
                    <asp:Label ID="FirstName" runat="server" Text='<%#: Eval("FirstName") %>'></asp:Label>  
                    <asp:Label ID="LastName" runat="server" Text='<%#: Eval("LastName") %>'></asp:Label>
                    <br />
                    <asp:Label ID="Address" runat="server" Text='<%#: Eval("Address") %>'></asp:Label>
                    <br />
                    <asp:Label ID="City" runat="server" Text='<%#: Eval("City") %>'></asp:Label>
                    <asp:Label ID="State" runat="server" Text='<%#: Eval("State") %>'></asp:Label>
                    <asp:Label ID="PostalCode" runat="server" Text='<%#: Eval("PostalCode") %>'></asp:Label>
                    <p></p>
                    <h3>Order Total:</h3>
                    <br />
                    <asp:Label ID="Total" runat="server" Text='<%#: Eval("Total", "{0:C}") %>'></asp:Label>
                </ItemTemplate>
                <ItemStyle HorizontalAlign="Left" />
            </asp:TemplateField>
              </Fields>
        </asp:DetailsView>
        <p></p>
        <hr />
        <asp:Button ID="CheckoutConfirm" runat="server" Text="Complete Order" OnClick="CheckoutConfirm_Click" />
    </asp:Content>
    
  3. CheckoutReview.aspx.cs adlı arka planda kod sayfasını açın ve mevcut kodu aşağıdakilerle değiştirin:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using WingtipToys.Models;
    
    namespace WingtipToys.Checkout
    {
      public partial class CheckoutReview : System.Web.UI.Page
      {
        protected void Page_Load(object sender, EventArgs e)
        {
          if (!IsPostBack)
          {
            NVPAPICaller payPalCaller = new NVPAPICaller();
    
            string retMsg = "";
            string token = "";
            string PayerID = "";
            NVPCodec decoder = new NVPCodec();
            token = Session["token"].ToString();
    
            bool ret = payPalCaller.GetCheckoutDetails(token, ref PayerID, ref decoder, ref retMsg);
            if (ret)
            {
              Session["payerId"] = PayerID;
    
              var myOrder = new Order();
              myOrder.OrderDate = Convert.ToDateTime(decoder["TIMESTAMP"].ToString());
              myOrder.Username = User.Identity.Name;
              myOrder.FirstName = decoder["FIRSTNAME"].ToString();
              myOrder.LastName = decoder["LASTNAME"].ToString();
              myOrder.Address = decoder["SHIPTOSTREET"].ToString();
              myOrder.City = decoder["SHIPTOCITY"].ToString();
              myOrder.State = decoder["SHIPTOSTATE"].ToString();
              myOrder.PostalCode = decoder["SHIPTOZIP"].ToString();
              myOrder.Country = decoder["SHIPTOCOUNTRYCODE"].ToString();
              myOrder.Email = decoder["EMAIL"].ToString();
              myOrder.Total = Convert.ToDecimal(decoder["AMT"].ToString());
    
              // Verify total payment amount as set on CheckoutStart.aspx.
              try
              {
                decimal paymentAmountOnCheckout = Convert.ToDecimal(Session["payment_amt"].ToString());
                decimal paymentAmoutFromPayPal = Convert.ToDecimal(decoder["AMT"].ToString());
                if (paymentAmountOnCheckout != paymentAmoutFromPayPal)
                {
                  Response.Redirect("CheckoutError.aspx?" + "Desc=Amount%20total%20mismatch.");
                }
              }
              catch (Exception)
              {
                Response.Redirect("CheckoutError.aspx?" + "Desc=Amount%20total%20mismatch.");
              }
    
              // Get DB context.
              ProductContext _db = new ProductContext();
    
              // Add order to DB.
              _db.Orders.Add(myOrder);
              _db.SaveChanges();
    
              // Get the shopping cart items and process them.
              using (WingtipToys.Logic.ShoppingCartActions usersShoppingCart = new WingtipToys.Logic.ShoppingCartActions())
              {
                List<CartItem> myOrderList = usersShoppingCart.GetCartItems();
    
                // Add OrderDetail information to the DB for each product purchased.
                for (int i = 0; i < myOrderList.Count; i++)
                {
                  // Create a new OrderDetail object.
                  var myOrderDetail = new OrderDetail();
                  myOrderDetail.OrderId = myOrder.OrderId;
                  myOrderDetail.Username = User.Identity.Name;
                  myOrderDetail.ProductId = myOrderList[i].ProductId;
                  myOrderDetail.Quantity = myOrderList[i].Quantity;
                  myOrderDetail.UnitPrice = myOrderList[i].Product.UnitPrice;
    
                  // Add OrderDetail to DB.
                  _db.OrderDetails.Add(myOrderDetail);
                  _db.SaveChanges();
                }
    
                // Set OrderId.
                Session["currentOrderId"] = myOrder.OrderId;
    
                // Display Order information.
                List<Order> orderList = new List<Order>();
                orderList.Add(myOrder);
                ShipInfo.DataSource = orderList;
                ShipInfo.DataBind();
    
                // Display OrderDetails.
                OrderItemList.DataSource = myOrderList;
                OrderItemList.DataBind();
              }
            }
            else
            {
              Response.Redirect("CheckoutError.aspx?" + retMsg);
            }
          }
        }
    
        protected void CheckoutConfirm_Click(object sender, EventArgs e)
        {
          Session["userCheckoutCompleted"] = "true";
          Response.Redirect("~/Checkout/CheckoutComplete.aspx");
        }
      }
    }
    

DetailsView denetimi, PayPal'dan döndürülen sipariş ayrıntılarını görüntülemek için kullanılır. Ayrıca, yukarıdaki kod sipariş ayrıntılarını Wingtip Toys veritabanına bir OrderDetail nesne olarak kaydeder. Kullanıcı Siparişi Tamamla düğmesine tıkladığında, CheckoutComplete.aspx sayfasına yönlendirilir.

Not

İpucu

CheckoutReview.aspx sayfasının işaretlemesinde, etiketin <ItemStyle> sayfanın alt kısmındaki DetailsView denetimindeki öğelerin stilini değiştirmek için kullanıldığına dikkat edin. Sayfayı Tasarım Görünümü'nde görüntüleyerek (Visual Studio'nun sol alt köşesindeki Tasarım'ı seçerek), detailsView denetimini ve Akıllı Etiket'i (denetimin sağ üst köşesindeki ok simgesi) seçerek DetailsView Görevlerini görebilirsiniz.

PayPal ile Ödeme ve Ödeme - Alanları Düzenle

Alanları Düzenle'yi seçtiğinizde Alanlar iletişim kutusu görüntülenir. Bu iletişim kutusunda, DetailsView denetiminin ItemStyle gibi görsel özelliklerini kolayca denetleyebilirsiniz.

PayPal ile Ödeme ve Ödeme - Alanlar İletişim Kutusu

Satın Alma Işlemini Tamamla

CheckoutComplete.aspx sayfası PayPal'dan satın alma işlemini yapar. Yukarıda belirtildiği gibi, uygulamanın CheckoutComplete.aspx sayfasına gidebilmesi için önce kullanıcının Siparişi Tamamla düğmesine tıklaması gerekir.

  1. Kullanıma Al klasöründe, CheckoutComplete.aspx adlı sayfayı açın.

  2. Mevcut işaretlemeyi aşağıdakilerle değiştirin:

    <%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="CheckoutComplete.aspx.cs" Inherits="WingtipToys.Checkout.CheckoutComplete" %>
    <asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
        <h1>Checkout Complete</h1>
        <p></p>
        <h3>Payment Transaction ID:</h3> <asp:Label ID="TransactionId" runat="server"></asp:Label>
        <p></p>
        <h3>Thank You!</h3>
        <p></p>
        <hr />
        <asp:Button ID="Continue" runat="server" Text="Continue Shopping" OnClick="Continue_Click" />
    </asp:Content>
    
  3. CheckoutComplete.aspx.cs adlı arka planda kod sayfasını açın ve mevcut kodu aşağıdakilerle değiştirin:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using WingtipToys.Models;
    
    namespace WingtipToys.Checkout
    {
      public partial class CheckoutComplete : System.Web.UI.Page
      {
        protected void Page_Load(object sender, EventArgs e)
        {
          if (!IsPostBack)
          {
            // Verify user has completed the checkout process.
            if ((string)Session["userCheckoutCompleted"] != "true")
            {
              Session["userCheckoutCompleted"] = string.Empty;
              Response.Redirect("CheckoutError.aspx?" + "Desc=Unvalidated%20Checkout.");
            }
    
            NVPAPICaller payPalCaller = new NVPAPICaller();
    
            string retMsg = "";
            string token = "";
            string finalPaymentAmount = "";
            string PayerID = "";
            NVPCodec decoder = new NVPCodec();
    
            token = Session["token"].ToString();
            PayerID = Session["payerId"].ToString();
            finalPaymentAmount = Session["payment_amt"].ToString();
    
            bool ret = payPalCaller.DoCheckoutPayment(finalPaymentAmount, token, PayerID, ref decoder, ref retMsg);
            if (ret)
            {
              // Retrieve PayPal confirmation value.
              string PaymentConfirmation = decoder["PAYMENTINFO_0_TRANSACTIONID"].ToString();
              TransactionId.Text = PaymentConfirmation;
    
              ProductContext _db = new ProductContext();
              // Get the current order id.
              int currentOrderId = -1;
              if (Session["currentOrderId"] != string.Empty)
              {
                currentOrderId = Convert.ToInt32(Session["currentOrderID"]);
              }
              Order myCurrentOrder;
              if (currentOrderId >= 0)
              {
                // Get the order based on order id.
                myCurrentOrder = _db.Orders.Single(o => o.OrderId == currentOrderId);
                // Update the order to reflect payment has been completed.
                myCurrentOrder.PaymentTransactionId = PaymentConfirmation;
                // Save to DB.
                _db.SaveChanges();
              }
    
              // Clear shopping cart.
              using (WingtipToys.Logic.ShoppingCartActions usersShoppingCart =
                  new WingtipToys.Logic.ShoppingCartActions())
              {
                usersShoppingCart.EmptyCart();
              }
    
              // Clear order id.
              Session["currentOrderId"] = string.Empty;
            }
            else
            {
              Response.Redirect("CheckoutError.aspx?" + retMsg);
            }
          }
        }
    
        protected void Continue_Click(object sender, EventArgs e)
        {
          Response.Redirect("~/Default.aspx");
        }
      }
    }
    

CheckoutComplete.aspx sayfası yüklendiğinde DoCheckoutPayment yöntemi çağrılır. Daha önce belirtildiği gibi yöntemi PayPal DoCheckoutPayment test ortamından satın alma işlemini tamamlar. PayPal siparişin satın alımını tamamladıktan sonra , CheckoutComplete.aspx sayfasında satın alan için bir ödeme işlemi ID görüntülenir.

Satın Alma İptali İşle

Kullanıcı satın alma işlemini iptal etmeye karar verirse, siparişinin iptal edildiğini göreceği CheckoutCancel.aspx sayfasına yönlendirilir.

  1. Kullanıma Alma klasöründe CheckoutCancel.aspx adlı sayfayı açın.

  2. Mevcut işaretlemeyi aşağıdakilerle değiştirin:

    <%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="CheckoutCancel.aspx.cs" Inherits="WingtipToys.Checkout.CheckoutCancel" %>
    <asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
        <h1>Checkout Cancelled</h1>
        <p></p>
        <h3>Your purchase has been cancelled.</h3>
    </asp:Content>
    

Satın Alma Hatalarını İşleme

Satın alma işlemi sırasındaki hatalar CheckoutError.aspx sayfası tarafından işlenir. Bir hata oluşursa CheckoutStart.aspx sayfasının, CheckoutReview.aspx sayfasının ve CheckoutComplete.aspx sayfasının arka planındaki kod, CheckoutError.aspx sayfasına yönlendirilir.

  1. Kullanıma Alma klasöründe CheckoutError.aspx adlı sayfayı açın.

  2. Mevcut işaretlemeyi aşağıdakilerle değiştirin:

    <%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="CheckoutError.aspx.cs" Inherits="WingtipToys.Checkout.CheckoutError" %>
    <asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
        <h1>Checkout Error</h1>
        <p></p>
    <table id="ErrorTable">
        <tr>
            <td class="field"></td>
            <td><%=Request.QueryString.Get("ErrorCode")%></td>
        </tr>
        <tr>
            <td class="field"></td>
            <td><%=Request.QueryString.Get("Desc")%></td>
        </tr>
        <tr>
            <td class="field"></td>
            <td><%=Request.QueryString.Get("Desc2")%></td>
        </tr>
    </table>
        <p></p>
    </asp:Content>
    

CheckoutError.aspx sayfası, kullanıma alma işlemi sırasında bir hata oluştuğunda hata ayrıntılarıyla birlikte görüntülenir.

Uygulamayı Çalıştırma

Ürün satın alma işlemini görmek için uygulamayı çalıştırın. PayPal test ortamında çalıştırılacağını unutmayın. Gerçek para değiş tokuşu yapılmaz.

  1. Tüm dosyalarınızın Visual Studio'ya kaydedildiğinden emin olun.

  2. Bir Web tarayıcısı açın ve adresine https://developer.paypal.comgidin.

  3. Bu öğreticinin önceki bölümlerinde oluşturduğunuz PayPal geliştirici hesabınızla oturum açın.
    PayPal'ın geliştirici korumalı alanı için hızlı ödeme test etmek için adresinde https://developer.paypal.com oturum açmanız gerekir. Bu yalnızca PayPal'ın korumalı alan testi için geçerlidir, PayPal'ın canlı ortamı için geçerli değildir.

  4. Visual Studio'da Wingtip Toys örnek uygulamasını çalıştırmak için F5 tuşuna basın.
    Veritabanı yeniden derledikten sonra tarayıcı açılır ve Default.aspx sayfası gösterilir.

  5. "Arabalar" gibi ürün kategorisini seçip her ürünün yanındaki Sepete Ekle'ye tıklayarak alışveriş sepetine üç farklı ürün ekleyin.
    Alışveriş sepeti seçtiğiniz ürünü görüntüler.

  6. Ödeme yapmak için PayPal düğmesine tıklayın.

    PayPal ile Ödeme ve Ödeme - Sepet

    Kullanıma alım için Wingtip Toys örnek uygulaması için bir kullanıcı hesabınız olması gerekir.

  7. Mevcut bir gmail.com e-posta hesabıyla oturum açmak için sayfanın sağındaki Google bağlantısına tıklayın.
    gmail.com hesabınız yoksa, www.gmail.com test amacıyla bir hesap oluşturabilirsiniz. "Kaydet"e tıklayarak standart bir yerel hesap da kullanabilirsiniz.

    PayPal ile Ödeme ve Ödeme - Oturum açma

  8. Gmail hesabınız ve parolanızla oturum açın.

    PayPal ile Ödeme ve Ödeme - Gmail Oturum Açma

  9. Gmail hesabınızı Wingtip Toys örnek uygulama kullanıcı adınızla kaydetmek için Oturum aç düğmesine tıklayın.

    PayPal ile Ödeme ve Ödeme - Hesabı Kaydet

  10. PayPal test sitesinde, bu öğreticide daha önce oluşturduğunuz alıcı e-posta adresinizi ve parolanızı ekleyin, ardından Oturum Aç düğmesine tıklayın.

    PayPal ile Ödeme ve Ödeme - PayPal Oturum Açma

  11. PayPal ilkesini kabul edin ve Kabul Et ve Devam Et düğmesine tıklayın.
    Bu sayfanın yalnızca bu PayPal hesabını ilk kez kullandığınızda görüntülendiğini unutmayın. Bunun bir test hesabı olduğunu, gerçek para değişimi yapılmadığını tekrar unutmayın.

    PayPal ile Ödeme ve Ödeme - PayPal İlkesi

  12. PayPal test ortamı gözden geçirme sayfasındaki sipariş bilgilerini gözden geçirin ve Devam'a tıklayın.

    PayPal ile Ödeme ve Ödeme - Bilgileri Gözden Geçirme

  13. CheckoutReview.aspx sayfasında sipariş tutarını doğrulayın ve oluşturulan sevkiyat adresini görüntüleyin. Ardından Siparişi Tamamla düğmesine tıklayın.

    PayPal ile Ödeme ve Ödeme - Sipariş Gözden Geçirme

  14. CheckoutComplete.aspx sayfası bir ödeme işlemi kimliğiyle görüntülenir.

    PayPal ile Ödeme ve Ödeme - Ödeme Tamamlandı

Veritabanını Gözden Geçirme

Uygulamayı çalıştırdıktan sonra Wingtip Toys örnek uygulama veritabanındaki güncelleştirilmiş verileri gözden geçirerek uygulamanın ürünlerin satın alımını başarıyla kaydettiğini görebilirsiniz.

Bu öğretici serisinin önceki bölümlerinde yaptığınız gibi Veritabanı Gezgini penceresini (Visual Studio'da Sunucu Gezgini penceresi) kullanarak Wingtiptoys.mdf veritabanı dosyasında bulunan verileri inceleyebilirsiniz.

  1. Hala açıksa tarayıcı penceresini kapatın.

  2. Visual Studio'da, App_Data klasörünü genişletmenize olanak sağlamak için Çözüm Gezgini üst kısmındaki Tüm Dosyaları Göster simgesini seçin.

  3. App_Data klasörünü genişletin.
    Klasör için Tüm Dosyaları Göster simgesini seçmeniz gerekebilir.

  4. Wingtiptoys.mdf veritabanı dosyasına sağ tıklayın ve Aç'ı seçin.
    Sunucu Gezgini görüntülenir.

  5. Tablolar klasörünü genişletin.

  6. Siparişlertablosuna sağ tıklayın ve Tablo Verilerini Göster'i seçin.
    Siparişler tablosu görüntülenir.

  7. Başarılı işlemleri onaylamak için PaymentTransactionID sütununu gözden geçirin.

    PayPal ile Ödeme ve Ödeme - Veritabanını Gözden Geçirme

  8. Siparişler tablosu penceresini kapatın.

  9. Sunucu Gezgini'nde OrderDetails tablosuna sağ tıklayın ve Tablo Verilerini Göster'i seçin.

  10. OrderIdOrderDetails tablosundaki ve Username değerlerini gözden geçirin. Bu değerlerin Siparişler tablosundaki OrderId ve Username değerleriyle eşleşdiğini unutmayın.

  11. OrderDetails tablo penceresini kapatın.

  12. Wingtip Toys veritabanı dosyasına (Wingtiptoys.mdf) sağ tıklayın ve Bağlantıyı Kapat'ı seçin.

  13. Çözüm Gezgini penceresini görmüyorsanız, Çözüm Gezgini yeniden göstermek için Sunucu Gezgini penceresinin altındaki Çözüm Gezgini tıklayın.

Özet

Bu öğreticide, ürünlerin satın alımını izlemek için sipariş ve sipariş ayrıntısı şemaları eklediniz. Ayrıca Wingtip Toys örnek uygulamasına PayPal işlevselliğini de tümleştirmişsinizdir.

Ek Kaynaklar

ASP.NET Yapılandırmasına Genel Bakış
Azure App Service'a Üyelik, OAuth ve SQL Veritabanı ile Güvenli ASP.NET Web Forms Uygulaması Dağıtma
Microsoft Azure - Ücretsiz Deneme

Disclaimer

Bu öğreticide örnek kod bulunur. Bu tür örnek kod herhangi bir garanti olmadan "olduğu gibi" sağlanır. Buna uygun olarak, Microsoft örnek kodun doğruluğunu, bütünlüğünü veya kalitesini garanti etmez. Örnek kodu kendi riskinizle kullanmayı kabul edersiniz. Hiçbir koşulda Microsoft herhangi bir örnek kod, içerik veya herhangi bir örnek kodun kullanımından kaynaklanan herhangi bir tür kayıp ya da zarar dahil ancak bunlarla sınırlı olmamak üzere herhangi bir örnek kod, içerik için size hiçbir şekilde sorumlu olmayacaktır. Burada size bildirilir ve burada ifade edilen görüşler dahil ancak bunlarla sınırlı olmamak kaydıyla gönderdiğiniz, ilettiğiniz, kullandığınız veya güvendiğiniz malzemelerle ilgili veya bu malzemeden kaynaklananlar dahil ancak bunlarla sınırlı olmamak üzere, bunlarla sınırlı olmamak kaydıyla microsoft'u her türlü kayıptan, kayıp iddiasından, yaralanmadan veya zarardan ve bunlarla sınırlı olmamak üzere tazmini tazmini, tasarrufunu ve zararını tazmini kabul edersiniz.