Completamento della transazione e pagamento con PayPal

di Erik Reitan

Scaricare il progetto di esempio Wingtip Toys (C#) o scaricare e-book (PDF)

Questa serie di esercitazioni illustra le nozioni di base per la creazione di un'applicazione Web Forms ASP.NET usando ASP.NET 4.5 e Microsoft Visual Studio Express 2013 per Web. Per questa serie di esercitazioni è disponibile un progetto di Visual Studio 2013 con codice sorgente C#.

Questa esercitazione descrive come modificare l'applicazione di esempio Wingtip Toys per includere l'autorizzazione utente, la registrazione e il pagamento tramite PayPal. Solo gli utenti che hanno effettuato l'accesso avranno l'autorizzazione per l'acquisto di prodotti. La funzionalità di registrazione utente predefinita del modello di progetto ASP.NET 4.5 Web Forms include già gran parte degli elementi necessari. Si aggiungerà la funzionalità pagamento Express PayPal. In questa esercitazione si usa l'ambiente di test per sviluppatori PayPal, quindi non verranno trasferiti fondi effettivi. Al termine dell'esercitazione, si testerà l'applicazione selezionando i prodotti da aggiungere al carrello acquisti, facendo clic sul pulsante checkout e trasferendo i dati al sito Web di test payPal. Nel sito Web di test payPal si verificheranno le informazioni di spedizione e pagamento e quindi si tornerà all'applicazione di esempio Wingtip Toys locale per confermare e completare l'acquisto.

Esistono diversi processori di pagamento di terze parti esperti specializzati nello shopping online che si occupa della scalabilità e della sicurezza. ASP.NET sviluppatori dovrebbero considerare i vantaggi dell'utilizzo di una soluzione di pagamento di terze parti prima di implementare una soluzione di acquisto e acquisto.

Nota

L'applicazione di esempio Wingtip Toys è stata progettata per mostrare ASP.NET concetti e funzionalità specifici disponibili per ASP.NET sviluppatori Web. Questa applicazione di esempio non è stata ottimizzata per tutte le circostanze possibili in relazione alla scalabilità e alla sicurezza.

Contenuto dell'esercitazione:

  • Come limitare l'accesso a pagine specifiche in una cartella.
  • Come creare un carrello acquisti noto da un carrello acquisti anonimo.
  • Come abilitare SSL per il progetto.
  • Come aggiungere un provider OAuth al progetto.
  • Come usare PayPal per acquistare prodotti usando l'ambiente di test payPal.
  • Come visualizzare i dettagli da PayPal in un controllo DetailsView .
  • Come aggiornare il database dell'applicazione Wingtip Toys con i dettagli ottenuti da PayPal.

Aggiunta del rilevamento degli ordini

In questa esercitazione verranno create due nuove classi per tenere traccia dei dati dall'ordine creato da un utente. Le classi tengono traccia dei dati relativi alle informazioni di spedizione, al totale degli acquisti e alla conferma del pagamento.

Aggiungere le classi del modello Order e OrderDetail

In precedenza in questa serie di esercitazioni è stato definito lo schema per categorie, prodotti e articoli del carrello acquisti creando le Categoryclassi , Producte CartItem nella cartella Models . Ora si aggiungeranno due nuove classi per definire lo schema per l'ordine di prodotto e i dettagli dell'ordine.

  1. Nella cartella Models aggiungere una nuova classe denominata Order.cs.
    Il nuovo file di classe viene visualizzato nell'editor.

  2. Sostituire il codice predefinito con quello riportato di seguito:

    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. Aggiungere una classe OrderDetail.cs alla cartella Models .

  4. Sostituire il codice predefinito con il codice seguente:

    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; }
    
        }
    }
    

Le Order classi e OrderDetail contengono lo schema per definire le informazioni sull'ordine utilizzate per l'acquisto e la spedizione.

Sarà inoltre necessario aggiornare la classe di contesto del database che gestisce le classi di entità e che fornisce l'accesso ai dati al database. A tale scopo, si aggiungeranno le classi Order e OrderDetail model appena create alla ProductContext classe .

  1. In Esplora soluzioni trovare e aprire il file ProductContext.cs.

  2. Aggiungere il codice evidenziato al file ProductContext.cs , come illustrato di seguito:

    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; }
      }
    }
    

Come accennato in precedenza in questa serie di esercitazioni, il codice nel file ProductContext.cs aggiunge lo System.Data.Entity spazio dei nomi in modo che sia possibile accedere a tutte le funzionalità di base di Entity Framework. Questa funzionalità include la possibilità di eseguire query, inserire, aggiornare ed eliminare dati usando oggetti fortemente tipizzati. Il codice precedente nella ProductContext classe aggiunge l'accesso a Entity Framework alle classi e OrderDetail appena aggiunteOrder.

Aggiunta dell'accesso alla transazione

L'applicazione di esempio Wingtip Toys consente agli utenti anonimi di esaminare e aggiungere prodotti a un carrello acquisti. Tuttavia, quando gli utenti anonimi scelgono di acquistare i prodotti aggiunti al carrello acquisti, devono accedere al sito. Dopo aver eseguito l'accesso, possono accedere alle pagine limitate dell'applicazione Web che gestiscono il processo di estrazione e acquisto. Queste pagine con restrizioni sono contenute nella cartella Checkout dell'applicazione.

