Уроки курса
Интеграция платежной системы Vipps
Настройка альтернативного способа оплаты через API Vipps для расширения возможностей магазина. Изучение работы с вебхуками.
Альтернативные методы оплаты: Vipps
В современной электронной коммерции важно предоставлять клиентам выбор. В Скандинавских странах доминирует система Vipps (мобильный кошелек). В отличие от Stripe Checkout, где мы используем готовую страницу, интеграция с Vipps часто требует более глубокой работы с REST API.
В этом уроке мы применим Project-Based Learning, добавив второй способ оплаты в наш магазин. Процесс состоит из двух этапов: инициация платежа (создание Payment Intent) и обработка асинхронного ответа через Вебхуки (Webhooks).
Что такое Webhook?
Когда пользователь подтверждает платеж в приложении Vipps на своем телефоне, наш сервер об этом не знает. Пользователь может закрыть браузер, не дождавшись редиректа на страницу успеха. Как нашему серверу узнать, что заказ оплачен?
Для этого используются вебхуки. Webhook — это маршрут в вашем приложении (например, POST /webhooks/vipps), на который сервер Vipps самостоятельно отправляет HTTP-запрос с информацией: "Заказ №123 успешно оплачен". Это гарантирует, что статус заказа обновится в базе данных независимо от действий пользователя в браузере.
// routes/web.php
// ОЧЕНЬ ВАЖНО: Маршруты для вебхуков должны быть исключены из проверки CSRF!
Route::post('/webhooks/vipps', [VippsWebhookController::class, 'handle']);
// app/Http/Middleware/VerifyCsrfToken.php
class VerifyCsrfToken extends Middleware {
protected $except = [
'webhooks/vipps', // Исключаем маршрут из проверки CSRF
'webhooks/stripe',
];
}
Типичная ошибка новичков (CSRF Token Mismatch)
По умолчанию Laravel защищает все POST-маршруты с помощью CSRF-токена. Это защищает от межсайтовой подделки запросов. Однако сторонние серверы (Vipps, Stripe) ничего не знают о вашем CSRF-токене и не могут его передать. Если не добавить URL вебхука в массив $except в middleware VerifyCsrfToken, Laravel отклонит запрос от платежной системы с ошибкой 419, и статус заказа никогда не обновится!
namespace App\Http\Controllers;
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');
if ($status === 'RESERVE') {
$order = Order::where('id', $orderId)->first();
if ($order) {
$order->update(['status' => 'paid']);
}
}
// Обязательно возвращаем 200 OK, иначе Vipps будет повторять запрос
return response()->json(['status' => 'success'], 200);
}
}