Skip to content

Instantly share code, notes, and snippets.

@ccfiel
Created February 15, 2024 06:38
Show Gist options
  • Save ccfiel/e643732f5bffc557f79242994165df1f to your computer and use it in GitHub Desktop.
Save ccfiel/e643732f5bffc557f79242994165df1f to your computer and use it in GitHub Desktop.
import { Client, getLagoError } from "lago-javascript-client";
import "dotenv/config";
const isInvoiceInvalid = (invoice) => {
let invalidInvoice = false;
invoice.metadata.forEach((meta) => {
if (meta.key === "invalidInvoice") {
invalidInvoice = true;
}
});
return invalidInvoice;
};
const getNumberOfRetries = (invoice) => {
let retries = 0;
let id = null;
invoice.metadata.forEach((meta) => {
if (meta.key === "numberOfRetries") {
id = meta.lago_id;
retries = parseInt(meta.value);
}
});
return { id, retries };
};
const isNotYetSubscribed = async (external_customer_id, lagoClient) => {
let customer_lago_id = "";
try {
const { data } = await lagoClient.customers.findCustomer(
external_customer_id
);
customer_lago_id = data.customer.lago_id
} catch (error) {
return true;
}
let invoices = [];
let page = 1;
while (page !== null) {
try {
const { data } = await lagoClient.invoices.findAllInvoices({
per_page: 10,
page,
payment_status: "succeeded",
external_customer_id: external_customer_id,
});
invoices.push(...data.invoices);
page = data.meta.next_page;
} catch (error) {
console.error(getLagoError(error));
}
}
for (let i = 0; i < invoices.length; i++) {
const invoice = invoices[i];
if (
invoice.customer.lago_id === customer_lago_id &&
invoice.total_amount_cents > 0
) {
return false;
}
}
return true;
};
const isCustomerLite = async (id, lagoClient) => {
const subUSD = await lagoClient.subscriptions.findAllSubscriptions({
external_customer_id: id,
page: 1,
plan_code: "usd-lite",
status: "active",
});
const subPHP = await lagoClient.subscriptions.findAllSubscriptions({
external_customer_id: id,
page: 1,
plan_code: "php-lite",
status: "active",
});
const liteCount =
subPHP.data.subscriptions.length + subUSD.data.subscriptions.length;
return liteCount > 0;
};
const firstInvoice = async () => {
const config = {
baseUrl: `${process.env.LAGO_URL}/api/v1/`,
};
const lagoClient = Client(process.env.LAGO_API_KEY, config);
let page = 1;
let invoices = [];
while (page !== null) {
try {
const { data } = await lagoClient.invoices.findAllInvoices({
per_page: 5,
page,
payment_status: "failed",
});
invoices.push(...data.invoices);
page = data.meta.next_page;
} catch (error) {
console.error(getLagoError(error));
}
}
for (let i = 0; i < invoices.length; i++) {
const invoice = invoices[i];
let customer_lago_id = "";
if (!isInvoiceInvalid(invoice)) {
try {
const { data } = await lagoClient.customers.findCustomer(
invoice.customer.external_id
);
customer_lago_id = data.customer.lago_id;
} catch (error) {}
if (customer_lago_id !== invoice.customer.lago_id) {
lagoClient.invoices.updateInvoice(invoice.lago_id, {
invoice: {
metadata: [
{
key: "invalidInvoice",
value: "true",
},
],
},
});
}
}
}
for (let i = 0; i < invoices.length; i++) {
const invoice = invoices[i];
const isLite = await isCustomerLite(
invoice.customer.external_id,
lagoClient
);
if (isInvoiceInvalid(invoice) || isLite) {
continue;
}
try {
await lagoClient.invoices.retryPayment(invoice.lago_id);
const { id, retries } = getNumberOfRetries(invoice);
console.log(id, retries);
await lagoClient.invoices.updateInvoice(invoice.lago_id, {
invoice: {
metadata: [
{
id,
value: retries + 1,
},
],
},
});
if (retries >= 5 && isNotYetSubscribed(invoice.customer.external_id)) {
console.log("Destroying customer");
console.log(invoice.customer.external_id);
await lagoClient.customers.destroyCustomer(invoice.customer.external_id);
// send email to customer subscription failed
}
} catch (error) {
const err = await getLagoError(error);
console.error(err.error_details);
}
}
};
await firstInvoice();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment