@payconductor-sdk-web/library-rsc 1.0.4 → 1.0.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
@@ -1,8 +1,8 @@
1
1
  # @payconductor-sdk-web/library-rsc
2
2
 
3
- React Server Components SDK for integrating with PayConductor Payment Gateway. Optimized for Next.js App Router.
3
+ React Server Components SDK para integração com o PayConductor. Otimizado para o Next.js App Router.
4
4
 
5
- ## Installation
5
+ ## Instalação
6
6
 
7
7
  ```bash
8
8
  npm install @payconductor-sdk-web/library-rsc
@@ -10,98 +10,94 @@ npm install @payconductor-sdk-web/library-rsc
10
10
  yarn add @payconductor-sdk-web/library-rsc
11
11
  # or
12
12
  pnpm add @payconductor-sdk-web/library-rsc
13
+ # or
14
+ bun add @payconductor-sdk-web/library-rsc
13
15
  ```
14
16
 
15
- ## Basic Usage with Next.js App Router
17
+ ## Uso com Next.js App Router
16
18
 
17
- ### 1. Create a client component for checkout
19
+ ### 1. Crie um Client Component para o checkout
18
20
 
19
21
  ```tsx
20
22
  // components/CheckoutForm.tsx
21
23
  "use client";
22
24
 
23
25
  import {
24
- useElement,
26
+ PayConductorCheckoutElement,
25
27
  usePayConductor,
28
+ usePayconductorElement,
29
+ type PaymentMethod,
26
30
  type PaymentResult,
27
31
  } from "@payconductor-sdk-web/library-rsc";
28
- import { useState, useEffect } from "react";
32
+ import { useState } from "react";
29
33
 
30
34
  export function CheckoutForm() {
31
35
  const { isReady, error } = usePayConductor();
32
- const { submit, confirmPayment, update } = useElement();
36
+ const { confirmPayment, getSelectedPaymentMethod } = usePayconductorElement();
33
37
 
34
38
  const [errorMessage, setErrorMessage] = useState<string | null>(null);
35
39
  const [isProcessing, setIsProcessing] = useState(false);
36
- const [clientName, setClientName] = useState("");
37
- const [clientEmail, setClientEmail] = useState("");
38
-
39
- useEffect(() => {
40
- update({
41
- billingDetails: {
42
- name: clientName,
43
- email: clientEmail,
44
- },
45
- });
46
- }, [clientName, clientEmail, update]);
47
-
48
- const handleSubmit = async (event: React.FormEvent) => {
49
- event.preventDefault();
50
40
 
41
+ const handleFinalize = async () => {
51
42
  if (!isReady) return;
52
43
 
53
44
  setIsProcessing(true);
54
45
  setErrorMessage(null);
55
46
 
56
47
  try {
57
- const { error: submitError } = await submit();
58
-
59
- if (submitError) {
60
- setErrorMessage(submitError.message || "Validation failed");
61
- setIsProcessing(false);
62
- return;
63
- }
64
-
65
- const result: PaymentResult = await confirmPayment({
66
- intentToken: "pi_xxx_intent_token_xxx",
67
- returnUrl: window.location.href,
48
+ // 1. Crie o pedido Draft no seu backend para obter o orderId
49
+ const response = await fetch("/api/orders", {
50
+ method: "POST",
51
+ headers: { "Content-Type": "application/json" },
52
+ body: JSON.stringify({
53
+ payment: {
54
+ paymentMethod: "Draft",
55
+ availablePaymentMethods: ["CreditCard", "Pix", "BankSlip"],
56
+ },
57
+ }),
68
58
  });
59
+ const { id: orderId } = await response.json();
60
+
61
+ // 2. Confirme o pagamento com o orderId obtido
62
+ const result: PaymentResult = await confirmPayment({ orderId });
69
63
 
70
64
  if (result.status === "succeeded") {
71
- alert("Payment successful!");
65
+ alert("Pagamento realizado com sucesso!");
72
66
  }
73
67
  } catch (err: any) {
74
- setErrorMessage(err.message || "Payment failed");
68
+ setErrorMessage(err.message || "Falha no pagamento");
75
69
  } finally {
76
70
  setIsProcessing(false);
77
71
  }
78
72
  };
79
73
 
74
+ const selectedMethod = getSelectedPaymentMethod();
75
+
80
76
  return (
81
- <form onSubmit={handleSubmit}>
82
- <input
83
- type="text"
84
- placeholder="Full name"
85
- value={clientName}
86
- onChange={(e) => setClientName(e.target.value)}
87
- />
88
- <input
89
- type="email"
90
- placeholder="Email"
91
- value={clientEmail}
92
- onChange={(e) => setClientEmail(e.target.value)}
93
- />
94
- <button type="submit" disabled={!isReady || isProcessing}>
95
- {isProcessing ? "Processing..." : "Pay now"}
77
+ <div>
78
+ {/* O iframe é renderizado aqui */}
79
+ <PayConductorCheckoutElement height="500px" />
80
+
81
+ {selectedMethod && (
82
+ <p>Método selecionado: <strong>{selectedMethod}</strong></p>
83
+ )}
84
+
85
+ <button
86
+ type="button"
87
+ onClick={handleFinalize}
88
+ disabled={!isReady || isProcessing}
89
+ >
90
+ {isProcessing ? "Processando..." : "Finalizar compra"}
96
91
  </button>
92
+
97
93
  {errorMessage && <div>{errorMessage}</div>}
98
- {error && <div>Error: {error}</div>}
99
- </form>
94
+ {error && <div>Erro: {error}</div>}
95
+ </div>
100
96
  );
101
97
  }
102
98
  ```
