checkout
Trang thanh toán. LƯU Ý: trang này không dùng bộ biến chung — không có menus và customer, còn store chỉ có trường name.
- Tệp giao diện:
checkout.html - Đường dẫn:
/thanh-toan - Controller:
App\Modules\Checkout\CheckoutController::checkoutPage
Ngoài những biến dưới đây, slot này còn nhận toàn bộ biến toàn cục.
Biến của trang
| Biến | Kiểu | Mô tả | Từ phiên bản |
|---|---|---|---|
cart |
Cart |
Giỏ hàng đang được thanh toán. | 1.0 |
Mã đầy đủ
Toàn bộ tệp checkout.html của bộ giao diện mặc định. Chép về templates/<bộ giao diện của bạn>/checkout.html rồi sửa theo ý muốn.
<div class="container page-content">
<h1 class="page-title">Thanh toán</h1>
<div class="checkout-layout">
<form id="checkout-form" class="checkout-form"
x-data="{
loading: false,
error: '',
async submit(e) {
e.preventDefault();
this.error = '';
this.loading = true;
var data = Object.fromEntries(new FormData(e.target));
try {
var cartToken = xStore.cart.getToken();
var session = await xStore.checkout.start(cartToken);
await xStore.checkout.setAddress(session.id, {
first_name: data.first_name,
last_name: data.last_name,
email: data.email,
address1: data.address1,
city: data.city,
country_code: data.country_code || 'VN',
phone: data.phone,
});
if (data.shipping_method_id) {
await xStore.checkout.setShipping(session.id, {
shipping_method_id: data.shipping_method_id,
shipping_amount: parseFloat(data.shipping_amount || '0'),
});
}
await xStore.checkout.initiatePayment(session.id, {
payment_method: data.payment_method || 'cod',
note: data.note || null,
});
window.location.href = '/tai-khoan';
} catch (err) {
this.error = err.message || 'Đặt hàng thất bại. Vui lòng thử lại.';
this.loading = false;
}
}
}"
@submit="submit($event)"
>
<div class="form-section">
<h2>Thông tin giao hàng</h2>
<input type="hidden" name="country_code" value="VN">
<div class="form-row">
<div class="form-group">
<label for="last_name">Họ *</label>
<input type="text" id="last_name" name="last_name" required class="form-input"
placeholder="Nguyễn">
</div>
<div class="form-group">
<label for="first_name">Tên *</label>
<input type="text" id="first_name" name="first_name" required class="form-input"
placeholder="Văn A">
</div>
</div>
<div class="form-row">
<div class="form-group">
<label for="email">Email *</label>
<input type="email" id="email" name="email" required class="form-input"
placeholder="[email protected]">
</div>
<div class="form-group">
<label for="phone">Số điện thoại</label>
<input type="tel" id="phone" name="phone" class="form-input"
placeholder="0901234567">
</div>
</div>
<div class="form-group">
<label for="address1">Địa chỉ *</label>
<input type="text" id="address1" name="address1" required class="form-input"
placeholder="Số nhà, tên đường, phường/xã">
</div>
<div class="form-row">
<div class="form-group">
<label for="city">Tỉnh/Thành phố *</label>
<input type="text" id="city" name="city" required class="form-input" placeholder="Hà Nội">
</div>
<div class="form-group">
<label for="note">Ghi chú</label>
<textarea id="note" name="note" class="form-input"
placeholder="Giao giờ hành chính..."></textarea>
</div>
</div>
</div>
<div class="form-section">
<h2>Phương thức thanh toán</h2>
<label class="radio-option">
<input type="radio" name="payment_method" value="cod" checked>
Thanh toán khi nhận hàng (COD)
</label>
<label class="radio-option">
<input type="radio" name="payment_method" value="bank_transfer">
Chuyển khoản ngân hàng
</label>
</div>
<div class="alert alert--error" x-show="error" x-text="error" style="display:none;"></div>
<button type="submit" class="btn btn--primary btn--lg btn--block" :disabled="loading">
<span x-show="!loading">Đặt hàng</span>
<span x-show="loading">Đang xử lý...</span>
</button>
</form>
<div class="checkout-summary">
<h2>Đơn hàng của bạn</h2>
{% for item in cart.items %}
<div class="checkout-item">
<span>{{ item.product_title }} × {{ item.quantity }}</span>
<span>{{ item.line_total | money }}</span>
</div>
{% endfor %}
<hr>
<div class="checkout-total">
<strong>Tổng cộng</strong>
<strong>{{ cart.total_amount | money }}</strong>
</div>
</div>
</div>
</div>