svelte-stripe-js
Everything you need to add Stripe to your Svelte project. 100% svelte-kit compatible.
Components
This package provides the following components:
<Container/>
: A wrapper component to set context.<CardNumber/>
: Input field for the card's number.<CardExpiry/>
: Input field for the card's expiration date.<CardCvc/>
: Input field for Card Verification Value.<Card/>
: All-in-one component that has inputs for card number, expiry, cvc, and zip code.<PaymentRequestButton/>
: A GooglePay or ApplePay button, depending on browser.<Iban/>
: Input field for IBAN (International bank account number).<Ideal/>
: Input field for iDEAL (payment system used in the Netherlands).<PaymentElement/>
: All-in-one component that allows the user to choose the type of payment.
Supported payment types
- Credit card
- GooglePay
- ApplePay
- SEPA direct deposit
- iDEAL
Please open a PR or issue, if you'd like to add more.
Usage
Install packages:
pnpm add -D @stripe/stripe-js svelte-stripe-js
Add your Stripe public key to the environment vars in your .env
:
VITE_STRIPE_PUBLIC_KEY=pk_....
For svelte-kit, add svelte-stripe-js
to the noExternal
list in svelte.config.js
:
const config = {
kit: {
// ...
vite: {
ssr: {
noExternal: ["svelte-stripe-js"],
}
}
},
}
And since svelte-kit can render on the server, don't initialize stripe during SSR:
<script>
import { onMount } from 'svelte'
import { loadStripe } from '@stripe/stripe-js'
import { isServer } from 'svelte-stripe-js'
let stripe = null
onMount(async () => {
if (!isServer) {
stripe = await loadStripe(import.meta.env.VITE_STRIPE_PUBLIC_KEY)
}
})
</script>
Then set up a payment form, according to what types of payment you want to capture.
Credit cards
To accept credit cards, in your payment form, add <CardNumber/>
, <CardExpiry/>
, and <CardCvc/>
components.
<script>
import { onMount } from 'svelte'
import { loadStripe } from '@stripe/stripe-js'
import { Container, CardNumber, CardExpiry, CardCvc } from 'svelte-stripe-js'
let stripe = null
let cardElement
onMount(async () => {
stripe = await loadStripe(import.meta.env.VITE_STRIPE_PUBLIC_KEY)
})
async function submit() {
const result = await stripe.createToken(cardElement)
// create payment intent
}
</script>
{#if stripe}
<Container {stripe}>
<form on:submit|preventDefault={submit}>
<CardNumber bind:element={cardElement}/>
<CardExpiry />
<CardCvc />
<button>Pay</button>
</form>
</Container>
{/if}
GooglePay or ApplePay
To accept GPay or ApplePay, add a <PaymentRequestButton/>
to your payment form:
<script>
import { onMount } from 'svelte'
import { loadStripe } from '@stripe/stripe-js'
import { Container, PaymentRequestButton } from 'svelte-stripe-js'
let stripe = null
let clientSecret = '...' // the payment intent's clientSecret, should come from server
// define payment details
const paymentRequest = {
country: 'US',
currency: 'usd',
total: {label: 'Demo total', amount: 1099},
requestPayerName: true,
requestPayerEmail: true,
}
onMount(async () => {
stripe = await loadStripe(import.meta.env.VITE_STRIPE_PUBLIC_KEY)
})
async function pay(e) {
const paymentMethod = e.detail.paymentMethod
let result = await stripe.confirmCardPayment(clientSecret,
{ payment_method: paymentMethod.id }
)
if (result.error) {
e.detail.complete('fail')
// payment failed, notify user
} else {
e.detail.complete('success')
// payment succeeded, redirect to "thank you" page
}
}
</script>
{#if stripe}
<Container {stripe}>
<PaymentRequestButton {paymentRequest} on:paymentmethod={pay}/>
</Container>
{/if}
SEPA
To accept SEPA direct deposit, add an <Iban/>
component to your payment form:
<script>
import { onMount } from 'svelte'
import { loadStripe } from '@stripe/stripe-js'
import { Container, Iban } from 'svelte-stripe-js'
let stripe = null
let name, email
let ibanElement
let clientSecret = '...' // the payment intent's clientSecret, should come from server
onMount(async () => {
stripe = await loadStripe(import.meta.env.VITE_STRIPE_PUBLIC_KEY)
})
async function submit() {
const result = await stripe.confirmSepaDebitPayment(
clientSecret,
{
payment_method: {
sepa_debit: ibanElement,
billing_details: {
name,
email,
},
},
}
)
// use result.paymentIntent
}
</script>
{#if stripe}
<Container {stripe}>
<form on:submit|preventDefault={submit}>
<input bind:value={name} placeholder="Name"/>
<input bind:value={email} placeholder="E-mail" type='email'/>
<Iban supportedCountries={['SEPA']} bind:element={ibanElement}/>
<button>Pay</button>
</form>
</Container>
{/if}
iDEAL
To accept iDEAL, add an <Ideal/>
component to your payment form:
<script>
import { onMount } from 'svelte'
import { loadStripe } from '@stripe/stripe-js'
import { Container, Ideal } from 'svelte-stripe-js'
let stripe = null
let name
let idealElement
let clientSecret = '...' // the payment intent's clientSecret, should come from server
onMount(async () => {
stripe = await loadStripe(import.meta.env.VITE_STRIPE_PUBLIC_KEY)
})
async function submit() {
const result = await stripe.confirmIdealPayment(
clientSecret,
{
payment_method: {
ideal: idealElement,
billing_details: {
name,
},
},
}
)
// use result.paymentIntent
}
</script>
{#if stripe}
<Container {stripe}>
<form on:submit|preventDefault={submit}>
<input bind:value={name} placeholder="Name"/>
<Ideal bind:element={idealElement}/>
<button>Pay</button>
</form>
</Container>
{/if}
License
MIT