📜 ⬆️ ⬇️

Meet the PayPal API

At the moment, PayPal is the most popular electronic payment platform. Exactly how easy it is to open an account and start receiving funds for it, compared to traditional methods of receiving payments, is the reason # 1 for its extreme popularity. The second reason many would agree with me is the powerful API provided by PayPal. In this topic, I will decompose in order all the methods and tricks associated with the work of PayPal API, so that you avoid problems with its integration.


Warning: PayPal API is one of the most disgusting that I have ever seen. Inaccurate, in some places incomplete or inconsistent documentation, unpredictable failures and a significant difference between the work of the API in real conditions and in the sandbox, all this is essentially a pain in the ass that you have to deal with.

Part 1: PayPal Payment Types


PayPal offers a whole range of payment methods, which is bound to confuse a person unfamiliar with PP:
')
Express payment
The main service from a variety of similar ones offered by PayPal. An express payment will allow you to receive funds without having a merchant account, and in general, no special requirements whatsoever, except for a banal account confirmation (either through a bank account or through a credit / debit card), no. Previously, users could only accept express payments from other PayPal users, but since the system introduced the ability to pay directly from a bank card for those who do not have an account, it is possible to receive payments from almost everyone who has a card. Please note that express payments are entirely made on PayPal, so this method cannot be fully integrated into your website.

Direct payment
This method will allow you to receive payments from bank cards through a simple API call. This will allow you to fully integrate the entire translation process into your website, which, in some cases, will make shopping for your users more convenient. There is another variation of the direct payment, which will allow you to authorize the transfer and execute it only after a certain period of time. The postpone method is available only to users from the United States, Canada and the United Kingdom.

Recurring payment
This method will allow you to re-withdraw funds from the user's account (for example, it is used in the monthly payment for any subscription).

Bulk payment
Mass payment will allow you to divide the funds received between multiple accounts.

Adaptive Payments
This option basically performs the same function as the previous one, but with some differences (I’ve already mentioned that PayPal API is confusing and full of excesses).

This list can not be called complete, but it lists the most popular ways to receive funds (Want more - welcome to the documentation ).

Part 2: Creating an API Request
PayPal supports two formats of data transfer via the HTTP protocol: NVP and SOAP. NVP is an abbreviation for the Name-Value Pair, meanwhile SOAP stands for Simple Object Access Protocol. I’ll only talk about NVP, since it’s much more flexible than SOAP.

All methods listed in part 1 have their own parameters, but they all have several identical basic parameters that are passed to identify the API account and authorize the payment:
The last of the required parameters is METHOD , which announces what method of transfer of funds we will use.

