mirror of
https://github.com/lukevella/rallly.git
synced 2025-07-07 11:37:26 +02:00
🐛 Fix licensing checkout and webhook (#1731)
This commit is contained in:
parent
518b66aa9a
commit
3ae7f7e021
7 changed files with 30 additions and 31 deletions
|
@ -46,15 +46,8 @@ if (env.LICENSE_API_AUTH_TOKEN) {
|
|||
}),
|
||||
),
|
||||
async (c) => {
|
||||
const {
|
||||
type,
|
||||
seats,
|
||||
expiresAt,
|
||||
licenseeEmail,
|
||||
licenseeName,
|
||||
version,
|
||||
stripeCustomerId,
|
||||
} = c.req.valid("json");
|
||||
const { type, seats, expiresAt, licenseeEmail, licenseeName, version } =
|
||||
c.req.valid("json");
|
||||
|
||||
try {
|
||||
const license = await prisma.license.create({
|
||||
|
@ -67,7 +60,6 @@ if (env.LICENSE_API_AUTH_TOKEN) {
|
|||
expiresAt,
|
||||
licenseeEmail,
|
||||
licenseeName,
|
||||
stripeCustomerId,
|
||||
},
|
||||
});
|
||||
return c.json({
|
||||
|
|
|
@ -63,6 +63,7 @@ export async function GET(request: NextRequest) {
|
|||
success_url: "https://rallly.co/licensing/thank-you",
|
||||
metadata: {
|
||||
licenseType: type,
|
||||
version: 4,
|
||||
seats,
|
||||
} satisfies LicenseCheckoutMetadata,
|
||||
});
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { env } from "@/env";
|
||||
import { licensingClient } from "@/features/licensing/client";
|
||||
import { licenseCheckoutMetadataSchema } from "@/features/licensing/schema";
|
||||
import { subscriptionCheckoutMetadataSchema } from "@/features/subscription/schema";
|
||||
|
@ -38,10 +39,11 @@ async function handleSelfHostedCheckoutSessionCompleted(
|
|||
|
||||
if (!success) {
|
||||
// If there is no metadata than this is likely a donation from a payment link
|
||||
console.info("No metadata found for session: ", checkoutSession.id);
|
||||
return;
|
||||
}
|
||||
|
||||
const { licenseType, seats } = data;
|
||||
const { licenseType, version, seats } = data;
|
||||
|
||||
const customerDetails = checkoutSession.customer_details;
|
||||
|
||||
|
@ -63,13 +65,13 @@ async function handleSelfHostedCheckoutSessionCompleted(
|
|||
type: licenseType,
|
||||
licenseeEmail: email,
|
||||
licenseeName: customerDetails.name ?? undefined,
|
||||
version,
|
||||
seats,
|
||||
stripeCustomerId: checkoutSession.customer as string,
|
||||
});
|
||||
|
||||
if (!license || !license.data) {
|
||||
throw new Error(
|
||||
`Failed to create team license for session: ${checkoutSession.id} - ${license?.error}`,
|
||||
`Failed to create license for session: ${checkoutSession.id} - ${license?.error}`,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -79,7 +81,7 @@ async function handleSelfHostedCheckoutSessionCompleted(
|
|||
to: email,
|
||||
from: {
|
||||
name: "Luke from Rallly",
|
||||
address: process.env.SUPPORT_EMAIL,
|
||||
address: env.SUPPORT_EMAIL,
|
||||
},
|
||||
props: {
|
||||
licenseKey: license.data.key,
|
||||
|
|
|
@ -10,7 +10,7 @@ export class LicensingClient {
|
|||
authToken?: string;
|
||||
|
||||
constructor({
|
||||
apiUrl = "https://licensing.rallly.co",
|
||||
apiUrl = "https://licensing.rallly.co/api/licensing/v1",
|
||||
authToken,
|
||||
}: {
|
||||
apiUrl?: string;
|
||||
|
@ -24,7 +24,7 @@ export class LicensingClient {
|
|||
throw new Error("Licensing API auth token is not configured.");
|
||||
}
|
||||
|
||||
const res = await fetch(`${this.apiUrl}/api/v1/licenses`, {
|
||||
const res = await fetch(`${this.apiUrl}/licenses`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
|
@ -39,16 +39,13 @@ export class LicensingClient {
|
|||
return createLicenseResponseSchema.parse(await res.json());
|
||||
}
|
||||
async validateLicenseKey(input: ValidateLicenseInputKeySchema) {
|
||||
const res = await fetch(
|
||||
`${this.apiUrl}/api/v1/licenses/actions/validate-key`,
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(input),
|
||||
const res = await fetch(`${this.apiUrl}/licenses/actions/validate-key`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
);
|
||||
body: JSON.stringify(input),
|
||||
});
|
||||
|
||||
if (!res.ok) {
|
||||
throw new Error("Failed to validate license key.");
|
||||
|
|
|
@ -31,12 +31,11 @@ export type ApiResponse<T> = {
|
|||
|
||||
export const createLicenseInputSchema = z.object({
|
||||
type: licenseTypeSchema,
|
||||
seats: z.number().optional(),
|
||||
expiresAt: z.date().optional(),
|
||||
seats: z.coerce.number().optional(),
|
||||
expiresAt: z.coerce.date().optional(),
|
||||
licenseeEmail: z.string().optional(),
|
||||
licenseeName: z.string().optional(),
|
||||
version: z.number().optional(),
|
||||
stripeCustomerId: z.string().optional(),
|
||||
version: z.coerce.number().optional(),
|
||||
});
|
||||
export type CreateLicenseInput = z.infer<typeof createLicenseInputSchema>;
|
||||
|
||||
|
@ -80,7 +79,8 @@ export type ValidateLicenseKeyResponse = z.infer<
|
|||
|
||||
export const licenseCheckoutMetadataSchema = z.object({
|
||||
licenseType: licenseTypeSchema,
|
||||
seats: z.number(),
|
||||
version: z.coerce.number(),
|
||||
seats: z.coerce.number(),
|
||||
});
|
||||
|
||||
export type LicenseCheckoutMetadata = z.infer<
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
Warnings:
|
||||
|
||||
- You are about to drop the column `stripe_customer_id` on the `licenses` table. All the data in the column will be lost.
|
||||
|
||||
*/
|
||||
-- AlterTable
|
||||
ALTER TABLE "licenses" DROP COLUMN "stripe_customer_id";
|
|
@ -20,7 +20,6 @@ model License {
|
|||
licenseeEmail String? @map("licensee_email")
|
||||
licenseeName String? @map("licensee_name")
|
||||
status LicenseStatus @default(ACTIVE) @map("status")
|
||||
stripeCustomerId String? @map("stripe_customer_id")
|
||||
|
||||
validations LicenseValidation[]
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue