Passerelle de Paiement PayPal

Acceptez les paiements avec PayPal sur votre boutique Larapen. Cet add-on intègre l’API REST PayPal pour créer des commandes, capturer les paiements, gérer les webhooks et traiter les remboursements : le tout via l’interface standard de passerelle de paiement Larapen.

Paiement PayPal

Redirigez les clients vers le checkout hébergé de PayPal. Aucun formulaire de carte bancaire nécessaire sur votre site.

Sandbox & Production

Basculez entre les modes sandbox (test) et live (production) depuis le panneau d’administration en un seul clic.

Support des Webhooks

Recevez des notifications de paiement en temps réel via les webhooks PayPal pour les événements de capture, refus et remboursement.

Traitement des Remboursements

Émettez des remboursements complets ou partiels directement via la passerelle. Les transactions de remboursement sont suivies automatiquement.

Identifiants Chiffrés

Les clés API et secrets sont chiffrés avant le stockage à l’aide de la facade Crypt de Laravel.

Payables Polymorphiques

Fonctionne avec tout modèle implémentant le contrat Payable : pas limité aux commandes de la boutique.

Cas d’Utilisation

Boutique en Ligne avec Paiement PayPal

Vous gérez une boutique e-commerce avec l’add-on Shop Larapen et souhaitez proposer PayPal comme option de paiement aux côtés d’autres passerelles (par ex. Stripe).

  • Installez et activez l’add-on PayPal.
  • Entrez vos identifiants API REST PayPal dans le panneau d’administration.
  • Les clients voient PayPal comme méthode de paiement lors du checkout.
  • Après sélection, ils sont redirigés vers PayPal pour compléter le paiement, puis renvoyés vers votre site.

Vente de Produits Numériques

Vous vendez des téléchargements numériques (e-books, licences logicielles, templates) et souhaitez une confirmation de paiement sécurisée et instantanée.

  • Les webhooks PayPal confirment le paiement en temps réel, même si le client ferme son navigateur avant de revenir.
  • La boutique marque la commande comme payée et débloque automatiquement les liens de téléchargement numérique.

Boutique Multi-Devises

Vous vendez à des clients internationaux dans plusieurs devises.

  • Configurez la devise PayPal par défaut dans les paramètres d’administration (USD, EUR, GBP, etc.).
  • Chaque commande envoie le code devise correct à PayPal en fonction de la configuration de la boutique.

Prérequis

  • Larapen CMS v1.0.0 ou ultérieur
  • PHP 8.3+
  • MySQL 8.0+
  • L’add-on Shop (dépendance requise)
  • Un compte PayPal Business avec des identifiants API REST
  • Le package Composer srmklive/paypal (SDK PayPal)
Note : L’add-on Shop doit être installé et actif pour que cet add-on fonctionne. L’add-on PayPal s’enregistre en tant que passerelle de paiement que la boutique découvre automatiquement.

Installation

Étape 1 : Placer l’Add-on

Copiez ou créez un lien symbolique du dossier paypal dans le répertoire « extensions/addons » de votre Larapen :

Étape 2 : Installer les Dépendances

Assurez-vous que le package SDK PayPal est installé :

Étape 3 : Activer l’Add-on

Allez dans Admin → Add-ons → Add-ons Installés et activez Passerelle de Paiement PayPal.

Étape 4 : Exécuter les Migrations

Cela crée la table paypal_orders pour le suivi des enregistrements de commandes PayPal, des captures et des métadonnées de paiement.

É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 → PayPal → Paramètres et entrez vos identifiants API PayPal. Voir Configuration et Obtenir les Identifiants PayPal.

Configuration

Tous les paramètres sont gérés dans Admin → PayPal → Paramètres (stockés dans la table settings, groupe paypal).