Aggiungere una cartella e pagine di estrazione

Si creerà ora la cartella Checkout e le pagine in esso contenute che il cliente visualizzerà durante il processo di estrazione. Queste pagine verranno aggiornate più avanti in questa esercitazione.

  1. Fare clic con il pulsante destro del mouse sul nome del progetto (Wingtip Toys) in Esplora soluzioni e scegliere Aggiungi una nuova cartella.

    Pagamento e pagamento con PayPal - Nuova cartella

  2. Assegnare alla nuova cartella il nome Checkout.

  3. Fare clic con il pulsante destro del mouse sulla cartella Checkout e quindi scegliere Aggiungi nuovo>elemento.

    Pagamento e pagamento con PayPal - Nuovo articolo

  4. La finestra di dialogo Aggiungi nuovo elemento viene visualizzata.

  5. Selezionare il gruppo Visual C# ->Web templates (Modelli Web) a sinistra. Quindi, nel riquadro centrale selezionare Web Form con pagina mastere denominarlo CheckoutStart.aspx.

    Pagamento e pagamento con PayPal - Finestra di dialogo Aggiungi nuovo elemento

  6. Come in precedenza, selezionare il file Site.Master come pagina master.

  7. Aggiungere le pagine aggiuntive seguenti alla cartella Checkout usando gli stessi passaggi precedenti:

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

Aggiungere un file di Web.config

Aggiungendo un nuovo file Web.config alla cartella Checkout , sarà possibile limitare l'accesso a tutte le pagine contenute nella cartella.

  1. Fare clic con il pulsante destro del mouse sulla cartella Checkout e scegliere Aggiungi ->Nuovo elemento.
    La finestra di dialogo Aggiungi nuovo elemento viene visualizzata.

  2. Selezionare il gruppo Visual C# ->Web templates (Modelli Web) a sinistra. Quindi, nel riquadro centrale selezionare File di configurazione Web, accettare il nome predefinito di Web.confige quindi selezionare Aggiungi.

  3. Sostituire il contenuto XML esistente nel file Web.config con il contenuto seguente:

    <?xml version="1.0"?>
    <configuration>
      <system.web>
        <authorization>
          <deny users="?"/>
        </authorization>
      </system.web>
    </configuration>
    
  4. Salvare il file Web.config.

Il file Web.config specifica che tutti gli utenti sconosciuti dell'applicazione Web devono essere negati l'accesso alle pagine contenute nella cartella Checkout . Tuttavia, se l'utente ha registrato un account ed è connesso, sarà un utente noto e avrà accesso alle pagine nella cartella Checkout .

È importante notare che ASP.NET configurazione segue una gerarchia, in cui ogni Web.config file applica le impostazioni di configurazione alla cartella in cui si trova e a tutte le directory figlio sottostanti.

Abilitare SSL per il progetto

Secure Sockets Layer (SSL) è un protocollo definito per consentire ai server Web e ai client Web di comunicare in modo più sicuro tramite l'uso della crittografia. Quando non si usa SSL, i dati inviati tra il client e il server possono essere soggetti allo sniffing dei pacchetti da qualsiasi soggetto con accesso fisico alla rete. Inoltre, numerosi schemi di autenticazione comuni non sono sicuri sul protocollo HTTP normale. In particolare, l'autenticazione di base e l'autenticazione basata su form inviano credenziali non crittografate. Per essere sicuri, questi schemi di autenticazione devono usare il protocollo SSL.

  1. In Esplora soluzioni fare clic sul progetto WingtipToys, quindi premere F4 per visualizzare la finestra Proprietà.
  2. Impostare SSL abilitato su true.
  3. Copiare l'URL SSL in modo da poterlo usare in un secondo momento.
    L'URL SSL sarà https://localhost:44300/ a meno che non sia stato creato in precedenza siti Web SSL (come illustrato di seguito).
    Proprietà progetto
  4. In Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto WingtipToys e scegliere Proprietà.
  5. Nella scheda a sinistra fare clic su Web.
  6. Modificare l'URL del progetto per usare l'URL SSL salvato in precedenza.
    Proprietà di Project Web
  7. Per salvare la pagina, premere CTRL+S.
  8. Premere CTRL+F5 per eseguire l'applicazione. In Visual Studio verrà visualizzata un'opzione che consente di evitare eventuali avvisi SSL.
  9. Fare clic su per considerare attendibile il certificato SSL di IIS Express e continuare.
    IIS Express dettagli del certificato SSL
    Verrà visualizzato un avviso di sicurezza.
  10. Fare clic su per installare il certificato per l'host locale.
    Finestra di dialogo Avviso sicurezza
    Verrà visualizzata la finestra del browser.

È ora possibile testare facilmente l'applicazione Web in locale usando SSL.

Aggiungere un provider OAuth 2.0

Web Forms ASP.NET offre opzioni avanzate per l'appartenenza e l'autenticazione. Questi miglioramenti includono OAuth. OAuth è un protocollo aperto che consente l'autorizzazione sicura in un metodo semplice e standard da applicazioni Web, mobili e desktop. Il modello Web Forms ASP.NET usa OAuth per esporre Facebook, Twitter, Google e Microsoft come provider di autenticazione. Anche se questa esercitazione usa solo Google come provider di autenticazione, è possibile modificare facilmente il codice per usare uno qualsiasi dei provider. I passaggi per implementare altri provider sono molto simili ai passaggi descritti in questa esercitazione.

Oltre all'autenticazione, nell'esercitazione verranno utilizzati anche i ruoli per implementare l'autorizzazione. Solo gli utenti aggiunti al ruolo canEdit saranno in grado di modificare i dati, ovvero creare, modificare o eliminare i contatti.

Nota

Le applicazioni Windows Live accettano solo un URL live per un sito Web funzionante, quindi non è possibile usare un URL del sito Web locale per testare gli account di accesso.

La procedura seguente consente di aggiungere un provider di autenticazione Google.

  1. Aprire il file App_Start\Startup.Auth.cs .

  2. Rimuovere i caratteri di commento dal metodo app.UseGoogleAuthentication() in modo da ottenere il codice seguente:

    app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions()
    {
        ClientId = "",
        ClientSecret = ""
    });
    
  3. Passare a Google Developers Console. Sarà necessario eseguire l'accesso con l'account di posta elettronica per sviluppatori di Google (gmail.com). Se non si dispone di un account Google, selezionare il collegamento Crea un account .
    Verrà quindi visualizzata la pagina Google Developers Console.
    Google Developers Console

  4. Fare clic sul pulsante Crea progetto e immettere un nome di progetto e un ID (è possibile usare i valori predefiniti). Fare quindi clic sulla casella di controllo Contratto e sul pulsante Crea .

    Google - Nuovo progetto

    In pochi secondi il nuovo progetto verrà creato e il browser visualizzerà la nuova pagina dei progetti.

  5. Nella scheda a sinistra fare clic su API & autenticazione e quindi fare clic su Credenziali.

  6. Fare clic su Crea nuovo ID client in OAuth.
    Verrà visualizzata la finestra di dialogo Create Client ID .
    Google - Crea ID client

  7. Nella finestra di dialogo Crea ID client mantenere l'applicazione Web predefinita per il tipo di applicazione.

  8. Impostare Le origini JavaScript autorizzate sull'URL SSL usato in precedenza in questa esercitazione (https://localhost:44300/ a meno che non siano stati creati altri progetti SSL).
    Questo URL rappresenta l'origine dell'applicazione. Per questo esempio, sarà necessario immettere solo l'URL di test localhost. È tuttavia possibile immettere più URL per account per localhost e produzione.

  9. Per Authorized Redirect URI immettere le impostazioni seguenti:

    https://localhost:44300/signin-google
    

    Questo valore è l'URI che verrà usato da ASP.NET OAuth per comunicare con il server OAuth di Google. Tenere presente l'URL SSL usato in precedenza ( https://localhost:44300/ a meno che non siano stati creati altri progetti SSL).

  10. Fare clic sul pulsante Crea ID client .

  11. Nel menu a sinistra della Console per sviluppatori Google fare clic sulla voce di menu Consenso e quindi impostare l'indirizzo di posta elettronica e il nome del prodotto. Al termine del modulo, fare clic su Salva.

  12. Fare clic sulla voce di menu API , scorrere verso il basso e fare clic sul pulsante disattivato accanto all'API Google+.
    Accettare questa opzione abilita l'API Google+.

  13. È anche necessario aggiornare il pacchetto NuGet Microsoft.Owin alla versione 3.0.0.
    Dal menu Strumenti selezionare Gestione pacchetti NuGet e quindi Selezionare Gestisci pacchetti NuGet per la soluzione.
    Nella finestra Gestisci pacchetti NuGet trovare e aggiornare il pacchetto Microsoft.Owin alla versione 3.0.0.

  14. In Visual Studio aggiornare il UseGoogleAuthentication metodo della pagina Startup.Auth.cs copiando e incollando l'ID client e il segreto client nel metodo . I valori id client e segreto client illustrati di seguito sono esempi e non funzioneranno.

    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. Premere CTRL+F5 per compilare ed eseguire l'applicazione. Fare clic sul collegamento Accedi .

  16. In Usa un altro servizio per accedere fare clic su Google.
    Accedi

  17. Se è necessario immettere le credenziali, si verrà reindirizzati al sito google in cui immettere le credenziali.
    Google - accesso

  18. Dopo aver immesso le credenziali, verrà richiesto di concedere le autorizzazioni all'applicazione Web appena creata.
    Account del servizio di progetto predefinito

  19. Fare clic Accept. Verrà ora reindirizzato alla pagina Registra dell'applicazione WingtipToys in cui è possibile registrare l'account Google.
    Registrare con l'account Google

  20. Sarà possibile modificare il nome di registrazione dell'indirizzo di posta elettronica locale usato per l'account Gmail, anche se in generale è preferibile mantenere l'alias di posta elettronica predefinito, ovvero quello usato per l'autenticazione. Fare clic su Accedi come illustrato in precedenza.

Modifica della funzionalità di accesso

Come accennato in precedenza in questa serie di esercitazioni, gran parte della funzionalità di registrazione utente è stata inclusa nel modello di Web Forms ASP.NET per impostazione predefinita. Ora si modificano le pagine predefinite Login.aspx e Register.aspx per chiamare il MigrateCart metodo. Il MigrateCart metodo associa un utente appena connesso a un carrello acquisti anonimo. Associando l'utente e il carrello acquisti, l'applicazione di esempio Wingtip Toys sarà in grado di mantenere il carrello degli acquisti dell'utente tra visite.

  1. In Esplora soluzioni trovare e aprire la cartella Account.

  2. Modificare la pagina code-behind denominata Login.aspx.cs per includere il codice evidenziato in giallo, in modo che venga visualizzato come indicato di seguito:

    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. Salvare il file Login.aspx.cs .

Per il momento, è possibile ignorare l'avviso che non esiste alcuna definizione per il MigrateCart metodo. Verrà aggiunto un po' più avanti in questa esercitazione.

Il file Login.aspx.cs code-behind supporta un metodo LogIn. Esaminando la pagina Login.aspx, si noterà che questa pagina include un pulsante "Accedi" che quando si fa clic LogIn sul gestore nel code-behind.

Quando viene chiamato il Login metodo in Login.aspx.cs , viene creata una nuova istanza del carrello acquisti denominata usersShoppingCart . L'ID del carrello acquisti (GUID) viene recuperato e impostato sulla cartId variabile. Viene quindi chiamato il MigrateCart metodo, passando sia il cartId nome dell'utente connesso a questo metodo. Quando il carrello acquisti viene migrato, il GUID usato per identificare il carrello acquisti anonimo viene sostituito con il nome utente.

Oltre a modificare il file Login.aspx.cs code-behind per eseguire la migrazione del carrello acquisti quando l'utente accede, è necessario modificare anche il file Register.aspx.cs code-behind per eseguire la migrazione del carrello acquisti quando l'utente crea un nuovo account e accede.

  1. Nella cartella Account aprire il file code-behind denominato Register.aspx.cs.

  2. Modificare il file code-behind includendo il codice in giallo, in modo che venga visualizzato come segue:

    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. Salvare il file Register.aspx.cs . Ignorare nuovamente l'avviso relativo al MigrateCart metodo.

Si noti che il codice usato nel CreateUser_Click gestore eventi è molto simile al codice usato nel LogIn metodo. Quando l'utente registra o accede al sito, verrà effettuata una chiamata al MigrateCart metodo.

Migrazione del carrello acquisti

Dopo aver aggiornato il processo di accesso e registrazione, è possibile aggiungere il codice per eseguire la migrazione del carrello acquisti usando il MigrateCart metodo .

  1. In Esplora soluzioni trovare la cartella Logica e aprire il file di classe ShoppingCartActions.cs.

  2. Aggiungere il codice evidenziato in giallo al codice esistente nel file ShoppingCartActions.cs , in modo che il codice nel file ShoppingCartActions.cs venga visualizzato come indicato di seguito:

    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();
        }
      }
    }
    

