@flopay/node 1.8.7 → 1.8.9

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/README.md CHANGED
@@ -50,6 +50,7 @@ const result = await flopay.checkout.sessions.create({
50
50
  successUrl: 'https://example.com/success',
51
51
  cancelUrl: 'https://example.com/cancel',
52
52
  checkoutMode: 'confirm', // 'confirm' | 'auto' | 'full'
53
+ checkoutMetadata: { merchantOrderId: 'order-123', campaign: 'summer' },
53
54
  couponCodes: ['SAVE10'],
54
55
  tagsData: { googleContainerId: 'GTM-XXXX' },
55
56
  redirectParams: { email: 'user@example.com', mode: 'confirm' },
@@ -61,6 +62,12 @@ const result = await flopay.checkout.sessions.create({
61
62
  // result = { status: 204 } (payment method already on file)
62
63
  ```
63
64
 
65
+ `checkoutMetadata` accepts `Record<string, string> | null` and is sent
66
+ unchanged. Omission leaves the request body unchanged, explicit `null` is
67
+ preserved, and `{}` remains an empty map. The backend is the sole runtime
68
+ authority for metadata limits; a validation rejection is a `FloPayError` with
69
+ the backend code, message, and HTTP `statusCode` intact.
70
+
64
71
  Pass the same `idempotencyKey` when retrying one logical session creation after
65
72
  an unknown outcome. `@flopay/node` sends a supplied non-whitespace key of at most
66
73
  255 characters unchanged as `Idempotency-Key`; it does not generate a key or add
@@ -179,8 +186,8 @@ new FloPay(secretKey: string, options?: FloPayNodeOptions)
179
186
  | Type | Description |
180
187
  |------|-------------|
181
188
  | `FloPayNodeOptions` | Constructor options |
182
- | `CreateSessionParams` | Full session creation parameters (from `@flopay/shared`), including optional `captureMethod: 'automatic' \| 'manual'` and caller-managed `idempotencyKey` |
189
+ | `CreateSessionParams` | Full session creation parameters (from `@flopay/shared`), including optional `checkoutMetadata: Record<string, string> \| null`, `captureMethod: 'automatic' \| 'manual'`, and caller-managed `idempotencyKey` |
183
190
  | `CheckoutSessionResult` | `{ status: 201, redirectUrl, nonce }` / `{ status: 204 }` / `{ status: number }` |
184
- | `CheckoutSession` | Normalized session; `status` can be `authorized`, with `paymentId` and `authorizationExpiresAt`, for manual capture |
191
+ | `CheckoutSession` | Normalized session with optional returned `checkoutMetadata`; `status` can be `authorized`, with `paymentId` and `authorizationExpiresAt`, for manual capture |
185
192
  | `Customer` | `id`, `email`, `firstName?`, `lastName?` |
186
193
  | `WebhookEvent` | `id`, `type`, `data`, `created` |
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";var j=Object.create;var m=Object.defineProperty;var z=Object.getOwnPropertyDescriptor;var F=Object.getOwnPropertyNames;var K=Object.getPrototypeOf,q=Object.prototype.hasOwnProperty;var H=(r,e)=>{for(var t in e)m(r,t,{get:e[t],enumerable:!0})},w=(r,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of F(e))!q.call(r,o)&&o!==t&&m(r,o,{get:()=>e[o],enumerable:!(i=z(e,o))||i.enumerable});return r};var W=(r,e,t)=>(t=r!=null?j(K(r)):{},w(e||!r||!r.__esModule?m(t,"default",{value:r,enumerable:!0}):t,r)),$=r=>w(m({},"__esModule",{value:!0}),r);var G={};H(G,{FloPay:()=>d,STRIPE_API_VERSION:()=>g});module.exports=$(G);var s=require("@flopay/shared"),I=W(require("stripe"),1),g="2026-04-22.dahlia";function Y(r){for(let e of r){let t=e.charCodeAt(0);if(t<=8||t>=10&&t<=31||t===127)return!0}return!1}function B(r){if(!r||r.trim()===""||r.length>s.MAX_IDEMPOTENCY_KEY_LENGTH||Y(r))return!1;try{return new Headers({[s.IDEMPOTENCY_KEY_HEADER]:r}).get(s.IDEMPOTENCY_KEY_HEADER)===r}catch{return!1}}var d=class{constructor(e,t){if(!e)throw new s.FloPayError("A secret key is required to initialize the FloPay server SDK.","authentication_error");this.stripe=new I.default(t?.stripeSecretKey??e,{apiVersion:t?.apiVersion??g,appInfo:{name:"flopay-node",version:s.SDK_VERSION}}),this.checkout={sessions:{create:this.createSession.bind(this),retrieve:this.retrieveSession.bind(this),expire:this.expireSession.bind(this),listLineItems:this.listLineItems.bind(this)}},this.webhooks={constructEvent:this.constructWebhookEvent.bind(this)},this.customers={create:this.createCustomer.bind(this),retrieve:this.retrieveCustomer.bind(this),update:this.updateCustomer.bind(this)}}async createSession(e){let{billingApiUrl:t,checkoutBaseUrl:i,items:o=[],subscriptions:f=[],products:E,account:n,successUrl:N,cancelUrl:_,checkoutMode:R="confirm",captureMethod:l,couponCodes:U=[],tagsData:S,redirectParams:x={},timeoutMs:M=12e3,clientId:O,currency:T,utmMetadata:P,idempotencyKey:k}=e,p=E??(0,s.foldIntoProducts)(o,f);(0,s.assertCaptureMethodEligible)({captureMethod:l,products:p});let h=(0,s.resolveSessionCurrency)(T,o,f,p);if(!h)throw new s.FloPayError("currency is required: pass `currency` on the session, or include a `currency` on the first item/subscription/product.","validation_error",{code:"CurrencyRequired",param:"currency"});let c={clientId:O,checkoutVersion:s.SDK_VERSION,successUrl:N,cancelUrl:_,currency:h,checkoutMode:R,products:p.map(a=>(0,s.buildProductPayload)(a,h)),accountData:{userId:n.userId,firstName:n.firstName??null,lastName:n.lastName??null,email:n.email,country:n.country??null,gender:n.gender??null,city:n.city??null,state:n.state??null,zip:n.zip??null},couponCodes:U};l==="manual"&&(c.captureMethod=l),S&&(c.tagsData=S),P?.length&&(c.utmMetadata=P);let V=`${t.replace(/\/+$/,"")}/v1/checkouts/sessions`,b=new AbortController,A=setTimeout(()=>b.abort(),M),u,y;try{let a=await fetch(V,{method:"POST",headers:{"Content-Type":"application/json",...B(k)?{[s.IDEMPOTENCY_KEY_HEADER]:k}:{}},body:JSON.stringify(c),signal:b.signal});u=a.status;try{y=await a.json()}catch{}}finally{clearTimeout(A)}if(u===201){let a=y?.data?.uuid,v=y?.data?.nonce;if(!a)throw new Error("Checkout session created but no UUID was returned by the billing API");if(!v)throw new s.FloPayError("Checkout session created but no `nonce` was returned by the billing API. Upgrade the billing service to TeamFloPay/backend#640 or later.","api_error",{code:"MissingCheckoutSessionToken"});let C=new URL(`${i.replace(/\/+$/,"")}/secure`);C.searchParams.set("id",a);for(let[L,D]of Object.entries(x))C.searchParams.set(L,D);return{status:201,redirectUrl:C.toString(),nonce:v}}return u===204?{status:204}:{status:u}}normalizeStripeSession(e){let t={open:"open",complete:"complete",expired:"expired"};return{id:e.id,clientSecret:e.client_secret??"",mode:e.mode,status:t[e.status??"open"]??"open",amount:e.amount_total??0,currency:e.currency??"usd",metadata:e.metadata??{}}}async retrieveSession(e){let t=await this.stripe.checkout.sessions.retrieve(e);return this.normalizeStripeSession(t)}async expireSession(e){let t=await this.stripe.checkout.sessions.expire(e);return this.normalizeStripeSession(t)}async listLineItems(e){return(await this.stripe.checkout.sessions.listLineItems(e)).data.map(i=>({price:i.price?.id,quantity:i.quantity??1}))}constructWebhookEvent(e,t,i){let o=this.stripe.webhooks.constructEvent(e,t,i);return{id:o.id,type:o.type,data:o.data,created:o.created}}async createCustomer(e){let t=await this.stripe.customers.create({email:e.email,name:e.name,metadata:e.metadata});return{id:t.id,email:t.email??e.email,firstName:e.name?.split(" ")[0],lastName:e.name?.split(" ").slice(1).join(" ")}}async retrieveCustomer(e){let t=await this.stripe.customers.retrieve(e);if(t.deleted)throw new s.FloPayError(`Customer ${e} has been deleted`,"api_error",{code:"resource_missing"});return{id:t.id,email:t.email??"",firstName:t.name?.split(" ")[0],lastName:t.name?.split(" ").slice(1).join(" ")}}async updateCustomer(e,t){let i=await this.stripe.customers.update(e,{email:t.email,name:t.name,metadata:t.metadata});return{id:i.id,email:i.email??"",firstName:i.name?.split(" ")[0],lastName:i.name?.split(" ").slice(1).join(" ")}}};0&&(module.exports={FloPay,STRIPE_API_VERSION});
1
+ "use strict";var $=Object.create;var m=Object.defineProperty;var z=Object.getOwnPropertyDescriptor;var H=Object.getOwnPropertyNames;var K=Object.getPrototypeOf,q=Object.prototype.hasOwnProperty;var W=(r,e)=>{for(var t in e)m(r,t,{get:e[t],enumerable:!0})},v=(r,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of H(e))!q.call(r,n)&&n!==t&&m(r,n,{get:()=>e[n],enumerable:!(i=z(e,n))||i.enumerable});return r};var Y=(r,e,t)=>(t=r!=null?$(K(r)):{},v(e||!r||!r.__esModule?m(t,"default",{value:r,enumerable:!0}):t,r)),G=r=>v(m({},"__esModule",{value:!0}),r);var Z={};W(Z,{FloPay:()=>l,STRIPE_API_VERSION:()=>g});module.exports=G(Z);var s=require("@flopay/shared"),_=Y(require("stripe"),1),g="2026-04-22.dahlia";function I(r){return typeof r=="string"&&r.trim()?r:void 0}function N(r){if(typeof r=="string")return r.trim()?r:void 0;if(!Array.isArray(r))return;let e=r.filter(t=>typeof t=="string"&&t.trim().length>0);return e.length?e.join("; "):void 0}function J(r,e){let t=e?.error,i=I(e?.code)??I(t?.code)??`http_${r}`,n=N(e?.message)??N(t?.message)??`Failed to create checkout session (HTTP ${r}).`;return new s.FloPayError(n,"api_error",{code:i,statusCode:r})}function X(r){for(let e of r){let t=e.charCodeAt(0);if(t<=8||t>=10&&t<=31||t===127)return!0}return!1}function Q(r){if(!r||r.trim()===""||r.length>s.MAX_IDEMPOTENCY_KEY_LENGTH||X(r))return!1;try{return new Headers({[s.IDEMPOTENCY_KEY_HEADER]:r}).get(s.IDEMPOTENCY_KEY_HEADER)===r}catch{return!1}}var l=class{constructor(e,t){if(!e)throw new s.FloPayError("A secret key is required to initialize the FloPay server SDK.","authentication_error");this.stripe=new _.default(t?.stripeSecretKey??e,{apiVersion:t?.apiVersion??g,appInfo:{name:"flopay-node",version:s.SDK_VERSION}}),this.checkout={sessions:{create:this.createSession.bind(this),retrieve:this.retrieveSession.bind(this),expire:this.expireSession.bind(this),listLineItems:this.listLineItems.bind(this)}},this.webhooks={constructEvent:this.constructWebhookEvent.bind(this)},this.customers={create:this.createCustomer.bind(this),retrieve:this.retrieveCustomer.bind(this),update:this.updateCustomer.bind(this)}}async createSession(e){let{billingApiUrl:t,checkoutBaseUrl:i,items:n=[],subscriptions:C=[],products:A,account:o,successUrl:M,cancelUrl:R,checkoutMode:T="confirm",captureMethod:p,couponCodes:U=[],checkoutMetadata:S,tagsData:k,redirectParams:x={},timeoutMs:O=12e3,clientId:V,currency:L,utmMetadata:P,idempotencyKey:b}=e,h=A??(0,s.foldIntoProducts)(n,C);(0,s.assertCaptureMethodEligible)({captureMethod:p,products:h});let f=(0,s.resolveSessionCurrency)(L,n,C,h);if(!f)throw new s.FloPayError("currency is required: pass `currency` on the session, or include a `currency` on the first item/subscription/product.","validation_error",{code:"CurrencyRequired",param:"currency"});let u={clientId:V,checkoutVersion:s.SDK_VERSION,successUrl:M,cancelUrl:R,currency:f,checkoutMode:T,products:h.map(a=>(0,s.buildProductPayload)(a,f)),accountData:{userId:o.userId,firstName:o.firstName??null,lastName:o.lastName??null,email:o.email,country:o.country??null,gender:o.gender??null,city:o.city??null,state:o.state??null,zip:o.zip??null},couponCodes:U};p==="manual"&&(u.captureMethod=p),S!==void 0&&(u.checkoutMetadata=S),k&&(u.tagsData=k),P?.length&&(u.utmMetadata=P);let D=`${t.replace(/\/+$/,"")}/v1/checkouts/sessions`,w=new AbortController,j=setTimeout(()=>w.abort(),O),c,d;try{let a=await fetch(D,{method:"POST",headers:{"Content-Type":"application/json",...Q(b)?{[s.IDEMPOTENCY_KEY_HEADER]:b}:{}},body:JSON.stringify(u),signal:w.signal});c=a.status;try{d=await a.json()}catch{}}finally{clearTimeout(j)}if(c>=400)throw J(c,d);if(c===201){let a=d?.data?.uuid,E=d?.data?.nonce;if(!a)throw new Error("Checkout session created but no UUID was returned by the billing API");if(!E)throw new s.FloPayError("Checkout session created but no `nonce` was returned by the billing API. Upgrade the billing service to TeamFloPay/backend#640 or later.","api_error",{code:"MissingCheckoutSessionToken"});let y=new URL(`${i.replace(/\/+$/,"")}/secure`);y.searchParams.set("id",a);for(let[F,B]of Object.entries(x))y.searchParams.set(F,B);return{status:201,redirectUrl:y.toString(),nonce:E}}return c===204?{status:204}:{status:c}}normalizeStripeSession(e){let t={open:"open",complete:"complete",expired:"expired"};return{id:e.id,clientSecret:e.client_secret??"",mode:e.mode,status:t[e.status??"open"]??"open",amount:e.amount_total??0,currency:e.currency??"usd",metadata:e.metadata??{}}}async retrieveSession(e){let t=await this.stripe.checkout.sessions.retrieve(e);return this.normalizeStripeSession(t)}async expireSession(e){let t=await this.stripe.checkout.sessions.expire(e);return this.normalizeStripeSession(t)}async listLineItems(e){return(await this.stripe.checkout.sessions.listLineItems(e)).data.map(i=>({price:i.price?.id,quantity:i.quantity??1}))}constructWebhookEvent(e,t,i){let n=this.stripe.webhooks.constructEvent(e,t,i);return{id:n.id,type:n.type,data:n.data,created:n.created}}async createCustomer(e){let t=await this.stripe.customers.create({email:e.email,name:e.name,metadata:e.metadata});return{id:t.id,email:t.email??e.email,firstName:e.name?.split(" ")[0],lastName:e.name?.split(" ").slice(1).join(" ")}}async retrieveCustomer(e){let t=await this.stripe.customers.retrieve(e);if(t.deleted)throw new s.FloPayError(`Customer ${e} has been deleted`,"api_error",{code:"resource_missing"});return{id:t.id,email:t.email??"",firstName:t.name?.split(" ")[0],lastName:t.name?.split(" ").slice(1).join(" ")}}async updateCustomer(e,t){let i=await this.stripe.customers.update(e,{email:t.email,name:t.name,metadata:t.metadata});return{id:i.id,email:i.email??"",firstName:i.name?.split(" ")[0],lastName:i.name?.split(" ").slice(1).join(" ")}}};0&&(module.exports={FloPay,STRIPE_API_VERSION});
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import{assertCaptureMethodEligible as D,buildProductPayload as j,FloPayError as u,foldIntoProducts as z,IDEMPOTENCY_KEY_HEADER as y,MAX_IDEMPOTENCY_KEY_LENGTH as F,resolveSessionCurrency as K,SDK_VERSION as v}from"@flopay/shared";import q from"stripe";var w="2026-04-22.dahlia";function H(s){for(let e of s){let t=e.charCodeAt(0);if(t<=8||t>=10&&t<=31||t===127)return!0}return!1}function W(s){if(!s||s.trim()===""||s.length>F||H(s))return!1;try{return new Headers({[y]:s}).get(y)===s}catch{return!1}}var C=class{constructor(e,t){if(!e)throw new u("A secret key is required to initialize the FloPay server SDK.","authentication_error");this.stripe=new q(t?.stripeSecretKey??e,{apiVersion:t?.apiVersion??w,appInfo:{name:"flopay-node",version:v}}),this.checkout={sessions:{create:this.createSession.bind(this),retrieve:this.retrieveSession.bind(this),expire:this.expireSession.bind(this),listLineItems:this.listLineItems.bind(this)}},this.webhooks={constructEvent:this.constructWebhookEvent.bind(this)},this.customers={create:this.createCustomer.bind(this),retrieve:this.retrieveCustomer.bind(this),update:this.updateCustomer.bind(this)}}async createSession(e){let{billingApiUrl:t,checkoutBaseUrl:r,items:o=[],subscriptions:g=[],products:I,account:i,successUrl:E,cancelUrl:N,checkoutMode:_="confirm",captureMethod:m,couponCodes:R=[],tagsData:f,redirectParams:U={},timeoutMs:x=12e3,clientId:M,currency:O,utmMetadata:S,idempotencyKey:P}=e,d=I??z(o,g);D({captureMethod:m,products:d});let l=K(O,o,g,d);if(!l)throw new u("currency is required: pass `currency` on the session, or include a `currency` on the first item/subscription/product.","validation_error",{code:"CurrencyRequired",param:"currency"});let a={clientId:M,checkoutVersion:v,successUrl:E,cancelUrl:N,currency:l,checkoutMode:_,products:d.map(n=>j(n,l)),accountData:{userId:i.userId,firstName:i.firstName??null,lastName:i.lastName??null,email:i.email,country:i.country??null,gender:i.gender??null,city:i.city??null,state:i.state??null,zip:i.zip??null},couponCodes:R};m==="manual"&&(a.captureMethod=m),f&&(a.tagsData=f),S?.length&&(a.utmMetadata=S);let T=`${t.replace(/\/+$/,"")}/v1/checkouts/sessions`,k=new AbortController,V=setTimeout(()=>k.abort(),x),c,p;try{let n=await fetch(T,{method:"POST",headers:{"Content-Type":"application/json",...W(P)?{[y]:P}:{}},body:JSON.stringify(a),signal:k.signal});c=n.status;try{p=await n.json()}catch{}}finally{clearTimeout(V)}if(c===201){let n=p?.data?.uuid,b=p?.data?.nonce;if(!n)throw new Error("Checkout session created but no UUID was returned by the billing API");if(!b)throw new u("Checkout session created but no `nonce` was returned by the billing API. Upgrade the billing service to TeamFloPay/backend#640 or later.","api_error",{code:"MissingCheckoutSessionToken"});let h=new URL(`${r.replace(/\/+$/,"")}/secure`);h.searchParams.set("id",n);for(let[A,L]of Object.entries(U))h.searchParams.set(A,L);return{status:201,redirectUrl:h.toString(),nonce:b}}return c===204?{status:204}:{status:c}}normalizeStripeSession(e){let t={open:"open",complete:"complete",expired:"expired"};return{id:e.id,clientSecret:e.client_secret??"",mode:e.mode,status:t[e.status??"open"]??"open",amount:e.amount_total??0,currency:e.currency??"usd",metadata:e.metadata??{}}}async retrieveSession(e){let t=await this.stripe.checkout.sessions.retrieve(e);return this.normalizeStripeSession(t)}async expireSession(e){let t=await this.stripe.checkout.sessions.expire(e);return this.normalizeStripeSession(t)}async listLineItems(e){return(await this.stripe.checkout.sessions.listLineItems(e)).data.map(r=>({price:r.price?.id,quantity:r.quantity??1}))}constructWebhookEvent(e,t,r){let o=this.stripe.webhooks.constructEvent(e,t,r);return{id:o.id,type:o.type,data:o.data,created:o.created}}async createCustomer(e){let t=await this.stripe.customers.create({email:e.email,name:e.name,metadata:e.metadata});return{id:t.id,email:t.email??e.email,firstName:e.name?.split(" ")[0],lastName:e.name?.split(" ").slice(1).join(" ")}}async retrieveCustomer(e){let t=await this.stripe.customers.retrieve(e);if(t.deleted)throw new u(`Customer ${e} has been deleted`,"api_error",{code:"resource_missing"});return{id:t.id,email:t.email??"",firstName:t.name?.split(" ")[0],lastName:t.name?.split(" ").slice(1).join(" ")}}async updateCustomer(e,t){let r=await this.stripe.customers.update(e,{email:t.email,name:t.name,metadata:t.metadata});return{id:r.id,email:r.email??"",firstName:r.name?.split(" ")[0],lastName:r.name?.split(" ").slice(1).join(" ")}}};export{C as FloPay,w as STRIPE_API_VERSION};
1
+ import{assertCaptureMethodEligible as B,buildProductPayload as $,FloPayError as u,foldIntoProducts as z,IDEMPOTENCY_KEY_HEADER as f,MAX_IDEMPOTENCY_KEY_LENGTH as H,resolveSessionCurrency as K,SDK_VERSION as E}from"@flopay/shared";import q from"stripe";var N="2026-04-22.dahlia";function v(r){return typeof r=="string"&&r.trim()?r:void 0}function I(r){if(typeof r=="string")return r.trim()?r:void 0;if(!Array.isArray(r))return;let e=r.filter(t=>typeof t=="string"&&t.trim().length>0);return e.length?e.join("; "):void 0}function W(r,e){let t=e?.error,s=v(e?.code)??v(t?.code)??`http_${r}`,i=I(e?.message)??I(t?.message)??`Failed to create checkout session (HTTP ${r}).`;return new u(i,"api_error",{code:s,statusCode:r})}function Y(r){for(let e of r){let t=e.charCodeAt(0);if(t<=8||t>=10&&t<=31||t===127)return!0}return!1}function G(r){if(!r||r.trim()===""||r.length>H||Y(r))return!1;try{return new Headers({[f]:r}).get(f)===r}catch{return!1}}var y=class{constructor(e,t){if(!e)throw new u("A secret key is required to initialize the FloPay server SDK.","authentication_error");this.stripe=new q(t?.stripeSecretKey??e,{apiVersion:t?.apiVersion??N,appInfo:{name:"flopay-node",version:E}}),this.checkout={sessions:{create:this.createSession.bind(this),retrieve:this.retrieveSession.bind(this),expire:this.expireSession.bind(this),listLineItems:this.listLineItems.bind(this)}},this.webhooks={constructEvent:this.constructWebhookEvent.bind(this)},this.customers={create:this.createCustomer.bind(this),retrieve:this.retrieveCustomer.bind(this),update:this.updateCustomer.bind(this)}}async createSession(e){let{billingApiUrl:t,checkoutBaseUrl:s,items:i=[],subscriptions:g=[],products:_,account:n,successUrl:A,cancelUrl:M,checkoutMode:R="confirm",captureMethod:m,couponCodes:T=[],checkoutMetadata:C,tagsData:S,redirectParams:U={},timeoutMs:x=12e3,clientId:O,currency:V,utmMetadata:k,idempotencyKey:P}=e,l=_??z(i,g);B({captureMethod:m,products:l});let p=K(V,i,g,l);if(!p)throw new u("currency is required: pass `currency` on the session, or include a `currency` on the first item/subscription/product.","validation_error",{code:"CurrencyRequired",param:"currency"});let c={clientId:O,checkoutVersion:E,successUrl:A,cancelUrl:M,currency:p,checkoutMode:R,products:l.map(o=>$(o,p)),accountData:{userId:n.userId,firstName:n.firstName??null,lastName:n.lastName??null,email:n.email,country:n.country??null,gender:n.gender??null,city:n.city??null,state:n.state??null,zip:n.zip??null},couponCodes:T};m==="manual"&&(c.captureMethod=m),C!==void 0&&(c.checkoutMetadata=C),S&&(c.tagsData=S),k?.length&&(c.utmMetadata=k);let L=`${t.replace(/\/+$/,"")}/v1/checkouts/sessions`,b=new AbortController,D=setTimeout(()=>b.abort(),x),a,d;try{let o=await fetch(L,{method:"POST",headers:{"Content-Type":"application/json",...G(P)?{[f]:P}:{}},body:JSON.stringify(c),signal:b.signal});a=o.status;try{d=await o.json()}catch{}}finally{clearTimeout(D)}if(a>=400)throw W(a,d);if(a===201){let o=d?.data?.uuid,w=d?.data?.nonce;if(!o)throw new Error("Checkout session created but no UUID was returned by the billing API");if(!w)throw new u("Checkout session created but no `nonce` was returned by the billing API. Upgrade the billing service to TeamFloPay/backend#640 or later.","api_error",{code:"MissingCheckoutSessionToken"});let h=new URL(`${s.replace(/\/+$/,"")}/secure`);h.searchParams.set("id",o);for(let[j,F]of Object.entries(U))h.searchParams.set(j,F);return{status:201,redirectUrl:h.toString(),nonce:w}}return a===204?{status:204}:{status:a}}normalizeStripeSession(e){let t={open:"open",complete:"complete",expired:"expired"};return{id:e.id,clientSecret:e.client_secret??"",mode:e.mode,status:t[e.status??"open"]??"open",amount:e.amount_total??0,currency:e.currency??"usd",metadata:e.metadata??{}}}async retrieveSession(e){let t=await this.stripe.checkout.sessions.retrieve(e);return this.normalizeStripeSession(t)}async expireSession(e){let t=await this.stripe.checkout.sessions.expire(e);return this.normalizeStripeSession(t)}async listLineItems(e){return(await this.stripe.checkout.sessions.listLineItems(e)).data.map(s=>({price:s.price?.id,quantity:s.quantity??1}))}constructWebhookEvent(e,t,s){let i=this.stripe.webhooks.constructEvent(e,t,s);return{id:i.id,type:i.type,data:i.data,created:i.created}}async createCustomer(e){let t=await this.stripe.customers.create({email:e.email,name:e.name,metadata:e.metadata});return{id:t.id,email:t.email??e.email,firstName:e.name?.split(" ")[0],lastName:e.name?.split(" ").slice(1).join(" ")}}async retrieveCustomer(e){let t=await this.stripe.customers.retrieve(e);if(t.deleted)throw new u(`Customer ${e} has been deleted`,"api_error",{code:"resource_missing"});return{id:t.id,email:t.email??"",firstName:t.name?.split(" ")[0],lastName:t.name?.split(" ").slice(1).join(" ")}}async updateCustomer(e,t){let s=await this.stripe.customers.update(e,{email:t.email,name:t.name,metadata:t.metadata});return{id:s.id,email:s.email??"",firstName:s.name?.split(" ")[0],lastName:s.name?.split(" ").slice(1).join(" ")}}};export{y as FloPay,N as STRIPE_API_VERSION};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flopay/node",
3
- "version": "1.8.7",
3
+ "version": "1.8.9",
4
4
  "type": "module",
5
5
  "sideEffects": false,
6
6
  "publishConfig": {
@@ -27,7 +27,7 @@
27
27
  ],
28
28
  "dependencies": {
29
29
  "stripe": "^22.2.1",
30
- "@flopay/shared": "1.8.7"
30
+ "@flopay/shared": "1.8.9"
31
31
  },
32
32
  "devDependencies": {
33
33
  "tsup": "^8.3.0",