@lunora/payment 1.0.0-alpha.61 → 1.0.0-alpha.63

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
@@ -472,6 +472,14 @@ declare const canTransitionSubscription: (from: SubscriptionState, action: Subsc
472
472
  declare const applyWebhookAction: (store: PaymentStore, action: WebhookAction, observer?: PaymentObserver) => Promise<ApplyResult>;
473
473
  /**
474
474
  * Constant-time string comparison to avoid leaking byte positions via timing.
475
+ *
476
+ * Re-exported from `shared/constant-time-equal` rather than defined here. The
477
+ * copy that used to live at this spot returned early on a length mismatch, so
478
+ * an attacker learned the expected signature's LENGTH from the response time —
479
+ * the exact divergence that shared file was created to stop, and which it
480
+ * records having already fixed once in the relay hub. It also compared by code
481
+ * POINT, making timing depend on surrogate boundaries; the canonical one
482
+ * compares per UTF-16 code unit.
475
483
  * @experimental
476
484
  */
477
485
  declare const constantTimeEqual: (a: string, b: string) => boolean;
@@ -491,7 +499,7 @@ interface VerifyStandardWebhookInput {
491
499
  readonly toleranceSeconds?: number;
492
500
  /** `webhook-id` header. */
493
501
  readonly webhookId: string;
494
- /** `webhook-signature` header — space-separated `v1,&lt;base64>` entries. */
502
+ /** `webhook-signature` header — space-separated `v1,<base64>` entries. */
495
503
  readonly webhookSignature: string;
496
504
  /** `webhook-timestamp` header — unix seconds as a string. */
497
505
  readonly webhookTimestamp: string;
package/dist/index.d.ts CHANGED
@@ -472,6 +472,14 @@ declare const canTransitionSubscription: (from: SubscriptionState, action: Subsc
472
472
  declare const applyWebhookAction: (store: PaymentStore, action: WebhookAction, observer?: PaymentObserver) => Promise<ApplyResult>;
473
473
  /**
474
474
  * Constant-time string comparison to avoid leaking byte positions via timing.
475
+ *
476
+ * Re-exported from `shared/constant-time-equal` rather than defined here. The
477
+ * copy that used to live at this spot returned early on a length mismatch, so
478
+ * an attacker learned the expected signature's LENGTH from the response time —
479
+ * the exact divergence that shared file was created to stop, and which it
480
+ * records having already fixed once in the relay hub. It also compared by code
481
+ * POINT, making timing depend on surrogate boundaries; the canonical one
482
+ * compares per UTF-16 code unit.
475
483
  * @experimental
476
484
  */
477
485
  declare const constantTimeEqual: (a: string, b: string) => boolean;
@@ -491,7 +499,7 @@ interface VerifyStandardWebhookInput {
491
499
  readonly toleranceSeconds?: number;
492
500
  /** `webhook-id` header. */
493
501
  readonly webhookId: string;
494
- /** `webhook-signature` header — space-separated `v1,&lt;base64>` entries. */
502
+ /** `webhook-signature` header — space-separated `v1,<base64>` entries. */
495
503
  readonly webhookSignature: string;
496
504
  /** `webhook-timestamp` header — unix seconds as a string. */
497
505
  readonly webhookTimestamp: string;
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import{createAdapterRegistry as r}from"./packem_shared/createAdapterRegistry-CafjyQwx.mjs";import{lunoraDatabaseToPaymentDatabase as a,paymentsFromContext as n}from"./packem_shared/lunoraDatabaseToPaymentDatabase-Bn3aBIoh.mjs";import{createPayment as y}from"./packem_shared/createPayment-BW6jnMP_.mjs";import{createDatabasePaymentStore as p}from"./packem_shared/createDatabasePaymentStore-4l41pJ0l.mjs";import{entitlementsForReference as s,featureNames as c,hasActivePrice as x,resolveEntitlements as S,usagePeriodStart as l}from"./packem_shared/entitlementsForReference-BbEOKu5d.mjs";import{LunoraPaymentError as T}from"./packem_shared/LunoraPaymentError-35kSImFc.mjs";import{idempotencyKey as P}from"./packem_shared/idempotencyKey-CfJKqcE3.mjs";import{addMoney as d,allocateMoney as A,compareMoney as E,formatMoney as N,fromMoneyJSON as h,isZeroDecimalCurrency as R,isZeroMoney as v,money as C,subtractMoney as D,toMoneyJSON as I,zeroMoney as _}from"./packem_shared/addMoney-JN0UrVXA.mjs";import{reconcile as L}from"./packem_shared/reconcile-y9d1yiVb.mjs";import{default as k}from"./packem_shared/paymentTables-BMtUrXkM.mjs";import{PAYMENT_TERMINAL_STATES as J,SUBSCRIPTION_TERMINAL_STATES as W,canTransitionPayment as Z,canTransitionSubscription as q,nextPaymentState as z,nextSubscriptionState as B}from"./packem_shared/PAYMENT_TERMINAL_STATES-DVNbZxBy.mjs";import{MemoryPaymentStore as K}from"./packem_shared/MemoryPaymentStore-BICI1RdZ.mjs";import{default as Y}from"./packem_shared/applyWebhookAction-6JwJo2XL.mjs";import{constantTimeEqual as w,hmacSha256Hex as G,verifyCreemSignature as Q,verifyStandardWebhook as V}from"./packem_shared/constantTimeEqual-mkrMYjOP.mjs";export{T as LunoraPaymentError,K as MemoryPaymentStore,J as PAYMENT_TERMINAL_STATES,W as SUBSCRIPTION_TERMINAL_STATES,d as addMoney,A as allocateMoney,Y as applyWebhookAction,Z as canTransitionPayment,q as canTransitionSubscription,E as compareMoney,w as constantTimeEqual,r as createAdapterRegistry,p as createDatabasePaymentStore,y as createPayment,s as entitlementsForReference,c as featureNames,N as formatMoney,h as fromMoneyJSON,x as hasActivePrice,G as hmacSha256Hex,P as idempotencyKey,R as isZeroDecimalCurrency,v as isZeroMoney,a as lunoraDatabaseToPaymentDatabase,C as money,z as nextPaymentState,B as nextSubscriptionState,k as paymentTables,n as paymentsFromContext,L as reconcile,S as resolveEntitlements,D as subtractMoney,I as toMoneyJSON,l as usagePeriodStart,Q as verifyCreemSignature,V as verifyStandardWebhook,_ as zeroMoney};
1
+ import{createAdapterRegistry as r}from"./packem_shared/createAdapterRegistry-CafjyQwx.mjs";import{lunoraDatabaseToPaymentDatabase as a,paymentsFromContext as n}from"./packem_shared/lunoraDatabaseToPaymentDatabase-Bn3aBIoh.mjs";import{createPayment as y}from"./packem_shared/createPayment-BW6jnMP_.mjs";import{createDatabasePaymentStore as p}from"./packem_shared/createDatabasePaymentStore-4l41pJ0l.mjs";import{entitlementsForReference as s,featureNames as c,hasActivePrice as x,resolveEntitlements as S,usagePeriodStart as l}from"./packem_shared/entitlementsForReference-BbEOKu5d.mjs";import{LunoraPaymentError as T}from"./packem_shared/LunoraPaymentError-35kSImFc.mjs";import{idempotencyKey as P}from"./packem_shared/idempotencyKey-CfJKqcE3.mjs";import{addMoney as d,allocateMoney as A,compareMoney as E,formatMoney as N,fromMoneyJSON as h,isZeroDecimalCurrency as R,isZeroMoney as v,money as C,subtractMoney as D,toMoneyJSON as I,zeroMoney as _}from"./packem_shared/addMoney-JN0UrVXA.mjs";import{reconcile as L}from"./packem_shared/reconcile-y9d1yiVb.mjs";import{default as k}from"./packem_shared/paymentTables-BMtUrXkM.mjs";import{PAYMENT_TERMINAL_STATES as J,SUBSCRIPTION_TERMINAL_STATES as W,canTransitionPayment as Z,canTransitionSubscription as q,nextPaymentState as z,nextSubscriptionState as B}from"./packem_shared/PAYMENT_TERMINAL_STATES-DVNbZxBy.mjs";import{MemoryPaymentStore as K}from"./packem_shared/MemoryPaymentStore-BICI1RdZ.mjs";import{default as Y}from"./packem_shared/applyWebhookAction-6JwJo2XL.mjs";import{constantTimeEqual as w,hmacSha256Hex as G,verifyCreemSignature as Q,verifyStandardWebhook as V}from"./packem_shared/constantTimeEqual-DG_4PS78.mjs";export{T as LunoraPaymentError,K as MemoryPaymentStore,J as PAYMENT_TERMINAL_STATES,W as SUBSCRIPTION_TERMINAL_STATES,d as addMoney,A as allocateMoney,Y as applyWebhookAction,Z as canTransitionPayment,q as canTransitionSubscription,E as compareMoney,w as constantTimeEqual,r as createAdapterRegistry,p as createDatabasePaymentStore,y as createPayment,s as entitlementsForReference,c as featureNames,N as formatMoney,h as fromMoneyJSON,x as hasActivePrice,G as hmacSha256Hex,P as idempotencyKey,R as isZeroDecimalCurrency,v as isZeroMoney,a as lunoraDatabaseToPaymentDatabase,C as money,z as nextPaymentState,B as nextSubscriptionState,k as paymentTables,n as paymentsFromContext,L as reconcile,S as resolveEntitlements,D as subtractMoney,I as toMoneyJSON,l as usagePeriodStart,Q as verifyCreemSignature,V as verifyStandardWebhook,_ as zeroMoney};
@@ -0,0 +1 @@
1
+ import{LunoraPaymentError as r}from"./LunoraPaymentError-35kSImFc.mjs";const m=(t,e)=>{const a=Math.max(t.length,e.length);let o=t.length^e.length;for(let n=0;n<a;n+=1){const s=n<t.length?t.charCodeAt(n):0,c=n<e.length?e.charCodeAt(n):0;o|=s^c}return o===0},h=new TextEncoder,I=t=>[...new Uint8Array(t)].map(e=>e.toString(16).padStart(2,"0")).join(""),g="whsec_",d=t=>new Uint8Array(Array.from(atob(t),e=>e.codePointAt(0)??0)),u=t=>btoa(String.fromCodePoint(...new Uint8Array(t))),A=async(t,e)=>{const a=await crypto.subtle.importKey("raw",t,{hash:"SHA-256",name:"HMAC"},!1,["sign"]),o=await crypto.subtle.sign("HMAC",a,h.encode(e));return u(o)},l=m,f=async(t,e)=>{const a=await crypto.subtle.importKey("raw",h.encode(t),{hash:"SHA-256",name:"HMAC"},!1,["sign"]),o=await crypto.subtle.sign("HMAC",a,h.encode(e));return I(o)},y=async t=>{if(!t.secret)throw new r("CONFIG_INVALID","webhook secret not configured");const e=t.toleranceSeconds??300,a=t.now??Date.now(),o=Number(t.webhookTimestamp);if(!t.webhookId||!t.webhookSignature||!Number.isFinite(o))throw new r("WEBHOOK_SIGNATURE_INVALID","missing standard-webhooks headers");if(Math.abs(Math.floor(a/1e3)-o)>e)throw new r("WEBHOOK_TIMESTAMP_INVALID","signature timestamp outside tolerance");const n=t.secret.startsWith(g)?t.secret.slice(g.length):t.secret;if(!n)throw new r("CONFIG_INVALID","webhook secret not configured");const s=d(n);if(s.length===0)throw new r("CONFIG_INVALID","webhook secret not configured");const c=await A(s,`${t.webhookId}.${t.webhookTimestamp}.${t.payload}`);if(!t.webhookSignature.split(" ").map(i=>{const w=i.indexOf(",");return w===-1?"":i.slice(w+1)}).filter(Boolean).some(i=>l(i,c)))throw new r("WEBHOOK_SIGNATURE_INVALID","no matching signature")},N=async t=>{if(!t.secret)throw new r("CONFIG_INVALID","webhook secret not configured");if(!t.signature)throw new r("WEBHOOK_SIGNATURE_INVALID","missing creem-signature header");const e=await f(t.secret,t.payload);if(!l(t.signature,e))throw new r("WEBHOOK_SIGNATURE_INVALID","no matching signature")};export{l as constantTimeEqual,f as hmacSha256Hex,N as verifyCreemSignature,y as verifyStandardWebhook};
@@ -0,0 +1 @@
1
+ const s={active:"subscription.active",canceled:"subscription.canceled",past_due:"subscription.past_due",paused:"subscription.paused",trialing:"subscription.active"},t=i=>i===void 0?"subscription.updated":s[i]??"subscription.updated";export{t as i};
@@ -1 +1 @@
1
- import{LunoraPaymentError as C}from"../packem_shared/LunoraPaymentError-35kSImFc.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-JN0UrVXA.mjs";import{verifyStandardWebhook as B}from"../packem_shared/constantTimeEqual-mkrMYjOP.mjs";import{e as j}from"../packem_shared/not-supported-Cqa8vy-R.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"},$={activated:"active",canceled:"canceled",cancelled:"canceled",expired:"canceled",scheduled:"paused"},b="::",y=j("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:$[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};
1
+ import{LunoraPaymentError as C}from"../packem_shared/LunoraPaymentError-35kSImFc.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-JN0UrVXA.mjs";import{verifyStandardWebhook as B}from"../packem_shared/constantTimeEqual-DG_4PS78.mjs";import{e as j}from"../packem_shared/not-supported-Cqa8vy-R.mjs";import{i as E}from"../packem_shared/subscription-event-BosLshSM.mjs";const h={active:"active",canceled:"canceled",expired:"canceled",past_due:"past_due",scheduled:"paused",trialing:"trialing"},$={activated:"active",canceled:"canceled",cancelled:"canceled",expired:"canceled",scheduled:"paused"},b="::",y=j("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:$[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};
@@ -1 +1 @@
1
- import{a as o,c as u,f as p,r as n,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-JN0UrVXA.mjs";import{verifyCreemSignature as P}from"../packem_shared/constantTimeEqual-mkrMYjOP.mjs";import{e as S}from"../packem_shared/not-supported-Cqa8vy-R.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(o(c),"id"),C=c=>u(c,"checkout_url","checkoutUrl")??"",g=c=>u(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=o(c),r=Date.now(),e=n(t,"status")??"";return{cancelAtPeriodEnd:g(t),createdAt:r,currentPeriodEnd:f(u(t,"current_period_end_date","currentPeriodEndDate")),currentPeriodStart:f(u(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=o(c),r=Date.now(),e=o(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=o(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=u(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(u(r,"current_period_end_date","currentPeriodEndDate")),currentPeriodStart:f(u(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:u(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(o(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=o(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=o(JSON.parse(a));return B(u(d,"id","event_id","eventId")??"",u(d,"eventType","type")??"",o(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};
1
+ import{a as o,c as u,f as p,r as n,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-JN0UrVXA.mjs";import{verifyCreemSignature as P}from"../packem_shared/constantTimeEqual-DG_4PS78.mjs";import{e as S}from"../packem_shared/not-supported-Cqa8vy-R.mjs";import{i as A}from"../packem_shared/subscription-event-BosLshSM.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(o(c),"id"),C=c=>u(c,"checkout_url","checkoutUrl")??"",g=c=>u(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=o(c),r=Date.now(),e=n(t,"status")??"";return{cancelAtPeriodEnd:g(t),createdAt:r,currentPeriodEnd:f(u(t,"current_period_end_date","currentPeriodEndDate")),currentPeriodStart:f(u(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=o(c),r=Date.now(),e=o(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=o(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=u(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(u(r,"current_period_end_date","currentPeriodEndDate")),currentPeriodStart:f(u(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:u(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(o(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=o(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=o(JSON.parse(a));return B(u(d,"id","event_id","eventId")??"",u(d,"eventType","type")??"",o(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};
@@ -1 +1 @@
1
- import{LunoraPaymentError as g}from"../packem_shared/LunoraPaymentError-35kSImFc.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-JN0UrVXA.mjs";import{verifyStandardWebhook as w}from"../packem_shared/constantTimeEqual-mkrMYjOP.mjs";import{e as S}from"../packem_shared/not-supported-Cqa8vy-R.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};
1
+ import{LunoraPaymentError as g}from"../packem_shared/LunoraPaymentError-35kSImFc.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-JN0UrVXA.mjs";import{verifyStandardWebhook as w}from"../packem_shared/constantTimeEqual-DG_4PS78.mjs";import{e as S}from"../packem_shared/not-supported-Cqa8vy-R.mjs";import{i as q}from"../packem_shared/subscription-event-BosLshSM.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};
@@ -1 +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-JN0UrVXA.mjs";import{verifyStandardWebhook as _}from"../packem_shared/constantTimeEqual-mkrMYjOP.mjs";import{e as h}from"../packem_shared/not-supported-Cqa8vy-R.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};
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-JN0UrVXA.mjs";import{verifyStandardWebhook as _}from"../packem_shared/constantTimeEqual-DG_4PS78.mjs";import{e as h}from"../packem_shared/not-supported-Cqa8vy-R.mjs";import{i as P}from"../packem_shared/subscription-event-BosLshSM.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};
@@ -1 +1 @@
1
- import{LunoraPaymentError as A}from"../packem_shared/LunoraPaymentError-35kSImFc.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-JN0UrVXA.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"}}},O=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{O as createStripeAdapter};
1
+ import{LunoraPaymentError as A}from"../packem_shared/LunoraPaymentError-35kSImFc.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-JN0UrVXA.mjs";import{i as q}from"../packem_shared/subscription-event-BosLshSM.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"}}},O=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{O as createStripeAdapter};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/payment",
3
- "version": "1.0.0-alpha.61",
3
+ "version": "1.0.0-alpha.63",
4
4
  "description": "Provider-agnostic payments for Lunora: Stripe-first adapter, webhook sync, and subscription/payment state machine",
5
5
  "keywords": [
6
6
  "billing",
@@ -71,9 +71,9 @@
71
71
  "access": "public"
72
72
  },
73
73
  "dependencies": {
74
- "@lunora/errors": "1.0.0-alpha.13",
75
- "@lunora/server": "1.0.0-alpha.61",
76
- "@lunora/values": "1.0.0-alpha.18",
74
+ "@lunora/errors": "1.0.0-alpha.14",
75
+ "@lunora/server": "1.0.0-alpha.62",
76
+ "@lunora/values": "1.0.0-alpha.19",
77
77
  "dinero.js": "2.0.2"
78
78
  },
79
79
  "peerDependencies": {
@@ -1 +0,0 @@
1
- import{LunoraPaymentError as o}from"./LunoraPaymentError-35kSImFc.mjs";const i=new TextEncoder,I=t=>[...new Uint8Array(t)].map(e=>e.toString(16).padStart(2,"0")).join(""),h="whsec_",d=t=>new Uint8Array(Array.from(atob(t),e=>e.codePointAt(0)??0)),f=t=>btoa(String.fromCodePoint(...new Uint8Array(t))),u=async(t,e)=>{const r=await crypto.subtle.importKey("raw",t,{hash:"SHA-256",name:"HMAC"},!1,["sign"]),n=await crypto.subtle.sign("HMAC",r,i.encode(e));return f(n)},g=(t,e)=>{if(t.length!==e.length)return!1;let r=0;for(let n=0;n<t.length;n+=1)r|=(t.codePointAt(n)??0)^(e.codePointAt(n)??0);return r===0},A=async(t,e)=>{const r=await crypto.subtle.importKey("raw",i.encode(t),{hash:"SHA-256",name:"HMAC"},!1,["sign"]),n=await crypto.subtle.sign("HMAC",r,i.encode(e));return I(n)},b=async t=>{if(!t.secret)throw new o("CONFIG_INVALID","webhook secret not configured");const e=t.toleranceSeconds??300,r=t.now??Date.now(),n=Number(t.webhookTimestamp);if(!t.webhookId||!t.webhookSignature||!Number.isFinite(n))throw new o("WEBHOOK_SIGNATURE_INVALID","missing standard-webhooks headers");if(Math.abs(Math.floor(r/1e3)-n)>e)throw new o("WEBHOOK_TIMESTAMP_INVALID","signature timestamp outside tolerance");const s=t.secret.startsWith(h)?t.secret.slice(h.length):t.secret;if(!s)throw new o("CONFIG_INVALID","webhook secret not configured");const c=d(s);if(c.length===0)throw new o("CONFIG_INVALID","webhook secret not configured");const m=await u(c,`${t.webhookId}.${t.webhookTimestamp}.${t.payload}`);if(!t.webhookSignature.split(" ").map(a=>{const w=a.indexOf(",");return w===-1?"":a.slice(w+1)}).filter(Boolean).some(a=>g(a,m)))throw new o("WEBHOOK_SIGNATURE_INVALID","no matching signature")},y=async t=>{if(!t.secret)throw new o("CONFIG_INVALID","webhook secret not configured");if(!t.signature)throw new o("WEBHOOK_SIGNATURE_INVALID","missing creem-signature header");const e=await A(t.secret,t.payload);if(!g(t.signature,e))throw new o("WEBHOOK_SIGNATURE_INVALID","no matching signature")};export{g as constantTimeEqual,A as hmacSha256Hex,y as verifyCreemSignature,b as verifyStandardWebhook};
@@ -1 +0,0 @@
1
- const s=i=>i==="canceled"?"subscription.canceled":i==="past_due"?"subscription.past_due":i==="paused"?"subscription.paused":i==="active"||i==="trialing"?"subscription.active":"subscription.updated";export{s as i};