6 Commits

Author SHA1 Message Date
OllyNicholass c47c933ce1 refactor(#22): add PP with @jcreek
Breaking version of customer stripe sync
2024-07-23 20:53:03 +01:00
Josh Creek 4d80534244 feat(#22): Hi Olly 2024-07-16 20:23:22 +01:00
Josh Creek 18772364f7 feat(#22): Add handling for sign up db events 2024-07-16 20:01:03 +01:00
Josh Creek 0539afb16e feat(#22): Add todo comment and strong typing 2024-07-16 19:46:32 +01:00
Josh Creek ef3abfe396 feat(#22): Add handling for customer.updated event 2024-07-16 19:16:49 +01:00
Josh Creek 7bf05b35a6 feat(#22): Add handling for customer.created event 2024-07-16 19:13:36 +01:00
6 changed files with 136 additions and 41 deletions
+57 -7
View File
@@ -1,7 +1,11 @@
<script lang="ts">
import { createEventDispatcher } from 'svelte';
import { general } from '$lib/stores/generalStore.js';
import stripe from 'stripe';
import { PUBLIC_STRIPE_SECRET_KEY } from '$env/static/public';
const stripeClient = new stripe(PUBLIC_STRIPE_SECRET_KEY);
const dispatch = createEventDispatcher();
function emitSignedInEvent() {
@@ -13,16 +17,62 @@
// Access the supabase client from the layout data
export let supabase: any;
export let session: any;
async function signInWithEmail() {
// TODO use the data and error from the response
const { data, error } = await supabase.auth
.signInWithPassword({
try {
// Sign in with email and password
const { data, error } = await supabase.auth.signInWithPassword({
email: email,
password: password
password: password,
});
if (error) {
console.error('Sign in error:', error.message);
return;
}
// Emit signed-in event
emitSignedInEvent();
// Check if the session data is available
if (data && data.session && data.session.user) {
const userId = data.session.user.id;
// Create Stripe customer
await createStripeCustomer(userId);
} else {
console.error('User session data is missing');
}
// Log data for debugging purposes
console.log(data);
} catch (err) {
console.error('Unexpected error:', err);
}
}
async function createStripeCustomer(userId: string) {
console.log('createStripeCustomer');
await stripeClient.customers
.create({
email
})
.then(() => {
emitSignedInEvent();
.then(async (customer) => {
// Create a new customer in the database customers table with id data.user.id and stripe_customer_id customer.id
const { dataFromUpsert, error } = await supabase.from('customers').upsert([
{
id: userId,
stripe_customer_id: customer.id
}
]);
console.log(dataFromUpsert);
if (error) {
throw error;
}
});
}
+20 -31
View File
@@ -1,44 +1,14 @@
<script lang="ts">
import stripe from 'stripe';
import { PUBLIC_STRIPE_SECRET_KEY } from '$env/static/public';
let email = '';
let password = '';
// Access the supabase client from the layout data
export let supabase: any;
const stripeClient = new stripe(PUBLIC_STRIPE_SECRET_KEY);
async function signUpNewUser() {
try {
const { data, error } = await supabase.auth.signUp({
email: email,
password: password,
options: {
// Redirect URL after successful sign-up
redirectTo: '/account'
}
});
if (error) {
throw error;
}
const customer = await stripeClient.customers.create({
email
});
const response = await supabase
.from('user')
.update({
customer_id: customer.id
})
.match({
id: data.user.id
});
console.log(response);
await supabaseSignUp();
// Handle success (optional)
} catch (error: any) {
@@ -46,6 +16,25 @@
// Handle error
}
}
async function supabaseSignUp() {
console.log('supabaseSignUp');
const { data, error } = await supabase.auth.signUp({
email: email,
password: password,
options: {
// Redirect URL after successful sign-up
redirectTo: '/account'
}
});
console.log(data);
if (error) {
throw error;
}
return data;
}
</script>
<form class="card-body">
+9 -2
View File
@@ -155,8 +155,15 @@ const createOrRetrieveCustomer = async ({ email, uuid }: { email: string; uuid:
console.warn(`Supabase customer record was missing. A new record was created.`);
// If Supabase has no record, create a new record and return Stripe customer ID
const upsertedStripeCustomer = await upsertCustomerToSupabase(uuid, stripeIdToInsert);
if (!upsertedStripeCustomer) throw new Error('Supabase customer record creation failed.');
try {
const upsertedStripeCustomer = await upsertCustomerToSupabase(uuid, stripeIdToInsert);
if (!upsertedStripeCustomer) throw new Error('Supabase customer record creation failed.');
return upsertedStripeCustomer;
} catch (error) {
console.error(`Supabase customer record creation failed: ${error}`);
return null;
}
return upsertedStripeCustomer;
}
+1 -1
View File
@@ -147,7 +147,7 @@
<div
class="mt-3 z-[1] p-2 shadow menu menu-sm dropdown-content bg-base-100 text-base-content rounded-box min-w-[13rem] w-auto"
>
<SignIn {supabase} />
<SignIn {supabase} {session} />
</div>
{/if}
</div>
+9
View File
@@ -3,6 +3,7 @@ import stripe from 'stripe';
import { PUBLIC_STRIPE_SECRET_KEY } from '$env/static/public';
import { PUBLIC_STRIPE_ENDPOINT_SECRET } from '$env/static/public';
import {
createOrRetrieveCustomer,
deletePriceRecord,
deleteProductRecord,
manageSubscriptionStatusChange,
@@ -54,6 +55,14 @@ export const POST: RequestHandler = async ({ request }) => {
case 'product.deleted':
await deleteProductRecord(event.data.object as stripe.Product);
break;
// case 'customer.created':
// case 'customer.updated':
// // TODO - this should be passing the supabase customer uuid not the stripe customer id
// await createOrRetrieveCustomer({
// email: (event.data.object as stripe.Customer).email!,
// uuid: event.data.object.id
// });
// break;
case 'customer.subscription.created':
case 'customer.subscription.updated':
case 'customer.subscription.deleted': {
@@ -0,0 +1,40 @@
-- TESTS FOR RLS policy
create policy "Enable update for users based on id"
on "public"."customers"
as permissive
for update
to public
using ((( SELECT auth.uid() AS uid) = id))
with check ((( SELECT auth.uid() AS uid) = id));
create policy "Enable insert for users based on id"
on "public"."customers"
as permissive
for insert
to public
with check ((( SELECT auth.uid() AS uid) = id));
create policy "DEMO Enable insert for users based on id"
on "public"."customers"
as permissive
for insert
to public
with check (true);
create policy "DEMO Enable update for users based on id"
on "public"."customers"
as permissive
for update
to public
using (true)
with check (true);
GRANT USAGE ON SCHEMA public TO anon, authenticated, service_role;
GRANT ALL ON ALL TABLES IN SCHEMA public TO anon, authenticated, service_role;
GRANT ALL ON ALL ROUTINES IN SCHEMA public TO anon, authenticated, service_role;
GRANT ALL ON ALL SEQUENCES IN SCHEMA public TO anon, authenticated, service_role;
ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public GRANT ALL ON TABLES TO anon, authenticated, service_role;
ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public GRANT ALL ON ROUTINES TO anon, authenticated, service_role;
ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public GRANT ALL ON SEQUENCES TO anon, authenticated, service_role;