Sample code sharing for implementing the cyclic fee deduction (subscription) function using Paypal

Source: Internet
Author: User
Tags webhook
This article mainly introduces the ideas and methods for implementing cyclic fee deduction (subscription) through Paypal, and summarizes how to use the Paypal payment interface, which has good reference value. Next, let's take a look at the small series. This article mainly introduces the ideas and methods for implementing the circular deduction (subscription) of Paypal, and summarizes how to use the Paypal payment interface, which has good reference value. Let's take a look at it with the small editor.

Cause

The business needs should be integrated with Paypal to implement the cycle deduction function. However, Baidu and GOOGLE did not find any development tutorials except the official website, so they had to look at it on Paypal, it took two days for the integration to succeed. here we will summarize how to use the Paypal payment interface.

Paypal now has multiple interfaces:

  • Implement Express Checkout through Braintree (Braintree will be discussed later;

  • Create an App and use the REST Api interface (the current mainstream interface method );

  • NVP/soap api apps interface (old interface );

Braintree interface

Braintree is a company acquired by Paypal. it not only supports payment by Paypal, but also provides a series of full management functions such as upgrade plan, credit card, and customer information, making it easier to use; the second REST interface of Paypal also integrates most of these functions, but the Dashboard of Paypal cannot directly manage the information and Braintree can, so I prefer Braintree. The key is that the backend framework I use is Laravel. its cashier solution supports Braintee by default, so this interface is my first choice. But when I implemented all of its functions, I found a problem: Braintree is not supported in China ...... Pawn...

REST API

This is a product that conforms to the development of the times. if you have used OAuth 2.0 and REST APIs before, these interfaces should not be confused.

Old interface

Unless the rest api interface cannot meet, such as policy restrictions, it is not recommended. All over the world are migrating to the OAuth 2.0 authentication method and the rest api usage method. why is it against the trend. Therefore, I did not make an in-depth comparison on this interface when the REST API can solve the problem.

Introduction to REST APIs

If you directly call these APIs, it is still very cumbersome. at the same time, we just want to complete the business requirements as soon as possible, rather than getting into a deeper understanding of the APIs.

So how to start, it is recommended to directly install the official PayPal-PHP-SDK, through its Wiki as the starting point.

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

  • Client ID

  • Client Secret

  • Webhook API (it must start with https and port 443. we recommend that you use ngrok reverse proxy to generate an address for local debugging)

  • Returnurl (same as above)

  • PaymentsThe one-time payment interface does not support circular donation. The main payment options include Paypal payment and credit card payment, which are supported by saved credit cards (using the Vault interface is required, and such an interface is mainly required by PCI, do not allow websites to collect sensitive credit card information.

  • PayoutsUseless, ignore;

  • Authorization and CaptureYou can directly log on to your website using a Paypal account and obtain relevant information;

  • SaleRelated to the mall, useless, ignored;

  • OrderRelated to the mall, useless, ignored;

  • Billing Plan & AgreementsThe upgrade plan and contract signing, that is, the subscription function, must be used to implement the cycle deduction function, which is the focus of this article;

  • VaultStore credit card information

  • Payment ExperienceUseless, ignore;

  • CommunicationsProcessingWebhookImportant, but not the content of this article;

  • InvoiceBill handling;

  • IdentityAuthentication processing, the implementation of OAuth 2.0 login, get the corresponding token to request other APIs, this Paypal-PHP-SDK has been done in, this article does not talk about.

    How to implement fee deduction cycle

    There are four steps:

    1. Create and activate an upgrade plan;

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

    3. After the user agrees, execute the subscription

    4. Get deduction bill

    1. create an upgrade plan

    The upgrade Plan corresponds to the Plan class. Note the following points:

    • After the upgrade plan is CREATED, it is in the CREATED state. you must change the status to ACTIVE for normal use.

    • The Plan has two objects: PaymentDefinition and MerchantPreferences. both objects cannot be empty;

    • If you want to create a TRIAL plan, the plan must have a corresponding REGULAR payment definition; otherwise, an error is reported;

    • The code calls a setsetupcharge (very, very, very important) method, which sets the fee for the first deduction after the subscription is completed, the cyclic fee deduction method of the Agreement object is set to the fee at the beginning of 2nd.

    Take creating a Standard plan as an example. the 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 for creating and activating a scheduler is as follows:

    // The above $ param example is an array. in my actual application, the input is actually an object, which can be understood by the user. 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 '); // The example is always set to an INFINITE loop // # Payment definitions for this billing plan. $ paymentDefinition = new PaymentDefinition (); // The possible values for su Ch 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 shoshould 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)-> setCy Cles (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-> setR EturnUrl ("$ returnUrl? Success = true ")-> setCancelUrl (" $ returnUrl? Success = false ")-> setAutoBillAmount (" yes ")-> setInitialFailAmountAction (" CONTINUE ")-> setMaxFailAttempts (" 0 ") -> setsetupcy (new Currency (array ('value' => $ param-> amount, 'currency '=> 'use '))); $ 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 the Paypal website waiting for the user's consent

    After the Plan is created, how can users subscribe to it? in fact, Agreement is created. for details about Agreement, pay attention to the following points:

    • As described above, the setsetupcharge method of the Plan object sets the fee for the first deduction after the subscription is completed, and the cycle deduction method of the Agreement object sets the fee at the beginning of the first 2nd.

    • The setStartDate method sets the time when the fee is deducted for 2nd times. Therefore, if you cycle by month, you should add the current time to a month. at the same time, this method requires that the time format be ISO8601, using the Carbon library can be easily solved;

    • When creating an Agreement, there is no unique ID yet, so I encountered a small difficulty: that is, when the user completes the subscription, how do I know which user the subscription belongs? The token in the URL obtained through the getApprovalLink method of Agreement is unique. I extract the token as the recognition method and replace it with a Real ID after the user completes the subscription.

    The example parameters are as follows:

    $ Param = ['id' => 'P-26T36113JT475352643KGIHY ', // id 'name' => 'standard' generated when you created the Plan in the previous step ', '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 shocould 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 inserting ing the ID just yet. $ agreement = $ agreement-> create ($ apiContext); // ### Get redirect url // The API response provides the url that you must redirect // the buyer. 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; // jump to $ approvalUrl, waiting for user consent}

    After the function is executed, $ approvalUrl is returned. remember to jump to the Paypal website through redirect ($ approvalUrl) and wait for the user to pay.

    After the user agrees, execute the subscription

    After the user agrees, the subscription has not been completed yet. the execute method of Agreement must be executed to complete the real subscription. Note that

    • After the subscription is completed, the fee deduction may be delayed for several minutes;

    • If the setSetupFee fee in step 1 is set to 0, the order will not be generated until the cycle deduction time is reached;

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

    Obtain transaction records

    After subscription, the transaction record of transaction fee deduction may not be generated immediately. if it is blank, try again in a few minutes. Note:

    • Start_date and end_date cannot be blank

    • During actual testing, the objects returned by the function cannot always return null JSON objects. Therefore, if you need to output JSON objects, manually retrieve the corresponding parameters according to the API description of AgreementTransactions.

    /** Obtain transaction records * @ param $ id subscribe payment_id * @ warning always obtains all records of this subscriber */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, the official Paypal course also has a corresponding tutorial, but it calls the native interface. Unlike the above process, the point is that only the first three steps are mentioned.

    Issues to consider

    The function is implemented, but some notes are also found:

    • When testing Sandbox in China, the connection is particularly slow, and timeout or errors are often prompted. Therefore, you need to take special consideration when you close the page halfway;

    • Make sure to implement webhook; otherwise, your website will not be notified when you cancel subscription through Paypal;

    • Once a subscription is generated, it will take effect until it is canceled. Therefore, if your website has designed multiple upgrade plans (such as Basic, Standard, and Advanced), when the user has subscribed to a plan and switched the upgrade plan, the previous upgrade plan must be canceled during development;

    • The user agrees to subscribe-(cancel the old subscription-contract the new subscription-change the user information to the new subscription). The entire process of parentheses should be atomic and time-consuming, therefore, it should be put into the queue for execution until the successful experience is better.

    The above is the sample code for Paypal to implement the cycle deduction (subscription) function. For more information, see other related articles in the first PHP community!

    Contact Us

    The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

    If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.