Skip to content

Commit

Permalink
moved payment controller
Browse files Browse the repository at this point in the history
  • Loading branch information
andre-brandao committed Aug 16, 2024
1 parent 3780cd1 commit c3c72d0
Show file tree
Hide file tree
Showing 8 changed files with 163 additions and 76 deletions.
2 changes: 2 additions & 0 deletions src/lib/server/db/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@ export { image } from './schema/image/controller'
export { bugReport } from './schema/bug-report/controller'

export { customer } from './schema/customer/controller'

export { stripeController as stripe } from './schema/stripe/controller'
5 changes: 2 additions & 3 deletions src/lib/server/db/schema/index.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
// USER
export * from './user'

// IMAGE
export * from './image'

// PRODUCT
export * from './product'

// BUG-REPORT
export * from './bug-report'

export * from './stock'

export * from './push-notification'

export * from './customer'

export * from './stripe'
51 changes: 51 additions & 0 deletions src/lib/server/db/schema/stripe/controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { stripeCheckoutSessionTable, type InsertCheckoutSession } from '.'
import { db } from '$db'

import { and, eq } from 'drizzle-orm'

async function processStripeOrder(sessionId: string) {
const [sessionDB] = await getStripeOrderFromID(sessionId)
if (!sessionDB) {
return
}

if (sessionDB.credited) {
return
}

await db.update(stripeCheckoutSessionTable).set({
credited: true,
})
}

function insertCheckoutSession(session: InsertCheckoutSession) {
return db.insert(stripeCheckoutSessionTable).values(session)
}

function getStripeOrderFromID(sessionId: string) {
return db
.select()
.from(stripeCheckoutSessionTable)
.where(eq(stripeCheckoutSessionTable.id, sessionId))
.limit(1)
}

function getPendingCheckoutSessionFromUserID(userId: string) {
return db
.select()
.from(stripeCheckoutSessionTable)
.where(
and(
eq(stripeCheckoutSessionTable.userId, userId),
eq(stripeCheckoutSessionTable.credited, false),
eq(stripeCheckoutSessionTable.expired, false),
),
)
}

export const stripeController = {
processStripeOrder,
insertCheckoutSession,
getStripeOrderFromID,
getPendingCheckoutSessionFromUserID,
}
29 changes: 29 additions & 0 deletions src/lib/server/db/schema/stripe/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import {
sqliteTable,
text,
integer,

// customType,
} from 'drizzle-orm/sqlite-core'
import { userTable } from '../user'

export const stripeCheckoutSessionTable = sqliteTable(
'stripe_checkout_session',
{
id: text('id').notNull().primaryKey(),
userId: text('user_id')
.notNull()
.references(() => userTable.id, {
onDelete: 'set null',
}),

geopoints: integer('geopoints').notNull(),
stripe_json: text('stripe_json', { mode: 'json' }).notNull(),
credited: integer('credited', { mode: 'boolean' }).notNull().default(false),
expiresAt: integer('expires_at', { mode: 'timestamp' }).notNull(),
expired: integer('expired', { mode: 'boolean' }).notNull().default(false),
},
)