Il MigrateCart metodo usa il cartId esistente per trovare il carrello degli acquisti dell'utente. Successivamente, il codice scorre tutti gli elementi del carrello acquisti e sostituisce la CartId proprietà (come specificato dallo CartItem schema) con il nome utente connesso.

Aggiornamento della connessione al database

Se si segue questa esercitazione usando l'applicazione di esempio Wingtip Toys predefinita , è necessario ricreare il database di appartenenza predefinito. Modificando la stringa di connessione predefinita, il database di appartenenza verrà creato al successivo esecuzione dell'applicazione.

  1. Aprire il file Web.config nella radice del progetto.

  2. Aggiornare il stringa di connessione predefinito in modo che venga visualizzato come segue:

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

Integrazione di PayPal

PayPal è una piattaforma di fatturazione basata sul Web che accetta pagamenti da commercianti online. Questa esercitazione illustra ora come integrare la funzionalità pagamento rapido di PayPal nell'applicazione. Express Checkout consente ai clienti di usare PayPal per pagare gli articoli aggiunti al carrello acquisti.

Creare account di test PayPal

Per usare l'ambiente di test payPal, è necessario creare e verificare un account di test per sviluppatore. Si userà l'account di test per sviluppatore per creare un account di test dell'acquirente e un account di test del venditore. Le credenziali dell'account di test dello sviluppatore consentiranno anche all'applicazione di esempio Wingtip Toys di accedere all'ambiente di test PayPal.

  1. In un browser passare al sito di test per sviluppatori PayPal:
    https://developer.paypal.com

  2. Se non si ha un account per sviluppatore PayPal, creare un nuovo account facendo clic su Iscrivitie seguendo la procedura di iscrizione. Se si dispone di un account per sviluppatore PayPal esistente, accedere facendo clic su Accedi. Sarà necessario l'account per sviluppatore PayPal per testare l'applicazione di esempio Wingtip Toys più avanti in questa esercitazione.

  3. Se hai appena effettuato l'iscrizione per il tuo account per sviluppatore PayPal, potrebbe essere necessario verificare il tuo account per sviluppatore PayPal con PayPal. Puoi verificare il tuo account seguendo i passaggi inviati da PayPal al tuo account di posta elettronica. Dopo aver verificato l'account per sviluppatore PayPal, accedere di nuovo al sito di test per sviluppatori PayPal.

  4. Dopo aver effettuato l'accesso al sito per sviluppatori PayPal con il tuo account per sviluppatore PayPal, devi creare un account di test di PayPal acquirente, se non ne hai già uno. Per creare un account di test dell'acquirente, nel sito PayPal fare clic sulla scheda Applicazioni e quindi su Account sandbox.
    Viene visualizzata la pagina Account di test sandbox .

    Nota

    Il sito PayPal Developer fornisce già un account di test commerciante.

    Screenshot che mostra la pagina Account di test sandbox con la scheda Applicazioni evidenziata.

  5. Nella pagina Account di test sandbox fare clic su Crea account.

  6. Nella pagina Crea account di test scegliere un indirizzo di posta elettronica e una password per l'account di test dell'acquirente a scelta.

    Nota

    Saranno necessari gli indirizzi di posta elettronica e la password dell'acquirente per testare l'applicazione di esempio Wingtip Toys alla fine di questa esercitazione.

    Screenshot della pagina Crea account di test che mostra i campi di un account creato.

  7. Creare l'account di test dell'acquirente facendo clic sul pulsante Crea account .
    Viene visualizzata la pagina Account di test sandbox .

    Pagamento e pagamento con PayPal - Account PayPal

  8. Nella pagina Account di test sandbox fare clic sull'account di posta elettronica del moderatore .
    Vengono visualizzate le opzioni profilo e notifica .

  9. Selezionare l'opzione Profilo , quindi fare clic su Credenziali API per visualizzare le credenziali API per l'account di test del commerciante.

  10. Copiare le credenziali dell'API TEST nel Blocco note.