103
99
 
104
- ### 2. Use in a Server Component page
100
+ ### 2. Use em um Server Component
105
101
 
106
102
  ```tsx
107
103
  // app/checkout/page.tsx
@@ -114,14 +110,13 @@ export default function CheckoutPage() {
114
110
  <h1>Checkout</h1>
115
111
  <PayConductor
116
112
  publicKey="pk_test_123"
117
- intentToken="pi_test_abc123"
113
+ locale="pt-BR"
118
114
  theme={{ primaryColor: "#0066ff" }}
119
- locale="en-US"
120
- height="500px"
121
115
  debug={true}
122
116
  onReady={() => console.log("Ready")}
123
117
  onError={(err) => console.error(err)}
124
118
  onPaymentComplete={(result) => console.log(result)}
119
+ onPaymentMethodSelected={(method) => console.log("Método:", method)}
125
120
  >
126
121
  <CheckoutForm />
127
122
  </PayConductor>
@@ -130,26 +125,24 @@ export default function CheckoutPage() {
130
125
  }
131
126
  ```
132
127
 
133
- ### 3. Passing server-side data
128
+ ### 3. Passando dados do servidor
134
129
 
135
130
  ```tsx
136
131
  // app/checkout/page.tsx
137
132
  import { PayConductor } from "@payconductor-sdk-web/library-rsc";
138
133
  import { CheckoutForm } from "@/components/CheckoutForm";
139
- import { getPaymentIntent } from "@/lib/payconductor";
140
134
 
141
135
  export default async function CheckoutPage() {
142
- // Fetch payment intent from your backend
143
- const { intentToken, amount, currency } = await getPaymentIntent();
144
-
136
+ // Configurações podem vir do servidor — publicKey, theme, locale, etc.
137
+ // O orderId NÃO é passado aqui; ele é obtido no clique de confirmar.
145
138
  return (
146
139
  <main>
147
- <h1>Checkout - {amount} {currency}</h1>
140
+ <h1>Checkout</h1>
148
141
  <PayConductor
149
142
  publicKey={process.env.NEXT_PUBLIC_PAYCONDUCTOR_PUBLIC_KEY!}
150
- intentToken={intentToken}
143
+ locale="pt-BR"
151
144
  theme={{ primaryColor: "#0066ff" }}
152
- locale="en-US"
145
+ paymentMethods={["CreditCard", "Pix", "BankSlip"]}
153
146
  >
154
147
  <CheckoutForm />
155
148
  </PayConductor>
@@ -162,66 +155,79 @@ export default async function CheckoutPage() {
162
155
 
163
156
  ### `<PayConductor />`
164
157
 
165
- Client-side component that initializes the payment iframe. Marked with `"use client"` for RSC compatibility.
158
+ Componente provider que inicializa a sessão de pagamento. Marcado com `"use client"` para compatibilidade com RSC. **Não renderiza o iframe diretamente** — use `<PayConductorCheckoutElement>` dentro do seu Client Component.
166
159
 
167
160
  | Prop | Type | Description |
168
161
  |------|------|-------------|
169
- | `publicKey` | `string` | Your PayConductor public key |
170
- | `intentToken` | `string` | Payment intent token |
171
- | `theme` | `PayConductorTheme` | Theme configuration |
172
- | `locale` | `string` | Locale (e.g., 'en-US', 'pt-BR') |
173
- | `height` | `string` | Iframe height (default: '500px') |
174
- | `debug` | `boolean` | Enable debug mode with prefixed console.log for key events |
175
- | `onReady` | `() => void` | Callback when iframe is ready |
176
- | `onError` | `(error: Error) => void` | Error callback |
177
- | `onPaymentComplete` | `(result: PaymentResult) => void` | Payment complete callback |
162
+ | `publicKey` | `string` | Sua chave pública do PayConductor |
163
+ | `theme` | `PayConductorTheme` | Opções de tema |
164
+ | `locale` | `string` | Localização (ex: `'pt-BR'`, `'en-US'`) |
165
+ | `paymentMethods` | `PaymentMethod[] \| "all"` | Métodos de pagamento disponíveis |
166
+ | `defaultPaymentMethod` | `PaymentMethod` | Método pré-selecionado |
167
+ | `paymentMethodsConfig` | `PaymentMethodConfig[]` | Config por método (parcelas, descontos) |
168
+ | `methodsDirection` | `"vertical" \| "horizontal"` | Direção do layout dos métodos |
169
+ | `showPaymentButtons` | `boolean` | Exibe botões de ação dentro do iframe |
170
+ | `nuPayConfig` | `NuPayData` | Obrigatório quando NuPay estiver disponível |
171
+ | `debug` | `boolean` | Habilita logs detalhados no console |
172
+ | `onReady` | `() => void` | Chamado quando o iframe está pronto |
173
+ | `onError` | `(error: Error) => void` | Chamado em caso de erro |
174
+ | `onPaymentComplete` | `(result: PaymentResult) => void` | Chamado quando o pagamento é concluído |
175
+ | `onPaymentFailed` | `(result: PaymentResult) => void` | Chamado quando o pagamento falha |
176
+ | `onPaymentPending` | `(result: PaymentResult) => void` | Chamado quando o pagamento fica pendente |
177
+ | `onPaymentMethodSelected` | `(method: PaymentMethod) => void` | Chamado quando o usuário seleciona um método |
178
+
179
+ ### `<PayConductorCheckoutElement />`
180
+
181
+ Componente que renderiza o iframe de pagamento. Use somente em Client Components (`"use client"`).
182
+
183
+ | Prop | Type | Description |
184
+ |------|------|-------------|
185
+ | `height` | `string` | Altura do iframe (padrão: `'600px'`) |
178
186
 
179
187
  ### `usePayConductor()`
180
188
 
181
- Hook that returns frame state and configuration. Use only in Client Components.
189
+ Hook que retorna o estado do frame. Use somente em Client Components.
182
190
 
183
191
  ```tsx
