Chuyên mục Tích hợp Api

Cách tích hợp cổng thanh toán VNPAY với PHP thuần trong vòng một nốt nhạc

Đăng bởi: Minacode|Cập nhật:12-12-2023

Ok 500 anh em thiện lành, bài này mình sẽ hướng dẫn anh em tích hợp thanh toán ví điện tử VNPAY vào code Php thuần nhé! Quá ngon lành cành đào luôn. Let ‘s Go thôi.

Bài toán đặt ra là thế này: 

Mình có một bức ảnh trị giá 50 triệu đô, bây giờ người nào muốn xem thì phải thanh toán cho mình số tiền 50 cành để được xem.

Bức ảnh đây:

Ok, bây giờ người ta bảo nằm ngủ cũng có tiền là có thật anh em ạ, vậy thực hư thế nào thì tiếp tục nhé!

Bức ảnh này mình đã ẩn và nó không có hiện trên website đâu. Khi vào website của mình khách hàng chỉ thấy như sau:

Nếu khách hàng muốn xem và click vào nút thanh toán. Màn hình sẽ chuyển sang giao diện thanh toán dưới đây.

Màn hình này thì quá quen thuộc đối với anh em nào thường xuyên thanh toán online bằng ví điện tử vnpay rồi đúng không.

Trường hợp này mình sẽ chọn phương thức thanh toán là Thẻ nội địa và tài khoản ngân hàng

 

Mình sẽ chọn ngân hàng NCB và dùng thông tin tài khoản test như sau:

Ngân hàng: NCB
Số thẻ: 9704198526191432198
Tên chủ thẻ:NGUYEN VAN A
Ngày phát hành:07/15
Mật khẩu OTP:123456

Sau khi các bạn thanh toán thành công thì màn hình sẽ tự động chuyển qua trang có hiện thị hình ảnh.

Đấy! vậy là bạn nằm ngủ còn tiền cứ tự động ting ting thôi. Đây mới gọi là nằm ngủ cũng có tiền thiệt nè. Chứ đừng nghe mấy mô hình lừa đảo trên mạng nhé. Hehe

Ok, Bây giờ đến khúc quan trọng nhất là code nhé!

Đầu tiên là phía giao diện, trong file index.php mình sẽ code như sau:

<?php 
include "PaymenVnpayClass.php";
$payment = new payment;
?>

<?php

if ($_SERVER["REQUEST_METHOD"] == "POST") {
$order_id = $_POST['order_id'];
$order_price = $_POST['order_price'];
$payment-> vnpay_payment($order_id,$order_price);
}
?>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Payment-Vnpay</title>
</head>

<style>
    body {
        width: 100vw;
        height: 100vh;
        display: flex;
        align-items: center;
        justify-content: center;
    }
    button {
        text-decoration: none;
        display: inline-block;
        padding: 10px 12px;
        background-color:cadetblue;
        color: whitesmoke;
        border: none;
        cursor: pointer;
    }
</style>
<body>
    <form action="" method="post">
        <img src="noimage.jpeg" style="width: 500px" alt="">
        <input type="hidden" name="order_id" value="<?php echo time() ?>"> <br>
        <input type="hidden" name="order_price" value="50000"> <br>
        <p style="color:red">Bạn cần thành toán 50.000<sup>đ</sup> để nhìn thấy em nó</p>
        <button name="redirect" type="submit">Thanh toán</button>
    </form>
    
</body>
</html>

 

Và tạo một class có tên là PaymenVnpayClass.php

Và thêm đoạn code sau:

<?php
error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED);
date_default_timezone_set('Asia/Ho_Chi_Minh');

class payment 
{
    function vnpay_payment ($order_id,$order_price){
        $vnp_Url = "https://sandbox.vnpayment.vn/paymentv2/vpcpay.html";
        $vnp_Returnurl =  "http://localhost:82/PHP/vnpay/test/success.php";
        $vnp_TmnCode = "262XSFHX";//Mã website tại VNPAY 
        $vnp_HashSecret = "MMZXWISZNUUUNKGOZQPCPASLLTHYGMTB"; //Chuỗi bí mật
        $vnp_TxnRef = $order_id; //Mã đơn hàng. Trong thực tế Merchant cần insert đơn hàng vào DB và gửi mã này sang VNPAY
        $vnp_OrderInfo = $order_id;
        $vnp_OrderType = '250000';
        $vnp_Amount = $order_price * 100;
        $vnp_Locale = 'vn';
        $vnp_BankCode = '';
        $vnp_IpAddr = $_SERVER['REMOTE_ADDR'];
        $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;
        }
        if (isset($vnp_Bill_State) && $vnp_Bill_State != "") {
            $inputData['vnp_Bill_State'] = $vnp_Bill_State;
        }
    