Saranno necessarie le credenziali dell'API TEST classica (nome utente, password e firma) visualizzate per effettuare chiamate API dall'applicazione di esempio Wingtip Toys all'ambiente di test payPal. Le credenziali verranno aggiunte nel passaggio successivo.

Aggiungere le credenziali API e la classe PayPal

La maggior parte del codice PayPal verrà inserita in una singola classe. Questa classe contiene i metodi usati per comunicare con PayPal. Inoltre, si aggiungeranno le credenziali di PayPal a questa classe.

  1. Nell'applicazione di esempio Wingtip Toys in Visual Studio fare clic con il pulsante destro del mouse sulla cartella Logica e quindi scegliere Aggiungi ->Nuovo elemento.
    La finestra di dialogo Aggiungi nuovo elemento viene visualizzata.

  2. In Visual C# dal riquadro Installato a sinistra selezionare Codice.

  3. Nel riquadro centrale selezionare Classe. Denominare questa nuova classe PayPalFunctions.cs.

  4. Fare clic su Aggiungi.
    Il nuovo file di classe viene visualizzato nell'editor.

  5. Sostituire il codice predefinito con il codice seguente:

    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. Aggiungere le credenziali dell'API Merchant (Nome utente, Password e Firma) visualizzate in precedenza in questa esercitazione in modo da poter effettuare chiamate di funzione all'ambiente di test payPal.

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

Nota

In questa applicazione di esempio si aggiungono semplicemente le credenziali a un file C# (.cs). In una soluzione implementata è tuttavia consigliabile crittografare le credenziali in un file di configurazione.

La classe NVPAPICaller contiene la maggior parte delle funzionalità di PayPal. Il codice nella classe fornisce i metodi necessari per effettuare un acquisto di test dall'ambiente di test PayPal. Per effettuare acquisti vengono usate le tre funzioni PayPal seguenti:

  • Funzione SetExpressCheckout
  • Funzione GetExpressCheckoutDetails
  • Funzione DoExpressCheckoutPayment

Il ShortcutExpressCheckout metodo raccoglie le informazioni sull'acquisto di test e i dettagli del prodotto dal carrello acquisti e chiama la SetExpressCheckout funzione PayPal. Il GetCheckoutDetails metodo conferma i dettagli di acquisto e chiama la GetExpressCheckoutDetails funzione PayPal prima di effettuare l'acquisto di test. Il DoCheckoutPayment metodo completa l'acquisto di test dall'ambiente di test chiamando la DoExpressCheckoutPayment funzione PayPal. Il codice rimanente supporta i metodi e il processo PayPal, ad esempio stringhe di codifica, decodifica di stringhe, elaborazione di matrici e determinazione delle credenziali.

Nota

PayPal consente di includere i dettagli di acquisto facoltativi in base alla specifica dell'API di PayPal. Estendendo il codice nell'applicazione di esempio Wingtip Toys, è possibile includere dettagli di localizzazione, descrizioni dei prodotti, imposte, un numero di servizio clienti e molti altri campi facoltativi.

Si noti che gli URL restituiti e annulla specificati nel metodo ShortcutExpressCheckout usano un numero di porta.

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

