import { f as InvalidAmountError, g as WebhookVerificationError, h as RefundFailedError, i as idempotencyKey } from "./src-BedZtlrm.js";
import Stripe from "stripe";
//#region src/stripe.ts
const DEFAULT_API_VERSION = "2026-04-22.dahlia";
/**
* Resolve the Connect split from the TYPED `req.stripe` extension only. Fails
* closed: an absent/blank `connectDestination` yields NO `transfer_data` (a
* normal non-split charge), never a metadata-sourced destination. A present
* destination must be a non-empty string (a typed-but-empty value is rejected
* rather than silently dropped onto an undefined transfer).
*/
function parseConnectSplit(extras) {
	if (!extras) return {};
	let transferData;
	if (extras.connectDestination !== void 0) {
		if (typeof extras.connectDestination !== "string" || extras.connectDestination.trim() === "") throw new Error("Stripe charge stripe.connectDestination must be a non-empty Connect account id");
		transferData = { destination: extras.connectDestination };
	}
	let applicationFeeAmount;
	if (extras.applicationFeeAmount !== void 0) {
		const fee = extras.applicationFeeAmount;
		if (typeof fee !== "number" || !Number.isInteger(fee) || fee < 0) throw new Error(`Stripe charge stripe.applicationFeeAmount must be a non-negative integer minor-units value, got ${fee}`);
		applicationFeeAmount = fee;
	}
	return {
		applicationFeeAmount,
		transferData
	};
}
async function classifyStripeEvent(event, client) {
	const base = { eventId: event.id };
	if (event.type === "payment_intent.succeeded") {
		const pi = event.data.object;
		const chargeKey = pi.metadata?.chargeKey;
		if (!chargeKey) return {
			...base,
			kind: "other",
			raw: event
		};
		return {
			...base,
			kind: "settlement",
			chargeKey,
			providerRef: pi.id,
			amount: pi.amount_received,
			currency: pi.currency.toUpperCase()
		};
	}
	if (event.type === "refund.created" || event.type === "refund.updated") {
		const refund = event.data.object;
		if (refund.status !== "succeeded") return {
			...base,
			kind: "other",
			raw: event
		};
		const paymentIntentId = typeof refund.payment_intent === "string" ? refund.payment_intent : refund.payment_intent?.id;
		if (!paymentIntentId) return {
			...base,
			kind: "other",
			raw: event
		};
		const pi = await client.paymentIntents.retrieve(paymentIntentId);
		const chargeKey = pi.metadata?.chargeKey;
		if (!chargeKey) return {
			...base,
			kind: "other",
			raw: event
		};
		return {
			...base,
			kind: "refund",
			refundKey: idempotencyKey([
				"refund",
				chargeKey,
				refund.id
			]),
			chargeKey,
			providerChargeId: paymentIntentId,
			providerRef: refund.id,
			amount: refund.amount ?? 0,
			currency: refund.currency?.toUpperCase() ?? pi.currency.toUpperCase()
		};
	}
	return {
		...base,
		kind: "other",
		raw: event
	};
}
const stripe = (creds) => {
	const { secretKey, webhookSecret, stripe: injected, apiVersion = DEFAULT_API_VERSION, authorizeConnectSplit, resolvePaymentIntentId } = creds;
	const client = injected ?? new Stripe(secretKey, { apiVersion });
	return {
		provider: "stripe",
		emitsInvoiceOnCharge: false,
		async charge(req) {
			const stripeExtras = req.stripe;
			const { applicationFeeAmount, transferData } = parseConnectSplit(stripeExtras);
			if (applicationFeeAmount !== void 0 && applicationFeeAmount > req.amount) throw new InvalidAmountError(`Stripe charge stripe.applicationFeeAmount ${applicationFeeAmount} exceeds the charge amount ${req.amount}`, {
				value: applicationFeeAmount,
				field: "stripe.applicationFeeAmount"
			});
			if (stripeExtras !== void 0 && (!authorizeConnectSplit || !await authorizeConnectSplit(req.chargeKey, stripeExtras))) throw new Error("Stripe charge Connect split is not authorized for this chargeKey");
			const currency = req.currency.toLowerCase();
			const params = {
				amount: req.amount,
				currency,
				metadata: {
					...req.metadata ?? {},
					chargeKey: req.chargeKey
				},
				...applicationFeeAmount !== void 0 ? { application_fee_amount: applicationFeeAmount } : {},
				...transferData ? { transfer_data: transferData } : {},
				automatic_payment_methods: { enabled: true }
			};
			const pi = await client.paymentIntents.create(params, { idempotencyKey: req.chargeKey });
			if (pi.status === "succeeded") return {
				kind: "settled",
				chargeKey: req.chargeKey,
				providerRef: pi.id,
				amount: pi.amount_received,
				currency: pi.currency.toUpperCase()
			};
			if (!pi.client_secret) throw new Error("Stripe PaymentIntent missing client_secret for client confirmation");
			return {
				kind: "requires_client_action",
				chargeKey: req.chargeKey,
				providerRef: pi.id,
				clientSecret: pi.client_secret
			};
		},
		async refund(req) {
			const stripeReq = req;
			if (!resolvePaymentIntentId) throw new Error("Stripe refund requires resolvePaymentIntentId authority in creds");
			const paymentIntent = await resolvePaymentIntentId(req.chargeKey);
			if (!paymentIntent) throw new Error("Stripe refund resolvePaymentIntentId returned no authoritative target");
			if (stripeReq.paymentIntentId && stripeReq.paymentIntentId !== paymentIntent) throw new Error("Stripe refund paymentIntentId does not match the authoritative charge target");
			const refund = await client.refunds.create({
				payment_intent: paymentIntent,
				amount: req.amount,
				reverse_transfer: true,
				refund_application_fee: true
			}, { idempotencyKey: req.refundKey });
			if (refund.status === "succeeded") {
				const currency = refund.currency?.toUpperCase();
				if (!currency) throw new Error("Stripe refund response missing currency");
				return {
					kind: "refunded",
					refundKey: idempotencyKey([
						"refund",
						req.chargeKey,
						refund.id
					]),
					chargeKey: req.chargeKey,
					providerRef: refund.id,
					amount: refund.amount ?? req.amount,
					currency
				};
			}
			if (refund.status === "pending" || refund.status === "requires_action") return { kind: "pending" };
			throw new RefundFailedError({
				chargeKey: req.chargeKey,
				providerRef: refund.id,
				status: refund.status ?? "unknown"
			});
		},
		async reconcileRefund(req) {
			if (req.amountMinor <= 0n || req.amountMinor > BigInt(Number.MAX_SAFE_INTEGER)) return {
				kind: "definite_failure",
				code: "INVALID_AMOUNT"
			};
			try {
				const refund = await client.refunds.create({
					payment_intent: req.providerChargeId,
					amount: Number(req.amountMinor)
				}, { idempotencyKey: req.refundKey });
				if (refund.status === "succeeded") return {
					kind: "confirmed",
					providerRefundId: refund.id,
					amountMinor: BigInt(refund.amount),
					currency: refund.currency.toUpperCase()
				};
				if (refund.status === "failed" || refund.status === "canceled") return {
					kind: "definite_failure",
					code: refund.status.toUpperCase()
				};
				return { kind: "pending_or_unknown" };
			} catch {
				return { kind: "pending_or_unknown" };
			}
		},
		async parseWebhook(raw, headers) {
			const sig = headers.get("stripe-signature");
			if (!sig) throw new WebhookVerificationError("missing stripe-signature header");
			let event;
			try {
				event = client.webhooks.constructEvent(raw, sig, webhookSecret);
			} catch (err) {
				throw new WebhookVerificationError(err instanceof Error ? err.message : "webhook verification failed");
			}
			return classifyStripeEvent(event, client);
		}
	};
};
//#endregion
export { classifyStripeEvent, stripe };
