skip to Main Content

I would like to integrate stripe to charge a user a one-time 20$ payment after successfully completing a form in my Vue3 application. I’ve integrated vue-stripe-js and have been able to obtain a token from stripe using the card element in that package, but have been unable to handle submitting the charge to stripe.

Here’s the request so far:

    const pay = () => {
      const cardElement = card.value.stripeElement

      elms.value.instance.createToken(cardElement).then((result) => {
        if (result.token) {
          // what should I do with the token to submit a charge for $20 and see it in my stripe dashboard?
          console.log(result.token)
        }
      })
    }

The ideal solution would show me what to do with the token to submit a payment and validate that the other fields in the form have been inputted before the payment is completed. Here’s a stackblitz that approximates the problem, thanks so much for sharing your knowledge.

2

Answers


  1. Unfortunately the library you’re using is old and only uses the CardElement and tokens which is no longer Stripe’s recommended integration path, and soon all token-based integrations will be deprecated(today only cards are still supported). As you can see in https://docs.stripe.com/sdks/community, Stripe recommends using vue-stripe.

    As for the integration flow that suits best your use-case, I recommend looking at the deferred flow and just replacing the front-end part with the vue-stripe components.

    Login or Signup to reply.
  2. When integrating stripe in Vue 3, I did not use a vue-specific stripe library. I used @stripe/stripe-js version 2.2.0. I did the following steps:

    I created a composable with the following functions and refs

    import { loadStripe as loadStripeLibrary, Stripe, StripeCardElement } from '@stripe/stripe-js';
    
    const isStripeLoaded = ref(false);
    const stripe = ref<Stripe | null>(null);
    const paymentIntent = ref<PaymentIntent>();
    const clientSecret = ref('');
    
    export function useBilling() {
      return {
        isStripeLoaded,
        stripe,
        paymentIntent,
        loadStripe,
        loadPaymentIntent,
        createStripeCardUIElement,
        createPaymentMethod,
        submitCardInformation,
      };
    }
    
    async function loadStripe() {
      try {
        if (isStripeLoaded.value && stripe.value !== null) {
          return;
        }
        stripe.value = await loadStripeLibrary(publishableKey);
        isStripeLoaded.value = true;
      } catch (error) {
        console.error(error);
      }
    }
    
    async function loadPaymentIntent(): Promise<void> {
      const response = await axios.get<PaymentIntent>(`/my-intent-url`);
      paymentIntent.value = response.data;
    }
    
    async function createPaymentMethod(
      createDto,
    ) {
      // call to create my record of the payment method
    }
    
    function createStripeCardUIElement() {
      clientSecret.value = paymentIntent.value?.client_secret ?? '';
      return stripe.value?.elements({ clientSecret: paymentIntent.value?.client_secret }).create('card');
    }
    
    async function submitCardInformation(cardElement: StripeCardElement) {
      return stripe.value?.confirmCardSetup(clientSecret.value, {
        payment_method: {
          card: cardElement,
        },
      });
    }
    
    

    Then inside my component

    const stripeCreditCardNumberPlaceholder = ref<HTMLDivElement>();
    const cardElement = ref<StripeCardElement>();
    
    async function setupStripe() {
      await loadStripe();
      await loadPaymentIntent();
      createStripeUiElement();
    }
    
    // This causes Stripe to inject its UI elements into the template
    function createStripeUiElement(): void {
      if (stripeCreditCardNumberPlaceholder.value !== undefined) {
        cardElement.value = createStripeCardUIElement();
        cardElement.value?.mount(stripeCreditCardNumberPlaceholder.value);
      }
    }
    
    onMounted(setupStripe);
    

    with simply

    <div ref="stripeCreditCardNumberPlaceholder" />
    

    in the template.

    I was then just able to use the stripe ref to access all the library’s methods, and in my case to submit a setup intent and then handle its response.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search