Add Stripe embedded checkout to book pages

Replaces the gumroad_url stub with an on-site embedded checkout (buy
button -> POST to the bookshop backend -> mounted Stripe iframe),
following the existing contact/submissions form's fetch/status-message
pattern. Adds thank-you and resend-link pages, an example book template
(draft), and updates the privacy policy and terms to honestly disclose
Stripe as a third-party payment processor.
This commit is contained in:
2026-07-14 18:35:50 -04:00
parent 40266cf811
commit 41475f4a5a
8 changed files with 171 additions and 12 deletions
+52
View File
@@ -0,0 +1,52 @@
{{ define "main" }}
<h1>{{ .Title }}</h1>
{{ with .Params.cover_image }}
<img src="{{ . }}" alt="Cover of {{ $.Title }}" style="max-width:300px;">
{{ end }}
{{ with .Params.author }}
<p><span class="author-name">{{ . }}</span></p>
{{ end }}
{{ .Content }}
{{ with .Params.stripe_price_id }}
<div id="buy-btn-wrap">
{{ with $.Params.price_display }}<p><strong>{{ . }}</strong></p>{{ end }}
<button type="button" id="buy-btn" class="btn">Buy the ebook</button>
</div>
<div id="checkout-container"></div>
<p id="buy-status" role="status" style="margin-top:1rem;"></p>
<script src="https://js.stripe.com/v3/"></script>
<script>
(function () {
var stripe = Stripe("{{ $.Site.Params.stripe_publishable_key }}");
var priceId = "{{ . }}";
var buyBtn = document.getElementById("buy-btn");
var buyWrap = document.getElementById("buy-btn-wrap");
var status = document.getElementById("buy-status");
buyBtn.addEventListener("click", function () {
buyBtn.disabled = true;
status.textContent = "Starting checkout…";
fetch("{{ $.Site.Params.bookshop_base_url }}/books/checkout", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ price_id: priceId })
}).then(function (res) {
if (!res.ok) { throw new Error("checkout session request failed"); }
return res.json();
}).then(function (data) {
status.textContent = "";
buyWrap.hidden = true;
return stripe.initEmbeddedCheckout({ clientSecret: data.clientSecret });
}).then(function (checkout) {
checkout.mount("#checkout-container");
}).catch(function () {
buyBtn.disabled = false;
buyWrap.hidden = false;
status.textContent = "Something went wrong starting checkout. Try again, or email hello@twosquirrelspress.com.";
});
});
})();
</script>
{{ end }}
{{ end }}