Commit ed94a785 by tdgiang

Add admin create-transaction endpoint and form page

Implements Task 7: newTransactionForm and createTransaction controller functions with supporting view.
- Controller generates merTrxId and transCode with UUID-based unique suffix
- Signs transaction using epaySign.signRequest
- Persists AdminTransaction record to MongoDB
- Returns JSON response with code 00/99 and payment URL
- View provides HTML form to submit customer data and display payment link
Co-Authored-By: 's avatarClaude Sonnet 5 <noreply@anthropic.com>
parent b49432d8
"use strict";
var moment = require("moment");
var uuidv4 = require("uuid").v4;
var config = require(__config_path + "/config");
var AdminTransaction = require("../models/AdminTransaction");
var epaySign = require("../libs/epaySign");
exports.newTransactionForm = function (req, res) {
res.render("admin/transactions-new", {});
};
exports.createTransaction = function (req, res) {
var customerName = req.body.customerName;
var customerPhone = req.body.customerPhone;
var customerAddress = req.body.customerAddress;
var amount = req.body.amount;
if (!customerName || !customerPhone || !customerAddress || !amount) {
return res.status(400).json({ code: "99", data: "MISSING_FIELDS" });
}
var timeStamp = moment().format("YYYYMMDDHHmmss");
var uniqueSuffix = uuidv4().split("-")[0];
var merTrxId = "HY_" + timeStamp + "_" + uniqueSuffix;
var transCode = "HY_RT_" + timeStamp + "_" + uniqueSuffix;
var merchantToken = epaySign.signRequest(
timeStamp,
merTrxId,
config.epay.merchant_id,
amount,
config.epay.encode_key
);
AdminTransaction.create(
{
merTrxId: merTrxId,
transCode: transCode,
customerName: customerName,
customerPhone: customerPhone,
customerAddress: customerAddress,
amount: parseInt(amount),
merchantToken: merchantToken,
timeStamp: timeStamp,
},
function (err, tx) {
if (err) {
return res.status(500).json({ code: "99", data: "DB_ERROR" });
}
var paymentUrl = config.epay.req_domain + "/admin/pay/" + tx.merTrxId;
return res.status(200).json({
code: "00",
data: { merTrxId: tx.merTrxId, paymentUrl: paymentUrl },
});
}
);
};
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Thêm mới giao dịch</title>
<style>
body { font-family: Arial, sans-serif; max-width: 480px; margin: 40px auto; }
label { display: block; margin-top: 12px; font-weight: bold; }
input { width: 100%; padding: 8px; margin-top: 4px; box-sizing: border-box; }
button { margin-top: 20px; padding: 10px 20px; background: #2d6cdf; color: #fff; border: none; cursor: pointer; }
#result { margin-top: 20px; padding: 12px; background: #f0f0f0; word-break: break-all; display: none; }
</style>
</head>
<body>
<h2>Thêm mới giao dịch</h2>
<p><a href="/admin/transactions">Xem lịch sử giao dịch</a></p>
<form id="txForm">
<label>Tên khách hàng</label>
<input type="text" name="customerName" required>
<label>Số điện thoại</label>
<input type="text" name="customerPhone" required>
<label>Địa chỉ</label>
<input type="text" name="customerAddress" required>
<label>Số tiền thanh toán (VNĐ)</label>
<input type="number" name="amount" required min="1000">
<button type="submit">Tạo giao dịch</button>
</form>
<div id="result"></div>
<script>
document.getElementById('txForm').addEventListener('submit', function (e) {
e.preventDefault();
var form = e.target;
var data = {
customerName: form.customerName.value,
customerPhone: form.customerPhone.value,
customerAddress: form.customerAddress.value,
amount: form.amount.value
};
fetch('/admin/transactions', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
})
.then(function (r) { return r.json(); })
.then(function (res) {
var el = document.getElementById('result');
el.style.display = 'block';
if (res.code === '00') {
el.innerHTML = 'Link thanh toán: <a href="' + res.data.paymentUrl + '" target="_blank">' + res.data.paymentUrl + '</a>';
} else {
el.innerHTML = 'Lỗi: ' + res.data;
}
});
});
</script>
</body>
</html>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment