@verapay/verapay-js 1.2.1 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -1,15 +1,24 @@
1
1
  import { Appearance, StripeElementLocale, StripeElementsOptions } from '@stripe/stripe-js';
2
2
 
3
- interface VerapayConfig {
4
- apiKey: string;
3
+ type VerapayConfig = FrontendConfig | BackendConfig;
4
+ interface BaseConfig {
5
5
  merchantId?: string;
6
- paymentData: PaymentData;
7
6
  appearance?: Appearance;
8
7
  locale?: StripeElementLocale;
9
8
  fonts?: StripeElementsOptions['fonts'];
10
9
  elementsConfig?: ElementsConfig;
11
10
  apiUrlOverride?: string;
12
11
  }
12
+ interface FrontendConfig extends BaseConfig {
13
+ apiKey: string;
14
+ paymentData: PaymentData;
15
+ clientSecret?: never;
16
+ }
17
+ interface BackendConfig extends BaseConfig {
18
+ clientSecret: string;
19
+ apiKey?: never;
20
+ paymentData?: never;
21
+ }
13
22
  interface PaymentData {
14
23
  amount: number;
15
24
  currency: string;
@@ -44,6 +53,13 @@ interface PaymentResult {
44
53
  status: 'succeeded' | 'processing' | 'failed';
45
54
  error?: string;
46
55
  }
56
+ interface SetupResult {
57
+ success: boolean;
58
+ savedPaymentMethodId?: string;
59
+ setupIntentId: string;
60
+ status: 'succeeded' | 'processing' | 'requires_action' | 'failed';
61
+ error?: string;
62
+ }
47
63
  interface CardValidation {
48
64
  number: {
49
65
  isValid: boolean;
@@ -77,7 +93,7 @@ interface ErrorDetails {
77
93
  formattedMessage: string;
78
94
  field?: string;
79
95
  stripeCode?: string;
80
- metadata?: Record<string, any>;
96
+ metadata?: Record<string, unknown>;
81
97
  }
82
98
 
83
99
  interface PaymentExtension {
@@ -105,12 +121,23 @@ declare class VerapayClient {
105
121
  private stripeAdapter;
106
122
  private elementsManager;
107
123
  private paymentService;
124
+ private setupService;
125
+ private initializationPromise;
108
126
  private isUsingStripePaymentElement;
109
127
  private isUsingIndividualFormElements;
110
- private clientSecret;
128
+ private intentKind;
129
+ private rawSecret;
111
130
  private paymentIntentId;
131
+ private amount;
132
+ private currency;
133
+ private merchantId;
112
134
  constructor(config: VerapayConfig);
113
135
  initialize(): Promise<void>;
136
+ confirmPayment(): Promise<PaymentResult>;
137
+ saveCard(): Promise<SetupResult>;
138
+ retrieveSetupIntent(): Promise<SetupResult>;
139
+ teardown(): void;
140
+ retrievePaymentIntent(): Promise<PaymentResult>;
114
141
  processPayment(request: ProcessPaymentRequest): Promise<PaymentResult>;
115
142
  mountPaymentForm(selector: string): Promise<void>;
116
143
  mountCardNumber(selector: string): Promise<void>;
@@ -119,6 +146,7 @@ declare class VerapayClient {
119
146
  mountAddress(selector: string, mode: 'billing' | 'shipping'): Promise<void>;
120
147
  addExtension(extension: PaymentExtension): void;
121
148
  private ensureInitialized;
149
+ private assertIntentKind;
122
150
  private validatePaymentInitialisation;
123
151
  private toMoney;
124
152
  private handlePaymentError;
@@ -140,14 +168,17 @@ interface ProcessPrePaymentRequest {
140
168
  paymentMethodId: string;
141
169
  amount: number;
142
170
  currency: string;
143
- customerData: Record<string, any>;
171
+ customerData: Record<string, unknown>;
144
172
  description?: string;
145
173
  metadata?: Record<string, string>;
146
174
  }
147
175
  declare class VerapayService {
148
176
  private readonly baseUrl;
149
- private readonly apiKey;
150
- constructor(baseUrl: string, apiKey: string);
177
+ private apiKey?;
178
+ constructor(baseUrl: string, apiKey?: string);
179
+ setApiKey(apiKey: string): void;
180
+ getPaymentIntentConfig(clientSecret: string): Promise<Record<string, unknown>>;
181
+ getSetupIntentConfig(clientSecret: string): Promise<Record<string, unknown>>;
151
182
  initialisePayment(request: InitialisePaymentRequest): Promise<InitialisePaymentResponse>;
152
183
  processPrePayment(request: ProcessPrePaymentRequest): Promise<void>;
153
184
  private extractErrorMessage;
@@ -167,18 +198,18 @@ declare class VerapayError extends Error {
167
198
  }
168
199
 
169
200
  declare class ValidationError extends VerapayError {
170
- constructor(message: string, field?: string, metadata?: Record<string, any>);
201
+ constructor(message: string, field?: string, metadata?: Record<string, unknown>);
171
202
  }
172
203
 
173
204
  declare class PaymentError extends VerapayError {
174
- constructor(message: string, stripeCode?: string, metadata?: Record<string, any>);
205
+ constructor(message: string, stripeCode?: string, metadata?: Record<string, unknown>);
175
206
  private static mapStripeCode;
176
207
  }
177
208
 
178
209
  declare class ErrorFormatter {
179
210
  static formatForUser(error: Error | ErrorDetails): string;
180
211
  static formatForDeveloper(error: Error | ErrorDetails): string;
181
- static toJSON(error: Error | ErrorDetails): Record<string, any>;
212
+ static toJSON(error: Error | ErrorDetails): Record<string, unknown>;
182
213
  }
183
214
 
184
215
  declare class CardValidator {
@@ -199,6 +230,6 @@ declare class InputSanitizer {
199
230
  } | null;
200
231
  }
201
232
 
202
- declare const VERSION = "1.1.0";
233
+ declare const VERSION = "1.4.0";
203
234
 
204
- export { type AnalyticsExtension, type CardValidation, CardValidator, type DatabaseExtension, type ElementsConfig, ErrorCode, type ErrorDetails, ErrorFormatter, type InitialisePaymentRequest, type InitialisePaymentResponse, InputSanitizer, PaymentError, type PaymentExtension, type PaymentResult, type ProcessPaymentRequest, type ProcessPrePaymentRequest, VERSION, ValidationError, VerapayClient, type VerapayConfig, VerapayError, VerapayService };
235
+ export { type AnalyticsExtension, type CardValidation, CardValidator, type DatabaseExtension, type ElementsConfig, ErrorCode, type ErrorDetails, ErrorFormatter, type InitialisePaymentRequest, type InitialisePaymentResponse, InputSanitizer, PaymentError, type PaymentExtension, type PaymentResult, type ProcessPaymentRequest, type ProcessPrePaymentRequest, type SetupResult, VERSION, ValidationError, VerapayClient, type VerapayConfig, VerapayError, VerapayService };
package/dist/index.d.ts CHANGED
@@ -1,15 +1,24 @@
1
1
  import { Appearance, StripeElementLocale, StripeElementsOptions } from '@stripe/stripe-js';
2
2
 
3
- interface VerapayConfig {
4
- apiKey: string;
3
+ type VerapayConfig = FrontendConfig | BackendConfig;
4
+ interface BaseConfig {
5
5
  merchantId?: string;
6
- paymentData: PaymentData;
7
6
  appearance?: Appearance;
8
7
  locale?: StripeElementLocale;
9
8
  fonts?: StripeElementsOptions['fonts'];
10
9
  elementsConfig?: ElementsConfig;
11
10
  apiUrlOverride?: string;
12
11
  }
12
+ interface FrontendConfig extends BaseConfig {
13
+ apiKey: string;
14
+ paymentData: PaymentData;
15
+ clientSecret?: never;
16
+ }
17
+ interface BackendConfig extends BaseConfig {
18
+ clientSecret: string;
19
+ apiKey?: never;
20
+ paymentData?: never;
21
+ }
13
22
  interface PaymentData {
14
23
  amount: number;
15
24
  currency: string;
@@ -44,6 +53,13 @@ interface PaymentResult {
44
53
  status: 'succeeded' | 'processing' | 'failed';
45
54
  error?: string;
46
55
  }
56
+ interface SetupResult {
57
+ success: boolean;
58
+ savedPaymentMethodId?: string;
59
+ setupIntentId: string;
60
+ status: 'succeeded' | 'processing' | 'requires_action' | 'failed';
61
+ error?: string;
62
+ }
47
63
  interface CardValidation {
48
64
  number: {
49
65
  isValid: boolean;
@@ -77,7 +93,7 @@ interface ErrorDetails {
77
93
  formattedMessage: string;
78
94
  field?: string;
79
95
  stripeCode?: string;
80
- metadata?: Record<string, any>;
96
+ metadata?: Record<string, unknown>;
81
97
  }
82
98
 
83
99
  interface PaymentExtension {
@@ -105,12 +121,23 @@ declare class VerapayClient {
105
121
  private stripeAdapter;
106
122
  private elementsManager;
107
123
  private paymentService;
124
+ private setupService;
125
+ private initializationPromise;
108
126
  private isUsingStripePaymentElement;
109
127
  private isUsingIndividualFormElements;
110
- private clientSecret;
128
+ private intentKind;
129
+ private rawSecret;
111
130
  private paymentIntentId;
131
+ private amount;
132
+ private currency;
133
+ private merchantId;
112
134
  constructor(config: VerapayConfig);
113
135
  initialize(): Promise<void>;
136
+ confirmPayment(): Promise<PaymentResult>;
137
+ saveCard(): Promise<SetupResult>;
138
+ retrieveSetupIntent(): Promise<SetupResult>;
139
+ teardown(): void;
140
+ retrievePaymentIntent(): Promise<PaymentResult>;
114
141
  processPayment(request: ProcessPaymentRequest): Promise<PaymentResult>;
115
142
  mountPaymentForm(selector: string): Promise<void>;
116
143
  mountCardNumber(selector: string): Promise<void>;
@@ -119,6 +146,7 @@ declare class VerapayClient {
119
146
  mountAddress(selector: string, mode: 'billing' | 'shipping'): Promise<void>;
120
147
  addExtension(extension: PaymentExtension): void;
121
148
  private ensureInitialized;
149
+ private assertIntentKind;
122
150
  private validatePaymentInitialisation;
123
151
  private toMoney;
124
152
  private handlePaymentError;
@@ -140,14 +168,17 @@ interface ProcessPrePaymentRequest {
140
168
  paymentMethodId: string;
141
169
  amount: number;
142
170
  currency: string;
143
- customerData: Record<string, any>;
171
+ customerData: Record<string, unknown>;
144
172
  description?: string;
145
173
  metadata?: Record<string, string>;
146
174
  }
147
175
  declare class VerapayService {
148
176
  private readonly baseUrl;
149
- private readonly apiKey;
150
- constructor(baseUrl: string, apiKey: string);
177
+ private apiKey?;
178
+ constructor(baseUrl: string, apiKey?: string);
179
+ setApiKey(apiKey: string): void;
180
+ getPaymentIntentConfig(clientSecret: string): Promise<Record<string, unknown>>;
181
+ getSetupIntentConfig(clientSecret: string): Promise<Record<string, unknown>>;
151
182
  initialisePayment(request: InitialisePaymentRequest): Promise<InitialisePaymentResponse>;
152
183
  processPrePayment(request: ProcessPrePaymentRequest): Promise<void>;
153
184
  private extractErrorMessage;
@@ -167,18 +198,18 @@ declare class VerapayError extends Error {
167
198
  }
168
199
 
169
200
  declare class ValidationError extends VerapayError {
170
- constructor(message: string, field?: string, metadata?: Record<string, any>);
201
+ constructor(message: string, field?: string, metadata?: Record<string, unknown>);
171
202
  }
172
203
 
173
204
  declare class PaymentError extends VerapayError {
174
- constructor(message: string, stripeCode?: string, metadata?: Record<string, any>);
205
+ constructor(message: string, stripeCode?: string, metadata?: Record<string, unknown>);
175
206
  private static mapStripeCode;
176
207
  }
177
208
 
178
209
  declare class ErrorFormatter {
179
210
  static formatForUser(error: Error | ErrorDetails): string;
180
211
  static formatForDeveloper(error: Error | ErrorDetails): string;
181
- static toJSON(error: Error | ErrorDetails): Record<string, any>;
212
+ static toJSON(error: Error | ErrorDetails): Record<string, unknown>;
182
213
  }
183
214
 
184
215
  declare class CardValidator {
@@ -199,6 +230,6 @@ declare class InputSanitizer {
199
230
  } | null;
200
231
  }
201
232
 
202
- declare const VERSION = "1.1.0";
233
+ declare const VERSION = "1.4.0";
203
234
 
204
- export { type AnalyticsExtension, type CardValidation, CardValidator, type DatabaseExtension, type ElementsConfig, ErrorCode, type ErrorDetails, ErrorFormatter, type InitialisePaymentRequest, type InitialisePaymentResponse, InputSanitizer, PaymentError, type PaymentExtension, type PaymentResult, type ProcessPaymentRequest, type ProcessPrePaymentRequest, VERSION, ValidationError, VerapayClient, type VerapayConfig, VerapayError, VerapayService };
235
+ export { type AnalyticsExtension, type CardValidation, CardValidator, type DatabaseExtension, type ElementsConfig, ErrorCode, type ErrorDetails, ErrorFormatter, type InitialisePaymentRequest, type InitialisePaymentResponse, InputSanitizer, PaymentError, type PaymentExtension, type PaymentResult, type ProcessPaymentRequest, type ProcessPrePaymentRequest, type SetupResult, VERSION, ValidationError, VerapayClient, type VerapayConfig, VerapayError, VerapayService };
package/dist/index.js CHANGED
@@ -1,3 +1,3 @@
1
- import {loadStripe}from'@stripe/stripe-js';import {Money}from'ts-money';var i=class o extends Error{constructor(e,t="PAYMENT_FAILED",r){super(e),this.name="VerapayError",this.code=t,this.details={code:t,message:e,formattedMessage:this.formatMessage(e,t),...r},Error.captureStackTrace&&Error.captureStackTrace(this,o);}formatMessage(e,t){return {VALIDATION_ERROR:"Please check your payment information and try again.",PAYMENT_FAILED:"Your payment could not be processed. Please try again.",AUTHENTICATION_FAILED:"Payment authentication failed. Please try again.",NETWORK_ERROR:"Network error. Please check your connection and try again.",STRIPE_ERROR:"Payment service error. Please try again later.",CONFIGURATION_ERROR:"Configuration error. Please contact support.",CARD_DECLINED:"Your card was declined. Please use a different payment method.",INSUFFICIENT_FUNDS:"Insufficient funds. Please use a different payment method.",EXPIRED_CARD:"Your card has expired. Please use a different payment method."}[t]||e}toJSON(){return {name:this.name,code:this.code,message:this.message,details:this.details}}};var m=class extends i{constructor(e,t,r){super(e,"VALIDATION_ERROR",{field:t,metadata:r}),this.name="ValidationError";}};var c=class o extends i{constructor(e,t,r){let n=o.mapStripeCode(t);super(e,n,{stripeCode:t,metadata:r}),this.name="PaymentError";}static mapStripeCode(e){return e?{card_declined:"CARD_DECLINED",insufficient_funds:"INSUFFICIENT_FUNDS",expired_card:"EXPIRED_CARD",incorrect_cvc:"VALIDATION_ERROR",processing_error:"PAYMENT_FAILED",authentication_failed:"AUTHENTICATION_FAILED"}[e]||"PAYMENT_FAILED":"PAYMENT_FAILED"}};var y=class{static formatForUser(e){return "formattedMessage"in e?e.formattedMessage:"details"in e&&e.details&&typeof e.details=="object"&&"formattedMessage"in e.details&&typeof e.details.formattedMessage=="string"?e.details.formattedMessage:"An unexpected error occurred. Please try again."}static formatForDeveloper(e){return "code"in e&&"message"in e?`[${e.code}] ${e.message}`:e.message||"Unknown error"}static toJSON(e){return "toJSON"in e&&typeof e.toJSON=="function"?e.toJSON():{name:e.name||"Error",message:e.message,..."code"in e&&{code:e.code},..."details"in e&&{details:e.details}}}};var u=class{constructor(e){this.stripe=e;}async confirmPayment(e,t){let r=await this.stripe.confirmPayment({clientSecret:t,confirmParams:{payment_method:e,return_url:window.location.href},redirect:"if_required"});if(r.error)throw new c(r.error.message||"Payment failed",r.error.code);return r}async confirmCardPayment(e,t){let r=await this.stripe.confirmCardPayment(t,{payment_method:e});if(r.error)throw new c(r.error.message||"Payment failed",r.error.code);return r}async createPaymentMethod(e,t=false){let r;if(!t)r=await this.stripe.createPaymentMethod({elements:e});else {let a=(await e.getElement("address",{mode:"billing"}).getValue()).value;r=await this.stripe.createPaymentMethod({type:"card",card:e.getElement("cardNumber"),billing_details:{name:a.name,address:{...a.address,line2:a.address.line2??void 0}}});}if(r.error||!r.paymentMethod)throw new c(r.error?.message||"Failed to create payment method",r.error?.code);return r.paymentMethod.id}};var p={showIcon:true,iconStyle:"solid",placeholders:{cardNumber:"1234 1234 1234 1234",cardExpiry:"MM / YY - TESTING",cardCvc:"CVC"},style:{base:{color:"#333333",fontFamily:"system-ui, -apple-system, sans-serif",fontSize:"16px","::placeholder":{color:"#aab7c4"}},complete:{color:"#333333"},empty:{},invalid:{color:"#df1b41"}}},v={cardNumber:"Card number",cardExpiry:"Expiry date",cardCvc:"CVC",address:"Address"},g=class{constructor(e,t,r){this.stripe=e;this.config=t;this.clientSecret=r;this.elements=null;this.mountedElements=new Map;this.elementStates=new Map;if(!r)throw new i("Client secret not initialized","CONFIGURATION_ERROR")}mountPaymentElement(e){if(!this.elements){let n={clientSecret:this.clientSecret,appearance:this.config.appearance,locale:this.config.locale,fonts:this.config.fonts,paymentMethodCreation:"manual"};this.elements=this.stripe.elements(n);}if(!document.querySelector(e))throw new i(`Element not found: ${e}`,"CONFIGURATION_ERROR");let r=this.elements.create("payment",{layout:"tabs",wallets:{link:"never"}});r.mount(e),this.mountedElements.set("payment",r);}mountCardNumberElement(e){this.mountIndividualFormElement(e,"cardNumber",this.cardElementOptions("cardNumber"));}mountCardExpiryElement(e){this.mountIndividualFormElement(e,"cardExpiry",this.cardElementOptions("cardExpiry"));}mountCardCvcElement(e){this.mountIndividualFormElement(e,"cardCvc",this.cardElementOptions("cardCvc"));}mountAddressElement(e,t){this.mountIndividualFormElement(e,"address",{mode:t});}cardElementOptions(e){let{elementsConfig:t}=this.config,r={placeholder:t?.placeholders?.[e]??p.placeholders[e],style:{base:{...p.style.base,...t?.style?.base},complete:{...p.style.complete,...t?.style?.complete},empty:{...p.style.empty,...t?.style?.empty},invalid:{...p.style.invalid,...t?.style?.invalid}}};return e==="cardNumber"&&(r.showIcon=t?.showIcon??p.showIcon,r.iconStyle=t?.iconStyle??p.iconStyle),r}mountIndividualFormElement(e,t,r){if(!document.querySelector(e))throw new i(`Element not found: ${e}`,"CONFIGURATION_ERROR");let a=this.createIndividualFormElement(t,r);a.mount(e),this.mountedElements.set(t,a),this.trackElementState(t,a);}createIndividualFormElement(e,t){return this.elements||(this.elements=this.stripe.elements({appearance:this.config.appearance,locale:this.config.locale,fonts:this.config.fonts,paymentMethodCreation:"manual"})),this.elements.create(e,t)}async validate(){let e=[];for(let[t,r]of this.elementStates.entries())r.complete||e.push({field:t,message:r.error??`${v[t]??t} failed validation`});return {isValid:e.length===0,errors:e}}getElements(){return this.elements}unmountAll(){for(let e of this.mountedElements.values())e.unmount();this.mountedElements.clear(),this.elementStates.clear();}trackElementState(e,t){this.elementStates.set(e,{complete:false});let r=n=>{this.elementStates.set(e,{complete:n.complete,error:n.error?.message});};t.on("change",r);}};var f=class{constructor(){this.extensions=[];}add(e){this.extensions.push(e);}async runBeforePayment(e){let t=e;for(let r of this.extensions)r.beforePayment&&(t=await r.beforePayment(t));return t}async runAfterPayment(e){await Promise.all(this.extensions.filter(t=>t.afterPayment).map(t=>t.afterPayment(e)));}async runOnError(e){await Promise.all(this.extensions.filter(t=>t.onPaymentError).map(t=>t.onPaymentError(e)));}};var h=class{constructor(e,t,r){this.stripeAdapter=e;this.elementsManager=t;this.verapayService=r;}async process(e,t){let r=this.elementsManager.getElements();await this.validatePaymentCanProceed(r,t),await r.submit();let n=await this.stripeAdapter.createPaymentMethod(r,t.isUsingIndividualFormElements);return await this.verapayService.processPrePayment({merchantId:t.merchantId,paymentIntentId:t.paymentIntentId,paymentMethodId:n,amount:t.amount,currency:t.currency,customerData:{email:e.customerEmail,firstName:e.customerFirstName,lastName:e.customerLastName},description:e.description,metadata:e.metadata}),this.confirmPayment(n,t)}async validatePaymentCanProceed(e,t){if(!e)throw new i("Payment form not mounted","CONFIGURATION_ERROR");if(t.isUsingStripePaymentElement&&t.isUsingIndividualFormElements)throw new i("Both forms of payment form in use");if(t.isUsingIndividualFormElements){let r=await this.elementsManager.validate();if(!r.isValid)throw new i(r.errors[0].message,"VALIDATION_ERROR")}}async confirmPayment(e,t){let{clientSecret:r,isUsingStripePaymentElement:n,isUsingIndividualFormElements:a}=t,s;return n?s=await this.stripeAdapter.confirmPayment(e,r):a&&(s=await this.stripeAdapter.confirmCardPayment(e,r)),this.formatPaymentResult(s)}formatPaymentResult(e){return {success:e.paymentIntent.status==="succeeded",paymentIntentId:e.paymentIntent.id,status:e.paymentIntent.status}}};var d=class{constructor(e,t){this.baseUrl=e,this.apiKey=t;}async initialisePayment(e){let{merchantId:t,paymentData:r}=e;try{let n=await fetch(`${this.baseUrl}/api/initialise-payment`,{method:"POST",headers:{"Content-Type":"application/json","x-api-key":this.apiKey},body:JSON.stringify({merchantId:t,paymentData:{...r,paymentMethodType:"card"}})});if(!n.ok){let s=await n.json().catch(()=>({}));throw new i(this.extractErrorMessage(s,n.status),"CONFIGURATION_ERROR")}let a=await n.json();if(!a.clientSecret||!a.paymentIntentId)throw new i("Missing clientSecret or paymentIntentId in server response","CONFIGURATION_ERROR");return {paymentIntentId:a.paymentIntentId,clientSecret:a.clientSecret,connectAccountId:a.connectAccountId,stripePublishableKey:a.stripePublishableKey}}catch(n){throw n instanceof i?n:new i(n instanceof Error?n.message:"Unknown error occurred","CONFIGURATION_ERROR")}}async processPrePayment(e){try{let t=await fetch(`${this.baseUrl}/api/process-prepayment`,{method:"POST",headers:{"Content-Type":"application/json","x-api-key":this.apiKey},body:JSON.stringify({merchantId:e.merchantId,paymentIntentId:e.paymentIntentId,paymentMethodId:e.paymentMethodId,amount:e.amount,currency:e.currency,customerData:e.customerData,description:e.description,metadata:e.metadata})});if(!t.ok){let r=await t.json().catch(()=>({}));throw new i(this.extractErrorMessage(r,t.status),"CONFIGURATION_ERROR")}}catch(t){throw t instanceof i?t:new i(t instanceof Error?t.message:"Unknown error occurred","CONFIGURATION_ERROR")}}extractErrorMessage(e,t){if(!e||typeof e!="object")return `HTTP error! status: ${t}`;let r=e,n=[r.error,r.message,r.details];for(let a of n){if(typeof a=="string"&&a.trim().length>0)return a;if(a&&typeof a=="object")try{return JSON.stringify(a)}catch{}}return `HTTP error! status: ${t}`}};var E=class E{constructor(e){this.stripeAdapter=null;this.elementsManager=null;this.paymentService=null;this.isUsingStripePaymentElement=false;this.isUsingIndividualFormElements=false;this.clientSecret=null;this.paymentIntentId=null;if(!e.apiKey)throw new i("apiKey is required. Pass your Verapay publishable key (vpy_pk_test_... or vpy_pk_live_...) when constructing VerapayClient.","CONFIGURATION_ERROR");this.config=e,!this.config.apiKey.includes("_pk_")&&typeof window<"u"&&console.warn("Verapay Security Warning: You are using a Secret Key in a frontend environment. Please use a Publishable Key (vpy_pk_...) instead.");let t=this.config.apiUrlOverride||E.BACKEND_URL;this.verapayService=new d(t,this.config.apiKey),this.extensionsManager=new f;}async initialize(){this.validatePaymentInitialisation();let{clientSecret:e,paymentIntentId:t,stripePublishableKey:r}=await this.verapayService.initialisePayment({merchantId:this.config.merchantId??"",paymentData:this.config.paymentData});this.clientSecret=e,this.paymentIntentId=t;let n=await loadStripe(r);if(!n)throw new i("Failed to load Stripe","CONFIGURATION_ERROR");this.stripeAdapter=new u(n),this.elementsManager=new g(n,this.config,e),this.paymentService=new h(this.stripeAdapter,this.elementsManager,this.verapayService);}async processPayment(e){await this.ensureInitialized();let t=await this.extensionsManager.runBeforePayment(e);try{let r=await this.paymentService.process(t,{merchantId:this.config.merchantId??"",paymentIntentId:this.paymentIntentId,clientSecret:this.clientSecret,amount:this.config.paymentData.amount,currency:this.config.paymentData.currency,isUsingStripePaymentElement:this.isUsingStripePaymentElement,isUsingIndividualFormElements:this.isUsingIndividualFormElements});return await this.extensionsManager.runAfterPayment(r),r}catch(r){throw await this.extensionsManager.runOnError(r),this.handlePaymentError(r)}}async mountPaymentForm(e){await this.ensureInitialized(),this.elementsManager.mountPaymentElement(e),this.isUsingStripePaymentElement=true;}async mountCardNumber(e){await this.ensureInitialized(),this.elementsManager.mountCardNumberElement(e),this.isUsingIndividualFormElements=true;}async mountCardExpiry(e){await this.ensureInitialized(),this.elementsManager.mountCardExpiryElement(e),this.isUsingIndividualFormElements=true;}async mountCardCvc(e){await this.ensureInitialized(),this.elementsManager.mountCardCvcElement(e),this.isUsingIndividualFormElements=true;}async mountAddress(e,t){await this.ensureInitialized(),this.elementsManager.mountAddressElement(e,t),this.isUsingIndividualFormElements=true;}addExtension(e){this.extensionsManager.add(e);}async ensureInitialized(){this.stripeAdapter||await this.initialize();}validatePaymentInitialisation(){let{amount:e,currency:t,partnerFee:r}=this.config.paymentData;if(!t)throw new m("Currency is required","currency");let n=t.toUpperCase(),a=this.toMoney(e,n,"amount");if(a.isZero()||a.isNegative())throw new m("Amount must be greater than 0","amount");if(r!==void 0){let s=this.toMoney(r,n,"partnerFee");if(s.isNegative())throw new m("partnerFee cannot be negative","partnerFee");if(s.greaterThan(a))throw new m("partnerFee cannot exceed the payment amount","partnerFee")}}toMoney(e,t,r){try{return Money.fromInteger(e,t)}catch{throw new m(`${r} must be an integer in the smallest currency unit (e.g., cents for USD)`,r)}}handlePaymentError(e){return e instanceof i?e:new c(e.message||"Payment failed",e.code)}};E.BACKEND_URL="https://api.verapay.app";var R=E;var I=class{validateCardNumber(e){let t=e.replace(/\D/g,"");if(t.length<13||t.length>19)return false;let r=0,n=false;for(let a=t.length-1;a>=0;a--){let s=parseInt(t[a],10);n&&(s*=2,s>9&&(s-=9)),r+=s,n=!n;}return r%10===0}detectCardType(e){let t=e.replace(/\D/g,"");return /^4/.test(t)?"visa":/^5[1-5]/.test(t)?"mastercard":/^3[47]/.test(t)?"amex":/^6(?:011|5)/.test(t)?"discover":"unknown"}validateExpiry(e,t){let r=new Date,n=r.getFullYear(),a=r.getMonth()+1;if(e<1||e>12)return false;let s=t<100?2e3+t:t;return !(s<n||s===n&&e<a)}validateCVC(e,t="unknown"){let r=e.replace(/\D/g,"");return t==="amex"?r.length===4:r.length===3||r.length===4}validateAll(e,t,r,n){let a=this.detectCardType(e);return {number:{isValid:this.validateCardNumber(e),cardType:a},expiry:{isValid:this.validateExpiry(t,r),month:t,year:r},cvc:{isValid:this.validateCVC(n,a),length:n.replace(/\D/g,"").length}}}};var P=class{static sanitizeCardNumber(e){return e.replace(/\D/g,"")}static formatCardNumber(e){return this.sanitizeCardNumber(e).replace(/(\d{4})/g,"$1 ").trim()}static sanitizeCVC(e){return e.replace(/\D/g,"").slice(0,4)}static sanitizeExpiry(e){let t=e.replace(/\D/g,"");return t.length===4?{month:parseInt(t.slice(0,2),10),year:parseInt(t.slice(2,4),10)}:t.length===6?{month:parseInt(t.slice(0,2),10),year:parseInt(t.slice(2,6),10)}:null}};var ue="1.1.0";
2
- export{I as CardValidator,y as ErrorFormatter,P as InputSanitizer,c as PaymentError,ue as VERSION,m as ValidationError,R as VerapayClient,i as VerapayError,d as VerapayService};//# sourceMappingURL=index.js.map
1
+ import {loadStripe}from'@stripe/stripe-js';import {Money}from'ts-money';var a=class s extends Error{constructor(e,t="PAYMENT_FAILED",n){super(e),this.name="VerapayError",this.code=t,this.details={code:t,message:e,formattedMessage:this.formatMessage(e,t),...n},Error.captureStackTrace&&Error.captureStackTrace(this,s);}formatMessage(e,t){return {VALIDATION_ERROR:"Please check your payment information and try again.",PAYMENT_FAILED:"Your payment could not be processed. Please try again.",AUTHENTICATION_FAILED:"Payment authentication failed. Please try again.",NETWORK_ERROR:"Network error. Please check your connection and try again.",STRIPE_ERROR:"Payment service error. Please try again later.",CONFIGURATION_ERROR:"Configuration error. Please contact support.",CARD_DECLINED:"Your card was declined. Please use a different payment method.",INSUFFICIENT_FUNDS:"Insufficient funds. Please use a different payment method.",EXPIRED_CARD:"Your card has expired. Please use a different payment method."}[t]||e}toJSON(){return {name:this.name,code:this.code,message:this.message,details:this.details}}};var l=class extends a{constructor(e,t,n){super(e,"VALIDATION_ERROR",{field:t,metadata:n}),this.name="ValidationError";}};var o=class s extends a{constructor(e,t,n){let i=s.mapStripeCode(t);super(e,i,{stripeCode:t,metadata:n}),this.name="PaymentError";}static mapStripeCode(e){return e?{card_declined:"CARD_DECLINED",insufficient_funds:"INSUFFICIENT_FUNDS",expired_card:"EXPIRED_CARD",incorrect_cvc:"VALIDATION_ERROR",processing_error:"PAYMENT_FAILED",authentication_failed:"AUTHENTICATION_FAILED"}[e]||"PAYMENT_FAILED":"PAYMENT_FAILED"}};var u=class{static formatForUser(e){return "formattedMessage"in e?e.formattedMessage:"details"in e&&e.details&&typeof e.details=="object"&&"formattedMessage"in e.details&&typeof e.details.formattedMessage=="string"?e.details.formattedMessage:"An unexpected error occurred. Please try again."}static formatForDeveloper(e){return "code"in e&&"message"in e?`[${e.code}] ${e.message}`:e.message||"Unknown error"}static toJSON(e){return "toJSON"in e&&typeof e.toJSON=="function"?e.toJSON():{name:e.name||"Error",message:e.message,..."code"in e&&{code:e.code},..."details"in e&&{details:e.details}}}};var y=class{constructor(e){this.stripe=e;}async confirmPayment(e,t){let n=await this.stripe.confirmPayment({clientSecret:t,confirmParams:{payment_method:e,return_url:window.location.href},redirect:"if_required"});if(n.error)throw new o(n.error.message||"Payment failed",n.error.code);return n}async confirmCardPayment(e,t){let n=await this.stripe.confirmCardPayment(t,{payment_method:e});if(n.error)throw new o(n.error.message||"Payment failed",n.error.code);return n}async createPaymentMethod(e,t=false){let n;if(!t)n=await this.stripe.createPaymentMethod({elements:e});else {let r=(await e.getElement("address",{mode:"billing"}).getValue()).value;n=await this.stripe.createPaymentMethod({type:"card",card:e.getElement("cardNumber"),billing_details:{name:r.name,address:{...r.address,line2:r.address.line2??void 0}}});}if(n.error||!n.paymentMethod)throw new o(n.error?.message||"Failed to create payment method",n.error?.code);return n.paymentMethod.id}async retrievePaymentIntent(e){let t=await this.stripe.retrievePaymentIntent(e);if(t.error)throw new o(t.error.message||"Failed to retrieve payment intent",t.error.code);return t}async confirmCardSetup(e,t){let n=await this.stripe.confirmCardSetup(t,{payment_method:e});if(n.error)throw new o(n.error.message||"Card setup failed",n.error.code);return n}async retrieveSetupIntent(e){let t=await this.stripe.retrieveSetupIntent(e);if(t.error)throw new o(t.error.message||"Failed to retrieve setup intent",t.error.code);return t}};var p={showIcon:true,iconStyle:"solid",placeholders:{cardNumber:"1234 1234 1234 1234",cardExpiry:"MM / YY - TESTING",cardCvc:"CVC"},style:{base:{color:"#333333",fontFamily:"system-ui, -apple-system, sans-serif",fontSize:"16px","::placeholder":{color:"#aab7c4"}},complete:{color:"#333333"},empty:{},invalid:{color:"#df1b41"}}},S={cardNumber:"Card number",cardExpiry:"Expiry date",cardCvc:"CVC",address:"Address"},h=class{constructor(e,t,n){this.stripe=e;this.config=t;this.clientSecret=n;this.elements=null;this.mountedElements=new Map;this.elementStates=new Map;if(!n)throw new a("Client secret not initialized","CONFIGURATION_ERROR")}mountPaymentElement(e){if(!this.elements){let i={clientSecret:this.clientSecret,appearance:this.config.appearance,locale:this.config.locale,fonts:this.config.fonts,paymentMethodCreation:"manual"};this.elements=this.stripe.elements(i);}if(!document.querySelector(e))throw new a(`Element not found: ${e}`,"CONFIGURATION_ERROR");let n=this.elements.create("payment",{layout:"tabs",wallets:{link:"never"}});n.mount(e),this.mountedElements.set("payment",n);}mountCardNumberElement(e){this.mountIndividualFormElement(e,"cardNumber",this.cardElementOptions("cardNumber"));}mountCardExpiryElement(e){this.mountIndividualFormElement(e,"cardExpiry",this.cardElementOptions("cardExpiry"));}mountCardCvcElement(e){this.mountIndividualFormElement(e,"cardCvc",this.cardElementOptions("cardCvc"));}mountAddressElement(e,t){this.mountIndividualFormElement(e,"address",{mode:t});}cardElementOptions(e){let{elementsConfig:t}=this.config,n={placeholder:t?.placeholders?.[e]??p.placeholders[e],style:{base:{...p.style.base,...t?.style?.base},complete:{...p.style.complete,...t?.style?.complete},empty:{...p.style.empty,...t?.style?.empty},invalid:{...p.style.invalid,...t?.style?.invalid}}};return e==="cardNumber"&&(n.showIcon=t?.showIcon??p.showIcon,n.iconStyle=t?.iconStyle??p.iconStyle),n}mountIndividualFormElement(e,t,n){if(!document.querySelector(e))throw new a(`Element not found: ${e}`,"CONFIGURATION_ERROR");let r=this.createIndividualFormElement(t,n);r.mount(e),this.mountedElements.set(t,r),this.trackElementState(t,r);}createIndividualFormElement(e,t){return this.elements||(this.elements=this.stripe.elements({appearance:this.config.appearance,locale:this.config.locale,fonts:this.config.fonts,paymentMethodCreation:"manual"})),this.elements.create(e,t)}async validate(){let e=[];for(let[t,n]of this.elementStates.entries())n.complete||e.push({field:t,message:n.error??`${S[t]??t} failed validation`});return {isValid:e.length===0,errors:e}}getElements(){return this.elements}unmountAll(){for(let e of this.mountedElements.values())e.unmount();this.mountedElements.clear(),this.elementStates.clear();}trackElementState(e,t){this.elementStates.set(e,{complete:false});let n=i=>{this.elementStates.set(e,{complete:i.complete,error:i.error?.message});};t.on("change",n);}};var g=class{constructor(){this.extensions=[];}add(e){this.extensions.push(e);}async runBeforePayment(e){let t=e;for(let n of this.extensions)n.beforePayment&&(t=await n.beforePayment(t));return t}async runAfterPayment(e){await Promise.all(this.extensions.filter(t=>t.afterPayment).map(t=>t.afterPayment(e)));}async runOnError(e){await Promise.all(this.extensions.filter(t=>t.onPaymentError).map(t=>t.onPaymentError(e)));}};var f=class{constructor(e,t,n){this.stripeAdapter=e;this.elementsManager=t;this.verapayService=n;}async process(e,t){let n=this.elementsManager.getElements();await this.validatePaymentCanProceed(n,t),await n.submit();let i=await this.stripeAdapter.createPaymentMethod(n,t.isUsingIndividualFormElements);return await this.verapayService.processPrePayment({merchantId:t.merchantId,paymentIntentId:t.paymentIntentId,paymentMethodId:i,amount:t.amount,currency:t.currency,customerData:{email:e.customerEmail,firstName:e.customerFirstName,lastName:e.customerLastName},description:e.description,metadata:e.metadata}),this.confirm(t.clientSecret,{paymentMethodId:i,isUsingStripePaymentElement:t.isUsingStripePaymentElement,isUsingIndividualFormElements:t.isUsingIndividualFormElements})}async validatePaymentCanProceed(e,t){if(!e)throw new a("Payment form not mounted","CONFIGURATION_ERROR");if(t.isUsingStripePaymentElement&&t.isUsingIndividualFormElements)throw new a("Both forms of payment form in use");if(t.isUsingIndividualFormElements){let n=await this.elementsManager.validate();if(!n.isValid)throw new a(n.errors[0].message,"VALIDATION_ERROR")}}async confirm(e,t={}){let n;return t.isUsingStripePaymentElement?n=await this.stripeAdapter.confirmPayment(t.paymentMethodId||"",e):t.isUsingIndividualFormElements?n=await this.stripeAdapter.confirmCardPayment(t.paymentMethodId||"",e):n=await this.stripeAdapter.confirmPayment(t.paymentMethodId||"",e),this.formatPaymentResult(n)}async retrievePaymentIntent(e){let t=await this.stripeAdapter.retrievePaymentIntent(e);return this.formatPaymentResult(t)}formatPaymentResult(e){let t=e.paymentIntent,n="failed";return t.status==="succeeded"?n="succeeded":["processing","requires_action","requires_confirmation"].includes(t.status)&&(n="processing"),{success:t.status==="succeeded",paymentIntentId:t.id,status:n}}};var I=class{constructor(e,t){this.stripeAdapter=e;this.elementsManager=t;}async save(e,t){let n=this.elementsManager.getElements();await this.validateSetupCanProceed(n,t),await n.submit();let i=await this.stripeAdapter.createPaymentMethod(n,t.isUsingIndividualFormElements),r=await this.stripeAdapter.confirmCardSetup(i,e);return this.formatSetupResult(r)}async retrieve(e){let t=await this.stripeAdapter.retrieveSetupIntent(e);return this.formatSetupResult(t)}async validateSetupCanProceed(e,t){if(!e)throw new a("Card form not mounted","CONFIGURATION_ERROR");if(t.isUsingStripePaymentElement&&t.isUsingIndividualFormElements)throw new a("Both forms of card form in use","CONFIGURATION_ERROR");if(t.isUsingIndividualFormElements){let n=await this.elementsManager.validate();if(!n.isValid)throw new a(n.errors[0].message,"VALIDATION_ERROR")}}formatSetupResult(e){let t=e.setupIntent,n="failed";t.status==="succeeded"?n="succeeded":t.status==="processing"?n="processing":(t.status==="requires_action"||t.status==="requires_confirmation")&&(n="requires_action");let i=t.payment_method,r=typeof i=="string"?i:i?.id;return {success:t.status==="succeeded",savedPaymentMethodId:r,setupIntentId:t.id,status:n}}};var d=class{constructor(e,t){this.baseUrl=e,this.apiKey=t;}setApiKey(e){this.apiKey=e;}async getPaymentIntentConfig(e){try{let t=await fetch(`${this.baseUrl}/v1/payment_intents/config?client_secret=${encodeURIComponent(e)}`,{method:"GET",headers:{"Content-Type":"application/json"}});if(!t.ok)throw new a("Failed to fetch provider config","CONFIGURATION_ERROR");return t.json()}catch(t){throw t instanceof a?t:new a("Error connecting to Verapay API","NETWORK_ERROR")}}async getSetupIntentConfig(e){try{let t=await fetch(`${this.baseUrl}/v1/setup_intents/config?client_secret=${encodeURIComponent(e)}`,{method:"GET",headers:{"Content-Type":"application/json"}});if(!t.ok)throw new a("Failed to fetch setup config","CONFIGURATION_ERROR");return t.json()}catch(t){throw t instanceof a?t:new a("Error connecting to Verapay API","NETWORK_ERROR")}}async initialisePayment(e){let{merchantId:t,paymentData:n}=e;try{let i=await fetch(`${this.baseUrl}/api/initialise-payment`,{method:"POST",headers:{"Content-Type":"application/json",...this.apiKey?{"x-api-key":this.apiKey}:{}},body:JSON.stringify({merchantId:t,paymentData:{...n,paymentMethodType:"card"}})});if(!i.ok){let m=await i.json().catch(()=>({}));throw new a(this.extractErrorMessage(m,i.status),"CONFIGURATION_ERROR")}let r=await i.json();if(!r.clientSecret||!r.paymentIntentId)throw new a("Missing clientSecret or paymentIntentId in server response","CONFIGURATION_ERROR");return {paymentIntentId:r.paymentIntentId,clientSecret:r.clientSecret,connectAccountId:r.connectAccountId,stripePublishableKey:r.stripePublishableKey}}catch(i){throw i instanceof a?i:new a(i instanceof Error?i.message:"Unknown error occurred","CONFIGURATION_ERROR")}}async processPrePayment(e){try{let t=await fetch(`${this.baseUrl}/api/process-prepayment`,{method:"POST",headers:{"Content-Type":"application/json",...this.apiKey?{"x-api-key":this.apiKey}:{}},body:JSON.stringify({merchantId:e.merchantId,paymentIntentId:e.paymentIntentId,paymentMethodId:e.paymentMethodId,amount:e.amount,currency:e.currency,customerData:e.customerData,description:e.description,metadata:e.metadata})});if(!t.ok){let n=await t.json().catch(()=>({}));throw new a(this.extractErrorMessage(n,t.status),"CONFIGURATION_ERROR")}}catch(t){throw t instanceof a?t:new a(t instanceof Error?t.message:"Unknown error occurred","CONFIGURATION_ERROR")}}extractErrorMessage(e,t){if(!e||typeof e!="object")return `HTTP error! status: ${t}`;let n=e,i=[n.error,n.message,n.details];for(let r of i){if(typeof r=="string"&&r.trim().length>0)return r;if(r&&typeof r=="object")try{return JSON.stringify(r)}catch{}}return `HTTP error! status: ${t}`}};function R(s){return s.startsWith("vpy_cs_test_")?s.replace("vpy_cs_test_",""):s.startsWith("vpy_cs_live_")?s.replace("vpy_cs_live_",""):s}var E=class E{constructor(e){this.stripeAdapter=null;this.elementsManager=null;this.paymentService=null;this.setupService=null;this.initializationPromise=null;this.isUsingStripePaymentElement=false;this.isUsingIndividualFormElements=false;this.intentKind="payment";this.rawSecret=null;this.paymentIntentId=null;this.amount=null;this.currency=null;this.merchantId=null;if(!e.apiKey&&!e.clientSecret)throw new a("Either apiKey or clientSecret is required.","CONFIGURATION_ERROR");if(e.apiKey&&e.clientSecret)throw new a("Cannot provide both apiKey and clientSecret. Use apiKey for frontend-initialized flows or clientSecret for backend-initialized flows.","CONFIGURATION_ERROR");e.apiKey&&!e.apiKey.includes("_pk_")&&typeof window<"u"&&console.warn("Verapay Security Warning: You are using a Secret Key in a frontend environment. Please use a Publishable Key (vpy_pk_...) instead."),this.config=e;let t=this.config.apiUrlOverride||E.BACKEND_URL;this.verapayService=new d(t,this.config.apiKey||""),this.extensionsManager=new g;}async initialize(){return this.initializationPromise?this.initializationPromise:(this.initializationPromise=(async()=>{let e,t,n;if(this.config.clientSecret)if(this.intentKind=R(this.config.clientSecret).startsWith("seti_")?"setup":"payment",this.intentKind==="setup"){let r=await this.verapayService.getSetupIntentConfig(this.config.clientSecret);if(r.object!=="setup_intent_config")throw new a("Unexpected configuration returned for setup intent","CONFIGURATION_ERROR");e=this.config.clientSecret,t="",n=r.publishableKey,this.merchantId=r.merchantId,r.verapayPublishableKey&&this.verapayService.setApiKey(r.verapayPublishableKey);}else {let r=await this.verapayService.getPaymentIntentConfig(this.config.clientSecret);e=this.config.clientSecret,t=r.paymentIntentId,n=r.publishableKey,this.amount=r.amount,this.currency=r.currency,this.merchantId=r.merchantId,r.verapayPublishableKey&&this.verapayService.setApiKey(r.verapayPublishableKey);}else {this.validatePaymentInitialisation();let r=await this.verapayService.initialisePayment({merchantId:this.config.merchantId??"",paymentData:this.config.paymentData});e=r.clientSecret,t=r.paymentIntentId,n=r.stripePublishableKey,this.amount=this.config.paymentData.amount,this.currency=this.config.paymentData.currency,this.merchantId=this.config.merchantId??"";}this.rawSecret=R(e),this.paymentIntentId=t;let i=await loadStripe(n);if(!i)throw new a("Failed to load Stripe","CONFIGURATION_ERROR");this.stripeAdapter=new y(i),this.elementsManager=new h(i,this.config,this.rawSecret),this.paymentService=new f(this.stripeAdapter,this.elementsManager,this.verapayService),this.setupService=new I(this.stripeAdapter,this.elementsManager);})().catch(e=>{throw this.initializationPromise=null,e}),this.initializationPromise)}async confirmPayment(){return await this.ensureInitialized(),this.assertIntentKind("payment","confirmPayment"),this.paymentService.confirm(this.rawSecret,{isUsingStripePaymentElement:this.isUsingStripePaymentElement,isUsingIndividualFormElements:this.isUsingIndividualFormElements})}async saveCard(){await this.ensureInitialized(),this.assertIntentKind("setup","saveCard");try{return await this.setupService.save(this.rawSecret,{isUsingStripePaymentElement:this.isUsingStripePaymentElement,isUsingIndividualFormElements:this.isUsingIndividualFormElements})}catch(e){throw this.handlePaymentError(e)}}async retrieveSetupIntent(){return await this.ensureInitialized(),this.assertIntentKind("setup","retrieveSetupIntent"),this.setupService.retrieve(this.rawSecret)}teardown(){this.elementsManager?.unmountAll(),this.stripeAdapter=null,this.elementsManager=null,this.paymentService=null,this.setupService=null,this.initializationPromise=null,this.isUsingStripePaymentElement=false,this.isUsingIndividualFormElements=false,this.intentKind="payment",this.rawSecret=null,this.paymentIntentId=null,this.amount=null,this.currency=null,this.merchantId=null;}async retrievePaymentIntent(){return await this.ensureInitialized(),this.paymentService.retrievePaymentIntent(this.rawSecret)}async processPayment(e){await this.ensureInitialized(),this.assertIntentKind("payment","processPayment");let t=await this.extensionsManager.runBeforePayment(e);try{let n=await this.paymentService.process(t,{merchantId:this.merchantId,paymentIntentId:this.paymentIntentId,clientSecret:this.rawSecret,amount:this.amount,currency:this.currency,isUsingStripePaymentElement:this.isUsingStripePaymentElement,isUsingIndividualFormElements:this.isUsingIndividualFormElements});return await this.extensionsManager.runAfterPayment(n),n}catch(n){throw await this.extensionsManager.runOnError(n),this.handlePaymentError(n)}}async mountPaymentForm(e){await this.ensureInitialized(),this.elementsManager.mountPaymentElement(e),this.isUsingStripePaymentElement=true;}async mountCardNumber(e){await this.ensureInitialized(),this.elementsManager.mountCardNumberElement(e),this.isUsingIndividualFormElements=true;}async mountCardExpiry(e){await this.ensureInitialized(),this.elementsManager.mountCardExpiryElement(e),this.isUsingIndividualFormElements=true;}async mountCardCvc(e){await this.ensureInitialized(),this.elementsManager.mountCardCvcElement(e),this.isUsingIndividualFormElements=true;}async mountAddress(e,t){await this.ensureInitialized(),this.elementsManager.mountAddressElement(e,t),this.isUsingIndividualFormElements=true;}addExtension(e){this.extensionsManager.add(e);}async ensureInitialized(){this.stripeAdapter||await this.initialize();}assertIntentKind(e,t){if(this.intentKind!==e)throw new a(`${t} requires a ${e} intent client secret`,"CONFIGURATION_ERROR")}validatePaymentInitialisation(){if(!this.config.paymentData)throw new a("paymentData is required for frontend-initialized flows.","CONFIGURATION_ERROR");let{amount:e,currency:t,partnerFee:n}=this.config.paymentData;if(!t)throw new l("Currency is required","currency");let i=t.toUpperCase(),r=this.toMoney(e,i,"amount");if(r.isZero()||r.isNegative())throw new l("Amount must be greater than 0","amount");if(n!==void 0){let m=this.toMoney(n,i,"partnerFee");if(m.isNegative())throw new l("partnerFee cannot be negative","partnerFee");if(m.greaterThan(r))throw new l("partnerFee cannot exceed the payment amount","partnerFee")}}toMoney(e,t,n){try{return Money.fromInteger(e,t)}catch{throw new l(`${n} must be an integer in the smallest currency unit (e.g., cents for USD)`,n)}}handlePaymentError(e){if(e instanceof a)return e;let t=e instanceof Error?e.message:"Payment failed",n=e?.code;return new o(t,n)}};E.BACKEND_URL="https://api.verapay.app";var w=E;var P=class{validateCardNumber(e){let t=e.replace(/\D/g,"");if(t.length<13||t.length>19)return false;let n=0,i=false;for(let r=t.length-1;r>=0;r--){let m=parseInt(t[r],10);i&&(m*=2,m>9&&(m-=9)),n+=m,i=!i;}return n%10===0}detectCardType(e){let t=e.replace(/\D/g,"");return /^4/.test(t)?"visa":/^5[1-5]/.test(t)?"mastercard":/^3[47]/.test(t)?"amex":/^6(?:011|5)/.test(t)?"discover":"unknown"}validateExpiry(e,t){let n=new Date,i=n.getFullYear(),r=n.getMonth()+1;if(e<1||e>12)return false;let m=t<100?2e3+t:t;return !(m<i||m===i&&e<r)}validateCVC(e,t="unknown"){let n=e.replace(/\D/g,"");return t==="amex"?n.length===4:n.length===3||n.length===4}validateAll(e,t,n,i){let r=this.detectCardType(e);return {number:{isValid:this.validateCardNumber(e),cardType:r},expiry:{isValid:this.validateExpiry(t,n),month:t,year:n},cvc:{isValid:this.validateCVC(i,r),length:i.replace(/\D/g,"").length}}}};var v=class{static sanitizeCardNumber(e){return e.replace(/\D/g,"")}static formatCardNumber(e){return this.sanitizeCardNumber(e).replace(/(\d{4})/g,"$1 ").trim()}static sanitizeCVC(e){return e.replace(/\D/g,"").slice(0,4)}static sanitizeExpiry(e){let t=e.replace(/\D/g,"");return t.length===4?{month:parseInt(t.slice(0,2),10),year:parseInt(t.slice(2,4),10)}:t.length===6?{month:parseInt(t.slice(0,2),10),year:parseInt(t.slice(2,6),10)}:null}};var ve="1.4.0";
2
+ export{P as CardValidator,u as ErrorFormatter,v as InputSanitizer,o as PaymentError,ve as VERSION,l as ValidationError,w as VerapayClient,a as VerapayError,d as VerapayService};//# sourceMappingURL=index.js.map
3
3
  //# sourceMappingURL=index.js.map