Как интегрировать PayPal на сайт с Laravel
Эта статья расскажет как интегрировать Paypal на сайт с фреймворком Laravel. Для этой цели я буду использовать пакет Omnipay, свежая версия которого требует, чтобы ваш сайт шуршал на версии PHP 7.4 или выше.
Теперь по порядку. План такой:
1) создаем бизнес-аккаунт в Paypal и создаем приложение;
2) устанавливаем пакет Omnipay;
3) наливаем чай с мёдом, чтобы поддержать мозги глюкозой и сахарозой;
4) создаем модель и миграцию таблицы для работы с платежами;
5) создаем контроллер и пишем код для отправки платежей.
Глава 1. Создаем бизнес-аккаунт в Paypal и создаем приложение
Если у вас нет бизнес-аккунта, то создаем его. Далее создаю тестовое приложение, т.к тестировать всё же приятно на виртуальных деньгах. Заходим в пространство разработчика Paypal по адресу https://developer.paypal.com. На странице «My apps & credentials» переключатель должен быть установлен на Sandbox(1), нажимаем на Creat App(2). Для работы с реальными деньгами переключатель должен быть становлен в Live
Затем на новой странице даем имя приложению, оставляем переключатель на Merchant, что дает нам возможность принимать баблишко. Выбираем бизнес аккаунт, на который они и будут сваливаться. Нажимаем Creat App и после этого создается приложение.
Из настроек забираем CLIENT ID и CLIENT SECRET.
И на этом на стороне Paypal заканчиваем телодвижения.
Глава 2. Устанавливаем пакет Omnipay
Возвращаемся в Laravel. В консоли вводим
composer require league/omnipay omnipay/paypal |
и ждем пока установится пакет и ворох зависимых пакетиков.
Глава 3. Наливаем чай с мёдом, чтобы поддержать мозги глюкозой и сахарозой
Здесь, наверное, самый важный момент в статье. Мёд нельзя добавлять в кипяток, чтобы избежать превращение его в казеиновую структуру. Только вприкуску. Пользу гарантирую.
Глава 4. Создаем модель и миграцию таблицы для работы с платежами
Чтобы работать с проведенными через сайт платежами, нужно создать модель и соответствующую таблицу. Тоже всё предсказуемо. Создаем их (миграцию и модель) одной командой.
php artisan make:model -m Payment |
В миграции должна быть такая картина
... ... public function up() { Schema::create('payments', function (Blueprint $table) { $table->bigIncrements('id'); $table->string('payment_id'); $table->string('payer_id'); $table->string('payer_email'); $table->float('amount', 10, 2); $table->string('currency'); $table->string('payment_status'); $table->timestamps(); }); } |
Затем миграцию превращаем в таблицу
php artisan migrate |
Далее у нас должны быть такие руты в файле routes/web.php
... ... Route::get('/payment', 'PaymentController@index'); Route::post('/charge', 'PaymentController@charge'); Route::get('/paymentsuccess', 'PaymentController@payment_success'); Route::get('/paymenterror', 'PaymentController@payment_error'); //для тестового платежа Route::get('/test', function () { return view('general.test'); }); // в папке resources/views/ должна быть папка general и в ней файл test.blade.php ... ... |
Ну и затем создаем контроллер
php artisan make:controller PaymentController |
и вносим в него код
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use Omnipay\Omnipay; use App\Payment; class PaymentController extends Controller { public $gateway; //создание объекта с настройками приложения public function __construct() { $this->gateway = Omnipay::create('PayPal_Rest'); $this->gateway->setClientId('AS6FH33GXitGrVxV-nfM3SQTStY27yD9e5KLcoXRjqBlARsGiuXU1vA7nLNJxksCV39SFJeblXnKWgRz'); $this->gateway->setSecret('EL-PjamJVm3VUWG2nsI42Lwwh3wt-Y9OEuZ400D3PC9SPD1dCh6gS79spWYQDwLAhtA_FhwOPSxG6Vl9'); $this->gateway->setTestMode(true); // для реальных платежей нужно будет ставить false } public function index() { return view('payment'); } //отправляем платеж в Paypal public function charge(Request $request) { if($request->input('submit')) { try { $response = $this->gateway->purchase(array( 'amount' => $request->input('amount'), 'currency' => 'EUR', //если доллары то пишем здесь USD 'returnUrl' => url('paymentsuccess'), // если платеж прошел удачно 'cancelUrl' => url('paymenterror'), // если ошибка, то перейдет на этот рут ))->send(); if ($response->isRedirect()) { $response->redirect(); // this will automatically forward the customer } else { // not successful return $response->getMessage(); } } catch(Exception $e) { return $e->getMessage(); } } } // если платеж прошел удачно public function payment_success(Request $request) { // Once the transaction has been approved, we need to complete it. if ($request->input('paymentId') && $request->input('PayerID')) { $transaction = $this->gateway->completePurchase(array( 'payer_id' => $request->input('PayerID'), 'transactionReference' => $request->input('paymentId'), )); $response = $transaction->send(); if ($response->isSuccessful()) { // The customer has successfully paid. $arr_body = $response->getData(); // Insert transaction data into the database $isPaymentExist = Payment::where('payment_id', $arr_body['id'])->first(); if(!$isPaymentExist) { $payment = new Payment; $payment->payment_id = $arr_body['id']; $payment->payer_id = $arr_body['payer']['payer_info']['payer_id']; $payment->payer_email = $arr_body['payer']['payer_info']['email']; $payment->amount = $arr_body['transactions'][0]['amount']['total']; $payment->currency = 'EUR'; //если доллары то пишем здесь USD $payment->payment_status = $arr_body['state']; $payment->save(); } return "Payment is successful. Your transaction id is: ". $arr_body['id']; } else { return $response->getMessage(); } } else { return 'Transaction is declined'; } } // если ошибка public function payment_error() { return 'User is canceled the payment.'; } } |
Для тестового платежа создаем рут (адрес) /test и для него заготавливаем view с именем test.blade.php в котором должна быть такая форма
<form action="/charge" method="post"> <input type="text" name="amount" /> {{ csrf_field() }} <input type="submit" name="submit" value="Pay Now"> </form> |
В тесте набираем число в input жмем кнопку. Ну вот и всё