Skip to main content

max / makenotwork

10.4 KB · 213 lines History Blame Raw
1 {% extends "base.html" %}
2
3 {% block title %}Confirm Purchase - Makenotwork{% endblock %}
4 {% block body_attrs %} class="purchase-page"{% endblock %}
5
6 {% block content %}
7 <div class="container">
8 <h1 class="brand-h1">Makenot<span class="dot">.</span>work</h1>
9 <p class="tagline">Fair distribution for creatives of all kinds<span class="dot">.</span></p>
10
11 <div class="checkout-box content-section">
12 <div class="step-indicator">Step 2 of 2</div>
13 <h2 class="section-header">Confirm Purchase</h2>
14
15 <div class="item-summary">
16 <div class="item-thumbnail">{{ item.thumbnail }}</div>
17 <div class="item-details">
18 <div class="item-title">{{ item.title }}</div>
19 <div class="item-creator">
20 by <a href="/u/{{ creator_username }}">{{ creator_username }}</a>
21 </div>
22 <div class="item-description">{{ item.description }}</div>
23 </div>
24 </div>
25
26 <div class="info-box">
27 <h3>What you'll get:</h3>
28 <ul>
29 <li>Lifetime access to all current and future versions</li>
30 <li>Email notifications for updates</li>
31 <li>Direct support from the creator</li>
32 </ul>
33 </div>
34
35 <div class="price-breakdown">
36 <h2 class="section-header">Price Breakdown</h2>
37 <div class="price-row">
38 <span>Item price</span>
39 <span>{{ item.price }}</span>
40 </div>
41 <div class="price-row total">
42 <span>You pay</span>
43 <span>{{ item.price }}</span>
44 </div>
45 <p class="price-breakdown-note">
46 {% if stripe_tax_enabled %}
47 Applicable taxes will be calculated at checkout based on your location.
48 {% else %}
49 Taxes not included. Applicable taxes may vary by jurisdiction.
50 {% endif %}
51 </p>
52 </div>
53
54 <div class="creator-breakdown">
55 <h2 class="section-header">What {{ creator_username }} receives</h2>
56 <div class="price-row">
57 <span>Payment processing (~2.9% + 30c)</span>
58 <span>-${{ stripe_fee }}</span>
59 </div>
60 <div class="price-row">
61 <span>Platform fee</span>
62 <span class="platform-fee-amount">$0.00</span>
63 </div>
64 <div class="price-row is-total">
65 <span>Creator receives</span>
66 <span>~${{ creator_receives }}</span>
67 </div>
68 <p class="creator-breakdown-note">
69 0% platform fee; only standard payment processing applies.
70 </p>
71 </div>
72
73 <div class="payment-section">
74 <h2 class="section-header">Secure Checkout</h2>
75 <p class="payment-section-lead">
76 You'll be redirected to a secure checkout page to complete your purchase.
77 </p>
78
79 {% if is_logged_in && !pending_started.is_empty() %}
80 <div class="info-box pending-checkout">
81 <p><strong>You have an unfinished checkout</strong> for this item, started {{ pending_started }}.</p>
82 <p class="is-sub">
83 Stripe only allows one open checkout at a time. Cancel the previous attempt to start a new one.
84 </p>
85 <form action="/stripe/checkout/{{ item.id }}/cancel-pending" method="POST">
86 <input type="hidden" name="_csrf" value="{{ csrf_token.as_deref().unwrap_or_default() }}">
87 <button class="btn-secondary" type="submit">Cancel previous checkout</button>
88 </form>
89 </div>
90 {% endif %}
91
92 {% if is_logged_in %}
93 {% if pending_started.is_empty() %}
94 <form action="/stripe/checkout/{{ item.id }}" method="POST">
95 {% if pwyw_enabled %}
96 <div class="checkout-field">
97 <label for="pwyw_amount" class="checkout-field-label">Name your price (suggested: ${{ suggested_price }})</label>
98 <div class="pwyw-row">
99 <span class="pwyw-symbol">$</span>
100 <input type="number" id="pwyw_amount" class="pwyw-input" value="{{ suggested_price }}" min="{{ pwyw_min_dollars }}" step="0.01" oninput="updatePwywButton(this.value)">
101 <input type="hidden" id="amount_cents" name="amount_cents" value="{{ pwyw_min_cents }}">
102 </div>
103 {% if pwyw_min_cents > 0 %}
104 <p class="pwyw-min-note">Minimum: ${{ pwyw_min_dollars }}</p>
105 {% endif %}
106 </div>
107 {% endif %}
108 <div class="checkout-field">
109 <label for="promo_code" class="checkout-field-label">Promo code (optional)</label>
110 <input type="text" id="promo_code" name="promo_code" class="promo-input" value="{{ promo_code }}" placeholder="e.g. LAUNCH50">
111 </div>
112 <div class="checkout-field">
113 <label class="share-contact-label">
114 <input type="checkbox" name="share_contact" value="true" class="share-contact-checkbox">
115 Share my email address with the creator
116 </label>
117 </div>
118 <button class="btn-primary" type="submit" id="checkout-btn" data-loading-text="Redirecting to Stripe...">Continue to Payment - {% if pwyw_enabled %}${{ suggested_price }}{% else %}{{ item.price }}{% endif %}</button>
119 </form>
120 <p class="cart-alt-link">
121 or <a href="#" onclick="fetch('/api/cart/{{ item.id }}',{method:'POST',headers:csrfHeaders()}).then(function(r){if(!r.ok)throw new Error('Failed');return r.json()}).then(function(){window.location.href='/cart'}).catch(function(){alert('Could not add to cart. Please try again.')});return false;">add to cart</a> to buy with other items and save the creator on fees
122 </p>
123 {% endif %}
124 {% else %}
125 <div id="guest-checkout">
126 {% if pwyw_enabled %}
127 <div class="checkout-field">
128 <label for="guest_pwyw_amount" class="checkout-field-label">Name your price (suggested: ${{ suggested_price }})</label>
129 <div class="pwyw-row">
130 <span class="pwyw-symbol">$</span>
131 <input type="number" id="guest_pwyw_amount" class="pwyw-input" value="{{ suggested_price }}" min="{{ pwyw_min_dollars }}" step="0.01">
132 </div>
133 {% if pwyw_min_cents > 0 %}
134 <p class="pwyw-min-note">Minimum: ${{ pwyw_min_dollars }}</p>
135 {% endif %}
136 </div>
137 {% endif %}
138 <button class="btn-primary" id="guest-checkout-btn" onclick="guestCheckout()">
139 Buy Now - {% if pwyw_enabled %}${{ suggested_price }}{% else %}{{ item.price }}{% endif %}
140 </button>
141 <p class="guest-hint">
142 No account required. You'll receive a download link via email.
143 </p>
144 <p class="guest-login-prompt">
145 <a href="/login?return_to=/purchase/{{ item.id }}">Log in</a> to save purchases to your library.
146 </p>
147 </div>
148 <script>
149 function guestCheckout() {
150 const btn = document.getElementById('guest-checkout-btn');
151 btn.disabled = true;
152 btn.textContent = 'Redirecting...';
153
154 const body = {};
155 {% if pwyw_enabled %}
156 const amount = parseFloat(document.getElementById('guest_pwyw_amount').value);
157 body.amount_cents = Math.round(amount * 100);
158 {% endif %}
159
160 fetch('/api/checkout/guest/{{ item.id }}', {
161 method: 'POST',
162 headers: { 'Content-Type': 'application/json' },
163 body: JSON.stringify(body),
164 })
165 .then(r => r.json())
166 .then(data => {
167 if (data.checkout_url) {
168 window.location.href = data.checkout_url;
169 } else {
170 btn.disabled = false;
171 btn.textContent = 'Buy Now';
172 alert(data.error || 'Something went wrong');
173 }
174 })
175 .catch(() => {
176 btn.disabled = false;
177 btn.textContent = 'Buy Now';
178 alert('Something went wrong. Please try again.');
179 });
180 }
181 </script>
182 {% endif %}
183 <button class="btn-secondary" onclick="window.history.back()">Cancel</button>
184 </div>
185
186 <div class="security-note">
187 Your payment information is encrypted and never stored on Makenotwork servers
188 </div>
189 </div>
190
191 <div class="checkout-footer">
192 By completing this purchase, you agree to our <a href="/policy">Content Policy</a>
193 </div>
194 </div>
195 {% endblock %}
196
197 {% block scripts %}
198 {% if pwyw_enabled %}
199 <script>
200 function updatePwywButton(val) {
201 var dollars = parseFloat(val) || 0;
202 document.getElementById('amount_cents').value = Math.round(dollars * 100);
203 document.getElementById('checkout-btn').textContent = 'Continue to Payment - $' + dollars.toFixed(2);
204 }
205 // Initialize on load
206 (function() {
207 var input = document.getElementById('pwyw_amount');
208 if (input) updatePwywButton(input.value);
209 })();
210 </script>
211 {% endif %}
212 {% endblock %}
213