Example of working PaymentIntent
Closed this issue · 0 comments
helloadmin commented
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>