184
192
  "use client";
185
-
186
- const { isReady, error, publicKey, intentToken, theme, locale } = usePayConductor();
193
+ const { isReady, error } = usePayConductor();
187
194
  ```
188
195
 
189
196
  | Property | Type | Description |
190
197
  |----------|------|-------------|
191
- | `isReady` | `boolean` | Whether iframe is ready |
192
- | `error` | `string \| null` | Error message if any |
193
- | `publicKey` | `string` | Public key from config |
194
- | `intentToken` | `string` | Intent token from config |
195
- | `theme` | `PayConductorTheme` | Theme from config |
196
- | `locale` | `string` | Locale from config |
198
+ | `isReady` | `boolean` | Se o iframe está pronto |
199
+ | `error` | `string \| null` | Mensagem de erro, se houver |
197
200
 
198
- ### `useElement()`
201
+ ### `usePayconductorElement()`
199
202
 
200
- Hook that provides payment methods. Use only in Client Components.
203
+ Hook que fornece métodos de ação de pagamento. Use somente em Client Components.
201
204
 
202
205
  ```tsx
203
206
  "use client";
204
-
205
207
  const {
206
- submit,
208
+ init,
207
209
  confirmPayment,
208
- update,
209
210
  validate,
210
211
  reset,
212
+ getSelectedPaymentMethod,
211
213
  updateConfig,
212
- updateIntentToken
213
- } = useElement();
214
+ updateorderId,
215
+ update,
216
+ submit,
217
+ } = usePayconductorElement();
214
218
  ```
215
219
 
216
- | Method | Description |
217
- |--------|-------------|
218
- | `submit()` | Submits the form, returns `{ error?, paymentMethod? }` |
219
- | `confirmPayment(options)` | Confirms payment with `{ intentToken, returnUrl? }` |
220
- | `update(options)` | Updates billing details `{ billingDetails?: { name, email, phone, address } }` |
221
- | `validate(data)` | Validates payment data |
222
- | `reset()` | Resets the payment form |
223
- | `updateConfig(config)` | Updates theme, locale, or paymentMethods config |
224
- | `updateIntentToken(token)` | Updates the intent token |
220
+ | Method | Signature | Description |
221
+ |--------|-----------|-------------|
222
+ | `init` | `(config: PayConductorConfig) => Promise<void>` | Envia configuração completa ao iframe |
223
+ | `confirmPayment` | `({ orderId: string }) => Promise<PaymentResult>` | Confirma o pagamento no iframe |
224
+ | `validate` | `(data: unknown) => Promise<boolean>` | Valida os dados do formulário |
225
+ | `reset` | `() => Promise<void>` | Reseta o formulário de pagamento |
226
+ | `getSelectedPaymentMethod` | `() => PaymentMethod \| null` | Retorna o método selecionado pelo usuário |
227
+ | `updateConfig` | `(config: Partial<PayConductorConfig>) => void` | Atualiza tema, locale ou métodos |
228
+ | `updateorderId` | `(orderId: string) => void` | Atualiza o orderId no iframe |
229
+ | `update` | `(options: UpdateOptions) => void` | Atualiza dados de cobrança |
230
+ | `submit` | `() => Promise<SubmitResult>` | Envia o formulário (valida + formata) |
225
231
 
226
232
  ## Theming
227
233
 
@@ -260,35 +266,72 @@ const theme: PayConductorTheme = {
260
266
 
261
267
  ## Types
262
268
 
269
+ ```tsx
270
+ import type {
271
+ PaymentResult,
272
+ PaymentMethod,
273
+ PayConductorTheme,
274
+ PayConductorConfig,
275
+ PaymentConfirmData,
276
+ PixPaymentData,
277
+ CreditCardPaymentData,
278
+ BankSlipPaymentData,
279
+ NuPayPaymentData,
280
+ PicPayPaymentData,
281
+ CardPaymentData,
282
+ BillingDetails,
283
+ } from "@payconductor-sdk-web/library-rsc";
284
+ ```
285
+
263
286
  ```tsx
264
287
  type PaymentResult = {
265
- paymentIntentId: string;
288
+ orderId: string;
266
289
  status: "succeeded" | "pending" | "failed";
267
290
  amount: number;
268
291
  currency: string;
292
+ message?: string;
269
293
  };
