Commande et paiement avec PayPal

par Erik Reitan

Télécharger Wingtip Toys Sample Project (C#) ou Télécharger le livre électronique (PDF)

Cette série de tutoriels vous apprend les principes de base de la création d’une application ASP.NET Web Forms à l’aide de ASP.NET 4.5 et Microsoft Visual Studio Express 2013 pour le web. Un projet Visual Studio 2013 avec du code source C# est disponible pour accompagner cette série de tutoriels.

Ce tutoriel explique comment modifier l’exemple d’application Wingtip Toys pour inclure l’autorisation utilisateur, l’inscription et le paiement à l’aide de PayPal. Seuls les utilisateurs connectés auront l’autorisation d’acheter des produits. La fonctionnalité d’inscription d’utilisateur intégrée du modèle de projet ASP.NET 4.5 Web Forms comprend déjà une grande partie de ce dont vous avez besoin. Vous allez ajouter la fonctionnalité Paiement express PayPal. Dans ce tutoriel, vous utilisez l’environnement de test des développeurs PayPal, donc aucun fonds réel ne sera transféré. À la fin du tutoriel, vous allez tester l’application en sélectionnant les produits à ajouter au panier, en cliquant sur le bouton de paiement et en transférant les données vers le site web de test PayPal. Sur le site web de test PayPal, vous confirmerez vos informations d’expédition et de paiement, puis retournerez à l’exemple d’application Wingtip Toys locale pour confirmer et terminer l’achat.

Il existe plusieurs processeurs de paiement tiers expérimentés qui se spécialisent dans les achats en ligne qui traitent de la scalabilité et de la sécurité. ASP.NET développeurs doivent prendre en compte les avantages de l’utilisation d’une solution de paiement tierce avant d’implémenter une solution d’achat et d’achat.

Notes

L’exemple d’application Wingtip Toys a été conçu pour montrer des concepts et des fonctionnalités ASP.NET spécifiques disponibles pour ASP.NET développeurs web. Cet exemple d’application n’a pas été optimisé pour toutes les circonstances possibles en ce qui concerne la scalabilité et la sécurité.

Ce que vous allez apprendre :

  • Comment restreindre l’accès à des pages spécifiques dans un dossier.
  • Comment créer un panier d’achat connu à partir d’un panier d’achat anonyme.
  • Comment activer SSL pour le projet.
  • Comment ajouter un fournisseur OAuth au projet.
  • Comment utiliser PayPal pour acheter des produits à l’aide de l’environnement de test PayPal.
  • Comment afficher les détails de PayPal dans un contrôle DetailsView .
  • Comment mettre à jour la base de données de l’application Wingtip Toys avec les détails obtenus à partir de PayPal.

Ajout du suivi des commandes

Dans ce tutoriel, vous allez créer deux nouvelles classes pour suivre les données de l’ordre créé par un utilisateur. Les classes effectuent le suivi des données relatives aux informations d’expédition, au total de l’achat et à la confirmation de paiement.

Ajouter les classes de modèle Order et OrderDetail

Plus tôt dans cette série de tutoriels, vous avez défini le schéma pour les catégories, les produits et les éléments du panier d’achat en créant les Categoryclasses , Productet CartItem dans le dossier Modèles . Vous allez maintenant ajouter deux nouvelles classes pour définir le schéma de la commande de produit et les détails de la commande.

  1. Dans le dossier Modèles , ajoutez une nouvelle classe nommée Order.cs.
    Le nouveau fichier de classe s’affiche dans l’éditeur.

  2. Remplacez le code par défaut par ce qui suit :

    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. Ajoutez une classe OrderDetail.cs au dossier Models .

  4. Remplacez le code par défaut par le code suivant :

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

Les Order classes et OrderDetail contiennent le schéma pour définir les informations de commande utilisées pour l’achat et l’expédition.

En outre, vous devez mettre à jour la classe de contexte de base de données qui gère les classes d’entité et qui fournit l’accès aux données à la base de données. Pour ce faire, vous allez ajouter les classes Order et OrderDetail model nouvellement créées à la ProductContext classe.

  1. Dans Explorateur de solutions, recherchez et ouvrez le fichier ProductContext.cs.

  2. Ajoutez le code mis en surbrillance au fichier ProductContext.cs comme indiqué ci-dessous :

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

Comme mentionné précédemment dans cette série de tutoriels, le code dans le fichier ProductContext.cs ajoute l’espace System.Data.Entity de noms afin que vous ayez accès à toutes les fonctionnalités principales d’Entity Framework. Cette fonctionnalité inclut la possibilité d’interroger, d’insérer, de mettre à jour et de supprimer des données en travaillant avec des objets fortement typés. Le code ci-dessus dans la classe ajoute l’accès ProductContext Entity Framework aux classes et OrderDetail nouvellement ajoutéesOrder.

Ajout de l’accès à la validation

L’exemple d’application Wingtip Toys permet aux utilisateurs anonymes d’examiner et d’ajouter des produits à un panier d’achat. Toutefois, lorsque des utilisateurs anonymes choisissent d’acheter les produits qu’ils ont ajoutés au panier d’achat, ils doivent se connecter au site. Une fois connectés, ils peuvent accéder aux pages restreintes de l’application web qui gèrent le processus de paiement et d’achat. Ces pages restreintes sont contenues dans le dossier Checkout de l’application.

Ajouter un dossier d’extraction et des pages

Vous allez maintenant créer le dossier Checkout et les pages qu’il contient que le client verra pendant le processus de paiement. Vous allez mettre à jour ces pages plus loin dans ce tutoriel.

  1. Cliquez avec le bouton droit sur le nom du projet (Wingtip Toys) dans Explorateur de solutions, puis sélectionnez Ajouter un nouveau dossier.

    Paiement et paiement avec PayPal - Nouveau dossier

  2. Nommez le nouveau dossier Checkout.

  3. Cliquez avec le bouton droit sur le dossier Checkout, puis sélectionnez Ajouter un>nouvel élément.

    Paiement et paiement avec PayPal - Nouvel élément

  4. La boîte de dialogue Ajouter un nouvel élément s’affiche.

  5. Sélectionnez le groupe Visual C# -> Modèles web sur la gauche. Ensuite, dans le volet central, sélectionnez Formulaire web avec page maîtreet nommez-le CheckoutStart.aspx.

    Paiement et paiement avec PayPal - Boîte de dialogue Ajouter un nouvel élément

  6. Comme précédemment, sélectionnez le fichier Site.Master comme page master.

  7. Ajoutez les pages supplémentaires suivantes au dossier Checkout en suivant les mêmes étapes ci-dessus :

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

Ajouter un fichier Web.config

En ajoutant un nouveau fichier Web.config au dossier Checkout , vous pouvez restreindre l’accès à toutes les pages contenues dans le dossier.

  1. Cliquez avec le bouton droit sur le dossier Checkout et sélectionnez Ajouter ->Nouvel élément.
    La boîte de dialogue Ajouter un nouvel élément s’affiche.

  2. Sélectionnez le groupe Visual C# -> Modèles web sur la gauche. Ensuite, dans le volet central, sélectionnez Fichier de configuration web, acceptez le nom par défaut de Web.config, puis sélectionnez Ajouter.

  3. Remplacez le contenu XML existant dans le fichier Web.config par le code suivant :

    <?xml version="1.0"?>
    <configuration>
      <system.web>
        <authorization>
          <deny users="?"/>
        </authorization>
      </system.web>
    </configuration>
    
  4. Enregistrez le fichier Web.config .

Le fichier Web.config spécifie que tous les utilisateurs inconnus de l’application web doivent se voir refuser l’accès aux pages contenues dans le dossier Checkout . Toutefois, si l’utilisateur a inscrit un compte et est connecté, il sera un utilisateur connu et aura accès aux pages du dossier Checkout .

Il est important de noter que ASP.NET configuration suit une hiérarchie, où chaque fichier Web.config applique les paramètres de configuration au dossier dans lequel il se trouve et à tous les répertoires enfants situés en dessous.

Activation du protocole SSL pour le projet

SSL (Secure Sockets Layer) est un protocole défini pour autoriser les serveurs et clients web à communiquer de manière plus sécurisée grâce au chiffrement. Lorsque SSL n'est pas utilisé, les données envoyées entre le client et le serveur peuvent être soumises à la détection des paquets par quiconque dispose d'un accès physique au réseau. En outre, plusieurs schémas d'authentification ne sont pas sécurisés sur le HTTP standard. En particulier, l'authentification de base et l'authentification par formulaires envoient des informations d'identification non chiffrées. Pour être sécurisés, ces schémas d'authentification doivent utiliser SSL.

  1. Dans Explorateur de solutions, cliquez sur le projet WingtipToys, puis appuyez sur F4 pour afficher la fenêtre Propriétés.
  2. Définissez l’option SSL activé sur true.
  3. Copiez l’ URL SSL afin de pouvoir l’utiliser ultérieurement.
    L’URL SSL sera https://localhost:44300/ sauf si vous avez déjà créé des sites Web SSL (comme indiqué ci-dessous).
    Propriétés du projet
  4. Dans Explorateur de solutions, cliquez avec le bouton droit sur le projet WingtipToys, puis cliquez sur Propriétés.
  5. Dans l’onglet de gauche, cliquez sur Web.
  6. Modifiez l’URL du projet pour utiliser l’URL SSL que vous avez enregistrée précédemment.
    Propriétés web du projet
  7. Enregistrez la page en appuyant sur Ctrl+S.
  8. Appuyez sur Ctrl+F5 pour exécuter l’application. Visual Studio affiche une option qui vous permet d'éviter les avertissements SSL.
  9. Cliquez sur Oui pour approuver le certificat IIS Express SSL et continuer.
    IIS Express détails du certificat SSL
    Un avertissement de sécurité s’affiche.
  10. Cliquez sur Oui pour installer le certificat sur votre hôte local (localhost).
    Boîte de dialogue Avertissement de sécurité
    La fenêtre du navigateur s’affiche.

Vous pouvez maintenant facilement tester votre application web localement à l’aide de SSL.

Ajout d'un fournisseur OAuth 2.0

ASP.NET Web Forms fournit des options améliorées pour l’appartenance et l’authentification. Ces améliorations incluent OAuth. OAuth est un protocole ouvert qui permet une autorisation sécurisée dans une méthode simple et standard à partir d’applications web, mobiles et de bureau. Le modèle ASP.NET Web Forms utilise OAuth pour exposer Facebook, Twitter, Google et Microsoft en tant que fournisseurs d’authentification. Bien que ce tutoriel utilise uniquement Google comme fournisseur d’authentification, vous pouvez facilement modifier le code pour utiliser l’un des fournisseurs. Les étapes d’implémentation d’autres fournisseurs sont très similaires à celles que vous verrez dans ce tutoriel.

En plus de l’authentification, ce didacticiel va également utiliser des rôles pour l’implémentation d’autorisations. Seuls les utilisateurs que vous ajoutez au rôle canEdit pourront créer, modifier ou supprimer des contacts.

Notes

Les applications Windows Live acceptent uniquement une URL dynamique pour un site web de travail, de sorte que vous ne pouvez pas utiliser une URL de site web local pour tester les connexions.

Les étapes suivantes vous permettent d'ajouter un fournisseur d'authentification Google.

  1. Ouvrez le fichier App_Start\Startup.Auth.cs .

  2. Supprimez les caractères de commentaire de la méthode app.UseGoogleAuthentication() de telle sorte qu’elle ait l’aspect suivant :

    app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions()
    {
        ClientId = "",
        ClientSecret = ""
    });
    
  3. Accédez à la Console développeur de Google. Vous devez également vous connecter avec votre compte de messagerie de développeur Google (gmail.com). Si vous n’avez pas de compte Google, sélectionnez le lien Créer un compte .
    Vous accédez alors à Google Developers Console.
    Console des développeurs Google

  4. Cliquez sur le bouton Créer un projet , puis entrez un nom et un ID de projet (vous pouvez utiliser les valeurs par défaut). Ensuite, cliquez sur la case à cocher contrat et sur le bouton Créer .

    Google - Nouveau projet

    En quelques secondes, le projet est créé et votre navigateur affiche la nouvelle page de projets.

  5. Dans l’onglet gauche, cliquez sur API & authentification, puis sur Informations d’identification.

  6. Cliquez sur Créer un ID client sous OAuth.
    La boîte de dialogue Créer un identifiant client s’affiche.
    Google - Créer un ID client

  7. Dans la boîte de dialogue Créer un ID client , conservez l’application web par défaut pour le type d’application.

  8. Définissez les origines JavaScript autorisées sur l’URL SSL que vous avez utilisée précédemment dans ce didacticiel (https://localhost:44300/ sauf si vous avez créé d’autres projets SSL).
    Cette URL est l'origine de votre application. Pour cet exemple, vous entrerez uniquement l'URL de test de l'hôte local (localhost). Toutefois, vous pouvez entrer plusieurs URL pour tenir compte de localhost et de production.

  9. Définissez les URI de redirection autorisés comme suit :

    https://localhost:44300/signin-google
    

    Cette valeur est l’URI que le protocole OAuth ASP.NET utilise pour communiquer avec le serveur OAuth Google. N’oubliez pas l’URL SSL que vous avez utilisée ci-dessus ( https://localhost:44300/ sauf si vous avez créé d’autres projets SSL).

  10. Cliquez sur le bouton Créer un ID client .

  11. Dans le menu de gauche de la console Google Developers, cliquez sur l’élément de menu de l’écran Consentement , puis définissez votre adresse e-mail et votre nom de produit. Une fois le formulaire rempli, cliquez sur Enregistrer.

  12. Cliquez sur l’élément de menu API , faites défiler vers le bas, puis cliquez sur le bouton Désactivé en regard de l’API Google+.
    L’acceptation de cette option active l’API Google+.

  13. Vous devez également mettre à jour le package NuGet Microsoft.Owin vers la version 3.0.0.
    Dans le menu Outils , sélectionnez Gestionnaire de package NuGet , puis Gérer les packages NuGet pour la solution.
    Dans la fenêtre Gérer les packages NuGet , recherchez et mettez à jour le package Microsoft.Owin vers la version 3.0.0.

  14. Dans Visual Studio, mettez à jour la UseGoogleAuthentication méthode de la page Startup.Auth.cs en copiant et collant l’ID client et la clé secrète client dans la méthode. Les valeurs ID client et Secret client ci-dessous sont des exemples et ne fonctionneront pas.

    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. Appuyez sur CTRL+F5 pour générer et exécuter l’application. Cliquez sur le lien Ouvrir une session .

  16. Sous Utiliser un autre service pour vous connecter, cliquez sur Google.
    Se connecter

  17. Si vous devez entrer vos informations d’identification, vous êtes redirigé vers le site Google approprié.
    Google - Se connecter

  18. Une fois que vous avez entré vos informations d’identification, vous êtes invité à accorder des autorisations à l’application web que vous venez de créer.
    Compte de service de projet par défaut

  19. Cliquez sur Accepter. Vous êtes désormais redirigé vers la page Inscrire de l’application WingtipToys , où vous pouvez inscrire votre compte Google.
    S’inscrire avec votre compte Google

  20. Vous avez la possibilité de changer le nom d'inscription local utilisé pour votre compte Gmail, mais, en règle générale, les utilisateurs préfèrent conserver l'alias de messagerie par défaut (c'est-à-dire celui que vous avez utilisé pour l'authentification). Cliquez sur Se connecter comme indiqué ci-dessus.

Modification des fonctionnalités de connexion

Comme mentionné précédemment dans cette série de tutoriels, la plupart des fonctionnalités d’inscription des utilisateurs ont été incluses dans le modèle ASP.NET Web Forms par défaut. Vous allez maintenant modifier les pages Login.aspx et Register.aspx par défaut pour appeler la MigrateCart méthode. La MigrateCart méthode associe un utilisateur nouvellement connecté à un panier d’achat anonyme. En associant l’utilisateur et le panier d’achat, l’exemple d’application Wingtip Toys sera en mesure de gérer le panier d’achat de l’utilisateur entre les visites.

  1. Dans Explorateur de solutions, recherchez et ouvrez le dossier Compte.

  2. Modifiez la page code-behind nommée Login.aspx.cs pour inclure le code mis en surbrillance en jaune, afin qu’il apparaisse comme suit :

    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. Enregistrez le fichier Login.aspx.cs .

Pour l’instant, vous pouvez ignorer l’avertissement indiquant qu’il n’existe aucune définition pour la MigrateCart méthode. Vous l’ajouterez un peu plus loin dans ce tutoriel.

Le fichier code-behind Login.aspx.cs prend en charge une méthode LogIn. En inspectant la page Login.aspx, vous verrez que cette page comprend un bouton « Se connecter » qui, quand un clic déclenche le LogIn gestionnaire sur le code-behind.

Lorsque la Login méthode de Login.aspx.cs est appelée, une nouvelle instance du panier d’achat nommée usersShoppingCart est créée. L’ID du panier d’achat (GUID) est récupéré et défini sur la cartId variable. Ensuite, la MigrateCart méthode est appelée, passant à la fois le cartId et le nom de l’utilisateur connecté à cette méthode. Lorsque le panier d’achat est migré, le GUID utilisé pour identifier le panier d’achat anonyme est remplacé par le nom d’utilisateur.

En plus de modifier le fichier code-behind Login.aspx.cs pour migrer le panier d’achat lorsque l’utilisateur se connecte, vous devez également modifier le fichier code-behind Register.aspx.cs pour migrer le panier d’achat lorsque l’utilisateur crée un compte et se connecte.

  1. Dans le dossier Compte , ouvrez le fichier code-behind nommé Register.aspx.cs.

  2. Modifiez le fichier code-behind en incluant le code en jaune, afin qu’il apparaisse comme suit :

    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. Enregistrez le fichier Register.aspx.cs . Une fois de plus, ignorez l’avertissement concernant la MigrateCart méthode.

Notez que le code que vous avez utilisé dans le CreateUser_Click gestionnaire d’événements est très similaire au code que vous avez utilisé dans la LogIn méthode . Lorsque l’utilisateur s’inscrit ou se connecte au site, un appel à la MigrateCart méthode est effectué.

Migration du panier d’achat

Maintenant que vous avez mis à jour le processus de connexion et d’inscription, vous pouvez ajouter le code pour migrer le panier à l’aide de la MigrateCart méthode .

  1. Dans Explorateur de solutions, recherchez le dossier Logique et ouvrez le fichier de classe ShoppingCartActions.cs.

  2. Ajoutez le code mis en surbrillance en jaune au code existant dans le fichier ShoppingCartActions.cs , afin que le code dans le fichier ShoppingCartActions.cs s’affiche comme suit :

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

La MigrateCart méthode utilise le cartId existant pour rechercher le panier de l’utilisateur. Ensuite, le code boucle tous les éléments du panier et remplace la CartId propriété (comme spécifié par le schéma) par le CartItem nom d’utilisateur connecté.

Mise à jour de la connexion de base de données

Si vous suivez ce tutoriel à l’aide de l’exemple d’application Wingtip Toys prédéfinie , vous devez recréer la base de données d’appartenance par défaut. En modifiant la chaîne de connexion par défaut, la base de données d’appartenance est créée lors de la prochaine exécution de l’application.

  1. Ouvrez le fichier Web.config à la racine du projet.

  2. Mettez à jour le chaîne de connexion par défaut afin qu’il s’affiche comme suit :

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

Intégration de PayPal

PayPal est une plateforme de facturation web qui accepte les paiements par les marchands en ligne. Ce tutoriel explique ensuite comment intégrer la fonctionnalité Paiement express de PayPal dans votre application. Express Checkout permet à vos clients d’utiliser PayPal pour payer les articles qu’ils ont ajoutés à leur panier d’achat.

Créer des comptes de test PayPal

Pour utiliser l’environnement de test PayPal, vous devez créer et vérifier un compte de test de développeur. Vous utiliserez le compte de test développeur pour créer un compte de test d’acheteur et un compte de test vendeur. Les informations d’identification du compte de test du développeur permettent également à l’exemple d’application Wingtip Toys d’accéder à l’environnement de test PayPal.

  1. Dans un navigateur, accédez au site de test du développeur PayPal :
    https://developer.paypal.com

  2. Si vous n’avez pas de compte de développeur PayPal, créez un compte en cliquant sur S’inscrireet en suivant les étapes d’inscription. Si vous disposez d’un compte de développeur PayPal, connectez-vous en cliquant sur Se connecter. Vous aurez besoin de votre compte de développeur PayPal pour tester l’exemple d’application Wingtip Toys plus loin dans ce tutoriel.

  3. Si vous venez de vous inscrire à votre compte de développeur PayPal, vous devrez peut-être vérifier votre compte de développeur PayPal auprès de PayPal. Vous pouvez vérifier votre compte en suivant les étapes que PayPal a envoyées à votre compte de messagerie. Une fois que vous avez vérifié votre compte de développeur PayPal, reconnectez-vous au site de test des développeurs PayPal.

  4. Une fois que vous êtes connecté au site du développeur PayPal avec votre compte de développeur PayPal, vous devez créer un compte de test d’acheteur PayPal si vous n’en avez pas déjà un. Pour créer un compte de test d’acheteur, sur le site PayPal, cliquez sur l’onglet Applications , puis sur Comptes de bac à sable.
    La page Comptes de test de bac à sable s’affiche.

    Notes

    Le site du développeur PayPal fournit déjà un compte de test marchand.

    Capture d’écran montrant la page Comptes de test de bac à sable avec l’onglet Applications mis en évidence.

  5. Dans la page Comptes de test de bac à sable, cliquez sur Créer un compte.

  6. Dans la page Créer un compte de test , choisissez l’adresse e-mail et le mot de passe d’un compte de test d’acheteur de votre choix.

    Notes

    Vous aurez besoin des adresses e-mail et du mot de passe de l’acheteur pour tester l’exemple d’application Wingtip Toys à la fin de ce tutoriel.

    Capture d’écran de la page Créer un compte de test affichant les champs d’un compte en cours de création.

  7. Créez le compte de test de l’acheteur en cliquant sur le bouton Créer un compte .
    La page Comptes de test de bac à sable s’affiche.

    Paiement et paiement avec PayPal - Comptes PayPal

  8. Dans la page Comptes de test de bac à sable , cliquez sur le compte de messagerie du facilitateur .
    Les options Profil et Notification s’affichent.

  9. Sélectionnez l’option Profil , puis cliquez sur Informations d’identification de l’API pour afficher vos informations d’identification d’API pour le compte de test marchand.

  10. Copiez les informations d’identification de l’API TEST dans le Bloc-notes.

Vous aurez besoin de vos informations d’identification de l’API TEST classique affichées (nom d’utilisateur, mot de passe et signature) pour effectuer des appels d’API à partir de l’exemple d’application Wingtip Toys vers l’environnement de test PayPal. Vous ajouterez les informations d’identification à l’étape suivante.

Ajouter des informations d’identification d’API et de classe PayPal

Vous placez la majorité du code PayPal dans une seule classe. Cette classe contient les méthodes utilisées pour communiquer avec PayPal. En outre, vous allez ajouter vos informations d’identification PayPal à cette classe.

  1. Dans l’exemple d’application Wingtip Toys dans Visual Studio, cliquez avec le bouton droit sur le dossier Logique , puis sélectionnez Ajouter ->Nouvel élément.
    La boîte de dialogue Ajouter un nouvel élément s’affiche.

  2. Sous Visual C# dans le volet Installé à gauche, sélectionnez Code.

  3. Dans le volet central, sélectionnez Classe. Nommez cette nouvelle classe PayPalFunctions.cs.

  4. Cliquez sur Ajouter.
    Le nouveau fichier de classe s’affiche dans l’éditeur.

  5. Remplacez le code par défaut par le code suivant :

    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. Ajoutez les informations d’identification de l’API Merchant (nom d’utilisateur, mot de passe et signature) que vous avez affichées précédemment dans ce tutoriel afin de pouvoir effectuer des appels de fonction vers l’environnement de test PayPal.

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

Notes

Dans cet exemple d’application, vous ajoutez simplement des informations d’identification à un fichier C# (.cs). Toutefois, dans une solution implémentée, vous devez envisager de chiffrer vos informations d’identification dans un fichier de configuration.

La classe NVPAPICaller contient la majorité des fonctionnalités PayPal. Le code de la classe fournit les méthodes nécessaires pour effectuer un achat de test à partir de l’environnement de test PayPal. Les trois fonctions PayPal suivantes sont utilisées pour effectuer des achats :

  • Fonction SetExpressCheckout
  • Fonction GetExpressCheckoutDetails
  • Fonction DoExpressCheckoutPayment

La ShortcutExpressCheckout méthode collecte les informations d’achat de test et les détails du produit à partir du panier d’achat et appelle la SetExpressCheckout fonction PayPal. La GetCheckoutDetails méthode confirme les détails de l’achat et appelle la GetExpressCheckoutDetails fonction PayPal avant d’effectuer l’achat de test. La DoCheckoutPayment méthode termine l’achat de test à partir de l’environnement de test en appelant la DoExpressCheckoutPayment fonction PayPal. Le code restant prend en charge les méthodes et processus PayPal, tels que l’encodage des chaînes, le décodage de chaînes, le traitement des tableaux et la détermination des informations d’identification.

Notes

PayPal vous permet d’inclure des détails d’achat facultatifs en fonction de la spécification de l’API de PayPal. En étendant le code dans l’exemple d’application Wingtip Toys, vous pouvez inclure des détails de localisation, des descriptions de produits, des taxes, un numéro de service client, ainsi que de nombreux autres champs facultatifs.

Notez que les URL de retour et d’annulation spécifiées dans la méthode ShortcutExpressCheckout utilisent un numéro de port.

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

Lorsque Visual Web Developer exécute un projet web à l’aide de SSL, le port 44300 est généralement utilisé pour le serveur web. Comme indiqué ci-dessus, le numéro de port est 44300. Lorsque vous exécutez l’application, vous pouvez voir un numéro de port différent. Votre numéro de port doit être correctement défini dans le code afin que vous puissiez exécuter correctement l’exemple d’application Wingtip Toys à la fin de ce tutoriel. La section suivante de ce didacticiel explique comment récupérer le numéro de port de l’hôte local et mettre à jour la classe PayPal.

Mettre à jour le numéro de port LocalHost dans la classe PayPal

L’exemple d’application Wingtip Toys achète des produits en accédant au site de test PayPal et en retournant à votre instance locale de l’exemple d’application Wingtip Toys. Pour que PayPal retourne l’URL correcte, vous devez spécifier le numéro de port de l’exemple d’application en cours d’exécution locale dans le code PayPal mentionné ci-dessus.

  1. Cliquez avec le bouton droit sur le nom du projet (WingtipToys) dans Explorateur de solutions, puis sélectionnez Propriétés.

  2. Dans la colonne de gauche, sélectionnez l’onglet Web .

  3. Récupérez le numéro de port à partir de la zone URL du projet .

  4. Si nécessaire, mettez à jour et returnURLcancelURL dans la classe PayPal (NVPAPICaller) dans le fichier PayPalFunctions.cs pour utiliser le numéro de port de votre application web :

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

À présent, le code que vous avez ajouté correspond au port attendu pour votre application web locale. PayPal pourra revenir à l’URL correcte sur votre ordinateur local.

Ajouter le bouton Paiement PayPal

Maintenant que les fonctions PayPal principales ont été ajoutées à l’exemple d’application, vous pouvez commencer à ajouter le balisage et le code nécessaires pour appeler ces fonctions. Tout d’abord, vous devez ajouter le bouton de paiement que l’utilisateur verra sur la page du panier d’achat.

  1. Ouvrez le fichier ShoppingCart.aspx .

  2. Faites défiler jusqu’au bas du fichier et recherchez le <!--Checkout Placeholder --> commentaire.

  3. Remplacez le commentaire par un ImageButton contrôle afin que le mark up soit remplacé comme suit :

    <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. Dans le fichier ShoppingCart.aspx.cs , après le UpdateBtn_Click gestionnaire d’événements à la fin du fichier, ajoutez le gestionnaire d’événements CheckOutBtn_Click :

    protected void CheckoutBtn_Click(object sender, ImageClickEventArgs e)
    {
        using (ShoppingCartActions usersShoppingCart = new ShoppingCartActions())
        {
            Session["payment_amt"] = usersShoppingCart.GetTotal();
        }
        Response.Redirect("Checkout/CheckoutStart.aspx");
    }
    
  5. Également dans le fichier ShoppingCart.aspx.cs , ajoutez une référence au CheckoutBtn, afin que le bouton nouvelle image soit référencé comme suit :

    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. Enregistrez vos modifications dans les fichiers ShoppingCart.aspx et ShoppingCart.aspx.cs .

  7. Dans le menu, sélectionnez Debug-Build>WingtipToys.
    Le projet sera reconstruit avec le contrôle ImageButton nouvellement ajouté.

Envoyer les détails de l’achat à PayPal

Lorsque l’utilisateur clique sur le bouton Paiement sur la page du panier d’achat (ShoppingCart.aspx), il commence le processus d’achat. Le code suivant appelle la première fonction PayPal nécessaire pour acheter des produits.

  1. Dans le dossier Checkout , ouvrez le fichier code-behind nommé CheckoutStart.aspx.cs.
    Veillez à ouvrir le fichier code-behind.

  2. Remplacez le code existant par le code ci-dessous :

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

Lorsque l’utilisateur de l’application clique sur le bouton Checkout dans la page du panier d’achat, le navigateur accède à la page CheckoutStart.aspx . Lorsque la page CheckoutStart.aspx se charge, la ShortcutExpressCheckout méthode est appelée. À ce stade, l’utilisateur est transféré vers le site web de test PayPal. Sur le site PayPal, l’utilisateur entre ses informations d’identification PayPal, passe en revue les détails de l’achat, accepte le contrat PayPal et retourne à l’exemple d’application Wingtip Toys où la ShortcutExpressCheckout méthode se termine. Une fois la ShortcutExpressCheckout méthode terminée, elle redirige l’utilisateur vers la page CheckoutReview.aspx spécifiée dans la ShortcutExpressCheckout méthode . Cela permet à l’utilisateur de passer en revue les détails de la commande à partir de l’exemple d’application Wingtip Toys.

Examiner les détails de la commande

Après le retour de PayPal, la page CheckoutReview.aspx de l’exemple d’application Wingtip Toys affiche les détails de la commande. Cette page permet à l’utilisateur de passer en revue les détails de la commande avant d’acheter les produits. La page CheckoutReview.aspx doit être créée comme suit :

  1. Dans le dossier Checkout , ouvrez la page nommée CheckoutReview.aspx.

  2. Remplacez le balisage existant par ce qui suit :

    <%@ 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. Ouvrez la page code-behind nommée CheckoutReview.aspx.cs et remplacez le code existant par ce qui suit :

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

Le contrôle DetailsView permet d’afficher les détails de commande retournés par PayPal. En outre, le code ci-dessus enregistre les détails de la commande dans la base de données Wingtip Toys en tant qu’objet OrderDetail . Lorsque l’utilisateur clique sur le bouton Terminer la commande , il est redirigé vers la page CheckoutComplete.aspx .

Notes

Conseil

Dans le balisage de la page CheckoutReview.aspx , notez que la <ItemStyle> balise est utilisée pour modifier le style des éléments dans le contrôle DetailsView en bas de la page. En affichant la page en mode Création (en sélectionnant Création dans le coin inférieur gauche de Visual Studio), puis en sélectionnant le contrôle DetailsView et en sélectionnant la balise active (l’icône de flèche en haut à droite du contrôle), vous pouvez voir les tâches DetailsView.

Paiement et paiement avec PayPal - Modifier les champs

En sélectionnant Modifier les champs, la boîte de dialogue Champs s’affiche. Dans cette boîte de dialogue, vous pouvez facilement contrôler les propriétés visuelles, telles que ItemStyle, du contrôle DetailsView .

Paiement et paiement avec PayPal - Boîte de dialogue Champs

Terminer l’achat

La page CheckoutComplete.aspx effectue l’achat auprès de PayPal. Comme mentionné ci-dessus, l’utilisateur doit cliquer sur le bouton Terminer la commande pour que l’application accède à la page CheckoutComplete.aspx .

  1. Dans le dossier Checkout , ouvrez la page nommée CheckoutComplete.aspx.

  2. Remplacez le balisage existant par ce qui suit :

    <%@ 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. Ouvrez la page code-behind nommée CheckoutComplete.aspx.cs et remplacez le code existant par ce qui suit :

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

Lorsque la page CheckoutComplete.aspx est chargée, la DoCheckoutPayment méthode est appelée. Comme mentionné précédemment, la DoCheckoutPayment méthode termine l’achat à partir de l’environnement de test PayPal. Une fois que PayPal a terminé l’achat de la commande, la page CheckoutComplete.aspx affiche une transaction ID de paiement à l’acheteur.

Gérer annuler l’achat

Si l’utilisateur décide d’annuler l’achat, il sera dirigé vers la page CheckoutCancel.aspx où il verra que sa commande a été annulée.

  1. Ouvrez la page nommée CheckoutCancel.aspx dans le dossier Checkout .

  2. Remplacez le balisage existant par ce qui suit :

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

Gérer les erreurs d’achat

Les erreurs pendant le processus d’achat sont gérées par la page CheckoutError.aspx . Le code-behind de la page CheckoutStart.aspx , la page CheckoutReview.aspx et la page CheckoutComplete.aspx redirigent chacun vers la page CheckoutError.aspx si une erreur se produit.

  1. Ouvrez la page nommée CheckoutError.aspx dans le dossier Checkout .

  2. Remplacez le balisage existant par ce qui suit :

    <%@ 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 page CheckoutError.aspx s’affiche avec les détails de l’erreur lorsqu’une erreur se produit pendant le processus de validation.

Exécution de l'application

Exécutez l’application pour voir comment acheter des produits. Notez que vous allez exécuter dans l’environnement de test PayPal. Aucun argent réel n’est échangé.

  1. Vérifiez que tous vos fichiers sont enregistrés dans Visual Studio.

  2. Ouvrez un navigateur web et accédez à https://developer.paypal.com.

  3. Connectez-vous avec votre compte de développeur PayPal que vous avez créé précédemment dans ce tutoriel.
    Pour le bac à sable de développeur de PayPal, vous devez être connecté à l’adresse https://developer.paypal.com pour tester l’extraction rapide. Cela s’applique uniquement au test de bac à sable de PayPal, et non à l’environnement en direct de PayPal.

  4. Dans Visual Studio, appuyez sur F5 pour exécuter l’exemple d’application Wingtip Toys.
    Une fois la base de données reconstruite, le navigateur s’ouvre et affiche la page Default.aspx .

  5. Ajoutez trois produits différents au panier en sélectionnant la catégorie de produit, par exemple « Voitures », puis en cliquant sur Ajouter au panier en regard de chaque produit.
    Le panier d’achat affiche le produit que vous avez sélectionné.

  6. Cliquez sur le bouton PayPal pour effectuer un paiement.

    Paiement et paiement avec PayPal - Panier

    L’extraction nécessite que vous disposiez d’un compte d’utilisateur pour l’exemple d’application Wingtip Toys.

  7. Cliquez sur le lien Google à droite de la page pour vous connecter avec un compte de messagerie gmail.com existant.
    Si vous n’avez pas de compte gmail.com, vous pouvez en créer un à des fins de test à www.gmail.com. Vous pouvez également utiliser un compte local standard en cliquant sur « Inscrire ».

    Paiement et paiement avec PayPal - Connexion

  8. Connectez-vous avec votre compte gmail et votre mot de passe.

    Paiement et paiement avec PayPal - Connexion Gmail

  9. Cliquez sur le bouton Se connecter pour inscrire votre compte gmail avec le nom d’utilisateur de votre exemple d’application Wingtip Toys.

    Paiement et paiement avec PayPal - Inscrire un compte

  10. Sur le site de test PayPal, ajoutez votre adresse e-mail et votre mot de passe d’acheteur que vous avez créés précédemment dans ce tutoriel, puis cliquez sur le bouton Connexion .

    Paiement et paiement avec PayPal - Connexion PayPal

  11. Acceptez la stratégie PayPal et cliquez sur le bouton Accepter et continuer .
    Notez que cette page s’affiche uniquement la première fois que vous utilisez ce compte PayPal. Notez encore qu’il s’agit d’un compte de test, aucun argent réel n’est échangé.

    Paiement et paiement avec PayPal - Politique PayPal

  12. Passez en revue les informations de commande sur la page de révision de l’environnement de test PayPal, puis cliquez sur Continuer.

    Paiement et paiement avec PayPal - Vérifier les informations

  13. Dans la page CheckoutReview.aspx , vérifiez le montant de la commande et affichez l’adresse de livraison générée. Cliquez ensuite sur le bouton Terminer la commande .

    Paiement et paiement avec PayPal - Révision de commande

  14. La page CheckoutComplete.aspx s’affiche avec un ID de transaction de paiement.

    Paiement et paiement avec PayPal - Paiement terminé

Examen de la base de données

En examinant les données mises à jour dans l’exemple de base de données d’application Wingtip Toys après l’exécution de l’application, vous pouvez voir que l’application a correctement enregistré l’achat des produits.

Vous pouvez inspecter les données contenues dans le fichier de base de données Wingtiptoys.mdf à l’aide de la fenêtre Explorer de base de données (fenêtre Server Explorer dans Visual Studio) comme vous l’avez fait précédemment dans cette série de tutoriels.

  1. Fermez la fenêtre du navigateur si elle est toujours ouverte.

  2. Dans Visual Studio, sélectionnez l’icône Afficher tous les fichiers en haut de Explorateur de solutions pour vous permettre de développer le dossier App_Data.

  3. Développez le dossier App_Data .
    Vous devrez peut-être sélectionner l’icône Afficher tous les fichiers pour le dossier.

  4. Cliquez avec le bouton droit sur le fichier de base de données Wingtiptoys.mdf , puis sélectionnez Ouvrir.
    Le serveur Explorer s’affiche.

  5. Développez le dossier Tables .

  6. Cliquez avec le bouton droit sur la table Orderset sélectionnez Afficher les données de table.
    La table Orders s’affiche.

  7. Passez en revue la colonne PaymentTransactionID pour confirmer la réussite des transactions.

    Paiement et paiement avec PayPal - Base de données de révision

  8. Fermez la fenêtre de la table Orders .

  9. Dans l’Explorer serveur, cliquez avec le bouton droit sur la table OrderDetails et sélectionnez Afficher les données de table.

  10. Passez en revue les OrderId valeurs et Username dans la table OrderDetails . Notez que ces valeurs correspondent aux OrderId valeurs et Username incluses dans la table Orders .

  11. Fermez la fenêtre de table OrderDetails .

  12. Cliquez avec le bouton droit sur le fichier de base de données Wingtip Toys (Wingtiptoys.mdf), puis sélectionnez Fermer la connexion.

  13. Si vous ne voyez pas la fenêtre Explorateur de solutions, cliquez sur Explorateur de solutions en bas de la fenêtre Explorer serveur pour afficher à nouveau le Explorateur de solutions.

Résumé

Dans ce tutoriel, vous avez ajouté des schémas de détails de commande et de commande pour suivre l’achat de produits. Vous avez également intégré la fonctionnalité PayPal dans l’exemple d’application Wingtip Toys.

Ressources supplémentaires

Vue d’ensemble de la configuration ASP.NET
Déployer une application ASP.NET Web Forms sécurisée avec appartenance, OAuth et SQL Database sur Azure App Service
Microsoft Azure - Essai gratuit

Clause d'exclusion de responsabilité

Ce tutoriel contient un exemple de code. Cet exemple de code est fourni « tel quel » sans garantie d’aucune sorte. Par conséquent, Microsoft ne garantit pas la précision, l’intégrité ou la qualité de l’exemple de code. Vous acceptez d’utiliser l’exemple de code à vos propres risques. En aucun cas, Microsoft ne sera responsable envers vous d’un exemple de code, d’un contenu, y compris, mais sans s’y limiter, d’erreurs ou d’omissions dans un exemple de code, de contenu ou de toute perte ou dommage de quelque nature que ce soit résultant de l’utilisation d’un exemple de code. Vous êtes informé par les présentes et acceptez par les présentes d’être indemnisé, d’épargner et de tenir Microsoft de toute responsabilité contre toute perte, réclamation de perte, blessure ou dommage de quelque nature que ce soit, y compris, sans limitation, celles qui sont provoquées par ou découlant de matériel que vous publiez, transmettez, utilisez ou utilisez, y compris, mais sans s’y limiter, les vues exprimées dans ce document.