diff --git a/make_post_sell/templates/cart_checkout.j2 b/make_post_sell/templates/cart_checkout.j2
index a48a10a..c82bee9 100644
--- a/make_post_sell/templates/cart_checkout.j2
+++ b/make_post_sell/templates/cart_checkout.j2
@@ -55,7 +55,15 @@
{% endif %}
-
+
+ {# For free checkouts (e.g., with coupons), provide a simple confirmation button #}
+ {% if not cart.requires_payment %}
+
+ {% endif %}
+
{# Offer Monero if globally enabled, shop has enabled processor, cart requires payment and is single-shop #}
{% if monero_enabled and xmr_processor_enabled and cart.requires_payment and cart.shop_product_dict|length == 1 %}
diff --git a/make_post_sell/tests/test_functional.py b/make_post_sell/tests/test_functional.py
index b5e9ea0..479e677 100644
--- a/make_post_sell/tests/test_functional.py
+++ b/make_post_sell/tests/test_functional.py
@@ -828,6 +828,9 @@ class AuthenticatedFunctionalTests(FunctionalTests):
# Should contain order confirmation elements
self.assertIn("Please confirm your order", checkout_body)
+ # NEW: Verify the "Confirm Free Checkout" button appears
+ self.assertIn("Yes, Confirm Free Checkout", checkout_body)
+
# 6. SUCCESS! We reached the checkout page without AttributeError crash
# This validates that the original bug (stripe_user_shop.active_card AttributeError) is fixed
@@ -837,6 +840,9 @@ class AuthenticatedFunctionalTests(FunctionalTests):
print(
"✓ Core bug fix validated: stripe_user_shop=None properly handled in cart.py:712"
)
+ print(
+ "✓ FREE CHECKOUT BUTTON VERIFIED: 'Confirm Free Checkout' button appears in HTML"
+ )
# 7. Complete the actual checkout to create a real invoice
# Now that transaction management is fixed, we can safely complete checkout