@lunora/payment 1.0.0-alpha.4 → 1.0.0-alpha.40

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.
Files changed (62) hide show
  1. package/LICENSE.md +6 -0
  2. package/README.md +5 -2
  3. package/dist/index.d.mts +266 -523
  4. package/dist/index.d.ts +266 -523
  5. package/dist/index.mjs +1 -16
  6. package/dist/packem_shared/LunoraPaymentError-DWQ-v_NC.mjs +1 -0
  7. package/dist/packem_shared/MemoryPaymentStore-BICI1RdZ.mjs +1 -0
  8. package/dist/packem_shared/PAYMENT_TERMINAL_STATES-DVNbZxBy.mjs +1 -0
  9. package/dist/packem_shared/adapter.d-CMjjkTGB.d.mts +427 -0
  10. package/dist/packem_shared/adapter.d-CMjjkTGB.d.ts +427 -0
  11. package/dist/packem_shared/addMoney-BiiMn67T.mjs +1 -0
  12. package/dist/packem_shared/applyWebhookAction-BMVcvJ3t.mjs +1 -0
  13. package/dist/packem_shared/constantTimeEqual-BpVBvmN-.mjs +1 -0
  14. package/dist/packem_shared/createAdapterRegistry-CNIpj46I.mjs +1 -0
  15. package/dist/packem_shared/createDatabasePaymentStore-IG8Cb3_L.mjs +1 -0
  16. package/dist/packem_shared/createPayment-CW_iR6Hg.mjs +1 -0
  17. package/dist/packem_shared/entitlementsForReference-BbEOKu5d.mjs +1 -0
  18. package/dist/packem_shared/idempotencyKey-CfJKqcE3.mjs +1 -0
  19. package/dist/packem_shared/json-D85Nbd92.mjs +1 -0
  20. package/dist/packem_shared/lunoraDatabaseToPaymentDatabase-BFBlKLG3.mjs +1 -0
  21. package/dist/packem_shared/not-supported-DwGy4SQL.mjs +1 -0
  22. package/dist/packem_shared/observability-C9tz8mj_.mjs +1 -0
  23. package/dist/packem_shared/paymentTables-BMtUrXkM.mjs +1 -0
  24. package/dist/packem_shared/reconcile-DDdfivoy.mjs +1 -0
  25. package/dist/packem_shared/subscription-event-C-71ye9J.mjs +1 -0
  26. package/dist/providers/autumn-features.d.mts +129 -0
  27. package/dist/providers/autumn-features.d.ts +129 -0
  28. package/dist/providers/autumn-features.mjs +1 -0
  29. package/dist/providers/autumn.d.mts +28 -0
  30. package/dist/providers/autumn.d.ts +28 -0
  31. package/dist/providers/autumn.mjs +1 -0
  32. package/dist/providers/creem.d.mts +26 -0
  33. package/dist/providers/creem.d.ts +26 -0
  34. package/dist/providers/creem.mjs +1 -0
  35. package/dist/providers/dodopayments.d.mts +30 -0
  36. package/dist/providers/dodopayments.d.ts +30 -0
  37. package/dist/providers/dodopayments.mjs +1 -0
  38. package/dist/providers/polar.d.mts +31 -0
  39. package/dist/providers/polar.d.ts +31 -0
  40. package/dist/providers/polar.mjs +1 -0
  41. package/dist/providers/stripe.d.mts +32 -0
  42. package/dist/providers/stripe.d.ts +32 -0
  43. package/dist/providers/stripe.mjs +1 -0
  44. package/package.json +46 -5
  45. package/dist/packem_shared/LunoraPaymentError-B3hEzXSs.mjs +0 -22
  46. package/dist/packem_shared/MemoryPaymentStore-DvgdWa3C.mjs +0 -72
  47. package/dist/packem_shared/PAYMENT_TERMINAL_STATES-DrxV0clv.mjs +0 -26
  48. package/dist/packem_shared/addMoney-bCcs1nyw.mjs +0 -60
  49. package/dist/packem_shared/applyWebhookAction-DpAqf3Lw.mjs +0 -177
  50. package/dist/packem_shared/constantTimeEqual-CfY0jYcL.mjs +0 -95
  51. package/dist/packem_shared/createAdapterRegistry-BuDHFCBc.mjs +0 -24
  52. package/dist/packem_shared/createDatabasePaymentStore-bYB_HUE6.mjs +0 -172
  53. package/dist/packem_shared/createPayment-BccfPGyw.mjs +0 -190
  54. package/dist/packem_shared/createPolarAdapter-BJtVGSlF.mjs +0 -217
  55. package/dist/packem_shared/createStripeAdapter-D40MVBXg.mjs +0 -270
  56. package/dist/packem_shared/entitlementsForReference-CzZGXPoZ.mjs +0 -51
  57. package/dist/packem_shared/idempotencyKey-BFzDCA7g.mjs +0 -3
  58. package/dist/packem_shared/json-Db337f36.mjs +0 -6
  59. package/dist/packem_shared/lunoraDatabaseToPaymentDatabase-RlKX3Kcd.mjs +0 -29
  60. package/dist/packem_shared/observability-CvhJ205g.mjs +0 -11
  61. package/dist/packem_shared/paymentTables-DccHwWr_.mjs +0 -127
  62. package/dist/packem_shared/reconcile-CI1ukJF9.mjs +0 -73
@@ -0,0 +1,129 @@
1
+ /**
2
+ * A per-seat / per-workspace sub-customer with its own feature balances.
3
+ * @experimental
4
+ */
5
+ interface AutumnEntity {
6
+ readonly featureId?: string;
7
+ readonly id: string;
8
+ readonly name?: string;
9
+ /** The raw provider record, for fields this facade does not normalize. */
10
+ readonly raw: Record<string, unknown>;
11
+ }
12
+ /**
13
+ * `CreateEntityInput` is part of the experimental `@lunora/payment` API and may change without a major version bump.
14
+ * @experimental
15
+ */
16
+ interface CreateEntityInput {
17
+ /** The feature the entity consumes a seat/allowance of (e.g. `"seats"`). */
18
+ readonly featureId: string;
19
+ /** Caller-chosen stable id — Autumn requires an entity id on create. */
20
+ readonly id: string;
21
+ readonly name?: string;
22
+ }
23
+ /**
24
+ * One point in a usage-events aggregation.
25
+ * @experimental
26
+ */
27
+ interface UsageEventPoint {
28
+ readonly count: number;
29
+ readonly period?: string;
30
+ readonly raw: Record<string, unknown>;
31
+ }
32
+ /**
33
+ * `EventsListInput` is part of the experimental `@lunora/payment` API and may change without a major version bump.
34
+ * @experimental
35
+ */
36
+ interface EventsListInput {
37
+ /** Feature(s) to report on. */
38
+ readonly featureId: ReadonlyArray<string> | string;
39
+ }
40
+ /**
41
+ * `EventsAggregateInput` is part of the experimental `@lunora/payment` API and may change without a major version bump.
42
+ * @experimental
43
+ */
44
+ interface EventsAggregateInput extends EventsListInput {
45
+ /** Time window to aggregate over (aggregate only — `list` ignores it, so it isn't accepted there). */
46
+ readonly range?: "7d" | "24h" | "30d" | "90d" | "last_cycle";
47
+ }
48
+ /**
49
+ * A prepaid feature quantity purchased at checkout (e.g. buy 5 seats up front).
50
+ * @experimental
51
+ */
52
+ interface PrepaidOption {
53
+ readonly featureId: string;
54
+ readonly quantity: number;
55
+ }
56
+ /**
57
+ * Autumn-native checkout — richer than the generic `createCheckout` (trials, prepaid, entities, rewards).
58
+ * @experimental
59
+ */
60
+ interface AutumnCheckoutInput {
61
+ /** Scope the checkout to a specific entity (seat/workspace) rather than the top-level customer. */
62
+ readonly entityId?: string;
63
+ /**
64
+ * Autumn applies a plan's configured free trial automatically. Pass `false` to opt out of that
65
+ * trial for this checkout; leave unset (or `true`) to keep the plan default.
66
+ */
67
+ readonly freeTrial?: boolean;
68
+ /** Prepaid feature quantities to purchase up front. */
69
+ readonly options?: ReadonlyArray<PrepaidOption>;
70
+ /** The plan to attach (Autumn's plan id — the successor to the classic "product" id). */
71
+ readonly planId: string;
72
+ /** An Autumn reward id to apply as a discount. */
73
+ readonly reward?: string;
74
+ readonly successUrl?: string;
75
+ }
76
+ /**
77
+ * The subset of the Autumn SDK surface the native facade calls. A real `Autumn` instance satisfies it.
78
+ * @experimental
79
+ */
80
+ interface AutumnFeaturesClientLike {
81
+ readonly billing: unknown;
82
+ readonly entities: unknown;
83
+ readonly events: unknown;
84
+ readonly plans: unknown;
85
+ readonly referrals: unknown;
86
+ }
87
+ /**
88
+ * `AutumnFeaturesOptions` is part of the experimental `@lunora/payment` API and may change without a major version bump.
89
+ * @experimental
90
+ */
91
+ interface AutumnFeaturesOptions {
92
+ readonly client: AutumnFeaturesClientLike;
93
+ }
94
+ /**
95
+ * The Autumn-native feature facade returned by {@link createAutumnFeatures}.
96
+ * @experimental
97
+ */
98
+ interface AutumnFeatures {
99
+ readonly checkout: (referenceId: string, input: AutumnCheckoutInput) => Promise<{
100
+ raw: Record<string, unknown>;
101
+ url: string;
102
+ }>;
103
+ readonly entities: {
104
+ readonly create: (referenceId: string, input: CreateEntityInput) => Promise<AutumnEntity>;
105
+ readonly delete: (referenceId: string, entityId: string) => Promise<void>;
106
+ readonly get: (referenceId: string, entityId: string) => Promise<AutumnEntity>;
107
+ };
108
+ readonly events: {
109
+ readonly aggregate: (referenceId: string, input: EventsAggregateInput) => Promise<UsageEventPoint[]>;
110
+ readonly list: (referenceId: string, input: EventsListInput) => Promise<UsageEventPoint[]>;
111
+ };
112
+ readonly plans: {
113
+ readonly list: () => Promise<Record<string, unknown>[]>;
114
+ };
115
+ readonly referrals: {
116
+ readonly createCode: (referenceId: string, programId: string) => Promise<{
117
+ code: string;
118
+ raw: Record<string, unknown>;
119
+ }>;
120
+ readonly redeemCode: (referenceId: string, code: string) => Promise<Record<string, unknown>>;
121
+ };
122
+ }
123
+ /**
124
+ * Build the Autumn-native feature facade over an injected client. Companion to `createAutumnAdapter`;
125
+ * share the same underlying `autumn-js` `Autumn` client between them.
126
+ * @experimental
127
+ */
128
+ declare const createAutumnFeatures: (options: AutumnFeaturesOptions) => AutumnFeatures;
129
+ export { type AutumnCheckoutInput, type AutumnEntity, type AutumnFeatures, type AutumnFeaturesClientLike, type AutumnFeaturesOptions, type CreateEntityInput, type EventsAggregateInput, type EventsListInput, type PrepaidOption, type UsageEventPoint, createAutumnFeatures };
@@ -0,0 +1 @@
1
+ import{a as s,r as d,b as i}from"../packem_shared/json-D85Nbd92.mjs";const u=r=>typeof r=="string"?r:[...r],o=r=>({featureId:d(r,"featureId")??d(r,"feature_id"),id:d(r,"id")??"",name:d(r,"name"),raw:r}),l=r=>{const n=r.list??r.data??r.events;return(Array.isArray(n)?n:[]).map(t=>{const e=s(t);return{count:i(e,"count")??i(e,"value")??0,period:d(e,"period"),raw:e}})},y=r=>{const n=r.client;return{checkout:async(t,e)=>{const a=s(await n.billing.attach({customerId:t,...e.freeTrial===!1?{customize:{freeTrial:null}}:{},discounts:e.reward?[{rewardId:e.reward}]:void 0,entityId:e.entityId,featureQuantities:e.options?.map(c=>({featureId:c.featureId,quantity:c.quantity})),planId:e.planId,successUrl:e.successUrl})),I=d(a,"paymentUrl")??d(a,"checkoutUrl")??d(a,"url")??"";return{raw:a,url:I}},entities:{create:async(t,e)=>{const a=await n.entities.create({customerId:t,entityId:e.id,featureId:e.featureId,name:e.name});return o(s(a))},delete:async(t,e)=>{await n.entities.delete({customerId:t,entityId:e})},get:async(t,e)=>{const a=await n.entities.get({customerId:t,entityId:e});return o(s(a))}},events:{aggregate:async(t,e)=>{const a=await n.events.aggregate({customerId:t,featureId:u(e.featureId),range:e.range});return l(s(a))},list:async(t,e)=>{const a=await n.events.list({customerId:t,featureId:u(e.featureId)});return l(s(a))}},plans:{list:async()=>{const t=s(await n.plans.list()),e=t.list??t.data??t.plans;return Array.isArray(e)?e.map(a=>s(a)):[]}},referrals:{createCode:async(t,e)=>{const a=s(await n.referrals.createCode({customerId:t,programId:e}));return{code:d(a,"code")??"",raw:a}},redeemCode:async(t,e)=>s(await n.referrals.redeemCode({code:e,customerId:t}))}}};export{y as createAutumnFeatures};
@@ -0,0 +1,28 @@
1
+ import { P as PaymentAdapter } from "../packem_shared/adapter.d-CMjjkTGB.mjs";
2
+ /**
3
+ * The `autumn-js` SDK surface the adapter uses, as a structural type — a real `Autumn` instance
4
+ * satisfies it without a cast. Resources/methods are `unknown` (the adapter re-types the client as
5
+ * the real `Autumn` internally); this keeps the SDK's full type out of the published declarations.
6
+ * @experimental
7
+ */
8
+ interface AutumnClientLike {
9
+ readonly billing: unknown;
10
+ readonly check: unknown;
11
+ readonly customers: unknown;
12
+ readonly track: unknown;
13
+ }
14
+ /**
15
+ * `AutumnAdapterOptions` is part of the experimental `@lunora/payment` API and may change without a major version bump.
16
+ * @experimental
17
+ */
18
+ interface AutumnAdapterOptions {
19
+ readonly client: AutumnClientLike;
20
+ readonly webhookSecret: string;
21
+ readonly webhookToleranceSeconds?: number;
22
+ }
23
+ /**
24
+ * `createAutumnAdapter` is part of the experimental `@lunora/payment` API and may change without a major version bump.
25
+ * @experimental
26
+ */
27
+ declare const createAutumnAdapter: (options: AutumnAdapterOptions) => PaymentAdapter;
28
+ export { type AutumnAdapterOptions, type AutumnClientLike, createAutumnAdapter };
@@ -0,0 +1,28 @@
1
+ import { P as PaymentAdapter } from "../packem_shared/adapter.d-CMjjkTGB.js";
2
+ /**
3
+ * The `autumn-js` SDK surface the adapter uses, as a structural type — a real `Autumn` instance
4
+ * satisfies it without a cast. Resources/methods are `unknown` (the adapter re-types the client as
5
+ * the real `Autumn` internally); this keeps the SDK's full type out of the published declarations.
6
+ * @experimental
7
+ */
8
+ interface AutumnClientLike {
9
+ readonly billing: unknown;
10
+ readonly check: unknown;
11
+ readonly customers: unknown;
12
+ readonly track: unknown;
13
+ }
14
+ /**
15
+ * `AutumnAdapterOptions` is part of the experimental `@lunora/payment` API and may change without a major version bump.
16
+ * @experimental
17
+ */
18
+ interface AutumnAdapterOptions {
19
+ readonly client: AutumnClientLike;
20
+ readonly webhookSecret: string;
21
+ readonly webhookToleranceSeconds?: number;
22
+ }
23
+ /**
24
+ * `createAutumnAdapter` is part of the experimental `@lunora/payment` API and may change without a major version bump.
25
+ * @experimental
26
+ */
27
+ declare const createAutumnAdapter: (options: AutumnAdapterOptions) => PaymentAdapter;
28
+ export { type AutumnAdapterOptions, type AutumnClientLike, createAutumnAdapter };
@@ -0,0 +1 @@
1
+ import{LunoraPaymentError as C}from"../packem_shared/LunoraPaymentError-DWQ-v_NC.mjs";import{a as u,c as o,d as s,e as l,r as D}from"../packem_shared/json-D85Nbd92.mjs";import{money as A}from"../packem_shared/addMoney-BiiMn67T.mjs";import{verifyStandardWebhook as B}from"../packem_shared/constantTimeEqual-BpVBvmN-.mjs";import{e as $}from"../packem_shared/not-supported-DwGy4SQL.mjs";import{i as E}from"../packem_shared/subscription-event-C-71ye9J.mjs";const h={active:"active",canceled:"canceled",expired:"canceled",past_due:"past_due",scheduled:"paused",trialing:"trialing"},j={activated:"active",canceled:"canceled",cancelled:"canceled",expired:"canceled",scheduled:"paused"},b="::",y=$("autumn"),f=(a,c)=>`${a}${b}${c}`,v=a=>{const c=a.lastIndexOf(b);if(c===-1)throw new C("PROVIDER_ERROR",`malformed autumn subscription id "${a}" (expected "<customerId>::<productId>")`);return{customerId:a.slice(0,c),productId:a.slice(c+b.length)}},P=a=>s(a,"canceled_at","canceledAt")!==void 0||o(a,"status")==="scheduled",k=(a,c)=>{const r=Date.now(),e=o(c,"id","product_id","productId","plan_id","planId")??"",d=o(c,"status")??"active",t=l(c,"past_due")??l(c,"pastDue")??!1;return{cancelAtPeriodEnd:P(c),createdAt:r,currentPeriodEnd:s(c,"current_period_end","currentPeriodEnd")??void 0,currentPeriodStart:s(c,"current_period_start","currentPeriodStart")??void 0,id:f(a,e),priceId:e,provider:"autumn",quantity:s(c,"quantity")??1,referenceId:a,state:t?"past_due":h[d]??"past_due",updatedAt:r}},w=a=>Array.isArray(a)?a.map(c=>u(c)):[],x=(a,c)=>[...w(a.products),...w(a.subscriptions)].find(r=>(o(r,"id","product_id","productId","plan_id","planId")??"")===c),S=a=>({balance:s(a,"remaining","balance"),limit:s(a,"granted","included_usage","limit"),unlimited:l(a,"unlimited")??!1,used:s(a,"usage","used")}),O=(a,c,r,e)=>{const d=Date.now();return{cancelAtPeriodEnd:e,createdAt:d,id:f(a,c),priceId:c,provider:"autumn",quantity:1,referenceId:a,state:r,updatedAt:d}},g=async(a,c,r)=>{const e=u(await a.customers.get({customerId:c})),d=x(e,r);return d?k(c,d):O(c,r,"canceled",!1)},I=a=>o(a,"customer_id","customerId"),M=(a,c)=>{const r={eventId:a,provider:"autumn",raw:{object:c,type:"billing.updated"}},e=I(c),d=w(c.plan_changes)[0]??c,t=d.subscription?u(d.subscription):d,n=o(t,"plan_id","planId","product_id","productId","id"),i=o(t,"status"),m=o(d,"action"),p=l(t,"past_due")??l(t,"pastDue")??!1,_=i===void 0?void 0:h[i],q=m===void 0?void 0:j[m],R=p?"past_due":_??q;return{...r,cancelAtPeriodEnd:l(t,"cancel_at_period_end")??P(t),currentPeriodEnd:s(t,"current_period_end","currentPeriodEnd"),currentPeriodStart:s(t,"current_period_start","currentPeriodStart"),customerId:e,priceId:n,referenceId:e,subscriptionId:e===void 0||n===void 0?void 0:f(e,n),type:E(R)}},N=(a,c,r)=>{const e={eventId:a,provider:"autumn",raw:{object:r,type:c}},d=o(r,"currency")??"usd";switch(c){case"billing.auto_topup_succeeded":{const t=u(r.invoice),n=s(t,"total","amount")??s(r,"total","amount"),i=o(t,"currency")??d;return{...e,amount:n===void 0?void 0:A(BigInt(Math.round(n)),i),customerId:I(r),referenceId:I(r),sessionId:o(t,"id","stripe_id","invoice_id")??o(r,"id"),type:"payment.captured"}}case"billing.updated":return M(a,r);case"customer.product.added":case"customer.product.canceled":case"customer.product.expired":case"customer.product.updated":case"product.attached":{const t=r.product?u(r.product):r,n=c==="customer.product.canceled"||c==="customer.product.expired"?"canceled":o(t,"status"),i=I(r)??I(t);return{...e,cancelAtPeriodEnd:l(t,"cancel_at_period_end")??P(t),currentPeriodEnd:s(t,"current_period_end","currentPeriodEnd"),currentPeriodStart:s(t,"current_period_start","currentPeriodStart"),customerId:i,priceId:o(t,"id","product_id","productId"),referenceId:i,subscriptionId:i===void 0?void 0:f(i,o(t,"id","product_id","productId")??""),type:E(h[n??""])}}case"invoice.paid":case"payment.succeeded":{const t=s(r,"total","amount","amount_paid");return{...e,amount:t===void 0?void 0:A(BigInt(Math.round(t)),d),customerId:I(r),referenceId:I(r),sessionId:o(r,"id","invoice_id","stripe_id"),type:"payment.captured"}}default:return{...e,type:"unhandled"}}},T=a=>o(a,"checkout_url","checkoutUrl","payment_url","paymentUrl","url")??"",z=a=>{const{webhookSecret:c}=a,r=a.client;return{cancelPayment:()=>y("manual payment cancellation"),cancelSubscription:async(e,d)=>{const{customerId:t,productId:n}=v(e);return await r.billing.update({cancelAction:d?.atPeriodEnd?"cancel_end_of_cycle":"cancel_immediately",customerId:t,planId:n}),d?.atPeriodEnd?{...await g(r,t,n),cancelAtPeriodEnd:!0}:O(t,n,"canceled",!1)},capabilities:{merchantOfRecord:!1,portal:!0,usageMetering:!0},capturePayment:e=>y("manual capture"),checkEntitlement:async e=>{if(e.featureId===void 0){const m=u(await r.customers.get({customerId:e.referenceId})),p=x(m,e.priceId??""),_=p?k(e.referenceId,p).state:void 0;return{allowed:_==="active"||_==="trialing",unlimited:!1}}const d=u(await r.check({customerId:e.referenceId,featureId:e.featureId,requiredBalance:e.quantity??1})),t=l(d,"allowed")??!1,n=d.balance,i=typeof n=="object"&&n!==null?u(n):d;return{allowed:t,...S(i)}},createCheckout:async e=>{const d=u(await r.billing.attach({customerId:e.referenceId,planId:e.priceId}));return{id:f(e.referenceId,e.priceId),provider:"autumn",url:T(d)}},createPortalSession:async e=>{const d=u(await r.billing.openCustomerPortal({customerId:e.customerId}));return{url:o(d,"url")??""}},getBalances:async e=>{const d=u(await r.customers.get({customerId:e})),t=u(d.balances??d.features);return Object.entries(t).map(([n,i])=>{const m=u(i),p=S(m);return{allowed:p.unlimited||(p.balance??0)>0,featureId:o(m,"featureId","feature_id")??n,...p}})},getOrCreateCustomer:async e=>{const d=u(await r.customers.getOrCreate({customerId:e.referenceId,email:e.email,name:e.metadata?.name}));return{createdAt:Date.now(),email:o(d,"email")??e.email,id:o(d,"id")??e.referenceId,provider:"autumn",referenceId:e.referenceId}},getPaymentStatus:()=>y("payment-session reconciliation"),getSubscriptionStatus:async e=>{const{customerId:d,productId:t}=v(e);return g(r,d,t)},identifier:"autumn",parseWebhook:async({headers:e,payload:d})=>{const t=e.get("svix-id")??e.get("webhook-id")??"";await B({payload:d,secret:c,toleranceSeconds:a.webhookToleranceSeconds,webhookId:t,webhookSignature:e.get("svix-signature")??e.get("webhook-signature")??"",webhookTimestamp:e.get("svix-timestamp")??e.get("webhook-timestamp")??""});const n=u(JSON.parse(d));return N(t,D(n,"type")??"",u(n.data))},refundPayment:()=>y("refunds"),reportUsage:async e=>{await r.track({customerId:e.referenceId,featureId:e.featureId,value:e.quantity})},resumeSubscription:async e=>{const{customerId:d,productId:t}=v(e);return await r.billing.update({cancelAction:"uncancel",customerId:d,planId:t}),{...await g(r,d,t),cancelAtPeriodEnd:!1}},updateSubscription:async(e,d)=>{const{customerId:t,productId:n}=v(e),i=d.priceId??n;return await r.billing.attach({customerId:t,planId:i}),g(r,t,i)}}};export{z as createAutumnAdapter};
@@ -0,0 +1,26 @@
1
+ import { P as PaymentAdapter } from "../packem_shared/adapter.d-CMjjkTGB.mjs";
2
+ /**
3
+ * The `creem` SDK surface the adapter uses, as a structural type — a real `Creem` instance satisfies
4
+ * it without a cast. Resources are `unknown` (the adapter re-types the client as the real `Creem`
5
+ * internally); this keeps the SDK's full type out of the published declarations.
6
+ * @experimental
7
+ */
8
+ interface CreemClientLike {
9
+ readonly checkouts: unknown;
10
+ readonly customers: unknown;
11
+ readonly subscriptions: unknown;
12
+ }
13
+ /**
14
+ * `CreemAdapterOptions` is part of the experimental `@lunora/payment` API and may change without a major version bump.
15
+ * @experimental
16
+ */
17
+ interface CreemAdapterOptions {
18
+ readonly client: CreemClientLike;
19
+ readonly webhookSecret: string;
20
+ }
21
+ /**
22
+ * `createCreemAdapter` is part of the experimental `@lunora/payment` API and may change without a major version bump.
23
+ * @experimental
24
+ */
25
+ declare const createCreemAdapter: (options: CreemAdapterOptions) => PaymentAdapter;
26
+ export { type CreemAdapterOptions, type CreemClientLike, createCreemAdapter };
@@ -0,0 +1,26 @@
1
+ import { P as PaymentAdapter } from "../packem_shared/adapter.d-CMjjkTGB.js";
2
+ /**
3
+ * The `creem` SDK surface the adapter uses, as a structural type — a real `Creem` instance satisfies
4
+ * it without a cast. Resources are `unknown` (the adapter re-types the client as the real `Creem`
5
+ * internally); this keeps the SDK's full type out of the published declarations.
6
+ * @experimental
7
+ */
8
+ interface CreemClientLike {
9
+ readonly checkouts: unknown;
10
+ readonly customers: unknown;
11
+ readonly subscriptions: unknown;
12
+ }
13
+ /**
14
+ * `CreemAdapterOptions` is part of the experimental `@lunora/payment` API and may change without a major version bump.
15
+ * @experimental
16
+ */
17
+ interface CreemAdapterOptions {
18
+ readonly client: CreemClientLike;
19
+ readonly webhookSecret: string;
20
+ }
21
+ /**
22
+ * `createCreemAdapter` is part of the experimental `@lunora/payment` API and may change without a major version bump.
23
+ * @experimental
24
+ */
25
+ declare const createCreemAdapter: (options: CreemAdapterOptions) => PaymentAdapter;
26
+ export { type CreemAdapterOptions, type CreemClientLike, createCreemAdapter };
@@ -0,0 +1 @@
1
+ import{a as u,c as o,r as n,f as p,b as m,p as f,e as v,d as w}from"../packem_shared/json-D85Nbd92.mjs";import{money as I,zeroMoney as b}from"../packem_shared/addMoney-BiiMn67T.mjs";import{verifyCreemSignature as P}from"../packem_shared/constantTimeEqual-BpVBvmN-.mjs";import{e as S}from"../packem_shared/not-supported-DwGy4SQL.mjs";import{i as A}from"../packem_shared/subscription-event-C-71ye9J.mjs";const k=/already exists/iu,E={canceled:"canceled",completed:"captured",expired:"canceled",paid:"captured",partially_refunded:"partially_refunded",pending:"initiated",refunded:"refunded"},_={active:"active",canceled:"canceled",cancelled:"canceled",expired:"canceled",incomplete:"past_due",paid:"active",past_due:"past_due",paused:"paused",scheduled_cancel:"active",trialing:"trialing",unpaid:"past_due"},y=S("creem (merchant-of-record)"),s=c=>typeof c=="string"?c:n(u(c),"id"),C=c=>o(c,"checkout_url","checkoutUrl")??"",g=c=>o(c,"canceled_at","canceledAt")!==void 0||n(c,"status")==="scheduled_cancel",D=c=>{if(!(c instanceof Error))return!1;const{statusCode:t}=c;return typeof t=="number"&&t!==400&&t!==409?!1:k.test(c.message)},l=c=>{const t=u(c),r=Date.now(),e=n(t,"status")??"";return{cancelAtPeriodEnd:g(t),createdAt:r,currentPeriodEnd:f(o(t,"current_period_end_date","currentPeriodEndDate")),currentPeriodStart:f(o(t,"current_period_start_date","currentPeriodStartDate")),id:n(t,"id")??"",priceId:s(t.product)??"",provider:"creem",quantity:m(t,"units")??1,referenceId:p(t)??s(t.customer)??"",state:_[e]??"past_due",updatedAt:r}},x=c=>{const t=u(c),r=Date.now(),e=u(t.order),a=n(e,"currency")??n(t,"currency")??"usd",d=I(BigInt(Math.round(m(e,"amount")??m(t,"amount")??0)),a),i=E[n(e,"status")??n(t,"status")??""]??"initiated";return{amount:d,capturedAmount:i==="captured"||i==="partially_refunded"||i==="refunded"?d:b(a),createdAt:r,id:n(t,"id")??"",provider:"creem",referenceId:p(t)??"",refundedAmount:i==="refunded"?d:b(a),state:i,updatedAt:r}},B=(c,t,r)=>{const e={eventId:c,provider:"creem",raw:{object:r,type:t}},a=u(r.order),d=n(a,"currency")??n(r,"currency")??"usd";switch(t){case"checkout.completed":{const i=m(a,"amount")??m(r,"amount");return{...e,amount:i===void 0?void 0:I(BigInt(Math.round(i)),d),customerId:s(r.customer),referenceId:p(r),sessionId:n(r,"id"),subscriptionId:s(r.subscription),type:"payment.captured"}}case"refund.created":{const i=w(r,"refund_amount","refundAmount","amount")??m(a,"amount"),h=o(r,"refund_currency","refundCurrency")??d;return{...e,amount:i===void 0?void 0:I(BigInt(Math.round(i)),h),referenceId:p(r),sessionId:s(r.transaction)??s(r.subscription)??s(r.order)??s(r.checkout)??n(r,"id"),type:"payment.refunded"}}case"subscription.active":case"subscription.canceled":case"subscription.expired":case"subscription.paid":case"subscription.past_due":case"subscription.paused":case"subscription.scheduled_cancel":case"subscription.trialing":case"subscription.unpaid":case"subscription.update":{const i=t==="subscription.scheduled_cancel"?"scheduled_cancel":n(r,"status");return{...e,cancelAtPeriodEnd:v(r,"cancel_at_period_end")??g(r),currentPeriodEnd:f(o(r,"current_period_end_date","currentPeriodEndDate")),currentPeriodStart:f(o(r,"current_period_start_date","currentPeriodStartDate")),customerId:s(r.customer),priceId:s(r.product),referenceId:p(r)??s(r.customer),subscriptionId:n(r,"id"),type:A(_[i??""])}}default:return{...e,type:"unhandled"}}},T=c=>{const{webhookSecret:t}=c,r=c.client;return{cancelPayment:()=>y("manual payment cancellation"),cancelSubscription:async(e,a)=>l(await r.subscriptions.cancel(e,{mode:a?.atPeriodEnd===!0?"scheduled":"immediate"})),capabilities:{merchantOfRecord:!0,portal:!0,usageMetering:!1},capturePayment:e=>y("manual capture"),createCheckout:async e=>{const a=await r.checkouts.create({customer:e.customerId?{id:e.customerId}:void 0,metadata:{...e.metadata,referenceId:e.referenceId},productId:e.priceId,requestId:e.idempotencyKey,successUrl:e.successUrl,units:e.quantity});return{id:n(a,"id")??"",provider:"creem",url:C(a)}},createPortalSession:async e=>{const a=await r.customers.generateBillingLinks({customerId:e.customerId});return{url:o(a,"customer_portal_link","customerPortalLink")??""}},getOrCreateCustomer:async e=>{const a=d=>({createdAt:Date.now(),email:n(d,"email")??e.email,id:n(d,"id")??"",provider:"creem",referenceId:e.referenceId});try{return a(u(await r.customers.create({email:e.email??"",metadata:{...e.metadata,referenceId:e.referenceId},name:e.metadata?.name??e.referenceId})))}catch(d){if(e.email!==void 0&&D(d)){const i=u(await r.customers.retrieve(void 0,e.email));if(p(i)!==e.referenceId)throw new Error(`Creem customer for email "${e.email}" already belongs to a different reference; refusing to bind it to "${e.referenceId}".`,{cause:d});return a(i)}throw d}},getPaymentStatus:async e=>x(await r.checkouts.retrieve(e)),getSubscriptionStatus:async e=>l(await r.subscriptions.get(e)),identifier:"creem",parseWebhook:async({headers:e,payload:a})=>{await P({payload:a,secret:t,signature:e.get("creem-signature")??""});const d=u(JSON.parse(a));return B(n(d,"id")??"",o(d,"eventType","type")??"",u(d.object))},refundPayment:()=>y("programmatic refunds"),resumeSubscription:async e=>l(await r.subscriptions.resume(e)),updateSubscription:async(e,a)=>a.priceId?l(await r.subscriptions.upgrade(e,{productId:a.priceId,updateBehavior:"proration-charge-immediately"})):l(await r.subscriptions.get(e))}};export{T as createCreemAdapter};
@@ -0,0 +1,30 @@
1
+ import { P as PaymentAdapter } from "../packem_shared/adapter.d-CMjjkTGB.mjs";
2
+ /**
3
+ * The `dodopayments` SDK surface the adapter uses, as a structural type — a real `DodoPayments`
4
+ * instance satisfies it without a cast. Resources are `unknown` (the adapter re-types the client as
5
+ * the real `DodoPayments` internally); this keeps the SDK's full type out of the published declarations.
6
+ * @experimental
7
+ */
8
+ interface DodoPaymentsClientLike {
9
+ readonly checkoutSessions: unknown;
10
+ readonly customers: unknown;
11
+ readonly payments: unknown;
12
+ readonly refunds: unknown;
13
+ readonly subscriptions: unknown;
14
+ readonly usageEvents: unknown;
15
+ }
16
+ /**
17
+ * `DodoPaymentsAdapterOptions` is part of the experimental `@lunora/payment` API and may change without a major version bump.
18
+ * @experimental
19
+ */
20
+ interface DodoPaymentsAdapterOptions {
21
+ readonly client: DodoPaymentsClientLike;
22
+ readonly webhookSecret: string;
23
+ readonly webhookToleranceSeconds?: number;
24
+ }
25
+ /**
26
+ * `createDodoPaymentsAdapter` is part of the experimental `@lunora/payment` API and may change without a major version bump.
27
+ * @experimental
28
+ */
29
+ declare const createDodoPaymentsAdapter: (options: DodoPaymentsAdapterOptions) => PaymentAdapter;
30
+ export { type DodoPaymentsAdapterOptions, type DodoPaymentsClientLike, createDodoPaymentsAdapter };
@@ -0,0 +1,30 @@
1
+ import { P as PaymentAdapter } from "../packem_shared/adapter.d-CMjjkTGB.js";
2
+ /**
3
+ * The `dodopayments` SDK surface the adapter uses, as a structural type — a real `DodoPayments`
4
+ * instance satisfies it without a cast. Resources are `unknown` (the adapter re-types the client as
5
+ * the real `DodoPayments` internally); this keeps the SDK's full type out of the published declarations.
6
+ * @experimental
7
+ */
8
+ interface DodoPaymentsClientLike {
9
+ readonly checkoutSessions: unknown;
10
+ readonly customers: unknown;
11
+ readonly payments: unknown;
12
+ readonly refunds: unknown;
13
+ readonly subscriptions: unknown;
14
+ readonly usageEvents: unknown;
15
+ }
16
+ /**
17
+ * `DodoPaymentsAdapterOptions` is part of the experimental `@lunora/payment` API and may change without a major version bump.
18
+ * @experimental
19
+ */
20
+ interface DodoPaymentsAdapterOptions {
21
+ readonly client: DodoPaymentsClientLike;
22
+ readonly webhookSecret: string;
23
+ readonly webhookToleranceSeconds?: number;
24
+ }
25
+ /**
26
+ * `createDodoPaymentsAdapter` is part of the experimental `@lunora/payment` API and may change without a major version bump.
27
+ * @experimental
28
+ */
29
+ declare const createDodoPaymentsAdapter: (options: DodoPaymentsAdapterOptions) => PaymentAdapter;
30
+ export { type DodoPaymentsAdapterOptions, type DodoPaymentsClientLike, createDodoPaymentsAdapter };
@@ -0,0 +1 @@
1
+ import{LunoraPaymentError as g}from"../packem_shared/LunoraPaymentError-DWQ-v_NC.mjs";import{idempotencyKey as v}from"../packem_shared/idempotencyKey-CfJKqcE3.mjs";import{a as o,b as s,r,f as u,p as l,e as I}from"../packem_shared/json-D85Nbd92.mjs";import{money as y,zeroMoney as f}from"../packem_shared/addMoney-BiiMn67T.mjs";import{verifyStandardWebhook as w}from"../packem_shared/constantTimeEqual-BpVBvmN-.mjs";import{e as S}from"../packem_shared/not-supported-DwGy4SQL.mjs";import{i as q}from"../packem_shared/subscription-event-C-71ye9J.mjs";const P={cancelled:"canceled",failed:"failed",partially_captured:"captured",partially_captured_and_capturable:"captured",processing:"initiated",requires_capture:"authorized",requires_confirmation:"initiated",requires_customer_action:"authorized",requires_merchant_action:"authorized",requires_payment_method:"initiated",succeeded:"captured"},h={active:"active",cancelled:"canceled",expired:"canceled",failed:"past_due",on_hold:"past_due",paused:"paused",pending:"past_due"},b=S("dodopayments (merchant-of-record)"),m=d=>r(o(d.customer),"customer_id")??r(d,"customer_id"),p=d=>{const n=o(d),t=Date.now(),e=r(n,"status")??"";return{cancelAtPeriodEnd:I(n,"cancel_at_next_billing_date")??!1,createdAt:t,currentPeriodEnd:l(r(n,"next_billing_date")),currentPeriodStart:l(r(n,"previous_billing_date")),id:r(n,"subscription_id")??"",priceId:r(n,"product_id")??"",provider:"dodopayments",quantity:s(n,"quantity")??1,referenceId:u(n)??m(n)??"",state:h[e]??"past_due",updatedAt:t}},A=d=>{const n=o(d),t=Date.now(),e=r(n,"currency")??"usd",a=y(BigInt(Math.round(s(n,"total_amount")??0)),e),i=P[r(n,"status")??""]??"initiated";return{amount:a,capturedAmount:i==="captured"?a:f(e),createdAt:t,id:r(n,"payment_id")??"",provider:"dodopayments",referenceId:u(n)??"",refundedAmount:f(e),state:i,updatedAt:t}},k=(d,n,t)=>{const e={eventId:d,provider:"dodopayments",raw:{object:t,type:n}},a=r(t,"currency")??"usd";switch(n){case"dispute.lost":case"refund.succeeded":return{...e,amount:y(BigInt(Math.round(s(t,"amount")??0)),a),referenceId:u(t),sessionId:r(t,"payment_id"),type:"payment.refunded"};case"payment.cancelled":case"payment.failed":return{...e,referenceId:u(t),sessionId:r(t,"payment_id"),type:"payment.failed"};case"payment.succeeded":return{...e,amount:y(BigInt(Math.round(s(t,"total_amount")??0)),a),customerId:m(t),referenceId:u(t),sessionId:r(t,"payment_id"),subscriptionId:r(t,"subscription_id"),type:"payment.captured"};case"subscription.active":case"subscription.cancelled":case"subscription.expired":case"subscription.failed":case"subscription.on_hold":case"subscription.paused":case"subscription.plan_changed":case"subscription.renewed":case"subscription.updated":{const i=r(t,"status");return{...e,cancelAtPeriodEnd:I(t,"cancel_at_next_billing_date"),currentPeriodEnd:l(r(t,"next_billing_date")),currentPeriodStart:l(r(t,"previous_billing_date")),customerId:m(t),priceId:r(t,"product_id"),quantity:s(t,"quantity"),referenceId:u(t)??m(t),subscriptionId:r(t,"subscription_id"),type:q(h[i??""])}}default:return{...e,type:"unhandled"}}},z=d=>{const{webhookSecret:n}=d,t=d.client;return{cancelPayment:()=>b("manual payment cancellation"),cancelSubscription:async(e,a)=>{const i=a?.atPeriodEnd?{cancel_at_next_billing_date:!0}:{status:"cancelled"};return p(await t.subscriptions.update(e,i))},capabilities:{merchantOfRecord:!0,portal:!0,usageMetering:!0},capturePayment:e=>b("manual capture"),createCheckout:async e=>{const a=o(await t.checkoutSessions.create({customer:e.customerId?{customer_id:e.customerId}:void 0,metadata:{...e.metadata,referenceId:e.referenceId},product_cart:[{product_id:e.priceId,quantity:e.quantity??1}],return_url:e.successUrl}));return{id:r(a,"session_id")??"",provider:"dodopayments",url:r(a,"checkout_url")??""}},createPortalSession:async e=>{const a=o(await t.customers.customerPortal.create(e.customerId,{return_url:e.returnUrl}));return{url:r(a,"link")??r(a,"url")??""}},getOrCreateCustomer:async e=>{const a=o(await t.customers.create({email:e.email??"",name:e.metadata?.name??e.referenceId},{idempotencyKey:v("customer","dodopayments",e.referenceId)}));return{createdAt:Date.now(),email:r(a,"email")??e.email,id:r(a,"customer_id")??"",provider:"dodopayments",referenceId:e.referenceId}},getPaymentStatus:async e=>A(await t.payments.retrieve(e)),getSubscriptionStatus:async e=>p(await t.subscriptions.retrieve(e)),identifier:"dodopayments",parseWebhook:async({headers:e,payload:a})=>{const i=e.get("webhook-id")??"";await w({payload:a,secret:n,toleranceSeconds:d.webhookToleranceSeconds,webhookId:i,webhookSignature:e.get("webhook-signature")??"",webhookTimestamp:e.get("webhook-timestamp")??""});const c=o(JSON.parse(a));return k(i,r(c,"type")??"",o(c.data))},refundPayment:async e=>{if(e.amount!==void 0)throw new g("PROVIDER_ERROR","dodopayments refunds a payment in full; partial refunds require line items and aren't supported here");const a=o(await t.refunds.create({payment_id:e.sessionId,reason:e.reason})),i=r(a,"currency")??"usd",c=y(BigInt(Math.round(s(a,"amount")??0)),i);let _="captured";return r(a,"status")==="succeeded"&&(_="refunded"),{amount:c,capturedAmount:c,createdAt:Date.now(),id:e.sessionId,provider:"dodopayments",referenceId:"",refundedAmount:c,state:_,updatedAt:Date.now()}},reportUsage:async e=>{await t.usageEvents.ingest({events:[{customer_id:e.customerId??e.referenceId,event_id:e.idempotencyKey,event_name:e.featureId,metadata:{value:e.quantity},timestamp:e.timestamp===void 0?void 0:new Date(e.timestamp).toISOString()}]})},resumeSubscription:async e=>{const a=await t.subscriptions.update(e,{cancel_at_next_billing_date:!1});return p(a)},updateSubscription:async(e,a)=>{if(a.priceId!==void 0||a.quantity!==void 0){const i=o(a.priceId!==void 0&&a.quantity!==void 0?void 0:await t.subscriptions.retrieve(e));await t.subscriptions.changePlan(e,{product_id:a.priceId??r(i,"product_id")??"",proration_billing_mode:"prorated_immediately",quantity:a.quantity??s(i,"quantity")??1})}return p(await t.subscriptions.retrieve(e))}}};export{z as createDodoPaymentsAdapter};
@@ -0,0 +1,31 @@
1
+ import { P as PaymentAdapter } from "../packem_shared/adapter.d-CMjjkTGB.mjs";
2
+ /**
3
+ * The `@polar-sh/sdk` surface the adapter uses, as a structural type — a real `Polar` instance
4
+ * satisfies it without a cast. Resources are `unknown` (the adapter re-types the client as the real
5
+ * `Polar` internally); this keeps the SDK's full type out of the published declarations.
6
+ * @experimental
7
+ */
8
+ interface PolarClientLike {
9
+ readonly checkouts: unknown;
10
+ readonly customers: unknown;
11
+ readonly customerSessions: unknown;
12
+ readonly events: unknown;
13
+ readonly orders: unknown;
14
+ readonly refunds: unknown;
15
+ readonly subscriptions: unknown;
16
+ }
17
+ /**
18
+ * `PolarAdapterOptions` is part of the experimental `@lunora/payment` API and may change without a major version bump.
19
+ * @experimental
20
+ */
21
+ interface PolarAdapterOptions {
22
+ readonly client: PolarClientLike;
23
+ readonly webhookSecret: string;
24
+ readonly webhookToleranceSeconds?: number;
25
+ }
26
+ /**
27
+ * `createPolarAdapter` is part of the experimental `@lunora/payment` API and may change without a major version bump.
28
+ * @experimental
29
+ */
30
+ declare const createPolarAdapter: (options: PolarAdapterOptions) => PaymentAdapter;
31
+ export { type PolarAdapterOptions, type PolarClientLike, createPolarAdapter };
@@ -0,0 +1,31 @@
1
+ import { P as PaymentAdapter } from "../packem_shared/adapter.d-CMjjkTGB.js";
2
+ /**
3
+ * The `@polar-sh/sdk` surface the adapter uses, as a structural type — a real `Polar` instance
4
+ * satisfies it without a cast. Resources are `unknown` (the adapter re-types the client as the real
5
+ * `Polar` internally); this keeps the SDK's full type out of the published declarations.
6
+ * @experimental
7
+ */
8
+ interface PolarClientLike {
9
+ readonly checkouts: unknown;
10
+ readonly customers: unknown;
11
+ readonly customerSessions: unknown;
12
+ readonly events: unknown;
13
+ readonly orders: unknown;
14
+ readonly refunds: unknown;
15
+ readonly subscriptions: unknown;
16
+ }
17
+ /**
18
+ * `PolarAdapterOptions` is part of the experimental `@lunora/payment` API and may change without a major version bump.
19
+ * @experimental
20
+ */
21
+ interface PolarAdapterOptions {
22
+ readonly client: PolarClientLike;
23
+ readonly webhookSecret: string;
24
+ readonly webhookToleranceSeconds?: number;
25
+ }
26
+ /**
27
+ * `createPolarAdapter` is part of the experimental `@lunora/payment` API and may change without a major version bump.
28
+ * @experimental
29
+ */
30
+ declare const createPolarAdapter: (options: PolarAdapterOptions) => PaymentAdapter;
31
+ export { type PolarAdapterOptions, type PolarClientLike, createPolarAdapter };
@@ -0,0 +1 @@
1
+ import{a as p,r as n,f as i,e as w,p as I,b as s}from"../packem_shared/json-D85Nbd92.mjs";import{money as m,zeroMoney as f}from"../packem_shared/addMoney-BiiMn67T.mjs";import{verifyStandardWebhook as _}from"../packem_shared/constantTimeEqual-BpVBvmN-.mjs";import{e as h}from"../packem_shared/not-supported-DwGy4SQL.mjs";import{i as P}from"../packem_shared/subscription-event-C-71ye9J.mjs";const y=o=>o instanceof Date?o.getTime():I(typeof o=="string"?o:void 0),v={draft:"initiated",paid:"captured",partially_refunded:"partially_refunded",pending:"initiated",refunded:"refunded",void:"canceled"},g={active:"active",canceled:"canceled",incomplete:"past_due",incomplete_expired:"canceled",past_due:"past_due",trialing:"trialing",unpaid:"past_due"},b=h("polar (merchant-of-record)"),u=o=>{const a=p(o),t=Date.now();return{cancelAtPeriodEnd:w(a,"cancelAtPeriodEnd")??!1,createdAt:t,currentPeriodEnd:y(a.currentPeriodEnd),currentPeriodStart:y(a.currentPeriodStart),id:n(a,"id")??"",priceId:n(a,"productId")??"",provider:"polar",quantity:1,referenceId:i(a)??"",state:g[n(a,"status")??""]??"active",updatedAt:t}},A=o=>{const a=p(o),t=Date.now(),e=n(a,"currency")??"usd",r=m(BigInt(Math.round(s(a,"totalAmount")??s(a,"amount")??0)),e),d=v[n(a,"status")??""]??"initiated";return{amount:r,capturedAmount:d==="captured"||d==="partially_refunded"||d==="refunded"?r:f(e),createdAt:t,id:n(a,"id")??"",provider:"polar",referenceId:i(a)??"",refundedAmount:d==="refunded"?r:f(e),state:d,updatedAt:t}},S=(o,a,t)=>{const e={eventId:o,provider:"polar",raw:{object:t,type:a}},r=n(t,"currency")??"usd";switch(a){case"order.created":case"order.paid":return a==="order.created"&&v[n(t,"status")??""]!=="captured"?{...e,type:"unhandled"}:{...e,amount:m(BigInt(s(t,"total_amount")??s(t,"amount")??0),r),customerId:n(t,"customer_id"),referenceId:i(t),sessionId:n(t,"id"),subscriptionId:n(t,"subscription_id"),type:"payment.captured"};case"refund.created":return{...e,amount:m(BigInt(s(t,"amount")??0),r),referenceId:i(t),sessionId:n(t,"order_id")??n(t,"id"),type:"payment.refunded"};case"subscription.active":case"subscription.canceled":case"subscription.created":case"subscription.revoked":case"subscription.uncanceled":case"subscription.updated":{const d=a==="subscription.revoked"?"subscription.canceled":P(g[n(t,"status")??""]);return{...e,cancelAtPeriodEnd:w(t,"cancel_at_period_end"),currentPeriodEnd:I(n(t,"current_period_end")),currentPeriodStart:I(n(t,"current_period_start")),customerId:n(t,"customer_id"),priceId:n(t,"product_id"),referenceId:i(t),subscriptionId:n(t,"id"),type:d}}default:return{...e,type:"unhandled"}}},B=o=>{const{webhookSecret:a}=o,t=o.client;return{cancelPayment:()=>b("manual payment cancellation"),cancelSubscription:async(e,r)=>{const d=r?.atPeriodEnd?await t.subscriptions.update({id:e,subscriptionUpdate:{cancelAtPeriodEnd:!0}}):await t.subscriptions.revoke({id:e});return u(d)},capabilities:{merchantOfRecord:!0,portal:!0,usageMetering:!0},capturePayment:e=>b("manual capture"),createCheckout:async e=>{const r=await t.checkouts.create({customerEmail:e.customerId?void 0:e.email,customerId:e.customerId,externalCustomerId:e.referenceId,metadata:{...e.metadata,referenceId:e.referenceId},products:[e.priceId],returnUrl:e.cancelUrl,successUrl:e.successUrl});return{id:r.id,provider:"polar",url:r.url}},createPortalSession:async e=>({url:(await t.customerSessions.create({customerId:e.customerId})).customerPortalUrl}),getOrCreateCustomer:async e=>{const r=await t.customers.create({email:e.email??"",externalId:e.referenceId,metadata:{...e.metadata,referenceId:e.referenceId},type:"individual"});return{createdAt:Date.now(),email:r.email??void 0,id:r.id,provider:"polar",referenceId:e.referenceId}},getPaymentStatus:async e=>A(await t.orders.get({id:e})),getSubscriptionStatus:async e=>u(await t.subscriptions.get({id:e})),identifier:"polar",parseWebhook:async({headers:e,payload:r})=>{const d=e.get("webhook-id")??"";await _({payload:r,secret:a,toleranceSeconds:o.webhookToleranceSeconds,webhookId:d,webhookSignature:e.get("webhook-signature")??"",webhookTimestamp:e.get("webhook-timestamp")??""});const c=p(JSON.parse(r));return S(d,n(c,"type")??"",p(c.data))},refundPayment:async e=>{const r=e.amount?void 0:await t.orders.get({id:e.sessionId}),d=e.amount?.currency??r?.currency??"usd",c=e.amount?Number(e.amount.minorUnits):r?.totalAmount??0;await t.refunds.create({amount:c,orderId:e.sessionId,reason:e.reason??"customer_request"});const l=e.amount??m(BigInt(Math.round(c)),d);return{amount:l,capturedAmount:l,createdAt:Date.now(),id:e.sessionId,provider:"polar",referenceId:"",refundedAmount:l,state:"refunded",updatedAt:Date.now()}},reportUsage:async e=>{await t.events.ingest({events:[{externalCustomerId:e.referenceId,metadata:{value:e.quantity},name:e.featureId,timestamp:e.timestamp===void 0?void 0:new Date(e.timestamp)}]})},resumeSubscription:async e=>{const r=await t.subscriptions.update({id:e,subscriptionUpdate:{cancelAtPeriodEnd:!1}});return u(r)},updateSubscription:async(e,r)=>{const d=await t.subscriptions.update({id:e,subscriptionUpdate:r.priceId?{productId:r.priceId}:{}});return u(d)}}};export{B as createPolarAdapter};
@@ -0,0 +1,32 @@
1
+ import { P as PaymentAdapter } from "../packem_shared/adapter.d-CMjjkTGB.mjs";
2
+ /**
3
+ * The Stripe SDK surface the adapter uses, as a structural type — a real `Stripe` instance satisfies
4
+ * it without a cast. Resources are `unknown` here (the adapter re-types the client as the real
5
+ * `Stripe` internally); this keeps the SDK's full type out of the published declaration files.
6
+ * @experimental
7
+ */
8
+ interface StripeClientLike {
9
+ readonly billing: unknown;
10
+ readonly billingPortal: unknown;
11
+ readonly checkout: unknown;
12
+ readonly customers: unknown;
13
+ readonly paymentIntents: unknown;
14
+ readonly refunds: unknown;
15
+ readonly subscriptions: unknown;
16
+ readonly webhooks: unknown;
17
+ }
18
+ /**
19
+ * `StripeAdapterOptions` is part of the experimental `@lunora/payment` API and may change without a major version bump.
20
+ * @experimental
21
+ */
22
+ interface StripeAdapterOptions {
23
+ readonly client: StripeClientLike;
24
+ readonly webhookSecret: string;
25
+ readonly webhookToleranceSeconds?: number;
26
+ }
27
+ /**
28
+ * `createStripeAdapter` is part of the experimental `@lunora/payment` API and may change without a major version bump.
29
+ * @experimental
30
+ */
31
+ declare const createStripeAdapter: (options: StripeAdapterOptions) => PaymentAdapter;
32
+ export { type StripeAdapterOptions, type StripeClientLike, createStripeAdapter };
@@ -0,0 +1,32 @@
1
+ import { P as PaymentAdapter } from "../packem_shared/adapter.d-CMjjkTGB.js";
2
+ /**
3
+ * The Stripe SDK surface the adapter uses, as a structural type — a real `Stripe` instance satisfies
4
+ * it without a cast. Resources are `unknown` here (the adapter re-types the client as the real
5
+ * `Stripe` internally); this keeps the SDK's full type out of the published declaration files.
6
+ * @experimental
7
+ */
8
+ interface StripeClientLike {
9
+ readonly billing: unknown;
10
+ readonly billingPortal: unknown;
11
+ readonly checkout: unknown;
12
+ readonly customers: unknown;
13
+ readonly paymentIntents: unknown;
14
+ readonly refunds: unknown;
15
+ readonly subscriptions: unknown;
16
+ readonly webhooks: unknown;
17
+ }
18
+ /**
19
+ * `StripeAdapterOptions` is part of the experimental `@lunora/payment` API and may change without a major version bump.
20
+ * @experimental
21
+ */
22
+ interface StripeAdapterOptions {
23
+ readonly client: StripeClientLike;
24
+ readonly webhookSecret: string;
25
+ readonly webhookToleranceSeconds?: number;
26
+ }
27
+ /**
28
+ * `createStripeAdapter` is part of the experimental `@lunora/payment` API and may change without a major version bump.
29
+ * @experimental
30
+ */
31
+ declare const createStripeAdapter: (options: StripeAdapterOptions) => PaymentAdapter;
32
+ export { type StripeAdapterOptions, type StripeClientLike, createStripeAdapter };
@@ -0,0 +1 @@
1
+ import{LunoraPaymentError as A}from"../packem_shared/LunoraPaymentError-DWQ-v_NC.mjs";import{idempotencyKey as P}from"../packem_shared/idempotencyKey-CfJKqcE3.mjs";import{r as a,e as b,b as o,a as u}from"../packem_shared/json-D85Nbd92.mjs";import{compareMoney as S,money as m,zeroMoney as f}from"../packem_shared/addMoney-BiiMn67T.mjs";import{i as q}from"../packem_shared/subscription-event-C-71ye9J.mjs";const E={canceled:"canceled",processing:"authorized",requires_action:"authorized",requires_capture:"authorized",requires_confirmation:"initiated",requires_payment_method:"initiated",succeeded:"captured"},v={active:"active",canceled:"canceled",incomplete:"past_due",incomplete_expired:"canceled",past_due:"past_due",paused:"paused",trialing:"trialing",unpaid:"past_due"},s=i=>a(u(i.metadata),"referenceId")??a(i,"client_reference_id"),_=i=>{const n=u(i.items),t=Array.isArray(n.data)?n.data:[];return u(t[0])},h=i=>a(u(_(i).price),"id"),w=i=>o(_(i),"quantity"),g=i=>{const n=o(_(i),"current_period_end")??o(i,"current_period_end");return n===void 0?void 0:n*1e3},K=i=>{const n=o(_(i),"current_period_start")??o(i,"current_period_start");return n===void 0?void 0:n*1e3},y=i=>{const n=u(i),t=a(n,"currency")??"usd",e=o(n,"amount")??0,r=m(BigInt(Math.round(e)),t),c=E[a(n,"status")??""]??"initiated",d=Date.now();return{amount:r,capturedAmount:c==="captured"?m(BigInt(Math.round(o(n,"amount_received")??e)),t):f(t),createdAt:d,id:a(n,"id")??"",provider:"stripe",referenceId:s(n)??"",refundedAmount:f(t),state:c,updatedAt:d}},l=i=>{const n=u(i),t=Date.now();return{cancelAtPeriodEnd:b(n,"cancel_at_period_end")??!1,createdAt:t,currentPeriodEnd:g(n),currentPeriodStart:K(n),id:a(n,"id")??"",priceId:h(n)??"",provider:"stripe",quantity:w(n)??1,referenceId:s(n)??"",state:v[a(n,"status")??""]??"active",updatedAt:t}},M=(i,n,t)=>{const e={eventId:i,provider:"stripe",raw:{object:t,type:n}},r=a(t,"currency")??"usd";switch(n){case"charge.refunded":return{...e,amount:m(BigInt(Math.round(o(t,"amount_refunded")??0)),r),amountKind:"absolute",referenceId:s(t),sessionId:a(t,"payment_intent")??a(t,"id"),type:"payment.refunded"};case"checkout.session.completed":{if(a(t,"mode")==="subscription"){const d=a(t,"payment_status"),p=d==="paid"||d==="no_payment_required";return{...e,customerId:a(t,"customer"),referenceId:s(t),subscriptionId:a(t,"subscription"),type:p?"subscription.active":"subscription.updated"}}const c=o(t,"amount_total");return{...e,amount:c===void 0?void 0:m(BigInt(Math.round(c)),r),customerId:a(t,"customer"),referenceId:s(t),sessionId:a(t,"payment_intent")??a(t,"id"),type:"payment.captured"}}case"customer.subscription.created":case"customer.subscription.updated":return{...e,cancelAtPeriodEnd:b(t,"cancel_at_period_end"),currentPeriodEnd:g(t),currentPeriodStart:K(t),customerId:a(t,"customer"),priceId:h(t),quantity:w(t),referenceId:s(t),subscriptionId:a(t,"id"),type:q(v[a(t,"status")??""])};case"customer.subscription.deleted":return{...e,referenceId:s(t),subscriptionId:a(t,"id"),type:"subscription.canceled"};case"payment_intent.amount_capturable_updated":return{...e,amount:m(BigInt(Math.round(o(t,"amount")??0)),r),referenceId:s(t),sessionId:a(t,"id"),type:"payment.authorized"};case"payment_intent.payment_failed":return{...e,referenceId:s(t),sessionId:a(t,"id"),type:"payment.failed"};case"payment_intent.succeeded":return{...e,amount:m(BigInt(Math.round(o(t,"amount_received")??o(t,"amount")??0)),r),customerId:a(t,"customer"),referenceId:s(t),sessionId:a(t,"id"),type:"payment.captured"};default:return{...e,type:"unhandled"}}},D=i=>{const{webhookSecret:n}=i,t=i.client;return{cancelPayment:async(e,r)=>{const c=await t.paymentIntents.cancel(e,void 0,{idempotencyKey:r?.idempotencyKey});return y(c)},cancelSubscription:async(e,r)=>{const c=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(c)},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 y(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:P("customer","stripe",e.referenceId)});return{createdAt:Date.now(),email:r.email??void 0,id:r.id,provider:"stripe",referenceId:e.referenceId}},getPaymentStatus:async e=>y(await t.paymentIntents.retrieve(e)),getSubscriptionStatus:async e=>l(await t.subscriptions.retrieve(e)),identifier:"stripe",parseWebhook:async({headers:e,payload:r})=>{const c=e.get("stripe-signature")??"";let d;try{d=await t.webhooks.constructEventAsync(r,c,n,i.webhookToleranceSeconds)}catch(I){throw new A("WEBHOOK_SIGNATURE_INVALID",I instanceof Error?I.message:"invalid webhook signature")}const p=u(u(d.data).object);return M(d.id,d.type,p)},refundPayment:async e=>{await t.refunds.create({amount:e.amount?Number(e.amount.minorUnits):void 0,payment_intent:e.sessionId,reason:e.reason},{idempotencyKey:e.idempotencyKey});const r=await t.paymentIntents.retrieve(e.sessionId),c=y(r),d=e.amount??c.capturedAmount,p=e.amount!==void 0&&S(e.amount,c.capturedAmount)<0;return{...c,refundedAmount:d,state:p?"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=>{const r=await t.subscriptions.update(e,{cancel_at_period_end:!1});return l(r)},updateSubscription:async(e,r)=>{const c={};if(r.priceId!==void 0||r.quantity!==void 0){const p=await t.subscriptions.retrieve(e);c.items=[{id:p.items.data[0]?.id,price:r.priceId,quantity:r.quantity}]}const d=await t.subscriptions.update(e,c);return l(d)}}};export{D as createStripeAdapter};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/payment",
3
- "version": "1.0.0-alpha.4",
3
+ "version": "1.0.0-alpha.40",
4
4
  "description": "Provider-agnostic payments for Lunora: Stripe-first adapter, webhook sync, and subscription/payment state machine",
5
5
  "keywords": [
6
6
  "billing",
@@ -26,7 +26,7 @@
26
26
  "directory": "packages/payment"
27
27
  },
28
28
  "files": [
29
- "dist",
29
+ "./dist",
30
30
  "__assets__",
31
31
  "README.md",
32
32
  "LICENSE.md"
@@ -41,20 +41,61 @@
41
41
  "types": "./dist/index.d.ts",
42
42
  "import": "./dist/index.mjs"
43
43
  },
44
+ "./stripe": {
45
+ "types": "./dist/providers/stripe.d.ts",
46
+ "import": "./dist/providers/stripe.mjs"
47
+ },
48
+ "./polar": {
49
+ "types": "./dist/providers/polar.d.ts",
50
+ "import": "./dist/providers/polar.mjs"
51
+ },
52
+ "./autumn": {
53
+ "types": "./dist/providers/autumn.d.ts",
54
+ "import": "./dist/providers/autumn.mjs"
55
+ },
56
+ "./autumn-features": {
57
+ "types": "./dist/providers/autumn-features.d.ts",
58
+ "import": "./dist/providers/autumn-features.mjs"
59
+ },
60
+ "./dodopayments": {
61
+ "types": "./dist/providers/dodopayments.d.ts",
62
+ "import": "./dist/providers/dodopayments.mjs"
63
+ },
64
+ "./creem": {
65
+ "types": "./dist/providers/creem.d.ts",
66
+ "import": "./dist/providers/creem.mjs"
67
+ },
44
68
  "./package.json": "./package.json"
45
69
  },
46
70
  "publishConfig": {
47
71
  "access": "public"
48
72
  },
49
73
  "dependencies": {
50
- "@lunora/server": "1.0.0-alpha.4",
51
- "@lunora/values": "1.0.0-alpha.2",
74
+ "@lunora/errors": "1.0.0-alpha.8",
75
+ "@lunora/server": "1.0.0-alpha.40",
76
+ "@lunora/values": "1.0.0-alpha.11",
52
77
  "dinero.js": "2.0.2"
53
78
  },
54
79
  "peerDependencies": {
55
- "stripe": "^19.0.0"
80
+ "@polar-sh/sdk": "^0.48.0",
81
+ "autumn-js": "^1.2.0",
82
+ "creem": "^1.5.0",
83
+ "dodopayments": "^2.41.0",
84
+ "stripe": "^22.0.0"
56
85
  },
57
86
  "peerDependenciesMeta": {
87
+ "@polar-sh/sdk": {
88
+ "optional": true
89
+ },
90
+ "autumn-js": {
91
+ "optional": true
92
+ },
93
+ "creem": {
94
+ "optional": true
95
+ },
96
+ "dodopayments": {
97
+ "optional": true
98
+ },
58
99
  "stripe": {
59
100
  "optional": true
60
101
  }
@@ -1,22 +0,0 @@
1
- const STATUS_BY_CODE = {
2
- CONFIG_INVALID: 500,
3
- CURRENCY_MISMATCH: 400,
4
- FORBIDDEN: 403,
5
- INVALID_TRANSITION: 409,
6
- NOT_FOUND: 404,
7
- PROVIDER_ERROR: 502,
8
- WEBHOOK_SIGNATURE_INVALID: 400,
9
- WEBHOOK_TIMESTAMP_INVALID: 400
10
- };
11
- class LunoraPaymentError extends Error {
12
- code;
13
- status;
14
- constructor(code, message) {
15
- super(message);
16
- this.name = "LunoraPaymentError";
17
- this.code = code;
18
- this.status = STATUS_BY_CODE[code];
19
- }
20
- }
21
-
22
- export { LunoraPaymentError };