/**
 * StripeService — manages customers, checkout sessions, subscription status,
 * and webhook processing for QuantRisk billing.
 *
 * Uses the Stripe npm SDK (stripe ^15.0.0) with the Cloudflare Workers
 * runtime adapter (httpClient: Stripe.createFetchHttpClient()).
 *
 * Constructor takes raw environment bindings; no global singletons.
 */
import Stripe from "stripe";
export interface StripeEnv {
    STRIPE_SECRET_KEY: string;
    STRIPE_WEBHOOK_SECRET: string;
}
export type UserTier = "free" | "paid";
export interface SubscriptionStatus {
    active: boolean;
    tier: UserTier;
    /** Stripe subscription ID, if one exists. */
    subscriptionId: string | null;
    /** Unix timestamp of the next billing cycle, if known. */
    currentPeriodEnd: number | null;
}
export declare class StripeService {
    private readonly stripe;
    private readonly webhookSecret;
    constructor(env: StripeEnv);
    /**
     * Create a new Stripe customer record.
     * Returns the Stripe customer ID.
     */
    createCustomer(email: string): Promise<string>;
    /**
     * Retrieve an existing Stripe customer by ID.
     * Returns null if the customer does not exist or has been deleted.
     */
    getCustomer(customerId: string): Promise<Stripe.Customer | null>;
    /**
     * Create a Stripe Checkout Session for the $29/month paid plan.
     *
     * The `apiKey` is propagated to the Subscription via `subscription_data.metadata`
     * so the webhook handler can find the right UserState DO to update when the
     * subscription's status changes. It is also stored on the session itself so
     * the success page can read it back.
     *
     * If `customerId` is null, Stripe creates a new customer at checkout.
     *
     * Returns the full Checkout Session (caller uses .url and .id).
     */
    createCheckoutSession(args: {
        customerId?: string | null;
        priceId: string;
        apiKey: string;
        successUrl: string;
        cancelUrl: string;
        customerEmail?: string | null;
    }): Promise<Stripe.Checkout.Session>;
    /**
     * Retrieve a Checkout Session by ID. Used by /checkout/success to read the
     * api_key + customer + subscription off the completed session.
     */
    retrieveCheckoutSession(sessionId: string): Promise<Stripe.Checkout.Session | null>;
    /**
     * Create a Stripe Billing Portal session so the user can manage their
     * subscription (cancel, update payment method, etc.).
     * Returns the portal URL.
     */
    createPortalSession(customerId: string, returnUrl?: string): Promise<string>;
    /**
     * Look up the subscription status for a customer.
     * Returns `{ active: false, tier: "free" }` if no active subscription is found.
     */
    getSubscriptionStatus(customerId: string): Promise<SubscriptionStatus>;
    /**
     * Verify the webhook signature and parse the event.
     * Returns a typed `Stripe.Event` on success.
     * Throws on invalid signature.
     */
    verifyWebhook(body: string, signature: string): Promise<Stripe.Event>;
    /**
     * Process a Stripe webhook event and return the resulting tier change (if any).
     *
     * Handles:
     *   - customer.subscription.created / updated: set tier based on status
     *   - customer.subscription.deleted: downgrade to free
     *   - invoice.payment_failed: optionally handle grace periods
     *
     * Returns null if the event type is not one we act on.
     */
    handleWebhook(body: string, signature: string): Promise<WebhookResult | null>;
}
export interface WebhookResult {
    eventType: string;
    customerId: string;
    subscriptionId: string | null;
    /**
     * The QuantRisk API key associated with this subscription, taken from
     * `subscription.metadata.api_key`. Null when the subscription was created
     * outside our checkout flow (e.g., manually in the Stripe dashboard) or
     * for events that don't carry a subscription (invoice.payment_failed).
     */
    apiKey: string | null;
    /** null means "no tier change" (e.g. payment_failed — not yet downgraded) */
    newTier: UserTier | null;
    currentPeriodEnd: number | null;
}
//# sourceMappingURL=stripe.d.ts.map