danstore / Views /Checkout /Index.cshtml
Danishathugging's picture
Sync from GitHub via hub-sync
6db0915 verified
Raw
History Blame Contribute Delete
5.77 kB
@model CheckoutViewModel
@{
ViewData["Title"] = "Checkout";
}
<div class="max-w-4xl mx-auto px-8 py-8">
<h1 class="text-3xl font-bold mb-6">Checkout</h1>
@if (!string.IsNullOrEmpty(Model.ErrorMessage))
{
<div class="alert-toast">@Model.ErrorMessage</div>
}
<div class="grid grid-cols-1 md:grid-cols-2 gap-8">
<div>
<div class="card border rounded-lg p-6 shadow-sm">
<h2 class="text-lg font-semibold mb-4">Shipping Address</h2>
<form id="payment-form" method="post" asp-action="PlaceOrder">
<div class="space-y-4">
<div>
<label class="form-label">Street</label>
<input type="text" id="street" name="street" class="form-control" required />
</div>
<div>
<label class="form-label">City</label>
<input type="text" id="city" name="city" class="form-control" required />
</div>
<div class="grid grid-cols-2 gap-4">
<div>
<label class="form-label">State</label>
<input type="text" id="state" name="state" class="form-control" />
</div>
<div>
<label class="form-label">ZIP Code</label>
<input type="text" id="zipCode" name="zipCode" class="form-control" required />
</div>
</div>
<div>
<label class="form-label">Country</label>
<input type="text" id="country" name="country" class="form-control" value="Pakistan" required />
</div>
</div>
<h2 class="text-lg font-semibold mt-6 mb-4">Payment</h2>
<div id="card-element" class="form-control p-3 mb-4">
<!-- Stripe card element -->
</div>
<div id="card-errors" class="text-sm text-danger mb-3" role="alert"></div>
<input type="hidden" id="paymentIntentId" name="paymentIntentId" value="@Model.StripeClientSecret" />
<button id="submit-btn" type="submit" class="btn btn-primary w-full py-3 transition-all duration-200 active:scale-95">
Pay $@Model.Cart.Total.ToString("F2")
</button>
</form>
</div>
</div>
<div>
<div class="card border rounded-lg p-6 shadow-sm">
<h2 class="text-lg font-semibold mb-4">Order Summary</h2>
<div class="space-y-4">
@foreach (var item in Model.Cart.Items)
{
<div class="flex items-center justify-between text-sm">
<div>
<span class="font-medium">@item.ProductName</span>
<span class="text-gray-400"> x@(item.Quantity)</span>
</div>
<span class="font-semibold">$@item.Subtotal.ToString("F2")</span>
</div>
}
</div>
<div class="border-t mt-4 pt-4 flex justify-between">
<span class="font-semibold text-lg">Total</span>
<span class="text-2xl font-bold text-gray-900">$@Model.Cart.Total.ToString("F2")</span>
</div>
</div>
</div>
</div>
</div>
@section Scripts {
<script src="https://js.stripe.com/v3/"></script>
<script>
const stripe = Stripe('@ViewBag.StripePublishableKey');
const elements = stripe.elements();
const cardElement = elements.create('card', {
style: {
base: {
fontSize: '16px',
color: '#212529',
fontFamily: "'Inter', sans-serif",
'::placeholder': { color: '#adb5bd' }
}
}
});
cardElement.mount('#card-element');
const form = document.getElementById('payment-form');
const submitBtn = document.getElementById('submit-btn');
const errorEl = document.getElementById('card-errors');
form.addEventListener('submit', async (e) => {
e.preventDefault();
submitBtn.disabled = true;
submitBtn.textContent = 'Processing...';
const clientSecret = document.getElementById('paymentIntentId').value;
const { error, paymentIntent } = await stripe.confirmCardPayment(clientSecret, {
payment_method: { card: cardElement }
});
if (error) {
errorEl.textContent = error.message;
submitBtn.disabled = false;
submitBtn.textContent = 'Pay $@Model.Cart.Total.ToString("F2")';
return;
}
if (paymentIntent.status === 'succeeded') {
document.getElementById('paymentIntentId').value = paymentIntent.id;
const form = document.getElementById('payment-form');
const hiddenInput = document.createElement('input');
hiddenInput.type = 'hidden';
hiddenInput.name = 'paymentIntentId';
hiddenInput.value = paymentIntent.id;
form.appendChild(hiddenInput);
form.submit();
}
});
</script>
}