        ksort($inputData);
        $query = "";
        $i = 0;
        $hashdata = "";
        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;
        }
        $returnData = array('code' => '00'
            , 'message' => 'success'
            , 'data' => $vnp_Url);
            if (isset($_POST['redirect'])) {
                header('Location: ' . $vnp_Url);
                die();
            } else {
                echo json_encode($returnData);
            }
    }
}

Đồng thời mình sẽ tạo thêm 1 file success.php để điều hướng và thêm đoạn code sau:

<?php 
if ($_SERVER["REQUEST_METHOD"] == "GET")
{
    if ($_GET['vnp_ResponseCode'] == '00') 
    {
        header('Location: ' . 'http://localhost:82/PHP/vnpay/test/success_result.php');
    }
    else {
        echo ('Mẩu khẩu là: còn lâu mới nói');
    }
    exit();
}

?>

Và tất nhiên tiếp theo là trang quan trọng nhất, là trang đích xuất hiện sau khi mà khách hàng đã thanh toán thành công cho chúng ta. Mình sẽ tạo một file có tên là success_result.php để chứa bức ảnh 50 triệu đô của chúng ta và code ở trong đó như sau:

!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Payment-Vnpay</title>
</head>

<style>
    body {
        width: 100vw;
        height: 100vh;
        display: flex;
        align-items: center;
        justify-content: center;
    }
    button {
        text-decoration: none;
        display: inline-block;
        padding: 10px 12px;
        background-color:cadetblue;
        color: whitesmoke;
        border: none;
        cursor: pointer;
    }
    a {
        text-decoration: none;
        display: inline-block;
        padding: 10px 12px;
        background-color:cadetblue;
        color: whitesmoke;
        border: none;
        cursor: pointer;
    }
</style>
<body>
    <form action="" method="post">
        <img src="yesimage.jpg" style="width: 500px" alt="">
        <input type="hidden" name="order_id" value="<?php echo time() ?>"> <br>
        <input type="hidden" name="order_price" value="50000"> <br>
        <p style="color:red">Cảm ơn bạn đã than toán thành công! Ngắm ảnh đi nhé</p>
        <a href="index.php">Quay về</a>
    </form>
    
</body>
</html>

Còn ảnh thì các bạn tự lấy ảnh của các bạn để thêm vào project nhé.  Bố cục của project hiện tại sẽ như dưới đây.

Các bạn lưu ý giúp mình đối với hai thông tin trong method vnpay_payment tại class payment của file PaymenVnpayClass.php:

$vnp_TmnCode = "262XSFHX";//Mã website tại VNPAY 
$vnp_HashSecret = "MMZXWISZNUUUNKGOZQPCPASLLTHYGMTB"; //Chuỗi bí mật

Trên môi trường test bạn đăng ký và bên ví vnpay họ sẽ gửi hai thông tin này về Email. Còn khi nào mà triển khai thật thì bạn cần làm việc trực tiếp với bên nhà cung cấp luôn nhé.  Bạn cũng có thể dùng chung thông tin của mình như trên cũng được nhé! Hy vọng không vấn đề gì.

Link đăng ký tại đây

Ok, Bây giờ các bạn chạy thử thôi nào. Quá ngon lành cành đào đúng ko. Nằm ngủ nhớ tắt điện thoại kèo tiền về ồn không ngủ được nhé!

Để Lại Ý Kiến Của bạn!
Bài Viết Chuyên Mục


Khóa Học Miễn Phí

IvyModa

FullStack

Chi tiết

Tạo tính năng CRUD với Livewire Laravel

FullStack

Chi tiết

Php-MySqli-DataBase Cơ Bản

FullStack

Chi tiết
Về MinaCode
Đọc Thơ Nhân Kỷ Niệm 10 Năm Thành Lập MB Nam Đà Nẵng

Banker To Coder

Hi All,


Nguyên đây! MinaCode là website mình tạo ra với mong muốn chia sẻ chút kiến thức liên quan đến lập trình FullStack.

Ngôn ngữ lập trình chủ yếu được sử dụng là Htm, Css, Javascript, Php cùng một số thư viện như Jquery, Fontawesome... Phía Frontend và Farmework Laravel phía Backend.

Mình chưa bao giờ tham gia bất cứ một trường lớp nào về lập trình. Tất cả kiến thức mình chia sẻ đều là trên tình thần tự học. Do đó:

+ MinaCode phù hợp với những tay ngang, xem lập trình như là một kỹ năng bổ trợ trong công việc hay là một kênh kiếm thêm thu nhập từ những very mini projects.

+ MinaCode không phù hợp với những bạn đang được đào tạo bài bản, chính quy.

Mình tin rằng, Trong tương lai không xa. Lập trình sẽ trở nên một kỹ năng không thể thiếu đối với các bạn trẻ.

Cuối cùng thì Ngôn ngữ lập trình không quan trọng bằng Tư duy lập trình. Mình chúc các bạn sẽ có được những kiến thức bổ ích với MinaCode.

--Ngô Sỹ Nguyên--

Coming Soon