feat(checkout): real Stripe Express + Elements on /checkout
- Add @stripe/stripe-js + @stripe/react-stripe-js - New src/lib/stripe-client.ts: cached loadStripe helper - New src/actions/billing/retail-payment-intent.ts: server action that creates a PaymentIntent with automatic_payment_methods - New src/components/storefront/StripeExpressCheckout.tsx: embedded ExpressCheckoutElement (Apple Pay, Google Pay, Link, PayPal) + PaymentElement (card) + hosted-checkout fallback - /checkout form is now controlled; StripeExpressCheckout reads name/email/stop from form state and confirms in-page via stripe.confirmPayment - /checkout/success handles both ?session_id= and ?payment_intent= so embedded + hosted flows both land on the same order-creation page using the pending_checkout sessionStorage payload - Export StopInfo from CartContext and select 'time' on the stops fetch so the local Stop shape matches the context's StopInfo - QuickCartSheet express buttons are visual shortcuts only; /checkout auto-renders the real Apple Pay / Google Pay buttons Requires NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY for the embedded path; if missing the embedded section falls back to the hosted Stripe Checkout button. npx tsc --noEmit passes.
This commit is contained in:
@@ -312,7 +312,10 @@ function SheetContent({
|
||||
|
||||
{/* Footer — sticky CTA + express */}
|
||||
<div className="border-t border-stone-900/10 bg-[#F5EFD9] px-6 sm:px-8 pt-5 pb-7 space-y-3">
|
||||
{/* Express checkout row */}
|
||||
{/* Express checkout row — the buttons are visual shortcuts.
|
||||
/checkout auto-renders Stripe's <ExpressCheckoutElement> for
|
||||
Apple Pay / Google Pay / Link + <PaymentElement> for card via
|
||||
StripeExpressCheckout. The `?express=` query is decorative. */}
|
||||
<div>
|
||||
<p className="font-mono text-[9px] uppercase tracking-[0.22em] text-stone-500 mb-2 text-center">
|
||||
Express checkout
|
||||
|
||||
Reference in New Issue
Block a user