Hướng dẫn tích hợp VNPAY trong Laravel với tài khoản Sandbox

Hướng dẫn chi tiết cách tích hợp VNPAY vào dự án Laravel sử dụng tài khoản Sandbox của VNPAY để thực hiện các giao dịch thanh toán trực tuyến, bao gồm việc cấu hình, tạo URL thanh toán, xử lý kết quả trả về, và xây dựng giao diện.

Bài viết sẽ hướng dẫn tích hợp cổng thanh toán VNPAY vào dự án Laravel bằng tài khoản Sandbox. Từ đó, bạn có thể thực hiện các giao dịch thử nghiệm và kiểm thử tính năng thanh toán trực tuyến trước khi triển khai tài khoản thật.

Mã Laravel:

Cấu hình VNPAY trong Laravel:

  1. Thêm các cấu hình sau trong file .env:
VNP_TMN_CODE= // Mã website tại VNPAY
VNP_HASH_SECRET= // Chuỗi bí mật từ VNPAY
VNP_URL=https://sandbox.vnpayment.vn/paymentv2/vpcpay.html // Địa chỉ cổng thanh toán
VNP_RETURN_URL= // URL nhận kết quả thanh toán sau khi giao dịch hoàn tất
  1. Tạo file cấu hình config/vnpay.php:
return [
    'vnp_TmnCode' => env('VNP_TMN_CODE'),
    'vnp_HashSecret' => env('VNP_HASH_SECRET'),
    'vnp_Url' => env('VNP_URL'),
    'vnp_Returnurl' => env('VNP_RETURN_URL'),
];
  1. Tạo Route và Controller cho thanh toán và xử lý callback:
  • Route:
use App\Http\Controllers\Payment\VnPayController;

Route::get('/payment', [VnPayController::class, 'createPayment'])->name('payment.create');
Route::get('/vnpay-return', [VnPayController::class, 'vnpayReturn'])->name('vnpay.return');
  • Controller:
namespace App\Http\Controllers\Payment;

use Illuminate\Http\Request;

class VnPayController extends Controller
{
    public function createPayment(Request $request){
        $vnp_TmnCode = config('vnpay.vnp_TmnCode');
        $vnp_HashSecret = config('vnpay.vnp_HashSecret');
        $vnp_Url = config('vnpay.vnp_Url');
        $vnp_ReturnUrl = config('vnpay.vnp_Returnurl');
        
        // Lấy thông tin từ đơn hàng phục vụ thanh toán
        // Dưới đây là thông tin giả định, bạn có thể lấy thông tin đơn hàng của bạn để thay thế
        $order = (object)[
            "code" => 'ORDER' . rand(100000, 999999),
            "total" => 100000,
            "bankCode" => 'NCB',
            "type" => "billpayment",
            "info" => "Thanh toán đơn hàng"
        ];

        $vnp_TxnRef = $order->code;
        $vnp_OrderInfo = $order->info;
        $vnp_OrderType =  $order->type;
        $vnp_Amount = $order->total * 100;
        $vnp_Locale = 'vn';
        $vnp_BankCode = $order->bankCode;
        $vnp_IpAddr = $request->ip();

        $inputData = array(
            "vnp_Version" => "2.1.0",
            "vnp_TmnCode" => $vnp_TmnCode,
            "vnp_Amount" => $vnp_Amount,
            "vnp_Command" => "pay",
            "vnp_CreateDate" => date('YmdHis'),
            "vnp_CurrCode" => "VND",
            "vnp_IpAddr" => $vnp_IpAddr,
            "vnp_Locale" => $vnp_Locale,
            "vnp_OrderInfo" => $vnp_OrderInfo,
            "vnp_OrderType" => $vnp_OrderType,
            "vnp_ReturnUrl" => $vnp_ReturnUrl,
            "vnp_TxnRef" => $vnp_TxnRef,
        );

        if (isset($vnp_BankCode) && $vnp_BankCode != "") {
            $inputData['vnp_BankCode'] = $vnp_BankCode;
        }

        ksort($inputData);

        $hashdata = "";
        $query = "";
        $i = 0;
        foreach ($inputData as $key => $value) {
            if ($i == 1) {
                $hashdata .= '&' . urlencode($key) . "=" . urlencode($value);
            } else {
                $hashdata .= urlencode($key) . "=" . urlencode($value);
                $i = 1;
            }
            $query .= urlencode($key) . "=" . urlencode($value) . '&';
        }

        $vnp_Url = $vnp_Url . "?" . $query;

        if (isset($vnp_HashSecret)) {
            $vnpSecureHash = hash_hmac('sha512', $hashdata, $vnp_HashSecret);
            $vnp_Url .= 'vnp_SecureHash=' . $vnpSecureHash;
        }

        return redirect($vnp_Url);
    }

    public function vnpayReturn(Request $request){
        $vnp_SecureHash = $request->vnp_SecureHash;
        $inputData = $request->all();

        unset($inputData['vnp_SecureHash']);
        ksort($inputData);
        $hashData = "";
        foreach ($inputData as $key => $value) {
            $hashData .= urlencode($key) . "=" . urlencode($value) . '&';
        }
        $hashData = rtrim($hashData, '&');

        $secureHash = hash_hmac('sha512', $hashData, config('vnpay.vnp_HashSecret'));

        if ($secureHash === $vnp_SecureHash) {
            if ($request->vnp_ResponseCode == '00') {
                return view('payment_success', compact('inputData'));
            } else {
                return view('payment_failed');
            }
        } else {
            return view('payment_failed');
        }
    }
}