Requests are transmitted using the HTTPS protocol. For example, we will use cURL to form our simple request, and then we will put the whole process into a separate class:
 class Paypal { /** *     * @var array */ protected $_errors = array(); /** *  API *    ,        * @var array */ protected $_credentials = array( 'USER' => 'seller_1297608781_biz_api1.lionite.com', 'PWD' => '1297608792', 'SIGNATURE' => 'A3g66.FS3NAf4mkHn3BDQdpo6JD.ACcPc4wMrInvUEqO3Uapovity47p', ); /** * ,     *   - https://api-3t.paypal.com/nvp *  - https://api-3t.sandbox.paypal.com/nvp * @var string */ protected $_endPoint = 'https://api-3t.sandbox.paypal.com/nvp'; /** *  API * @var string */ protected $_version = '74.0'; /** *   * * @param string $method      * @param array $params   * @return array / boolean Response array / boolean false on failure */ public function request($method,$params = array()) { $this -> _errors = array(); if( empty($method) ) { // ,     $this -> _errors = array('    '); return false; } //    $requestParams = array( 'METHOD' => $method, 'VERSION' => $this -> _version ) + $this -> _credentials; //    NVP $request = http_build_query($requestParams + $params); //  cURL $curlOptions = array ( CURLOPT_URL => $this -> _endPoint, CURLOPT_VERBOSE => 1, CURLOPT_SSL_VERIFYPEER => true, CURLOPT_SSL_VERIFYHOST => 2, CURLOPT_CAINFO => dirname(__FILE__) . '/cacert.pem', //   CURLOPT_RETURNTRANSFER => 1, CURLOPT_POST => 1, CURLOPT_POSTFIELDS => $request ); $ch = curl_init(); curl_setopt_array($ch,$curlOptions); //   , $response     API $response = curl_exec($ch); // ,      cURL if (curl_errno($ch)) { $this -> _errors = curl_error($ch); curl_close($ch); return false; } else { curl_close($ch); $responseArray = array(); parse_str($response,$responseArray); //  ,   NVP   return $responseArray; } } } 

Please note that I used a CA certificate for SSL validation. The certificate file can be found on the cURL website . Do not forget to change the path to the certificate in accordance with the location where you downloaded it.

The response to the request will be in NVP format, and I have broken it into an array. The ACK parameter indicates the result of processing the request: Success or SuccessWithWarning in case the request was successful, Error or Warning in case the request failed.

The request can be rejected for a variety of reasons, and for each method of payment has its own reasons, which are discussed in detail in the documentation . A little later we will look at some of them and learn how to fix them. By the way, pay attention to the fact that all the parameters in the request are case-sensitive, which is often the reason for the failure.

Part 3: We work with express payment
One of the most popular ways to transfer funds is an express payment, which allows you to receive funds without opening a special account (Website Payments Pro), which is available only to US citizens, and the payment is made on the PayPal side, which does not require any protection.

The entire payment passes according to the following algorithm:
  1. We request access tokens from PayPal by sending transfer details;
  2. If the token is received, we redirect the user to the PayPal site using the received token;
  3. The user makes or cancels a payment on the PayPal platform, and then redirects back to our site;
  4. We complete the payment, either when the user is redirected back, or via Instant Payment Notification (IPN) .



1. Get the token: SetExpressCheckout
The express payment process starts by sending payment data to the PayPal API, after which we get a token that identifies our transaction. This token will come in handy in the next step when we send the user to the PayPal platform.

The following parameters must be specified in the request:
We can also pass additional parameters that will allow us to expand the set of information about the payment, some of the parameters have default values:
If the user pays for several products at once, then it is possible to make a list of products for convenience:


The variable m identifies a specific product (use the same variable index for the parameters applicable to the same product).

There is a whole host of optional parameters that you can easily find in the documentation .

We use the function we wrote earlier in part 2 to form a SetExpressCheckout request:
 //    $requestParams = array( 'RETURNURL' => 'http://www.yourdomain.com/payment/success', 'CANCELURL' => 'http://www.yourdomain.com/payment/cancelled' ); $orderParams = array( 'PAYMENTREQUEST_0_AMT' => '500', 'PAYMENTREQUEST_0_SHIPPINGAMT' => '4', 'PAYMENTREQUEST_0_CURRENCYCODE' => 'GBP', 'PAYMENTREQUEST_0_ITEMAMT' => '496' ); $item = array( 'L_PAYMENTREQUEST_0_NAME0' => 'iPhone', 'L_PAYMENTREQUEST_0_DESC0' => 'White iPhone, 16GB', 'L_PAYMENTREQUEST_0_AMT0' => '496', 'L_PAYMENTREQUEST_0_QTY0' => '1' ); $paypal = new Paypal(); $response = $paypal -> request('SetExpressCheckout',$requestParams + $orderParams + $item); 


2. Use the resulting token to redirect to PayPal
If the request was successful, we will receive a token in the TOKEN parameter in the response from PayPal.
 if(is_array($response) && $response['ACK'] == 'Success') { //     $token = $response['TOKEN']; header( 'Location: https://www.paypal.com/webscr?cmd=_express-checkout&token=' . urlencode($token) ); } 
Now the user is sent to the PayPal platform, where the entire transfer process will be processed. When the user successfully completes or cancels the payment, he will be sent to one of the relevant pages, which we indicated in the request.

3. Complete the translation
Suppose a user has confirmed a transfer, after which he will be sent back to our website. At this very moment, we need to use two appropriate API functions: DoExpressCheckoutPayment will complete the transfer, but before that we need to get more information about the customer using GetExpressCheckoutDetails .

PayPal will redirect the user back to our website along with the token we will use to call these functions. The token will be listed in the URL in the token parameter. We will check its presence in the address to which the user is transferred and send the necessary requests to the API in case he is present.

The GetExpressCheckoutDetails function requires the transfer of a single token, and the DoExpressCheckoutPayment requires the specification of several additional parameters:
 if( isset($_GET['token']) && !empty($_GET['token']) ) { //   //   ,    . //        ,  ,    $paypal = new Paypal(); $checkoutDetails = $paypal -> request('GetExpressCheckoutDetails', array('TOKEN' => $_GET['token'])); //   $requestParams = array( 'PAYMENTREQUEST_0_PAYMENTACTION' => 'Sale', 'PAYERID' => $_GET['PayerID'] ); $response = $paypal -> request('DoExpressCheckoutPayment',$requestParams); if( is_array($response) && $response['ACK'] == 'Success') { //    //    ID ,      $transactionId = $response['PAYMENTINFO_0_TRANSACTIONID']; } } 


Part 4: We work with direct payment
Direct payment allows you to fully control the entire process of transferring funds right on your website. For some unknown reason, in this case, buyers without a PayPal account will not be able to pay for services and products on your site, but it will be possible to make the whole process as simple as possible, which will have a positive impact on users' opinions. Full control over the process actually allows us to optimize and increase sales.

This method is a bit simpler than an express payment, because all user interaction occurs on your website, and we will need to make only one request to the API: DoDirectPayment .

But you should pay attention to the fact that you will have to make a few more requests if you are going to debit money from the user's account after a certain period of time (for example, when you are waiting for the goods to be transferred to the delivery service). For this, we will use the methods of Authorization and Capture , about which I will not tell you, but you still need to know about their existence.

1. Required parameters
Direct payment, as was said earlier, requires the indication of completely different parameters. Despite the fact that the parameters indicating the details of the transfer are similar to the express payment (the same appointments, other names are more fun), this method requires information about the bank card and address.

The main parameters of direct payment:

Bank card details:

Information about the buyer:The address will be processed by the address verification system (AVS) . You will be returned a specific error if the transaction was rejected due to an incorrect address.

The parameters for specifying payment details are similar to those for express payments, but with some differences in names ( AMT , ITEMAMT , CURRENCYCODE , SHIPPINGAMT , TAXAMT and DESC should be used). See the documentation for details.

In the same way, to enter information about products, you must use the following parameters: L_NAMEm , L_DESCm , L_AMTm and L_QTYm . The variable m is used to delimit the parameters for each individual product (replace with 0, 1 and further for the numbered positions in the order). Consult the documentation for a more complete list .

2. Conducting a transaction
Sending a request using the function we wrote earlier is very similar to the case of express payment. We pass all parameters in exactly the same way, but specify DoDirectPayment as the method.
 $requestParams = array( 'IPADDRESS' => $_SERVER['REMOTE_ADDR'], 'PAYMENTACTION' => 'Sale' ); $creditCardDetails = array( 'CREDITCARDTYPE' => 'Visa', 'ACCT' => '4929802607281663', 'EXPDATE' => '062012', 'CVV2' => '984' ); $payerDetails = array( 'FIRSTNAME' => 'John', 'LASTNAME' => 'Doe', 'COUNTRYCODE' => 'US', 'STATE' => 'NY', 'CITY' => 'New York', 'STREET' => '14 Argyle Rd.', 'ZIP' => '10010' ); $orderParams = array( 'AMT' => '500', 'ITEMAMT' => '496', 'SHIPPINGAMT' => '4', 'CURRENCYCODE' => 'GBP' ); $item = array( 'L_NAME0' => 'iPhone', 'L_DESC0' => 'White iPhone, 16GB', 'L_AMT0' => '496', 'L_QTY0' => '1' ); $paypal = new Paypal(); $response = $paypal -> request('DoDirectPayment', $requestParams + $creditCardDetails + $payerDetails + $orderParams + $item ); if( is_array($response) && $response['ACK'] == 'Success') { $transactionId = $response['TRANSACTIONID']; } 


5:
If we lived in an ideal world, this part would not exist. In reality, you will have to refer to this part or similar sections in other articles quite often. PayPal may refuse to make a payment for one of a whole bunch of errors, and the correction of some of them is not under our control.

The $response variable, which contains the response from the paypalApiRequest() function, may contain in the ACK parameter a value that does not correspond to Success , namely:
It turns out that there are two successful statuses and two failures. All the code specified above works only with the status of success, but we can easily replace it with SuccessWithWarning , but do not forget to check what the matter is and what the warning is about. The most common error scenario for a direct payment is that the request was successfully accepted and verified, but the bank rejected the request to withdraw funds from the card.

The errors returned by PayPal are enclosed in four parameters in the response:The variable 0 at the end of the parameters is the sequence number of the error that occurred (if there are several errors, then the variable will have 1, 2, and so on).

Here is a small list of the most common errors:
?
Some PayPal errors may contain private information in your description, which you hardly want to show to users. For this reason, users are advised to turn off error display, even if it may be useful.

In most cases, I would advise to do the following:
  1. Create a white list of errors that can be shown to users (for example, incorrect data on a bank card);
  2. Make it so that when returning errors, they are checked against the white list;
  3. If there is no error in this list, the user needs to display some general error, for example, “An error has occurred during the processing of your payment. Wait a few minutes or contact us to solve this problem. "


In this topic, I talked about the two most popular APIs and about working with errors. This should be enough so that you can start working with the most popular payment system on the network.

In the PayPal API, you can find a lot more methods and methods, more than one topic. Once you learn how to work with the two most popular ways, learning the rest will be much easier. I hope that this guide will give you a good start in using the API.

Original article: Getting Started With The PayPal API , Eran Galperin, September 5, 2011.

I really hope that this translation will be really useful for the habrasoobshchestvo. In other words, I still do not lose hope for the holiday on September 24th. Wait and see.

image
This text is distributed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 license .
You can copy, edit and use this text for non-commercial purposes with the obligatory indication of authorship and preservation of the original license.

Source: https://habr.com/ru/post/128198/


All Articles