# Encaisser un paiement ponctuel sous Elementor avec Stripe Checkout, sans WooCommerce

> Intégration de Stripe Checkout dans un widget HTML Elementor dédié, pour un paiement ponctuel simple, quand WooCommerce Builder serait disproportionné.

- Auteur : WordPress Développement
- Publié le : 2023-12-07
- Mis à jour le : 2023-12-07
- Catégorie : Elementor
- URL : https://www.wpmoderne.fr/elementor/elementor-stripe-checkout-page-paiement-sans-woocommerce/

## L’essentiel

- Session Checkout créée côté serveur avant redirection
- Aucun numéro de carte transitant par le serveur WordPress
- Solution adaptée à un seul produit ou service ponctuel

Installer WooCommerce et son Builder Elementor pour vendre un unique billet d'événement ou une seule prestation ponctuelle représente souvent un coût de maintenance disproportionné par rapport au besoin réel. Sur ce projet, la demande tenait en une phrase : une page Elementor, un bouton « Payer 45 € », une redirection vers un paiement sécurisé, puis une page de confirmation. Rien de plus.

Stripe Checkout, la page de paiement hébergée par Stripe, correspond exactement à ce besoin : aucune donnée de carte bancaire ne transite par le serveur WordPress, la conformité PCI DSS reste entièrement à la charge de Stripe, et l'intégration se limite à créer une session de paiement côté serveur puis à rediriger le visiteur.

## Pourquoi ne pas passer par WooCommerce Builder ici

WooCommerce Builder apporte une richesse fonctionnelle précieuse pour un catalogue de produits, une gestion de stock, des variations, un panier persistant. Pour un paiement ponctuel unique, cette richesse devient un poids : plugin supplémentaire à maintenir, tables de base de données additionnelles, mises à jour à surveiller, pour un usage qui ne dépasse jamais un seul article vendu à la fois.

## Construire le bouton dans un widget HTML Elementor

Le bouton de paiement est un simple widget HTML personnalisé placé dans un Container, avec un formulaire minimal qui appelle une route REST maison au clic, plutôt qu'un widget Bouton natif qui ne gère pas ce type d'appel asynchrone directement.

```
<button id="bouton-paiement" data-produit="billet-conference">
  Payer 45 €
</button>
<script>
document.getElementById('bouton-paiement').addEventListener('click', async (e) => {
  e.target.disabled = true;
  const reponse = await fetch('/wp-json/paiement/v1/creer-session', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ produit: e.target.dataset.produit })
  });
  const { url } = await reponse.json();
  window.location.href = url;
});
</script>
```

> L'essentiel à retenir : Session Checkout créée côté serveur avant redirection ; Aucun numéro de carte transitant par le serveur WordPress ; Solution adaptée à un seul produit ou service ponctuel

## Créer la session Checkout côté serveur

La route REST maison, enregistrée via `register_rest_route()`, appelle le SDK PHP officiel de Stripe pour créer une session Checkout, en fixant le montant côté serveur (jamais transmis depuis le navigateur, pour éviter toute manipulation du prix affiché).

```
add_action('rest_api_init', function () {
    register_rest_route('paiement/v1', '/creer-session', [
        'methods'  => 'POST',
        'callback' => 'creer_session_stripe',
        'permission_callback' => '__return_true',
    ]);
});

function creer_session_stripe(\WP_REST_Request $request) {
    \Stripe\Stripe::setApiKey(getenv('STRIPE_SECRET_KEY'));

    $session = \Stripe\Checkout\Session::create([
        'mode' => 'payment',
        'line_items' => [[
            'price_data' => [
                'currency' => 'eur',
                'unit_amount' => 4500,
                'product_data' => ['name' => 'Billet conférence'],
            ],
            'quantity' => 1,
        ]],
        'success_url' => home_url('/merci-paiement/'),
        'cancel_url'  => home_url('/paiement-annule/'),
    ]);

    return new \WP_REST_Response(['url' => $session->url]);
}
```

## Confirmer le paiement côté serveur, pas seulement l'URL de succès

Un point de sécurité important : la page de confirmation (`success_url`) ne doit jamais servir seule de preuve de paiement, car un visiteur pourrait y accéder manuellement sans avoir payé. La confirmation réelle passe par un webhook Stripe (`checkout.session.completed`), reçu sur une route REST distincte, qui déclenche l'action métier (envoi du billet, activation d'un accès) uniquement à réception de cet événement signé.

- Montant fixé côté serveur, jamais transmis depuis le client
- Confirmation métier déclenchée par webhook signé, pas par la page de succès seule
- Clé secrète Stripe stockée en variable d'environnement, jamais dans le code du thème

Cette intégration ne couvre volontairement pas les paiements récurrents (abonnements) ni la facturation automatisée avec envoi de factures légales, deux besoins qui justifient à eux seuls une solution plus structurée.

> Le bon outil de paiement n'est pas toujours le plus complet : pour un besoin ponctuel et unique, une intégration Stripe Checkout minimale reste plus simple à maintenir qu'une boutique WooCommerce entière.

## En résumé

Pour un encaissement ponctuel sous Elementor, Stripe Checkout intégré dans un simple widget HTML évite d'installer WooCommerce Builder pour un usage qui ne le justifie pas. La rigueur reste la même qu'avec n'importe quelle intégration de paiement : montant côté serveur, confirmation par webhook, clé secrète hors du code source.
