svelte-stripe

repository·main·Indexed 19 days ago

https://github.com/joshnuss/svelte-stripe

A library providing Svelte components for integrating Stripe Elements into Svelte and SvelteKit projects. It includes a suite of components such as <Elements/>, <PaymentElement/>, <Card/>, <ExpressCheckout/>, and specialized inputs for card details (CardNumber, CardExpiry, CardCvc), IBAN, iDEAL, and addresses. The library enables seamless payment processing UI and supports various payment flows including standard credit cards, digital wallets like Google Pay and Apple Pay, and regional methods such as SEPA, Alipay, and Klarna.

Tokens
9.7K
Snippets
30
Records
45
Agent score
66%

What's inside svelte-stripe

  1. Overview of svelte-stripe components

    main

    The svelte-stripe library provides a suite of Svelte components to integrate Stripe Elements into your application. It is 100% SvelteKit compatible.

    Key components include:

    • <Elements/>: A wrapper component used to set the Stripe context for child components.
    • <PaymentElement/>: An all-in-one component that allows users to choose their preferred payment method.
    • <Card/>: A composite component containing inputs for card number, expiry, CVC, and zip code.
    • <ExpressCheckout/>: Enables wallet-based payments (Google Pay, Apple Pay, or Link) without leaving the page.
    • <CardNumber/>, <CardExpiry/>, <CardCvc/>: Individual input fields for specific card details.
    • <Iban/>, <Ideal/>: Specialized input fields for IBAN and iDEAL payments.
    • <LinkAuthenticationElement/>: For using saved payment methods via Link.
    • <Address/>: For collecting billing and shipping addresses.
  2. Handle Stripe Webhooks

    main

    Use webhooks to fulfill orders after a payment succeeds. You must verify the webhook signature using stripe.webhooks.constructEvent() to ensure the request is authentic.

    In development, use the Stripe CLI to forward webhooks to your local server: stripe listen --forward-to localhost:5173/stripe/webhooks

    import Stripe from 'stripe'
    import { error, json } from '@sveltejs/kit'
    import { env } from '$env/dynamic/private'
    
    const stripe = new Stripe(env.SECRET_STRIPE_KEY)
    
    export async function POST({ request }) {
      const body = await request.text()
      const signature = request.headers.get('stripe-signature')
    
      let event
      try {
        event = stripe.webhooks.constructEvent(body, signature, env.STRIPE_WEBHOOK_SECRET)
      } catch (err) {
        throw error(400, 'Invalid request')
      }
    
      if (event.type == 'charge.succeeded') {
        const charge = event.data.object
        // Fulfill order
      }
    
      return json()
    }
  3. Accept SEPA and iDEAL payments

    main

    SEPA

    Use the <Iban> component. You can restrict supported countries using the supportedCountries prop (e.g., ['SEPA']). Complete the payment using stripe.confirmSepaDebitPayment().

    iDEAL

    Use the <Ideal> component. Complete the payment using stripe.confirmIdealPayment(), ensuring you provide a return_url.

    <!-- SEPA Example -->
    <Iban supportedCountries={['SEPA']} bind:element={ibanElement} />
    
    <!-- iDEAL Example -->
    <Ideal bind:element={idealElement} />
  4. Set up Stripe environment variables

    main

    Configure your Stripe credentials by adding your public and secret keys to your environment variables. Use the public key for client-side operations and the secret key for server-side operations (like creating Payment Intents or handling webhooks).

    PUBLIC_STRIPE_KEY=pk_test_...
    SECRET_STRIPE_KEY=sk_test_...
  5. Use <ExpressCheckout> for GooglePay and ApplePay

    main

    The <ExpressCheckout> component displays express payment buttons.

    1. Set the mode="payment" prop on <Elements>.
    2. Handle the onclick event to resolve line items (name and amount).
    3. Handle the onconfirm event to submit the elements and call stripe.confirmPayment().
    <Elements {stripe} mode="payment" currency="usd" amount={1099} bind:elements>
      <ExpressCheckout
        onclick={click}
        onconfirm={confirm}
        buttonHeight={50}
        buttonTheme={{ googlePay: 'white' }}
        buttonType={{ googlePay: 'donate' }}
        paymentMethodOrder={['googlePay', 'link']}
      />
    </Elements>
    
    <script>
      async function click(event) {
        const options = {
          emailRequired: true,
          phoneNumberRequired: true,
          lineItems: [{ name: 'Rad T-Shirt', amount: 1099 }]
        }
        event.resolve(options)
      }
    
      async function confirm(event) {
        let result = await elements.submit()
        if (result.error) return error = result.error
    
        const clientSecret = await createPaymentIntent()
        result = await stripe.confirmPayment({
          elements,
          clientSecret,
          confirmParams: { return_url: '...' }
        })
      }
    </script>
  6. Use the <PaymentElement> for all-in-one payments

    main

    The <PaymentElement> is an all-in-one component that supports various payment methods like credit cards, SEPA, Google Pay, and Apple Pay.

    To use it:

    1. Enable automatic_payment_methods: { enabled: true } when creating the Payment Intent on the server.
    2. Include <PaymentElement /> inside the <Elements> provider.
    3. Bind the elements instance to your form to call stripe.confirmPayment() upon submission.
    <form onsubmit={submit}>
      <Elements {stripe} {clientSecret} bind:elements>
        <PaymentElement options="{...}" />
      </Elements>
    
      <button>Pay</button>
    </form>
    
    <script>
      // ... inside submit function
      const result = await stripe.confirmPayment({
        elements,
        redirect: 'if_required'
      })
    </script>
  7. Install svelte-stripe and dependencies

    main

    To use svelte-stripe in your Svelte or SvelteKit project, you need to install the library itself along with Stripe's official server-side and client-side libraries. Use pnpm to add these three packages:

    • stripe: Official Stripe server-side library.
    • @stripe/stripe-js: Official Stripe client-side library.
    • svelte-stripe: The community-supported Svelte wrapper for Stripe Elements.
    pnpm install -D stripe @stripe/stripe-js svelte-stripe
  8. Initialize Stripe with the <Elements> component

    main

    To use Stripe components, you must first initialize Stripe using loadStripe from @stripe/stripe-js and then wrap your components in the <Elements> component provided by svelte-stripe. This is typically done inside an onMount block to ensure the code runs in the browser.

    <script lang="ts">
      import { loadStripe } from '@stripe/stripe-js'
      import { Elements } from 'svelte-stripe'
      import { onMount } from 'svelte'
      import { PUBLIC_STRIPE_KEY } from '$env/static/public'
    
      let stripe = null
    
      onMount(async () => {
        stripe = await loadStripe(PUBLIC_STRIPE_KEY)
      })
    </script>
    
    <Elements {stripe}>
      <!-- your Stripe components go here -->
    </Elements>
  9. Create a Payment Intent server-side

    main

    Before charging a customer, you must create a Payment Intent on your server to securely define the amount and currency. This prevents clients from tampering with the price. The server should return the client_secret to the client to complete the payment process.

    import Stripe from 'stripe'
    import { SECRET_STRIPE_KEY } from '$env/static/private'
    
    const stripe = new Stripe(SECRET_STRIPE_KEY)
    
    export async function POST() {
      const paymentIntent = await stripe.paymentIntents.create({
        amount: 2000,
        currency: 'usd',
        payment_method_types: ['card']
      })
    
      return {
        body: {
          clientSecret: paymentIntent.client_secret
        }
      }
    }
  10. Accept Credit Card payments manually

    main

    For granular control over credit card inputs, use the <CardNumber>, <CardExpiry>, and <CardCvc> components. You must bind the cardElement from <CardNumber> to pass it to stripe.confirmCardPayment().

    <Elements {stripe}>
      <form onsubmit={submit}>
        <CardNumber bind:element={cardElement} />
        <CardExpiry />
        <CardCvc />
    
        <button>Pay</button>
      </form>
    </Elements>
    
    <script>
      // ... inside submit function
      const result = await stripe.confirmCardPayment(clientSecret, {
        payment_method: {
          card: cardElement,
          billing_details: { ... }
        }
      })
    </script>
  11. Style Stripe components with the appearance API

    main

    You can customize the look of your Stripe components by passing an appearance object to the <Elements> component. This allows you to set themes, label styles, and custom CSS variables like colorPrimary.

    <Elements
      appearance={{
        theme: "flat",
        labels: "floating",
        variables: { colorPrimary: 'pink' },
        rules: {...}
      }}
    />
  12. Use <LinkAuthenticationElement> with <PaymentElement>

    main

    To enable Link authentication (which allows customers to use saved details via email/SMS), add the <LinkAuthenticationElement /> alongside the <PaymentElement /> inside your <Elements> container.

    <form onsubmit={submit}>
      <Elements {stripe} {clientSecret} bind:elements>
        <LinkAuthenticationElement />
        <PaymentElement />
      </Elements>
    
      <button>Pay</button>
    </form>