|
1 | 1 | <script setup lang="ts">
|
2 |
| -import { ref } from 'vue' |
| 2 | +import { useBillable } from '../../../../functions/billing/payments' |
3 | 3 |
|
4 |
| -const cardNumber = ref('') |
| 4 | +const { loadPaymentElement, handleAddPaymentMethod } = useBillable() |
| 5 | +const paymentStore = usePaymentStore() |
5 | 6 |
|
6 |
| -function formatCardNumber(e: Event) { |
7 |
| - const input = e.target as HTMLInputElement |
8 |
| - let value = input.value.replace(/\D/g, '') |
9 |
| - value = value.replace(/(.{4})/g, '$1 ').trim() |
10 |
| - cardNumber.value = value |
11 |
| -} |
12 |
| -
|
13 |
| -const expiryDate = ref('') |
| 7 | +const paymentIntent = ref('') |
| 8 | +const element = ref(null as any) |
14 | 9 |
|
15 |
| -function formatExpiryDate(e: Event) { |
16 |
| - const input = e.target as HTMLInputElement |
17 |
| - let value = input.value.replace(/\D/g, '') |
| 10 | +onMounted( async () => { |
| 11 | + paymentIntent.value = await paymentStore.fetchSetupIntent(1) |
18 | 12 |
|
19 |
| - if (value.length > 2) { |
20 |
| - value = `${value.slice(0, 2)}/${value.slice(2)}` |
21 |
| - } |
| 13 | + element.value = await loadPaymentElement(paymentIntent.value) |
| 14 | +}) |
22 | 15 |
|
23 |
| - expiryDate.value = value.slice(0, 5) |
| 16 | +async function addPaymentMethod() { |
| 17 | + // console.log(paymentIntent.value) |
| 18 | + // console.log(element.value) |
| 19 | + await handleAddPaymentMethod(paymentIntent.value, element.value) |
24 | 20 | }
|
25 | 21 | </script>
|
26 | 22 |
|
27 | 23 | <template>
|
28 |
| - <div class="flex items-center justify-center bg-gray-50 px-4 py-8 lg:px-8 sm:px-6"> |
29 |
| - <div class="max-w-md w-full space-y-8"> |
30 |
| - <div> |
31 |
| - <h2 class="text-center text-3xl text-gray-900 font-extrabold"> |
32 |
| - Payment Form |
33 |
| - </h2> |
34 |
| - <p class="mt-2 text-center text-sm text-gray-600"> |
35 |
| - Enter your card details below |
36 |
| - </p> |
37 |
| - </div> |
38 |
| - <form id="payment-form" class="mt-8 rounded-lg bg-white p-6 shadow-md space-y-6"> |
39 |
| - <div> |
40 |
| - <label for="card-number" class="block text-sm text-gray-700 font-medium">Card Number</label> |
41 |
| - <input |
42 |
| - id="card-number" |
43 |
| - v-model="cardNumber" |
44 |
| - type="text" |
45 |
| - maxlength="19" |
46 |
| - placeholder="4242 4242 4242 4242" |
47 |
| - class="mt-1 block w-full border border-gray-300 rounded-lg px-4 py-2 shadow-sm focus:border-indigo-500 sm:text-sm focus:ring-indigo-500" |
48 |
| - @input="formatCardNumber" |
49 |
| - > |
50 |
| - </div> |
51 |
| - <div class="grid grid-cols-2 gap-4"> |
52 |
| - <div> |
53 |
| - <label for="expiry-date" class="block text-sm text-gray-700 font-medium">Expiry Date</label> |
54 |
| - <input |
55 |
| - id="expiry-date" |
56 |
| - v-model="expiryDate" |
57 |
| - type="text" |
58 |
| - maxlength="5" |
59 |
| - placeholder="MM/YY" |
60 |
| - class="mt-1 block w-full border border-gray-300 rounded-lg px-4 py-2 shadow-sm focus:border-indigo-500 sm:text-sm focus:ring-indigo-500" |
61 |
| - @input="formatExpiryDate" |
62 |
| - > |
63 |
| - </div> |
64 |
| - <div> |
65 |
| - <label for="cvc" class="block text-sm text-gray-700 font-medium">CVC</label> |
66 |
| - <input |
67 |
| - id="cvc" |
68 |
| - type="text" |
69 |
| - maxlength="3" |
70 |
| - placeholder="CVC" |
71 |
| - class="mt-1 block w-full border border-gray-300 rounded-lg px-4 py-2 shadow-sm focus:border-indigo-500 sm:text-sm focus:ring-indigo-500" |
72 |
| - required |
73 |
| - > |
74 |
| - </div> |
75 |
| - </div> |
76 |
| - |
77 |
| - <div class="mt-6 flex justify-between space-x-4"> |
78 |
| - <button |
79 |
| - type="button" |
80 |
| - class="w-full border border-gray-300 rounded-lg bg-white px-4 py-2 text-sm text-gray-700 font-medium shadow-sm hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500" |
81 |
| - > |
82 |
| - Cancel |
83 |
| - </button> |
84 |
| - |
85 |
| - <button |
86 |
| - type="submit" |
87 |
| - class="w-full rounded-lg bg-indigo-600 px-4 py-2 text-sm text-white font-medium shadow-sm hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500" |
88 |
| - > |
89 |
| - Save Payment Method |
90 |
| - </button> |
91 |
| - </div> |
92 |
| - </form> |
93 |
| - </div> |
| 24 | + <div> |
| 25 | + <form |
| 26 | + id="payment-form" |
| 27 | + > |
| 28 | + <div id="link-authentication-element" /> |
| 29 | + <div id="card-element" /> |
| 30 | + <button @click="addPaymentMethod" type="button" class="rounded bg-indigo-600 w-full px-2 py-1 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">Save Payment Method</button> |
| 31 | + </form> |
94 | 32 | </div>
|
95 | 33 | </template>
|
| 34 | + |
| 35 | +<style> |
| 36 | +#payment-message { |
| 37 | + color: rgb(105, 115, 134); |
| 38 | + font-size: 16px; |
| 39 | + line-height: 20px; |
| 40 | + padding-top: 12px; |
| 41 | + text-align: center; |
| 42 | +} |
| 43 | +
|
| 44 | +#payment-element { |
| 45 | + margin-bottom: 24px; |
| 46 | +} |
| 47 | +
|
| 48 | +#payment-form { |
| 49 | + width: 30vw; |
| 50 | + min-width: 500px; |
| 51 | + align-self: center; |
| 52 | + border-radius: 7px; |
| 53 | + padding: 40px; |
| 54 | +} |
| 55 | +</style> |
0 commit comments