Уроки курса
1 Основы синтаксиса PHP 8
60 мин
2 Функции и управляющие конструкции
60 мин
3 Объектно-ориентированное программирование на PHP
60 мин
4 Наследование, интерфейсы и полиморфизм
60 мин
5 Основы баз данных MySQL и работа через PDO
60 мин
6 Архитектурный паттерн MVC
60 мин
7 Введение в Laravel и настройка окружения
60 мин
8 Маршрутизация и контроллеры в Laravel
60 мин
9 Шаблонизатор Blade и создание интерфейса
60 мин
10 Миграции баз данных и Eloquent ORM
60 мин
11 Связи моделей в Eloquent — Настройка связей 'один …
60 мин
12 Аутентификация и защита маршрутов
60 мин
13 Разработка каталога товаров и категорий
60 мин
14 Реализация корзины покупок через сессии
60 мин
15 Оформление заказа и транзакции базы данных
60 мин
16 Интеграция платежной системы Stripe
60 мин
17 Интеграция платежной системы Vipps
60 мин
18 Разработка панели администратора
60 мин
19 Оптимизация и подготовка к production
60 мин
20 Деплой Laravel-приложения на сервер
60 мин
21 Основы PHP 8: Синтаксис, переменные и управляющие конструкции
60 мин
22 Функции и массивы в PHP 8
60 мин
23 Объектно-ориентированное программирование: Классы и объекты
60 мин
24 Продвинутое ООП: Наследование, интерфейсы и полиморфизм
60 мин
25 Основы баз данных: Проектирование БД и работа с …
60 мин
26 Взаимодействие PHP с MySQL через PDO
60 мин
27 Архитектура MVC и введение в фреймворк Laravel
60 мин
28 Маршрутизация и контроллеры в Laravel
60 мин
29 Шаблонизатор Blade: Создание пользовательского интерфейса
60 мин
30 Миграции и Eloquent ORM: Создание таблиц товаров
60 мин
31 Связи в Eloquent ORM: Отношения между моделями
60 мин
32 Аутентификация и авторизация пользователей
60 мин
33 Разработка каталога товаров: Вывод, фильтрация и пагинация
60 мин
34 Реализация корзины покупок с использованием сессий
60 мин
35 Оформление заказа: Работа с формами и валидация
60 мин
36 Транзакции базы данных: Сохранение заказа
60 мин
37 Интеграция платежной системы Stripe
60 мин
38 Интеграция платежной системы Vipps
60 мин
39 Создание панели администратора
60 мин
40 Подготовка к production и деплой приложения
60 мин
41 Основы PHP 8 и синтаксис
60 мин
42 Объектно-ориентированное программирование на PHP
60 мин
43 Продвинутое ООП и интерфейсы
60 мин
44 Основы баз данных и MySQL
60 мин
45 Архитектурный паттерн MVC
60 мин
46 Введение в Laravel и маршрутизация
60 мин
47 Шаблонизатор Blade и верстка интерфейса
60 мин
48 Миграции и структура базы данных
60 мин
49 Eloquent ORM и модели
60 мин
50 Отношения в Eloquent ORM
60 мин
51 Авторизация и защита маршрутов
60 мин
52 Создание каталога товаров
60 мин
53 Реализация корзины покупок
60 мин
54 Оформление заказа и транзакции БД
60 мин
55 Интеграция платежной системы Stripe
60 мин
56 Интеграция платежной системы Vipps
60 мин
57 Панель администратора: управление товарами
60 мин
58 Панель администратора: управление заказами
60 мин
59 Подготовка к production и деплой
60 мин
60 Запуск и тестирование готового интернет-магазина
60 мин

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

Студент добавит альтернативный способ оплаты через популярную систему Vipps, работая с внешними API, и изучит концепцию вебхуков.

Прогресс урока: 0%

Введение в интеграцию альтернативных платежных систем

На прошлом уроке мы успешно интегрировали Stripe. Однако современные интернет-магазины часто требуют подключения локальных или специфических платежных решений, таких как Vipps (популярная система в скандинавских странах). Интеграция нескольких платежных шлюзов требует правильной архитектуры. Мы будем использовать принцип проектирования, основанный на интерфейсах (Direct Instruction). Это позволит нашему приложению легко переключаться между Stripe и Vipps без переписывания основной логики оформления заказа. В этом уроке мы изучим работу с REST API внешних сервисов, аутентификацию по API-ключам и обработку асинхронных ответов через вебхуки (Webhooks).

