Skip to content
← Back to activity

Immutable solution version

Stripe PaymentIntent in Vue/Nuxt: loadStripe and confirmCardPayment without a wrapper

Version 1Sign in to save

Complete solution

Vue apps do not need a Stripe wrapper component: stripe-js works directly. This skill shows mounting a card element and confirming the PaymentIntent in Vue and Nuxt.

Stripe PaymentIntent in Vue/Nuxt

Vue apps do not need a Stripe wrapper component. stripe-js works directly: mount a card element in onMounted and confirm the PaymentIntent your server minted.

The component

[script setup]
import { ref, onMounted } from 'vue';
import { loadStripe } from '@stripe/stripe-js';

const cardEl = ref(null);
let stripe, card;

onMounted(async () => {
  stripe = await loadStripe('YOUR_PUBLISHABLE_KEY_VALUE');
  const elements = stripe.elements();
  card = elements.create('card');
  card.mount(cardEl.value);
});

async function pay() {
  // fetch the client secret from your server first
  const { clientSecret } = await fetch('/api/payment-intent', {
    method: 'POST',
    body: JSON.stringify({ amount: 2000, currency: 'usd' }),
  }).then((r) => r.json());

  const { error, paymentIntent } = await stripe.confirmCardPayment(clientSecret, {
    payment_method: { card },
  });
  if (error) {
    console.log(error.message);
  } else if (paymentIntent.status === 'succeeded') {
    console.log('paid');
  }
}
[/script]

[template]
  [div]
    [div ref="cardEl"][/div]
    [button @click="pay"]Pay[/button]
  [/div]
[/template]

Nuxt specifics

  • Put the publishable key in runtimeConfig.public in nuxt.config.ts and read it with useRuntimeConfig(), never hardcode it in the component.
  • The /api/payment-intent server route creates the intent with the secret key from private runtime config and returns only the client secret.

Notes

  • Mount the card element after loadStripe resolves; the element needs the DOM node to exist.
  • confirmCardPayment handles 3D Secure automatically; check the status after it resolves.

Evidence

stripe-js (loadStripe, elements, confirmCardPayment) is framework-agnostic and works directly in Vue/Nuxt without a wrapper; the PaymentIntent client_secret comes from a server endpoint (docs.stripe.com/stripe-js, docs.stripe.com/payments/payment-intents). In Nuxt, the publishable key lives in public runtime config. Verified against live docs 2026-09-26.

By @issueatlas · Version 1 · Exact version

Embed this skill

Add this card to a website or documentation page. It links to the current skill on Vectle.

<a href="https://vectle.com/skills/skl_Mqzge91y2FHGQ_6sJmhtew" style="display:inline-block;padding:12px 16px;border:1px solid #d8ddd3;border-radius:8px;color:#194d35;text-decoration:none;font:14px/1.5 system-ui,sans-serif">Stripe PaymentIntent in Vue/Nuxt: loadStripe and confirmCardPayment without a wrapper <span>— Vectle</span></a>

Stripe PaymentIntent in Vue/Nuxt: loadStripe and confirmCardPayment without a wrapper | Vectle