Passerelle de Paiement Paddle
Acceptez les paiements via Paddle : une plateforme « merchant of record » qui gère
les paiements, les taxes et la conformité. S’intègre au Shop Larapen via le
contrat PaymentGatewayInterface.
Overlay de Paiement Paddle
Les clients paient via l’overlay de paiement intégré de Paddle, propulsé par Paddle.js v2. Aucune redirection hors de votre site.
Merchant of Record
Paddle gère la taxe de vente, la TVA et la conformité dans le monde entier. Vous recevez des versements nets.
Piloté par Webhooks
Les mises à jour de statut des commandes sont confirmées via des webhooks signés pour un traitement fiable des paiements.
Support des Remboursements
Traitez des remboursements complets ou partiels directement depuis le panneau d’administration via l’API Paddle Adjustments.
Cas d’Utilisation
Vente de Produits Numériques
Vous vendez des produits numériques (thèmes, plugins, e-books) via le Shop Larapen et souhaitez que Paddle gère la conformité fiscale mondiale et les versements.
- Installez l’add-on Paddle en même temps que l’add-on Shop.
- Configurez vos identifiants API Paddle dans le panneau d’administration.
- Les clients sélectionnent Paddle au moment du paiement et paient via l’overlay.
- Paddle collecte les taxes, traite le paiement et vous envoie le revenu net.
Boutique de Produits Physiques ou Mixtes
Vous vendez des produits physiques ou un mélange de produits physiques et numériques et souhaitez une passerelle de paiement fiable.
- Paddle prend en charge les cartes de crédit/débit, PayPal, Apple Pay, Google Pay et les méthodes de paiement locales.
- Les commandes sont confirmées via des webhooks, garantissant qu’aucun paiement n’est perdu même si le client ferme son navigateur.
Tests en Sandbox
Utilisez l’environnement sandbox de Paddle pour le développement et les tests avant de passer en production.
- Définissez l’environnement sur « Sandbox » dans les paramètres d’administration.
- Utilisez les numéros de carte de test de Paddle pour simuler des paiements.
- Passez en « Production » lorsque vous êtes prêt pour les paiements réels.
Prérequis
- Larapen CMS v1.0.0 ou ultérieur
- PHP 8.3+
- MySQL 8.0+
- L’add-on Shop doit être installé et actif (dépendance déclarée)
- Un compte Paddle : paddle.com
- Paddle PHP SDK (
paddle/paddle-php-sdk) installé via Composer
Installation
Étape 1 : Placer l’Add-on
Copiez ou créez un lien symbolique du dossier paddle dans le répertoire « extensions/addons » de votre Larapen :
Étape 2 : Installer le SDK PHP Paddle
Étape 3 : Activer l’Add-on
Allez dans Admin → Add-ons → Add-ons Installés et activez Passerelle de Paiement Paddle.
Étape 4 : Exécuter les Migrations
Cela crée 2 tables : paddle_customers et paddle_transactions.
Étape 5 : Définir les Permissions
L’add-on enregistre 2 permissions (voir Permissions). Attribuez-les aux rôles d’administration via Admin → Utilisateurs → Rôles & Permissions.
Étape 6 : Configurer
Naviguez vers Admin → Paddle → Paramètres et entrez votre clé API, votre jeton côté client, votre ID vendeur et votre secret webhook. Voir Configuration et Obtenir les Identifiants Paddle.
Étape 7 : Configurer les Webhooks dans Paddle
- Allez dans votre Tableau de Bord Paddle → Outils Développeur → Notifications.
- Créez une nouvelle destination de notification.
- Définissez l’URL sur
https://votresite.com/paddle/webhook. - Sélectionnez ces événements :
transaction.completed,transaction.payment_failed,transaction.updated,adjustment.created,adjustment.updated. - Copiez le secret webhook et collez-le dans les paramètres d’administration.
Configuration
Tous les paramètres sont gérés dans Admin → Paddle → Paramètres (stockés dans la table settings, groupe paddle).
| Paramètre | Description | Par défaut |
|---|---|---|
paddle_api_key |
Clé API Paddle pour les appels API côté serveur (transactions, remboursements). Chiffrée au repos. | (vide) |
paddle_client_token |
Jeton côté client Paddle pour initialiser Paddle.js sur le frontend. Chiffré au repos. Les jetons sandbox commencent par test_, les jetons live par live_. |
(vide) |
paddle_webhook_secret |
Clé secrète pour vérifier les signatures des webhooks Paddle (HMAC-SHA256). Chiffrée au repos. | (vide) |
paddle_environment |
Environnement Paddle : sandbox pour les tests, production pour les paiements réels. |
sandbox |
paddle_seller_id |
Votre ID vendeur/seller Paddle. Requis pour l’initialisation de Paddle.js. | (vide) |
paddle_currency |
Code devise (par ex., USD, EUR, GBP). Doit correspondre à la devise de votre boutique. |
USD |
Crypt::encryptString() de Laravel avant d’être stockés dans la base de données. Ils sont déchiffrés au moment de l’exécution
lorsque le PaddleServiceProvider démarre.
Variables d’Environnement
Les variables d’environnement servent de valeurs par défaut. Les paramètres enregistrés dans le panneau d’administration les remplacent.
Obtenir les Identifiants Paddle
Clé API & Jeton Côté Client
- Connectez-vous à votre Tableau de Bord Paddle (ou au Tableau de Bord Sandbox pour les tests).
- Naviguez vers Outils Développeur → Authentification.
- Copiez votre Clé API (utilisée pour les appels API côté serveur).
- Copiez votre Jeton Côté Client (utilisé pour l’initialisation de Paddle.js).
ID Vendeur
- Dans le Tableau de Bord Paddle, votre ID Vendeur est affiché dans les paramètres du compte ou l’URL.
- Copiez l’ID numérique et entrez-le dans les paramètres d’administration.
Secret Webhook
- Allez dans Outils Développeur → Notifications dans le Tableau de Bord Paddle.
- Créez une nouvelle destination de notification avec l’URL
https://votresite.com/paddle/webhook. - Sélectionnez les événements auxquels vous abonner (voir Événements Supportés).
- Copiez le secret webhook généré et entrez-le dans les paramètres d’administration.
test_ et les jetons live par live_.
Assurez-vous que vos identifiants correspondent à l’environnement sélectionné.
Admin : Paramètres
La page des paramètres (Admin → Paddle → Paramètres) est organisée en deux sections.
Identifiants API
Trois champs de mot de passe masqués avec des boutons afficher/masquer :
- Clé API : Votre clé API Paddle depuis Outils Développeur > Authentification. Utilisée pour tous les appels API côté serveur (création de transactions, traitement des remboursements).
- Jeton Côté Client : Votre jeton côté client Paddle. Utilisé pour initialiser Paddle.js sur la page de paiement. Les jetons sandbox commencent par
test_. - Secret Webhook : Utilisé pour vérifier la signature HMAC-SHA256 des requêtes webhook entrantes.
La page affiche également un panneau d’information avec des liens directs vers :
- Tableau de Bord Paddle (production et sandbox)
- Outils Développeur > Authentification (clés API)
- Outils Développeur > Notifications (webhooks)
- Documentation de l’API Paddle
- Numéros de carte de test pour les tests sandbox
Options de Paiement
- Environnement : Menu déroulant pour sélectionner
sandbox(test) ouproduction(réel). - ID Vendeur : Champ texte pour votre ID vendeur/seller Paddle. Requis pour l’initialisation de Paddle.js.
- Devise : Code devise à 3 caractères (par ex.,
USD,EUR,GBP). Doit correspondre à la devise de votre boutique.
Flux de Paiement
L’add-on Paddle utilise un flux de paiement par overlay propulsé par Paddle.js v2. Voici le cycle de vie complet du paiement :
- Le client sélectionne Paddle : Sur la page de paiement de la boutique, le client sélectionne « Paddle » comme méthode de paiement. Un message d’information apparaît : « Vous serez redirigé vers le paiement sécurisé de Paddle. »
- Soumission du formulaire (AJAX) : Lorsque le client soumet le formulaire de paiement, JavaScript intercepte
la soumission et l’envoie via
fetch()avec des en-têtes JSON. - Le serveur crée une transaction Paddle : La méthode
PaddleGateway::createPaymentIntent():- Crée une transaction hors catalogue via l’API Paddle avec le montant, la devise et les métadonnées de la commande.
- Stocke un enregistrement local
paddle_transactionsliant l’ID de transaction Paddle à la commande. - Lie le client Paddle à l’utilisateur local (si authentifié).
- Renvoie l’ID de transaction Paddle au frontend.
- L’overlay Paddle.js s’ouvre : Le JavaScript ouvre l’overlay de paiement Paddle en utilisant
Paddle.Checkout.open()avec l’ID de transaction. - Le client complète le paiement : Le client entre ses informations de paiement dans l’overlay Paddle.
- Callback de paiement terminé : Sur
checkout.completed, le JavaScript redirige vers l’URL de retour (/paddle/return?_ptxn={transaction_id}). - Confirmation par URL de retour : La méthode
PaddleController::return()appelleconfirmPayment()pour vérifier le statut de la transaction via l’API Paddle. Si terminée, la commande est marquée comme payée et le client est redirigé vers la page de succès. - Confirmation par webhook : Paddle envoie également un webhook
transaction.completedcomme sauvegarde fiable. Cela garantit que les commandes sont marquées comme payées même si le client ferme son navigateur avant la redirection de retour.
Gestion des Webhooks
Les webhooks sont reçus à POST /paddle/webhook. Ce point d’entrée est exclu de
la protection CSRF et du middleware web.
Événements Supportés
| Événement | Action |
|---|---|
transaction.completed |
Marque la transaction locale comme terminée, appelle markAsPaid() sur le payable (commande),
et crée un enregistrement shop_transactions avec les détails du paiement. |
transaction.payment_failed |
Marque la transaction locale comme échouée, appelle markPaymentFailed() sur le payable,
et crée un enregistrement de transaction échouée avec le code d’erreur. |
adjustment.created |
Si l’action de l’ajustement est refund et le statut est approved ou completed,
met à jour le statut de paiement de la commande en refunded. |
adjustment.updated |
Même traitement que adjustment.created : vérifie les changements de statut de remboursement. |
transaction.updated |
Configuré dans la liste des événements webhook mais actuellement traité par le cas par défaut (ignoré). |
Vérification de Signature
Tous les webhooks entrants sont vérifiés à l’aide de signatures HMAC-SHA256. Paddle envoie la signature dans
l’en-tête HTTP Paddle-Signature au format :
Le processus de vérification :
- Analyser les valeurs
ts(horodatage) eth1(hash) depuis l’en-tête. - Calculer
HMAC-SHA256(timestamp + ':' + rawBody, webhookSecret). - Comparer le hash calculé avec la valeur
h1reçue en utilisanthash_equals(). - Si la signature est invalide ou le secret webhook est vide, renvoyer une réponse
400.
Remboursements
L’add-on prend en charge les remboursements complets et partiels via l’API Paddle Adjustments.
Comment Fonctionnent les Remboursements
- Un administrateur initie un remboursement depuis la page de gestion des commandes de la boutique.
- La méthode
PaddleGateway::refund():- Récupère la transaction Paddle pour obtenir les IDs des articles.
- Crée un ajustement partiel avec
Action::Refund()sur le premier article. - Crée un enregistrement
shop_transactionsde typerefund.
- Paddle traite le remboursement et envoie un webhook
adjustment.created. - Le gestionnaire de webhook met à jour le statut de la commande en
refundedsi l’ajustement est approuvé.
Statuts de Remboursement
| Statut | Description |
|---|---|
approved |
Remboursement approuvé et traité immédiatement. Commande marquée comme remboursée. |
pending |
Remboursement soumis mais en attente d’approbation Paddle. Le statut de la commande est mis à jour lorsque le webhook adjustment.updated arrive. |
rejected |
Remboursement rejeté par Paddle. Aucun changement de statut de commande. |
Mise à Jour
Étape 1 : Remplacer les Fichiers
Remplacez le répertoire de l’add-on par la nouvelle version.
Étape 2 : Mettre à Jour les Dépendances Composer
Étape 3 : Exécuter les Migrations
Étape 4 : Vider les Caches
Étape 5 : Vérifier
Visitez Admin → Paddle → Paramètres et confirmez que vos identifiants sont toujours configurés. Effectuez un paiement de test en mode sandbox pour vérifier l’intégration.
Dépannage
L’overlay de paiement Paddle ne s’ouvre pas
- Assurez-vous que le
paddle_client_tokenest configuré dans les paramètres d’administration. - Vérifiez la console du navigateur pour les erreurs JavaScript. Un jeton client manquant ou invalide affichera
Paddle client token not configured. - Vérifiez que le jeton correspond à l’environnement : les jetons sandbox commencent par
test_, les jetons de production parlive_. - Assurez-vous que Paddle.js se charge : vérifiez que
https://cdn.paddle.com/paddle/v2/paddle.jsn’est pas bloqué par votre Content Security Policy ou votre bloqueur de publicités.
Le paiement ne se confirme pas : la commande reste en « pending »
- Vérifiez que votre URL webhook (
/paddle/webhook) est accessible depuis Internet. Paddle doit pouvoir envoyer des requêtes POST. - Vérifiez que le
paddle_webhook_secretest défini et correspond au secret dans votre Tableau de Bord Paddle. - Consultez
storage/logs/laravel.logpour les erreurs liées aux webhooks. - Dans le Tableau de Bord Paddle sous Notifications, vérifiez si les livraisons de webhooks échouent.
Le webhook renvoie 400 : « Invalid signature »
- Le
paddle_webhook_secretdans les paramètres d’administration ne correspond pas au secret du Tableau de Bord Paddle. - Si vous avez récemment renouvelé le secret webhook, mettez-le à jour dans les paramètres d’administration.
- Assurez-vous que le corps brut de la requête n’est pas modifié par un middleware avant la vérification de signature.
La création de transaction échoue : « Paddle transaction creation failed »
- Vérifiez que la
paddle_api_keyest correcte et n’a pas été révoquée. - Assurez-vous que le
paddle_seller_idest défini. - Vérifiez que le code devise est valide et supporté par Paddle.
- Consultez les logs du serveur pour le message d’erreur complet de l’API Paddle.
- Si vous utilisez le sandbox, assurez-vous que la clé API est une clé sandbox (pas de production).
Le remboursement échoue : « Paddle refund failed »
- Vérifiez que la transaction originale était terminée (seules les transactions terminées peuvent être remboursées).
- Vérifiez que le montant du remboursement ne dépasse pas le montant de la transaction originale.
- Certains ajustements Paddle nécessitent une approbation manuelle : consultez le Tableau de Bord Paddle.
- Consultez les logs du serveur pour l’erreur détaillée de l’API Paddle.
La passerelle n’apparaît pas sur la page de paiement
- Assurez-vous que l’add-on Paddle est activé dans Admin → Add-ons.
- Assurez-vous que
paddle_api_keyetpaddle_seller_idsont configurés (isAvailable()vérifie les deux). - Vérifiez que l’add-on Shop est actif (Paddle en dépend).
Le client n’est pas lié à un ID client Paddle
- La liaison du client se fait automatiquement lors de la création de la transaction lorsque le payable a un ID utilisateur.
- Les paiements en tant qu’invité (sans utilisateur authentifié) ne créent pas d’enregistrement
paddle_customers. - Consultez les logs du serveur pour les avertissements de
linkCustomer().
Les paramètres ne s’enregistrent pas : les identifiants apparaissent vides après la sauvegarde
- Les identifiants sont chiffrés avant le stockage et déchiffrés pour l’affichage. Si la
APP_KEYa changé, les valeurs précédemment chiffrées ne peuvent pas être déchiffrées. - Saisissez à nouveau tous les identifiants après un changement de
APP_KEY. - Vérifiez que la table
settingsest accessible en écriture.