1
1
<script setup lang="ts">
2
+ import { paymentIntent } from ' ../../../../../core/payments/src/drivers/stripe'
2
3
import SettingsHeader from ' ../../components/SettingsHeader.vue'
4
+ import { loadStripe } from ' @stripe/stripe-js' ;
5
+ import type { Stripe } from ' @stripe/stripe-js' ;
6
+ import { ref } from ' vue'
7
+
8
+
9
+ let elements;
10
+
11
+ const loading = ref (true );
12
+
13
+ // TODO: learn about subscriptions
14
+ async function initialize() {
15
+ const stripe: Stripe = await loadStripe (' ' );
16
+
17
+ // const items = [{ id: 'stacks-monthly-sub' }]
18
+
19
+ const response = await paymentIntent .create ({
20
+ amount: calculateOrderAmount (),
21
+ currency: " usd" ,
22
+ automatic_payment_methods: {
23
+ enabled: true ,
24
+ },
25
+ })
26
+
27
+ const clientSecret: string | null = response .client_secret
28
+
29
+ elements = stripe .elements ({
30
+ clientSecret ,
31
+ });
32
+
33
+ // const linkAuthenticationElement = elements.create("linkAuthentication");
34
+ // linkAuthenticationElement.mount("#link-authentication-element");
35
+
36
+ // linkAuthenticationElement.on('change', (event) => {
37
+ // emailAddress = event.value.email;
38
+ // });
39
+
40
+ const paymentElementOptions = {
41
+ layout: " tabs" ,
42
+ };
43
+
44
+ const paymentElement = elements .create (" payment" , paymentElementOptions );
45
+ paymentElement .mount (" #payment-element" );
46
+
47
+ loading .value = false
48
+ }
49
+
50
+ async function payPlan() {
51
+ await initialize ()
52
+ }
53
+
54
+ const calculateOrderAmount = () => {
55
+ // Replace this constant with a calculation of the order's amount
56
+ // Calculate the order total on the server to prevent
57
+ // people from directly manipulating the amount on the client
58
+ return 2000 ;
59
+ };
3
60
</script >
4
61
5
62
<template >
@@ -39,115 +96,28 @@ import SettingsHeader from '../../components/SettingsHeader.vue'
39
96
40
97
<button
41
98
type =" button"
99
+ @click =" payPlan()"
42
100
class =" rounded-md ml-4 bg-blue-600 px-2.5 py-1.5 text-sm font-semibold text-white shadow-sm hover:bg-blue-gray-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-600"
43
101
>
44
102
Change Plan
45
103
</button >
46
104
</div >
47
105
</div >
48
106
49
- <div class =" bg-white shadow-md px-8 py-6 rounded-md w-2/3" >
50
- <h2 class =" text-lg font-medium text-gray-900" >
51
- Payment
52
- </h2 >
53
-
54
- <fieldset class =" mt-4" >
55
- <legend class =" sr-only" >
56
- Payment type
57
- </legend >
58
- <div class =" space-y-4 sm:flex sm:items-center sm:space-x-10 sm:space-y-0" >
59
- <div class =" flex items-center" >
60
- <input
61
- id =" credit-card"
62
- name =" payment-type"
63
- type =" radio"
64
- class =" h-4 w-4 border-gray-300 text-blue-600 focus:ring-blue-500"
65
- >
66
- <label
67
- for =" credit-card"
68
- class =" ml-3 block text-sm font-medium text-gray-700"
69
- >Credit card</label >
70
- </div >
71
- <div class =" flex items-center" >
72
- <input
73
- id =" paypal"
74
- name =" payment-type"
75
- type =" radio"
76
- class =" h-4 w-4 border-gray-300 text-blue-600 focus:ring-blue-500"
77
- >
78
- <label
79
- for =" paypal"
80
- class =" ml-3 block text-sm font-medium text-gray-700"
81
- >PayPal</label >
82
- </div >
107
+ <div v-show =" !loading" class =" bg-white shadow-md px-8 py-6 rounded-md w-2/3" >
108
+ <form id =" payment-form" >
109
+ <div id =" link-authentication-element" >
110
+ <!-- Stripe.js injects the Link Authentication Element-->
83
111
</div >
84
- </fieldset >
85
-
86
- <div class =" mt-6 grid grid-cols-4 gap-x-4 gap-y-6" >
87
- <div class =" col-span-4" >
88
- <label
89
- for =" card-number"
90
- class =" block text-sm font-medium text-gray-700"
91
- >Card number</label >
92
- <div class =" mt-1" >
93
- <input
94
- id =" card-number"
95
- type =" text"
96
- name =" card-number"
97
- autocomplete =" cc-number"
98
- class =" block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 sm:text-sm"
99
- >
100
- </div >
101
- </div >
102
-
103
- <div class =" col-span-4" >
104
- <label
105
- for =" name-on-card"
106
- class =" block text-sm font-medium text-gray-700"
107
- >Name on card</label >
108
- <div class =" mt-1" >
109
- <input
110
- id =" name-on-card"
111
- type =" text"
112
- name =" name-on-card"
113
- autocomplete =" cc-name"
114
- class =" block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 sm:text-sm"
115
- >
116
- </div >
112
+ <div id =" payment-element" >
113
+ <!-- Stripe.js injects the Payment Element-->
117
114
</div >
118
-
119
- <div class =" col-span-3" >
120
- <label
121
- for =" expiration-date"
122
- class =" block text-sm font-medium text-gray-700"
123
- >Expiration date (MM/YY)</label >
124
- <div class =" mt-1" >
125
- <input
126
- id =" expiration-date"
127
- type =" text"
128
- name =" expiration-date"
129
- autocomplete =" cc-exp"
130
- class =" block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 sm:text-sm"
131
- >
132
- </div >
133
- </div >
134
-
135
- <div >
136
- <label
137
- for =" cvc"
138
- class =" block text-sm font-medium text-gray-700"
139
- >CVC</label >
140
- <div class =" mt-1" >
141
- <input
142
- id =" cvc"
143
- type =" text"
144
- name =" cvc"
145
- autocomplete =" csc"
146
- class =" block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 sm:text-sm"
147
- >
148
- </div >
149
- </div >
150
- </div >
115
+ <button class =" primary-button" id =" submit" >
116
+ <div class =" spinner hidden" id =" spinner" ></div >
117
+ <span id =" button-text" >Pay now</span >
118
+ </button >
119
+ <div id =" payment-message" class =" hidden" ></div >
120
+ </form >
151
121
</div >
152
122
</div >
153
123
@@ -213,3 +183,25 @@ import SettingsHeader from '../../components/SettingsHeader.vue'
213
183
</div >
214
184
</div >
215
185
</template >
186
+
187
+ <style >
188
+ #payment-message {
189
+ color : rgb (105 , 115 , 134 );
190
+ font-size : 16px ;
191
+ line-height : 20px ;
192
+ padding-top : 12px ;
193
+ text-align : center ;
194
+ }
195
+
196
+ #payment-element {
197
+ margin-bottom : 24px ;
198
+ }
199
+
200
+ #payment-form {
201
+ width : 30vw ;
202
+ min-width : 500px ;
203
+ align-self : center ;
204
+ border-radius : 7px ;
205
+ padding : 40px ;
206
+ }
207
+ </style >
0 commit comments