Merge pull request #1007 from automatisch/remove-stripe
chore: Remove stripe-related functionality
This commit is contained in:
@@ -41,10 +41,6 @@ type AppConfig = {
|
|||||||
isCloud: boolean;
|
isCloud: boolean;
|
||||||
paddleVendorId: number;
|
paddleVendorId: number;
|
||||||
paddleVendorAuthCode: string;
|
paddleVendorAuthCode: string;
|
||||||
stripeSecretKey: string;
|
|
||||||
stripeSigningSecret: string;
|
|
||||||
stripeStarterPriceKey: string;
|
|
||||||
stripeGrowthPriceKey: string;
|
|
||||||
licenseKey: string;
|
licenseKey: string;
|
||||||
sentryDsn: string;
|
sentryDsn: string;
|
||||||
};
|
};
|
||||||
@@ -115,10 +111,6 @@ const appConfig: AppConfig = {
|
|||||||
isCloud: process.env.AUTOMATISCH_CLOUD === 'true',
|
isCloud: process.env.AUTOMATISCH_CLOUD === 'true',
|
||||||
paddleVendorId: Number(process.env.PADDLE_VENDOR_ID),
|
paddleVendorId: Number(process.env.PADDLE_VENDOR_ID),
|
||||||
paddleVendorAuthCode: process.env.PADDLE_VENDOR_AUTH_CODE,
|
paddleVendorAuthCode: process.env.PADDLE_VENDOR_AUTH_CODE,
|
||||||
stripeSecretKey: process.env.STRIPE_SECRET_KEY,
|
|
||||||
stripeSigningSecret: process.env.STRIPE_SIGNING_SECRET,
|
|
||||||
stripeStarterPriceKey: process.env.STRIPE_STARTER_PRICE_KEY,
|
|
||||||
stripeGrowthPriceKey: process.env.STRIPE_GROWTH_PRICE_KEY,
|
|
||||||
licenseKey: process.env.LICENSE_KEY,
|
licenseKey: process.env.LICENSE_KEY,
|
||||||
sentryDsn: process.env.SENTRY_DSN,
|
sentryDsn: process.env.SENTRY_DSN,
|
||||||
};
|
};
|
||||||
|
@@ -1,27 +0,0 @@
|
|||||||
import { Response } from 'express';
|
|
||||||
import { IRequest } from '@automatisch/types';
|
|
||||||
|
|
||||||
import * as Sentry from '../../helpers/sentry.ee';
|
|
||||||
import Billing from '../../helpers/billing/index.ee';
|
|
||||||
import appConfig from '../../config/app';
|
|
||||||
import logger from '../../helpers/logger';
|
|
||||||
|
|
||||||
export default async (request: IRequest, response: Response) => {
|
|
||||||
const signature = request.headers['stripe-signature'];
|
|
||||||
|
|
||||||
try {
|
|
||||||
const event = Billing.stripe.webhooks.constructEvent(
|
|
||||||
request.rawBody,
|
|
||||||
signature,
|
|
||||||
appConfig.stripeSigningSecret
|
|
||||||
);
|
|
||||||
|
|
||||||
await Billing.handleWebhooks(event);
|
|
||||||
return response.sendStatus(200);
|
|
||||||
} catch (error) {
|
|
||||||
logger.error(`Webhook Error: ${error.message}`);
|
|
||||||
|
|
||||||
Sentry.captureException(error);
|
|
||||||
return response.sendStatus(400);
|
|
||||||
}
|
|
||||||
};
|
|
@@ -1,6 +1,4 @@
|
|||||||
import User from '../../models/user';
|
import User from '../../models/user';
|
||||||
import Billing from '../../helpers/billing/index.ee';
|
|
||||||
import appConfig from '../../config/app';
|
|
||||||
|
|
||||||
type Params = {
|
type Params = {
|
||||||
input: {
|
input: {
|
||||||
@@ -26,10 +24,6 @@ const createUser = async (_parent: unknown, params: Params) => {
|
|||||||
role: 'user',
|
role: 'user',
|
||||||
});
|
});
|
||||||
|
|
||||||
if (appConfig.isCloud) {
|
|
||||||
await Billing.createSubscription(user);
|
|
||||||
}
|
|
||||||
|
|
||||||
return user;
|
return user;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -1,16 +0,0 @@
|
|||||||
import appConfig from '../../config/app';
|
|
||||||
import Context from '../../types/express/context';
|
|
||||||
import Billing from '../../helpers/billing/index.ee';
|
|
||||||
|
|
||||||
const getPaymentPortalUrl = async (
|
|
||||||
_parent: unknown,
|
|
||||||
_params: unknown,
|
|
||||||
context: Context
|
|
||||||
) => {
|
|
||||||
if (!appConfig.isCloud) return;
|
|
||||||
|
|
||||||
const url = Billing.createPaymentPortalUrl(context.currentUser);
|
|
||||||
return { url };
|
|
||||||
};
|
|
||||||
|
|
||||||
export default getPaymentPortalUrl;
|
|
@@ -14,7 +14,6 @@ import getCurrentUser from './queries/get-current-user';
|
|||||||
import getUsageData from './queries/get-usage-data.ee';
|
import getUsageData from './queries/get-usage-data.ee';
|
||||||
import getPaymentPlans from './queries/get-payment-plans.ee';
|
import getPaymentPlans from './queries/get-payment-plans.ee';
|
||||||
import getPaddleInfo from './queries/get-paddle-info.ee';
|
import getPaddleInfo from './queries/get-paddle-info.ee';
|
||||||
import getPaymentPortalUrl from './queries/get-payment-portal-url.ee';
|
|
||||||
import getAutomatischInfo from './queries/get-automatisch-info';
|
import getAutomatischInfo from './queries/get-automatisch-info';
|
||||||
import healthcheck from './queries/healthcheck';
|
import healthcheck from './queries/healthcheck';
|
||||||
|
|
||||||
@@ -35,7 +34,6 @@ const queryResolvers = {
|
|||||||
getUsageData,
|
getUsageData,
|
||||||
getPaymentPlans,
|
getPaymentPlans,
|
||||||
getPaddleInfo,
|
getPaddleInfo,
|
||||||
getPaymentPortalUrl,
|
|
||||||
getAutomatischInfo,
|
getAutomatischInfo,
|
||||||
healthcheck,
|
healthcheck,
|
||||||
};
|
};
|
||||||
|
@@ -35,7 +35,6 @@ type Query {
|
|||||||
): [SubstepArgument]
|
): [SubstepArgument]
|
||||||
getCurrentUser: User
|
getCurrentUser: User
|
||||||
getUsageData: GetUsageData
|
getUsageData: GetUsageData
|
||||||
getPaymentPortalUrl: GetPaymentPortalUrl
|
|
||||||
getPaymentPlans: [PaymentPlan]
|
getPaymentPlans: [PaymentPlan]
|
||||||
getPaddleInfo: GetPaddleInfo
|
getPaddleInfo: GetPaddleInfo
|
||||||
getAutomatischInfo: GetAutomatischInfo
|
getAutomatischInfo: GetAutomatischInfo
|
||||||
@@ -479,10 +478,6 @@ type GetUsageData {
|
|||||||
nextResetAt: String
|
nextResetAt: String
|
||||||
}
|
}
|
||||||
|
|
||||||
type GetPaymentPortalUrl {
|
|
||||||
url: String
|
|
||||||
}
|
|
||||||
|
|
||||||
type GetPaddleInfo {
|
type GetPaddleInfo {
|
||||||
sandbox: Boolean
|
sandbox: Boolean
|
||||||
vendorId: Int
|
vendorId: Int
|
||||||
|
@@ -1,106 +1,12 @@
|
|||||||
import Stripe from 'stripe';
|
|
||||||
import User from '../../models/user';
|
|
||||||
import PaymentPlan from '../../models/payment-plan.ee';
|
|
||||||
import UsageData from '../../models/usage-data.ee';
|
|
||||||
import appConfig from '../../config/app';
|
import appConfig from '../../config/app';
|
||||||
import handleWebhooks from './webhooks.ee';
|
|
||||||
import paddlePlans from './plans.ee';
|
import paddlePlans from './plans.ee';
|
||||||
|
|
||||||
const plans = [
|
|
||||||
{
|
|
||||||
price: appConfig.stripeStarterPriceKey,
|
|
||||||
name: 'Starter',
|
|
||||||
taskCount: 1000,
|
|
||||||
default: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
price: appConfig.stripeGrowthPriceKey,
|
|
||||||
name: 'Growth',
|
|
||||||
taskCount: 10000,
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
const stripe = new Stripe(appConfig.stripeSecretKey, {
|
|
||||||
apiVersion: '2022-11-15',
|
|
||||||
});
|
|
||||||
|
|
||||||
const createStripeCustomer = async (user: User) => {
|
|
||||||
const params: Stripe.CustomerCreateParams = {
|
|
||||||
email: user.email,
|
|
||||||
name: user.fullName,
|
|
||||||
description: `User ID: ${user.id}`,
|
|
||||||
};
|
|
||||||
|
|
||||||
return await stripe.customers.create(params);
|
|
||||||
};
|
|
||||||
|
|
||||||
const defaultPlan = plans.find((plan) => plan.default);
|
|
||||||
|
|
||||||
const createStripeSubscription = async (
|
|
||||||
user: User,
|
|
||||||
stripeCustomer: Stripe.Customer
|
|
||||||
) => {
|
|
||||||
const params: Stripe.SubscriptionCreateParams = {
|
|
||||||
customer: stripeCustomer.id,
|
|
||||||
items: [{ price: defaultPlan.price }],
|
|
||||||
};
|
|
||||||
|
|
||||||
return await stripe.subscriptions.create(params);
|
|
||||||
};
|
|
||||||
|
|
||||||
const createSubscription = async (user: User) => {
|
|
||||||
const stripeCustomer = await createStripeCustomer(user);
|
|
||||||
const stripeSubscription = await createStripeSubscription(
|
|
||||||
user,
|
|
||||||
stripeCustomer
|
|
||||||
);
|
|
||||||
|
|
||||||
await PaymentPlan.query().insert({
|
|
||||||
name: defaultPlan.name,
|
|
||||||
taskCount: defaultPlan.taskCount,
|
|
||||||
userId: user.id,
|
|
||||||
stripeCustomerId: stripeCustomer.id,
|
|
||||||
stripeSubscriptionId: stripeSubscription.id,
|
|
||||||
currentPeriodStartedAt: new Date(
|
|
||||||
stripeSubscription.current_period_start * 1000
|
|
||||||
).toISOString(),
|
|
||||||
currentPeriodEndsAt: new Date(
|
|
||||||
stripeSubscription.current_period_end * 1000
|
|
||||||
).toISOString(),
|
|
||||||
});
|
|
||||||
|
|
||||||
await UsageData.query().insert({
|
|
||||||
userId: user.id,
|
|
||||||
consumedTaskCount: 0,
|
|
||||||
nextResetAt: new Date(
|
|
||||||
stripeSubscription.current_period_end * 1000
|
|
||||||
).toISOString(),
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const createPaymentPortalUrl = async (user: User) => {
|
|
||||||
const paymentPlan = await user.$relatedQuery('paymentPlan');
|
|
||||||
|
|
||||||
const userSession = await stripe.billingPortal.sessions.create({
|
|
||||||
customer: paymentPlan.stripeCustomerId,
|
|
||||||
return_url: 'https://cloud.automatisch.io/settings/billing',
|
|
||||||
});
|
|
||||||
|
|
||||||
return userSession.url;
|
|
||||||
};
|
|
||||||
|
|
||||||
const paddleInfo = {
|
const paddleInfo = {
|
||||||
sandbox: appConfig.isDev ? true : false,
|
sandbox: appConfig.isDev ? true : false,
|
||||||
vendorId: appConfig.paddleVendorId,
|
vendorId: appConfig.paddleVendorId,
|
||||||
};
|
};
|
||||||
|
|
||||||
const billing = {
|
const billing = {
|
||||||
createSubscription,
|
|
||||||
createPaymentPortalUrl,
|
|
||||||
handleWebhooks,
|
|
||||||
stripe,
|
|
||||||
plans,
|
|
||||||
paddlePlans,
|
paddlePlans,
|
||||||
paddleInfo,
|
paddleInfo,
|
||||||
};
|
};
|
||||||
|
@@ -1,42 +0,0 @@
|
|||||||
import Stripe from 'stripe';
|
|
||||||
import PaymentPlan from '../../models/payment-plan.ee';
|
|
||||||
import Billing from './index.ee';
|
|
||||||
|
|
||||||
const handleWebhooks = async (event: Stripe.Event) => {
|
|
||||||
const trackedWebhookTypes = [
|
|
||||||
'customer.subscription.created',
|
|
||||||
'customer.subscription.updated',
|
|
||||||
'customer.subscription.deleted',
|
|
||||||
];
|
|
||||||
|
|
||||||
if (!trackedWebhookTypes.includes(event.type)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
await updatePaymentPlan(event);
|
|
||||||
};
|
|
||||||
|
|
||||||
const updatePaymentPlan = async (event: Stripe.Event) => {
|
|
||||||
const subscription = event.data.object as Stripe.Subscription;
|
|
||||||
const priceKey = subscription.items.data[0].plan.id;
|
|
||||||
const plan = Billing.plans.find((plan) => plan.price === priceKey);
|
|
||||||
|
|
||||||
const paymentPlan = await PaymentPlan.query().findOne({
|
|
||||||
stripe_customer_id: subscription.customer,
|
|
||||||
});
|
|
||||||
|
|
||||||
await paymentPlan.$query().patchAndFetch({
|
|
||||||
name: plan.name,
|
|
||||||
taskCount: plan.taskCount,
|
|
||||||
stripeSubscriptionId: subscription.id,
|
|
||||||
});
|
|
||||||
|
|
||||||
const user = await paymentPlan.$relatedQuery('user');
|
|
||||||
const usageData = await user.$relatedQuery('usageData');
|
|
||||||
|
|
||||||
await usageData.$query().patchAndFetch({
|
|
||||||
nextResetAt: new Date(subscription.current_period_end * 1000).toISOString(),
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export default handleWebhooks;
|
|
@@ -1,12 +1,10 @@
|
|||||||
import { Router } from 'express';
|
import { Router } from 'express';
|
||||||
import graphQLInstance from '../helpers/graphql-instance';
|
import graphQLInstance from '../helpers/graphql-instance';
|
||||||
import webhooksRouter from './webhooks';
|
import webhooksRouter from './webhooks';
|
||||||
import stripeRouter from './stripe.ee';
|
|
||||||
|
|
||||||
const router = Router();
|
const router = Router();
|
||||||
|
|
||||||
router.use('/graphql', graphQLInstance);
|
router.use('/graphql', graphQLInstance);
|
||||||
router.use('/webhooks', webhooksRouter);
|
router.use('/webhooks', webhooksRouter);
|
||||||
router.use('/stripe', stripeRouter);
|
|
||||||
|
|
||||||
export default router;
|
export default router;
|
||||||
|
@@ -1,23 +0,0 @@
|
|||||||
import express, { Router } from 'express';
|
|
||||||
import multer from 'multer';
|
|
||||||
import { IRequest } from '@automatisch/types';
|
|
||||||
import appConfig from '../config/app';
|
|
||||||
import stripeWebhooksAction from '../controllers/stripe/webhooks.ee';
|
|
||||||
|
|
||||||
const router = Router();
|
|
||||||
const upload = multer();
|
|
||||||
|
|
||||||
router.use(upload.none());
|
|
||||||
|
|
||||||
router.use(
|
|
||||||
express.text({
|
|
||||||
limit: appConfig.requestBodySizeLimit,
|
|
||||||
verify(req, res, buf) {
|
|
||||||
(req as IRequest).rawBody = buf;
|
|
||||||
},
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
router.post('/webhooks', stripeWebhooksAction);
|
|
||||||
|
|
||||||
export default router;
|
|
Reference in New Issue
Block a user