search
HomeBackend DevelopmentPHP TutorialSample code sharing for Paypal to implement recurring deduction (subscription) function

This article mainly introduces the ideas and methods of Paypal to implement recurring deductions (subscriptions); it also summarizes how to use Paypal's payment interface , which has a good reference value. Let’s take a look with the editor below

Cause

The business needs to integrate Paypal to realize the recurring deduction function. However, Baidu and GOOGLE have gone around, except the official website In addition, I couldn't find any relevant development tutorials, so I had to look at Paypal. After two days, the integration was successful. Here is a summary of how to use Paypal's payment interface.

Paypal now has multiple sockets:

  • Express Checkout is implemented through Braintree (we will talk about Braintree later);

  • Create App through the interface of REST Api (now the mainstream interface);

  • The interface of NVP/SOAP API apps (old interface);

Braintree's interface

Braintree is a company acquired by Paypal. In addition to supporting Paypal payment, it also provides upgrade plans, credit cards, customer information, etc. A complete series of management, more convenient to use; Paypal's second set of REST interface actually integrates most of these functions, but Paypal's Dashboard cannot directly manage this information but Braintree can, so I actually prefer to use Braintree. The key is that the backend framework I use is Laravel, and its cashier solution supports Braintee by default, so this set of interfaces is my first choice. But when I implemented all its functions, I found a painful problem: Braintree is not supported in China. . . . . . Death. . .

REST API

This is a product that adapts to the development of the times. If you have used OAuth 2.0 and REST API before, you should not have any confusion when looking at these interfaces.

Old interface

Unless the REST API interface cannot be satisfied, such as policy restrictions, it is not recommended to use it. The whole world is migrating to the OAuth 2.0 authentication method and the API usage method of REST API, so why go against the trend? Therefore, when the REST API can solve the problem, I did not make an in-depth comparison of this set of interfaces.

Introduction to REST API

It is still very cumbersome to adjust these APIs directly. At the same time, we just want to complete the business requirements as soon as possible instead of getting into an in-depth understanding of the API.

So how to get started? It is recommended to directly install the officially provided PayPal-PHP-SDK and use its Wiki as a starting point.

Before completing the first example, please make sure you have a Sandbox account and configured it correctly:

  • Client ID

  • Client Secret

  • Webhook API (must start with https and be port 443, localDebuggingIt is recommended to use ngrok reverse proxy to generate the address)

  • Returnurl (note the same as above)

  • Payments This is a one-time payment interface and does not support recurring donations. The main payment content includes support for Paypal payment, credit card payment, support through saved credit card (requires the use of Vault interface, such an interface is mainly due to PCI requirements, does not allow general websites to collect sensitive credit card information), supports payment to the third Third party payee.

  • Payouts Not used, ignore;

  • Authorization and Capture supports logging in to your website directly through your Paypal account and obtains relevant information;

  • Sale Follow Relevant to the mall, not used, ignored;

  • Order Relevant to the mall, not used, ignored;

  • Billing Plan & Agreements Upgrade plan and contract, that is, the subscription function, you must use the function here to achieve recurring deductions, which is the focus of this article;

  • Vault Store credit card information

  • ##Payment Experience Not used, ignored;

  • Notifications Process the information of Webhook, Important, but not the focus of this article;

  • Invoice Invoice processing;

  • Identity Authentication processing, realizing OAuth 2.0 login, and obtaining the corresponding token to request other APIs. This Paypal-PHP-SDK has already been completed and will not be discussed in this article.

    How to implement recurring deductions

    Four steps:

    1. Create an upgrade plan and activate it;

    2. Create a subscription (create Agreement), and then jump to Paypal's website to wait for user consent;

    3. After the user agrees, execute the subscription

    4. Get the debit bill

    1. Create an upgrade plan

    The upgrade plan corresponds to the Plan class. There are several points to note in this step:

    • After the upgrade plan is created, it is in the CREATED state and must be changed to ACTIVE before it can be used normally.

    • Plan has two objects, PaymentDefinition and MerchantPreferences, both of which cannot be empty;

    • If you want to create a TRIAL type plan, The plan must also have a matching REGULAR payment definition, otherwise an error will be reported;

    • Look at the code and call a setSetupFee (very, very, very important) method, which sets the completion of the subscription The fee for the first debit after that, while the recurring deduction method of the Agreement object sets the fee at the beginning of the second time.

    Take creating a Standard plan as an example, its parameters are as follows:

    $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"
     ];

    The code to create and activate the plan is as follows:

     //上面的$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. Create a subscription (create Agreement), and then jump to Paypal's website to wait for the user's consent

    After the Plan is created, how do you let users subscribe? In fact, it is to create an Agreement. Regarding Agreement, there are the following points to note:

    • As mentioned earlier, the setSetupFee method of the Plan object sets the fee for the first deduction after completing the subscription, while the cyclic deduction method of the Agreement object The fee is set at the beginning of the second time.

    • The setStartDate method sets the time for the second deduction, so if you cycle on a monthly basis, it should be the current time plus one month. At the same time, this method requires that the time format is ISO8601 format. , can be easily solved using the Carbon library;

    • When creating the Agreement, the unique ID has not been generated yet, so I encountered a small difficulty: that is when the user completes the subscription , how do I know which user this subscription belongs to? The token in the URL obtained through Agreement's getApprovalLink method is unique. I extract the token as a method of identification and replace it with the real ID after the user completes the subscription.

    The example parameters are as follows:

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

    The code is as follows:

     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,等待用户同意
     }

    Function Returns $approvalUrl after execution, remember to pass redirect( $approvalUrl) jumps to Paypal's website to wait for user payment.

    After the user agrees, execute the subscription

    After the user agrees, the subscription has not been completed. The execute method of Agreement must be executed to complete the real process. subscription. The important thing to note in this step is that

    • After completing the subscription, it does not mean that the payment will be deducted, and it may be delayed for a few minutes;

    • If the first step If the setSetupFee fee is set to 0, the order will not be generated until the recurring deduction time is up;

    The code snippet is as follows:

     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;
     }

    Get transaction records

    After subscribing, the transaction record of transaction deduction may not be generated immediately. If it is empty, try again after a few minutes. Notes on this step:

    • start_date and end_date cannot be empty

    • In actual testing, the object returned by this function cannot always return empty JSON object, so if you need to output JSON, please manually extract the corresponding parameters according to the API description of 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() ;
     }

    Finally, of course Paypal also has a corresponding official tutorial, but it calls the native interface. The difference with the process above is that it only talks about the first three steps

    Issues that need to be considered

    The function has been implemented, but many attention points have also been found:

    • The connection is particularly slow when using Sandbox for testing in China. It often prompts a timeout or error, so special consideration needs to be given to the situation where the user closes the page mid-execution;

    • Be sure to implement webhook, otherwise when the user cancels the subscription in Paypal, your website will not be able to Notice;

    • Once a subscription (Agreement) is generated, it will remain in effect unless canceled actively. Therefore, if your website is designed with multiple upgrade plans (such as Basic, Standard, Advanced), when the user has subscribed to a plan and switches to an upgrade plan, the previous upgrade plan must be canceled during development;

    • The user agrees to subscribe - (cancel the old subscription - complete the signing of the new subscription - modify the user information to the new subscription), the whole process of brackets should be an atomic operation, and it is time-consuming and long. Therefore, it should be put into the queue until it succeeds and the experience will be better.

    The above is the detailed content of Sample code sharing for Paypal to implement recurring deduction (subscription) function. For more information, please follow other related articles on the PHP Chinese website!

    Statement
    The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
    使用PHP和PayPal实现在线支付使用PHP和PayPal实现在线支付May 11, 2023 pm 03:37 PM

    随着互联网的迅猛发展,越来越多的企业选择将产品和服务线上销售,这使得在线支付成为企业的一大需求。而PayPal作为世界领先的在线支付平台,也成为了许多企业的首选。本文将介绍如何使用PHP和PayPal实现在线支付。我们将分为以下几个步骤:创建PayPal账号和应用集成PayPalSDK获取付款Token处理付款处理付款确认创建PayPal账号和应用要使用P

    paypal无法付款的原因是什么paypal无法付款的原因是什么Sep 01, 2023 pm 05:00 PM

    paypal无法付款的原因是账户余额不足、付款方式被限制、交易被风控系统拦截、收款方账户问题、网络连接问题以及用户账户异常等。详细介绍:1、账户余额不足,可以通过银行转账或信用卡充值来增加账户余额;2、付款方式被限制,查看付款设置并确保所选的付款方式没有受到限制;3、交易被风控系统拦截,联系PayPal客服,提供相关信息以证明交易的合法性,并请求解除付款限制等等。

    GCash launches PayPal's stable coin, allowing Filipinos to trade cryptocurrency protected from price volatilityGCash launches PayPal's stable coin, allowing Filipinos to trade cryptocurrency protected from price volatilityJul 31, 2024 am 06:36 AM

    GCash on Tuesday said PayPal USD (PYUSD) tokens could now be traded via GCrypto, an in-app feature powered by the Philippine Digital Asset Exchange, at “low transaction fees.”

    paypal无法付款是什么原因paypal无法付款是什么原因Oct 16, 2023 pm 03:23 PM

    paypal无法付款是因为付款方式、账户余额、Paypal余额、付款信息、网络问题、Paypal系统、商家和浏览器等问题造成的。详细介绍:1、付款方式,请确使用的付款方式已经添加到Paypal账户中;2、账户余额,确保Paypal账户余额足够支付订单金额;3、Paypal余额,查看账户状态,了解是否存在异常情况;4、付款信息,确保输入的付款信息正确无误,如信用卡号、到期日期等。

    欧洲人用paypal吗欧洲人用paypal吗Nov 10, 2022 am 10:52 AM

    欧洲人用paypal,但不是通用的,只有开通的地区才可以使用;PayPal是一个总部在美国加利福尼亚州圣荷塞市的在线支付服务商;PayPal账户是PayPal公司推出的安全的网络电子账户,使用它可有效降低网络欺诈的发生;PayPal账户所集成的高级管理功能,能掌控每一笔交易详情。

    paypal官方app下载paypal官方app下载Apr 23, 2024 am 10:00 AM

    要下载 PayPal 官方应用程序,请访问 PayPal 官方网站:https://www.paypal.com/ 单击“下载”,根据您的设备选择相应应用程序商店,搜索“PayPal”,下载并安装,最后登录您的 PayPal 账户。该应用程序可让您轻松管理账户、确保安全、跟踪支出、无缝付款,并适用于 iOS 和 Android 设备。

    Paypal's PYUSD Nears $1B MilestonePaypal's PYUSD Nears $1B MilestoneAug 17, 2024 am 06:10 AM

    The stablecoin asset issued by Paypal is now the sixth largest stablecoin asset today after growing significantly over the past ten days.

    PayPal联手苹果Tap to Pay,数百万美国小企业实现iPhone免接触支付PayPal联手苹果Tap to Pay,数百万美国小企业实现iPhone免接触支付Apr 10, 2024 pm 12:10 PM

    3月8日消息,贝宝(PayPal)控股有限公司近日发布公告,宣布数百万美国小企业,这些企业均是Venmo和PayPalZettle的用户,现在无需任何额外硬件如扩展配件或蓝牙读卡器,只需通过支持苹果的TaptoPay功能,便可仅靠一台iPhone实现免接触式支付。苹果公司于2022年5月推出的TaptoPay功能,使得美国商家可以利用iPhone及与支持商家的iOS应用程序来接受ApplePay和其他免接触式支付方式。通过此服务,使用兼容iPhone设备的用户能够安全地处理免接触式支付以及已启用

    See all articles

    Hot AI Tools

    Undresser.AI Undress

    Undresser.AI Undress

    AI-powered app for creating realistic nude photos

    AI Clothes Remover

    AI Clothes Remover

    Online AI tool for removing clothes from photos.

    Undress AI Tool

    Undress AI Tool

    Undress images for free

    Clothoff.io

    Clothoff.io

    AI clothes remover

    AI Hentai Generator

    AI Hentai Generator

    Generate AI Hentai for free.

    Hot Article

    R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
    2 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
    Repo: How To Revive Teammates
    4 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
    Hello Kitty Island Adventure: How To Get Giant Seeds
    3 weeks agoBy尊渡假赌尊渡假赌尊渡假赌

    Hot Tools

    ZendStudio 13.5.1 Mac

    ZendStudio 13.5.1 Mac

    Powerful PHP integrated development environment

    SAP NetWeaver Server Adapter for Eclipse

    SAP NetWeaver Server Adapter for Eclipse

    Integrate Eclipse with SAP NetWeaver application server.

    EditPlus Chinese cracked version

    EditPlus Chinese cracked version

    Small size, syntax highlighting, does not support code prompt function

    DVWA

    DVWA

    Damn Vulnerable Web App (DVWA) is a PHP/MySQL web application that is very vulnerable. Its main goals are to be an aid for security professionals to test their skills and tools in a legal environment, to help web developers better understand the process of securing web applications, and to help teachers/students teach/learn in a classroom environment Web application security. The goal of DVWA is to practice some of the most common web vulnerabilities through a simple and straightforward interface, with varying degrees of difficulty. Please note that this software

    Atom editor mac version download

    Atom editor mac version download

    The most popular open source editor