UNPKG

run402-mcp

Version:

MCP server for Run402 — full-stack backend infrastructure for AI agents: Postgres, auth, storage, serverless functions and atomic deploys. Paid with x402/MPP. Includes $0.03 image generation.

166 lines • 7.27 kB
/** * `projects.stripe` namespace — the organization's Stripe account for a * project's app, and Checkout / customer-portal sessions on it. * * The organization that owns the project holds its own Stripe account, * connected to Run402's platform; Run402 charges nothing on it (zero platform * fee) and never holds the money. Every call here is a thin, typed request to * the project-scoped `/projects/v1/:project_id/stripe/*` routes: the gateway * owns account state, body validation, the return-URL allowlist, and * idempotency, and its `next_actions` and error codes surface unchanged. * * Two methods hand out a one-time Stripe-hosted onboarding link meant for the * account holder, not a payer: `account.connect` (while onboarding is * incomplete) and `onboardingLinks.create`. They are secret-returning, so the * MCP `run` sandbox refuses them and names the CLI command. Checkout and * portal URLs are meant to be handed to a payer and run on every surface. * Nothing here caches a URL. */ import { gateSecret } from "../secret-gate.js"; function stripePath(projectId, suffix) { return `/projects/v1/${encodeURIComponent(projectId)}/stripe/${suffix}`; } function authMeta(method, projectId) { return { method, target: { project_id: projectId } }; } function defined(entries) { const out = {}; for (const [key, value] of Object.entries(entries)) if (value !== undefined) out[key] = value; return out; } /** `r.projects.stripe.account` — connect, read, and detach the organization's account. */ export class ProjectStripeAccount { client; constructor(client) { this.client = client; } /** * Connect the organization's Stripe account, or return the one it already * has (idempotent per organization). While onboarding is incomplete the * result carries a one-time `onboarding` link for the account holder. */ async connect(projectId, input = {}) { gateSecret(this.client, "projects.stripe.account.connect", projectId, input); return this.client.request(stripePath(projectId, "account"), { method: "POST", body: defined({ country: input.country, business_type: input.businessType, business_name: input.businessName, support_email: input.supportEmail, statement_descriptor: input.statementDescriptor, email: input.email, }), authMeta: authMeta("projects.stripe.account.connect", projectId), context: "connecting Stripe account", }); } /** The organization's account, read fresh from Stripe. Never carries a link. */ async get(projectId) { return this.client.request(stripePath(projectId, "account"), { method: "GET", authMeta: authMeta("projects.stripe.account.get", projectId), context: "reading Stripe account", }); } /** Detach the account from the platform. The Stripe account itself is unaffected. */ async disconnect(projectId) { return this.client.request(stripePath(projectId, "account"), { method: "DELETE", authMeta: authMeta("projects.stripe.account.disconnect", projectId), context: "disconnecting Stripe account", }); } } /** `r.projects.stripe.onboardingLinks` — one-time Stripe-hosted onboarding links. */ export class ProjectStripeOnboardingLinks { client; constructor(client) { this.client = client; } /** Mint a one-time onboarding (or update) link for the account holder. */ async create(projectId, input = {}) { gateSecret(this.client, "projects.stripe.onboardingLinks.create", projectId, input); return this.client.request(stripePath(projectId, "onboarding-links"), { method: "POST", body: defined({ return_url: input.returnUrl, refresh_url: input.refreshUrl }), authMeta: authMeta("projects.stripe.onboardingLinks.create", projectId), context: "minting Stripe onboarding link", }); } } /** `r.projects.stripe.checkoutSessions` — Checkout Sessions on the organization's account. */ export class ProjectStripeCheckoutSessions { client; constructor(client) { this.client = client; } /** * Create a Checkout Session and get the URL to send the payer to. Pass * `idempotencyKey` so a retry returns the original session (`deduplicated`). */ async create(projectId, input) { const { idempotencyKey, ...rest } = input; return this.client.request(stripePath(projectId, "checkout-sessions"), { method: "POST", body: defined({ mode: rest.mode, line_items: rest.lineItems, success_url: rest.successUrl, cancel_url: rest.cancelUrl, customer: rest.customer, customer_email: rest.customerEmail, client_reference_id: rest.clientReferenceId, metadata: rest.metadata, automatic_tax: rest.automaticTax, subscription: rest.subscription, locale: rest.locale, allow_promotion_codes: rest.allowPromotionCodes, expires_at: rest.expiresAt, }), ...(idempotencyKey ? { headers: { "Idempotency-Key": idempotencyKey } } : {}), authMeta: authMeta("projects.stripe.checkoutSessions.create", projectId), context: "creating Stripe checkout session", }); } /** A session's outcome (`status`, `payment_status`, ids), read from Stripe. */ async get(projectId, checkoutSessionId) { return this.client.request(stripePath(projectId, `checkout-sessions/${encodeURIComponent(checkoutSessionId)}`), { method: "GET", authMeta: authMeta("projects.stripe.checkoutSessions.get", projectId), context: "reading Stripe checkout session", }); } } /** `r.projects.stripe.portalSessions` — the organization's Stripe customer portal. */ export class ProjectStripePortalSessions { client; constructor(client) { this.client = client; } /** Open the customer portal for an existing customer; send them to `url`. */ async create(projectId, input) { return this.client.request(stripePath(projectId, "portal-sessions"), { method: "POST", body: { customer: input.customer, return_url: input.returnUrl }, authMeta: authMeta("projects.stripe.portalSessions.create", projectId), context: "creating Stripe portal session", }); } } /** `r.projects.stripe` — the organization's Stripe account and sessions for a project. */ export class ProjectStripe { account; onboardingLinks; checkoutSessions; portalSessions; constructor(client) { this.account = new ProjectStripeAccount(client); this.onboardingLinks = new ProjectStripeOnboardingLinks(client); this.checkoutSessions = new ProjectStripeCheckoutSessions(client); this.portalSessions = new ProjectStripePortalSessions(client); } } //# sourceMappingURL=stripe.js.map