You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
CREATE OR REPLACEFUNCTIONapp_private.tg__user_stripe_customer_sync() RETURNS trigger AS
$$
DECLARE
stripe_customer app_private.stripe_customers;
BEGINSELECT*
INTO stripe_customer
FROMapp_private.stripe_customersWHERE user_id =new.id;
IF stripe_customer IS NULL
THEN
PERFORM graphile_worker.add_job('stripe__sync_customer', JSON_BUILD_OBJECT('id', new.id), 'stripe__customer_sync');
END IF;
RETURN new;
END;
$$ LANGUAGE plpgsql VOLATILE
SECURITY DEFINER
SET search_path TO pg_catalog, public, pg_temp;
DROPTRIGGER IF EXISTS _600_stripe_customer_sync ONapp_public.users;
CREATETRIGGER_600_stripe_customer_sync
BEFORE INSERT ORUPDATEONapp_public.users
FOR EACH ROW
EXECUTE PROCEDURE app_private.tg__user_stripe_customer_sync();
Worker
import{Task}from"graphile-worker";import{stripe}from"../utils";interfaceStripeSyncCustomerPayload{/** * user id */id: string;}consttask: Task=async(inPayload,{ addJob, withPgClient })=>{constpayload: StripeSyncCustomerPayload=inPayloadasany;const{id: userId}=payload;const{rows: [user],}=awaitwithPgClient((pgClient)=>pgClient.query<{name: string}>(`SELECT name FROM app_public.users WHERE id = $1`,[userId]));if(!user){throw"A user was not found";}const{rows: [userEmail],}=awaitwithPgClient((pgClient)=>pgClient.query<{email: string}>(` SELECT email FROM app_public.user_emails WHERE user_id = $1 ORDER BY user_emails.is_verified DESC, -- Prefer verified email user_emails.created_at ASC -- Failing that, prefer the first registered (unverified users _should_ verify before logging in) `,[userId]));constcreateStripeCustomerParams: {name: string;email?: string;metadata: Record<string,string>;}={name: user.name,metadata: { userId },};if(userEmail){createStripeCustomerParams.email=userEmail.email;}const{rows: [stripeCustomer],}=awaitwithPgClient((pgClient)=>pgClient.query("SELECT * FROM app_private.stripe_customers WHERE user_id=$1",[userId]));if(!stripeCustomer){constcustomer=awaitstripe.customers.create(createStripeCustomerParams);awaitwithPgClient((pgClient)=>pgClient.query(`INSERT INTO app_private.stripe_customers (user_id, stripe_id) VALUES ($1, $2)`,[userId,customer.id]));}else{console.log("Stripe update customer not implemented yet");}};module.exports=task;
Extended Stripe GraphQL schema
import{gql,makeExtendSchemaPlugin}from"graphile-utils";import{OurGraphQLContext}from"../middleware/postgraphile";importstripefrom"../utils/stripe";constStripePlugin=makeExtendSchemaPlugin((build)=>({typeDefs: gql` extend type User { """ Returns the stripe customers secret """ stripeClientSecret: String @requires(columns: ["id"]) } `,resolvers: {User: {asyncstripeClientSecret(user,_,context: OurGraphQLContext,resolveInfo){// console.log("user", user, context.pgClient);const{rows: stripeCustomers}=awaitcontext.rootPgPool.query<{stripe_id: string;}>("SELECT stripe_id FROM app_private.stripe_customers WHERE user_id = $1",[user.id]);conststripeCustomer=stripeCustomers?.[0];if(stripeCustomer){constsetupIntent=awaitstripe.setupIntents.create({customer: stripeCustomer.stripe_id,});returnsetupIntent.client_secret;}},},},}));exportdefaultPassportLoginPlugin;