ectoflow / vue-stripe-js Goto Github PK
View Code? Open in Web Editor NEWVue 3 components for Stripe.js
License: MIT License
Vue 3 components for Stripe.js
License: MIT License
[Vue Router warn]: uncaught error during route navigation:
file:///Users/nn/Work/mf-products/.vite-ssg-temp/assets/index-df334bb5.js:15
import { StripeElements, StripeElement } from "vue-stripe-js";
^^^^^^^^^^^^^
SyntaxError: Named export 'StripeElement' not found. The requested module 'vue-stripe-js' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:
import pkg from 'vue-stripe-js';
const { StripeElements, StripeElement } = pkg;
Can you please take a look at this and let me know what's the work-around until fixed?
Is it possible to use Themes with this component? https://stripe.com/docs/stripe-js/appearance-api#theme
Hi,
How can I use this library to use Payment Element instead of Card Element? Any sample code would be highly appreciated.
Thank you
Bill
I tried to install this library but it seems it's not working! The stripe folder inside the node modules is completely empty!
const cardNumber = ref<StripeCardNumberElement>();
elms.value.instance.confirmCardPayment(clientSecret.value, {
payment_method: {
billing_details: {
...
},
card: cardNumber.value,
}
});
When I run this code I receive a 400 on the /confirm endpoint of the stripe API.
Received unknown parameters: type, elements, options, stripeElement
I have the StripeElement inside a Modal which is shown/hidden with v-if so when the Modal disappears before the modal gets destroyed, the StripeElement disappears causing some stage behavior.. is there a way to avoid or delay the StripeElement disappearing before the parent component is destroyed?
I used your Card only example. According to the doc, the clientSecret value from the PaymentIntent object is used in the elements Options (it's even required).
Unfortunately, your component provides this warning :
Unrecognized create() parameter: clientSecret is not a recognized parameter. This may cause issues with your integration in the future.
I use this parameter this way :
const elementsOptions = ref({
clientSecret: 'pi_1DrNBJ2eZvKYlo2CXQCh5Pwi_secret_wx8kjhsOZnAz6axvBPGFXUww7',
})
Either I miss something about the paymentIntent secret key here, or there's some misunderstanding about the options.
Could you update the example by specifying where you input your intent secret key ?
Hi there, I have a question about how to implement multiple elements.
I have a form with three Stripe elements: cardNumber, cardExpiry, and cardCvc. When the user submits the form, I need to retrieve the values entered by the user in these Stripe elements to fill the payment_method card object before sending it to Stripe for payment confirmation.
I've tried using the stripeElement property of each element reference to retrieve the values, but I'm not sure how to properly format the card object to send it with the confirmCardPayment method.
Here's my example code:
<template>
<stripe-elements
v-if="stripeLoaded"
v-slot="{ elements }"
ref="elms"
:stripe-key="stripeKey"
class="stripe-elements"
>
<stripe-element
ref="cardNumber"
type="cardNumber"
:elements="elements"
:options="cardNumberOptions"
/>
<stripe-element
ref="cardExpiry"
type="cardExpiry"
:elements="elements"
:options="elementOptions"
/>
<stripe-element
ref="cardCvc"
type="cardCvc"
:elements="elements"
:options="elementOptions"
/>
</stripe-elements>
</template>
<script setup>
const cardNumber = ref();
const cardExpiry = ref();
const cardCvc = ref();
const elms = ref();
const confirmPayment = async () => {
try {
// get stripe element
const cardNumberElement = cardNumber.value.stripeElement;
const cardExpiryElement = cardExpiry.value.stripeElement;
const cardCvcElement = cardCvc.value.stripeElement;
// confirming the payment.
await elms.value.instance
.confirmCardPayment(state.clientSecret, {
payment_method: {
// https://stripe.com/docs/api/payment_methods/create?lang=node#create_payment_method-card
card: {
number: cardNumberElement (?),
exp_month: cardExpiryElement (?),
exp_year: cardExpiryElement (?),
cvc: cardCvcElement (?),
},
},
})
.then((result) => {
console.log("result", result);
});
} catch (error) {
console.error("Error creating subscription", error);
throw error;
};
};
</script>
Can someone help me with how to properly implement multiple elements and fill the card object? Thanks.
Its taken me a lot of time to pull together something working with PaymentIntent. Attached is my working code. I hope if will save some time for others...
<template>
<div>
<div class="mt-3 text-center sm:mt-5">
<DialogTitle
as="h3"
class="text-lg font-medium leading-6 text-gray-900"
>
Secure Payment Portal
</DialogTitle>
<div class="mt-2">
<p class="text-sm text-gray-500">Complete payment form to submit <span
class="uppercase">{{ $filters.formatMoney(charge, currency) }}</span> deposit for the {{
sssusername
}} account</p>
</div>
</div>
</div>
<form id="payment-form">
<div class="mt-3 text-center sm:mt-5"
>
<hr/>
<StripeElements
v-if="stripeLoaded && (clientSecret != null)"
v-slot="{ elements }"
ref="elms"
:stripe-key="props.publishedKey"
:instance-options="instanceOptions"
:elements-options="elementsOptions"
>
<StripeElement
type="payment"
ref="card"
:elements="elements"
:options="cardOptions"
/>
</StripeElements>
<div v-else class="mt-2">
<LockClosedIcon class="text-green-300 w-full p-8"/>
</div>
<hr/>
<div class="mt-5 sm:mt-6"
v-show="stripeLoaded && (clientSecret != null)"
>
<button type="submit" @click="pay"
class="inline-flex w-full justify-center rounded-md bg-indigo-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600">
Process <span class="uppercase">{{ $filters.formatMoney(charge, currency) }}</span>
</button>
</div>
</div>
</form>
</template>
<script setup>
import {onBeforeMount, onMounted, ref} from 'vue'
import {StripeElement, StripeElements} from "vue-stripe-js";
import {loadStripe} from "@stripe/stripe-js";
import {DialogTitle} from "@headlessui/vue";
import {LockClosedIcon} from "@heroicons/vue/24/solid";
onMounted(() => {
axios.post(urlClientSecret, {
sssusername: props.sssusername, // custom subaccount metadata for paymentIntent
currency: props.currency,
charge: props.charge,
}).then(response => {
clientSecret.value = response["data"]["clientSecret"];
}).catch(error => {
console.log(error)
})
})
//================================================================================================
onBeforeMount(() => {
// alert(props.publishedKey); // dz this is the correct value.
const stripePromise = loadStripe(props.publishedKey)
stripePromise.then(() => {
stripeLoaded.value = true
})
})
const props = defineProps({
publishedKey: String,
charge: Number,
currency: String,
baseurl: String,
sssusername: String,
});
// const urlInitiate = props.baseurl + "payment/initiate";
// const urlSuccess = props.baseurl + "payment/success";
// const urlFailure = props.baseurl + "payment/failure";
const urlClientSecret = props.baseurl + "payment/cs";
const clientSecret = ref(null);
//===================================================================
// https://github.com/ectoflow/vue-stripe-js/blob/main/examples/CardOnly.vue
const instanceOptions = ref({
// https://stripe.com/docs/js/initializing#init_stripe_js-options
})
const elementsOptions = ref({
clientSecret: clientSecret, // This is where the payment intent get's attached.
// https://stripe.com/docs/js/elements_object/create#stripe_elements-options
})
const cardOptions = ref({
// https://stripe.com/docs/stripe.js#element-options
// value: {
// postalCode: '12345',
// },
})
const stripeLoaded = ref(false)
const card = ref()
const elms = ref()
const pay = () => {
// Get stripe element
const cardElement = card.value.stripeElement
// Access instance methods, e.g. createToken()
elms.value.instance.createToken(cardElement).then((result) => {
// Handle result.error or result.token
alert(JSON.stringify(result));
console.log(result);
})
}
</script>
There are two small problems in the instructions that can be quickly addressed.
const pay = () => { // Get stripe element const cardElement = card.value.stripeElement // Access instance methods, e.g. createToken() elms.value.instance.createToken(cardElement).then((result: object) => { // Handle result.error or result.token console.log(result) }) },
Currently, I'm trying to get Pricing Tables to display, but having a tough time.
Could you implement a way to display Pricing Tables provided by Stripe and their generated embed code?
<script async src="https://js.stripe.com/v3/pricing-table.js"></script>
<stripe-pricing-table pricing-table-id="prctbl_..." publishable-key="pk_test_...">
</stripe-pricing-table>
Though it seems like it should be intuitive, I don't know how to make the <stripe-pricing-table>
work.
Found const = pay () => {
instead of const pay = () => {
in step 3 of docs in README.md file.
Dont seem to know whats wrong. I cant seem to get it to work no matter what i try
<template>
<div>
<StripeElements v-slot="{ elements, instance }" ref="paymentElements"
:stripe-key="appStateStore.clientSettings!.stripePublishableKey" :instance-options="instanceOptions"
:elements-options="elementsOptions">
<StripeElement ref="payment" type="payment" :elements="elements" />
</StripeElements>
<v-btn @click="pay">Pay</v-btn>
</div>
</template>
<script setup lang="ts">
import { loadStripe } from '@stripe/stripe-js'
import { StripeElement, StripeElements, initStripe } from 'vue-stripe-js'
const s = await loadStripe(
useAppStateStore().clientSettings!.stripePublishableKey,
{
betas: ['process_order_beta_1'],
apiVersion: "2020-08-27; orders_beta=v4",
}
);
const paymentElements = ref<any>();
const pay = async () => {
const v = paymentElements.value!;
console.log(v.elements);
try {
const res = await s!.processOrder({
elements: v.elements,
confirmParams: {
// Return URL where the customer should be redirected after the Order's payment is confirmed.
return_url: 'http://localhost:3001/order/123/status',
},
})
console.log('RESULT');
console.log(res);
} catch (e) {
console.log('ERROR');
console.log(e);
}
}
</script>
LOGS
ERROR
{}
Put all the relevant code in. Anything that is used but not defined there is custom way of getting whats needed so didnt put it in. The order is successfully submitting (200ok) but is not passing the payment method and is throwon gan error with an empty error message
Would be possible to add screenshots for the examples in the markdown?
Hi, actually it is not a issue but i just want to take your opinion. I really need help.
in my project there is promotion codes
when payment page opens i take clientSecret from backend and with that clientsecret stripeelements form loads.
when user applies promotion this process repeats(i take another clientsecret from backend)
my first question is: is this process correct what do you think?
second question is: for now i cant update client secret after promotion how can i change it?
i tried
this.$refs.elms.elements.update({
clientSecret: this.elementsOptions.clientSecret,
});
this one but it only takes upgrade 1 times (for example user applied promotion and delete promotion afterwards) when user clicks buy. It take the discounted price
if i give :key to stripeelements component form reloads and everything works fine but i dont know is it a good solution or not
Hi there,
Trying to use this library to add a payment element and I keep running into this error: "payment Element didn't mount normally". Do you have any guidance on what might cause this?
Many thanks!
Hi, can you please show me how to add a customer's name and address into the Stripe card element
When creating the <StripeElement>
component, the options
prop is considered optional, but it generates an "Invalid watch source" console warning due to a watch()
being supplied with a plain object instance via its default value:
vue-stripe-js/src/components/StripeElement.vue
Lines 33 to 35 in ca1f828
vue-stripe-js/src/components/StripeElement.vue
Lines 85 to 87 in ca1f828
I think I'm misunderstanding how the options transfer to the actual Stripe elements themselves or something. This is what it looks like without any options on page load:
Here's how my component looks currently:
<template>
<StripeElements
v-if="stripeLoaded"
v-slot="{ elements }"
ref="elms"
:stripe-key="stripeKey"
:instance-options="instanceOptions"
:elements-options="elementsOptions">
<StripeElement
ref="card"
:elements="elements"
:options="cardOptions" />
</StripeElements>
<q-btn
color="primary"
@click="pay">
Pay
</q-btn>
</template>
<script lang='ts' setup>
import { onBeforeMount, ref } from 'vue';
import { loadStripe } from '@stripe/stripe-js';
import { StripeElements, StripeElement } from 'vue-stripe-js';
import type { StripeConstructorOptions, StripeElementsOptions } from '@stripe/stripe-js';
import { colors } from 'quasar';
const stripeKey = ref(import.meta.env.VITE_STRIPE_PUBLIC_KEY);
const stripeLoaded = ref(false);
const card = ref();
const elms = ref();
const instanceOptions = ref<StripeConstructorOptions>({
// https://stripe.com/docs/js/initializing#init_stripe_js-options
});
const elementsOptions = ref<StripeElementsOptions>({
fonts: [{ cssSrc: 'https://fonts.googleapis.com/css2?family=Lato' }],
locale: 'auto',
appearance: {
// theme: 'stripe',
variables: {
colorPrimary: colors.getPaletteColor('primary'),
colorText: '#f00',
},
},
loader: 'auto',
// https://stripe.com/docs/js/elements_object/create#stripe_elements-options
});
const cardOptions = ref({
// https://stripe.com/docs/stripe.js#element-options
// value: {
// postalCode: '12345',
// },
});
const pay = () => {
// Get stripe element
const cardElement = card.value.stripeElement;
// Access instance methods, e.g. createToken()
elms.value.instance.createToken(cardElement)
.then((result: object) => {
// Handle result.error or result.token
console.log(result);
});
};
onBeforeMount(() => {
const stripePromise = loadStripe(stripeKey.value);
stripePromise.then(() => {
stripeLoaded.value = true;
});
});
</script>
I am receiving a console warning: Unrecognized create() parameter: appearance is not a recognized parameter.
What's the proper way to go about styling?
EDIT: I noticed that at the very bottom of the README, that it's supposed to be unstyled, and to visit the docs for Element Options to handle styling. I'm trying out everything, however I'm still receiving console warnings about unrecognized parameters?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.