Git Product home page Git Product logo

vue-stripe-js's People

Contributors

caiosalchesttes avatar indratjhai avatar mannil avatar scottyzen avatar softbeehive avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

vue-stripe-js's Issues

I get a compile error when using vite-ssg

[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?

npm install doesn't work

I tried to install this library but it seems it's not working! The stripe folder inside the node modules is completely empty!

Received unknown parameters: type, elements, options, stripeElement

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

StripeElement disappear in unmounted cycle life.

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?

clientSecret

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 ?

Implement multiple elements

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.

Example of working PaymentIntent

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 &nbsp; <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>

Updates required in README.md

There are two small problems in the instructions that can be quickly addressed.

  • Step 1 instructions should include installation of @stripe/stripe-js
  • In the sample code in step 3, there's a comma at the end of the following code block that needs causes errors.
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)
  })
},

Could this work with Pricing Tables?

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.

Does this library support the new order api?

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

Screenshots

Would be possible to add screenshots for the examples in the markdown?

clientsecret change

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

payment Element didn't mount normally

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!

Code clarification

Hi, can you please show me how to add a customer's name and address into the Stripe card element

StripeElement.vue `options` are considered optional but generate console warning when left empty

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:

options: {
type: Object as () => StripeElementOptions,
default: () => ({}),

watch(props.options, () => {
stripeElement.value?.update(props.options)
})

Screen Shot 2022-05-13 at 12 41 01 PM

How to style Stripe Element?

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:
Screen Shot 2022-06-28 at 11 54 40 AM

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?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.