Skip to content

Instantly share code, notes, and snippets.

@feliche93
Created June 26, 2023 09:16
Show Gist options
  • Save feliche93/1d7fac7ff7014e8a6cf905cf9c1d6d06 to your computer and use it in GitHub Desktop.
Save feliche93/1d7fac7ff7014e8a6cf905cf9c1d6d06 to your computer and use it in GitHub Desktop.
Server Actions to manage lemon squeezy subscriptions
"use server"
import { revalidatePath } from "next/cache";
import { SLemonSqueezyRequest, TLemonSqueezyRequest } from "./zod-lemon-squeezy";
const lemonSqueezyBaseUrl = 'https://api.lemonsqueezy.com/v1';
const lemonSqueezyApiKey = process.env.LEMON_SQUEEZY_API_KEY;
if (!lemonSqueezyApiKey) throw new Error("No LEMON_SQUEEZY_API_KEY environment variable set");
function createHeaders() {
const headers = new Headers();
headers.append('Accept', 'application/vnd.api+json');
headers.append('Content-Type', 'application/vnd.api+json');
headers.append('Authorization', `Bearer ${lemonSqueezyApiKey}`);
return headers;
}
function createRequestOptions(method: string, headers: Headers): RequestInit {
return {
method,
headers,
redirect: 'follow',
cache: "no-store"
};
}
type DeleteSubscriptionParams = {
subscriptionId: number;
};
export async function deleteSubscription(params: DeleteSubscriptionParams): Promise<void> {
const url = `${lemonSqueezyBaseUrl}/subscriptions/${params.subscriptionId}`;
const headers = createHeaders();
const requestOptions = createRequestOptions('DELETE', headers);
const response: Response = await fetch(url, requestOptions,);
if (!response.ok) {
const responseBody = await response.json();
throw new Error(`HTTP error! status: ${response.status}, body: ${JSON.stringify(responseBody)}`);
}
// Add delay
await new Promise(resolve => setTimeout(resolve, 2000));
revalidatePath('/account/billing');
}
type UpdateSubscriptionParams = {
subscriptionId: number;
cancelled: boolean;
};
export async function updateSubscription(params: UpdateSubscriptionParams): Promise<void> {
const url = `${lemonSqueezyBaseUrl}/subscriptions/${params.subscriptionId}`;
const headers = createHeaders();
const body = {
"data": {
"type": "subscriptions",
"id": params.subscriptionId.toString(),
"attributes": {
"cancelled": params.cancelled,
}
}
};
const requestOptions = createRequestOptions('PATCH', headers);
requestOptions.body = JSON.stringify(body);
const response: Response = await fetch(url, requestOptions);
if (!response.ok) {
const responseBody = await response.json();
throw new Error(`HTTP error! status: ${response.status}, body: ${JSON.stringify(responseBody)}`);
}
// console.log(await response.json());
// Add delay
await new Promise(resolve => setTimeout(resolve, 2000));
revalidatePath('/account/billing');
}
export async function getProductVariants(productId: string): Promise<TLemonSqueezyRequest> {
const url = `${lemonSqueezyBaseUrl}/variants?filter[product_id]=${productId}`;
const headers = createHeaders();
const requestOptions = createRequestOptions('GET', headers);
const response: Response = await fetch(url, requestOptions);
if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
const data = await response.json();
const parsedData = SLemonSqueezyRequest.parse(data);
return parsedData;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment