@thavguard/arc-pay 0.1.4 → 0.1.6

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
@@ -68,6 +68,27 @@ Mutating server-client methods require an explicit `{ idempotencyKey }`:
68
68
  `createCheckoutSession`. Missing idempotency raises `ArcPayError` with
69
69
  `code="missing_idempotency_key"` before any HTTP request is sent.
70
70
 
71
+ H2H card execution returns a standardized `next_action` when the buyer must do
72
+ something in the browser. The SDK helper turns that action into the POST form
73
+ descriptor you render in a hidden iframe or visible browser page:
74
+
75
+ ```ts
76
+ import { buildThreeDSBrowserForm, getThreeDSAction } from "@thavguard/arc-pay/server";
77
+
78
+ const result = await client.executePayment(paymentId, body, { idempotencyKey });
79
+ const action = getThreeDSAction(result.next_action);
80
+
81
+ if (action) {
82
+ const form = buildThreeDSBrowserForm(action);
83
+ // Render POST form using form.action, form.method, form.target, form.fields.
84
+ // For action.type === "three_ds_method", call completeThreeDSMethod from your
85
+ // backend after the hidden iframe finishes or times out.
86
+ }
87
+ ```
88
+
89
+ Do not branch on bank-specific 3DS fields. Arc Pay normalizes 3DS 1.x and 2.x
90
+ into `next_action.three_ds.submit`.
91
+
71
92
  The server client accepts an optional `apiBase` only for local or isolated test
72
93
  environments. Production integrations should use the default
73
94
  `https://api.arcpay.space/v1`; sandbox/live is selected by the key prefix.