Paramètre Description Par défaut
paypal_mode Mode API : sandbox pour les tests ou live pour les paiements en production. sandbox
paypal_client_id Client ID de l’API REST PayPal. Stocké chiffré dans la base de données. (vide)
paypal_client_secret Client Secret de l’API REST PayPal. Stocké chiffré dans la base de données. (vide)
paypal_webhook_id ID du Webhook PayPal pour vérifier les signatures des événements webhook entrants. Stocké chiffré. (vide)
paypal_currency Code devise ISO 4217 utilisé pour les transactions PayPal (par ex. USD, EUR, GBP). USD
paypal_brand_name Nom de marque affiché sur la page de paiement PayPal (127 caractères max). (nom de l’application)

Correspondance Paramètres Base de Données → Config

Les paramètres stockés dans la base de données remplacent les valeurs par défaut du fichier de configuration au démarrage via le service provider :

Clé Base de Données Clé Config Chiffré ?
paypal_mode paypal.mode Non
paypal_client_id paypal.{mode}.client_id Oui
paypal_client_secret paypal.{mode}.client_secret Oui
paypal_webhook_id paypal.webhook_id Oui
paypal_currency paypal.currency Non
paypal_brand_name paypal.brand_name Non
Note : Les paypal_client_id et paypal_client_secret sont stockés en fonction du mode actuellement actif. Si le mode est sandbox, ils correspondent à paypal.sandbox.client_id et paypal.sandbox.client_secret.

Variables d’Environnement

Note : Les variables d’environnement sont utilisées comme valeurs par défaut. Les paramètres enregistrés dans le panneau d’administration (stockés chiffrés dans la base de données) les remplacent.

Obtenir les Identifiants PayPal

  1. Allez sur developer.paypal.com/dashboard et connectez-vous avec votre compte PayPal Business.
  2. Naviguez vers Apps & Credentials.
  3. Cliquez sur Create App (ou sélectionnez une application existante).
  4. Copiez le Client ID et le Client Secret depuis la page de détails de l’application.
  5. Pour les tests sandbox, basculez sur l’onglet Sandbox pour obtenir les identifiants sandbox.
  6. Pour les webhooks, allez dans Webhooks dans le tableau de bord, créez un webhook pointant vers https://votresite.com/paypal/webhook, et copiez le Webhook ID.

Événements Webhook Requis

Lors de la création de votre webhook PayPal, abonnez-vous à ces événements :

  • PAYMENT.CAPTURE.COMPLETED : le paiement a été capturé avec succès
  • PAYMENT.CAPTURE.DENIED : la capture du paiement a été refusée
  • PAYMENT.CAPTURE.REFUNDED : un remboursement a été traité
Important : L’URL du webhook doit être accessible publiquement en HTTPS. Les webhooks sandbox nécessitent une URL en production (pas localhost). Utilisez un service tunnel comme ngrok pour les tests locaux.

Admin : Paramètres

La page des paramètres (PayPal → Paramètres) est organisée en deux sections :

Identifiants API

  • Client ID : champ de mot de passe masqué avec bouton afficher/masquer. Votre Client ID de l’API REST PayPal.
  • Client Secret : champ de mot de passe masqué avec bouton afficher/masquer. Stocké chiffré dans la base de données.
  • Webhook ID : champ de mot de passe masqué avec bouton afficher/masquer. Utilisé pour vérifier les signatures des webhooks. Optionnel mais recommandé.
Sécurité : Les trois champs d’identifiants sont chiffrés avec Crypt::encryptString() de Laravel avant d’être enregistrés dans la table settings. Ils ne sont déchiffrés que pour l’affichage dans le formulaire ou lors de la configuration du client API PayPal. Laissez les champs vides pour conserver les valeurs actuelles.

Options de Paiement

  • Mode : menu déroulant pour sélectionner Sandbox (Test) ou Live (Production). Contrôle quel jeu d’identifiants API est utilisé.
  • Devise : code devise ISO 4217 à trois caractères (par ex. USD, EUR, GBP). Utilisé comme devise par défaut pour les commandes PayPal.
  • Nom de Marque : le nom affiché sur la page de paiement PayPal (127 caractères max). Se rabat sur le nom de l’application si vide.

Une carte d’aide en haut de la page des paramètres fournit des liens directs vers :