Вебхук — это механизм получения уведомлений от сторонних сервисов в реальном времени. Когда пользователь оплачивает заказ в приложении Vipps на своем телефоне, сервер Vipps отправляет HTTP POST запрос на специальный URL (вебхук) нашего магазина, сообщая, что статус платежа изменился. Это критически важно, так как пользователь может закрыть браузер до перенаправления на страницу успешной оплаты, и вебхук гарантирует, что мы зафиксируем оплату.

php
<?php

namespace App\Services\Payment;

// Определяем единый контракт для всех платежных систем
interface PaymentGateway {
    public function pay(float $amount, string $orderId): bool;
}

class VippsGateway implements PaymentGateway {
    private string $clientId;
    private string $clientSecret;
    private string $merchantSerialNumber;

    public function __construct() {
        $this->clientId = env('VIPPS_CLIENT_ID');
        $this->clientSecret = env('VIPPS_CLIENT_SECRET');
        $this->merchantSerialNumber = env('VIPPS_MERCHANT_SERIAL_NUMBER');
    }

    public function pay(float $amount, string $orderId): bool {
        // Логика формирования запроса к REST API Vipps
        // 1. Получение Access Token
        // 2. Инициация платежа (Payment Intent)
        // В рамках данного примера возвращаем true для симуляции
        return true;
    }
}

Архитектура взаимодействия с API

Разберем процесс шаг за шагом (Scaffolding). Интеграция с API Vipps состоит из нескольких этапов. Во-первых, аутентификация. Большинство банковских API используют стандарт OAuth 2.0. Наше приложение должно отправить `client_id` и `client_secret` на сервер авторизации Vipps, чтобы получить временный токен доступа (Access Token). Во-вторых, инициация платежа. Мы отправляем POST-запрос с деталями заказа (сумма, валюта, номер телефона пользователя, если известен) и получаем взамен URL, на который нужно перенаправить пользователя для подтверждения оплаты.

Типичная ошибка новичков — хранение ключей API прямо в коде. Как вы можете видеть в примере выше, мы используем функцию `env()`, которая читает конфигурацию из файла `.env`. Это гарантирует, что секретные ключи не попадут в систему контроля версий Git и не будут скомпрометированы.

Задание

Настройка локального тестирования вебхуков

  • Зарегистрируйте аккаунт разработчика на портале Vipps (или используйте тестовые ключи).
  • Добавьте ключи VIPPS_CLIENT_ID и VIPPS_CLIENT_SECRET в ваш файл .env.
  • Скачайте и установите утилиту Ngrok для проброса локального порта в интернет.
  • Запустите команду 'ngrok http 8000' в терминале.
  • Скопируйте сгенерированный HTTPS URL и укажите его в настройках вебхуков в панели Vipps (например, https://your-ngrok-url.com/api/webhooks/vipps).
10 баллов
php
<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\Order;
use Illuminate\Support\Facades\Log;

class VippsWebhookController extends Controller {
    public function handle(Request $request) {
        // Логируем входящий запрос для отладки
        Log::info('Vipps Webhook Received', $request->all());

        $orderId = $request->input('orderId');
        $status = $request->input('transactionInfo.status');

        $order = Order::find($orderId);
        if (!$order) {
            return response()->json(['error' => 'Order not found'], 404);
        }

        if ($status === 'RESERVED' || $status === 'SALE') {
            $order->status = 'paid';
            $order->save();
        }

        // Обязательно возвращаем 200 OK, чтобы Vipps понял, что мы приняли вебхук
        return response()->json(['status' => 'success'], 200);
    }
}

Обработка вебхуков и безопасность

В коде выше представлен контроллер для обработки вебхуков. Важно понимать, что маршрут для этого контроллера должен находиться в файле `routes/api.php`, а не `web.php`. Маршруты в `web.php` по умолчанию защищены middleware `VerifyCsrfToken`, который блокирует POST-запросы без специального скрытого токена. Сторонний сервер (Vipps) не знает ваш CSRF-токен, поэтому запрос будет отклонен с ошибкой 419. Размещение маршрута в `api.php` отключает проверку CSRF.

Для обеспечения безопасности (Mastery Learning) мы должны проверять подпись запроса. Vipps присылает специальные заголовки (headers), которые мы должны расшифровать с помощью нашего секретного ключа, чтобы убедиться, что запрос действительно пришел от Vipps, а не от злоумышленника, пытающегося подделать статус заказа на 'paid'.

Как называется механизм получения асинхронных HTTP-уведомлений от сторонних сервисов (например, о статусе платежа)?

Почему маршрут для приема уведомлений от платежной системы следует размещать в routes/api.php, а не routes/web.php?