@@ -0,0 +1,292 @@
1
+ type Currency = "RUB" | "KZT" | "UZS";
2
+ type PaymentMethod = "bank_card" | "sbp" | "sberpay" | "tpay" | "alfapay" | "dolyami" | "mirpay" | "applepay" | "googlepay" | "bnpl";
3
+ type CaptureMode = "one_stage" | "two_stage";
4
+ type PaymentFlowMode = "h2h" | "redirect";
5
+ type Locale = "ru" | "en";
6
+ type PaymentStatus = "created" | "pending" | "pending_3ds" | "authorized" | "captured" | "settled" | "voided" | "expired" | "refunded" | "chargeback" | "declined" | "failed" | "timeout";
7
+ interface Payment {
8
+ id: string;
9
+ amount: number;
10
+ authorized_amount?: number;
11
+ captured_amount?: number;
12
+ refunded_amount?: number;
13
+ currency: Currency;
14
+ payment_method: PaymentMethod;
15
+ status: PaymentStatus;
16
+ external_id?: string;
17
+ description?: string;
18
+ bank_payment_id?: string;
19
+ bank_code?: string;
20
+ bank_order_id?: string;
21
+ bank_terminal_id?: string;
22
+ bank_rrn?: string;
23
+ bank_internal_ref?: string;
24
+ bank_auth_code?: string;
25
+ card_token_id?: string;
26
+ decline_code?: string;
27
+ card_mask?: string;
28
+ card_scheme?: string;
29
+ redirect_url?: string;
30
+ payment_mode?: PaymentFlowMode;
31
+ capture_mode?: CaptureMode;
32
+ created_at: string;
33
+ updated_at: string;
34
+ metadata?: Record<string, string>;
35
+ }
36
+ interface PaymentList {
37
+ payments: Payment[];
38
+ total: number;
39
+ page: number;
40
+ page_size: number;
41
+ }
42
+ interface CreatePaymentRequest {
43
+ amount: number;
44
+ currency: Currency;
45
+ payment_method: PaymentMethod;
46
+ external_id: string;
47
+ capture_mode: CaptureMode;
48
+ save_card?: boolean;
49
+ customer_id?: string;
50
+ description?: string;
51
+ success_url?: string;
52
+ fail_url?: string;
53
+ callback_url?: string;
54
+ customer_email?: string;
55
+ customer_phone?: string;
56
+ metadata?: Record<string, string>;
57
+ }
58
+ interface CaptureRequest {
59
+ amount?: number;
60
+ }
61
+ interface VoidRequest {
62
+ reason?: string;
63
+ }
64
+ interface CreateRefundRequest {
65
+ amount: number;
66
+ reason?: string;
67
+ }
68
+ interface Refund {
69
+ id: string;
70
+ payment_id: string;
71
+ amount: number;
72
+ currency: Currency;
73
+ status: "pending" | "completed" | "failed";
74
+ reason?: string;
75
+ created_at: string;
76
+ }
77
+ interface ExecutePaymentRequest {
78
+ card_token_id: string;
79
+ payment_mode: "h2h";
80
+ browser_info: {
81
+ accept_header: string;
82
+ language: string;
83
+ screen_width: number;
84
+ screen_height: number;
85
+ color_depth: 1 | 4 | 8 | 15 | 16 | 24 | 32 | 48;
86
+ timezone_offset_minutes: number;
87
+ java_enabled?: boolean;
88
+ user_agent: string;
89
+ window_size?: "01" | "02" | "03" | "04" | "05";
90
+ };
91
+ }
92
+ interface ExecutePaymentResponse {
93
+ payment_id: string;
94
+ status: "authorized" | "captured" | "pending" | "pending_3ds" | "failed" | "declined";
95
+ authorized_amount?: number;
96
+ payment_mode?: PaymentFlowMode;
97
+ redirect_url?: string;
98
+ qr_url?: string;
99
+ qr_image_base64?: string;
100
+ qr_content_type?: "image/png" | "image/svg+xml" | string;
101
+ qr_expires_at?: string;
102
+ liability_shifted?: boolean;
103
+ next_action?: PaymentNextAction;
104
+ decline_code?: string;
105
+ decline_message?: string;
106
+ }
107
+ interface PaymentNextAction {
108
+ type: "three_ds_method" | "three_ds_challenge";
109
+ three_ds: {
110
+ version: "1" | "2";
111
+ phase: "method" | "challenge";
112
+ three_ds_server_trans_id?: string;
113
+ completion_endpoint?: string;
114
+ submit: {
115
+ method: "POST";
116
+ url: string;
117
+ target: "hidden_iframe" | "browser";
118
+ fields: {
119
+ name: string;
120
+ value: string;
121
+ }[];
122
+ };
123
+ };
124
+ }
125
+ interface ChargeSavedCardRequest {
126
+ amount: number;
127
+ currency: Currency;
128
+ card_token_id: string;
129
+ customer_id: string;
130
+ external_id?: string;
131
+ description?: string;
132
+ metadata?: Record<string, string>;
133
+ fiscal_items?: {
134
+ name: string;
135
+ quantity: number;
136
+ unit_price: number;
137
+ vat_rate: "no_vat" | "vat0" | "vat10" | "vat20";
138
+ }[];
139
+ }
140
+ interface CompleteThreeDSMethodRequest {
141
+ completion_indicator: "Y" | "N" | "U";
142
+ three_ds_server_trans_id: string;
143
+ }
144
+ interface AvailablePaymentMethod {
145
+ method: PaymentMethod;
146
+ payment_mode: PaymentFlowMode;
147
+ display_name: string;
148
+ is_active: boolean;
149
+ unavailable_reason?: string;
150
+ icon_url?: string;
151
+ supported_currencies?: Currency[];
152
+ supported_countries?: string[];
153
+ min_amount?: number;
154
+ max_amount?: number;
155
+ sandbox_requirements?: string;
156
+ }
157
+ interface CreateLinkRequest {
158
+ link_type: "one_time" | "reusable" | "invoice" | "recurring";
159
+ amount: number;
160
+ currency: Currency;
161
+ description?: string;
162
+ environment?: "live" | "sandbox";
163
+ max_uses?: number;
164
+ expires_at?: string;
165
+ customer_name?: string;
166
+ customer_id?: string;
167
+ customer_email?: string;
168
+ due_date?: string;
169
+ redirect_url?: string;
170
+ webhook_url?: string;
171
+ external_order_id?: string;
172
+ metadata?: Record<string, string>;
173
+ capture_mode: CaptureMode;
174
+ autocompletion_date?: string;
175
+ locale?: Locale;
176
+ payment_methods: {
177
+ method: PaymentMethod;
178
+ payment_mode: PaymentFlowMode;
179
+ }[];
180
+ items?: {
181
+ name: string;
182
+ quantity: string;
183
+ unit_price: number;
184
+ vat_rate?: number;
185
+ }[];
186
+ billing_config?: {
187
+ interval_type?: "day" | "week" | "month" | "year";
188
+ interval_count?: number;
189
+ trial_days?: number;
190
+ trial_price?: number;
191
+ };
192
+ }
193
+ interface Link {
194
+ id: string;
195
+ tenant_id?: string;
196
+ organization_id?: string;
197
+ short_code: string;
198
+ link_type: "one_time" | "reusable" | "invoice" | "recurring";
199
+ status: "active" | "paid" | "expired" | "canceled";
200
+ environment: "live" | "sandbox";
201
+ amount: number;
202
+ currency: Currency;
203
+ created_at?: string;
204
+ updated_at?: string;
205
+ description?: string;
206
+ url: string;
207
+ max_uses?: number;
208
+ uses_count?: number;
209
+ expires_at?: string;
210
+ customer_name?: string;
211
+ customer_id?: string;
212
+ customer_email?: string;
213
+ due_date?: string;
214
+ external_order_id?: string;
215
+ payment_methods: {
216
+ method: PaymentMethod;
217
+ payment_mode: PaymentFlowMode;
218
+ display_name?: string;
219
+ }[];
220
+ redirect_url?: string;
221
+ webhook_url?: string;
222
+ items?: {
223
+ name?: string;
224
+ quantity?: string;
225
+ unit_price?: number;
226
+ vat_rate?: number;
227
+ }[];
228
+ billing_config?: {
229
+ interval_type?: string;
230
+ interval_count?: number;
231
+ trial_days?: number;
232
+ trial_price?: number;
233
+ };
234
+ metadata?: Record<string, string>;
235
+ capture_mode: CaptureMode;
236
+ autocompletion_date?: string;
237
+ locale?: Locale;
238
+ }
239
+ interface CreateCheckoutSessionRequest {
240
+ amount: number;
241
+ currency: Currency;
242
+ description?: string;
243
+ payment_methods: {
244
+ method: PaymentMethod;
245
+ payment_mode: PaymentFlowMode;
246
+ }[];
247
+ capture_mode: CaptureMode;
248
+ success_url?: string;
249
+ fail_url?: string;
250
+ cancel_url?: string;
251
+ customer_email?: string;
252
+ customer_id?: string;
253
+ external_id?: string;
254
+ metadata?: Record<string, string>;
255
+ autocompletion_date?: string;
256
+ locale?: Locale;
257
+ }
258
+ interface CheckoutSession {
259
+ id: string;
260
+ url: string;
261
+ }
262
+ interface ListPaymentsQuery {
263
+ page?: number;
264
+ page_size?: number;
265
+ status?: PaymentStatus;
266
+ payment_method?: PaymentMethod;
267
+ bank_code?: string;
268
+ decline_code?: string;
269
+ payment_flow_id?: string;
270
+ search?: string;
271
+ date_from?: string;
272
+ date_to?: string;
273
+ }
274
+ interface ListAvailablePaymentMethodsQuery {
275
+ environment: "live" | "sandbox";
276
+ }
277
+
278
+ type ThreeDSAction = PaymentNextAction;
279
+ interface BrowserFormField {
280
+ name: string;
281
+ value: string;
282
+ }
283
+ interface BrowserPostForm {
284
+ action: string;
285
+ method: "POST";
286
+ target: "hidden_iframe" | "browser";
287
+ fields: BrowserFormField[];
288
+ }
289
+ declare const getThreeDSAction: (nextAction?: PaymentNextAction) => PaymentNextAction | null;
290
+ declare const buildThreeDSBrowserForm: (nextAction: PaymentNextAction) => BrowserPostForm;
291
+
292
+ export { type AvailablePaymentMethod as A, type BrowserFormField as B, type CaptureRequest as C, type ExecutePaymentRequest as E, type Link as L, type Payment as P, type Refund as R, type ThreeDSAction as T, type VoidRequest as V, type BrowserPostForm as a, type ChargeSavedCardRequest as b, type CheckoutSession as c, type CompleteThreeDSMethodRequest as d, type CreateCheckoutSessionRequest as e, type CreateLinkRequest as f, type CreatePaymentRequest as g, type CreateRefundRequest as h, type ExecutePaymentResponse as i, type ListAvailablePaymentMethodsQuery as j, type ListPaymentsQuery as k, type PaymentFlowMode as l, type PaymentList as m, type PaymentMethod as n, type PaymentNextAction as o, buildThreeDSBrowserForm as p, getThreeDSAction as q };
@@ -0,0 +1,292 @@
1
+ type Currency = "RUB" | "KZT" | "UZS";
2
+ type PaymentMethod = "bank_card" | "sbp" | "sberpay" | "tpay" | "alfapay" | "dolyami" | "mirpay" | "applepay" | "googlepay" | "bnpl";
3
+ type CaptureMode = "one_stage" | "two_stage";
4
+ type PaymentFlowMode = "h2h" | "redirect";
5
+ type Locale = "ru" | "en";
6
+ type PaymentStatus = "created" | "pending" | "pending_3ds" | "authorized" | "captured" | "settled" | "voided" | "expired" | "refunded" | "chargeback" | "declined" | "failed" | "timeout";
7
+ interface Payment {
8
+ id: string;
9
+ amount: number;
10
+ authorized_amount?: number;
11
+ captured_amount?: number;
12
+ refunded_amount?: number;
13
+ currency: Currency;
14
+ payment_method: PaymentMethod;
15
+ status: PaymentStatus;
16
+ external_id?: string;
17
+ description?: string;
18
+ bank_payment_id?: string;
19
+ bank_code?: string;
20
+ bank_order_id?: string;
21
+ bank_terminal_id?: string;
22
+ bank_rrn?: string;
23
+ bank_internal_ref?: string;
24
+ bank_auth_code?: string;
25
+ card_token_id?: string;
26
+ decline_code?: string;
27
+ card_mask?: string;
28
+ card_scheme?: string;
29
+ redirect_url?: string;
30
+ payment_mode?: PaymentFlowMode;
31
+ capture_mode?: CaptureMode;
32
+ created_at: string;
33
+ updated_at: string;
34
+ metadata?: Record<string, string>;
35
+ }
36
+ interface PaymentList {
37
+ payments: Payment[];
38
+ total: number;
39
+ page: number;
40
+ page_size: number;
41
+ }
42
+ interface CreatePaymentRequest {
43
+ amount: number;
44
+ currency: Currency;
45
+ payment_method: PaymentMethod;
46
+ external_id: string;
47
+ capture_mode: CaptureMode;
48
+ save_card?: boolean;
49
+ customer_id?: string;
50
+ description?: string;
51
+ success_url?: string;
52
+ fail_url?: string;
53
+ callback_url?: string;
54
+ customer_email?: string;
55
+ customer_phone?: string;
56
+ metadata?: Record<string, string>;
57
+ }
58
+ interface CaptureRequest {
59
+ amount?: number;
60
+ }
61
+ interface VoidRequest {
62
+ reason?: string;
63
+ }
64
+ interface CreateRefundRequest {
65
+ amount: number;
66
+ reason?: string;
67
+ }
68
+ interface Refund {
69
+ id: string;
70
+ payment_id: string;
71
+ amount: number;
72
+ currency: Currency;
73
+ status: "pending" | "completed" | "failed";
74
+ reason?: string;
75
+ created_at: string;
76
+ }
77
+ interface ExecutePaymentRequest {
78
+ card_token_id: string;
79
+ payment_mode: "h2h";
80
+ browser_info: {
81
+ accept_header: string;
82
+ language: string;
83
+ screen_width: number;
84
+ screen_height: number;
85
+ color_depth: 1 | 4 | 8 | 15 | 16 | 24 | 32 | 48;
86
+ timezone_offset_minutes: number;
87
+ java_enabled?: boolean;
88
+ user_agent: string;
89
+ window_size?: "01" | "02" | "03" | "04" | "05";
90
+ };
91
+ }
92
+ interface ExecutePaymentResponse {
93
+ payment_id: string;
94
+ status: "authorized" | "captured" | "pending" | "pending_3ds" | "failed" | "declined";
95
+ authorized_amount?: number;
96
+ payment_mode?: PaymentFlowMode;
97
+ redirect_url?: string;
98
+ qr_url?: string;
99
+ qr_image_base64?: string;
100
+ qr_content_type?: "image/png" | "image/svg+xml" | string;
101
+ qr_expires_at?: string;
102
+ liability_shifted?: boolean;
103
+ next_action?: PaymentNextAction;
104
+ decline_code?: string;
105
+ decline_message?: string;
106
+ }
107
+ interface PaymentNextAction {
108
+ type: "three_ds_method" | "three_ds_challenge";
109
+ three_ds: {
110
+ version: "1" | "2";
111
+ phase: "method" | "challenge";
112
+ three_ds_server_trans_id?: string;
113
+ completion_endpoint?: string;
114
+ submit: {
115
+ method: "POST";
116
+ url: string;
117
+ target: "hidden_iframe" | "browser";
118
+ fields: {
119
+ name: string;
120
+ value: string;
121
+ }[];
122
+ };
123
+ };
124
+ }
125
+ interface ChargeSavedCardRequest {
126
+ amount: number;
127
+ currency: Currency;
128
+ card_token_id: string;
129
+ customer_id: string;
130
+ external_id?: string;
131
+ description?: string;
132
+ metadata?: Record<string, string>;
133
+ fiscal_items?: {
134
+ name: string;
135
+ quantity: number;
136
+ unit_price: number;
137
+ vat_rate: "no_vat" | "vat0" | "vat10" | "vat20";
138
+ }[];
139
+ }
140
+ interface CompleteThreeDSMethodRequest {
141
+ completion_indicator: "Y" | "N" | "U";
142
+ three_ds_server_trans_id: string;
143
+ }
144
+ interface AvailablePaymentMethod {
145
+ method: PaymentMethod;
146
+ payment_mode: PaymentFlowMode;
147
+ display_name: string;
148
+ is_active: boolean;
149
+ unavailable_reason?: string;
150
+ icon_url?: string;
151
+ supported_currencies?: Currency[];
152
+ supported_countries?: string[];
153
+ min_amount?: number;
154
+ max_amount?: number;
155
+ sandbox_requirements?: string;
156
+ }
157
+ interface CreateLinkRequest {
158
+ link_type: "one_time" | "reusable" | "invoice" | "recurring";
159
+ amount: number;
160
+ currency: Currency;
161
+ description?: string;
162
+ environment?: "live" | "sandbox";
163
+ max_uses?: number;
164
+ expires_at?: string;
165
+ customer_name?: string;
166
+ customer_id?: string;
167
+ customer_email?: string;
168
+ due_date?: string;
169
+ redirect_url?: string;
170
+ webhook_url?: string;
171
+ external_order_id?: string;
172
+ metadata?: Record<string, string>;
173
+ capture_mode: CaptureMode;
174
+ autocompletion_date?: string;
175
+ locale?: Locale;
176
+ payment_methods: {
177
+ method: PaymentMethod;
178
+ payment_mode: PaymentFlowMode;
179
+ }[];
180
+ items?: {
181
+ name: string;
182
+ quantity: string;
183
+ unit_price: number;
184
+ vat_rate?: number;
185
+ }[];
186
+ billing_config?: {
187
+ interval_type?: "day" | "week" | "month" | "year";
188
+ interval_count?: number;
189
+ trial_days?: number;
190
+ trial_price?: number;
191
+ };
192
+ }
193
+ interface Link {
194
+ id: string;
195
+ tenant_id?: string;
196
+ organization_id?: string;
197
+ short_code: string;
198
+ link_type: "one_time" | "reusable" | "invoice" | "recurring";
199
+ status: "active" | "paid" | "expired" | "canceled";
200
+ environment: "live" | "sandbox";
201
+ amount: number;
202
+ currency: Currency;
203
+ created_at?: string;
204
+ updated_at?: string;
205
+ description?: string;
206
+ url: string;
207
+ max_uses?: number;
208
+ uses_count?: number;
209
+ expires_at?: string;
210
+ customer_name?: string;
211
+ customer_id?: string;
212
+ customer_email?: string;
213
+ due_date?: string;
214
+ external_order_id?: string;
215
+ payment_methods: {
216
+ method: PaymentMethod;
217
+ payment_mode: PaymentFlowMode;
218
+ display_name?: string;
219
+ }[];
220
+ redirect_url?: string;
221
+ webhook_url?: string;
222
+ items?: {
223
+ name?: string;
224
+ quantity?: string;
225
+ unit_price?: number;
226
+ vat_rate?: number;
227
+ }[];
228
+ billing_config?: {
229
+ interval_type?: string;
230
+ interval_count?: number;
231
+ trial_days?: number;
232
+ trial_price?: number;
233
+ };
234
+ metadata?: Record<string, string>;
235
+ capture_mode: CaptureMode;
236
+ autocompletion_date?: string;
237
+ locale?: Locale;
238
+ }
239
+ interface CreateCheckoutSessionRequest {
240
+ amount: number;
241
+ currency: Currency;
242
+ description?: string;
243
+ payment_methods: {
244
+ method: PaymentMethod;
245
+ payment_mode: PaymentFlowMode;
246
+ }[];
247
+ capture_mode: CaptureMode;
248
+ success_url?: string;
249
+ fail_url?: string;
250
+ cancel_url?: string;
251
+ customer_email?: string;
252
+ customer_id?: string;
253
+ external_id?: string;
254
+ metadata?: Record<string, string>;
255
+ autocompletion_date?: string;
256
+ locale?: Locale;
257
+ }
258
+ interface CheckoutSession {
259
+ id: string;
260
+ url: string;
261
+ }
262
+ interface ListPaymentsQuery {
263
+ page?: number;
264
+ page_size?: number;
265
+ status?: PaymentStatus;
266
+ payment_method?: PaymentMethod;
267
+ bank_code?: string;
268
+ decline_code?: string;
269
+ payment_flow_id?: string;
270
+ search?: string;
271
+ date_from?: string;
272
+ date_to?: string;
273
+ }
274
+ interface ListAvailablePaymentMethodsQuery {
275
+ environment: "live" | "sandbox";
276
+ }
277
+
278
+ type ThreeDSAction = PaymentNextAction;
279
+ interface BrowserFormField {
280
+ name: string;
281
+ value: string;
282
+ }
283
+ interface BrowserPostForm {
284
+ action: string;
285
+ method: "POST";
286
+ target: "hidden_iframe" | "browser";
287
+ fields: BrowserFormField[];
288
+ }
289
+ declare const getThreeDSAction: (nextAction?: PaymentNextAction) => PaymentNextAction | null;
290
+ declare const buildThreeDSBrowserForm: (nextAction: PaymentNextAction) => BrowserPostForm;
291
+
292
+ export { type AvailablePaymentMethod as A, type BrowserFormField as B, type CaptureRequest as C, type ExecutePaymentRequest as E, type Link as L, type Payment as P, type Refund as R, type ThreeDSAction as T, type VoidRequest as V, type BrowserPostForm as a, type ChargeSavedCardRequest as b, type CheckoutSession as c, type CompleteThreeDSMethodRequest as d, type CreateCheckoutSessionRequest as e, type CreateLinkRequest as f, type CreatePaymentRequest as g, type CreateRefundRequest as h, type ExecutePaymentResponse as i, type ListAvailablePaymentMethodsQuery as j, type ListPaymentsQuery as k, type PaymentFlowMode as l, type PaymentList as m, type PaymentMethod as n, type PaymentNextAction as o, buildThreeDSBrowserForm as p, getThreeDSAction as q };
@@ -1,3 +1,3 @@
1
- var ArcPay=(function(exports){'use strict';var n=class extends Error{constructor(t){super(t.message),this.name="ArcPayError",this.type=t.type,this.code=t.code,this.param=t.param,this.paymentId=t.paymentId,this.declineCode=t.declineCode,this.retryable=t.retryable,this.requestId=t.requestId;}},T=e=>e instanceof n&&e.type==="validation_error",I=e=>e instanceof n&&e.type==="authentication_error",P=e=>e instanceof n&&e.type==="authorization_error",A=e=>e instanceof n&&e.type==="state_error",z=e=>e instanceof n&&e.type==="rate_limit_error",S=e=>e instanceof n&&e.type==="api_error",R=e=>e instanceof n&&e.type==="network_error",M=e=>e instanceof n&&e.type==="challenge_aborted";var f=e=>e.startsWith("pk_test_")?"sandbox":"live",x=e=>{if(typeof e!="string"||e.length===0)throw new n({type:"validation_error",code:"invalid_publishable_key",message:"Publishable key must be a non-empty string",retryable:false});if(!e.startsWith("pk_test_")&&!e.startsWith("pk_live_"))throw new n({type:"validation_error",code:"invalid_publishable_key",message:"Publishable key must start with pk_test_ or pk_live_. Secret keys (sk_*) cannot be used in browser.",retryable:false})};var w="data-arcpay-sandbox-banner",_=()=>{if(typeof document=="undefined"||document.querySelector(`[${w}]`))return;let e=document.createElement("div");e.setAttribute(w,""),e.style.cssText="position:fixed;top:0;left:0;right:0;z-index:2147483647;background:#ffd166;color:#222;font:13px/1.4 system-ui,sans-serif;padding:6px 12px;display:flex;align-items:center;justify-content:center;box-shadow:0 1px 3px rgba(0,0,0,0.1);";let t=document.createElement("span");t.textContent="ARC PAY TEST MODE \u2014 payments are simulated",e.appendChild(t);let r=document.createElement("button");r.type="button",r.setAttribute("data-arcpay-banner-dismiss",""),r.textContent="\xD7",r.setAttribute("aria-label","Dismiss test mode banner"),r.style.cssText="margin-left:12px;background:transparent;border:0;font-size:18px;cursor:pointer;color:inherit;",r.addEventListener("click",()=>e.remove()),e.appendChild(r),document.body.appendChild(e);};var C="arcpay:",F=e=>typeof e=="object"&&e!==null&&"type"in e&&typeof e.type=="string"&&e.type.startsWith(C),u=(e,t,r)=>{if(r==="*")throw new n({type:"validation_error",code:"wildcard_origin_forbidden",message:"postToIframe: targetOrigin cannot be '*'",retryable:false});if(!e.contentWindow)throw new n({type:"validation_error",code:"iframe_not_loaded",message:"postToIframe: iframe.contentWindow is null (iframe not mounted)",retryable:false});e.contentWindow.postMessage(t,r);};var y=(e,t)=>e.origin!==t||!F(e.data)?null:e.data;var L=new Set(["position","transform","pointer-events","z-index","top","left","right","bottom","inset"]),g=e=>{let t={};for(let[r,o]of Object.entries(e)){let s=r.toLowerCase();L.has(s)||(t[r]=o);}return t},h=e=>{let t={base:g(e.base)};return e.invalid!==void 0&&(t.invalid=g(e.invalid)),e.focus!==void 0&&(t.focus=g(e.focus)),t};var m=class{constructor(t,r,o){this.field=t;this.options=r;this.context=o;this.iframe=null;this.listeners=new Set;this.status="pending";this.messageHandler=null;}mount(t){if(this.iframe)throw new n({type:"validation_error",code:"already_mounted",message:`Element ${this.field} is already mounted`,retryable:false});let r=typeof t=="string"?document.querySelector(t):t;if(!(r instanceof HTMLElement))throw new n({type:"validation_error",code:"mount_target_not_found",message:`mount target not found: ${String(t)}`,retryable:false});let o=document.createElement("iframe");o.src=`${this.context.iframeBase}/iframe/${this.field}`,o.style.cssText="border:0;width:100%;height:100%;display:block;",o.setAttribute("allow","payment"),o.setAttribute("data-arcpay-element",this.field),r.appendChild(o),this.iframe=o;let s=new URL(this.context.iframeBase).origin;this.messageHandler=a=>{var l;if(a.source!==((l=this.iframe)==null?void 0:l.contentWindow))return;let d=y(a,s);d&&this.handleMessage(d);},window.addEventListener("message",this.messageHandler),o.addEventListener("load",()=>{if(!this.iframe)return;let a={type:"arcpay:hello",origin:window.location.origin,publishableKey:this.context.publishableKey,channelId:this.context.channelId};u(this.iframe,a,s);},{once:true});}handleMessage(t){t.type==="arcpay:ready"?(this.status="ready",this.options.style&&this.send({type:"arcpay:style",payload:h(this.options.style)}),this.emit({type:"ready"})):t.type==="arcpay:rejected"?(this.status="error",this.emit({type:"error",reason:t.reason})):t.type==="arcpay:change"&&t.field===this.field&&this.emit({type:"change",isValid:t.isValid,brand:t.brand,lastFour:t.lastFour});}update(t){t.style&&this.send({type:"arcpay:style",payload:h(t.style)});}destroy(){this.iframe&&(this.iframe.remove(),this.iframe=null),this.messageHandler&&(window.removeEventListener("message",this.messageHandler),this.messageHandler=null),this.listeners.clear(),this.status="pending";}on(t,r){return this.listeners.add(r),()=>this.listeners.delete(r)}focus(){this.send({type:"arcpay:focus"});}clear(){this.send({type:"arcpay:clear"});}isReady(){return this.status==="ready"}getIframeContentWindow(){var t,r;return (r=(t=this.iframe)==null?void 0:t.contentWindow)!=null?r:null}send(t){if(!this.iframe)throw new n({type:"validation_error",code:"not_mounted",message:`Element ${this.field} is not mounted`,retryable:false});u(this.iframe,t,new URL(this.context.iframeBase).origin);}emit(t){for(let r of this.listeners)r(t);}};var B="https://sdk.arcpay.space",O=()=>{var e;if(!((e=globalThis.crypto)!=null&&e.randomUUID))throw new n({type:"validation_error",code:"crypto_unavailable",message:"crypto.randomUUID is required for Hosted Fields",retryable:false});return globalThis.crypto.randomUUID()},p=class{constructor(t){this.elementMap=new Map;this.tokenizeInFlight=false;var r;this.publishableKey=t.publishableKey,this.iframeBase=(r=t.iframeBase)!=null?r:B,this.channelId=O();}create(t,r={}){if(this.elementMap.has(t))throw new n({type:"validation_error",code:"duplicate_element",message:`Element for ${t} already created`,retryable:false});let o={iframeBase:this.iframeBase,publishableKey:this.publishableKey,channelId:this.channelId},s=new m(t,r,o);return this.elementMap.set(t,s),s}async tokenize(t,r){if(this.tokenizeInFlight)throw new n({type:"validation_error",code:"tokenize_in_progress",message:"A tokenize() call is already in progress for this Elements instance",retryable:false});let o=this.elementMap.get("cardNumber"),s=this.elementMap.get("cardExpiry"),a=this.elementMap.get("cardCvv");if(!o||!s||!a)throw new n({type:"validation_error",code:"incomplete_elements",message:"All three elements (cardNumber, cardExpiry, cardCvv) must be created and mounted before tokenize()",retryable:false});if(!o.isReady()||!s.isReady()||!a.isReady())throw new n({type:"validation_error",code:"elements_not_ready",message:"Wait for all elements to fire 'ready' event before tokenize()",retryable:false});this.tokenizeInFlight=true;try{return await this.doTokenize(o,t,r)}finally{this.tokenizeInFlight=false;}}doTokenize(t,r,o){let s=new URL(this.iframeBase).origin,a=t.getIframeContentWindow();return new Promise((d,l)=>{let E=window.setTimeout(()=>{window.removeEventListener("message",c),l(new n({type:"network_error",code:"tokenize_timeout",message:"tokenize() timed out after 30 seconds",retryable:true,paymentId:r}));},3e4),c=v=>{if(a!==null&&v.source!==a)return;let i=y(v,s);if(i){if(i.type==="arcpay:tokenize-result")clearTimeout(E),window.removeEventListener("message",c),d({cardTokenId:i.cardTokenId,cardMask:i.cardMask,cardScheme:i.cardScheme,cardBin:i.cardBin,expiresIn:i.expiresIn,expiresAt:i.expiresAt});else if(i.type==="arcpay:tokenize-error"){clearTimeout(E),window.removeEventListener("message",c);let k=i.errorType==="validation_error"||i.errorType==="api_error"?i.errorType:"api_error";l(new n({type:k,code:i.code,message:i.message,retryable:false,paymentId:r}));}}};window.addEventListener("message",c),t.send({type:"arcpay:tokenize",paymentId:r,idempotencyKey:o});})}destroy(){for(let t of this.elementMap.values())t.destroy();this.elementMap.clear();}};var W=x,b=new Map,K=e=>(f(e)==="sandbox"&&_(),{publishableKey:e,environment:f(e),elements:()=>new p({publishableKey:e})});function H(e){try{W(e);}catch(s){return Promise.reject(s)}let t=e,r=b.get(t);if(r)return r;let o=Promise.resolve(K(e));return b.set(t,o),o}var U=()=>{b.clear();},D={load:H,__resetForTests:U};var le="0.1.4";
2
- exports.ArcPay=D;exports.ArcPayError=n;exports.Elements=p;exports.SDK_VERSION=le;exports.isApiError=S;exports.isAuthenticationError=I;exports.isAuthorizationError=P;exports.isChallengeAborted=M;exports.isNetworkError=R;exports.isRateLimitError=z;exports.isStateError=A;exports.isValidationError=T;return exports;})({});//# sourceMappingURL=arcpay.global.js.map
1
+ var ArcPay=(function(exports){'use strict';var n=class extends Error{constructor(t){super(t.message),this.name="ArcPayError",this.type=t.type,this.code=t.code,this.param=t.param,this.paymentId=t.paymentId,this.declineCode=t.declineCode,this.retryable=t.retryable,this.requestId=t.requestId;}},I=e=>e instanceof n&&e.type==="validation_error",A=e=>e instanceof n&&e.type==="authentication_error",S=e=>e instanceof n&&e.type==="authorization_error",z=e=>e instanceof n&&e.type==="state_error",F=e=>e instanceof n&&e.type==="rate_limit_error",R=e=>e instanceof n&&e.type==="api_error",B=e=>e instanceof n&&e.type==="network_error",M=e=>e instanceof n&&e.type==="challenge_aborted";var f=e=>e.startsWith("pk_test_")?"sandbox":"live",w=e=>{if(typeof e!="string"||e.length===0)throw new n({type:"validation_error",code:"invalid_publishable_key",message:"Publishable key must be a non-empty string",retryable:false});if(!e.startsWith("pk_test_")&&!e.startsWith("pk_live_"))throw new n({type:"validation_error",code:"invalid_publishable_key",message:"Publishable key must start with pk_test_ or pk_live_. Secret keys (sk_*) cannot be used in browser.",retryable:false})};var x="data-arcpay-sandbox-banner",_=()=>{if(typeof document=="undefined"||document.querySelector(`[${x}]`))return;let e=document.createElement("div");e.setAttribute(x,""),e.style.cssText="position:fixed;top:0;left:0;right:0;z-index:2147483647;background:#ffd166;color:#222;font:13px/1.4 system-ui,sans-serif;padding:6px 12px;display:flex;align-items:center;justify-content:center;box-shadow:0 1px 3px rgba(0,0,0,0.1);";let t=document.createElement("span");t.textContent="ARC PAY TEST MODE \u2014 payments are simulated",e.appendChild(t);let r=document.createElement("button");r.type="button",r.setAttribute("data-arcpay-banner-dismiss",""),r.textContent="\xD7",r.setAttribute("aria-label","Dismiss test mode banner"),r.style.cssText="margin-left:12px;background:transparent;border:0;font-size:18px;cursor:pointer;color:inherit;",r.addEventListener("click",()=>e.remove()),e.appendChild(r),document.body.appendChild(e);};var C="arcpay:",L=e=>typeof e=="object"&&e!==null&&"type"in e&&typeof e.type=="string"&&e.type.startsWith(C),u=(e,t,r)=>{if(r==="*")throw new n({type:"validation_error",code:"wildcard_origin_forbidden",message:"postToIframe: targetOrigin cannot be '*'",retryable:false});if(!e.contentWindow)throw new n({type:"validation_error",code:"iframe_not_loaded",message:"postToIframe: iframe.contentWindow is null (iframe not mounted)",retryable:false});e.contentWindow.postMessage(t,r);};var m=(e,t)=>e.origin!==t||!L(e.data)?null:e.data;var O=new Set(["position","transform","pointer-events","z-index","top","left","right","bottom","inset"]),h=e=>{let t={};for(let[r,o]of Object.entries(e)){let s=r.toLowerCase();O.has(s)||(t[r]=o);}return t},g=e=>{let t={base:h(e.base)};return e.invalid!==void 0&&(t.invalid=h(e.invalid)),e.focus!==void 0&&(t.focus=h(e.focus)),t};var y=class{constructor(t,r,o){this.field=t;this.options=r;this.context=o;this.iframe=null;this.listeners=new Set;this.status="pending";this.messageHandler=null;}mount(t){if(this.iframe)throw new n({type:"validation_error",code:"already_mounted",message:`Element ${this.field} is already mounted`,retryable:false});let r=typeof t=="string"?document.querySelector(t):t;if(!(r instanceof HTMLElement))throw new n({type:"validation_error",code:"mount_target_not_found",message:`mount target not found: ${String(t)}`,retryable:false});let o=document.createElement("iframe");o.src=`${this.context.iframeBase}/iframe/${this.field}`,o.style.cssText="border:0;width:100%;height:100%;display:block;",o.setAttribute("allow","payment"),o.setAttribute("data-arcpay-element",this.field),r.appendChild(o),this.iframe=o;let s=new URL(this.context.iframeBase).origin;this.messageHandler=a=>{var l;if(a.source!==((l=this.iframe)==null?void 0:l.contentWindow))return;let d=m(a,s);d&&this.handleMessage(d);},window.addEventListener("message",this.messageHandler),o.addEventListener("load",()=>{if(!this.iframe)return;let a={type:"arcpay:hello",origin:window.location.origin,publishableKey:this.context.publishableKey,channelId:this.context.channelId};u(this.iframe,a,s);},{once:true});}handleMessage(t){t.type==="arcpay:ready"?(this.status="ready",this.options.style&&this.send({type:"arcpay:style",payload:g(this.options.style)}),this.emit({type:"ready"})):t.type==="arcpay:rejected"?(this.status="error",this.emit({type:"error",reason:t.reason})):t.type==="arcpay:change"&&t.field===this.field&&this.emit({type:"change",isValid:t.isValid,brand:t.brand,lastFour:t.lastFour});}update(t){t.style&&this.send({type:"arcpay:style",payload:g(t.style)});}destroy(){this.iframe&&(this.iframe.remove(),this.iframe=null),this.messageHandler&&(window.removeEventListener("message",this.messageHandler),this.messageHandler=null),this.listeners.clear(),this.status="pending";}on(t,r){return this.listeners.add(r),()=>this.listeners.delete(r)}focus(){this.send({type:"arcpay:focus"});}clear(){this.send({type:"arcpay:clear"});}isReady(){return this.status==="ready"}getIframeContentWindow(){var t,r;return (r=(t=this.iframe)==null?void 0:t.contentWindow)!=null?r:null}send(t){if(!this.iframe)throw new n({type:"validation_error",code:"not_mounted",message:`Element ${this.field} is not mounted`,retryable:false});u(this.iframe,t,new URL(this.context.iframeBase).origin);}emit(t){for(let r of this.listeners)r(t);}};var D="https://sdk.arcpay.space",N=()=>{var e;if(!((e=globalThis.crypto)!=null&&e.randomUUID))throw new n({type:"validation_error",code:"crypto_unavailable",message:"crypto.randomUUID is required for Hosted Fields",retryable:false});return globalThis.crypto.randomUUID()},p=class{constructor(t){this.elementMap=new Map;this.tokenizeInFlight=false;var r;this.publishableKey=t.publishableKey,this.iframeBase=(r=t.iframeBase)!=null?r:D,this.channelId=N();}create(t,r={}){if(this.elementMap.has(t))throw new n({type:"validation_error",code:"duplicate_element",message:`Element for ${t} already created`,retryable:false});let o={iframeBase:this.iframeBase,publishableKey:this.publishableKey,channelId:this.channelId},s=new y(t,r,o);return this.elementMap.set(t,s),s}async tokenize(t,r){if(this.tokenizeInFlight)throw new n({type:"validation_error",code:"tokenize_in_progress",message:"A tokenize() call is already in progress for this Elements instance",retryable:false});let o=this.elementMap.get("cardNumber"),s=this.elementMap.get("cardExpiry"),a=this.elementMap.get("cardCvv");if(!o||!s||!a)throw new n({type:"validation_error",code:"incomplete_elements",message:"All three elements (cardNumber, cardExpiry, cardCvv) must be created and mounted before tokenize()",retryable:false});if(!o.isReady()||!s.isReady()||!a.isReady())throw new n({type:"validation_error",code:"elements_not_ready",message:"Wait for all elements to fire 'ready' event before tokenize()",retryable:false});this.tokenizeInFlight=true;try{return await this.doTokenize(o,t,r)}finally{this.tokenizeInFlight=false;}}doTokenize(t,r,o){let s=new URL(this.iframeBase).origin,a=t.getIframeContentWindow();return new Promise((d,l)=>{let v=window.setTimeout(()=>{window.removeEventListener("message",c),l(new n({type:"network_error",code:"tokenize_timeout",message:"tokenize() timed out after 30 seconds",retryable:true,paymentId:r}));},3e4),c=E=>{if(a!==null&&E.source!==a)return;let i=m(E,s);if(i){if(i.type==="arcpay:tokenize-result")clearTimeout(v),window.removeEventListener("message",c),d({cardTokenId:i.cardTokenId,cardMask:i.cardMask,cardScheme:i.cardScheme,cardBin:i.cardBin,expiresIn:i.expiresIn,expiresAt:i.expiresAt});else if(i.type==="arcpay:tokenize-error"){clearTimeout(v),window.removeEventListener("message",c);let P=i.errorType==="validation_error"||i.errorType==="api_error"?i.errorType:"api_error";l(new n({type:P,code:i.code,message:i.message,retryable:false,paymentId:r}));}}};window.addEventListener("message",c),t.send({type:"arcpay:tokenize",paymentId:r,idempotencyKey:o});})}destroy(){for(let t of this.elementMap.values())t.destroy();this.elementMap.clear();}};var W=w,b=new Map,K=e=>(f(e)==="sandbox"&&_(),{publishableKey:e,environment:f(e),elements:()=>new p({publishableKey:e})});function H(e){try{W(e);}catch(s){return Promise.reject(s)}let t=e,r=b.get(t);if(r)return r;let o=Promise.resolve(K(e));return b.set(t,o),o}var U=()=>{b.clear();},q={load:H,__resetForTests:U};var T=e=>e!=null?e:null,k=e=>({action:e.three_ds.submit.url,method:e.three_ds.submit.method,target:e.three_ds.submit.target,fields:e.three_ds.submit.fields});var ye="0.1.6";
2
+ exports.ArcPay=q;exports.ArcPayError=n;exports.Elements=p;exports.SDK_VERSION=ye;exports.buildThreeDSBrowserForm=k;exports.getThreeDSAction=T;exports.isApiError=R;exports.isAuthenticationError=A;exports.isAuthorizationError=S;exports.isChallengeAborted=M;exports.isNetworkError=B;exports.isRateLimitError=F;exports.isStateError=z;exports.isValidationError=I;return exports;})({});//# sourceMappingURL=arcpay.global.js.map
3
3
  //# sourceMappingURL=arcpay.global.js.map