@parsrun/payments 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/types.ts","../../src/providers/stripe.ts","../../src/providers/paddle.ts","../../src/providers/iyzico.ts"],"sourcesContent":["/**\n * @parsrun/payments - Type Definitions\n * Payment types and interfaces\n */\n\n// Re-export types from @parsrun/types for convenience\nexport {\n type,\n currencyCode,\n money,\n paymentCustomer,\n createCustomerRequest,\n cardDetails,\n paymentMethod,\n paymentIntentStatus,\n paymentIntent as parsPaymentIntent,\n createPaymentIntentRequest,\n subscriptionStatus as parsSubscriptionStatus,\n priceInterval,\n price as parsPrice,\n subscription as parsSubscription,\n createSubscriptionRequest,\n refundStatus,\n refund,\n createRefundRequest,\n webhookEventType,\n webhookEvent,\n stripeConfig,\n paddleConfig,\n iyzicoConfig,\n paymentsConfig,\n type CurrencyCode as ParsCurrencyCode,\n type Money,\n type PaymentCustomer,\n type CreateCustomerRequest as ParsCreateCustomerRequest,\n type CardDetails,\n type PaymentMethod as ParsPaymentMethod,\n type PaymentIntentStatus,\n type PaymentIntent as ParsPaymentIntentType,\n type CreatePaymentIntentRequest,\n type SubscriptionStatus as ParsSubscriptionStatus,\n type PriceInterval,\n type Price as ParsPrice,\n type Subscription as ParsSubscription,\n type CreateSubscriptionRequest as ParsCreateSubscriptionRequest,\n type RefundStatus,\n type Refund,\n type CreateRefundRequest,\n type WebhookEventType as ParsWebhookEventType,\n type WebhookEvent as ParsWebhookEvent,\n type StripeConfig,\n type PaddleConfig,\n type IyzicoConfig,\n type PaymentsConfig,\n} from \"@parsrun/types\";\n\n/**\n * Payment provider type\n */\nexport type PaymentProviderType = \"stripe\" | \"paddle\" | \"iyzico\";\n\n/**\n * Currency code (ISO 4217)\n */\nexport type CurrencyCode = \"USD\" | \"EUR\" | \"GBP\" | \"TRY\" | \"JPY\" | \"CAD\" | \"AUD\" | string;\n\n/**\n * Payment status\n */\nexport type PaymentStatus =\n | \"pending\"\n | \"processing\"\n | \"succeeded\"\n | \"failed\"\n | \"canceled\"\n | \"refunded\"\n | \"partially_refunded\";\n\n/**\n * Subscription status\n */\nexport type SubscriptionStatus =\n | \"active\"\n | \"past_due\"\n | \"unpaid\"\n | \"canceled\"\n | \"incomplete\"\n | \"incomplete_expired\"\n | \"trialing\"\n | \"paused\";\n\n/**\n * Billing interval\n */\nexport type BillingInterval = \"day\" | \"week\" | \"month\" | \"year\";\n\n// ============================================================================\n// Customer\n// ============================================================================\n\n/**\n * Customer data\n */\nexport interface Customer {\n /** Provider customer ID */\n id: string;\n /** Customer email */\n email: string;\n /** Customer name */\n name?: string | undefined;\n /** Phone number */\n phone?: string | undefined;\n /** Billing address */\n address?: Address | undefined;\n /** Custom metadata */\n metadata?: Record<string, string> | undefined;\n /** Provider-specific data */\n providerData?: unknown;\n}\n\n/**\n * Address\n */\nexport interface Address {\n line1?: string | undefined;\n line2?: string | undefined;\n city?: string | undefined;\n state?: string | undefined;\n postalCode?: string | undefined;\n country?: string | undefined;\n}\n\n/**\n * Create customer options\n */\nexport interface CreateCustomerOptions {\n email: string;\n name?: string | undefined;\n phone?: string | undefined;\n address?: Address | undefined;\n metadata?: Record<string, string> | undefined;\n}\n\n// ============================================================================\n// Products & Prices\n// ============================================================================\n\n/**\n * Product\n */\nexport interface Product {\n /** Provider product ID */\n id: string;\n /** Product name */\n name: string;\n /** Description */\n description?: string | undefined;\n /** Active status */\n active: boolean;\n /** Custom metadata */\n metadata?: Record<string, string> | undefined;\n /** Provider-specific data */\n providerData?: unknown;\n}\n\n/**\n * Price\n */\nexport interface Price {\n /** Provider price ID */\n id: string;\n /** Product ID */\n productId: string;\n /** Price in smallest currency unit (cents) */\n unitAmount: number;\n /** Currency */\n currency: CurrencyCode;\n /** Recurring billing details */\n recurring?: {\n interval: BillingInterval;\n intervalCount: number;\n } | undefined;\n /** Active status */\n active: boolean;\n /** Custom metadata */\n metadata?: Record<string, string> | undefined;\n /** Provider-specific data */\n providerData?: unknown;\n}\n\n// ============================================================================\n// Checkout\n// ============================================================================\n\n/**\n * Checkout line item\n */\nexport interface CheckoutLineItem {\n /** Price ID */\n priceId: string;\n /** Quantity */\n quantity: number;\n}\n\n/**\n * Create checkout options\n */\nexport interface CreateCheckoutOptions {\n /** Customer ID (optional, creates new if not provided) */\n customerId?: string | undefined;\n /** Customer email (for new customers) */\n customerEmail?: string | undefined;\n /** Line items */\n lineItems: CheckoutLineItem[];\n /** Success redirect URL */\n successUrl: string;\n /** Cancel redirect URL */\n cancelUrl: string;\n /** Checkout mode */\n mode: \"payment\" | \"subscription\" | \"setup\";\n /** Allow promotion codes */\n allowPromotionCodes?: boolean | undefined;\n /** Trial period days (subscription only) */\n trialDays?: number | undefined;\n /** Custom metadata */\n metadata?: Record<string, string> | undefined;\n /** Tenant ID for multi-tenant */\n tenantId?: string | undefined;\n}\n\n/**\n * Checkout session\n */\nexport interface CheckoutSession {\n /** Provider session ID */\n id: string;\n /** Checkout URL */\n url: string;\n /** Customer ID */\n customerId?: string | undefined;\n /** Payment status */\n status: \"open\" | \"complete\" | \"expired\";\n /** Mode */\n mode: \"payment\" | \"subscription\" | \"setup\";\n /** Amount total */\n amountTotal?: number | undefined;\n /** Currency */\n currency?: CurrencyCode | undefined;\n /** Provider-specific data */\n providerData?: unknown;\n}\n\n// ============================================================================\n// Subscriptions\n// ============================================================================\n\n/**\n * Subscription\n */\nexport interface Subscription {\n /** Provider subscription ID */\n id: string;\n /** Customer ID */\n customerId: string;\n /** Status */\n status: SubscriptionStatus;\n /** Price ID */\n priceId: string;\n /** Product ID */\n productId?: string | undefined;\n /** Current period start */\n currentPeriodStart: Date;\n /** Current period end */\n currentPeriodEnd: Date;\n /** Cancel at period end */\n cancelAtPeriodEnd: boolean;\n /** Canceled at */\n canceledAt?: Date | undefined;\n /** Trial start */\n trialStart?: Date | undefined;\n /** Trial end */\n trialEnd?: Date | undefined;\n /** Custom metadata */\n metadata?: Record<string, string> | undefined;\n /** Provider-specific data */\n providerData?: unknown;\n}\n\n/**\n * Create subscription options\n */\nexport interface CreateSubscriptionOptions {\n /** Customer ID */\n customerId: string;\n /** Price ID */\n priceId: string;\n /** Trial period days */\n trialDays?: number | undefined;\n /** Custom metadata */\n metadata?: Record<string, string> | undefined;\n /** Payment behavior */\n paymentBehavior?: \"default_incomplete\" | \"error_if_incomplete\" | \"allow_incomplete\" | undefined;\n}\n\n/**\n * Update subscription options\n */\nexport interface UpdateSubscriptionOptions {\n /** New price ID */\n priceId?: string | undefined;\n /** Cancel at period end */\n cancelAtPeriodEnd?: boolean | undefined;\n /** Custom metadata */\n metadata?: Record<string, string> | undefined;\n /** Proration behavior */\n prorationBehavior?: \"create_prorations\" | \"none\" | \"always_invoice\" | undefined;\n}\n\n// ============================================================================\n// Payments & Invoices\n// ============================================================================\n\n/**\n * Payment intent\n */\nexport interface PaymentIntent {\n /** Provider payment ID */\n id: string;\n /** Amount */\n amount: number;\n /** Currency */\n currency: CurrencyCode;\n /** Status */\n status: PaymentStatus;\n /** Customer ID */\n customerId?: string | undefined;\n /** Provider-specific data */\n providerData?: unknown;\n}\n\n/**\n * Invoice\n */\nexport interface Invoice {\n /** Provider invoice ID */\n id: string;\n /** Customer ID */\n customerId: string;\n /** Subscription ID */\n subscriptionId?: string | undefined;\n /** Status */\n status: \"draft\" | \"open\" | \"paid\" | \"void\" | \"uncollectible\";\n /** Amount due */\n amountDue: number;\n /** Amount paid */\n amountPaid: number;\n /** Currency */\n currency: CurrencyCode;\n /** Invoice URL */\n hostedInvoiceUrl?: string | undefined;\n /** PDF URL */\n invoicePdf?: string | undefined;\n /** Due date */\n dueDate?: Date | undefined;\n /** Provider-specific data */\n providerData?: unknown;\n}\n\n// ============================================================================\n// Portal\n// ============================================================================\n\n/**\n * Customer portal session\n */\nexport interface PortalSession {\n /** Portal URL */\n url: string;\n /** Return URL */\n returnUrl: string;\n}\n\n/**\n * Create portal options\n */\nexport interface CreatePortalOptions {\n /** Customer ID */\n customerId: string;\n /** Return URL */\n returnUrl: string;\n}\n\n// ============================================================================\n// Webhooks\n// ============================================================================\n\n/**\n * Webhook event types\n */\nexport type WebhookEventType =\n // Checkout\n | \"checkout.session.completed\"\n | \"checkout.session.expired\"\n // Customer\n | \"customer.created\"\n | \"customer.updated\"\n | \"customer.deleted\"\n // Subscription\n | \"subscription.created\"\n | \"subscription.updated\"\n | \"subscription.deleted\"\n | \"subscription.trial_will_end\"\n // Payment\n | \"payment.succeeded\"\n | \"payment.failed\"\n // Invoice\n | \"invoice.created\"\n | \"invoice.paid\"\n | \"invoice.payment_failed\"\n | \"invoice.upcoming\"\n // Refund\n | \"refund.created\"\n | \"refund.updated\";\n\n/**\n * Webhook event\n */\nexport interface WebhookEvent<T = unknown> {\n /** Event ID */\n id: string;\n /** Event type */\n type: WebhookEventType;\n /** Event data */\n data: T;\n /** Created timestamp */\n created: Date;\n /** Provider type */\n provider: PaymentProviderType;\n /** Raw event data */\n raw: unknown;\n}\n\n/**\n * Webhook handler\n */\nexport type WebhookHandler<T = unknown> = (\n event: WebhookEvent<T>\n) => void | Promise<void>;\n\n// ============================================================================\n// Provider Interface\n// ============================================================================\n\n/**\n * Payment provider interface\n */\nexport interface PaymentProvider {\n /** Provider type */\n readonly type: PaymentProviderType;\n\n // Customer\n createCustomer(options: CreateCustomerOptions): Promise<Customer>;\n getCustomer(customerId: string): Promise<Customer | null>;\n updateCustomer(customerId: string, options: Partial<CreateCustomerOptions>): Promise<Customer>;\n deleteCustomer(customerId: string): Promise<void>;\n\n // Checkout\n createCheckout(options: CreateCheckoutOptions): Promise<CheckoutSession>;\n getCheckout(sessionId: string): Promise<CheckoutSession | null>;\n\n // Subscriptions\n createSubscription(options: CreateSubscriptionOptions): Promise<Subscription>;\n getSubscription(subscriptionId: string): Promise<Subscription | null>;\n updateSubscription(subscriptionId: string, options: UpdateSubscriptionOptions): Promise<Subscription>;\n cancelSubscription(subscriptionId: string, cancelAtPeriodEnd?: boolean): Promise<Subscription>;\n listSubscriptions(customerId: string): Promise<Subscription[]>;\n\n // Portal\n createPortalSession(options: CreatePortalOptions): Promise<PortalSession>;\n\n // Webhooks\n verifyWebhook(payload: string | Uint8Array, signature: string): Promise<WebhookEvent | null>;\n\n // Products & Prices (optional)\n getProduct?(productId: string): Promise<Product | null>;\n getPrice?(priceId: string): Promise<Price | null>;\n listPrices?(productId?: string): Promise<Price[]>;\n}\n\n// ============================================================================\n// Provider Config\n// ============================================================================\n\n/**\n * Stripe provider config\n */\nexport interface StripeProviderConfig {\n /** Stripe secret key */\n secretKey: string;\n /** Webhook signing secret */\n webhookSecret?: string | undefined;\n /** API version */\n apiVersion?: string | undefined;\n}\n\n/**\n * Paddle provider config\n */\nexport interface PaddleProviderConfig {\n /** Paddle API key */\n apiKey: string;\n /** Paddle environment */\n environment?: \"sandbox\" | \"production\" | undefined;\n /** Webhook secret key */\n webhookSecret?: string | undefined;\n /** Seller ID */\n sellerId?: string | undefined;\n}\n\n// ============================================================================\n// Service Config\n// ============================================================================\n\n/**\n * Payment service config\n */\nexport interface PaymentServiceConfig {\n /** Payment provider */\n provider: PaymentProvider;\n /** Enable debug logging */\n debug?: boolean | undefined;\n}\n\n// ============================================================================\n// Errors\n// ============================================================================\n\n/**\n * Payment error\n */\nexport class PaymentError extends Error {\n constructor(\n message: string,\n public readonly code: string,\n public readonly cause?: unknown\n ) {\n super(message);\n this.name = \"PaymentError\";\n }\n}\n\n/**\n * Common payment error codes\n */\nexport const PaymentErrorCodes = {\n INVALID_CONFIG: \"INVALID_CONFIG\",\n CUSTOMER_NOT_FOUND: \"CUSTOMER_NOT_FOUND\",\n SUBSCRIPTION_NOT_FOUND: \"SUBSCRIPTION_NOT_FOUND\",\n CHECKOUT_FAILED: \"CHECKOUT_FAILED\",\n PAYMENT_FAILED: \"PAYMENT_FAILED\",\n WEBHOOK_VERIFICATION_FAILED: \"WEBHOOK_VERIFICATION_FAILED\",\n API_ERROR: \"API_ERROR\",\n RATE_LIMITED: \"RATE_LIMITED\",\n} as const;\n","/**\n * @parsrun/payments - Stripe Provider\n * Edge-compatible Stripe provider using fetch API\n */\n\nimport type {\n CheckoutSession,\n CreateCheckoutOptions,\n CreateCustomerOptions,\n CreatePortalOptions,\n CreateSubscriptionOptions,\n Customer,\n PaymentProvider,\n PortalSession,\n Price,\n Product,\n StripeProviderConfig,\n Subscription,\n SubscriptionStatus,\n UpdateSubscriptionOptions,\n WebhookEvent,\n WebhookEventType,\n} from \"../types.js\";\nimport { PaymentError, PaymentErrorCodes } from \"../types.js\";\n\n/**\n * Stripe Payment Provider\n * Edge-compatible using fetch API\n *\n * @example\n * ```typescript\n * const stripe = new StripeProvider({\n * secretKey: process.env.STRIPE_SECRET_KEY,\n * webhookSecret: process.env.STRIPE_WEBHOOK_SECRET,\n * });\n *\n * const checkout = await stripe.createCheckout({\n * lineItems: [{ priceId: 'price_xxx', quantity: 1 }],\n * successUrl: 'https://example.com/success',\n * cancelUrl: 'https://example.com/cancel',\n * mode: 'subscription',\n * });\n * ```\n */\nexport class StripeProvider implements PaymentProvider {\n readonly type = \"stripe\" as const;\n\n private secretKey: string;\n private webhookSecret: string | undefined;\n private baseUrl = \"https://api.stripe.com/v1\";\n private apiVersion: string;\n\n constructor(config: StripeProviderConfig) {\n this.secretKey = config.secretKey;\n this.webhookSecret = config.webhookSecret;\n this.apiVersion = config.apiVersion ?? \"2024-12-18.acacia\";\n }\n\n private async request<T>(\n endpoint: string,\n options: {\n method?: string;\n body?: Record<string, unknown>;\n } = {}\n ): Promise<T> {\n const { method = \"GET\", body } = options;\n\n const headers: Record<string, string> = {\n Authorization: `Bearer ${this.secretKey}`,\n \"Stripe-Version\": this.apiVersion,\n };\n\n const fetchOptions: RequestInit = {\n method,\n headers,\n };\n\n if (body) {\n headers[\"Content-Type\"] = \"application/x-www-form-urlencoded\";\n fetchOptions.body = this.encodeFormData(body);\n }\n\n const response = await fetch(`${this.baseUrl}${endpoint}`, fetchOptions);\n\n const data = await response.json() as T & { error?: { message: string; type: string; code?: string } };\n\n if (!response.ok || data.error) {\n const errorMessage = data.error?.message ?? `HTTP ${response.status}`;\n throw new PaymentError(\n `Stripe API error: ${errorMessage}`,\n data.error?.code ?? PaymentErrorCodes.API_ERROR,\n data.error\n );\n }\n\n return data;\n }\n\n private encodeFormData(obj: Record<string, unknown>, prefix = \"\"): string {\n const parts: string[] = [];\n\n for (const [key, value] of Object.entries(obj)) {\n if (value === undefined || value === null) continue;\n\n const fullKey = prefix ? `${prefix}[${key}]` : key;\n\n if (typeof value === \"object\" && !Array.isArray(value)) {\n parts.push(this.encodeFormData(value as Record<string, unknown>, fullKey));\n } else if (Array.isArray(value)) {\n value.forEach((item, index) => {\n if (typeof item === \"object\") {\n parts.push(this.encodeFormData(item as Record<string, unknown>, `${fullKey}[${index}]`));\n } else {\n parts.push(`${encodeURIComponent(`${fullKey}[${index}]`)}=${encodeURIComponent(String(item))}`);\n }\n });\n } else {\n parts.push(`${encodeURIComponent(fullKey)}=${encodeURIComponent(String(value))}`);\n }\n }\n\n return parts.filter(Boolean).join(\"&\");\n }\n\n // ============================================================================\n // Customer\n // ============================================================================\n\n async createCustomer(options: CreateCustomerOptions): Promise<Customer> {\n const body: Record<string, unknown> = {\n email: options.email,\n };\n\n if (options.name) body[\"name\"] = options.name;\n if (options.phone) body[\"phone\"] = options.phone;\n if (options.metadata) body[\"metadata\"] = options.metadata;\n if (options.address) {\n body[\"address\"] = {\n line1: options.address.line1,\n line2: options.address.line2,\n city: options.address.city,\n state: options.address.state,\n postal_code: options.address.postalCode,\n country: options.address.country,\n };\n }\n\n const result = await this.request<StripeCustomer>(\"/customers\", {\n method: \"POST\",\n body,\n });\n\n return this.mapCustomer(result);\n }\n\n async getCustomer(customerId: string): Promise<Customer | null> {\n try {\n const result = await this.request<StripeCustomer>(`/customers/${customerId}`);\n return this.mapCustomer(result);\n } catch (err) {\n if (err instanceof PaymentError && err.code === \"resource_missing\") {\n return null;\n }\n throw err;\n }\n }\n\n async updateCustomer(\n customerId: string,\n options: Partial<CreateCustomerOptions>\n ): Promise<Customer> {\n const body: Record<string, unknown> = {};\n\n if (options.email) body[\"email\"] = options.email;\n if (options.name) body[\"name\"] = options.name;\n if (options.phone) body[\"phone\"] = options.phone;\n if (options.metadata) body[\"metadata\"] = options.metadata;\n if (options.address) {\n body[\"address\"] = {\n line1: options.address.line1,\n line2: options.address.line2,\n city: options.address.city,\n state: options.address.state,\n postal_code: options.address.postalCode,\n country: options.address.country,\n };\n }\n\n const result = await this.request<StripeCustomer>(`/customers/${customerId}`, {\n method: \"POST\",\n body,\n });\n\n return this.mapCustomer(result);\n }\n\n async deleteCustomer(customerId: string): Promise<void> {\n await this.request(`/customers/${customerId}`, { method: \"DELETE\" });\n }\n\n private mapCustomer(stripe: StripeCustomer): Customer {\n return {\n id: stripe.id,\n email: stripe.email ?? \"\",\n name: stripe.name ?? undefined,\n phone: stripe.phone ?? undefined,\n address: stripe.address\n ? {\n line1: stripe.address.line1 ?? undefined,\n line2: stripe.address.line2 ?? undefined,\n city: stripe.address.city ?? undefined,\n state: stripe.address.state ?? undefined,\n postalCode: stripe.address.postal_code ?? undefined,\n country: stripe.address.country ?? undefined,\n }\n : undefined,\n metadata: stripe.metadata ?? undefined,\n providerData: stripe,\n };\n }\n\n // ============================================================================\n // Checkout\n // ============================================================================\n\n async createCheckout(options: CreateCheckoutOptions): Promise<CheckoutSession> {\n const body: Record<string, unknown> = {\n mode: options.mode,\n success_url: options.successUrl,\n cancel_url: options.cancelUrl,\n line_items: options.lineItems.map((item) => ({\n price: item.priceId,\n quantity: item.quantity,\n })),\n };\n\n if (options.customerId) body[\"customer\"] = options.customerId;\n if (options.customerEmail) body[\"customer_email\"] = options.customerEmail;\n if (options.allowPromotionCodes) body[\"allow_promotion_codes\"] = true;\n if (options.metadata) body[\"metadata\"] = options.metadata;\n\n if (options.mode === \"subscription\" && options.trialDays) {\n body[\"subscription_data\"] = {\n trial_period_days: options.trialDays,\n };\n }\n\n const result = await this.request<StripeCheckoutSession>(\"/checkout/sessions\", {\n method: \"POST\",\n body,\n });\n\n return this.mapCheckoutSession(result);\n }\n\n async getCheckout(sessionId: string): Promise<CheckoutSession | null> {\n try {\n const result = await this.request<StripeCheckoutSession>(\n `/checkout/sessions/${sessionId}`\n );\n return this.mapCheckoutSession(result);\n } catch (err) {\n if (err instanceof PaymentError && err.code === \"resource_missing\") {\n return null;\n }\n throw err;\n }\n }\n\n private mapCheckoutSession(stripe: StripeCheckoutSession): CheckoutSession {\n return {\n id: stripe.id,\n url: stripe.url ?? \"\",\n customerId: stripe.customer ?? undefined,\n status: stripe.status as \"open\" | \"complete\" | \"expired\",\n mode: stripe.mode as \"payment\" | \"subscription\" | \"setup\",\n amountTotal: stripe.amount_total ?? undefined,\n currency: stripe.currency ?? undefined,\n providerData: stripe,\n };\n }\n\n // ============================================================================\n // Subscriptions\n // ============================================================================\n\n async createSubscription(options: CreateSubscriptionOptions): Promise<Subscription> {\n const body: Record<string, unknown> = {\n customer: options.customerId,\n items: [{ price: options.priceId }],\n };\n\n if (options.trialDays) body[\"trial_period_days\"] = options.trialDays;\n if (options.metadata) body[\"metadata\"] = options.metadata;\n if (options.paymentBehavior) body[\"payment_behavior\"] = options.paymentBehavior;\n\n const result = await this.request<StripeSubscription>(\"/subscriptions\", {\n method: \"POST\",\n body,\n });\n\n return this.mapSubscription(result);\n }\n\n async getSubscription(subscriptionId: string): Promise<Subscription | null> {\n try {\n const result = await this.request<StripeSubscription>(\n `/subscriptions/${subscriptionId}`\n );\n return this.mapSubscription(result);\n } catch (err) {\n if (err instanceof PaymentError && err.code === \"resource_missing\") {\n return null;\n }\n throw err;\n }\n }\n\n async updateSubscription(\n subscriptionId: string,\n options: UpdateSubscriptionOptions\n ): Promise<Subscription> {\n const body: Record<string, unknown> = {};\n\n if (options.cancelAtPeriodEnd !== undefined) {\n body[\"cancel_at_period_end\"] = options.cancelAtPeriodEnd;\n }\n if (options.metadata) body[\"metadata\"] = options.metadata;\n if (options.prorationBehavior) body[\"proration_behavior\"] = options.prorationBehavior;\n\n // Price change requires updating subscription items\n if (options.priceId) {\n // Get current subscription to find item ID\n const current = await this.request<StripeSubscription>(\n `/subscriptions/${subscriptionId}`\n );\n const itemId = current.items.data[0]?.id;\n if (itemId) {\n body[\"items\"] = [{ id: itemId, price: options.priceId }];\n }\n }\n\n const result = await this.request<StripeSubscription>(\n `/subscriptions/${subscriptionId}`,\n { method: \"POST\", body }\n );\n\n return this.mapSubscription(result);\n }\n\n async cancelSubscription(\n subscriptionId: string,\n cancelAtPeriodEnd = true\n ): Promise<Subscription> {\n if (cancelAtPeriodEnd) {\n return this.updateSubscription(subscriptionId, { cancelAtPeriodEnd: true });\n }\n\n const result = await this.request<StripeSubscription>(\n `/subscriptions/${subscriptionId}`,\n { method: \"DELETE\" }\n );\n\n return this.mapSubscription(result);\n }\n\n async listSubscriptions(customerId: string): Promise<Subscription[]> {\n const result = await this.request<{ data: StripeSubscription[] }>(\n `/subscriptions?customer=${customerId}`\n );\n\n return result.data.map((sub) => this.mapSubscription(sub));\n }\n\n private mapSubscription(stripe: StripeSubscription): Subscription {\n const item = stripe.items.data[0];\n\n return {\n id: stripe.id,\n customerId: typeof stripe.customer === \"string\" ? stripe.customer : stripe.customer.id,\n status: stripe.status as SubscriptionStatus,\n priceId: item?.price.id ?? \"\",\n productId: typeof item?.price.product === \"string\" ? item.price.product : item?.price.product?.id,\n currentPeriodStart: new Date(stripe.current_period_start * 1000),\n currentPeriodEnd: new Date(stripe.current_period_end * 1000),\n cancelAtPeriodEnd: stripe.cancel_at_period_end,\n canceledAt: stripe.canceled_at ? new Date(stripe.canceled_at * 1000) : undefined,\n trialStart: stripe.trial_start ? new Date(stripe.trial_start * 1000) : undefined,\n trialEnd: stripe.trial_end ? new Date(stripe.trial_end * 1000) : undefined,\n metadata: stripe.metadata ?? undefined,\n providerData: stripe,\n };\n }\n\n // ============================================================================\n // Portal\n // ============================================================================\n\n async createPortalSession(options: CreatePortalOptions): Promise<PortalSession> {\n const result = await this.request<{ url: string }>(\"/billing_portal/sessions\", {\n method: \"POST\",\n body: {\n customer: options.customerId,\n return_url: options.returnUrl,\n },\n });\n\n return {\n url: result.url,\n returnUrl: options.returnUrl,\n };\n }\n\n // ============================================================================\n // Products & Prices\n // ============================================================================\n\n async getProduct(productId: string): Promise<Product | null> {\n try {\n const result = await this.request<StripeProduct>(`/products/${productId}`);\n return this.mapProduct(result);\n } catch (err) {\n if (err instanceof PaymentError && err.code === \"resource_missing\") {\n return null;\n }\n throw err;\n }\n }\n\n async getPrice(priceId: string): Promise<Price | null> {\n try {\n const result = await this.request<StripePrice>(`/prices/${priceId}`);\n return this.mapPrice(result);\n } catch (err) {\n if (err instanceof PaymentError && err.code === \"resource_missing\") {\n return null;\n }\n throw err;\n }\n }\n\n async listPrices(productId?: string): Promise<Price[]> {\n let endpoint = \"/prices?active=true&limit=100\";\n if (productId) {\n endpoint += `&product=${productId}`;\n }\n\n const result = await this.request<{ data: StripePrice[] }>(endpoint);\n return result.data.map((price) => this.mapPrice(price));\n }\n\n private mapProduct(stripe: StripeProduct): Product {\n return {\n id: stripe.id,\n name: stripe.name,\n description: stripe.description ?? undefined,\n active: stripe.active,\n metadata: stripe.metadata ?? undefined,\n providerData: stripe,\n };\n }\n\n private mapPrice(stripe: StripePrice): Price {\n return {\n id: stripe.id,\n productId: typeof stripe.product === \"string\" ? stripe.product : stripe.product.id,\n unitAmount: stripe.unit_amount ?? 0,\n currency: stripe.currency.toUpperCase(),\n recurring: stripe.recurring\n ? {\n interval: stripe.recurring.interval as \"day\" | \"week\" | \"month\" | \"year\",\n intervalCount: stripe.recurring.interval_count,\n }\n : undefined,\n active: stripe.active,\n metadata: stripe.metadata ?? undefined,\n providerData: stripe,\n };\n }\n\n // ============================================================================\n // Webhooks\n // ============================================================================\n\n async verifyWebhook(\n payload: string | Uint8Array,\n signature: string\n ): Promise<WebhookEvent | null> {\n if (!this.webhookSecret) {\n throw new PaymentError(\n \"Webhook secret not configured\",\n PaymentErrorCodes.INVALID_CONFIG\n );\n }\n\n const payloadString = typeof payload === \"string\" ? payload : new TextDecoder().decode(payload);\n\n // Parse signature header\n const signatureParts = signature.split(\",\").reduce((acc, part) => {\n const [key, value] = part.split(\"=\");\n if (key && value) {\n acc[key] = value;\n }\n return acc;\n }, {} as Record<string, string>);\n\n const timestamp = signatureParts[\"t\"];\n const expectedSignature = signatureParts[\"v1\"];\n\n if (!timestamp || !expectedSignature) {\n return null;\n }\n\n // Check timestamp (within 5 minutes)\n const timestampSeconds = parseInt(timestamp, 10);\n const now = Math.floor(Date.now() / 1000);\n if (Math.abs(now - timestampSeconds) > 300) {\n return null;\n }\n\n // Compute expected signature\n const signedPayload = `${timestamp}.${payloadString}`;\n const computedSignature = await this.computeHmacSignature(\n signedPayload,\n this.webhookSecret\n );\n\n // Constant-time comparison\n if (!this.secureCompare(computedSignature, expectedSignature)) {\n return null;\n }\n\n // Parse event\n const event = JSON.parse(payloadString) as StripeWebhookEvent;\n\n return {\n id: event.id,\n type: this.mapEventType(event.type),\n data: event.data.object,\n created: new Date(event.created * 1000),\n provider: \"stripe\",\n raw: event,\n };\n }\n\n private async computeHmacSignature(payload: string, secret: string): Promise<string> {\n const encoder = new TextEncoder();\n const keyData = encoder.encode(secret);\n const messageData = encoder.encode(payload);\n\n const cryptoKey = await crypto.subtle.importKey(\n \"raw\",\n keyData,\n { name: \"HMAC\", hash: \"SHA-256\" },\n false,\n [\"sign\"]\n );\n\n const signature = await crypto.subtle.sign(\"HMAC\", cryptoKey, messageData);\n const signatureArray = new Uint8Array(signature);\n\n return Array.from(signatureArray)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n }\n\n private secureCompare(a: string, b: string): boolean {\n if (a.length !== b.length) return false;\n\n let result = 0;\n for (let i = 0; i < a.length; i++) {\n result |= a.charCodeAt(i) ^ b.charCodeAt(i);\n }\n return result === 0;\n }\n\n private mapEventType(stripeType: string): WebhookEventType {\n const mapping: Record<string, WebhookEventType> = {\n \"checkout.session.completed\": \"checkout.session.completed\",\n \"checkout.session.expired\": \"checkout.session.expired\",\n \"customer.created\": \"customer.created\",\n \"customer.updated\": \"customer.updated\",\n \"customer.deleted\": \"customer.deleted\",\n \"customer.subscription.created\": \"subscription.created\",\n \"customer.subscription.updated\": \"subscription.updated\",\n \"customer.subscription.deleted\": \"subscription.deleted\",\n \"customer.subscription.trial_will_end\": \"subscription.trial_will_end\",\n \"payment_intent.succeeded\": \"payment.succeeded\",\n \"payment_intent.payment_failed\": \"payment.failed\",\n \"invoice.created\": \"invoice.created\",\n \"invoice.paid\": \"invoice.paid\",\n \"invoice.payment_failed\": \"invoice.payment_failed\",\n \"invoice.upcoming\": \"invoice.upcoming\",\n \"charge.refunded\": \"refund.created\",\n \"refund.created\": \"refund.created\",\n \"refund.updated\": \"refund.updated\",\n };\n\n return mapping[stripeType] ?? (\"unknown\" as WebhookEventType);\n }\n\n // ============================================================================\n // Usage Reporting (Metered Billing)\n // ============================================================================\n\n /**\n * Report usage for metered billing\n *\n * @example\n * ```typescript\n * // Report 100 API calls for a subscription item\n * await stripe.reportUsage({\n * subscriptionItemId: \"si_xxx\",\n * quantity: 100,\n * action: \"increment\", // or \"set\" to replace\n * });\n * ```\n */\n async reportUsage(record: {\n subscriptionItemId: string;\n quantity: number;\n timestamp?: Date;\n action?: \"increment\" | \"set\";\n idempotencyKey?: string;\n }): Promise<void> {\n const body: Record<string, unknown> = {\n quantity: record.quantity,\n action: record.action ?? \"increment\",\n };\n\n if (record.timestamp) {\n body[\"timestamp\"] = Math.floor(record.timestamp.getTime() / 1000);\n }\n\n const headers: Record<string, string> = {};\n if (record.idempotencyKey) {\n headers[\"Idempotency-Key\"] = record.idempotencyKey;\n }\n\n await this.request<StripeUsageRecord>(\n `/subscription_items/${record.subscriptionItemId}/usage_records`,\n {\n method: \"POST\",\n body,\n }\n );\n }\n\n /**\n * Report multiple usage records (batch)\n * Note: Stripe doesn't have a batch API, so this is sequential\n */\n async reportUsageBatch(records: Array<{\n subscriptionItemId: string;\n quantity: number;\n timestamp?: Date;\n action?: \"increment\" | \"set\";\n idempotencyKey?: string;\n }>): Promise<void> {\n for (const record of records) {\n await this.reportUsage(record);\n }\n }\n\n /**\n * Get subscription item ID for a subscription and price\n */\n async getSubscriptionItemId(\n subscriptionId: string,\n priceId: string\n ): Promise<string | null> {\n const subscription = await this.request<StripeSubscription>(\n `/subscriptions/${subscriptionId}`\n );\n\n const item = subscription.items.data.find((i) => i.price.id === priceId);\n return item?.id ?? null;\n }\n\n /**\n * Get usage records for a subscription item\n */\n async getUsageRecords(\n subscriptionItemId: string,\n options?: {\n startingAfter?: string;\n endingBefore?: string;\n limit?: number;\n }\n ): Promise<{\n data: Array<{\n id: string;\n quantity: number;\n timestamp: Date;\n subscriptionItem: string;\n }>;\n hasMore: boolean;\n }> {\n let endpoint = `/subscription_items/${subscriptionItemId}/usage_record_summaries?`;\n\n if (options?.limit) {\n endpoint += `limit=${options.limit}&`;\n }\n if (options?.startingAfter) {\n endpoint += `starting_after=${options.startingAfter}&`;\n }\n if (options?.endingBefore) {\n endpoint += `ending_before=${options.endingBefore}&`;\n }\n\n const result = await this.request<{\n data: StripeUsageRecordSummary[];\n has_more: boolean;\n }>(endpoint);\n\n return {\n data: result.data.map((r) => ({\n id: r.id,\n quantity: r.total_usage,\n timestamp: new Date(r.period.start * 1000),\n subscriptionItem: r.subscription_item,\n })),\n hasMore: result.has_more,\n };\n }\n\n /**\n * Get current period usage total for a subscription item\n */\n async getCurrentUsage(subscriptionItemId: string): Promise<number> {\n const result = await this.getUsageRecords(subscriptionItemId, { limit: 1 });\n return result.data[0]?.quantity ?? 0;\n }\n}\n\n// ============================================================================\n// Stripe API Types\n// ============================================================================\n\ninterface StripeCustomer {\n id: string;\n email: string | null;\n name: string | null;\n phone: string | null;\n address: {\n line1: string | null;\n line2: string | null;\n city: string | null;\n state: string | null;\n postal_code: string | null;\n country: string | null;\n } | null;\n metadata: Record<string, string> | null;\n}\n\ninterface StripeCheckoutSession {\n id: string;\n url: string | null;\n customer: string | null;\n status: string;\n mode: string;\n amount_total: number | null;\n currency: string | null;\n}\n\ninterface StripeSubscription {\n id: string;\n customer: string | { id: string };\n status: string;\n items: {\n data: Array<{\n id: string;\n price: StripePrice;\n }>;\n };\n current_period_start: number;\n current_period_end: number;\n cancel_at_period_end: boolean;\n canceled_at: number | null;\n trial_start: number | null;\n trial_end: number | null;\n metadata: Record<string, string> | null;\n}\n\ninterface StripeProduct {\n id: string;\n name: string;\n description: string | null;\n active: boolean;\n metadata: Record<string, string> | null;\n}\n\ninterface StripePrice {\n id: string;\n product: string | { id: string };\n unit_amount: number | null;\n currency: string;\n recurring: {\n interval: string;\n interval_count: number;\n } | null;\n active: boolean;\n metadata: Record<string, string> | null;\n}\n\ninterface StripeWebhookEvent {\n id: string;\n type: string;\n created: number;\n data: {\n object: unknown;\n };\n}\n\ninterface StripeUsageRecord {\n id: string;\n object: \"usage_record\";\n quantity: number;\n subscription_item: string;\n timestamp: number;\n}\n\ninterface StripeUsageRecordSummary {\n id: string;\n object: \"usage_record_summary\";\n invoice: string | null;\n period: {\n start: number;\n end: number;\n };\n subscription_item: string;\n total_usage: number;\n}\n\n/**\n * Create a Stripe provider\n */\nexport function createStripeProvider(config: StripeProviderConfig): StripeProvider {\n return new StripeProvider(config);\n}\n","/**\n * @parsrun/payments - Paddle Provider\n * Edge-compatible Paddle provider using fetch API (Paddle Billing API v2)\n */\n\nimport type {\n CheckoutSession,\n CreateCheckoutOptions,\n CreateCustomerOptions,\n CreatePortalOptions,\n CreateSubscriptionOptions,\n Customer,\n PaddleProviderConfig,\n PaymentProvider,\n PortalSession,\n Price,\n Product,\n Subscription,\n SubscriptionStatus,\n UpdateSubscriptionOptions,\n WebhookEvent,\n WebhookEventType,\n} from \"../types.js\";\nimport { PaymentError, PaymentErrorCodes } from \"../types.js\";\n\n/**\n * Paddle Payment Provider\n * Edge-compatible using fetch API (Paddle Billing API v2)\n *\n * @example\n * ```typescript\n * const paddle = new PaddleProvider({\n * apiKey: process.env.PADDLE_API_KEY,\n * environment: 'sandbox', // or 'production'\n * webhookSecret: process.env.PADDLE_WEBHOOK_SECRET,\n * });\n *\n * const checkout = await paddle.createCheckout({\n * lineItems: [{ priceId: 'pri_xxx', quantity: 1 }],\n * successUrl: 'https://example.com/success',\n * cancelUrl: 'https://example.com/cancel',\n * mode: 'subscription',\n * });\n * ```\n */\nexport class PaddleProvider implements PaymentProvider {\n readonly type = \"paddle\" as const;\n\n private apiKey: string;\n private webhookSecret: string | undefined;\n private baseUrl: string;\n\n constructor(config: PaddleProviderConfig) {\n this.apiKey = config.apiKey;\n this.webhookSecret = config.webhookSecret;\n this.baseUrl =\n config.environment === \"production\"\n ? \"https://api.paddle.com\"\n : \"https://sandbox-api.paddle.com\";\n }\n\n private async request<T>(\n endpoint: string,\n options: {\n method?: string;\n body?: Record<string, unknown>;\n } = {}\n ): Promise<T> {\n const { method = \"GET\", body } = options;\n\n const headers: Record<string, string> = {\n Authorization: `Bearer ${this.apiKey}`,\n \"Content-Type\": \"application/json\",\n };\n\n const fetchOptions: RequestInit = {\n method,\n headers,\n };\n\n if (body) {\n fetchOptions.body = JSON.stringify(body);\n }\n\n const response = await fetch(`${this.baseUrl}${endpoint}`, fetchOptions);\n\n const data = await response.json() as {\n data?: T;\n error?: { type: string; code: string; detail: string };\n };\n\n if (!response.ok || data.error) {\n const errorMessage = data.error?.detail ?? `HTTP ${response.status}`;\n throw new PaymentError(\n `Paddle API error: ${errorMessage}`,\n data.error?.code ?? PaymentErrorCodes.API_ERROR,\n data.error\n );\n }\n\n return data.data as T;\n }\n\n // ============================================================================\n // Customer\n // ============================================================================\n\n async createCustomer(options: CreateCustomerOptions): Promise<Customer> {\n const body: Record<string, unknown> = {\n email: options.email,\n };\n\n if (options.name) body[\"name\"] = options.name;\n if (options.metadata) body[\"custom_data\"] = options.metadata;\n\n const result = await this.request<PaddleCustomer>(\"/customers\", {\n method: \"POST\",\n body,\n });\n\n return this.mapCustomer(result);\n }\n\n async getCustomer(customerId: string): Promise<Customer | null> {\n try {\n const result = await this.request<PaddleCustomer>(`/customers/${customerId}`);\n return this.mapCustomer(result);\n } catch (err) {\n if (err instanceof PaymentError && err.code === \"not_found\") {\n return null;\n }\n throw err;\n }\n }\n\n async updateCustomer(\n customerId: string,\n options: Partial<CreateCustomerOptions>\n ): Promise<Customer> {\n const body: Record<string, unknown> = {};\n\n if (options.email) body[\"email\"] = options.email;\n if (options.name) body[\"name\"] = options.name;\n if (options.metadata) body[\"custom_data\"] = options.metadata;\n\n const result = await this.request<PaddleCustomer>(`/customers/${customerId}`, {\n method: \"PATCH\",\n body,\n });\n\n return this.mapCustomer(result);\n }\n\n async deleteCustomer(_customerId: string): Promise<void> {\n // Paddle doesn't support customer deletion via API\n // Customers can only be archived\n throw new PaymentError(\n \"Paddle does not support customer deletion\",\n PaymentErrorCodes.API_ERROR\n );\n }\n\n private mapCustomer(paddle: PaddleCustomer): Customer {\n return {\n id: paddle.id,\n email: paddle.email,\n name: paddle.name ?? undefined,\n metadata: paddle.custom_data ?? undefined,\n providerData: paddle,\n };\n }\n\n // ============================================================================\n // Checkout\n // ============================================================================\n\n async createCheckout(options: CreateCheckoutOptions): Promise<CheckoutSession> {\n const items = options.lineItems.map((item) => ({\n price_id: item.priceId,\n quantity: item.quantity,\n }));\n\n const body: Record<string, unknown> = {\n items,\n };\n\n if (options.customerId) body[\"customer_id\"] = options.customerId;\n if (options.customerEmail) {\n body[\"customer\"] = { email: options.customerEmail };\n }\n if (options.metadata) body[\"custom_data\"] = options.metadata;\n\n // Paddle handles return URLs differently - they're configured in dashboard\n // or passed as settings\n body[\"settings\"] = {\n success_url: options.successUrl,\n };\n\n const result = await this.request<PaddleTransaction>(\"/transactions\", {\n method: \"POST\",\n body,\n });\n\n return {\n id: result.id,\n url: result.checkout?.url ?? \"\",\n customerId: result.customer_id ?? undefined,\n status: result.status === \"completed\" ? \"complete\" : \"open\",\n mode: result.subscription_id ? \"subscription\" : \"payment\",\n amountTotal: this.parsePaddleAmount(result.details?.totals?.total),\n currency: result.currency_code,\n providerData: result,\n };\n }\n\n async getCheckout(sessionId: string): Promise<CheckoutSession | null> {\n try {\n const result = await this.request<PaddleTransaction>(`/transactions/${sessionId}`);\n\n return {\n id: result.id,\n url: result.checkout?.url ?? \"\",\n customerId: result.customer_id ?? undefined,\n status: result.status === \"completed\" ? \"complete\" : \"open\",\n mode: result.subscription_id ? \"subscription\" : \"payment\",\n amountTotal: this.parsePaddleAmount(result.details?.totals?.total),\n currency: result.currency_code,\n providerData: result,\n };\n } catch (err) {\n if (err instanceof PaymentError && err.code === \"not_found\") {\n return null;\n }\n throw err;\n }\n }\n\n // ============================================================================\n // Subscriptions\n // ============================================================================\n\n async createSubscription(_options: CreateSubscriptionOptions): Promise<Subscription> {\n // Paddle subscriptions are created through the checkout flow\n // Direct subscription creation is not supported\n throw new PaymentError(\n \"Paddle subscriptions must be created through checkout\",\n PaymentErrorCodes.API_ERROR\n );\n }\n\n async getSubscription(subscriptionId: string): Promise<Subscription | null> {\n try {\n const result = await this.request<PaddleSubscription>(\n `/subscriptions/${subscriptionId}`\n );\n return this.mapSubscription(result);\n } catch (err) {\n if (err instanceof PaymentError && err.code === \"not_found\") {\n return null;\n }\n throw err;\n }\n }\n\n async updateSubscription(\n subscriptionId: string,\n options: UpdateSubscriptionOptions\n ): Promise<Subscription> {\n const body: Record<string, unknown> = {};\n\n if (options.priceId) {\n body[\"items\"] = [{ price_id: options.priceId, quantity: 1 }];\n }\n if (options.metadata) body[\"custom_data\"] = options.metadata;\n if (options.prorationBehavior) {\n body[\"proration_billing_mode\"] =\n options.prorationBehavior === \"none\" ? \"do_not_bill\" : \"prorated_immediately\";\n }\n\n const result = await this.request<PaddleSubscription>(\n `/subscriptions/${subscriptionId}`,\n { method: \"PATCH\", body }\n );\n\n return this.mapSubscription(result);\n }\n\n async cancelSubscription(\n subscriptionId: string,\n cancelAtPeriodEnd = true\n ): Promise<Subscription> {\n const body: Record<string, unknown> = {\n effective_from: cancelAtPeriodEnd ? \"next_billing_period\" : \"immediately\",\n };\n\n const result = await this.request<PaddleSubscription>(\n `/subscriptions/${subscriptionId}/cancel`,\n { method: \"POST\", body }\n );\n\n return this.mapSubscription(result);\n }\n\n async listSubscriptions(customerId: string): Promise<Subscription[]> {\n const result = await this.request<PaddleSubscription[]>(\n `/subscriptions?customer_id=${customerId}`\n );\n\n return result.map((sub) => this.mapSubscription(sub));\n }\n\n private mapSubscription(paddle: PaddleSubscription): Subscription {\n const item = paddle.items?.[0];\n\n const statusMap: Record<string, SubscriptionStatus> = {\n active: \"active\",\n canceled: \"canceled\",\n past_due: \"past_due\",\n paused: \"paused\",\n trialing: \"trialing\",\n };\n\n return {\n id: paddle.id,\n customerId: paddle.customer_id,\n status: statusMap[paddle.status] ?? \"active\",\n priceId: item?.price?.id ?? \"\",\n productId: item?.price?.product_id,\n currentPeriodStart: new Date(paddle.current_billing_period?.starts_at ?? Date.now()),\n currentPeriodEnd: new Date(paddle.current_billing_period?.ends_at ?? Date.now()),\n cancelAtPeriodEnd: paddle.scheduled_change?.action === \"cancel\",\n canceledAt: paddle.canceled_at ? new Date(paddle.canceled_at) : undefined,\n trialStart: paddle.started_at ? new Date(paddle.started_at) : undefined,\n trialEnd: paddle.first_billed_at ? new Date(paddle.first_billed_at) : undefined,\n metadata: paddle.custom_data ?? undefined,\n providerData: paddle,\n };\n }\n\n // ============================================================================\n // Portal\n // ============================================================================\n\n async createPortalSession(options: CreatePortalOptions): Promise<PortalSession> {\n // Paddle uses customer portal links that are generated per customer\n // Get customer to retrieve portal session\n const customer = await this.getCustomer(options.customerId);\n if (!customer) {\n throw new PaymentError(\n \"Customer not found\",\n PaymentErrorCodes.CUSTOMER_NOT_FOUND\n );\n }\n\n // In Paddle Billing, you need to create a portal session\n // This creates a session link for the customer portal\n const result = await this.request<{ urls: { general: { overview: string } } }>(\n `/customers/${options.customerId}/portal-sessions`,\n { method: \"POST\" }\n );\n\n return {\n url: result.urls.general.overview,\n returnUrl: options.returnUrl,\n };\n }\n\n // ============================================================================\n // Products & Prices\n // ============================================================================\n\n async getProduct(productId: string): Promise<Product | null> {\n try {\n const result = await this.request<PaddleProduct>(`/products/${productId}`);\n return this.mapProduct(result);\n } catch (err) {\n if (err instanceof PaymentError && err.code === \"not_found\") {\n return null;\n }\n throw err;\n }\n }\n\n async getPrice(priceId: string): Promise<Price | null> {\n try {\n const result = await this.request<PaddlePrice>(`/prices/${priceId}`);\n return this.mapPrice(result);\n } catch (err) {\n if (err instanceof PaymentError && err.code === \"not_found\") {\n return null;\n }\n throw err;\n }\n }\n\n async listPrices(productId?: string): Promise<Price[]> {\n let endpoint = \"/prices?status=active\";\n if (productId) {\n endpoint += `&product_id=${productId}`;\n }\n\n const result = await this.request<PaddlePrice[]>(endpoint);\n return result.map((price) => this.mapPrice(price));\n }\n\n private mapProduct(paddle: PaddleProduct): Product {\n return {\n id: paddle.id,\n name: paddle.name,\n description: paddle.description ?? undefined,\n active: paddle.status === \"active\",\n metadata: paddle.custom_data ?? undefined,\n providerData: paddle,\n };\n }\n\n private mapPrice(paddle: PaddlePrice): Price {\n const amount = paddle.unit_price?.amount\n ? parseInt(paddle.unit_price.amount, 10)\n : 0;\n\n return {\n id: paddle.id,\n productId: paddle.product_id,\n unitAmount: amount,\n currency: paddle.unit_price?.currency_code ?? \"USD\",\n recurring: paddle.billing_cycle\n ? {\n interval: paddle.billing_cycle.interval as \"day\" | \"week\" | \"month\" | \"year\",\n intervalCount: paddle.billing_cycle.frequency,\n }\n : undefined,\n active: paddle.status === \"active\",\n metadata: paddle.custom_data ?? undefined,\n providerData: paddle,\n };\n }\n\n private parsePaddleAmount(amount?: string): number | undefined {\n if (!amount) return undefined;\n return parseInt(amount, 10);\n }\n\n // ============================================================================\n // Webhooks\n // ============================================================================\n\n async verifyWebhook(\n payload: string | Uint8Array,\n signature: string\n ): Promise<WebhookEvent | null> {\n if (!this.webhookSecret) {\n throw new PaymentError(\n \"Webhook secret not configured\",\n PaymentErrorCodes.INVALID_CONFIG\n );\n }\n\n const payloadString = typeof payload === \"string\" ? payload : new TextDecoder().decode(payload);\n\n // Parse Paddle signature header (ts=xxx;h1=xxx)\n const signatureParts = signature.split(\";\").reduce((acc, part) => {\n const [key, value] = part.split(\"=\");\n if (key && value) {\n acc[key] = value;\n }\n return acc;\n }, {} as Record<string, string>);\n\n const timestamp = signatureParts[\"ts\"];\n const expectedSignature = signatureParts[\"h1\"];\n\n if (!timestamp || !expectedSignature) {\n return null;\n }\n\n // Compute expected signature\n const signedPayload = `${timestamp}:${payloadString}`;\n const computedSignature = await this.computeHmacSignature(\n signedPayload,\n this.webhookSecret\n );\n\n // Constant-time comparison\n if (!this.secureCompare(computedSignature, expectedSignature)) {\n return null;\n }\n\n // Parse event\n const event = JSON.parse(payloadString) as PaddleWebhookEvent;\n\n return {\n id: event.event_id,\n type: this.mapEventType(event.event_type),\n data: event.data,\n created: new Date(event.occurred_at),\n provider: \"paddle\",\n raw: event,\n };\n }\n\n private async computeHmacSignature(payload: string, secret: string): Promise<string> {\n const encoder = new TextEncoder();\n const keyData = encoder.encode(secret);\n const messageData = encoder.encode(payload);\n\n const cryptoKey = await crypto.subtle.importKey(\n \"raw\",\n keyData,\n { name: \"HMAC\", hash: \"SHA-256\" },\n false,\n [\"sign\"]\n );\n\n const signature = await crypto.subtle.sign(\"HMAC\", cryptoKey, messageData);\n const signatureArray = new Uint8Array(signature);\n\n return Array.from(signatureArray)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n }\n\n private secureCompare(a: string, b: string): boolean {\n if (a.length !== b.length) return false;\n\n let result = 0;\n for (let i = 0; i < a.length; i++) {\n result |= a.charCodeAt(i) ^ b.charCodeAt(i);\n }\n return result === 0;\n }\n\n private mapEventType(paddleType: string): WebhookEventType {\n const mapping: Record<string, WebhookEventType> = {\n \"transaction.completed\": \"checkout.session.completed\",\n \"customer.created\": \"customer.created\",\n \"customer.updated\": \"customer.updated\",\n \"subscription.created\": \"subscription.created\",\n \"subscription.updated\": \"subscription.updated\",\n \"subscription.canceled\": \"subscription.deleted\",\n \"subscription.past_due\": \"subscription.updated\",\n \"subscription.activated\": \"subscription.created\",\n \"transaction.payment_failed\": \"payment.failed\",\n \"adjustment.created\": \"refund.created\",\n };\n\n return mapping[paddleType] ?? (\"unknown\" as WebhookEventType);\n }\n}\n\n// ============================================================================\n// Paddle API Types\n// ============================================================================\n\ninterface PaddleCustomer {\n id: string;\n email: string;\n name: string | null;\n custom_data: Record<string, string> | null;\n}\n\ninterface PaddleTransaction {\n id: string;\n status: string;\n customer_id: string | null;\n subscription_id: string | null;\n currency_code: string;\n checkout?: {\n url: string;\n };\n details?: {\n totals?: {\n total: string;\n };\n };\n}\n\ninterface PaddleSubscription {\n id: string;\n customer_id: string;\n status: string;\n items?: Array<{\n price: {\n id: string;\n product_id: string;\n };\n }>;\n current_billing_period?: {\n starts_at: string;\n ends_at: string;\n };\n scheduled_change?: {\n action: string;\n };\n started_at: string | null;\n first_billed_at: string | null;\n canceled_at: string | null;\n custom_data: Record<string, string> | null;\n}\n\ninterface PaddleProduct {\n id: string;\n name: string;\n description: string | null;\n status: string;\n custom_data: Record<string, string> | null;\n}\n\ninterface PaddlePrice {\n id: string;\n product_id: string;\n status: string;\n unit_price?: {\n amount: string;\n currency_code: string;\n };\n billing_cycle?: {\n interval: string;\n frequency: number;\n };\n custom_data: Record<string, string> | null;\n}\n\ninterface PaddleWebhookEvent {\n event_id: string;\n event_type: string;\n occurred_at: string;\n data: unknown;\n}\n\n/**\n * Create a Paddle provider\n */\nexport function createPaddleProvider(config: PaddleProviderConfig): PaddleProvider {\n return new PaddleProvider(config);\n}\n","/**\n * @parsrun/payments - iyzico Provider\n * Edge-compatible iyzico provider using fetch API\n */\n\nimport type {\n CheckoutSession,\n CreateCheckoutOptions,\n CreateCustomerOptions,\n CreatePortalOptions,\n CreateSubscriptionOptions,\n Customer,\n PaymentProvider,\n PortalSession,\n Subscription,\n UpdateSubscriptionOptions,\n WebhookEvent,\n WebhookEventType,\n} from \"../types.js\";\nimport { PaymentError, PaymentErrorCodes } from \"../types.js\";\n\n/**\n * iyzico provider config\n */\nexport interface IyzicoProviderConfig {\n /** iyzico API key */\n apiKey: string;\n /** iyzico secret key */\n secretKey: string;\n /** Environment */\n environment?: \"sandbox\" | \"production\" | undefined;\n /** Base URL override */\n baseUrl?: string | undefined;\n}\n\n/**\n * iyzico basket item\n */\nexport interface IyzicoBasketItem {\n id: string;\n name: string;\n category1: string;\n category2?: string | undefined;\n itemType: \"PHYSICAL\" | \"VIRTUAL\";\n price: string; // Decimal string like \"1.0\"\n}\n\n/**\n * iyzico buyer info\n */\nexport interface IyzicoBuyer {\n id: string;\n name: string;\n surname: string;\n email: string;\n gsmNumber?: string | undefined;\n identityNumber: string;\n registrationAddress: string;\n city: string;\n country: string;\n ip: string;\n}\n\n/**\n * iyzico address\n */\nexport interface IyzicoAddress {\n contactName: string;\n city: string;\n country: string;\n address: string;\n}\n\n/**\n * Extended checkout options for iyzico\n */\nexport interface IyzicoCheckoutOptions extends CreateCheckoutOptions {\n /** Buyer information (required for iyzico) */\n buyer: IyzicoBuyer;\n /** Billing address */\n billingAddress: IyzicoAddress;\n /** Shipping address */\n shippingAddress: IyzicoAddress;\n /** Basket items */\n basketItems: IyzicoBasketItem[];\n /** Price (total amount as decimal string) */\n price: string;\n /** Paid price (can include installment fees) */\n paidPrice: string;\n /** Currency (TRY, USD, EUR, GBP, IRR) */\n currency: \"TRY\" | \"USD\" | \"EUR\" | \"GBP\" | \"IRR\";\n /** Installment options */\n enabledInstallments?: number[] | undefined;\n /** Force 3D Secure */\n force3ds?: boolean | undefined;\n /** Conversation ID for tracking */\n conversationId?: string | undefined;\n}\n\n/**\n * iyzico Payment Provider\n * Edge-compatible using fetch API\n *\n * @example\n * ```typescript\n * const iyzico = new IyzicoProvider({\n * apiKey: process.env.IYZICO_API_KEY,\n * secretKey: process.env.IYZICO_SECRET_KEY,\n * environment: 'sandbox',\n * });\n *\n * const checkout = await iyzico.createCheckoutForm({\n * price: '100.00',\n * paidPrice: '100.00',\n * currency: 'TRY',\n * basketItems: [...],\n * buyer: {...},\n * billingAddress: {...},\n * shippingAddress: {...},\n * callbackUrl: 'https://example.com/callback',\n * });\n * ```\n */\nexport class IyzicoProvider implements PaymentProvider {\n readonly type = \"iyzico\" as const;\n\n private apiKey: string;\n private secretKey: string;\n private baseUrl: string;\n\n constructor(config: IyzicoProviderConfig) {\n this.apiKey = config.apiKey;\n this.secretKey = config.secretKey;\n this.baseUrl =\n config.baseUrl ??\n (config.environment === \"production\"\n ? \"https://api.iyzipay.com\"\n : \"https://sandbox-api.iyzipay.com\");\n }\n\n private async request<T>(\n endpoint: string,\n body: Record<string, unknown>\n ): Promise<T> {\n const randomString = this.generateRandomString(8);\n\n // Generate authorization header\n const authorizationString = await this.generateAuthorizationString(\n body,\n randomString\n );\n\n const response = await fetch(`${this.baseUrl}${endpoint}`, {\n method: \"POST\",\n headers: {\n Accept: \"application/json\",\n \"Content-Type\": \"application/json\",\n Authorization: authorizationString,\n \"x-iyzi-rnd\": randomString,\n },\n body: JSON.stringify(body),\n });\n\n const data = (await response.json()) as IyzicoResponse & T;\n\n if (data.status !== \"success\") {\n throw new PaymentError(\n `iyzico API error: ${data.errorMessage ?? \"Unknown error\"}`,\n data.errorCode ?? PaymentErrorCodes.API_ERROR,\n data\n );\n }\n\n return data as T;\n }\n\n private generateRandomString(length: number): string {\n const chars = \"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\";\n let result = \"\";\n const randomValues = new Uint8Array(length);\n crypto.getRandomValues(randomValues);\n for (let i = 0; i < length; i++) {\n const randomValue = randomValues[i];\n if (randomValue !== undefined) {\n result += chars[randomValue % chars.length];\n }\n }\n return result;\n }\n\n private async generateAuthorizationString(\n body: Record<string, unknown>,\n randomString: string\n ): Promise<string> {\n // Sort and flatten the body for PKI string\n const pkiString = this.generatePkiString(body);\n\n // Create hash string\n const hashString = `${this.apiKey}${randomString}${this.secretKey}${pkiString}`;\n\n // SHA256 hash\n const encoder = new TextEncoder();\n const data = encoder.encode(hashString);\n const hashBuffer = await crypto.subtle.digest(\"SHA-256\", data);\n const hashArray = new Uint8Array(hashBuffer);\n const hashBase64 = btoa(String.fromCharCode(...hashArray));\n\n // Create authorization\n const authorizationString = `${this.apiKey}:${hashBase64}`;\n const authorizationBase64 = btoa(authorizationString);\n\n return `IYZWS ${authorizationBase64}`;\n }\n\n private generatePkiString(obj: Record<string, unknown>): string {\n const parts: string[] = [];\n\n for (const [key, value] of Object.entries(obj)) {\n if (value === undefined || value === null) continue;\n\n if (Array.isArray(value)) {\n const arrayParts = value.map((item) => {\n if (typeof item === \"object\" && item !== null) {\n return this.generatePkiString(item as Record<string, unknown>);\n }\n return String(item);\n });\n parts.push(`${key}=[${arrayParts.join(\", \")}]`);\n } else if (typeof value === \"object\") {\n parts.push(\n `${key}=[${this.generatePkiString(value as Record<string, unknown>)}]`\n );\n } else {\n parts.push(`${key}=${value}`);\n }\n }\n\n return `[${parts.join(\",\")}]`;\n }\n\n // ============================================================================\n // Customer - iyzico uses buyer info per transaction, not stored customers\n // ============================================================================\n\n async createCustomer(_options: CreateCustomerOptions): Promise<Customer> {\n // iyzico doesn't have a separate customer API\n // Customers are identified by buyer info in each transaction\n throw new PaymentError(\n \"iyzico does not support stored customers. Use buyer info in checkout.\",\n PaymentErrorCodes.API_ERROR\n );\n }\n\n async getCustomer(_customerId: string): Promise<Customer | null> {\n return null;\n }\n\n async updateCustomer(\n _customerId: string,\n _options: Partial<CreateCustomerOptions>\n ): Promise<Customer> {\n throw new PaymentError(\n \"iyzico does not support stored customers\",\n PaymentErrorCodes.API_ERROR\n );\n }\n\n async deleteCustomer(_customerId: string): Promise<void> {\n throw new PaymentError(\n \"iyzico does not support stored customers\",\n PaymentErrorCodes.API_ERROR\n );\n }\n\n // ============================================================================\n // Checkout\n // ============================================================================\n\n async createCheckout(_options: CreateCheckoutOptions): Promise<CheckoutSession> {\n // For standard createCheckout, we need extended options\n throw new PaymentError(\n \"Use createCheckoutForm() with IyzicoCheckoutOptions for iyzico\",\n PaymentErrorCodes.INVALID_CONFIG\n );\n }\n\n /**\n * Create iyzico checkout form (iframe/popup)\n */\n async createCheckoutForm(options: IyzicoCheckoutOptions): Promise<IyzicoCheckoutResult> {\n const body: Record<string, unknown> = {\n locale: \"tr\",\n conversationId: options.conversationId ?? this.generateRandomString(16),\n price: options.price,\n paidPrice: options.paidPrice,\n currency: options.currency,\n basketId: options.metadata?.[\"basketId\"] ?? this.generateRandomString(16),\n paymentGroup: \"PRODUCT\",\n callbackUrl: options.successUrl,\n buyer: {\n id: options.buyer.id,\n name: options.buyer.name,\n surname: options.buyer.surname,\n gsmNumber: options.buyer.gsmNumber,\n email: options.buyer.email,\n identityNumber: options.buyer.identityNumber,\n registrationAddress: options.buyer.registrationAddress,\n ip: options.buyer.ip,\n city: options.buyer.city,\n country: options.buyer.country,\n },\n shippingAddress: {\n contactName: options.shippingAddress.contactName,\n city: options.shippingAddress.city,\n country: options.shippingAddress.country,\n address: options.shippingAddress.address,\n },\n billingAddress: {\n contactName: options.billingAddress.contactName,\n city: options.billingAddress.city,\n country: options.billingAddress.country,\n address: options.billingAddress.address,\n },\n basketItems: options.basketItems.map((item) => ({\n id: item.id,\n name: item.name,\n category1: item.category1,\n category2: item.category2,\n itemType: item.itemType,\n price: item.price,\n })),\n };\n\n if (options.enabledInstallments) {\n body[\"enabledInstallments\"] = options.enabledInstallments;\n }\n\n if (options.force3ds) {\n body[\"forceThreeDS\"] = 1;\n }\n\n const result = await this.request<IyzicoCheckoutFormResponse>(\n \"/payment/iyzi-pos/checkoutform/initialize/auth/ecom\",\n body\n );\n\n return {\n token: result.token,\n checkoutFormContent: result.checkoutFormContent,\n tokenExpireTime: result.tokenExpireTime,\n paymentPageUrl: result.paymentPageUrl,\n };\n }\n\n /**\n * Retrieve checkout form result\n */\n async retrieveCheckoutForm(token: string): Promise<IyzicoPaymentResult> {\n const body = {\n locale: \"tr\",\n conversationId: this.generateRandomString(16),\n token,\n };\n\n const result = await this.request<IyzicoPaymentResponse>(\n \"/payment/iyzi-pos/checkoutform/auth/ecom/detail\",\n body\n );\n\n return {\n paymentId: result.paymentId,\n status: result.status,\n paymentStatus: result.paymentStatus,\n price: result.price,\n paidPrice: result.paidPrice,\n currency: result.currency,\n installment: result.installment,\n basketId: result.basketId,\n binNumber: result.binNumber,\n lastFourDigits: result.lastFourDigits,\n cardAssociation: result.cardAssociation,\n cardFamily: result.cardFamily,\n cardType: result.cardType,\n fraudStatus: result.fraudStatus,\n raw: result,\n };\n }\n\n async getCheckout(_sessionId: string): Promise<CheckoutSession | null> {\n // Use retrieveCheckoutForm instead\n return null;\n }\n\n // ============================================================================\n // 3D Secure Payment\n // ============================================================================\n\n /**\n * Initialize 3D Secure payment\n */\n async initialize3DSPayment(options: {\n price: string;\n paidPrice: string;\n currency: \"TRY\" | \"USD\" | \"EUR\" | \"GBP\" | \"IRR\";\n installment: number;\n paymentCard: {\n cardHolderName: string;\n cardNumber: string;\n expireMonth: string;\n expireYear: string;\n cvc: string;\n registerCard?: 0 | 1;\n };\n buyer: IyzicoBuyer;\n billingAddress: IyzicoAddress;\n shippingAddress: IyzicoAddress;\n basketItems: IyzicoBasketItem[];\n callbackUrl: string;\n conversationId?: string;\n }): Promise<IyzicoThreeDSInitResult> {\n const body: Record<string, unknown> = {\n locale: \"tr\",\n conversationId: options.conversationId ?? this.generateRandomString(16),\n price: options.price,\n paidPrice: options.paidPrice,\n currency: options.currency,\n installment: options.installment,\n basketId: this.generateRandomString(16),\n paymentChannel: \"WEB\",\n paymentGroup: \"PRODUCT\",\n paymentCard: options.paymentCard,\n buyer: options.buyer,\n shippingAddress: options.shippingAddress,\n billingAddress: options.billingAddress,\n basketItems: options.basketItems,\n callbackUrl: options.callbackUrl,\n };\n\n const result = await this.request<IyzicoThreeDSResponse>(\n \"/payment/3dsecure/initialize\",\n body\n );\n\n return {\n threeDSHtmlContent: result.threeDSHtmlContent,\n status: result.status,\n };\n }\n\n /**\n * Complete 3D Secure payment after callback\n */\n async complete3DSPayment(paymentId: string, conversationId?: string): Promise<IyzicoPaymentResult> {\n const body = {\n locale: \"tr\",\n conversationId: conversationId ?? this.generateRandomString(16),\n paymentId,\n };\n\n const result = await this.request<IyzicoPaymentResponse>(\n \"/payment/3dsecure/auth\",\n body\n );\n\n return {\n paymentId: result.paymentId,\n status: result.status,\n paymentStatus: result.paymentStatus,\n price: result.price,\n paidPrice: result.paidPrice,\n currency: result.currency,\n installment: result.installment,\n basketId: result.basketId,\n binNumber: result.binNumber,\n lastFourDigits: result.lastFourDigits,\n cardAssociation: result.cardAssociation,\n cardFamily: result.cardFamily,\n cardType: result.cardType,\n fraudStatus: result.fraudStatus,\n raw: result,\n };\n }\n\n // ============================================================================\n // Refund\n // ============================================================================\n\n /**\n * Create a refund\n */\n async createRefund(options: {\n paymentTransactionId: string;\n price: string;\n currency: \"TRY\" | \"USD\" | \"EUR\" | \"GBP\" | \"IRR\";\n ip: string;\n conversationId?: string;\n }): Promise<IyzicoRefundResult> {\n const body = {\n locale: \"tr\",\n conversationId: options.conversationId ?? this.generateRandomString(16),\n paymentTransactionId: options.paymentTransactionId,\n price: options.price,\n currency: options.currency,\n ip: options.ip,\n };\n\n const result = await this.request<IyzicoRefundResponse>(\n \"/payment/refund\",\n body\n );\n\n return {\n paymentId: result.paymentId,\n paymentTransactionId: result.paymentTransactionId,\n price: result.price,\n status: result.status,\n };\n }\n\n /**\n * Cancel a payment (full refund before settlement)\n */\n async cancelPayment(options: {\n paymentId: string;\n ip: string;\n conversationId?: string;\n }): Promise<IyzicoCancelResult> {\n const body = {\n locale: \"tr\",\n conversationId: options.conversationId ?? this.generateRandomString(16),\n paymentId: options.paymentId,\n ip: options.ip,\n };\n\n const result = await this.request<IyzicoCancelResponse>(\n \"/payment/cancel\",\n body\n );\n\n return {\n paymentId: result.paymentId,\n price: result.price,\n currency: result.currency,\n status: result.status,\n };\n }\n\n // ============================================================================\n // Installment\n // ============================================================================\n\n /**\n * Get installment info for a BIN number\n */\n async getInstallmentInfo(\n binNumber: string,\n price: string\n ): Promise<IyzicoInstallmentResult> {\n const body = {\n locale: \"tr\",\n conversationId: this.generateRandomString(16),\n binNumber: binNumber.substring(0, 6),\n price,\n };\n\n const result = await this.request<IyzicoInstallmentResponse>(\n \"/payment/iyzi-pos/installment\",\n body\n );\n\n return {\n installmentDetails: result.installmentDetails ?? [],\n };\n }\n\n // ============================================================================\n // Subscriptions - iyzico has separate subscription API\n // ============================================================================\n\n async createSubscription(_options: CreateSubscriptionOptions): Promise<Subscription> {\n throw new PaymentError(\n \"Use iyzico subscription API methods directly\",\n PaymentErrorCodes.API_ERROR\n );\n }\n\n async getSubscription(_subscriptionId: string): Promise<Subscription | null> {\n return null;\n }\n\n async updateSubscription(\n _subscriptionId: string,\n _options: UpdateSubscriptionOptions\n ): Promise<Subscription> {\n throw new PaymentError(\n \"Use iyzico subscription API methods directly\",\n PaymentErrorCodes.API_ERROR\n );\n }\n\n async cancelSubscription(\n _subscriptionId: string,\n _cancelAtPeriodEnd?: boolean\n ): Promise<Subscription> {\n throw new PaymentError(\n \"Use iyzico subscription API methods directly\",\n PaymentErrorCodes.API_ERROR\n );\n }\n\n async listSubscriptions(_customerId: string): Promise<Subscription[]> {\n return [];\n }\n\n // ============================================================================\n // Portal - not supported\n // ============================================================================\n\n async createPortalSession(_options: CreatePortalOptions): Promise<PortalSession> {\n throw new PaymentError(\n \"iyzico does not support customer portal\",\n PaymentErrorCodes.API_ERROR\n );\n }\n\n // ============================================================================\n // Webhooks\n // ============================================================================\n\n async verifyWebhook(\n payload: string | Uint8Array,\n _signature: string\n ): Promise<WebhookEvent | null> {\n // iyzico uses IPN (Instant Payment Notification) system\n // The callback includes payment data that should be verified by retrieving the payment\n\n const payloadString = typeof payload === \"string\" ? payload : new TextDecoder().decode(payload);\n\n try {\n const data = JSON.parse(payloadString) as {\n token?: string;\n paymentId?: string;\n status?: string;\n iyziEventType?: string;\n };\n\n // Verify by retrieving the payment\n if (data.token) {\n const result = await this.retrieveCheckoutForm(data.token);\n\n return {\n id: result.paymentId ?? data.token,\n type: this.mapEventType(data.status ?? result.status),\n data: result,\n created: new Date(),\n provider: \"iyzico\",\n raw: data,\n };\n }\n\n return null;\n } catch {\n return null;\n }\n }\n\n private mapEventType(status: string): WebhookEventType {\n const mapping: Record<string, WebhookEventType> = {\n success: \"payment.succeeded\",\n failure: \"payment.failed\",\n INIT_THREEDS: \"payment.succeeded\",\n CALLBACK_THREEDS: \"payment.succeeded\",\n };\n\n return mapping[status] ?? \"payment.succeeded\";\n }\n}\n\n// ============================================================================\n// iyzico Response Types\n// ============================================================================\n\ninterface IyzicoResponse {\n status: \"success\" | \"failure\";\n errorCode?: string;\n errorMessage?: string;\n locale?: string;\n systemTime?: number;\n conversationId?: string;\n}\n\ninterface IyzicoCheckoutFormResponse extends IyzicoResponse {\n token: string;\n checkoutFormContent: string;\n tokenExpireTime: number;\n paymentPageUrl: string;\n}\n\ninterface IyzicoPaymentResponse extends IyzicoResponse {\n paymentId: string;\n paymentStatus: string;\n price: string;\n paidPrice: string;\n currency: string;\n installment: number;\n basketId: string;\n binNumber: string;\n lastFourDigits: string;\n cardAssociation: string;\n cardFamily: string;\n cardType: string;\n fraudStatus: number;\n itemTransactions?: Array<{\n itemId: string;\n paymentTransactionId: string;\n transactionStatus: number;\n price: string;\n paidPrice: string;\n }>;\n}\n\ninterface IyzicoThreeDSResponse extends IyzicoResponse {\n threeDSHtmlContent: string;\n}\n\ninterface IyzicoRefundResponse extends IyzicoResponse {\n paymentId: string;\n paymentTransactionId: string;\n price: string;\n}\n\ninterface IyzicoCancelResponse extends IyzicoResponse {\n paymentId: string;\n price: string;\n currency: string;\n}\n\ninterface IyzicoInstallmentResponse extends IyzicoResponse {\n installmentDetails?: Array<{\n binNumber: string;\n price: string;\n cardType: string;\n cardAssociation: string;\n cardFamilyName: string;\n force3ds: number;\n bankCode: number;\n bankName: string;\n forceCvc: number;\n installmentPrices: Array<{\n installmentNumber: number;\n totalPrice: string;\n installmentPrice: string;\n }>;\n }>;\n}\n\n// ============================================================================\n// Result Types\n// ============================================================================\n\nexport interface IyzicoCheckoutResult {\n token: string;\n checkoutFormContent: string;\n tokenExpireTime: number;\n paymentPageUrl: string;\n}\n\nexport interface IyzicoPaymentResult {\n paymentId: string;\n status: string;\n paymentStatus: string;\n price: string;\n paidPrice: string;\n currency: string;\n installment: number;\n basketId: string;\n binNumber: string;\n lastFourDigits: string;\n cardAssociation: string;\n cardFamily: string;\n cardType: string;\n fraudStatus: number;\n raw: unknown;\n}\n\nexport interface IyzicoThreeDSInitResult {\n threeDSHtmlContent: string;\n status: string;\n}\n\nexport interface IyzicoRefundResult {\n paymentId: string;\n paymentTransactionId: string;\n price: string;\n status: string;\n}\n\nexport interface IyzicoCancelResult {\n paymentId: string;\n price: string;\n currency: string;\n status: string;\n}\n\nexport interface IyzicoInstallmentResult {\n installmentDetails: Array<{\n binNumber: string;\n price: string;\n cardType: string;\n cardAssociation: string;\n cardFamilyName: string;\n force3ds: number;\n bankCode: number;\n bankName: string;\n forceCvc: number;\n installmentPrices: Array<{\n installmentNumber: number;\n totalPrice: string;\n installmentPrice: string;\n }>;\n }>;\n}\n\n/**\n * Create an iyzico provider\n */\nexport function createIyzicoProvider(config: IyzicoProviderConfig): IyzicoProvider {\n return new IyzicoProvider(config);\n}\n"],"mappings":"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","names":["price","subscription","price","price"]}
@@ -0,0 +1,250 @@
1
+ import { PaymentProvider, CreateCustomerOptions, Customer, CreateCheckoutOptions, CheckoutSession, CreateSubscriptionOptions, Subscription, UpdateSubscriptionOptions, CreatePortalOptions, PortalSession, WebhookEvent } from '../types.js';
2
+ import '@parsrun/types';
3
+
4
+ /**
5
+ * @parsrun/payments - iyzico Provider
6
+ * Edge-compatible iyzico provider using fetch API
7
+ */
8
+
9
+ /**
10
+ * iyzico provider config
11
+ */
12
+ interface IyzicoProviderConfig {
13
+ /** iyzico API key */
14
+ apiKey: string;
15
+ /** iyzico secret key */
16
+ secretKey: string;
17
+ /** Environment */
18
+ environment?: "sandbox" | "production" | undefined;
19
+ /** Base URL override */
20
+ baseUrl?: string | undefined;
21
+ }
22
+ /**
23
+ * iyzico basket item
24
+ */
25
+ interface IyzicoBasketItem {
26
+ id: string;
27
+ name: string;
28
+ category1: string;
29
+ category2?: string | undefined;
30
+ itemType: "PHYSICAL" | "VIRTUAL";
31
+ price: string;
32
+ }
33
+ /**
34
+ * iyzico buyer info
35
+ */
36
+ interface IyzicoBuyer {
37
+ id: string;
38
+ name: string;
39
+ surname: string;
40
+ email: string;
41
+ gsmNumber?: string | undefined;
42
+ identityNumber: string;
43
+ registrationAddress: string;
44
+ city: string;
45
+ country: string;
46
+ ip: string;
47
+ }
48
+ /**
49
+ * iyzico address
50
+ */
51
+ interface IyzicoAddress {
52
+ contactName: string;
53
+ city: string;
54
+ country: string;
55
+ address: string;
56
+ }
57
+ /**
58
+ * Extended checkout options for iyzico
59
+ */
60
+ interface IyzicoCheckoutOptions extends CreateCheckoutOptions {
61
+ /** Buyer information (required for iyzico) */
62
+ buyer: IyzicoBuyer;
63
+ /** Billing address */
64
+ billingAddress: IyzicoAddress;
65
+ /** Shipping address */
66
+ shippingAddress: IyzicoAddress;
67
+ /** Basket items */
68
+ basketItems: IyzicoBasketItem[];
69
+ /** Price (total amount as decimal string) */
70
+ price: string;
71
+ /** Paid price (can include installment fees) */
72
+ paidPrice: string;
73
+ /** Currency (TRY, USD, EUR, GBP, IRR) */
74
+ currency: "TRY" | "USD" | "EUR" | "GBP" | "IRR";
75
+ /** Installment options */
76
+ enabledInstallments?: number[] | undefined;
77
+ /** Force 3D Secure */
78
+ force3ds?: boolean | undefined;
79
+ /** Conversation ID for tracking */
80
+ conversationId?: string | undefined;
81
+ }
82
+ /**
83
+ * iyzico Payment Provider
84
+ * Edge-compatible using fetch API
85
+ *
86
+ * @example
87
+ * ```typescript
88
+ * const iyzico = new IyzicoProvider({
89
+ * apiKey: process.env.IYZICO_API_KEY,
90
+ * secretKey: process.env.IYZICO_SECRET_KEY,
91
+ * environment: 'sandbox',
92
+ * });
93
+ *
94
+ * const checkout = await iyzico.createCheckoutForm({
95
+ * price: '100.00',
96
+ * paidPrice: '100.00',
97
+ * currency: 'TRY',
98
+ * basketItems: [...],
99
+ * buyer: {...},
100
+ * billingAddress: {...},
101
+ * shippingAddress: {...},
102
+ * callbackUrl: 'https://example.com/callback',
103
+ * });
104
+ * ```
105
+ */
106
+ declare class IyzicoProvider implements PaymentProvider {
107
+ readonly type: "iyzico";
108
+ private apiKey;
109
+ private secretKey;
110
+ private baseUrl;
111
+ constructor(config: IyzicoProviderConfig);
112
+ private request;
113
+ private generateRandomString;
114
+ private generateAuthorizationString;
115
+ private generatePkiString;
116
+ createCustomer(_options: CreateCustomerOptions): Promise<Customer>;
117
+ getCustomer(_customerId: string): Promise<Customer | null>;
118
+ updateCustomer(_customerId: string, _options: Partial<CreateCustomerOptions>): Promise<Customer>;
119
+ deleteCustomer(_customerId: string): Promise<void>;
120
+ createCheckout(_options: CreateCheckoutOptions): Promise<CheckoutSession>;
121
+ /**
122
+ * Create iyzico checkout form (iframe/popup)
123
+ */
124
+ createCheckoutForm(options: IyzicoCheckoutOptions): Promise<IyzicoCheckoutResult>;
125
+ /**
126
+ * Retrieve checkout form result
127
+ */
128
+ retrieveCheckoutForm(token: string): Promise<IyzicoPaymentResult>;
129
+ getCheckout(_sessionId: string): Promise<CheckoutSession | null>;
130
+ /**
131
+ * Initialize 3D Secure payment
132
+ */
133
+ initialize3DSPayment(options: {
134
+ price: string;
135
+ paidPrice: string;
136
+ currency: "TRY" | "USD" | "EUR" | "GBP" | "IRR";
137
+ installment: number;
138
+ paymentCard: {
139
+ cardHolderName: string;
140
+ cardNumber: string;
141
+ expireMonth: string;
142
+ expireYear: string;
143
+ cvc: string;
144
+ registerCard?: 0 | 1;
145
+ };
146
+ buyer: IyzicoBuyer;
147
+ billingAddress: IyzicoAddress;
148
+ shippingAddress: IyzicoAddress;
149
+ basketItems: IyzicoBasketItem[];
150
+ callbackUrl: string;
151
+ conversationId?: string;
152
+ }): Promise<IyzicoThreeDSInitResult>;
153
+ /**
154
+ * Complete 3D Secure payment after callback
155
+ */
156
+ complete3DSPayment(paymentId: string, conversationId?: string): Promise<IyzicoPaymentResult>;
157
+ /**
158
+ * Create a refund
159
+ */
160
+ createRefund(options: {
161
+ paymentTransactionId: string;
162
+ price: string;
163
+ currency: "TRY" | "USD" | "EUR" | "GBP" | "IRR";
164
+ ip: string;
165
+ conversationId?: string;
166
+ }): Promise<IyzicoRefundResult>;
167
+ /**
168
+ * Cancel a payment (full refund before settlement)
169
+ */
170
+ cancelPayment(options: {
171
+ paymentId: string;
172
+ ip: string;
173
+ conversationId?: string;
174
+ }): Promise<IyzicoCancelResult>;
175
+ /**
176
+ * Get installment info for a BIN number
177
+ */
178
+ getInstallmentInfo(binNumber: string, price: string): Promise<IyzicoInstallmentResult>;
179
+ createSubscription(_options: CreateSubscriptionOptions): Promise<Subscription>;
180
+ getSubscription(_subscriptionId: string): Promise<Subscription | null>;
181
+ updateSubscription(_subscriptionId: string, _options: UpdateSubscriptionOptions): Promise<Subscription>;
182
+ cancelSubscription(_subscriptionId: string, _cancelAtPeriodEnd?: boolean): Promise<Subscription>;
183
+ listSubscriptions(_customerId: string): Promise<Subscription[]>;
184
+ createPortalSession(_options: CreatePortalOptions): Promise<PortalSession>;
185
+ verifyWebhook(payload: string | Uint8Array, _signature: string): Promise<WebhookEvent | null>;
186
+ private mapEventType;
187
+ }
188
+ interface IyzicoCheckoutResult {
189
+ token: string;
190
+ checkoutFormContent: string;
191
+ tokenExpireTime: number;
192
+ paymentPageUrl: string;
193
+ }
194
+ interface IyzicoPaymentResult {
195
+ paymentId: string;
196
+ status: string;
197
+ paymentStatus: string;
198
+ price: string;
199
+ paidPrice: string;
200
+ currency: string;
201
+ installment: number;
202
+ basketId: string;
203
+ binNumber: string;
204
+ lastFourDigits: string;
205
+ cardAssociation: string;
206
+ cardFamily: string;
207
+ cardType: string;
208
+ fraudStatus: number;
209
+ raw: unknown;
210
+ }
211
+ interface IyzicoThreeDSInitResult {
212
+ threeDSHtmlContent: string;
213
+ status: string;
214
+ }
215
+ interface IyzicoRefundResult {
216
+ paymentId: string;
217
+ paymentTransactionId: string;
218
+ price: string;
219
+ status: string;
220
+ }
221
+ interface IyzicoCancelResult {
222
+ paymentId: string;
223
+ price: string;
224
+ currency: string;
225
+ status: string;
226
+ }
227
+ interface IyzicoInstallmentResult {
228
+ installmentDetails: Array<{
229
+ binNumber: string;
230
+ price: string;
231
+ cardType: string;
232
+ cardAssociation: string;
233
+ cardFamilyName: string;
234
+ force3ds: number;
235
+ bankCode: number;
236
+ bankName: string;
237
+ forceCvc: number;
238
+ installmentPrices: Array<{
239
+ installmentNumber: number;
240
+ totalPrice: string;
241
+ installmentPrice: string;
242
+ }>;
243
+ }>;
244
+ }
245
+ /**
246
+ * Create an iyzico provider
247
+ */
248
+ declare function createIyzicoProvider(config: IyzicoProviderConfig): IyzicoProvider;
249
+
250
+ export { type IyzicoAddress, type IyzicoBasketItem, type IyzicoBuyer, type IyzicoCancelResult, type IyzicoCheckoutOptions, type IyzicoCheckoutResult, type IyzicoInstallmentResult, type IyzicoPaymentResult, IyzicoProvider, type IyzicoProviderConfig, type IyzicoRefundResult, type IyzicoThreeDSInitResult, createIyzicoProvider };