Flux de Paiement

Le flux de paiement PayPal suit le schéma standard de checkout par redirection :

  1. Le client sélectionne PayPal : lors du checkout de la boutique, le client choisit PayPal comme méthode de paiement.
  2. Création de la commande : la boutique appelle PaypalGateway::createPaymentIntent($order), qui crée une commande PayPal via l’API REST avec l’intent CAPTURE.
  3. Enregistrement local : un enregistrement est sauvegardé dans la table paypal_orders avec l’ID de commande PayPal, le montant, la devise, l’URL d’approbation et la référence payable polymorphique.
  4. Redirection vers PayPal : le client est redirigé vers la page de checkout hébergée de PayPal (l’approval_url de la réponse API).
  5. Le client approuve : le client se connecte à PayPal, vérifie la commande et clique sur « Payer ».
  6. Retour sur le site : PayPal redirige le client vers /paypal/return?token={paypal_order_id}.
  7. Capture du paiement : la méthode PaypalController::return() appelle PaypalGateway::confirmPayment() pour capturer le paiement autorisé.
  8. Finalisation de la commande : si la capture réussit, la commande est marquée comme payée, un enregistrement de transaction est créé, et le client est redirigé vers la page de succès.

Annulation

Si le client clique sur « Annuler » sur la page de checkout PayPal, il est redirigé vers /paypal/cancel. Le contrôleur le redirige vers la page de checkout de la boutique avec un message d’avertissement « Paiement annulé ».

Double confirmation : Les paiements sont confirmés à la fois par la redirection de retour (immédiate) et par les webhooks (asynchrone). Cela garantit que les commandes sont marquées comme payées même si le client ferme son navigateur avant la fin de la redirection de retour.

Confirmation de Paiement

Lorsqu’un paiement est capturé avec succès, la passerelle effectue ces actions :

  1. Met à jour l’enregistrement paypal_orders avec : status = COMPLETED, capture_id, payer_id, payer_email et confirmed_at.
  2. Appelle $payable->markAsPaid('paypal', $captureId) sur le modèle de commande.
  3. Crée un enregistrement Transaction dans la table shop_transactions avec :
    • gateway = 'paypal'
    • gateway_transaction_id = {capture_id}
    • status = 'completed'
    • type = 'payment'
    • Métadonnées incluant paypal_order_id, payer_id et payer_email

Remboursements

La passerelle prend en charge les remboursements complets et partiels via PaypalGateway::refund().

Processus de Remboursement

  1. L’administrateur initie un remboursement depuis la gestion des commandes de la boutique.
  2. La passerelle appelle l’API refundCapturedPayment() de PayPal en utilisant l’ID de capture original.
  3. En cas de succès, un nouvel enregistrement Transaction est créé avec type = 'refund'.
  4. Le statut de la commande est mis à jour si le remboursement couvre le montant total.

Statuts de Remboursement

Statut Description
COMPLETED Remboursement traité immédiatement.
PENDING Remboursement en attente (par ex. paiements eCheck). Un webhook PAYMENT.CAPTURE.REFUNDED le confirmera plus tard.
Note : Les remboursements partiels sont supportés. Vous pouvez rembourser tout montant jusqu’au montant du paiement original. Une raison/note optionnelle peut être incluse, que PayPal affiche à l’acheteur.

Configuration des Webhooks

Les webhooks PayPal fournissent des notifications asynchrones d’événements de paiement. Ils servent de filet de sécurité pour confirmer les paiements même lorsque la redirection de retour du client échoue.

URL du Webhook

Configurez PayPal pour envoyer les événements webhook à :

Ce point d’entrée est exempt de CSRF et ne nécessite pas d’authentification.

Configuration

  1. Allez dans Tableau de Bord Développeur PayPal → Webhooks.
  2. Cliquez sur Add Webhook.
  3. Entrez votre URL de webhook.
  4. Sélectionnez les trois événements requis (voir ci-dessous).
  5. Copiez le Webhook ID généré et collez-le dans Admin → PayPal → Paramètres.

