Basic Stripe integration. new pages for stripe handshake and new Account page. use query instead of useQuery for trpc fetches from store
This commit is contained in:
31
pages/account.vue
Normal file
31
pages/account.vue
Normal file
@@ -0,0 +1,31 @@
|
||||
<script setup lang="ts">
|
||||
import { storeToRefs } from 'pinia';
|
||||
const store = useAppStore();
|
||||
const { activeMembership } = storeToRefs(store);
|
||||
const config = useRuntimeConfig();
|
||||
|
||||
function formatDate(date: Date | undefined){
|
||||
if(!date){ return ""; }
|
||||
return new Intl.DateTimeFormat('default', {dateStyle: 'long'}).format(date);
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<div>
|
||||
<h3>Account</h3>
|
||||
<p>Name: {{ activeMembership?.account.name }}</p>
|
||||
<p>Current Period Ends: {{ formatDate(activeMembership?.account.current_period_ends) }}</p>
|
||||
<p>Permitted Features: {{ activeMembership?.account.features }}</p>
|
||||
<p>Maximum Notes: {{ activeMembership?.account.max_notes }}</p>
|
||||
<p>Access Level: {{ activeMembership?.access }}</p>
|
||||
|
||||
<template v-if="config.public.debugMode">
|
||||
<p>******* Debug *******</p>
|
||||
<p>Account ID: {{ activeMembership?.account.id }}</p>
|
||||
<p>Plan Id: {{ activeMembership?.account.plan_id }}</p>
|
||||
<p>Stripe Subscription Id: {{ activeMembership?.account.stripe_subscription_id }}</p>
|
||||
<p>Stripe Customer Id: {{ activeMembership?.account.stripe_customer_id }}</p>
|
||||
<p>Membership Id: {{ activeMembership?.id }}</p>
|
||||
<p>User Id: {{ activeMembership?.user_id }}</p>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
9
pages/cancel.vue
Normal file
9
pages/cancel.vue
Normal file
@@ -0,0 +1,9 @@
|
||||
<template>
|
||||
<div>
|
||||
<p>
|
||||
We are sorry that you canceled your transaction!
|
||||
<NuxtLink to="/pricing">Pricing</NuxtLink>
|
||||
<NuxtLink to="/dashboard">To Your Dashboard</NuxtLink>
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
@@ -8,9 +8,6 @@
|
||||
const store = useAppStore();
|
||||
const { notes } = storeToRefs(store); // ensure the notes list is reactive
|
||||
|
||||
onMounted(async () => {
|
||||
await store.initUser();
|
||||
})
|
||||
</script>
|
||||
<template>
|
||||
<div>
|
||||
|
||||
9
pages/fail.vue
Normal file
9
pages/fail.vue
Normal file
@@ -0,0 +1,9 @@
|
||||
<template>
|
||||
<div>
|
||||
<p>
|
||||
We are sorry that you were unable to subscribe.
|
||||
<NuxtLink to="/pricing">Pricing</NuxtLink>
|
||||
<NuxtLink to="/dashboard">To Your Dashboard</NuxtLink>
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
28
pages/pricing.vue
Normal file
28
pages/pricing.vue
Normal file
@@ -0,0 +1,28 @@
|
||||
<script setup lang="ts">
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { ACCOUNT_ACCESS } from '@prisma/client';
|
||||
|
||||
const store = useAppStore()
|
||||
const { activeMembership } = storeToRefs(store);
|
||||
|
||||
</script>
|
||||
<template>
|
||||
<div>
|
||||
<h3>Pricing</h3>
|
||||
<form action="/create-checkout-session" method="POST">
|
||||
<label for="submit">Individual Plan, Normal Price</label>
|
||||
<input type="hidden" name="price_id" value="price_1MfaKVJfLn4RhYiLgruKo89E" />
|
||||
<input type="hidden" name="account_id" :value="activeMembership?.account_id" />
|
||||
|
||||
<button type="submit" :disabled="!activeMembership || (activeMembership.access !== ACCOUNT_ACCESS.OWNER && activeMembership.access !== ACCOUNT_ACCESS.ADMIN)">Checkout</button>
|
||||
</form>
|
||||
|
||||
<form action="/create-checkout-session" method="POST">
|
||||
<label for="submit">Team Plan, Normal Price</label>
|
||||
<input type="hidden" name="price_id" value="price_1MfaM6JfLn4RhYiLPdr1OTDS" />
|
||||
<input type="hidden" name="account_id" :value="activeMembership?.account_id" />
|
||||
|
||||
<button type="submit" :disabled="!activeMembership || (activeMembership.access !== ACCOUNT_ACCESS.OWNER && activeMembership.access !== ACCOUNT_ACCESS.ADMIN)">Checkout</button>
|
||||
</form>
|
||||
</div>
|
||||
</template>
|
||||
23
pages/success.vue
Normal file
23
pages/success.vue
Normal file
@@ -0,0 +1,23 @@
|
||||
<script setup lang="ts">
|
||||
import Stripe from 'stripe';
|
||||
const config = useRuntimeConfig();
|
||||
const stripe = new Stripe(config.stripeSecretKey, { apiVersion: '2022-11-15' });
|
||||
const route = useRoute();
|
||||
let customer: Stripe.Response<Stripe.Customer | Stripe.DeletedCustomer>
|
||||
try{
|
||||
const session = await stripe.checkout.sessions.retrieve(route?.query?.session_id as string);
|
||||
customer = await stripe.customers.retrieve(session?.customer as string);
|
||||
} catch(e) {
|
||||
console.log(`Error ${e}`)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<p>
|
||||
<span v-if="!customer.deleted">We appreciate your business {{customer.name}}!</span>
|
||||
<span v-if="customer.deleted">It appears your stripe customer information has been deleted!</span>
|
||||
</p>
|
||||
<p><NuxtLink to="/dashboard">To Your Dashboard</NuxtLink></p>
|
||||
</div>
|
||||
</template>
|
||||
Reference in New Issue
Block a user