Интегрируем Paypal в Laravel

Займемся интеграцией платежного шлюза Paypal в приложение Laravel.

Я для вас всё уже подготовил. Вам нужно будет просто скопировать код и вставить к себе. Предполагается, что у вас есть есть готовое приложение на Laravel. Выполните следующие шаги для интеграции Paypal.

Зарегистрируйте бесплатный бизнес-аккаунт в PayPal.

Войдите в панель инструментов разработчиков в PayPal.

В PayPal есть два режима API:

  1. Sandbox —для тестирования платежей при разработке.
  2. Live — для настоящих платежей в продакшне.

Создайте по приложению в обоих режимах.

PayPal SDK (Набор Средств Разработки) для PHP

Добавьте пакет paypal/rest-api-sdk-php в ваш проект следующей командой:

composer require paypal/rest-api-sdk-php

Создайте файл paypal.php в папке config и добавьте в него следующий код:

return [ 
    'client_id' => env('PAYPAL_CLIENT_ID',''),
    'secret' => env('PAYPAL_SECRET',''),
    'settings' => array(
        'mode' => env('PAYPAL_MODE','sandbox'),
        'http.ConnectionTimeOut' => 30,
        'log.LogEnabled' => true,
        'log.FileName' => storage_path() . '/logs/paypal.log',
        'log.LogLevel' => 'ERROR'
    ),
];

Теперь перейдите в панель инструментов PayPal и откройте приложение, которое вы создали в начале. Найдите PAYPAL_CLIENT_ID и PAYPAL_SECRET, как указано ниже.

Paypal Credentials

В ваш файл .env добавьте следующие переменные:

PAYPAL_MODE=sandbox
PAYPAL_CLIENT_ID=XXXXXXXXXXXXXXX
PAYPAL_SECRET=XXXXXXXXXXXXXXX

Создайте контроллер PaymentController:

php artisan make:controller PaymentController

Добавьте в него следующий код:

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use PayPal\Rest\ApiContext;
use PayPal\Auth\OAuthTokenCredential;
use PayPal\Api\Agreement;
use PayPal\Api\Payer;
use PayPal\Api\Plan;
use PayPal\Api\PaymentDefinition;
use PayPal\Api\PayerInfo;
use PayPal\Api\Item;
use PayPal\Api\ItemList;
use PayPal\Api\Amount;
use PayPal\Api\Transaction;
use PayPal\Api\RedirectUrls;
use PayPal\Api\Payment;
use PayPal\Api\PaymentExecution;
use Illuminate\Support\Facades\Input;
use Redirect;
use URL;

class PaymentController extends Controller
{    
    public function __construct()
    {
         /** PayPal api context **/
         $paypal_conf = \Config::get('paypal');
         $this->_api_context = new ApiContext(new OAuthTokenCredential(
             $paypal_conf['client_id'],
             $paypal_conf['secret'])
         );
         $this->_api_context->setConfig($paypal_conf['settings']);
    }    
    
    public function payWithpaypal()
    {
      $amountToBePaid = 100;
      $payer = new Payer();
      $payer->setPaymentMethod('paypal');
  
      $item_1 = new Item();
      $item_1->setName('Mobile Payment') /** название элемента **/
              ->setCurrency('USD')
              ->setQuantity(1)
              ->setPrice($amountToBePaid); /** цена **/
  
      $item_list = new ItemList();
      $item_list->setItems(array($item_1));
  
      $amount = new Amount();
      $amount->setCurrency('USD')
             ->setTotal($amountToBePaid);      
             
      $redirect_urls = new RedirectUrls();
      /** Укажите обратный URL **/
      $redirect_urls->setReturnUrl(URL::route('status'))
                ->setCancelUrl(URL::route('status'));
      
      $transaction = new Transaction();
      $transaction->setAmount($amount)
              ->setItemList($item_list)
              ->setDescription('Описание транзакции');   
   
      $payment = new Payment();
      $payment->setIntent('Sale')
              ->setPayer($payer)
              ->setRedirectUrls($redirect_urls)
              ->setTransactions(array($transaction));
      try {
           $payment->create($this->_api_context);
      } catch (\PayPal\Exception\PPConnectionException $ex) {
           if (\Config::get('app.debug')) {
              \Session::put('error', 'Таймаут соединения');
              return Redirect::route('/');
           } else {
              \Session::put('error', 'Возникла ошибка, извините за неудобство');
              return Redirect::route('/');
           }
      }
      
      foreach ($payment->getLinks() as $link) {
        if ($link->getRel() == 'approval_url') {
           $redirect_url = $link->getHref();
           break;
        }
      }
      
      /** добавляем ID платежа в сессию **/
      \Session::put('paypal_payment_id', $payment->getId());
      
      if (isset($redirect_url)) {
         /** редиректим в paypal **/
         return Redirect::away($redirect_url);
      }
  
      \Session::put('error', 'Произошла неизвестная ошибка');
      return Redirect::route('/');
    }
    
    public function getPaymentStatus(Request $request)
    {
      /** Получаем ID платежа до очистки сессии **/
      $payment_id = Session::get('paypal_payment_id');
      /** Очищаем ID платежа **/
      Session::forget('paypal_payment_id');      
      
      if (empty($request->PayerID) || empty($request->token)) {
         session()->flash('error', 'Payment failed');
         return Redirect::route('/');
      }      
      
      $payment = Payment::get($payment_id, $this->_api_context);
      $execution = new PaymentExecution();
      $execution->setPayerId($request->PayerID);      
      
      /** Выполняем платёж **/
      $result = $payment->execute($execution, $this->_api_context);
      
      if ($result->getState() == 'approved') {
         session()->flash('success', 'Платеж прошел успешно');
         return Redirect::route('/');
      }      
      
      session()->flash('error', 'Платеж не прошел');
      return Redirect::route('/');    
    }
}

 

В файл routes/web.php добавьте маршруты:

//Payment
Route::post('/payment', ['as' => 'payment', 'uses' => 'PaymentController@payWithpaypal']);
Route::get('/payment/status',['as' => 'status', 'uses' => 'PaymentController@getPaymentStatus']);

Вот и всё! Я старался всё максимально упростить, чтобы вам было удобно этим пользоваться.

Автор: Parth Patel
Перевод: Алексей Широков

Наш Телеграм-канал — следите за новостями о Laravel.