Интеграция платёжной системы PayPal на сайт

Наша компания занимается разработкой, поддержкой и обслуживанием сайтов любой сложности. От простых одностраничных сайтов до масштабных кластерных систем построенных на микро сервисах. Опыт разработчиков подтвержден сертификатами от вендоров.
Разработка и обслуживание любых видов сайтов:
Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Предлагаемые услуги
Показано 1 из 1 услугВсе 2065 услуг
Интеграция платёжной системы PayPal на сайт
Средняя
от 1 рабочего дня до 3 рабочих дней
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1214
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1161
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    852
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1041
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    823
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    815

Интеграция платёжной системы PayPal на сайт

PayPal — крупнейшая в мире платёжная система с более чем 430 млн активных аккаунтов. Для международной торговли, особенно в направлении США и Западной Европы, кнопка PayPal на сайте — базовое требование. Поддерживает оплату балансом PayPal, банковскими картами (через аккаунт или без), а также кредитование через PayPal Credit.

SDK и режимы интеграции

PayPal предлагает JavaScript SDK, который загружает кнопки оплаты и управляет всем флоу. Серверная часть нужна для создания ордера, его захвата и обработки уведомлений.

<script src="https://www.paypal.com/sdk/js?client-id=YOUR_CLIENT_ID&currency=USD"></script>

Или через npm в React/Vue проектах:

npm install @paypal/react-paypal-js

React-интеграция через PayPalScriptProvider

import { PayPalScriptProvider, PayPalButtons } from '@paypal/react-paypal-js';

export function PayPalCheckout({ orderId }: { orderId: number }) {
  return (
    <PayPalScriptProvider options={{
      clientId: import.meta.env.VITE_PAYPAL_CLIENT_ID,
      currency:  'USD',
    }}>
      <PayPalButtons
        style={{ layout: 'vertical', color: 'gold', shape: 'rect' }}
        createOrder={async () => {
          // Создаём ордер на сервере, возвращаем PayPal order ID
          const res = await fetch('/api/paypal/create-order', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ orderId }),
          });
          const data = await res.json();
          return data.paypalOrderId;
        }}
        onApprove={async (data) => {
          // После подтверждения пользователем — захватываем платёж
          const res = await fetch('/api/paypal/capture-order', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ paypalOrderId: data.orderID }),
          });
          const capture = await res.json();
          if (capture.status === 'COMPLETED') {
            window.location.href = '/payment/success';
          }
        }}
        onError={(err) => {
          console.error('PayPal error', err);
        }}
      />
    </PayPalScriptProvider>
  );
}

Серверная часть — создание и захват ордера

use GuzzleHttp\Client;

class PayPalService
{
    private string $baseUrl;
    private string $accessToken;

    public function __construct()
    {
        $this->baseUrl = env('PAYPAL_MODE') === 'live'
            ? 'https://api-m.paypal.com'
            : 'https://api-m.sandbox.paypal.com';

        $this->accessToken = $this->getAccessToken();
    }

    private function getAccessToken(): string
    {
        $response = Http::withBasicAuth(env('PAYPAL_CLIENT_ID'), env('PAYPAL_SECRET'))
            ->asForm()
            ->post("{$this->baseUrl}/v1/oauth2/token", ['grant_type' => 'client_credentials']);

        return $response->json('access_token');
    }

    public function createOrder(Order $order): string
    {
        $response = Http::withToken($this->accessToken)
            ->post("{$this->baseUrl}/v2/checkout/orders", [
                'intent'         => 'CAPTURE',
                'purchase_units' => [[
                    'reference_id' => (string) $order->id,
                    'amount'       => [
                        'currency_code' => 'USD',
                        'value'         => number_format($order->total_usd, 2, '.', ''),
                    ],
                    'description'  => "Order #{$order->id}",
                ]],
            ]);

        return $response->json('id'); // PayPal Order ID
    }

    public function captureOrder(string $paypalOrderId): array
    {
        $response = Http::withToken($this->accessToken)
            ->post("{$this->baseUrl}/v2/checkout/orders/{$paypalOrderId}/capture");

        return $response->json();
    }
}
// Контроллер
public function createOrder(Request $request): JsonResponse
{
    $order = Order::findOrFail($request->input('orderId'));
    $paypalOrderId = app(PayPalService::class)->createOrder($order);

    $order->update(['paypal_order_id' => $paypalOrderId]);
    return response()->json(['paypalOrderId' => $paypalOrderId]);
}

public function captureOrder(Request $request): JsonResponse
{
    $paypalOrderId = $request->input('paypalOrderId');
    $result = app(PayPalService::class)->captureOrder($paypalOrderId);

    if ($result['status'] === 'COMPLETED') {
        $captureId = $result['purchase_units'][0]['payments']['captures'][0]['id'];
        Order::where('paypal_order_id', $paypalOrderId)->update([
            'status'     => 'paid',
            'capture_id' => $captureId,
        ]);
    }

    return response()->json(['status' => $result['status']]);
}

Webhook — асинхронные уведомления

PayPal отправляет события через Webhooks. Подписки настраиваются в Developer Dashboard:

public function webhook(Request $request): Response
{
    // Верификация подписи через PayPal API
    $verified = Http::withToken($this->accessToken)
        ->post("{$this->baseUrl}/v1/notifications/verify-webhook-signature", [
            'auth_algo'         => $request->header('PAYPAL-AUTH-ALGO'),
            'cert_url'          => $request->header('PAYPAL-CERT-URL'),
            'transmission_id'   => $request->header('PAYPAL-TRANSMISSION-ID'),
            'transmission_sig'  => $request->header('PAYPAL-TRANSMISSION-SIG'),
            'transmission_time' => $request->header('PAYPAL-TRANSMISSION-TIME'),
            'webhook_id'        => env('PAYPAL_WEBHOOK_ID'),
            'webhook_event'     => $request->json()->all(),
        ])->json('verification_status') === 'SUCCESS';

    if (!$verified) return response('Forbidden', 403);

    $eventType = $request->json('event_type');
    // PAYMENT.CAPTURE.COMPLETED, PAYMENT.CAPTURE.REFUNDED, etc.

    return response('OK', 200);
}

Возвраты

Http::withToken($this->accessToken)
    ->post("{$this->baseUrl}/v2/payments/captures/{$captureId}/refund", [
        'amount' => [
            'value'         => '7.50',
            'currency_code' => 'USD',
        ],
        'note_to_payer' => 'Refund for order #12345',
    ]);

Тестирование

В Sandbox создаются тестовые аккаунты покупателей и продавцов. Sandbox URL: https://api-m.sandbox.paypal.com. Переключение на боевой режим — замена Client ID/Secret и URL. Время активации боевого аккаунта — мгновенно после верификации личных данных владельца.