Aller au contenu principal

33-3 Intégration de Stripe Checkout

Installer Stripe.net

Stripe propose une librairie pour .NET facilitant la communication avec ses API, en plus d'offrir des objets et fonctions facilitant l'interaction avec Stripe. Il est possible d'installer cette dernière via NuGet.

  1. Sous le projet Mvc -> Manage NuGet Packages
  2. Rechercher Stripe.net
  3. Installer la librairie dans le projet Mvc

Configurer le service Stripe

La librairie Stripe.net vient avec un service appelé SessionService responsable de créer des sessions de Checkout.

Cependant, pour utiliser ce service, on doit le rendre disponible pour injection de dépendance en plus de configurer Stripe.Net pour utiliser la clé privée provenant de appsettings.

Dans Program.cs du projet MVC, ajoutez à la liste de services disponibles SessionService et utilisez la clé secrète de appsettings pour la configuration de Stripe.

Snowfall.Web.Mvc/Program.cs
// Stripe
builder.Services.AddScoped<SessionService>();
string secretKey = builder.Configuration["Stripe:SecretKey"]!;
StripeConfiguration.ApiKey = secretKey;
info

IMPORTANT: importez SessionService de Stripe.Checkout.

Je propose de mettre l'injection du service directement dans program.cs plutôt que dans le fichier partagé dans le dossier Shared puisqu'il s'agit d'une dépendance qui ne sera pas utilisée par les autres projets (ex.: API). En effet, l'achat avec Stripe est propre au projet MVC.

Créer une session Stripe

Tout commence par une session Stripe. Une session vient avec un identifiant unique fourni par Stripe (id) et les informations de la commande.

C'est ce qui nous permet de rediriger l'utilisateur vers le site de Stripe pour la prise de paiement et que Stripe puisse être en mesure de récupérer le contenu de la commande. En effet, en renvoyant l'utilisateur vers Stripe pour le paiement, on inclut le id de session unique.

