Maison  >  Article  >  développement back-end  >  Comment implémenter la fonction de déduction récurrente (abonnement) dans Paypal

Comment implémenter la fonction de déduction récurrente (abonnement) dans Paypal

墨辰丷
墨辰丷original
2018-05-24 16:18:482076parcourir

Cet article présente principalement les idées et méthodes de Paypal pour mettre en œuvre des déductions récurrentes (abonnements) ; il résume également comment utiliser l'interface de paiement de Paypal, qui a une bonne valeur de référence.

Cause

L'entreprise doit intégrer Paypal pour réaliser la fonction de déduction récurrente. Cependant, Baidu et GOOGLE ont cherché et trouvé aucun tutoriel de développement pertinent à l'exception du site officiel, j'ai donc dû regarder Paypal, il a fallu deux jours pour réussir l'intégration. Voici un résumé de la façon d'utiliser l'interface de paiement de Paypal.

Paypal dispose désormais de plusieurs sockets :

  • Le paiement express est implémenté via Braintree (nous parlerons de Braintree plus tard

  • Créer une application via l'interface de REST Api (l'interface grand public actuelle) ;

  • L'interface des applications API NVP/SOAP (ancienne interface) ;

Interface de Braintree

Braintree est une société acquise par Paypal. En plus de prendre en charge le paiement Paypal, elle propose également des plans de mise à niveau, des cartes de crédit, des informations client, etc. Une série complète de gestion, plus pratique à utiliser ; le deuxième ensemble d'interfaces REST de Paypal intègre en fait la plupart de ces fonctions, mais le tableau de bord de Paypal ne peut pas gérer directement ces informations mais Braintree le peut, donc je préfère en fait utiliser Braintree. La clé est que le framework backend que j'utilise est Laravel et que sa solution de caisse prend en charge Braintee par défaut, donc cet ensemble d'interfaces est mon premier choix. Mais lorsque j'ai implémenté toutes ses fonctions, j'ai découvert un problème douloureux : Braintree n'est pas supporté en Chine. . . . . . La mort. . .

API REST

Il s'agit d'un produit qui s'adapte à l'évolution de l'époque. Si vous avez déjà utilisé OAuth 2.0 et l'API REST, il ne devrait y avoir aucune confusion quand. en regardant ces interfaces.

Ancienne interface

À moins que l'interface de l'API REST ne puisse pas répondre aux exigences, telles que les restrictions de politique, il n'est pas recommandé de l'utiliser. Le monde entier migre vers la méthode d'authentification OAuth 2.0 et la méthode d'utilisation de l'API REST. Pourquoi aller à contre-courant ? Par conséquent, lorsque l'API REST peut résoudre le problème, je n'ai pas fait de comparaison approfondie de cet ensemble d'interfaces.

Introduction à l'API REST

Document officiel de référence de l'API https://developer.paypal.com/webapps/developer/docs/api/ pour son API et son utilisation. La méthode est présentée plus en détail, mais il est toujours très fastidieux d'ajuster directement ces API. En même temps, nous voulons simplement répondre aux exigences commerciales le plus rapidement possible au lieu d'entrer dans une compréhension approfondie de l'API.

Alors, comment commencer ? Il est recommandé d'installer directement le PayPal-PHP-SDK officiellement fourni et d'utiliser son Wiki comme point de départ.