Quando Visual Web Developer esegue un progetto Web tramite SSL, in genere la porta 44300 viene usata per il server Web. Come illustrato in precedenza, il numero di porta è 44300. Quando si esegue l'applicazione, è possibile visualizzare un numero di porta diverso. Il numero di porta deve essere impostato correttamente nel codice in modo che sia possibile eseguire correttamente l'applicazione di esempio Wingtip Toys alla fine di questa esercitazione. La sezione successiva di questa esercitazione illustra come recuperare il numero di porta host locale e aggiornare la classe PayPal.

Aggiornare il numero di porta LocalHost nella classe PayPal

L'applicazione di esempio Wingtip Toys acquista prodotti passando al sito di test payPal e restituendo all'istanza locale dell'applicazione di esempio Wingtip Toys. Per fare in modo che PayPal torni all'URL corretto, è necessario specificare il numero di porta dell'applicazione di esempio in esecuzione in locale nel codice PayPal indicato in precedenza.

  1. Fare clic con il pulsante destro del mouse sul nome del progetto (WingtipToys) in Esplora soluzioni e scegliere Proprietà.

  2. Nella colonna a sinistra selezionare la scheda Web .

  3. Recuperare il numero di porta dalla casella Url progetto .

  4. Se necessario, aggiornare e returnURLcancelURL nella classe PayPal (NVPAPICaller) nel file PayPalFunctions.cs per usare il numero di porta dell'applicazione Web:

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

Ora il codice aggiunto corrisponderà alla porta prevista per l'applicazione Web locale. PayPal sarà in grado di tornare all'URL corretto nel computer locale.

Aggiungere il pulsante Pagamento PayPal

Ora che le funzioni PayPal principali sono state aggiunte all'applicazione di esempio, è possibile iniziare ad aggiungere il markup e il codice necessari per chiamare queste funzioni. Prima di tutto, è necessario aggiungere il pulsante checkout che l'utente visualizzerà nella pagina del carrello acquisti.

  1. Aprire il file ShoppingCart.aspx .

  2. Scorrere fino alla fine del file e trovare il <!--Checkout Placeholder --> commento.

  3. Sostituire il commento con un ImageButton controllo in modo che il contrassegno venga sostituito come segue:

    <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. Nel file ShoppingCart.aspx.cs , dopo il UpdateBtn_Click gestore eventi vicino alla fine del file, aggiungere il CheckOutBtn_Click gestore eventi:

    protected void CheckoutBtn_Click(object sender, ImageClickEventArgs e)
    {
        using (ShoppingCartActions usersShoppingCart = new ShoppingCartActions())
        {
            Session["payment_amt"] = usersShoppingCart.GetTotal();
        }
        Response.Redirect("Checkout/CheckoutStart.aspx");
    }
    
  5. Nel file ShoppingCart.aspx.cs aggiungere anche un riferimento a , in modo che venga fatto riferimento al CheckoutBtnpulsante nuova immagine come indicato di seguito:

    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. Salvare le modifiche nel file ShoppingCart.aspx e nel file ShoppingCart.aspx.cs .

  7. Scegliere Debug-Build>WingtipToys dal menu.
    Il progetto verrà ricompilato con il controllo ImageButton appena aggiunto.

Invia dettagli acquisto a PayPal

Quando l'utente fa clic sul pulsante Checkout (Checkout ) nella pagina del carrello acquisti (ShoppingCart.aspx), inizierà il processo di acquisto. Il codice seguente chiama la prima funzione PayPal necessaria per acquistare i prodotti.

  1. Dalla cartella Checkout aprire il file code-behind denominato CheckoutStart.aspx.cs.
    Assicurarsi di aprire il file code-behind.

  2. Sostituire il codice esistente con quello seguente:

    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");
                }
            }
        }
    }
    

Quando l'utente dell'applicazione fa clic sul pulsante Checkout nella pagina del carrello acquisti, il browser passerà alla pagina CheckoutStart.aspx . Quando viene caricata la pagina CheckoutStart.aspx , viene chiamato il ShortcutExpressCheckout metodo . A questo punto, l'utente viene trasferito al sito Web di test payPal. Nel sito PayPal, l'utente immette le credenziali di PayPal, esamina i dettagli di acquisto, accetta il contratto PayPal e torna all'applicazione di esempio Wingtip Toys in cui il ShortcutExpressCheckout metodo viene completato. Al termine del ShortcutExpressCheckout metodo, l'utente verrà reindirizzato alla pagina CheckoutReview.aspx specificata nel ShortcutExpressCheckout metodo . In questo modo l'utente può esaminare i dettagli dell'ordine dall'applicazione di esempio Wingtip Toys.

Esaminare i dettagli dell'ordine

Dopo aver restituito da PayPal, la pagina CheckoutReview.aspx dell'applicazione di esempio Wingtip Toys visualizza i dettagli dell'ordine. Questa pagina consente all'utente di esaminare i dettagli dell'ordine prima di acquistare i prodotti. La pagina CheckoutReview.aspx deve essere creata come segue:

  1. Nella cartella Checkout aprire la pagina denominata CheckoutReview.aspx.

  2. Sostituire il markup esistente con quanto segue:

    <%@ 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. Aprire la pagina code-behind denominata CheckoutReview.aspx.cs e sostituire il codice esistente con quanto segue:

    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");
        }
      }
    }
    

