ectoflow/vue-stripe-js

Example of working PaymentIntent

Closed this issue · 0 comments

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>