Giao diện thanh toán và kết quả giao dịch:

  • Nút thanh toán với VNPAY:
<a href="{{ route('payment.create') }}" class="btn btn-primary">Thanh toán qua VNPay</a>
  • Giao diện payment_success.blade.php:
<h1>Thanh toán thành công!</h1>
<p>Mã giao dịch: {{ $inputData['vnp_TxnRef'] }}</p>
<p>Số tiền: {{ number_format($inputData['vnp_Amount'] / 100) }} VND</p>
  • Giao diện payment_failed.blade.php:
<h1>Thanh toán thất bại!</h1>
<p>Vui lòng thử lại.</p>

Giải thích chi tiết từng dòng code:

  1. Cấu hình trong .env: Thiết lập các thông số cần thiết cho VNPAY bao gồm mã website, chuỗi bí mật và URL cổng thanh toán.
  2. Tạo file cấu hình vnpay.php: Để dễ quản lý các thông tin cấu hình từ .env trong Laravel.
  3. Route và Controller: Tạo các route cho việc khởi tạo thanh toán và xử lý kết quả trả về từ VNPAY. Trong controller, createPayment tạo URL thanh toán và vnpayReturn xử lý kết quả trả về.
  4. Nút thanh toán và giao diện: Cung cấp giao diện người dùng với nút thanh toán và hiển thị kết quả thành công hoặc thất bại sau khi giao dịch hoàn tất.

Yêu cầu hệ thống:

  • Laravel 8.x trở lên.
  • Tài khoản VNPAY Sandbox để kiểm thử trước khi chuyển sang tài khoản thật.

Lời khuyên:

  • Kiểm thử kỹ lưỡng trên môi trường Sandbox trước khi triển khai cổng thanh toán VNPAY lên môi trường thật.
  • Cần lưu ý bảo mật các thông tin nhạy cảm như vnp_HashSecret.
  • Xem tài liệu API của VNPAY tại đây: https://sandbox.vnpayment.vn/apis/
Tags: PHP, Laravel, VNPAY


Các Hướng Dẫn Cùng Chủ Đề Đang Xem

Liệt kê các cách sử dụng hàm where lồng nhau trong Laravel

Bài viết tổng hợp các cách sử dụng hàm `where` lồng nhau trong Laravel, giúp người đọc hiểu rõ cách xây dựng các truy vấn phức tạp trong ứng dụng.
Tạo mã Captcha trong Laravel

Hướng dẫn chi tiết cách tạo mã Captcha trong Laravel để bảo vệ form khỏi spam và xác thực người dùng. Bài viết sẽ giúp bạn tích hợp Captcha vào dự án Laravel một cách dễ dàng.
Các cách SELECT dữ liệu từ database MySQL trong Laravel

Khám phá các phương pháp khác nhau để select dữ liệu từ database MySQL trong Laravel, bao gồm sử dụng Eloquent ORM và Query Builder.
Hướng dẫn force HTTPS trong Laravel

Hướng dẫn chi tiết cách thiết lập force HTTPS trong Laravel để đảm bảo rằng tất cả các yêu cầu tới ứng dụng đều được chuyển hướng sang HTTPS, giúp tăng cường bảo mật cho trang web của bạn.
Tất cả cách UPDATE dữ liệu từ database MySQL trong Laravel

Hướng dẫn chi tiết cách cập nhật dữ liệu trong database MySQL sử dụng Laravel, bao gồm cách sử dụng Eloquent ORM và Query Builder.
Cách chuyển đổi chuỗi Markdown sang HTML bằng Laravel

Hướng dẫn cách chuyển đổi chuỗi Markdown sang HTML trong Laravel bằng cách sử dụng thư viện `league/commonmark`, giúp quá trình chuyển đổi trở nên dễ dàng và hiệu quả.
Cách POST dữ liệu tới API trong Laravel

Hướng dẫn cách sử dụng Laravel để gửi yêu cầu POST dữ liệu tới API bên ngoài hoặc API nội bộ. Sử dụng phương thức HTTP Client tích hợp trong Laravel để gửi dữ liệu một cách dễ dàng và bảo mật.
Hướng dẫn làm chức năng đăng nhập bằng Apple ID trong Laravel

Bài viết hướng dẫn chi tiết cách tích hợp chức năng đăng nhập bằng Apple ID vào Laravel, sử dụng OAuth2. Bạn sẽ học cách cấu hình ứng dụng để kết nối với dịch vụ Apple và xử lý thông tin đăng nhập của người dùng.
Các cách DELETE dữ liệu từ database MySQL trong Laravel

Hướng dẫn chi tiết về các phương pháp khác nhau để xóa dữ liệu từ database MySQL trong Laravel, bao gồm Eloquent, Query Builder, và cách thực hiện soft delete.
Các cách INSERT dữ liệu vào database MySQL trong Laravel

Khám phá các phương pháp khác nhau để insert dữ liệu vào database MySQL trong Laravel, bao gồm sử dụng Eloquent ORM và Query Builder.

Đã thêm vào giỏ hàng