vue-stripe-js

repository·main·Indexed 41 days ago

https://github.com/ectoflow/vue-stripe-js

Vue 3 components for Stripe.js that provide a reactive wrapper for building payment integrations, including support for Nuxt 3. Version 2.0.2 features a shift to ES modules and a focus on the Payment Element.

Tokens
5.2K
Snippets
20
Records
21
Agent score
43%

What's inside vue-stripe-js

  1. Styling Stripe elements

    main

    You can style Stripe elements in two ways:

    1. CSS Classes: Add standard CSS classes directly to the StripeElements or StripeElement components.
    2. Options Object: Pass a style object via the component's :options prop to customize the internal appearance (e.g., base, invalid).
    <!-- Using CSS classes -->
    <StripeElements class="border">
      <StripeElement class="p-4" type="card" :options="cardOptions" />
    </StripeElements>
    
    <script setup>
    // Using options object
    const cardOptions = ref({
      style: {
        base: {
          iconColor: "green",
        },
        invalid: {
          iconColor: "red",
        },
      },
    });
    </script>
  2. Upgrade from v1 to v2

    main

    Upgrading to v2.0.0 involves a shift towards ES modules.

    Critical Requirement: This version has removed CommonJS exports and added npm type module. If your project relies on require instead of import, do not upgrade to v2, as Vite and other modern tools are moving away from CommonJS support.

    Key Changes in v2:

    • The Payment Element is now the new default.
    • Improved TypeScript support.
    • Backward compatibility is maintained for most old implementations.
    npm install vue-stripe-js@latest
  3. Simplify StripeElement usage by removing slot props

    main

    In v2, you no longer need to manually pass elements via slot props from <StripeElements> to <StripeElement>. The library now uses provide/inject internally to handle this automatically.

    <!-- Before v2 -->
    <StripeElements v-slot="{ elements, instance }">
      <StripeElement :elements="elements" />
    </StripeElements>
    
    <!-- v2 Recommended Pattern -->
    <StripeElements>
      <StripeElement type="card" />
    </StripeElements>
  4. Load Stripe.js in a Vue component

    main

    You need to initialize Stripe.js using the loadStripe function from @stripe/stripe-js. It is recommended to do this within the onBeforeMount lifecycle hook to ensure the instance is available before the component is fully mounted. Alternatively, you can include Stripe.js via a script tag in your HTML, ensuring it loads before your Vue components.

    <script setup lang="ts">
    import { onBeforeMount, ref } from "vue"
    import { loadStripe, type Stripe } from "@stripe/stripe-js"
    
    const publishableKey = '' // use your publishable key
    const stripe = ref<Stripe | null>(null)
    
    onBeforeMount(async() => {
      stripe.value = await loadStripe(publishableKey)
    })
    </script>
  5. Run the vue-stripe-js demo locally

    main

    To explore the capabilities of vue-stripe-js including Payment Element, Card, and Express Checkout integrations, you can run the official demo project by cloning the repository and using npm.

    # 1. Clone the repository
    git clone git@github.com:ectoflow/vue-stripe-js.git --depth=1 && cd vue-stripe-js
    
    # 2. Install dependencies
    npm install
    
    # 3. Start the development server
    npm run dev
  6. Implement the Payment Element (Deferred Payment)

    main

    The Payment Element allows you to collect payment details securely. This implementation follows the deferred payment pattern:

    1. Wrap StripeElement inside StripeElements.
    2. Use StripeElements to manage the lifecycle and configuration (mode, amount, currency).
    3. Use StripeElement with type="payment" to render the UI.
    4. Access the underlying Stripe instance and elements via component refs (elementsComponent.value.instance and elementsComponent.value.elements) to call confirmPayment.
    <template>
      <form v-if="stripeLoaded" @submit.prevent="handleSubmit">
        <StripeElements
          :stripe-key="stripeKey"
          :instance-options="stripeOptions"
          :elements-options="elementsOptions"
          ref="elementsComponent"
        >
          <StripeElement
            type="payment"
            :options="paymentElementOptions"
            ref="paymentComponent"
          />
        </StripeElements>
        <button type="submit">Submit</button>
      </form>
    </template>
    
    <script setup lang="ts">
    import { onBeforeMount, ref } from "vue"
    import { loadStripe } from "@stripe/stripe-js"
    import { StripeElements, StripeElement } from "vue-stripe-js"
    import type { StripeElementsOptionsMode, StripePaymentElementOptions } from "@stripe/stripe-js"
    
    const stripeKey = "pk_test_..."
    const stripeOptions = ref({})
    const elementsOptions = ref<StripeElementsOptionsMode>({
      mode: "payment",
      amount: 1099,
      currency: "usd",
      appearance: { theme: "flat" },
    })
    const paymentElementOptions = ref<StripePaymentElementOptions>({})
    const stripeLoaded = ref(false)
    const clientSecret = ref("")
    
    const elementsComponent = ref()
    const paymentComponent = ref()
    
    onBeforeMount(() => {
      loadStripe(stripeKey).then(() => {
        stripeLoaded.value = true
      })
    })
    
    async function handleSubmit() {
      const stripeInstance = elementsComponent.value?.instance
      const elements = elementsComponent.value?.elements
    
      if (stripeInstance) {
        const { error } = await stripeInstance.confirmPayment({
          elements,
          clientSecret: clientSecret.value,
          confirmParams: {
            return_url: "https://example.com/order/123/complete",
          },
        })
    
        if (error) {
          console.log(error)
        }
      }
    }
    </script>
  7. Available StripeElement types

    main

    When using the StripeElement component, you must specify a type prop. The following types are supported:

    type StripeElementType =
      | "address"
      | "affirmMessage"
      | "afterpayClearpayMessage"
      | "auBankAccount"
      | "card"
      | "cardNumber"
      | "cardExpiry"
      | "cardCvc"
      | "currencySelector"
      | "epsBank"
      | "expressCheckout"
      | "fpxBank"
      | "iban"
      | "idealBank"
      | "p24Bank"
      | "payment"
      | "paymentMethodMessaging"
      | "paymentRequestButton"
      | "linkAuthentication"
      | "shippingAddress"
      | "issuingCardNumberDisplay"
      | "issuingCardCvcDisplay"
      | "issuingCardExpiryDisplay"
      | "issuingCardPinDisplay"
      | "issuingCardCopyButton";
  8. Create Elements with createElements()

    main

    Use createElements to create a StripeElements instance. This instance is required to manage the lifecycle of individual Stripe Elements.

    It accepts a Stripe instance and an optional StripeElementsOptions object. The options can include a clientSecret (for Payment Intents) or other configuration modes.

    import { createElements } from 'vue-stripe-js';
    
    // Assuming 'stripe' is an initialized Stripe instance
    const elements = createElements(stripe, { clientSecret: 'secret_abc123' });
  9. Initialize Stripe with initStripe()

    main

    Use initStripe to initialize the Stripe instance using your publishable key. This function expects window.Stripe to be available (either via a script tag or loaded via @stripe/stripe-js).

    Returns a Stripe instance or undefined if initialization fails.

    import { initStripe } from 'vue-stripe-js';
    
    const stripe = initStripe('pk_test_your_key');