Mise à Jour

Étape 1 : Remplacer les Fichiers

Remplacez le répertoire de l’add-on par la nouvelle version.

Étape 2 : Exécuter les Migrations

Étape 3 : Vider les Caches

Étape 4 : Vérifier

Visitez PayPal → Paramètres et confirmez que vos identifiants API sont toujours configurés. Essayez un paiement de test sandbox pour vous assurer que tout fonctionne correctement.

Sauvegarde d’abord : Sauvegardez toujours votre base de données avant d’exécuter des migrations sur un système de production.

Dépannage

« PayPal API credentials are not configured »

  • Assurez-vous d’avoir saisi à la fois le Client ID et le Client Secret dans Admin → PayPal → Paramètres.
  • Vérifiez que le bon Mode est sélectionné : les identifiants sandbox ne fonctionnent pas en mode live et vice versa.
  • Vérifiez que les identifiants correspondent au bon mode (sandbox vs. live).

« PayPal authentication failed »

  • Vérifiez que le Client ID et le Client Secret sont corrects (pas d’espaces ou sauts de ligne supplémentaires).
  • Assurez-vous que votre application PayPal n’est pas suspendue ou supprimée.
  • Vérifiez que votre serveur peut atteindre api-m.sandbox.paypal.com (sandbox) ou api-m.paypal.com (live) en HTTPS.
  • Consultez les logs du serveur pour les messages d’erreur détaillés de l’API PayPal.

Client redirigé vers le checkout mais paiement non capturé

  • L’URL de retour n’a peut-être pas été atteinte (le client a fermé son navigateur). Vérifiez si le webhook a reçu un événement PAYMENT.CAPTURE.COMPLETED.
  • Assurez-vous que l’URL du webhook est correctement configurée dans le Tableau de Bord Développeur PayPal.
  • Vérifiez que l’enregistrement paypal_orders a été créé (consultez la colonne status).

Les webhooks ne sont pas reçus

  • Vérifiez que l’URL du webhook est accessible publiquement en HTTPS.
  • Consultez le Tableau de Bord Développeur PayPal → Webhooks → Events pour le statut de livraison.
  • Assurez-vous que le webhook n’est pas derrière des règles de pare-feu basées sur l’IP qui bloquent les serveurs de PayPal.
  • Pour le développement local, utilisez un service tunnel (par ex. ngrok) pour exposer votre serveur local.

La vérification de signature du webhook échoue

  • Assurez-vous que le Webhook ID dans les paramètres d’administration correspond à celui du Tableau de Bord Développeur PayPal.
  • Si vous avez récemment recréé le webhook, mettez à jour le Webhook ID dans vos paramètres.
  • Laissez le Webhook ID vide pour désactiver la vérification de signature (non recommandé en production).

Le remboursement échoue : « Refund failed »

  • Assurez-vous que le paiement original a été capturé (statut COMPLETED).
  • Vérifiez que le montant du remboursement ne dépasse pas le montant du paiement original.
  • PayPal peut rejeter les remboursements pour les paiements de plus de 180 jours.
  • Consultez les logs du serveur pour le message d’erreur spécifique de l’API PayPal.

Commandes bloquées au statut CREATED ou APPROVED

  • Le client a peut-être approuvé le paiement mais la capture a échoué. Consultez les logs du serveur pour les erreurs durant confirmPayment().
  • Essayez de traiter la capture manuellement via le Tableau de Bord Marchand PayPal.
  • Assurez-vous que le package srmklive/paypal est à jour.

Erreurs « Array to string conversion »

  • Cela se produit généralement lorsque la bibliothèque srmklive/paypal reçoit des clés de configuration inattendues. La passerelle filtre la configuration pour ne transmettre que les clés supportées. Assurez-vous d’utiliser une version compatible du package.
  • Videz le cache de configuration : php artisan config:clear

Cet article vous a-t-il été utile ?

Merci pour votre retour !

Besoin d'aide ? Créez un ticket de support

Créer un Ticket