PayPal implementation of circular Debit (subscription) function method

Source: Internet
Author: User
Tags oauth webhook
This paper mainly introduces the idea and method of PayPal to realize cyclic debit (subscription), and summarizes how to use PayPal's payment interface, which has good reference value.

Cause

Business needs to integrate PayPal, to achieve a circular debit function, however, Baidu and Google a lap, in addition to the official website, did not find relevant development tutorials, had to look at PayPal, spent two days after the integration success, here on how to use PayPal payment interface to do a summary.

PayPal now has multiple sets of interfaces:

    • Express Checkout is realized through Braintree (later talks Braintree);

    • Create apps, via the Rest API interface (now the mainstream interface mode);

    • Nvp/soap API Apps Interface (Legacy interface);

interface of the Braintree

Braintree is a PayPal acquisition of a company, in addition to support PayPal's payment, but also provides upgrade plans, credit cards, customer information, such as a full range of management, the use of more convenient; these features PayPal's second set of rest interfaces actually integrates most of the But PayPal's dashboard can't manage this information directly and 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 interface is my first choice. But when I put it to the realization of the function and found an egg pain problem: Braintree in the country does not support ... Stroke ...

REST API

This is the product of the development of the times, if you have used OAuth 2.0 and Rest API, then look at these interfaces should not be confused.

Old interface

It is not recommended unless the rest API interface is not satisfied, such as policy restrictions. The world is migrating to the OAuth 2.0 authentication method and the rest API's API usage, why not go against the trend. So in the rest API can solve the problem situation, I also did not do in-depth comparison of this interface.

Introduction to REST APIs

The official API Reference document, https://developer.paypal.com/webapps/developer/docs/api/, has a more detailed description of its API and usage, but it is cumbersome to directly tune these APIs. At the same time, we just want to complete the business requirements as soon as possible rather than get into the API.

So how to get started, it is recommended to install the official PAYPAL-PHP-SDK directly through its wiki as a starting point.

Before you complete the first example, make sure you have the sandbox account and configure it correctly:

    • Client ID

    • Client Secret

    • Webhook API (must be HTTPS start and port 443, local debug recommendations combined with Ngrok reverse proxy generation address)

    • Returnurl (note above)

After completing the first example of the wiki, understanding the classification of the interface will help you to complete your business requirements, let me introduce the interface classification, please use the example to understand the http://paypal.github.io/PayPal-PHP-SDK/sample/#payments.

  • Payments One-time payment interface, does not support circular donation. The main payment content is to support PayPal payment, credit card payment, through the saved credit card support (need to use the Vault interface, there will be such interface is mainly PCI requirements, do not allow the general website to collect credit card sensitive information), support to third-party payee.

  • Payouts useless, neglect;

  • Authorization and capture support to access your website directly via PayPal's account and obtain relevant information;

  • Sale with the mall, useless to, ignore;

  • Order is related to the mall, useless, ignored;

  • Billing Plan & agreements upgrade program and signing, that is, the subscription function, the realization of circular debit must use the function here, this is the focus of this article;

  • Vault Stores credit card information

  • Payment Experience useless, ignore;

  • Notifications Processing Webhook information, important, but not the content of this article;

  • Invoice bill processing;

  • Identity Authentication processing, the implementation of OAuth 2.0 landing, to obtain the corresponding token in order to request other APIs, this piece of paypal-php-sdk has been done, this article also does not talk about.

How to achieve circular deduction

In four steps:

    1. Create an upgrade plan and activate it;

    2. Create a subscription (create agreement) and then jump to PayPal's website for user consent;

    3. After the user agrees to execute the subscription

    4. Get a debit Bill

1. Create an upgrade plan

The upgrade plan corresponds to plan class. This step has several points to note:

    • After the upgrade plan is created, in the created state, you must modify the state to active for normal use.

    • Plan has paymentdefinition and merchantpreferences two objects, both of which cannot be empty;

    • If you want to create a trial type of plan, the plan must also have a matching regular payment definition, otherwise it will be an error;

    • Look at the code that calls a Setsetupfee (very, very, very important) method that sets the cost of the first deduction after the subscription is completed, while the Agreement object's circular deduction method sets the cost at the start of the 2nd time.

To create a standard plan, for example, the parameters are as follows:

