Skip to content

Commit 8525b51

Browse files
chore: wip
1 parent 6ae81a3 commit 8525b51

File tree

4 files changed

+99
-109
lines changed

4 files changed

+99
-109
lines changed

.stacks/core/payments/src/drivers/stripe.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
import Stripe from 'stripe';
22

3-
import { services } from '@stacksjs/config'
4-
5-
const apiKey = services.stripe?.apiKey ?? ''
3+
const apiKey = ''
64

75
const stripe = new Stripe(apiKey, {
86
apiVersion: '2023-08-16',
97
});
108

11-
9+
// TODO: learn about subscriptions
1210
export const paymentIntent = function() {
1311
async function create(params: Stripe.PaymentIntentCreateParams) {
1412
return await stripe.paymentIntents.create(params);
@@ -27,7 +25,7 @@ export const paymentIntent = function() {
2725
}
2826

2927
return { create, retrieve, update, cancel }
30-
}
28+
}()
3129

3230
export const balance = function(){
3331
async function retrieve() {

.stacks/stacks/dashboard/src/components/Navbar.vue

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -152,13 +152,12 @@ watch(theme, (currentVal) => {
152152
role="menuitem"
153153
tabindex="-1"
154154
>Teams</a>
155-
<a
156-
id="user-menu-item-0"
157-
href="#"
155+
<router-link
156+
to="/settings/billing"
158157
class="block px-3 py-1 text-sm leading-6 text-gray-500 dark-hover:bg-gray-600 hover:bg-blue-gray-50 hover:text-blue-gray-600 dark:text-gray-300"
159158
role="menuitem"
160159
tabindex="-1"
161-
>Settings</a>
160+
>Billing Settings</router-link>
162161
<a
163162
id="user-menu-item-0"
164163
href="#"

.stacks/stacks/dashboard/src/layouts/default.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<script setup lang="ts">
2+
23
import Sidebar from '../components/Sidebar.vue'
34
import MobileSidebar from '../components/MobileSidebar.vue'
45
import Navbar from '../components/Navbar.vue'
Lines changed: 92 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,62 @@
11
<script setup lang="ts">
2+
import { paymentIntent } from '../../../../../core/payments/src/drivers/stripe'
23
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+
};
360
</script>
461

562
<template>
@@ -39,115 +96,28 @@ import SettingsHeader from '../../components/SettingsHeader.vue'
3996

4097
<button
4198
type="button"
99+
@click="payPlan()"
42100
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"
43101
>
44102
Change Plan
45103
</button>
46104
</div>
47105
</div>
48106

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-->
83111
</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-->
117114
</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>
151121
</div>
152122
</div>
153123

@@ -213,3 +183,25 @@ import SettingsHeader from '../../components/SettingsHeader.vue'
213183
</div>
214184
</div>
215185
</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

Comments
 (0)