Avant de compléter le premier exemple, assurez-vous d'avoir un compte Sandbox et configurez-le correctement :

  • ID client

  • Client Secret

  • API Webhook (doit commencer par https et être le port 443, le débogage local est recommandé pour utiliser le proxy inverse ngrok pour générer l'adresse)

  • Returnurl (les notes sont les mêmes que ci-dessus)

Après avoir terminé le premier exemple dans Wiki, comprendre la classification des interfaces vous aidera à répondre aux besoins de votre entreprise. Laissez-moi vous présenter l'interface. classification ci-dessous. Veuillez comprendre http://paypal.github.io/PayPal-PHP-SDK/sample/#payments avec des exemples.

  • Paiements Interface de paiement unique, ne prend pas en charge les dons récurrents. Le contenu principal du paiement comprend la prise en charge du paiement Paypal, le paiement par carte de crédit, la prise en charge via une carte de crédit enregistrée (nécessite l'utilisation de l'interface Vault, une telle interface est principalement due aux exigences PCI, les sites Web généraux ne sont pas autorisés à collecter des informations sensibles sur les cartes de crédit), et prend en charge le paiement à des tiers.

  • Paiements Non utilisé, ignorer

  • Autorisation et Capture prend en charge la connexion à votre site Web directement via votre compte Paypal et obtient des informations pertinentes

  • Vente Suivre pertinent ; au centre commercial, non utilisé, ignorer ;

  • Commande Pertinent pour le centre commercial, non utilisé, ignoré ;

  • Plan de facturation et accords Plans et contrats de mise à niveau, c'est-à-dire les fonctions d'abonnement, vous devez utiliser les fonctions ici pour obtenir des déductions récurrentes, ce qui est au centre de ce document. article ;

  • Coffre-fort Stocker les informations de carte de crédit

  • Paiement ExpérienceNon utilisé, ignorer; Important, mais ce n'est pas l'objet de cet article

  • FactureTraitement des factures ;

    Identité
  • Traitement de l'authentification, réalisation de la connexion OAuth 2.0 et obtention du jeton correspondant pour demander d'autres API. Ce Paypal-PHP-SDK possède. ont déjà été mises en œuvre et ne seront pas abordées dans cet article.

    Comment mettre en œuvre des déductions récurrentes

  • Quatre étapes :

    Créer un plan de mise à niveau et activer;

  • Créez un abonnement (créer un accord), puis accédez au site Web de Paypal pour attendre le consentement de l'utilisateur

  • Une fois que l'utilisateur a accepté, exécutez l'abonnement ;

  • Obtenir la facture de débit

  • 1. Créer un plan de mise à niveau

    Plan de mise à niveau Correspond à la classe Plan. Il y a plusieurs points à noter dans cette étape :

    • Une fois le plan de mise à niveau créé, il est dans l'état CRÉÉ et doit être changé en ACTIF avant de pouvoir être utilisé normalement.

    • Le plan a deux objets, PaymentDefinition et MerchantPreferences, qui ne peuvent pas tous deux être vides

    • Si vous souhaitez créer un plan de type TRIAL, Le plan doit également avoir une définition de paiement REGULIER correspondante, sinon une erreur sera signalée

    • En regardant le code, une méthode setSetupFee (très, très, très importante) est appelée, qui fixe la réalisation de l'abonnement. Les frais pour le premier débit suivant, tandis que la méthode de déduction récurrente de l'objet du Contrat fixe les frais au début de la deuxième fois.

    Prenons comme exemple la création d'un plan Standard. Les paramètres sont les suivants :

    $param = [
     "name" => "standard_monthly",
     "display_name" => "Standard Plan",
     "desc" => "standard Plan for one month",
     "type" => "REGULAR",
     "frequency" => "MONTH",
     "frequency_interval" => 1,
     "cycles" => 0,
     "amount" => 20,
     "currency" => "USD"
     ];

    Créer et activer le plan Le code est le suivant :

     //上面的$param例子是个数组,我的实际应用传入的实际是个对象,用户理解下就好。
     public function createPlan($param)
     {
     $apiContext = $this->getApiContext();
     $plan = new Plan();
     // # Basic Information
     // Fill up the basic information that is required for the plan
     $plan->setName($param->name)
     ->setDescription($param->desc)
     ->setType('INFINITE');//例子总是设置为无限循环
     // # Payment definitions for this billing plan.
     $paymentDefinition = new PaymentDefinition();
     // The possible values for such setters are mentioned in the setter method documentation.
     // Just open the class file. e.g. lib/PayPal/Api/PaymentDefinition.php and look for setFrequency method.
     // You should be able to see the acceptable values in the comments.
     $paymentDefinition->setName($param->name)
     ->setType($param->type)
     ->setFrequency($param->frequency)
     ->setFrequencyInterval((string)$param->frequency_interval)
     ->setCycles((string)$param->cycles)
     ->setAmount(new Currency(array('value' => $param->amount, 'currency' => $param->currency)));
     // Charge Models
     $chargeModel = new ChargeModel();
     $chargeModel->setType('TAX')
     ->setAmount(new Currency(array('value' => 0, 'currency' => $param->currency)));
     $returnUrl = config('payment.returnurl');
     $merchantPreferences = new MerchantPreferences();
     $merchantPreferences->setReturnUrl("$returnUrl?success=true")
     ->setCancelUrl("$returnUrl?success=false")
     ->setAutoBillAmount("yes")
     ->setInitialFailAmountAction("CONTINUE")
     ->setMaxFailAttempts("0")
     ->setSetupFee(new Currency(array('value' => $param->amount, 'currency' => 'USD')));
     $plan->setPaymentDefinitions(array($paymentDefinition));
     $plan->setMerchantPreferences($merchantPreferences);
     // For Sample Purposes Only.
     $request = clone $plan;
     // ### Create Plan
     try {
     $output = $plan->create($apiContext);
     } catch (Exception $ex) {
     return false;
     }
     $patch = new Patch();
     $value = new PayPalModel('{"state":"ACTIVE"}');
     $patch->setOp('replace')
     ->setPath('/')
     ->setValue($value);
     $patchRequest = new PatchRequest();
     $patchRequest->addPatch($patch);
     $output->update($patchRequest, $apiContext);
     return $output;
     }

    2. Créez un abonnement (créer un accord), puis passez à Le site Web de Paypal doit attendre le consentement de l'utilisateur

    Une fois le plan créé, comment permettre aux utilisateurs de s'abonner. En fait, il s'agit de créer un accord. Concernant l'accord, il y a les éléments suivants ? points à noter :

    • Comme avant Comme mentionné ci-dessus, la méthode setSetupFee de l'objet Plan fixe les frais pour la première déduction après avoir terminé la souscription, tandis que la méthode de déduction récurrente de l'objet Agreement fixe les frais pour le deuxième départ.

    • La méthode setStartDate définit l'heure de la deuxième déduction, donc si vous faites du vélo sur une base mensuelle, ce devrait être l'heure actuelle plus un mois. En même temps, cette méthode nécessite. que le format de l'heure est au format ISO8601, peut être facilement résolu en utilisant la bibliothèque Carbon

    • Lors de la création de l'accord, l'identifiant unique n'avait pas encore été généré, j'ai donc rencontré une petite difficulté : c'est à ce moment-là que l'utilisateur termine l'abonnement, comment savoir à quel utilisateur appartient cet abonnement ? Le jeton dans l'URL obtenu via la méthode getApprovalLink de l'accord est unique. J'extrait le jeton comme méthode d'identification et je le remplace par le véritable identifiant une fois que l'utilisateur a terminé l'abonnement.

    Les exemples de paramètres sont les suivants :

    $param = [
     'id' => 'P-26T36113JT475352643KGIHY',//上一步创建Plan时生成的ID
     'name' => 'Standard', 
     'desc' => 'Standard Plan for one month'
    ];

    Le code est le suivant :

     public function createPayment($param)
     {
     $apiContext = $this->getApiContext();
     $agreement = new Agreement();
     $agreement->setName($param['name'])
     ->setDescription($param['desc'])
     ->setStartDate(Carbon::now()->addMonths(1)->toIso8601String());
     // Add Plan ID
     // Please note that the plan Id should be only set in this case.
     $plan = new Plan();
     $plan->setId($param['id']);
     $agreement->setPlan($plan);
     // Add Payer
     $payer = new Payer();
     $payer->setPaymentMethod('paypal');
     $agreement->setPayer($payer);
     // For Sample Purposes Only.
     $request = clone $agreement;
     // ### Create Agreement
     try {
     // Please note that as the agreement has not yet activated, we wont be receiving the ID just yet.
     $agreement = $agreement->create($apiContext);
     // ### Get redirect url
     // The API response provides the url that you must redirect
     // the buyer to. Retrieve the url from the $agreement->getApprovalLink()
     // method
     $approvalUrl = $agreement->getApprovalLink();
     } catch (Exception $ex) {
     return "create payment failed, please retry or contact the merchant.";
     }
     return $approvalUrl;//跳转到$approvalUrl,等待用户同意
     }

    Une fois la fonction exécutée, elle renvoie $approvalUrl N'oubliez pas d'accéder au site Web Paypal via la redirection ($approvalUrl) pour attendre que l'utilisateur paie.

    Après l'accord de l'utilisateur, exécutez l'abonnement

    Après l'accord de l'utilisateur, l'abonnement n'est pas terminé et la méthode d'exécution de l'accord doit être exécuté pour être véritablement complété. La chose importante à noter dans cette étape est que

    • Après avoir finalisé l'abonnement, cela ne signifie pas que le paiement sera déduit, et il peut être retardé de quelques minutes

    • Si la première étape Si les frais setSetupFee sont fixés à 0, la commande ne sera pas générée tant que le délai de déduction récurrent n'est pas écoulé

    Le L'extrait de code est le suivant :

     public function onPay($request)
     {
     $apiContext = $this->getApiContext();
     if ($request->has('success') && $request->success == 'true') {
     $token = $request->token;
     $agreement = new \PayPal\Api\Agreement();
     try {
     $agreement->execute($token, $apiContext);
     } catch(\Exception $e) {
     return ull;
     return $agreement;
     }
     return null;
     }

    Obtenir l'enregistrement de la transaction

    Après votre inscription , l'enregistrement de transaction de déduction de transaction peut ne pas être généré immédiatement s'il est vide, il faudra quelques minutes pour réessayer. Notes sur cette étape :

    • start_date et end_date ne peuvent pas être vides

    • Pendant les tests réels, l'objet renvoyé par cette fonction ne peut pas toujours renvoyer un JSON vide objet, donc si vous devez générer du JSON, veuillez extraire manuellement les paramètres correspondants selon la description de l'API de AgreementTransactions.

     /** 获取交易记录
     * @param $id subscription payment_id
     * @warning 总是获取该subscription的所有记录
     */
     public function transactions($id)
     {
     $apiContext = $this->getApiContext();
     $params = ['start_date' => date('Y-m-d', strtotime('-15 years')), 'end_date' => date('Y-m-d', strtotime('+5 days'))];
     try {
     $result = Agreement::searchTransactions($id, $params, $apiContext);
     } catch(\Exception $e) {
     Log::error("get transactions failed" . $e->getMessage());
     return null;
     }
     return $result->getAgreementTransactionList() ;
     }

    Enfin, bien sûr, Paypal a également un tutoriel officiel correspondant, mais il appelle l'interface native, qui est différente de le processus ci-dessus. Le fait est que seules les trois premières étapes sont mentionnées à titre de référence : https://developer.paypal.com/docs/integration/direct/billing-plans-and-agreements/.

    Problèmes à prendre en compte

    La fonction a été implémentée, mais il y a aussi de nombreuses mises en garde :

    • Domestique utilisation de Sandbox La connexion était extrêmement lente pendant le test, provoquant souvent des délais d'attente ou des erreurs, une attention particulière doit donc être accordée à la situation dans laquelle l'utilisateur ferme la page pendant l'exécution

    • Be ; assurez-vous d'implémenter le webhook, sinon lorsque l'utilisateur annule l'abonnement dans Paypal, votre site Web ne sera pas informé

    • Une fois qu'un abonnement (accord) est généré, il restera en vigueur sauf annulation ; de manière proactive. Par conséquent, si votre site Web est conçu avec plusieurs plans de mise à niveau (tels que Basic, Standard, Advanced), lorsqu'un utilisateur s'est abonné à un certain plan et passe à un plan de mise à niveau, le développement doit annuler le plan de mise à niveau précédent

    • L'utilisateur accepte de s'abonner - (annuler l'ancien abonnement - terminer la signature du nouvel abonnement - modifier les informations de l'utilisateur vers le nouvel abonnement), l'ensemble du processus de parenthèses doit être une opération et un temps atomiques -consommateur, il doit donc être placé en cours d'exécution dans la file d'attente jusqu'à ce qu'il réussisse, ce qui offrira une meilleure expérience.

    Ce qui précède représente l'intégralité du contenu de cet article, j'espère qu'il sera utile à l'étude de chacun.


    Recommandations associées :

    PaypalExemple de partage de code pour implémenter la fonction de déduction récurrente (abonnement)

    zen cart implémente l'ajout de réservations Paypal aux commandes Méthode téléphonique

    paypal Le SDK de paiement en ligne PHP le plus simple

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn