mirror of
https://github.com/Dokploy/dokploy
synced 2025-06-26 18:27:59 +00:00
feat: add stripe integration
This commit is contained in:
@@ -80,6 +80,7 @@ export const SettingsLayout = ({ children }: Props) => {
|
|||||||
icon: ListMusic,
|
icon: ListMusic,
|
||||||
href: "/dashboard/settings/registry",
|
href: "/dashboard/settings/registry",
|
||||||
},
|
},
|
||||||
|
|
||||||
...(!isCloud
|
...(!isCloud
|
||||||
? [
|
? [
|
||||||
{
|
{
|
||||||
@@ -102,6 +103,16 @@ export const SettingsLayout = ({ children }: Props) => {
|
|||||||
icon: Server,
|
icon: Server,
|
||||||
href: "/dashboard/settings/servers",
|
href: "/dashboard/settings/servers",
|
||||||
},
|
},
|
||||||
|
...(isCloud
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
title: "Billing",
|
||||||
|
label: "",
|
||||||
|
icon: CreditCardIcon,
|
||||||
|
href: "/dashboard/settings/billing",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
: []),
|
||||||
]
|
]
|
||||||
: []),
|
: []),
|
||||||
...(user?.canAccessToSSHKeys
|
...(user?.canAccessToSSHKeys
|
||||||
@@ -137,6 +148,7 @@ import {
|
|||||||
Activity,
|
Activity,
|
||||||
Bell,
|
Bell,
|
||||||
BoxesIcon,
|
BoxesIcon,
|
||||||
|
CreditCardIcon,
|
||||||
Database,
|
Database,
|
||||||
GitBranch,
|
GitBranch,
|
||||||
KeyIcon,
|
KeyIcon,
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
"test": "vitest --config __test__/vitest.config.ts"
|
"test": "vitest --config __test__/vitest.config.ts"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"stripe": "17.2.0",
|
||||||
"@dokploy/server": "workspace:*",
|
"@dokploy/server": "workspace:*",
|
||||||
"@codemirror/lang-json": "^6.0.1",
|
"@codemirror/lang-json": "^6.0.1",
|
||||||
"@codemirror/lang-yaml": "^6.1.1",
|
"@codemirror/lang-yaml": "^6.1.1",
|
||||||
|
|||||||
66
apps/dokploy/pages/dashboard/settings/billing.tsx
Normal file
66
apps/dokploy/pages/dashboard/settings/billing.tsx
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
import { ShowNodes } from "@/components/dashboard/settings/cluster/nodes/show-nodes";
|
||||||
|
import { DashboardLayout } from "@/components/layouts/dashboard-layout";
|
||||||
|
import { SettingsLayout } from "@/components/layouts/settings-layout";
|
||||||
|
import { api } from "@/utils/api";
|
||||||
|
import { IS_CLOUD, validateRequest } from "@dokploy/server";
|
||||||
|
import type { GetServerSidePropsContext } from "next";
|
||||||
|
import React, { type ReactElement } from "react";
|
||||||
|
|
||||||
|
const Page = () => {
|
||||||
|
const { data } = api.stripe.getProducts.useQuery();
|
||||||
|
console.log(data);
|
||||||
|
return (
|
||||||
|
<div className="flex flex-col gap-4 w-full">
|
||||||
|
{data?.map((product) => (
|
||||||
|
<div key={product.id} className="border p-4 rounded-lg shadow-md">
|
||||||
|
<h2 className="text-xl font-semibold">{product.name}</h2>
|
||||||
|
{product.description && (
|
||||||
|
<p className="text-gray-500">{product.description}</p>
|
||||||
|
)}
|
||||||
|
<p className="text-lg font-bold">
|
||||||
|
Price: {product.default_price.unit_amount / 100}{" "}
|
||||||
|
{product.default_price.currency.toUpperCase()}
|
||||||
|
</p>
|
||||||
|
{/* <button className="mt-2 px-4 py-2 bg-blue-500 text-white rounded">
|
||||||
|
Subscribe
|
||||||
|
</button> */}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Page;
|
||||||
|
|
||||||
|
Page.getLayout = (page: ReactElement) => {
|
||||||
|
return (
|
||||||
|
<DashboardLayout tab={"settings"}>
|
||||||
|
<SettingsLayout>{page}</SettingsLayout>
|
||||||
|
</DashboardLayout>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export async function getServerSideProps(
|
||||||
|
ctx: GetServerSidePropsContext<{ serviceId: string }>,
|
||||||
|
) {
|
||||||
|
if (!IS_CLOUD) {
|
||||||
|
return {
|
||||||
|
redirect: {
|
||||||
|
permanent: true,
|
||||||
|
destination: "/dashboard/projects",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
const { user, session } = await validateRequest(ctx.req, ctx.res);
|
||||||
|
if (!user || user.rol === "user") {
|
||||||
|
return {
|
||||||
|
redirect: {
|
||||||
|
permanent: true,
|
||||||
|
destination: "/",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
props: {},
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
import { ShowNodes } from "@/components/dashboard/settings/cluster/nodes/show-nodes";
|
import { ShowNodes } from "@/components/dashboard/settings/cluster/nodes/show-nodes";
|
||||||
import { ShowRegistry } from "@/components/dashboard/settings/cluster/registry/show-registry";
|
|
||||||
import { DashboardLayout } from "@/components/layouts/dashboard-layout";
|
import { DashboardLayout } from "@/components/layouts/dashboard-layout";
|
||||||
import { SettingsLayout } from "@/components/layouts/settings-layout";
|
import { SettingsLayout } from "@/components/layouts/settings-layout";
|
||||||
import { IS_CLOUD, validateRequest } from "@dokploy/server";
|
import { IS_CLOUD, validateRequest } from "@dokploy/server";
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import { securityRouter } from "./routers/security";
|
|||||||
import { serverRouter } from "./routers/server";
|
import { serverRouter } from "./routers/server";
|
||||||
import { settingsRouter } from "./routers/settings";
|
import { settingsRouter } from "./routers/settings";
|
||||||
import { sshRouter } from "./routers/ssh-key";
|
import { sshRouter } from "./routers/ssh-key";
|
||||||
|
import { stripeRouter } from "./routers/stripe";
|
||||||
import { userRouter } from "./routers/user";
|
import { userRouter } from "./routers/user";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -69,6 +70,7 @@ export const appRouter = createTRPCRouter({
|
|||||||
gitlab: gitlabRouter,
|
gitlab: gitlabRouter,
|
||||||
github: githubRouter,
|
github: githubRouter,
|
||||||
server: serverRouter,
|
server: serverRouter,
|
||||||
|
stripe: stripeRouter,
|
||||||
});
|
});
|
||||||
|
|
||||||
// export type definition of API
|
// export type definition of API
|
||||||
|
|||||||
22
apps/dokploy/server/api/routers/stripe.ts
Normal file
22
apps/dokploy/server/api/routers/stripe.ts
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import Stripe from "stripe";
|
||||||
|
import { adminProcedure, createTRPCRouter } from "../trpc";
|
||||||
|
|
||||||
|
export const stripeRouter = createTRPCRouter({
|
||||||
|
getProducts: adminProcedure.query(async () => {
|
||||||
|
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY || "", {
|
||||||
|
apiVersion: "2024-09-30.acacia",
|
||||||
|
});
|
||||||
|
|
||||||
|
const products = await stripe.products.list({
|
||||||
|
expand: ["data.default_price"],
|
||||||
|
});
|
||||||
|
console.log(products);
|
||||||
|
return products.data;
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
// {
|
||||||
|
// "Parallelism": 1,
|
||||||
|
// "Delay": 10000000000,
|
||||||
|
// "FailureAction": "rollback",
|
||||||
|
// "Order": "start-first"
|
||||||
|
// }
|
||||||
12
pnpm-lock.yaml
generated
12
pnpm-lock.yaml
generated
@@ -353,6 +353,9 @@ importers:
|
|||||||
ssh2:
|
ssh2:
|
||||||
specifier: 1.15.0
|
specifier: 1.15.0
|
||||||
version: 1.15.0
|
version: 1.15.0
|
||||||
|
stripe:
|
||||||
|
specifier: 17.2.0
|
||||||
|
version: 17.2.0
|
||||||
superjson:
|
superjson:
|
||||||
specifier: ^2.2.1
|
specifier: ^2.2.1
|
||||||
version: 2.2.1
|
version: 2.2.1
|
||||||
@@ -7641,6 +7644,10 @@ packages:
|
|||||||
strip-literal@2.1.0:
|
strip-literal@2.1.0:
|
||||||
resolution: {integrity: sha512-Op+UycaUt/8FbN/Z2TWPBLge3jWrP3xj10f3fnYxf052bKuS3EKs1ZQcVGjnEMdsNVAM+plXRdmjrZ/KgG3Skw==}
|
resolution: {integrity: sha512-Op+UycaUt/8FbN/Z2TWPBLge3jWrP3xj10f3fnYxf052bKuS3EKs1ZQcVGjnEMdsNVAM+plXRdmjrZ/KgG3Skw==}
|
||||||
|
|
||||||
|
stripe@17.2.0:
|
||||||
|
resolution: {integrity: sha512-KuDplY9WrNKi07+uEFeguis/Mh+HC+hfEMy8P5snhQzCXUv01o+4KcIJ9auFxpv4Odp2R2krs9rZ9PhQl8+Sdw==}
|
||||||
|
engines: {node: '>=12.*'}
|
||||||
|
|
||||||
style-mod@4.1.2:
|
style-mod@4.1.2:
|
||||||
resolution: {integrity: sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw==}
|
resolution: {integrity: sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw==}
|
||||||
|
|
||||||
@@ -16297,6 +16304,11 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
js-tokens: 9.0.0
|
js-tokens: 9.0.0
|
||||||
|
|
||||||
|
stripe@17.2.0:
|
||||||
|
dependencies:
|
||||||
|
'@types/node': 20.14.10
|
||||||
|
qs: 6.12.3
|
||||||
|
|
||||||
style-mod@4.1.2: {}
|
style-mod@4.1.2: {}
|
||||||
|
|
||||||
style-to-object@0.4.4:
|
style-to-object@0.4.4:
|
||||||
|
|||||||
Reference in New Issue
Block a user