shellphone.app/integrations/paddle.ts

117 lines
2.9 KiB
TypeScript
Raw Normal View History

2021-09-26 22:08:02 +00:00
import { getConfig } from "blitz";
import got from "got";
import type { PaddleSdkSubscriptionCreatedEvent } from "@devoxa/paddle-sdk";
import { PaddleSdk, PaddleSdkSubscriptionStatus, stringifyMetadata } from "@devoxa/paddle-sdk";
import { SubscriptionStatus } from "db";
2021-09-26 22:08:02 +00:00
const { publicRuntimeConfig, serverRuntimeConfig } = getConfig();
const vendor_id = publicRuntimeConfig.paddle.vendorId;
const vendor_auth_code = serverRuntimeConfig.paddle.apiKey;
export const paddleSdk = new PaddleSdk({
publicKey: serverRuntimeConfig.paddle.publicKey,
vendorId: vendor_id,
vendorAuthCode: vendor_auth_code,
metadataCodec: stringifyMetadata(),
});
export type Metadata = { organizationId: string };
export function translateSubscriptionStatus(
status: PaddleSdkSubscriptionCreatedEvent<unknown>["status"],
): SubscriptionStatus {
switch (status) {
case PaddleSdkSubscriptionStatus.ACTIVE:
return SubscriptionStatus.active;
case PaddleSdkSubscriptionStatus.CANCELLED:
return SubscriptionStatus.deleted;
case PaddleSdkSubscriptionStatus.PAUSED:
return SubscriptionStatus.paused;
case PaddleSdkSubscriptionStatus.PAST_DUE:
return SubscriptionStatus.past_due;
case PaddleSdkSubscriptionStatus.TRIALING:
return SubscriptionStatus.trialing;
default:
throw new Error("unreachable");
}
}
2021-09-26 22:08:02 +00:00
const client = got.extend({
prefixUrl: "https://vendors.paddle.com/api/2.0",
});
async function request<T>(path: string, data: any) {
return client.post<T>(path, {
2021-09-30 22:59:35 +00:00
json: {
...data,
vendor_id,
vendor_auth_code,
},
responseType: "json",
2021-09-26 22:08:02 +00:00
});
}
2021-09-30 22:59:35 +00:00
type GetPaymentsParams = {
subscriptionId: number;
2021-09-30 22:59:35 +00:00
};
export async function getPayments({ subscriptionId }: GetPaymentsParams) {
type Payment = {
id: number;
subscription_id: number;
amount: number;
currency: string;
payout_date: string;
is_paid: number;
is_one_off_charge: boolean;
receipt_url?: string;
};
type PaymentsSuccessResponse = {
success: true;
response: Payment[];
};
type PaymentsErrorResponse = {
success: false;
error: {
code: number;
message: string;
};
};
type PaymentsResponse = PaymentsSuccessResponse | PaymentsErrorResponse;
const { body } = await request<PaymentsResponse>("subscription/payments", { subscription_id: subscriptionId });
console.log("body", typeof body);
if (!body.success) {
throw new Error(body.error.message);
}
return body.response;
}
2021-09-26 22:08:02 +00:00
type UpdateSubscriptionPlanParams = {
subscriptionId: number;
planId: number;
2021-09-26 22:08:02 +00:00
prorate?: boolean;
};
export async function updateSubscriptionPlan({ subscriptionId, planId, prorate = true }: UpdateSubscriptionPlanParams) {
2021-09-30 22:59:35 +00:00
const { body } = await request("subscription/users/update", {
2021-09-26 22:08:02 +00:00
subscription_id: subscriptionId,
plan_id: planId,
prorate,
});
return body;
}
export async function cancelPaddleSubscription({ subscriptionId }: { subscriptionId: number }) {
2021-09-30 22:59:35 +00:00
const { body } = await request("subscription/users_cancel", { subscription_id: subscriptionId });
2021-09-26 22:08:02 +00:00
return body;
}