Skip to content

Commit bdaee96

Browse files
chore: wip
1 parent 4f714e4 commit bdaee96

File tree

3 files changed

+91
-107
lines changed

3 files changed

+91
-107
lines changed

resources/functions/billing/payments.ts

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -41,21 +41,23 @@ export function useBillable() {
4141
async function handleAddPaymentMethod(clientSecret: string, elements: any) {
4242
const param = {
4343
clientSecret,
44-
payment_method: {
44+
paymentMethod: {
4545
card: elements,
4646
billing_details: { name: 'Chris Breuer' },
4747
},
4848
};
4949

50-
const { setupIntent, error } = await confirmCardSetup(param)
5150

52-
if (error) {
53-
console.error(error.message)
54-
} // Display or handle error for the user
55-
else {
56-
if (!paymentStore.hasPaymentMethods)
57-
await paymentStore.setDefaultPaymentMethod(setupIntent.payment_method)
58-
}
51+
// const { setupIntent, error } =
52+
await confirmCardSetup(param)
53+
54+
// if (error) {
55+
// console.error(error.message)
56+
// } // Display or handle error for the user
57+
// else {
58+
// if (!paymentStore.hasPaymentMethods)
59+
// await paymentStore.setDefaultPaymentMethod(setupIntent.payment_method)
60+
// }
5961
}
6062

6163
function isEmpty(object: any) {
Lines changed: 43 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -1,95 +1,55 @@
11
<script setup lang="ts">
2-
import { ref } from 'vue'
2+
import { useBillable } from '../../../../functions/billing/payments'
33
4-
const cardNumber = ref('')
4+
const { loadPaymentElement, handleAddPaymentMethod } = useBillable()
5+
const paymentStore = usePaymentStore()
56
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)
149
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)
1812
19-
if (value.length > 2) {
20-
value = `${value.slice(0, 2)}/${value.slice(2)}`
21-
}
13+
element.value = await loadPaymentElement(paymentIntent.value)
14+
})
2215
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)
2420
}
2521
</script>
2622

2723
<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>
9432
</div>
9533
</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>

storage/framework/core/browser/src/utils/billlable.ts

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,40 +10,62 @@ interface PaymentMethod {
1010

1111
interface PaymentParam {
1212
clientSecret: string;
13-
payment_method: PaymentMethod;
13+
paymentMethod: PaymentMethod;
1414
}
1515

1616
export const publishableKey: string = import.meta.env.FRONTEND_STRIPE_PUBLIC_KEY || ''
1717

1818
const client = ref(null as any)
1919

20-
export async function loadCardElement(clientSecret: string): Promise<boolean> {
20+
export async function loadCardElement(clientSecret: string): Promise<any> {
2121
client.value = await loadStripe(publishableKey)
2222

2323
const elements = client.value.elements()
24-
const cardElement = elements.create('card')
24+
const cardElement = elements.create('card', {
25+
style: {
26+
base: {
27+
color: '#32325d',
28+
fontFamily: '"Poppins", sans-serif',
29+
fontSize: '16px',
30+
fontWeight: '500',
31+
'::placeholder': {
32+
color: '#aab7c4',
33+
},
34+
},
35+
invalid: {
36+
color: '#fa755a',
37+
},
38+
},
39+
})
2540

26-
cardElement.mount('#payment-element')
41+
cardElement.mount('#card-element')
42+
43+
return cardElement
44+
}
45+
46+
export async function loadPaymentElement(clientSecret: string): Promise<any> {
47+
client.value = await loadStripe(publishableKey)
48+
49+
const elements = client.value.elements()
50+
const cardElement = elements.create('payment')
2751

28-
if (client) {
29-
elements.value = client.value.elements({ clientSecret })
52+
cardElement.mount('#payment-element')
3053

31-
const paymentElement = elements.value.create('payment', {
32-
fields: { billingDetails: 'auto' },
33-
})
54+
elements.value = client.value.elements({ clientSecret })
3455

35-
paymentElement.mount('#payment-element')
56+
const paymentElement = elements.value.create('payment', {
57+
fields: { billingDetails: 'auto' },
58+
})
3659

37-
return true
38-
}
60+
paymentElement.mount('#payment-element')
3961

40-
return false
62+
return cardElement
4163
}
4264

4365
export async function confirmCardSetup(card: PaymentParam): Promise<{ setupIntent: any, error: any }> {
44-
const clientSecret = card.clientSecret
66+
console.log(card)
4567

46-
const { setupIntent, error } = await client.value.confirmCardSetup(card)
68+
const { setupIntent, error } = await client.value.confirmCardSetup(card.clientSecret, { payment_method: card.paymentMethod })
4769

4870
return { setupIntent, error }
4971
}

0 commit comments

Comments
 (0)