Il controllo DetailsView viene usato per visualizzare i dettagli dell'ordine restituiti da PayPal. Inoltre, il codice precedente salva i dettagli dell'ordine nel database Wingtip Toys come OrderDetail oggetto. Quando l'utente fa clic sul pulsante Completa ordine , vengono reindirizzati alla pagina CheckoutComplete.aspx .

Nota

Suggerimento

Nel markup della pagina CheckoutReview.aspx si noti che il <ItemStyle> tag viene usato per modificare lo stile degli elementi all'interno del controllo DetailsView nella parte inferiore della pagina. Visualizzando la pagina in Visualizzazione progettazione (selezionando Progettazione nell'angolo inferiore sinistro di Visual Studio), selezionare il controllo DetailsView e selezionare Smart Tag (icona freccia in alto a destra del controllo), sarà possibile visualizzare le attività DetailsView.

Pagamento e pagamento con PayPal - Modifica campi

Selezionando Modifica campi, verrà visualizzata la finestra di dialogo Campi . In questa finestra di dialogo è possibile controllare facilmente le proprietà visive, ad esempio ItemStyle, del controllo DetailsView .

Pagamento e pagamento con PayPal - Finestra di dialogo Campi

Acquisto completo

La pagina CheckoutComplete.aspx effettua l'acquisto da PayPal. Come accennato in precedenza, l'utente deve fare clic sul pulsante Completa ordine prima che l'applicazione passerà alla pagina CheckoutComplete.aspx .

  1. Nella cartella Checkout aprire la pagina denominata CheckoutComplete.aspx.

  2. Sostituire il markup esistente con quanto segue:

    <%@ 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. Aprire la pagina code-behind denominata CheckoutComplete.aspx.cs e sostituire il codice esistente con quanto segue:

    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");
        }
      }
    }
    

Quando viene caricata la pagina CheckoutComplete.aspx , viene chiamato il DoCheckoutPayment metodo. Come accennato in precedenza, il DoCheckoutPayment metodo completa l'acquisto dall'ambiente di test di PayPal. Dopo aver completato l'acquisto dell'ordine, la pagina CheckoutComplete.aspx visualizza una transazione ID di pagamento all'acquirente.

Gestire l'acquisto annulla

Se l'utente decide di annullare l'acquisto, verrà indirizzato alla pagina CheckoutCancel.aspx in cui vedranno che l'ordine è stato annullato.

  1. Aprire la pagina denominata CheckoutCancel.aspx nella cartella Checkout .

  2. Sostituire il markup esistente con quanto segue:

    <%@ 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>
    

Gestire gli errori di acquisto

Gli errori durante il processo di acquisto verranno gestiti dalla pagina CheckoutError.aspx . Il code-behind della pagina CheckoutStart.aspx , la pagina CheckoutReview.aspx e la pagina CheckoutComplete.aspx verranno reindirizzata alla pagina CheckoutError.aspx se si verifica un errore.

  1. Aprire la pagina denominata CheckoutError.aspx nella cartella Checkout .

  2. Sostituire il markup esistente con quanto segue:

    <%@ 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>
    

La pagina CheckoutError.aspx viene visualizzata con i dettagli dell'errore quando si verifica un errore durante il processo di estrazione.

Esecuzione dell'applicazione

Eseguire l'applicazione per vedere come acquistare prodotti. Si noti che si eseguirà nell'ambiente di test di PayPal. Nessun denaro effettivo viene scambiato.

  1. Assicurarsi che tutti i file vengano salvati in Visual Studio.

  2. Aprire un Web browser e passare a https://developer.paypal.com.

  3. Accedere con l'account per sviluppatori PayPal creato in precedenza in questa esercitazione.
    Per la sandbox per sviluppatori di PayPal, è necessario eseguire l'accesso in https://developer.paypal.com per testare il pagamento rapido. Questo vale solo per i test sandbox di PayPal, non per l'ambiente live di PayPal.

  4. In Visual Studio premere F5 per eseguire l'applicazione di esempio Wingtip Toys.
    Dopo la ricompilazione del database, il browser verrà aperto e visualizzato la pagina Default.aspx .

  5. Aggiungere tre prodotti diversi al carrello acquisti selezionando la categoria di prodotti, ad esempio "Auto" e quindi facendo clic su Aggiungi al carrello accanto a ogni prodotto.
    Il carrello acquisti visualizzerà il prodotto selezionato.

  6. Fare clic sul pulsante PayPal per eseguire il pagamento.

    Pagamento e pagamento con PayPal - Carrello

    Il controllo richiederà di avere un account utente per l'applicazione di esempio Wingtip Toys.

  7. Fare clic sul collegamento Google a destra della pagina per accedere con un account di posta elettronica gmail.com esistente.
    Se non si dispone di un account gmail.com, è possibile crearne uno per scopi di test in www.gmail.com. È anche possibile usare un account locale standard facendo clic su "Registra".

    Pagamento e pagamento con PayPal - Accedere

  8. Accedere con l'account gmail e la password.

    Pagamento e pagamento con PayPal - Gmail Accedi

  9. Fare clic sul pulsante Accedi per registrare l'account gmail con il nome utente dell'applicazione di esempio Wingtip Toys.

    Pagamento e pagamento con PayPal - Account di registrazione

  10. Nel sito di test di PayPal aggiungere l'indirizzo di posta elettronica e la password dell'acquirente creati in precedenza in questa esercitazione, quindi fare clic sul pulsante Accedi .

    Pagamento e pagamento con PayPal - Accesso PayPal

  11. Accettare il criterio PayPal e fare clic sul pulsante Accetta e Continua .
    Si noti che questa pagina viene visualizzata solo la prima volta che si usa questo account PayPal. Si noti di nuovo che si tratta di un conto di test, nessun denaro reale viene scambiato.

    Pagamento e pagamento con PayPal - Criterio PayPal

  12. Esaminare le informazioni sull'ordine nella pagina di revisione dell'ambiente di test di PayPal e fare clic su Continua.

    Pagamento e pagamento con PayPal - Esaminare le informazioni

  13. Nella pagina CheckoutReview.aspx verificare l'importo dell'ordine e visualizzare l'indirizzo di spedizione generato. Fare quindi clic sul pulsante Completa ordine .

    Pagamento e pagamento con PayPal - Verifica ordine

  14. La pagina CheckoutComplete.aspx viene visualizzata con un ID transazione di pagamento.

    Pagamento e pagamento con PayPal - Pagamento completo

