@lunora/payment 1.0.0-alpha.109 → 1.0.0-alpha.110

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.
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import { a as ProviderId, C as Customer, b as PaymentSession, S as Subscription, U as UsageEvent, W as WebhookActionType, A as ApplyResult, P as PaymentAdapter, c as AttachInput, d as CheckoutResult, e as CancelSubscriptionOptions, f as CaptureInput, g as CheckInput, h as CheckResult, i as CheckoutInput, F as FeatureBalance, R as RefundInput, T as TrackInput, j as TrackResult, k as CurrencyCode, M as Money, l as PaymentState, m as SubscriptionState, n as WebhookAction } from "./packem_shared/adapter.d-mtRgt9o6.mjs";
2
- export { type o as AdapterRegistry, type p as CustomerRef, type q as PortalInput, type r as ProviderCapabilities, type s as RefundAmountKind, type t as RefundResult, type u as ReportUsageInput, type v as SubscriptionPatch, type w as WebhookHeaders, type x as WebhookInput, y as createAdapterRegistry } from "./packem_shared/adapter.d-mtRgt9o6.mjs";
1
+ import { a as ProviderId, C as Customer, b as PaymentSession, S as Subscription, U as UsageEvent, W as WebhookActionType, A as ApplyResult, P as PaymentAdapter, c as AttachInput, d as CheckoutResult, e as CancelSubscriptionOptions, f as CaptureInput, g as CheckInput, h as CheckResult, i as CheckoutInput, F as FeatureBalance, R as RefundInput, T as TrackInput, j as TrackResult, k as CurrencyCode, M as Money, l as PaymentState, m as SubscriptionState, n as WebhookAction } from "./packem_shared/adapter.d-CeLGlHv_.mjs";
2
+ export { type o as AdapterRegistry, type p as CustomerRef, type q as PortalInput, type r as ProviderCapabilities, type s as RefundAmountKind, type t as RefundResult, type u as ReportUsageInput, type v as SubscriptionPatch, type w as WebhookHeaders, type x as WebhookInput, y as createAdapterRegistry } from "./packem_shared/adapter.d-CeLGlHv_.mjs";
3
3
  import { LunoraError } from '@lunora/errors';
4
4
  import { TableDefinition } from '@lunora/server';
5
5
  /**
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { a as ProviderId, C as Customer, b as PaymentSession, S as Subscription, U as UsageEvent, W as WebhookActionType, A as ApplyResult, P as PaymentAdapter, c as AttachInput, d as CheckoutResult, e as CancelSubscriptionOptions, f as CaptureInput, g as CheckInput, h as CheckResult, i as CheckoutInput, F as FeatureBalance, R as RefundInput, T as TrackInput, j as TrackResult, k as CurrencyCode, M as Money, l as PaymentState, m as SubscriptionState, n as WebhookAction } from "./packem_shared/adapter.d-mtRgt9o6.js";
2
- export { type o as AdapterRegistry, type p as CustomerRef, type q as PortalInput, type r as ProviderCapabilities, type s as RefundAmountKind, type t as RefundResult, type u as ReportUsageInput, type v as SubscriptionPatch, type w as WebhookHeaders, type x as WebhookInput, y as createAdapterRegistry } from "./packem_shared/adapter.d-mtRgt9o6.js";
1
+ import { a as ProviderId, C as Customer, b as PaymentSession, S as Subscription, U as UsageEvent, W as WebhookActionType, A as ApplyResult, P as PaymentAdapter, c as AttachInput, d as CheckoutResult, e as CancelSubscriptionOptions, f as CaptureInput, g as CheckInput, h as CheckResult, i as CheckoutInput, F as FeatureBalance, R as RefundInput, T as TrackInput, j as TrackResult, k as CurrencyCode, M as Money, l as PaymentState, m as SubscriptionState, n as WebhookAction } from "./packem_shared/adapter.d-CeLGlHv_.js";
2
+ export { type o as AdapterRegistry, type p as CustomerRef, type q as PortalInput, type r as ProviderCapabilities, type s as RefundAmountKind, type t as RefundResult, type u as ReportUsageInput, type v as SubscriptionPatch, type w as WebhookHeaders, type x as WebhookInput, y as createAdapterRegistry } from "./packem_shared/adapter.d-CeLGlHv_.js";
3
3
  import { LunoraError } from '@lunora/errors';
4
4
  import { TableDefinition } from '@lunora/server';
5
5
  /**
@@ -325,6 +325,14 @@ interface CancelSubscriptionOptions {
325
325
  * @experimental
326
326
  */
