Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
640e72d
Add Stripe Express Checkout (Apple Pay, Google Pay, Link) to cart
Cichorek Mar 16, 2026
fe9eed4
Improve Express Checkout: show subtotal without shipping, add shippin…
Cichorek Mar 17, 2026
a815602
Update Express Checkout for Spree SDK 0.12.0
Cichorek Mar 17, 2026
1a14f58
Add express checkout to checkout page for guest users
Cichorek Mar 17, 2026
1ed20a2
Add HTTPS development instructions for Apple Pay / Google Pay
Cichorek Mar 17, 2026
cccc368
Disable checkout UI during express checkout processing
Cichorek Mar 17, 2026
b253382
Fix express checkout review feedback: onReady guard, basePath prop, l…
Cichorek Mar 18, 2026
6011452
Replace onProcessingChange useEffect with direct callback invocation
Cichorek Mar 18, 2026
bfac850
Update express checkout for Spree SDK 0.15 field renames
Cichorek Mar 23, 2026
007cdf9
Smooth fade transition for express checkout finalizing state
Cichorek Mar 30, 2026
2e9c508
Fix order-placed page showing "Order not found" after express checkout
Cichorek Apr 8, 2026
2daaca5
Hide express checkout section when no payment methods are available
Cichorek Apr 8, 2026
05b30ea
Switch HTTPS dev instructions from mkcert+lvh.me to Cloudflare Tunnel
Cichorek Apr 13, 2026
1e749f0
Remove mkcert HTTPS dev setup, allow *.trycloudflare.com
Cichorek Apr 13, 2026
afb0e9f
Remove Stripe Connect account ID support
Cichorek Apr 14, 2026
38504e9
Adjustments & Fixes requested by Damian
Cichorek Apr 14, 2026
6d4b3a6
Fix Express Checkout amount mismatch with Stripe line items
Cichorek Apr 14, 2026
6b0039b
Add debug logging to Express Checkout amount flow
Cichorek Apr 14, 2026
343bb83
Fix Express Checkout amount: use buildLineItems total instead of item…
Cichorek Apr 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .env.local.example
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# Spree API Configuration (server-side only)
SPREE_API_URL=http://localhost:3000
SPREE_PUBLISHABLE_KEY=your_publishable_api_key_here

# Stripe Configuration (client-side)
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_your_key_here
32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,38 @@ npm run dev

Open [http://localhost:3001](http://localhost:3001) in your browser.

### HTTPS Development (Apple Pay / Google Pay)

Apple Pay and Google Pay require HTTPS **and a publicly-reachable URL** — Stripe verifies the payment method domain from the internet, so `localhost` and locally-trusted certificates (e.g. `mkcert` + `lvh.me`) won't pass domain verification. The simplest way to expose your local storefront with a valid public HTTPS URL is [Cloudflare Tunnel](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/):

1. Install `cloudflared`:

```bash
brew install cloudflared
```

2. Start the dev server normally (HTTP on port 3001):

```bash
npm run dev
```

3. In a second terminal, expose it through a quick tunnel:

```bash
cloudflared tunnel --url http://localhost:3001
```

The output will contain a URL like `https://<random-words>.trycloudflare.com`.

4. Register that URL in your [Stripe Payment method domains](https://dashboard.stripe.com/settings/payment_methods/domains).

5. Open the tunnel URL in your browser and test the Express Checkout buttons in the cart.

> **`allowedDevOrigins`:** `next.config.ts` already allows `*.trycloudflare.com`, so quick tunnels work out of the box. Every time you restart `cloudflared tunnel --url ...` you get a new random subdomain — if you need a stable URL (to avoid re-registering in Stripe on each run), set up a [named tunnel](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/do-more-with-tunnels/trycloudflare/#using-named-tunnels) on your own domain.

> **Spree backend must also be publicly reachable.** The storefront's server-side fetches go to `SPREE_API_URL`, but image URLs and a few other backend-served paths (e.g. the Apple Pay domain-verification file under `/.well-known/apple-developer-merchantid-domain-association`) are fetched by the browser directly and must resolve from the public internet. Point `SPREE_API_URL` at a hosted Spree (e.g. `*.spree.sh`, `*.vendo.dev`, your own staging) or expose your local Spree with another `cloudflared tunnel --url http://localhost:3000`. When tunneling a local Rails app, allow the tunnel host, e.g. `RAILS_DEVELOPMENT_HOSTS=.trycloudflare.com` in the backend's `.env`.

### Production Build

```bash
Expand Down
5 changes: 5 additions & 0 deletions messages/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -504,5 +504,10 @@
"privacyPolicy": "Datenschutzrichtlinie",
"returnsPolicy": "Rückgaberichtlinie",
"termsOfService": "Nutzungsbedingungen"
},
"expressCheckout": {
"shipping": "Versand",
"finalizingPayment": "Zahlung wird abgeschlossen...",
"or": "oder"
}
}
5 changes: 5 additions & 0 deletions messages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -504,5 +504,10 @@
"privacyPolicy": "Privacy Policy",
"returnsPolicy": "Returns Policy",
"termsOfService": "Terms of Service"
},
"expressCheckout": {
"shipping": "Shipping",
"finalizingPayment": "Finalizing your payment...",
"or": "or"
}
}
5 changes: 5 additions & 0 deletions messages/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -504,5 +504,10 @@
"privacyPolicy": "Politica de privacidad",
"returnsPolicy": "Politica de devoluciones",
"termsOfService": "Terminos de servicio"
},
"expressCheckout": {
"shipping": "Envio",
"finalizingPayment": "Finalizando tu pago...",
"or": "o"
}
}
5 changes: 5 additions & 0 deletions messages/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -504,5 +504,10 @@
"privacyPolicy": "Politique de confidentialite",
"returnsPolicy": "Politique de retour",
"termsOfService": "Conditions generales"
},
"expressCheckout": {
"shipping": "Livraison",
"finalizingPayment": "Finalisation du paiement...",
"or": "ou"
}
}
5 changes: 5 additions & 0 deletions messages/pl.json
Original file line number Diff line number Diff line change
Expand Up @@ -504,5 +504,10 @@
"privacyPolicy": "Polityka prywatności",
"returnsPolicy": "Polityka zwrotów",
"termsOfService": "Regulamin"
},
"expressCheckout": {
"shipping": "Dostawa",
"finalizingPayment": "Finalizowanie płatności...",
"or": "lub"
}
}
6 changes: 6 additions & 0 deletions next.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import createNextIntlPlugin from "next-intl/plugin";
const withNextIntl = createNextIntlPlugin();

const nextConfig: NextConfig = {
allowedDevOrigins: ["shop.lvh.me", "*.trycloudflare.com"],
env: {
NEXT_PUBLIC_SENTRY_DSN: process.env.SENTRY_DSN || "",
},
Expand Down Expand Up @@ -49,6 +50,11 @@ const nextConfig: NextConfig = {
hostname: "**.spree.sh",
pathname: "/rails/active_storage/**",
},
{
protocol: "https",
hostname: "**.trycloudflare.com",
pathname: "/rails/active_storage/**",
},
],
},
};
Expand Down
Loading
Loading