Revisione del database

Esaminando i dati aggiornati nel database dell'applicazione di esempio Wingtip Toys dopo l'esecuzione dell'applicazione, è possibile notare che l'applicazione ha registrato correttamente l'acquisto dei prodotti.

È possibile esaminare i dati contenuti nel file di database Wingtiptoys.mdf usando la finestra Esploradatabase (finestra Esplora server in Visual Studio) come illustrato in precedenza in questa serie di esercitazioni.

  1. Chiudere la finestra del browser se è ancora aperta.

  2. In Visual Studio selezionare l'icona Mostra tutti i file nella parte superiore di Esplora soluzioni per consentire di espandere la cartella App_Data.

  3. Espandere la cartella App_Data .
    Potrebbe essere necessario selezionare l'icona Mostra tutti i file per la cartella.

  4. Fare clic con il pulsante destro del mouse sul file di database Wingtiptoys.mdf e scegliere Apri.
    Viene visualizzato Esplora server .

  5. Espandere la cartella Tabelle .

  6. Fare clic con il pulsante destro del mouse sulla tabella Orderse scegliere Mostra dati tabella.
    Viene visualizzata la tabella Orders .

  7. Esaminare la colonna PaymentTransactionID per confermare le transazioni riuscite.

    Pagamento e pagamento con PayPal - Rivedi database

  8. Chiudere la finestra Della tabella Orders .

  9. In Esplora server fare clic con il pulsante destro del mouse sulla tabella OrderDetails e selezionareMostra dati tabella.

  10. Esaminare i OrderId valori e Username nella tabella OrderDetails . Si noti che questi valori corrispondono ai OrderId valori e Username inclusi nella tabella Orders .

  11. Chiudere la finestra della tabella OrderDetails .

  12. Fare clic con il pulsante destro del mouse sul file di database Wingtip Toys (Wingtiptoys.mdf) e scegliere Chiudi connessione.

  13. Se non viene visualizzata la finestra Esplora soluzioni, fare clic Esplora soluzioni nella parte inferiore della finestra Esplora server per visualizzare di nuovo l'Esplora soluzioni.

Riepilogo

In questa esercitazione sono stati aggiunti schemi di ordine e dettagli dell'ordine per tenere traccia dell'acquisto di prodotti. È anche possibile integrare la funzionalità PayPal nell'applicazione di esempio Wingtip Toys.

Risorse aggiuntive

Panoramica della configurazione di ASP.NET
Distribuire un'app di Web Forms ASP.NET sicura con appartenenza, OAuth e database SQL in Servizio app di Azure
Microsoft Azure - Versione di valutazione gratuita

Dichiarazione di non responsabilità

Questa esercitazione contiene codice di esempio. Tale codice di esempio viene fornito "così com'è" senza garanzia di alcun tipo. Di conseguenza, Microsoft non garantisce l'accuratezza, l'integrità o la qualità del codice di esempio. Si accetta di usare il codice di esempio a proprio rischio. In nessun caso Microsoft sarà responsabile in alcun modo per qualsiasi codice di esempio, contenuto, incluso, non limitato, eventuali errori o omissioni in qualsiasi codice di esempio, contenuto o qualsiasi perdita o danno di qualsiasi tipo in seguito all'uso di qualsiasi codice di esempio. L'utente riceve una notifica e accetta di insodmettere, salvare e conservare Microsoft innocuo da e contro qualsiasi perdita, attestazioni di perdita, danno o danno di qualsiasi tipo, inclusi, senza limitazioni, quelli generati o derivanti da materiale che si pubblica, trasmette, usa o si basa su, tra cui, a titolo esemplificativo, le opinioni espresse.