327
327
  interface SubscriptionPatch {
328
+ /**
329
+ * Override the outbound idempotency key. Honoured by the Stripe adapter only — no other provider's
330
+ * plan-change endpoint accepts a key at all (see the `idempotency` module docblock). Stripe
331
+ * otherwise derives one from the subscription and the target plan/quantity, which is stable across
332
+ * retries of the same intent; pass your own only to re-issue a target that was already applied and
333
+ * then changed away from, which a stable key would replay rather than prorate again.
334
+ */
335
+ readonly idempotencyKey?: string;
328
336
  readonly priceId?: string;
329
337
  readonly quantity?: number;
330
338
  }
@@ -454,7 +462,13 @@ interface PaymentAdapter {
454
462
  * absent, `track` still records usage durably and `check` enforces limits locally.
455
463
  */
456
464
  reportUsage?: (input: ReportUsageInput) => Promise<void>;
457
- resumeSubscription: (subscriptionId: string) => Promise<Subscription>;
465
+ /**
466
+ * Clear a pending cancellation. `options.idempotencyKey` overrides the adapter's own stable key
467
+ * and is honoured by the Stripe adapter only — no other provider's endpoint accepts one.
468
+ */
469
+ resumeSubscription: (subscriptionId: string, options?: {
470
+ idempotencyKey?: string;
471
+ }) => Promise<Subscription>;
458
472
  updateSubscription: (subscriptionId: string, patch: SubscriptionPatch) => Promise<Subscription>;
459
473
  }
460
474
  /**
@@ -325,6 +325,14 @@ interface CancelSubscriptionOptions {
325
325
  * @experimental
326
326
  */
327
327
  interface SubscriptionPatch {
328
+ /**
329
+ * Override the outbound idempotency key. Honoured by the Stripe adapter only — no other provider's
330
+ * plan-change endpoint accepts a key at all (see the `idempotency` module docblock). Stripe
331
+ * otherwise derives one from the subscription and the target plan/quantity, which is stable across
332
+ * retries of the same intent; pass your own only to re-issue a target that was already applied and
333
+ * then changed away from, which a stable key would replay rather than prorate again.
334
+ */
335
+ readonly idempotencyKey?: string;
328
336
  readonly priceId?: string;
329
337
  readonly quantity?: number;
330
338
  }
@@ -454,7 +462,13 @@ interface PaymentAdapter {
454
462
  * absent, `track` still records usage durably and `check` enforces limits locally.
455
463
  */
456
464
  reportUsage?: (input: ReportUsageInput) => Promise<void>;
457
- resumeSubscription: (subscriptionId: string) => Promise<Subscription>;
465
+ /**
466
+ * Clear a pending cancellation. `options.idempotencyKey` overrides the adapter's own stable key
467
+ * and is honoured by the Stripe adapter only — no other provider's endpoint accepts one.
468
+ */
469
+ resumeSubscription: (subscriptionId: string, options?: {
470
+ idempotencyKey?: string;
471
+ }) => Promise<Subscription>;
458
472
  updateSubscription: (subscriptionId: string, patch: SubscriptionPatch) => Promise<Subscription>;
459
473
  }