270
294
 
271
- type BillingDetails = {
272
- name: string;
273
- email?: string;
274
- phone?: string;
275
- address?: {
276
- line1: string;
277
- line2?: string;
278
- city: string;
279
- state: string;
280
- postalCode: string;
281
- country: string;
282
- };
283
- };
295
+ type PaymentConfirmData =
296
+ | PixPaymentData // { paymentMethod: 'Pix', expirationInSeconds? }
297
+ | CreditCardPaymentData // { paymentMethod: 'CreditCard', card, installments, softDescriptor? }
298
+ | BankSlipPaymentData // { paymentMethod: 'BankSlip', expirationInDays? }
299
+ | NuPayPaymentData // { paymentMethod: 'NuPay', nuPay: NuPayData }
300
+ | PicPayPaymentData; // { paymentMethod: 'PicPay' }
284
301
  ```
285
302
 
286
- ## Differences from @payconductor-sdk-web/library-react
303
+ ## Diferenças do `@payconductor-sdk-web/library-react`
287
304
 
288
- - Optimized for Server Components and Next.js App Router
289
- - `PayConductor` component marked with `"use client"`
290
- - Hooks must only be used in Client Components
291
- - Allows passing server-side data (intentToken, config) directly to the component
305
+ - Otimizado para Server Components e Next.js App Router
306
+ - `PayConductor` é marcado com `"use client"` internamente
307
+ - Hooks e `PayConductorCheckoutElement` devem ser usados somente em Client Components
308
+ - Configurações (publicKey, theme, locale, paymentMethods) podem ser passadas a partir de dados do servidor
309
+ - O `orderId` **não** é uma prop do `<PayConductor>` — ele é obtido via chamada ao backend no momento do clique de confirmar
310
+
311
+ ## Fluxo Completo
312
+
313
+ ```
314
+ 1. Server Component renderiza <PayConductor publicKey="pk_xxx" ...>
315
+ └─ Registra window.PayConductor, guarda iframeUrl
316
+
317
+ 2. Client Component renderiza <PayConductorCheckoutElement />
318
+ └─ Lê iframeUrl, registra o iframe em window.PayConductor.frame.iframe
319
+ └─ Renderiza o iframe
320
+
321
+ 3. iframe carrega → busca métodos de pagamento → envia Ready
322
+ SDK recebe Ready → envia config (theme, locale, paymentMethods)
323
+
324
+ 4. Usuário seleciona método de pagamento
325
+ └─ onPaymentMethodSelected é chamado
326
+ └─ getSelectedPaymentMethod() retorna o método
327
+
328
+ 5. Usuário clica em "Finalizar" (botão do merchant, fora do iframe)
329
+ └─ Backend cria pedido Draft → retorna { id: "ord_xxx" }
330
+ └─ confirmPayment({ orderId: "ord_xxx" })
331
+ └─ iframe coleta dados → POST /orders/:id/confirm
332
+
333
+ 6. SDK recebe PaymentComplete/Failed/Pending → callbacks disparam
334
+ ```
292
335
 
293
336
  ## License
294
337
 
package/dist/index.cjs.js CHANGED
@@ -1,2 +1,2 @@
1
- "use client";"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const L=require("react/jsx-runtime"),m=require("react"),D="https://iframe.payconductor.ai/v1",U="http://localhost:5175",B=3e4,W="600px";var I=(e=>(e.Init="Init",e.Config="Config",e.Update="Update",e.ConfirmPayment="ConfirmPayment",e.Validate="Validate",e.Reset="Reset",e))(I||{}),h=(e=>(e.Ready="Ready",e.Error="Error",e.PaymentComplete="PaymentComplete",e.PaymentFailed="PaymentFailed",e.PaymentPending="PaymentPending",e.ValidationError="ValidationError",e.PaymentMethodSelected="PaymentMethodSelected",e))(h||{});const Q=typeof window<"u"&&(window.location.hostname==="localhost"||window.location.hostname==="127.0.0.1"),O=Q?U:D,b=[U,D],v=W,F=B,s={INIT:I.Init,CONFIG:I.Config,UPDATE:I.Update,CONFIRM_PAYMENT:I.ConfirmPayment,VALIDATE:I.Validate,RESET:I.Reset,READY:h.Ready,ERROR:h.Error,PAYMENT_COMPLETE:h.PaymentComplete,PAYMENT_FAILED:h.PaymentFailed,PAYMENT_PENDING:h.PaymentPending,VALIDATION_ERROR:h.ValidationError,PAYMENT_METHOD_SELECTED:h.PaymentMethodSelected},$={INVALID_CLIENT:"InvalidClient",INVALID_TOKEN:"InvalidToken",NETWORK_ERROR:"NetworkError",IFRAME_NOT_READY:"IframeNotReady",PAYMENT_DECLINED:"PaymentDeclined",VALIDATION_ERROR:"ValidationError",TIMEOUT:"Timeout"};function k(e){const n=new URLSearchParams({publicKey:e.publicKey});return`${O}?${n.toString()}`}function K(){return crypto.randomUUID()}function V(e,n){return n.includes(e)}function S(){return new Map}function T(e,n,o,t){return new Promise((i,f)=>{if(!e||!("contentWindow"in e)){f(new Error("Iframe not defined"));return}if(!(e!=null&&e.contentWindow)){f(new Error("Iframe not ready"));return}if(!n){f(new Error("Pending requests not initialized"));return}const l=K();n.set(l,{resolve:i,reject:f}),e.contentWindow.postMessage({type:o,data:t,requestId:l},"*"),setTimeout(()=>{n!=null&&n.has(l)&&(n.delete(l),f(new Error("Request timeout")))},F)})}function g(e,n,o){return T(e,n,s.CONFIRM_PAYMENT,{intentToken:o.intentToken})}function J(e,n,o){return T(e,n,s.VALIDATE,o)}function X(e,n){return T(e,n,s.RESET)}function Z(e,n,o){return T(e,n,s.CONFIG,o)}function x(e,n,o){return T(e,n,s.INIT,o)}function p(e,n,o,t,i,f,l,C,R,E){if(!V(e.origin,b))return;const N=e.data,{requestId:w,type:P,data:u,error:y}=N;if(w&&(n!=null&&n.has(w))){const{resolve:d,reject:M}=n.get(w);n.delete(w),y?M(new Error(String(y.message))):d(u);return}if(P===s.READY){o(!0),i==null||i();return}if(P===s.ERROR){t((y==null?void 0:y.message)||"Unknown error"),f==null||f(new Error(String(y==null?void 0:y.message)));return}if(P===s.PAYMENT_COMPLETE){u&&typeof u=="object"&&"status"in u&&(l==null||l(u));return}if(P===s.PAYMENT_FAILED){u&&typeof u=="object"&&"status"in u&&(C==null||C(u));return}if(P===s.PAYMENT_PENDING){u&&typeof u=="object"&&"status"in u&&(R==null||R(u));return}if(P===s.PAYMENT_METHOD_SELECTED){u&&typeof u=="object"&&"paymentMethod"in u&&(E==null||E(u.paymentMethod));return}}function Y(e){const[n,o]=m.useState(()=>!1),[t,i]=m.useState(()=>!1),[f,l]=m.useState(()=>null),[C,R]=m.useState(()=>""),[E,N]=m.useState(()=>null),[w,P]=m.useState(()=>null),[u,y]=m.useState(()=>!1);return m.useEffect(()=>{const d=(...r)=>{e.debug&&console.log("[PayConductor]",...r)};d("SDK initializing",{publicKey:e.publicKey});const M=k({publicKey:e.publicKey});R(M),o(!0),N(S()),d("iframeUrl built:",M),d("pendingMap created");const _=()=>{var a,c;const r=(c=(a=window.PayConductor)==null?void 0:a.frame)==null?void 0:c.iframe;if(r){if(r instanceof HTMLIFrameElement)return r;if(typeof r=="object"&&r!==null){if("current"in r)return r.current??void 0;if("value"in r)return r.value??void 0}return r}},G={iframe:null,iframeUrl:M,get isReady(){return t},get error(){return f}},H={publicKey:e.publicKey,theme:e.theme,locale:e.locale,paymentMethods:e.paymentMethods,defaultPaymentMethod:e.defaultPaymentMethod},z={confirmPayment:r=>(d("confirmPayment called",{intentToken:r.intentToken}),g(_(),E,r)),validate:r=>(d("validate called",r),J(_(),E,r)),reset:()=>(d("reset called"),X(_(),E)),getSelectedPaymentMethod:()=>w};window.PayConductor={frame:G,config:H,api:z,selectedPaymentMethod:w},d("window.PayConductor registered");const q=async()=>{if(!u){const r=_();if(!r){d("sendConfigToIframe: iframe not found, skipping");return}y(!0),d("sendConfig →",{theme:e.theme,locale:e.locale,paymentMethods:e.paymentMethods,defaultPaymentMethod:e.defaultPaymentMethod,showPaymentButtons:e.showPaymentButtons}),Z(r,E,{theme:e.theme,locale:e.locale,paymentMethods:e.paymentMethods,defaultPaymentMethod:e.defaultPaymentMethod,showPaymentButtons:e.showPaymentButtons,nuPayConfig:e.nuPayConfig})}},j=r=>{p(r,E,a=>{i(a),a&&(d("iframe Ready — sending config"),q())},a=>{l(a),d("iframe Error:",a)},()=>{var a;d("onReady fired"),(a=e.onReady)==null||a.call(e)},a=>{var c;d("onError fired:",a),(c=e.onError)==null||c.call(e,a)},a=>{var c;d("PaymentComplete:",a),(c=e.onPaymentComplete)==null||c.call(e,a)},a=>{var c;d("PaymentFailed:",a),(c=e.onPaymentFailed)==null||c.call(e,a)},a=>{var c;d("PaymentPending:",a),(c=e.onPaymentPending)==null||c.call(e,a)},a=>{var c;d("PaymentMethodSelected:",a),P(a),window.PayConductor&&(window.PayConductor.selectedPaymentMethod=a),(c=e.onPaymentMethodSelected)==null||c.call(e,a)})};window.addEventListener("message",j),d("SDK initialized — waiting for PayConductorCheckoutElement")},[]),L.jsx("div",{className:"payconductor",id:"payconductor",style:{display:"contents"},children:e.children})}function ee(e){const n=m.useRef(null),[o,t]=m.useState(()=>""),[i,f]=m.useState(()=>!1);return m.useEffect(()=>{const l=typeof window<"u"?window.PayConductor:null;l||console.warn("[PayConductorCheckoutElement] window.PayConductor not found — ensure <PayConductor> is mounted before <PayConductorCheckoutElement>"),l!=null&&l.frame&&(t(l.frame.iframeUrl||""),l.frame.iframe=n.current,console.log("[PayConductorCheckoutElement] iframe registered, src:",o)),f(!0)},[]),L.jsx("div",{className:"payconductor-element",style:{width:"100%"},children:i&&o?L.jsx("iframe",{allow:"payment",title:"PayConductor",ref:n,src:o,style:{width:"100%",height:e.height||v,border:"none"}}):null})}function te(){const e=typeof window<"u"?window.PayConductor:null,n=e!=null&&e.config?{publicKey:e.config.publicKey,intentToken:e.config.intentToken,theme:e.config.theme,locale:e.config.locale}:{},o=e!=null&&e.frame?{iframe:e.frame.iframe,isReady:e.frame.isReady,error:e.frame.error}:{iframe:null,isReady:!1,error:null};return{...n,...o}}function A(e){var o;if(!((o=e==null?void 0:e.frame)!=null&&o.iframe))return null;const n=e.frame.iframe;if(n instanceof HTMLIFrameElement)return n;if(n&&typeof n=="object"&&"value"in n){const t=n.value;if(t instanceof HTMLIFrameElement)return t}return null}function ne(){const e=typeof window<"u"?window.PayConductor:null,n=(o,t)=>{if(!e)return;const i=A(e);i!=null&&i.contentWindow&&i.contentWindow.postMessage({type:o,data:t},"*")};return e?{init:async o=>{const t=A(e),i=S();return x(t||void 0,i,o)},confirmPayment:async o=>{const t=A(e),i=S();if(!o.intentToken)throw new Error("Intent token is required");return g(t||void 0,i,o)},validate:e.api.validate,reset:e.api.reset,getSelectedPaymentMethod:()=>(e==null?void 0:e.selectedPaymentMethod)??null,updateConfig:o=>{const t=e.config;n(s.CONFIG,{publicKey:t==null?void 0:t.publicKey,intentToken:t==null?void 0:t.intentToken,theme:o.theme??(t==null?void 0:t.theme),locale:o.locale??(t==null?void 0:t.locale),paymentMethods:o.paymentMethods??(t==null?void 0:t.paymentMethods)})},updateIntentToken:o=>{const t=e.config;n(s.CONFIG,{publicKey:t==null?void 0:t.publicKey,intentToken:o,theme:t==null?void 0:t.theme,locale:t==null?void 0:t.locale,paymentMethods:t==null?void 0:t.paymentMethods})},update:o=>{n(s.UPDATE,o)},submit:async()=>{const o=A(e),t=S();try{return await T(o||void 0,t,s.CONFIRM_PAYMENT,{}),{paymentMethod:void 0}}catch(i){return{error:{message:i instanceof Error?i.message:"Payment failed",code:"payment_error",type:"payment_error"}}}}}:{init:async()=>{throw new Error("PayConductor not initialized")},confirmPayment:async()=>{throw new Error("PayConductor not initialized")},validate:async()=>{throw new Error("PayConductor not initialized")},reset:async()=>{throw new Error("PayConductor not initialized")},getSelectedPaymentMethod:()=>null,updateConfig:()=>{throw new Error("PayConductor not initialized")},updateIntentToken:()=>{throw new Error("PayConductor not initialized")},update:()=>{throw new Error("PayConductor not initialized")},submit:async()=>{throw new Error("PayConductor not initialized")}}}exports.ALLOWED_ORIGINS=b;exports.ERROR_CODES=$;exports.IFRAME_BASE_URL=O;exports.IFRAME_DEFAULT_HEIGHT_VALUE=v;exports.POST_MESSAGES=s;exports.PayConductor=Y;exports.PayConductorCheckoutElement=ee;exports.REQUEST_TIMEOUT=F;exports.buildIframeUrl=k;exports.default=Y;exports.generateRequestId=K;exports.isValidOrigin=V;exports.usePayConductor=te;exports.usePayconductorElement=ne;
1
+ "use client";"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const D=require("react/jsx-runtime"),m=require("react"),L="https://iframe.payconductor.ai/v1",O="http://localhost:5175",j=3e4,B="600px";var w=(e=>(e.Init="Init",e.Config="Config",e.Update="Update",e.ConfirmPayment="ConfirmPayment",e.Validate="Validate",e.Reset="Reset",e))(w||{}),I=(e=>(e.Ready="Ready",e.Error="Error",e.PaymentComplete="PaymentComplete",e.PaymentFailed="PaymentFailed",e.PaymentPending="PaymentPending",e.ValidationError="ValidationError",e.PaymentMethodSelected="PaymentMethodSelected",e))(I||{});const Q=typeof window<"u"&&(window.location.hostname==="localhost"||window.location.hostname==="127.0.0.1"),U=Q?O:L,b=[O,L],v=B,F=j,s={INIT:w.Init,CONFIG:w.Config,UPDATE:w.Update,CONFIRM_PAYMENT:w.ConfirmPayment,VALIDATE:w.Validate,RESET:w.Reset,READY:I.Ready,ERROR:I.Error,PAYMENT_COMPLETE:I.PaymentComplete,PAYMENT_FAILED:I.PaymentFailed,PAYMENT_PENDING:I.PaymentPending,VALIDATION_ERROR:I.ValidationError,PAYMENT_METHOD_SELECTED:I.PaymentMethodSelected},$={INVALID_CLIENT:"InvalidClient",INVALID_TOKEN:"InvalidToken",NETWORK_ERROR:"NetworkError",IFRAME_NOT_READY:"IframeNotReady",PAYMENT_DECLINED:"PaymentDeclined",VALIDATION_ERROR:"ValidationError",TIMEOUT:"Timeout"};function K(e){const n=new URLSearchParams({publicKey:e.publicKey});return`${U}?${n.toString()}`}function V(){return crypto.randomUUID()}function g(e,n){return n.includes(e)}function S(){return new Map}function R(e,n,r,t){return new Promise((i,f)=>{if(!e||!("contentWindow"in e)){f(new Error("Iframe not defined"));return}if(!(e!=null&&e.contentWindow)){f(new Error("Iframe not ready"));return}if(!n){f(new Error("Pending requests not initialized"));return}const c=V();n.set(c,{resolve:i,reject:f}),e.contentWindow.postMessage({type:r,data:t,requestId:c},"*"),setTimeout(()=>{n!=null&&n.has(c)&&(n.delete(c),f(new Error("Request timeout")))},F)})}function Y(e,n,r){return R(e,n,s.CONFIRM_PAYMENT,{orderId:r.orderId})}function J(e,n,r){return R(e,n,s.VALIDATE,r)}function X(e,n){return R(e,n,s.RESET)}function Z(e,n,r){return R(e,n,s.CONFIG,r)}function x(e,n,r){return R(e,n,s.INIT,r)}function p(e,n,r,t,i,f,c,C,T,E){if(!g(e.origin,b))return;const N=e.data,{requestId:h,type:P,data:u,error:y}=N;if(h&&(n!=null&&n.has(h))){const{resolve:d,reject:M}=n.get(h);n.delete(h),y?M(new Error(String(y.message))):d(u);return}if(P===s.READY){r(!0),i==null||i();return}if(P===s.ERROR){t((y==null?void 0:y.message)||"Unknown error"),f==null||f(new Error(String(y==null?void 0:y.message)));return}if(P===s.PAYMENT_COMPLETE){u&&typeof u=="object"&&"status"in u&&(c==null||c(u));return}if(P===s.PAYMENT_FAILED){u&&typeof u=="object"&&"status"in u&&(C==null||C(u));return}if(P===s.PAYMENT_PENDING){u&&typeof u=="object"&&"status"in u&&(T==null||T(u));return}if(P===s.PAYMENT_METHOD_SELECTED){u&&typeof u=="object"&&"paymentMethod"in u&&(E==null||E(u.paymentMethod));return}}function G(e){const[n,r]=m.useState(()=>!1),[t,i]=m.useState(()=>!1),[f,c]=m.useState(()=>null),[C,T]=m.useState(()=>""),[E,N]=m.useState(()=>null),[h,P]=m.useState(()=>null),[u,y]=m.useState(()=>!1);return m.useEffect(()=>{const d=(...a)=>{e.debug&&console.log("[PayConductor]",...a)};d("SDK initializing",{publicKey:e.publicKey});const M=K({publicKey:e.publicKey});T(M),r(!0),N(S()),d("iframeUrl built:",M),d("pendingMap created");const _=()=>{var o,l;const a=(l=(o=window.PayConductor)==null?void 0:o.frame)==null?void 0:l.iframe;if(a){if(a instanceof HTMLIFrameElement)return a;if(typeof a=="object"&&a!==null){if("current"in a)return a.current??void 0;if("value"in a)return a.value??void 0}return a}},H={iframe:null,iframeUrl:M,get isReady(){return t},get error(){return f}},z={publicKey:e.publicKey,theme:e.theme,locale:e.locale,paymentMethods:e.paymentMethods,defaultPaymentMethod:e.defaultPaymentMethod},k={confirmPayment:a=>(d("confirmPayment called",{orderId:a.orderId}),Y(_(),E,a)),validate:a=>(d("validate called",a),J(_(),E,a)),reset:()=>(d("reset called"),X(_(),E)),getSelectedPaymentMethod:()=>h};window.PayConductor={frame:H,config:z,api:k,selectedPaymentMethod:h},d("window.PayConductor registered");const q=async()=>{if(!u){const a=_();if(!a){d("sendConfigToIframe: iframe not found, skipping");return}y(!0),d("sendConfig →",{theme:e.theme,locale:e.locale,paymentMethods:e.paymentMethods,defaultPaymentMethod:e.defaultPaymentMethod,showPaymentButtons:e.showPaymentButtons}),Z(a,E,{theme:e.theme,locale:e.locale,paymentMethods:e.paymentMethods,defaultPaymentMethod:e.defaultPaymentMethod,showPaymentButtons:e.showPaymentButtons,nuPayConfig:e.nuPayConfig})}},W=a=>{p(a,E,o=>{i(o),o&&(d("iframe Ready — sending config"),q())},o=>{c(o),d("iframe Error:",o)},()=>{var o;d("onReady fired"),(o=e.onReady)==null||o.call(e)},o=>{var l;d("onError fired:",o),(l=e.onError)==null||l.call(e,o)},o=>{var l;d("PaymentComplete:",o),(l=e.onPaymentComplete)==null||l.call(e,o)},o=>{var l;d("PaymentFailed:",o),(l=e.onPaymentFailed)==null||l.call(e,o)},o=>{var l;d("PaymentPending:",o),(l=e.onPaymentPending)==null||l.call(e,o)},o=>{var l;d("PaymentMethodSelected:",o),P(o),window.PayConductor&&(window.PayConductor.selectedPaymentMethod=o),(l=e.onPaymentMethodSelected)==null||l.call(e,o)})};window.addEventListener("message",W),d("SDK initialized — waiting for PayConductorCheckoutElement")},[]),D.jsx("div",{className:"payconductor",id:"payconductor",style:{display:"contents"},children:e.children})}function ee(e){const n=m.useRef(null),[r,t]=m.useState(()=>""),[i,f]=m.useState(()=>!1);return m.useEffect(()=>{const c=typeof window<"u"?window.PayConductor:null;c||console.warn("[PayConductorCheckoutElement] window.PayConductor not found — ensure <PayConductor> is mounted before <PayConductorCheckoutElement>"),c!=null&&c.frame&&(t(c.frame.iframeUrl||""),c.frame.iframe=n.current,console.log("[PayConductorCheckoutElement] iframe registered, src:",r)),f(!0)},[]),D.jsx("div",{className:"payconductor-element",style:{width:"100%"},children:i&&r&&n.current&&"contentWindow"in n.current?D.jsx("iframe",{allow:"payment",title:"PayConductor",ref:n,src:r,style:{width:"100%",height:e.height||v,border:"none"}}):null})}function te(){const e=typeof window<"u"?window.PayConductor:null,n=e!=null&&e.config?{publicKey:e.config.publicKey,orderId:e.config.orderId,theme:e.config.theme,locale:e.config.locale}:{},r=e!=null&&e.frame?{iframe:e.frame.iframe,isReady:e.frame.isReady,error:e.frame.error}:{iframe:null,isReady:!1,error:null};return{...n,...r}}function A(e){var r;if(!((r=e==null?void 0:e.frame)!=null&&r.iframe))return null;const n=e.frame.iframe;if(n instanceof HTMLIFrameElement)return n;if(n&&typeof n=="object"&&"value"in n){const t=n.value;if(t instanceof HTMLIFrameElement)return t}return null}function ne(){const e=typeof window<"u"?window.PayConductor:null,n=(r,t)=>{if(!e)return;const i=A(e);i!=null&&i.contentWindow&&i.contentWindow.postMessage({type:r,data:t},"*")};return e?{init:async r=>{const t=A(e),i=S();return x(t||void 0,i,r)},confirmPayment:async r=>{const t=A(e),i=S();if(!r.orderId)throw new Error("Order ID is required");return Y(t||void 0,i,r)},validate:e.api.validate,reset:e.api.reset,getSelectedPaymentMethod:()=>(e==null?void 0:e.selectedPaymentMethod)??null,updateConfig:r=>{const t=e.config;n(s.CONFIG,{publicKey:t==null?void 0:t.publicKey,orderId:t==null?void 0:t.orderId,theme:r.theme??(t==null?void 0:t.theme),locale:r.locale??(t==null?void 0:t.locale),paymentMethods:r.paymentMethods??(t==null?void 0:t.paymentMethods)})},updateorderId:r=>{const t=e.config;n(s.CONFIG,{publicKey:t==null?void 0:t.publicKey,orderId:r,theme:t==null?void 0:t.theme,locale:t==null?void 0:t.locale,paymentMethods:t==null?void 0:t.paymentMethods})},update:r=>{n(s.UPDATE,r)},submit:async()=>{const r=A(e),t=S();try{return await R(r||void 0,t,s.CONFIRM_PAYMENT,{}),{paymentMethod:void 0}}catch(i){return{error:{message:i instanceof Error?i.message:"Payment failed",code:"payment_error",type:"payment_error"}}}}}:{init:async()=>{throw new Error("PayConductor not initialized")},confirmPayment:async()=>{throw new Error("PayConductor not initialized")},validate:async()=>{throw new Error("PayConductor not initialized")},reset:async()=>{throw new Error("PayConductor not initialized")},getSelectedPaymentMethod:()=>null,updateConfig:()=>{throw new Error("PayConductor not initialized")},updateorderId:()=>{throw new Error("PayConductor not initialized")},update:()=>{throw new Error("PayConductor not initialized")},submit:async()=>{throw new Error("PayConductor not initialized")}}}exports.ALLOWED_ORIGINS=b;exports.ERROR_CODES=$;exports.IFRAME_BASE_URL=U;exports.IFRAME_DEFAULT_HEIGHT_VALUE=v;exports.POST_MESSAGES=s;exports.PayConductor=G;exports.PayConductorCheckoutElement=ee;exports.REQUEST_TIMEOUT=F;exports.buildIframeUrl=K;exports.default=G;exports.generateRequestId=V;exports.isValidOrigin=g;exports.usePayConductor=te;exports.usePayconductorElement=ne;
2
2
  //# sourceMappingURL=index.cjs.js.map