Lorsque le paiement sera effectué, Stripe redirigera vers notre site en incluant le id de session. C'est ce qui permettra à notre tour de compléter la commande.

  1. Dans le contrôleur d'achat, injectez SessionService pour pouvoir l'utiliser et créer une session Stripe. Par exemple:

    Snowfall.Web.Mvc/Controllers/AchatsController.cs
    private readonly IEvenementService _evenementService;
    private readonly IInscriptionService _inscriptionService;
    private readonly IPrixService _prixService;
    private readonly UserManager<ApplicationUser> _userManager;
    private readonly SessionService _stripeSessionService;

    public InscriptionsController(
    IEvenementService evenementService,
    IInscriptionService inscriptionService,
    IPrixService prixService,
    UserManager<ApplicationUser> userManager,
    SessionService stripeSessionService)
    {
    _evenementService = evenementService;
    _inscriptionService = inscriptionService;
    _prixService = prixService;
    _userManager = userManager;
    _stripeSessionService = stripeSessionService;
    }
  2. Toujours dans votre contrôleur d'achat, juste après avoir calculé le prix de la commande, débutez la création d'une session Stripe. Une session Stripe requiert un objet de type SessionCreateOptions contenant les options associées à la session: les items, le prix, etc. On crée le tout après avoir calculé le prix puisque nous aurons besoin des informations de prix.

    Snowfall.Web.Mvc/Controllers/AchatsController.cs
    public async Task<IActionResult> Create()
    {
    //...

    Prix prix = _prixService.CalculerPrix(evenement);

    var options = new SessionCreateOptions();
    Session session = _stripeSessionService.Create(options);

    //...
    }
  3. À son strict minimum, les options doivent contenir le mode, une URL de retour en cas de paiement réussi et une URL de retour en cas d'annulation du client. Modifiez pour ajouter ces options.

    Snowfall.Web.Mvc/Controllers/AchatsController.cs
    var options = new SessionCreateOptions
    {
    Mode = "payment",
    SuccessUrl = // URL de retour ici
    CancelUrl = // URL en cas d'annulation
    };
    Session session = _stripeSessionService.Create(options);
  4. Nous avons déjà une sorte d'URL de succès, soit l'action Confirmation du contrôleur, mais rien en cas d'annulation. C'est normal, il n'y avait pas vraiment de concept de paiement, donc aucune façon d'annuler ce processus. Pour supporter ce cas de figure, créez une action Annuler, répondant à une action HTTP de type Get et acceptant un identifiant de session stripe en paramètre via son URL.

    [HttpGet("[Action]")]
    public async Task<IActionResult> Annuler([FromQuery] string sessionId)
    {
    return RedirectToAction("Index", "Evenements");
    }
    info

    sessionId sera fourni par Stripe en cas d'annulation. La fonction contiendra plus de code, mais pour l'instant contentons-nous de retourner une redirection vers la page d'accueil.

    La mention [FromQuery] est optionnelle, elle ne fait que préciser que le paramètre proviendra du Query String(?sessionId=...).

  5. Il est maintenant possible de compléter les URLs de succès et d'annulation dans l'action Create puisque les deux actions associées sont en place.

    var options = new SessionCreateOptions
    {
    Mode = "payment",
    SuccessUrl = Url.Action("Confirmation", "Achats", null, Request.Scheme),
    CancelUrl = Url.Action("Annuler", "Achats", null, Request.Scheme)
    };
    info

    On utilise ici Url.Action puisqu'il faut une URL complète (incluant http://...). En effet, on envoie ces URL à Stripe et Stripe doit être en mesure de rediriger à son tour vers notre site. Il a donc besoin d'une URL complète

  6. Ensuite, lorsque le paiement sera complété et que Stripe redirigera vers notre application, on doit obtenir de ce dernier le id de session. Pour ce faire, on peut fournir à Stripe dans nos URL de succès et de retour un genre de gabarit d'URL avec une variable qu'il pourra remplacer par le id de session. Cette variable est prédéfinie par Stripe et doit être nommée {CHECKOUT_SESSION_ID}. Ainsi, modifiez les URL de retour et d'annulation comme suit:

    var options = new SessionCreateOptions
    {
    Mode = "payment",
    SuccessUrl = Url.Action("Confirmation", "Achats", null , Request.Scheme) + "?sessionId={CHECKOUT_SESSION_ID}",
    CancelUrl = Url.Action("Annuler", "Achats", null, Request.Scheme) + "?sessionId={CHECKOUT_SESSION_ID}",
    };
    Session session = _stripeSessionService.Create(options);
    info

    Dans le paramètre d'URL ?sessionId={CHECKOUT_SESSION_ID}, la portion {CHECKOUT_SESSION_ID} sera remplacée par un réel identifiant de session et c'est Stripe qui fera cette opération.

    Au fond, on lui dit que cette portion de l'URL peut être remplacée par son identifiant.

  7. Puis, lors de la création du DTO de d'achat, il faut assigner le statut du paiement (En attente) et l'identifiant de la session Stripe ayant été créé. Modifiez la création du DTO dans l'action Create pour y inclure ces deux nouveaux attributs.

    Snowfall.Web.Mvc/Controllers/AchatsController.cs
    //...
    var options = new SessionCreateOptions
    {
    Mode = "payment",
    SuccessUrl = Url.Action("Confirmation", "Inscriptions", null , Request.Scheme) + "?sessionId={CHECKOUT_SESSION_ID}",
    CancelUrl = Url.Action("Annuler", "Inscriptions", null, Request.Scheme) + "?sessionId={CHECKOUT_SESSION_ID}",
    };
    Session session = _stripeSessionService.Create(options);

    Inscription inscription = new Inscription
    {
    UtilisateurId = utilisateur.Id!,
    // ...
    StatutPaiement = StatutPaiement.Attente,
    StripeSessionId = session.Id
    };

    //...
  8. Pour la suite, assurez vous que vous ne videz pas le contenu du panier dans la fonction Create. En effet, la commande est temporaire à cette étape-ci. Ainsi, si vous avez (vous devriez) une ligne similaire à celle-ci, supprimez-la.

    //...
    // Ligne à retirer si présente!
    HttpContext.Session.Remove("Panier");
    //...
  9. Finalement, après l'insertion dans la BD, autrefois on redirigeait vers la page de confirmation directement, mais il est maintenant nécessaire de passer par Stripe afin de prendre le paiement. Redirigez-vers plutôt l'URL fournie par Stripe contenant l'identifiant de session.

    //return RedirectToAction("Confirmation", new {id = inscription.Id});
    return new RedirectResult(session.Url);

Test

Vous pouvez essayer d'appuyer sur le bouton de confirmation de l'achat (que j'ai renommé "procéder au paiement" dans mon cas pour être plus clair).

Imgur

Malheureusement, vous obtiendrez l'erreur suivante:

Imgur

L'erreur nous indique que Stripe, en mode payment requiers un paramètre line_items, soit les articles à acheter et leur prix.

En effet, on n'a pas fourni de détails quant au prix ni aux articles! Nous verrons cela à la prochaine étape.