export type InsertCheckoutSession =
typeof stripeCheckoutSessionTable.$inferInsert
52 changes: 2 additions & 50 deletions src/lib/server/db/schema/user/controller.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { eq, and } from 'drizzle-orm'
import { eq } from 'drizzle-orm'
import { db } from '$db'
import {
type InsertUser,
Expand All @@ -9,9 +9,7 @@ import {
type UserPermissions,
type SelectUser,
sessionTable,
stripeCheckoutSessionTable,
type InsertCheckoutSession,
DEFAULT_PERMISSIONS
DEFAULT_PERMISSIONS,
} from '$db/schema'

import { TimeSpan, createDate, isWithinExpirationDate } from 'oslo'
Expand All @@ -20,7 +18,6 @@ import type { User } from 'lucia'
import { encodeHex } from 'oslo/encoding'
import { generateIdFromEntropySize } from 'lucia'


function getUserByUsername(username: string) {
return db
.select()
Expand Down Expand Up @@ -182,49 +179,4 @@ export const user = {
getMagicLinkToken,
deleteMagicLinkToken,
DEFAULT_PERMISSIONS,
getPendingCheckoutSessionFromUserID,
insertCheckoutSession,
getStripeOrderFromID,
processStripeOrder,
}

async function processStripeOrder(sessionId: string) {
const [sessionDB] = await getStripeOrderFromID(sessionId)
if (!sessionDB) {
return
}

if (sessionDB.credited) {
return
}


await db.update(stripeCheckoutSessionTable).set({
credited: true,
})
}

function insertCheckoutSession(session: InsertCheckoutSession) {
return db.insert(stripeCheckoutSessionTable).values(session)
}

function getStripeOrderFromID(sessionId: string) {
return db
.select()
.from(stripeCheckoutSessionTable)
.where(eq(stripeCheckoutSessionTable.id, sessionId))
.limit(1)
}

function getPendingCheckoutSessionFromUserID(userId: string) {
return db
.select()
.from(stripeCheckoutSessionTable)
.where(
and(
eq(stripeCheckoutSessionTable.userId, userId),
eq(stripeCheckoutSessionTable.credited, false),
eq(stripeCheckoutSessionTable.expired, false),
),
)
}
21 changes: 0 additions & 21 deletions src/lib/server/db/schema/user/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,24 +89,3 @@ export const magicLinkTable = sqliteTable('magic_link', {
email: text('email').notNull(),
expiresAt: integer('expires_at', { mode: 'timestamp' }).notNull(),
})

export const stripeCheckoutSessionTable = sqliteTable(
'stripe_checkout_session',
{
id: text('id').notNull().primaryKey(),
userId: text('user_id')
.notNull()
.references(() => userTable.id, {
onDelete: 'set null',
}),

geopoints: integer('geopoints').notNull(),
stripe_json: text('stripe_json', { mode: 'json' }).notNull(),
credited: integer('credited', { mode: 'boolean' }).notNull().default(false),
expiresAt: integer('expires_at', { mode: 'timestamp' }).notNull(),
expired: integer('expired', { mode: 'boolean' }).notNull().default(false),
},
)

export type InsertCheckoutSession =
typeof stripeCheckoutSessionTable.$inferInsert
74 changes: 74 additions & 0 deletions src/routes/api/stripe/webhook/+server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import type { RequestHandler } from './$types'

export const GET: RequestHandler = async () => {
return new Response()
}
import { error, json } from '@sveltejs/kit'
import { env } from '$env/dynamic/private'
import { stripe } from '$lib/server/stripe'

// endpoint to handle incoming webhooks
export const POST: RequestHandler = async ({ request }) => {
// extract body
const body = await request.text()

// get the signature from the header
const signature = request.headers.get('stripe-signature')

if (!signature) {
// signature is missing
console.warn('⚠️ Webhook signature missing.')

// return, because it's a bad request
throw error(400, 'Invalid request')
}

if (!env.STRIPE_WEBHOOK_SECRET) {
// webhook secret is missing
console.warn('⚠️ Webhook secret missing.')

// return, because it's a bad request
throw error(400, 'Invalid request')
}

// var to hold event data
let event

// verify it
try {
event = stripe.webhooks.constructEvent(
body,
signature,
env.STRIPE_WEBHOOK_SECRET,
)
} catch (err) {
// signature is invalid!
console.warn('⚠️ Webhook signature verification failed.', err)

// return, because it's a bad request
throw error(400, 'Invalid request')
}

// signature has been verified, so we can process events
// full list of events: https://stripe.com/docs/api/events/list

switch (event.type) {
case 'charge.succeeded': {
const charge = event.data.object
console.log(`✅ Charge succeeded ${charge.id}`)
break
}
case 'checkout.session.completed': {
const session = event.data.object
console.log(`✅ Checkout session completed ${session.id}`)
break
}

default:
// unhandled event
console.log(`🤷‍♂️ Unhandled event type: ${event.type}`)
break
}
// return a 200 with an empty JSON response
return json({})
}
5 changes: 3 additions & 2 deletions src/trpc/routes/stripe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import { middleware } from '../middleware'
import { TRPCError } from '@trpc/server'
import { stripe } from '$lib/server/stripe'

import { user as userController } from '$lib/server/db/controller'
// import { user as userController } from '$lib/server/db/controller'
import { stripe as stripeControler } from '$lib/server/db/controller'

export const checkout = router({
createCheckoutSession: publicProcedure
Expand Down Expand Up @@ -68,7 +69,7 @@ export const checkout = router({
console.log(session)

const geoPoints = items[0].quantity
await userController.insertCheckoutSession({
await stripeControler.insertCheckoutSession({
id: session.id,
userId: user.id,
expiresAt: new Date(session.expires_at),
Expand Down

0 comments on commit c3c72d0

Please sign in to comment.