$param = ["Name" = "standard_monthly", "display_name" and "Standard Plan", "desc" and "standard plan for one Mont" H "," type "=" REGULAR "," frequency "=" MONTH "," frequency_interval "= 1," cycles "= 0," Amount "+ 20, "Currency" = "USD"];

Create and activate the plan code as follows:

 The above $param example is the number of groups, my actual application is actually an object, the user understand the next good. Public Function Createplan ($param) {$apiContext = $this->getapicontext (); $plan = new plan ();//# Basic Information/ /Fill up the basic information, that's required for the plan $plan->setname ($param->name)->setdescription ($para M->DESC)->settype (' INFINITE ');//The example is always set to infinite loop//# Payment definitions for this billing plan. $paymentDefinition = new Paymentdefinition (); The possible values for such setters is 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 is 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 (' value ' = = $param->amount, ' Currency ' => $param->currency))); Charge Models $chargeModel = new Chargemodel (); $chargeModel->settype (' tax ')->setamount (The New Currency (' 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 (The 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 P Atch (); $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 waiting for user consent

Plan created, how to let users subscribe to, in fact, is to create agreement, about agreement, there are the following points of attention:

    • As mentioned earlier, the Plan object's Setsetupfee method sets the charge for the first deduction after the subscription is completed, while the Agreement object's circular deduction method sets the cost at the start of the 2nd time.

    • The Setstartdate method sets the time for the 2nd deduction, so if you cycle by month, it should be the current time plus one months, and the method requires time format is ISO8601 format, using carbon library can easily solve;

    • When I created agreement, I didn't generate a unique ID at this point, so I ran into a little difficulty: how do I know which user this subscription is when the user completes the subscription? By agreement the Getapprovallink method to get the URL, inside the token is unique, I by extracting the token as a recognition method, after the user completes the subscription to replace the real ID.

The example parameters are as follows:

$param = [' id ' = ' p-26t36113jt475352643kgihy ',//the ID generated in the previous step to create plan ' 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 is 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 have 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's must redirect//the buyer to. Retrieve the URL from the $agreement->getapprovallink ()//Method $APPROVALURL = $agreement->getapprovallink (); } catch (ExceptioN $ex) {return "Create payment failed, retry or contact the merchant.";} return $APPROVALURL;//Jump to $approvalurl, wait User Consent}

After the function is executed, return to $approvalurl, and remember to jump to PayPal's website by redirect ($APPROVALURL) waiting for the user to pay.

After the user agrees to execute the subscription

After the user agrees, the subscription is not completed and the agreement execute method must be executed to complete the real subscription. The point of attention in this step is

    • After completing the subscription, it is not equal to the debit, may delay a few minutes;

    • If the Setsetupfee fee for the first step is set to 0, the order must wait until the time of the loop deduction 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-& Gt;execute ($token, $apiContext); } catch (\exception $e) {return ull; return $agreement;} return null; }

Get Transaction history

After subscribing, transactions that may not immediately incur a transaction charge, if empty, are tried again in a few minutes. This step notes the point:

    • Start_date and end_date cannot be empty

    • When actually testing, the object returned by the function cannot always return an empty JSON object, so if you need to output JSON, manually remove the corresponding parameters according to the Agreementtransactions API description.

/** Get Transaction * @param $id subscription payment_id * @warning always get all records of the 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 Transac tions failed ". $e->getmessage ()); return null; } return $result->getagreementtransactionlist (); }

Finally, PayPal official course also has a corresponding tutorial, but call the native interface, and my above process is not the same point is only said the first 3 steps for interested reference: https://developer.paypal.com/docs/integration/ direct/billing-plans-and-agreements/.

Issues to consider

function is realized, but also found a lot of attention points:

    • Domestic use of the sandbox test connection is particularly slow, often prompt time-out or error, it is necessary to consider the implementation of the halfway user to close the page;

    • Be sure to implement Webhook, otherwise when the user into the PayPal unsubscribe, your site will not be notified;

    • The subscription (agreement) will remain in effect once it is created, unless it is actively canceled. So if your site is designed with multiple upgrade plans (such as basic,standard,advanced), when a user has subscribed to a plan to switch the upgrade plan, the previous upgrade plan must be canceled on development;

    • User agrees to subscribe-(cancel old subscription-sign up for new subscription-modify user information to new subscription), the entire process should be atomic and time-consuming, so it should be put in the queue for execution until the successful experience is better.

The above is the whole content of this article, I hope that everyone's study has helped.


Related Article

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.