Skip to content

Commit

Permalink
Sync subscription manually on login and billing page
Browse files Browse the repository at this point in the history
  • Loading branch information
yunusefendi52 committed Jan 21, 2025
1 parent 5626e9d commit 3a0627e
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 12 deletions.
25 changes: 18 additions & 7 deletions pages/signin.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
<div class="w-full flex justify-center" style="color-scheme: auto;">
<GoogleSignInButton @success="handleLoginSuccess" @error="handleLoginError"></GoogleSignInButton>
</div>
<ProgressSpinner v-if="isLoggingIn" style="width: 40px; height: 40px; margin: unset;" strokeWidth="4"
class="self-center" />
</div>
</div>
</template>
Expand All @@ -24,21 +26,30 @@ import {
GoogleSignInButton,
type CredentialResponse,
} from "vue3-google-signin";
import ProgressSpinner from 'primevue/progressspinner';
function handleSuccessSignIn(r: { param: string } | undefined) {
if (r) {
location.href = `/?${r.param}`
}
}
const isLoggingIn = ref(false)
const handleLoginSuccess = async (response: CredentialResponse) => {
const r = await $fetch('/api/auth/sign-in-google', {
method: 'post',
body: {
token: response.credential,
},
})
handleSuccessSignIn(r)
try {
isLoggingIn.value = true
const r = await $fetch('/api/auth/sign-in-google', {
method: 'post',
body: {
token: response.credential,
},
})
handleSuccessSignIn(r)
} finally {
isLoggingIn.value = false
}
}
const handleLoginError = () => {
Expand Down
26 changes: 24 additions & 2 deletions server/api/auth/sign-in-google.post.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { isNull } from "drizzle-orm"
import type { EventHandlerRequest, H3Event } from "h3"
import * as jose from 'jose'
import { syncUserSubscription } from "../billing/subscription-sync"

const alg = 'HS256'

Expand All @@ -18,10 +19,29 @@ export default defineEventHandler(async event => {
message: 'Invalid payload sign in google',
})
}
const userId = payload.sub!
const name = payload['name'] as string
const email = payload['email'] as string
const { token: userToken } = await generateUserToken(event, 'google', userId, email, name)
const { token: userToken, appUserId, pUserId } = await generateUserToken(event, 'google', payload.sub!, email, name)
const userSubLms = await getUserSubscriptionLms(email)
if (userSubLms) {
const subAttrs = userSubLms.attributes
await syncUserSubscription(event, appUserId, pUserId, userSubLms.id, {
card_brand: subAttrs.card_brand || undefined,
created_at: subAttrs.created_at,
customer_id: subAttrs.customer_id,
ends_at: subAttrs.ends_at,
product_id: subAttrs.product_id,
product_name: subAttrs.product_name,
renews_at: subAttrs.renews_at,
status: subAttrs.status,
status_formatted: subAttrs.status_formatted,
updated_at: subAttrs.updated_at,
user_email: subAttrs.user_email,
user_name: subAttrs.user_name,
variant_id: subAttrs.variant_id,
variant_name: subAttrs.variant_name,
})
}
signInUser(event, userToken)
const param = new URLSearchParams({
usr: userToken,
Expand Down Expand Up @@ -88,6 +108,8 @@ export const generateUserToken = async (
.sign(getJwtKey(event))
return {
token,
pUserId: userId,
appUserId: appUserId,
}
}

Expand Down
27 changes: 27 additions & 0 deletions server/api/billing/current-billing.get.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,33 @@
import { defineEventHandler } from 'h3'
import { syncUserSubscription } from './subscription-sync'

export default defineEventHandler(async event => {
const userSubLms = await getUserSubscriptionLms(event.context.auth.email!)
if (userSubLms) {
const subAttrs = userSubLms.attributes
const db = event.context.drizzle
const user = await db.select()
.from(tables.users)
.where(eq(tables.users.id, event.context.auth.userId))
.then(takeUniqueOrThrow)
await syncUserSubscription(event, user.id, user.providerUserId!, userSubLms.id, {
card_brand: subAttrs.card_brand || undefined,
created_at: subAttrs.created_at,
customer_id: subAttrs.customer_id,
ends_at: subAttrs.ends_at,
product_id: subAttrs.product_id,
product_name: subAttrs.product_name,
renews_at: subAttrs.renews_at,
status: subAttrs.status,
status_formatted: subAttrs.status_formatted,
updated_at: subAttrs.updated_at,
user_email: subAttrs.user_email,
user_name: subAttrs.user_name,
variant_id: subAttrs.variant_id,
variant_name: subAttrs.variant_name,
})
}

const productPlan = await getProductPlan()
var userSub = await getUserSubFromDb(event)
// https://github.com/lmsqueezy/lemonsqueezy.js/blob/b1f66e905ee0614be87c3711d6529f2582e5729f/src/subscriptions/types.ts#L159-L167
Expand Down
3 changes: 1 addition & 2 deletions server/api/billing/subscription-sync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,10 +125,9 @@ export type SubscriptionSyncData = {
user_email: string;
status: string;
status_formatted: string;
card_brand: string;
card_brand: string | undefined;
renews_at: string | undefined;
ends_at: string | null;
created_at: string;
updated_at: string;
subscription_id: number | undefined;
}
1 change: 1 addition & 0 deletions server/middleware/auth-middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export default defineEventHandler(async (event) => {
} else {
const userId = verifiedData.payload.sub
const email = verifiedData.payload.email as string | undefined
const provider = verifiedData.payload.provider as string
event.context.auth = {
userId: userId!,
email: email,
Expand Down
24 changes: 23 additions & 1 deletion server/utils/lemonsqueezy-utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { getSubscription, getVariant, lemonSqueezySetup } from "@lemonsqueezy/lemonsqueezy.js"
import { getSubscription, getVariant, lemonSqueezySetup, listSubscriptions } from "@lemonsqueezy/lemonsqueezy.js"

export function getProductVariandId() {
return getLsTestMode() ? process.env.NUXT_LEMONSQUEEZY_VARIANT_ID_TEST! : process.env.NUXT_LEMONSQUEEZY_VARIANT_ID_PROD!
Expand Down Expand Up @@ -47,3 +47,25 @@ export async function getUrlsSubscription(subscriptionId: string) {
updatePaymentMethod: data?.data.attributes.urls.update_payment_method,
}
}

export async function getUserSubscriptionLms(userEmail: string) {
// this will get latest subscription
const userSubs = await listSubscriptions({
filter: {
productId: process.env.NUXT_LEMONSQUEEZY_PRODUCT_ID_TEST!,
storeId: process.env.NUXT_LEMONSQUEEZY_STORE_ID!,
userEmail: userEmail
},
page: {
size: 1
}
});
if (userSubs.error) {
throw createError({
message: userSubs.error.message,
statusCode: 500
});
}
const data = userSubs.data?.data;
return data && data.length ? data[0] : undefined;
}

0 comments on commit 3a0627e

Please sign in to comment.