460
474
  /**
@@ -1,4 +1,4 @@
1
- import { P as PaymentAdapter } from "../packem_shared/adapter.d-mtRgt9o6.mjs";
1
+ import { P as PaymentAdapter } from "../packem_shared/adapter.d-CeLGlHv_.mjs";
2
2
  /**
3
3
  * The `autumn-js` SDK surface the adapter uses, as a structural type — a real `Autumn` instance
4
4
  * satisfies it without a cast. Resources/methods are `unknown` (the adapter re-types the client as
@@ -1,4 +1,4 @@
1
- import { P as PaymentAdapter } from "../packem_shared/adapter.d-mtRgt9o6.js";
1
+ import { P as PaymentAdapter } from "../packem_shared/adapter.d-CeLGlHv_.js";
2
2
  /**
3
3
  * The `autumn-js` SDK surface the adapter uses, as a structural type — a real `Autumn` instance
4
4
  * satisfies it without a cast. Resources/methods are `unknown` (the adapter re-types the client as
@@ -1,4 +1,4 @@
1
- import { P as PaymentAdapter } from "../packem_shared/adapter.d-mtRgt9o6.mjs";
1
+ import { P as PaymentAdapter } from "../packem_shared/adapter.d-CeLGlHv_.mjs";
2
2
  /**
3
3
  * The `creem` SDK surface the adapter uses, as a structural type — a real `Creem` instance satisfies
4
4
  * it without a cast. Resources are `unknown` (the adapter re-types the client as the real `Creem`
@@ -1,4 +1,4 @@
1
- import { P as PaymentAdapter } from "../packem_shared/adapter.d-mtRgt9o6.js";
1
+ import { P as PaymentAdapter } from "../packem_shared/adapter.d-CeLGlHv_.js";
2
2
  /**
3
3
  * The `creem` SDK surface the adapter uses, as a structural type — a real `Creem` instance satisfies
4
4
  * it without a cast. Resources are `unknown` (the adapter re-types the client as the real `Creem`
@@ -1,4 +1,4 @@
1
- import { P as PaymentAdapter } from "../packem_shared/adapter.d-mtRgt9o6.mjs";
1
+ import { P as PaymentAdapter } from "../packem_shared/adapter.d-CeLGlHv_.mjs";
2
2
  /**
3
3
  * The `dodopayments` SDK surface the adapter uses, as a structural type — a real `DodoPayments`
4
4
  * instance satisfies it without a cast. Resources are `unknown` (the adapter re-types the client as
@@ -1,4 +1,4 @@
1
- import { P as PaymentAdapter } from "../packem_shared/adapter.d-mtRgt9o6.js";
1
+ import { P as PaymentAdapter } from "../packem_shared/adapter.d-CeLGlHv_.js";
2
2
  /**
3
3
  * The `dodopayments` SDK surface the adapter uses, as a structural type — a real `DodoPayments`
4
4
  * instance satisfies it without a cast. Resources are `unknown` (the adapter re-types the client as
@@ -1,4 +1,4 @@
1
- import { P as PaymentAdapter } from "../packem_shared/adapter.d-mtRgt9o6.mjs";
1
+ import { P as PaymentAdapter } from "../packem_shared/adapter.d-CeLGlHv_.mjs";
2
2
  /**
3
3
  * The `@polar-sh/sdk` surface the adapter uses, as a structural type — a real `Polar` instance
4
4
  * satisfies it without a cast. Resources are `unknown` (the adapter re-types the client as the real
@@ -1,4 +1,4 @@
1
- import { P as PaymentAdapter } from "../packem_shared/adapter.d-mtRgt9o6.js";
1
+ import { P as PaymentAdapter } from "../packem_shared/adapter.d-CeLGlHv_.js";
2
2
  /**
3
3
  * The `@polar-sh/sdk` surface the adapter uses, as a structural type — a real `Polar` instance
4
4
  * satisfies it without a cast. Resources are `unknown` (the adapter re-types the client as the real
@@ -1,4 +1,4 @@
1
- import { P as PaymentAdapter } from "../packem_shared/adapter.d-mtRgt9o6.mjs";
1
+ import { P as PaymentAdapter } from "../packem_shared/adapter.d-CeLGlHv_.mjs";
2
2
  /**
3
3
  * The Stripe SDK surface the adapter uses, as a structural type — a real `Stripe` instance satisfies
4
4
  * it without a cast. Resources are `unknown` here (the adapter re-types the client as the real
@@ -1,4 +1,4 @@
1
- import { P as PaymentAdapter } from "../packem_shared/adapter.d-mtRgt9o6.js";
1
+ import { P as PaymentAdapter } from "../packem_shared/adapter.d-CeLGlHv_.js";
2
2
  /**
3
3
  * The Stripe SDK surface the adapter uses, as a structural type — a real `Stripe` instance satisfies
4
4
  * it without a cast. Resources are `unknown` here (the adapter re-types the client as the real
@@ -1 +1 @@
1
- import{LunoraPaymentError as E}from"../packem_shared/LunoraPaymentError-BSxyhWgu.mjs";import{idempotencyKey as K}from"../packem_shared/idempotencyKey-DBL6bpmj.mjs";import{a as u,r as a,d as v,b as c}from"../packem_shared/json-BJJPJVYj.mjs";import{compareMoney as P,money as m,zeroMoney as f}from"../packem_shared/addMoney-B4ufWAnD.mjs";import{assertWebhookSecret as T}from"../packem_shared/constantTimeEqual-ggrwGvRa.mjs";import{s as q}from"../packem_shared/subscription-event-C8GiQSFM.mjs";const M={canceled:"canceled",processing:"authorized",requires_action:"authorized",requires_capture:"authorized",requires_confirmation:"initiated",requires_payment_method:"initiated",succeeded:"captured"},h={active:"active",canceled:"canceled",incomplete:"past_due",incomplete_expired:"canceled",past_due:"past_due",paused:"paused",trialing:"trialing",unpaid:"past_due"},o=s=>a(u(s.metadata),"referenceId")??a(s,"client_reference_id"),I=s=>{const n=u(s.items),e=Array.isArray(n.data)?n.data:[];return u(e[0])},S=s=>a(u(I(s).price),"id"),w=s=>c(I(s),"quantity"),g=s=>{const n=c(I(s),"current_period_end")??c(s,"current_period_end");return n===void 0?void 0:n*1e3},A=s=>{const n=c(I(s),"current_period_start")??c(s,"current_period_start");return n===void 0?void 0:n*1e3},_=s=>{const n=u(s),e=a(n,"currency")??"usd",t=c(n,"amount")??0,r=m(BigInt(Math.round(t)),e),i=M[a(n,"status")??""]??"initiated",d=Date.now();return{amount:r,capturedAmount:i==="captured"?m(BigInt(Math.round(c(n,"amount_received")??t)),e):f(e),createdAt:d,id:a(n,"id")??"",provider:"stripe",referenceId:o(n)??"",refundedAmount:f(e),state:i,updatedAt:d}},l=s=>{const n=u(s),e=Date.now();return{cancelAtPeriodEnd:v(n,"cancel_at_period_end")??!1,createdAt:e,currentPeriodEnd:g(n),currentPeriodStart:A(n),id:a(n,"id")??"",priceId:S(n)??"",provider:"stripe",quantity:w(n)??1,referenceId:o(n)??"",state:h[a(n,"status")??""]??"past_due",updatedAt:e}},k=({base:s,currency:n,object:e})=>{const t=a(e,"payment_status"),r=t==="paid"||t==="no_payment_required";if(a(e,"mode")==="subscription")return{...s,customerId:a(e,"customer"),referenceId:o(e),subscriptionId:a(e,"subscription"),type:r?"subscription.active":"subscription.updated"};const i=a(e,"payment_intent");if(i===void 0&&t!=="no_payment_required")return{...s,type:"unhandled"};const d=c(e,"amount_total");return{...s,amount:d===void 0?void 0:m(BigInt(Math.round(d)),n),customerId:a(e,"customer"),referenceId:o(e),sessionId:i??a(e,"id"),type:r?"payment.captured":"payment.authorized"}},B=({base:s,currency:n,object:e})=>a(e,"status")!=="lost"?{...s,type:"unhandled"}:{...s,amount:m(BigInt(Math.round(c(e,"amount")??0)),n),referenceId:o(e),refundId:a(e,"id"),sessionId:a(e,"payment_intent"),type:"payment.refunded"},U=(s,n,e)=>{const t={eventId:s,provider:"stripe",raw:{object:e,type:n}},r=a(e,"currency")??"usd",i={base:t,currency:r,object:e};switch(n){case"charge.dispute.closed":return B(i);case"charge.refunded":return{...t,amount:m(BigInt(Math.round(c(e,"amount_refunded")??0)),r),amountKind:"absolute",referenceId:o(e),sessionId:a(e,"payment_intent")??a(e,"id"),type:"payment.refunded"};case"checkout.session.async_payment_failed":return a(e,"mode")==="subscription"?{...t,customerId:a(e,"customer"),referenceId:o(e),subscriptionId:a(e,"subscription"),type:"subscription.past_due"}:{...t,referenceId:o(e),sessionId:a(e,"payment_intent")??a(e,"id"),type:"payment.failed"};case"checkout.session.async_payment_succeeded":case"checkout.session.completed":return k(i);case"customer.subscription.created":case"customer.subscription.updated":return{...t,cancelAtPeriodEnd:v(e,"cancel_at_period_end"),currentPeriodEnd:g(e),currentPeriodStart:A(e),customerId:a(e,"customer"),priceId:S(e),quantity:w(e),referenceId:o(e),subscriptionId:a(e,"id"),type:q(h[a(e,"status")??""]??"past_due")};case"customer.subscription.deleted":return{...t,referenceId:o(e),subscriptionId:a(e,"id"),type:"subscription.canceled"};case"payment_intent.amount_capturable_updated":return{...t,amount:m(BigInt(Math.round(c(e,"amount")??0)),r),referenceId:o(e),sessionId:a(e,"id"),type:"payment.authorized"};case"payment_intent.payment_failed":return{...t,referenceId:o(e),sessionId:a(e,"id"),type:"payment.failed"};case"payment_intent.succeeded":return{...t,amount:m(BigInt(Math.round(c(e,"amount_received")??c(e,"amount")??0)),r),customerId:a(e,"customer"),referenceId:o(e),sessionId:a(e,"id"),type:"payment.captured"};default:return{...t,type:"unhandled"}}},W=s=>{const{webhookSecret:n}=s,e=s.client;return{cancelPayment:async(t,r)=>{const i=await e.paymentIntents.cancel(t,void 0,{idempotencyKey:r?.idempotencyKey});return _(i)},cancelSubscription:async(t,r)=>{const i=r?.atPeriodEnd?await e.subscriptions.update(t,{cancel_at_period_end:!0},{idempotencyKey:r.idempotencyKey}):await e.subscriptions.cancel(t,void 0,{idempotencyKey:r?.idempotencyKey});return l(i)},capabilities:{merchantOfRecord:!1,portal:!0,usageMetering:!0},capturePayment:async t=>{const r=await e.paymentIntents.capture(t.sessionId,t.amount?{amount_to_capture:Number(t.amount.minorUnits)}:void 0,{idempotencyKey:t.idempotencyKey});return _(r)},createCheckout:async t=>{const r=await e.checkout.sessions.create({cancel_url:t.cancelUrl,client_reference_id:t.referenceId,customer:t.customerId,line_items:[{price:t.priceId,quantity:t.quantity??1}],metadata:{...t.metadata,referenceId:t.referenceId},mode:t.mode,subscription_data:t.mode==="subscription"?{metadata:{referenceId:t.referenceId}}:void 0,success_url:t.successUrl},{idempotencyKey:t.idempotencyKey});return{id:r.id,provider:"stripe",url:r.url??""}},createPortalSession:async t=>({url:(await e.billingPortal.sessions.create({customer:t.customerId,return_url:t.returnUrl})).url}),getOrCreateCustomer:async t=>{const r=await e.customers.create({email:t.email,metadata:{...t.metadata,referenceId:t.referenceId}},{idempotencyKey:K("customer","stripe",t.referenceId)});return{createdAt:Date.now(),email:r.email??void 0,id:r.id,provider:"stripe",referenceId:t.referenceId}},getPaymentStatus:async t=>_(await e.paymentIntents.retrieve(t)),getSubscriptionStatus:async t=>l(await e.subscriptions.retrieve(t)),identifier:"stripe",parseWebhook:async({headers:t,payload:r})=>{T(n);const i=t.get("stripe-signature")??"";let d;try{d=await e.webhooks.constructEventAsync(r,i,n,s.webhookToleranceSeconds)}catch(y){throw new E("WEBHOOK_SIGNATURE_INVALID",y instanceof Error?y.message:"invalid webhook signature")}const p=u(u(d.data).object);return U(d.id,d.type,p)},refundPayment:async t=>{const r=await e.refunds.create({amount:t.amount?Number(t.amount.minorUnits):void 0,payment_intent:t.sessionId,reason:t.reason},{idempotencyKey:t.idempotencyKey}),i=await e.paymentIntents.retrieve(t.sessionId),d=_(i),p=t.amount??d.capturedAmount,y=t.amount!==void 0&&P(t.amount,d.capturedAmount)<0;return{...d,refundedAmount:p,refundId:r.id,state:y?"partially_refunded":"refunded"}},reportUsage:async t=>{await e.billing.meterEvents.create({event_name:t.featureId,identifier:t.idempotencyKey,payload:{stripe_customer_id:t.customerId??"",value:String(t.quantity)},timestamp:t.timestamp===void 0?void 0:Math.floor(t.timestamp/1e3)},{idempotencyKey:t.idempotencyKey})},resumeSubscription:async t=>{const r=await e.subscriptions.update(t,{cancel_at_period_end:!1});return l(r)},updateSubscription:async(t,r)=>{const i={};if(r.priceId!==void 0||r.quantity!==void 0){const p=await e.subscriptions.retrieve(t);i.items=[{id:p.items.data[0]?.id,price:r.priceId,quantity:r.quantity}]}const d=await e.subscriptions.update(t,i);return l(d)}}};export{W as createStripeAdapter};
1
+ import{LunoraPaymentError as E}from"../packem_shared/LunoraPaymentError-BSxyhWgu.mjs";import{idempotencyKey as f}from"../packem_shared/idempotencyKey-DBL6bpmj.mjs";import{a as u,r as s,d as S,b as c}from"../packem_shared/json-BJJPJVYj.mjs";import{compareMoney as P,money as m,zeroMoney as v}from"../packem_shared/addMoney-B4ufWAnD.mjs";import{assertWebhookSecret as T}from"../packem_shared/constantTimeEqual-ggrwGvRa.mjs";import{s as q}from"../packem_shared/subscription-event-C8GiQSFM.mjs";const M={canceled:"canceled",processing:"authorized",requires_action:"authorized",requires_capture:"authorized",requires_confirmation:"initiated",requires_payment_method:"initiated",succeeded:"captured"},h={active:"active",canceled:"canceled",incomplete:"past_due",incomplete_expired:"canceled",past_due:"past_due",paused:"paused",trialing:"trialing",unpaid:"past_due"},o=a=>s(u(a.metadata),"referenceId")??s(a,"client_reference_id"),I=a=>{const n=u(a.items),t=Array.isArray(n.data)?n.data:[];return u(t[0])},w=a=>s(u(I(a).price),"id"),g=a=>c(I(a),"quantity"),A=a=>{const n=c(I(a),"current_period_end")??c(a,"current_period_end");return n===void 0?void 0:n*1e3},K=a=>{const n=c(I(a),"current_period_start")??c(a,"current_period_start");return n===void 0?void 0:n*1e3},_=a=>{const n=u(a),t=s(n,"currency")??"usd",e=c(n,"amount")??0,r=m(BigInt(Math.round(e)),t),i=M[s(n,"status")??""]??"initiated",d=Date.now();return{amount:r,capturedAmount:i==="captured"?m(BigInt(Math.round(c(n,"amount_received")??e)),t):v(t),createdAt:d,id:s(n,"id")??"",provider:"stripe",referenceId:o(n)??"",refundedAmount:v(t),state:i,updatedAt:d}},l=a=>{const n=u(a),t=Date.now();return{cancelAtPeriodEnd:S(n,"cancel_at_period_end")??!1,createdAt:t,currentPeriodEnd:A(n),currentPeriodStart:K(n),id:s(n,"id")??"",priceId:w(n)??"",provider:"stripe",quantity:g(n)??1,referenceId:o(n)??"",state:h[s(n,"status")??""]??"past_due",updatedAt:t}},k=({base:a,currency:n,object:t})=>{const e=s(t,"payment_status"),r=e==="paid"||e==="no_payment_required";if(s(t,"mode")==="subscription")return{...a,customerId:s(t,"customer"),referenceId:o(t),subscriptionId:s(t,"subscription"),type:r?"subscription.active":"subscription.updated"};const i=s(t,"payment_intent");if(i===void 0&&e!=="no_payment_required")return{...a,type:"unhandled"};const d=c(t,"amount_total");return{...a,amount:d===void 0?void 0:m(BigInt(Math.round(d)),n),customerId:s(t,"customer"),referenceId:o(t),sessionId:i??s(t,"id"),type:r?"payment.captured":"payment.authorized"}},B=({base:a,currency:n,object:t})=>s(t,"status")!=="lost"?{...a,type:"unhandled"}:{...a,amount:m(BigInt(Math.round(c(t,"amount")??0)),n),referenceId:o(t),refundId:s(t,"id"),sessionId:s(t,"payment_intent"),type:"payment.refunded"},U=(a,n,t)=>{const e={eventId:a,provider:"stripe",raw:{object:t,type:n}},r=s(t,"currency")??"usd",i={base:e,currency:r,object:t};switch(n){case"charge.dispute.closed":return B(i);case"charge.refunded":return{...e,amount:m(BigInt(Math.round(c(t,"amount_refunded")??0)),r),amountKind:"absolute",referenceId:o(t),sessionId:s(t,"payment_intent")??s(t,"id"),type:"payment.refunded"};case"checkout.session.async_payment_failed":return s(t,"mode")==="subscription"?{...e,customerId:s(t,"customer"),referenceId:o(t),subscriptionId:s(t,"subscription"),type:"subscription.past_due"}:{...e,referenceId:o(t),sessionId:s(t,"payment_intent")??s(t,"id"),type:"payment.failed"};case"checkout.session.async_payment_succeeded":case"checkout.session.completed":return k(i);case"customer.subscription.created":case"customer.subscription.updated":return{...e,cancelAtPeriodEnd:S(t,"cancel_at_period_end"),currentPeriodEnd:A(t),currentPeriodStart:K(t),customerId:s(t,"customer"),priceId:w(t),quantity:g(t),referenceId:o(t),subscriptionId:s(t,"id"),type:q(h[s(t,"status")??""]??"past_due")};case"customer.subscription.deleted":return{...e,referenceId:o(t),subscriptionId:s(t,"id"),type:"subscription.canceled"};case"payment_intent.amount_capturable_updated":return{...e,amount:m(BigInt(Math.round(c(t,"amount")??0)),r),referenceId:o(t),sessionId:s(t,"id"),type:"payment.authorized"};case"payment_intent.payment_failed":return{...e,referenceId:o(t),sessionId:s(t,"id"),type:"payment.failed"};case"payment_intent.succeeded":return{...e,amount:m(BigInt(Math.round(c(t,"amount_received")??c(t,"amount")??0)),r),customerId:s(t,"customer"),referenceId:o(t),sessionId:s(t,"id"),type:"payment.captured"};default:return{...e,type:"unhandled"}}},W=a=>{const{webhookSecret:n}=a,t=a.client;return{cancelPayment:async(e,r)=>{const i=await t.paymentIntents.cancel(e,void 0,{idempotencyKey:r?.idempotencyKey});return _(i)},cancelSubscription:async(e,r)=>{const i=r?.atPeriodEnd?await t.subscriptions.update(e,{cancel_at_period_end:!0},{idempotencyKey:r.idempotencyKey}):await t.subscriptions.cancel(e,void 0,{idempotencyKey:r?.idempotencyKey});return l(i)},capabilities:{merchantOfRecord:!1,portal:!0,usageMetering:!0},capturePayment:async e=>{const r=await t.paymentIntents.capture(e.sessionId,e.amount?{amount_to_capture:Number(e.amount.minorUnits)}:void 0,{idempotencyKey:e.idempotencyKey});return _(r)},createCheckout:async e=>{const r=await t.checkout.sessions.create({cancel_url:e.cancelUrl,client_reference_id:e.referenceId,customer:e.customerId,line_items:[{price:e.priceId,quantity:e.quantity??1}],metadata:{...e.metadata,referenceId:e.referenceId},mode:e.mode,subscription_data:e.mode==="subscription"?{metadata:{referenceId:e.referenceId}}:void 0,success_url:e.successUrl},{idempotencyKey:e.idempotencyKey});return{id:r.id,provider:"stripe",url:r.url??""}},createPortalSession:async e=>({url:(await t.billingPortal.sessions.create({customer:e.customerId,return_url:e.returnUrl})).url}),getOrCreateCustomer:async e=>{const r=await t.customers.create({email:e.email,metadata:{...e.metadata,referenceId:e.referenceId}},{idempotencyKey:f("customer","stripe",e.referenceId)});return{createdAt:Date.now(),email:r.email??void 0,id:r.id,provider:"stripe",referenceId:e.referenceId}},getPaymentStatus:async e=>_(await t.paymentIntents.retrieve(e)),getSubscriptionStatus:async e=>l(await t.subscriptions.retrieve(e)),identifier:"stripe",parseWebhook:async({headers:e,payload:r})=>{T(n);const i=e.get("stripe-signature")??"";let d;try{d=await t.webhooks.constructEventAsync(r,i,n,a.webhookToleranceSeconds)}catch(y){throw new E("WEBHOOK_SIGNATURE_INVALID",y instanceof Error?y.message:"invalid webhook signature")}const p=u(u(d.data).object);return U(d.id,d.type,p)},refundPayment:async e=>{const r=await t.refunds.create({amount:e.amount?Number(e.amount.minorUnits):void 0,payment_intent:e.sessionId,reason:e.reason},{idempotencyKey:e.idempotencyKey}),i=await t.paymentIntents.retrieve(e.sessionId),d=_(i),p=e.amount??d.capturedAmount,y=e.amount!==void 0&&P(e.amount,d.capturedAmount)<0;return{...d,refundedAmount:p,refundId:r.id,state:y?"partially_refunded":"refunded"}},reportUsage:async e=>{await t.billing.meterEvents.create({event_name:e.featureId,identifier:e.idempotencyKey,payload:{stripe_customer_id:e.customerId??"",value:String(e.quantity)},timestamp:e.timestamp===void 0?void 0:Math.floor(e.timestamp/1e3)},{idempotencyKey:e.idempotencyKey})},resumeSubscription:async(e,r)=>{const i=await t.subscriptions.update(e,{cancel_at_period_end:!1},{idempotencyKey:r?.idempotencyKey??f("resume_subscription","stripe",e)});return l(i)},updateSubscription:async(e,r)=>{const i={};if(r.priceId!==void 0||r.quantity!==void 0){const p=await t.subscriptions.retrieve(e);i.items=[{id:p.items.data[0]?.id,price:r.priceId,quantity:r.quantity}]}const d=await t.subscriptions.update(e,i,{idempotencyKey:r.idempotencyKey??f("update_subscription","stripe",e,r.priceId??"",r.quantity??"")});return l(d)}}};export{W as createStripeAdapter};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/payment",
3
- "version": "1.0.0-alpha.109",
3
+ "version": "1.0.0-alpha.110",
4
4
  "description": "Provider-agnostic payments for Lunora: Stripe-first adapter, webhook sync, and subscription/payment state machine",
5
5
  "keywords": [
6
6
  "billing",