@bcc-code/payment-client 1.0.1 → 1.0.2
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 +329 -2
- package/dist/components/index.js +1 -0
- package/dist/components/index.mjs +286 -0
- package/dist/index.d.mts +24 -1
- package/dist/index.d.ts +24 -1
- package/dist/styles/adyen.css +1 -0
- package/dist/styles/index.js +1 -0
- package/dist/styles/index.mjs +1 -0
- package/package.json +26 -6
- package/src/client/PaymentClient.ts +0 -117
- package/src/client/PaymentClientOptions.ts +0 -10
- package/src/client/index.ts +0 -6
- package/src/index.ts +0 -7
- package/src/types/index.ts +0 -5
- package/src/types/payment.ts +0 -99
- package/tsconfig.json +0 -26
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @bcc-code/payment-client
|
|
2
2
|
|
|
3
|
-
Client SDK for BCC Payment Orchestrator API
|
|
3
|
+
Client SDK for BCC Payment Orchestrator API with Vue 3 payment components.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -10,7 +10,29 @@ pnpm add @bcc-code/payment-client
|
|
|
10
10
|
npm install @bcc-code/payment-client
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
### Peer Dependencies
|
|
14
|
+
|
|
15
|
+
This package requires the following peer dependencies. Install them based on which payment providers you use:
|
|
16
|
+
|
|
17
|
+
**Required:**
|
|
18
|
+
- `vue` ^3.0.0
|
|
19
|
+
|
|
20
|
+
**For Stripe payments:**
|
|
21
|
+
```bash
|
|
22
|
+
pnpm add @stripe/stripe-js@^3.0.0
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
**For Adyen payments:**
|
|
26
|
+
```bash
|
|
27
|
+
pnpm add @adyen/adyen-web@^6.0.0
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
**Install all at once:**
|
|
31
|
+
```bash
|
|
32
|
+
pnpm add @bcc-code/payment-client vue@^3.0.0 @stripe/stripe-js@^3.0.0 @adyen/adyen-web@^6.0.0
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## API Client Usage
|
|
14
36
|
|
|
15
37
|
```typescript
|
|
16
38
|
import { PaymentClient } from '@bcc-code/payment-client'
|
|
@@ -46,6 +68,311 @@ const status = await client.getPayment(payment.paymentId)
|
|
|
46
68
|
const receipt = await client.getReceipt(payment.paymentId)
|
|
47
69
|
```
|
|
48
70
|
|
|
71
|
+
## Vue Components Usage
|
|
72
|
+
|
|
73
|
+
The SDK includes pre-built Vue 3 components for Stripe and Adyen payments.
|
|
74
|
+
|
|
75
|
+
### Import CSS (Required for Adyen)
|
|
76
|
+
|
|
77
|
+
If you're using Adyen payments, import the CSS file:
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
import '@bcc-code/payment-client/styles/adyen.css'
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Stripe Payment Component
|
|
84
|
+
|
|
85
|
+
```vue
|
|
86
|
+
<template>
|
|
87
|
+
<StripePayment
|
|
88
|
+
:payment-id="payment.paymentId"
|
|
89
|
+
:client-data="payment.clientData"
|
|
90
|
+
:amount="99.99"
|
|
91
|
+
currency="EUR"
|
|
92
|
+
:publishable-key="stripePublishableKey"
|
|
93
|
+
:return-url="returnUrl"
|
|
94
|
+
@success="handleSuccess"
|
|
95
|
+
@error="handleError"
|
|
96
|
+
@ready="handleReady"
|
|
97
|
+
/>
|
|
98
|
+
</template>
|
|
99
|
+
|
|
100
|
+
<script setup lang="ts">
|
|
101
|
+
import { PaymentClient } from '@bcc-code/payment-client'
|
|
102
|
+
import { StripePayment } from '@bcc-code/payment-client/components'
|
|
103
|
+
|
|
104
|
+
const paymentClient = new PaymentClient({
|
|
105
|
+
baseUrl: 'http://localhost:3200',
|
|
106
|
+
tenantId: 'your-tenant-uuid',
|
|
107
|
+
getAuthToken: async () => getBccAuthToken()
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
const payment = await paymentClient.createPayment({
|
|
111
|
+
amount: 99.99,
|
|
112
|
+
currency: 'EUR',
|
|
113
|
+
paymentMethodType: 'stripe',
|
|
114
|
+
returnUrl: 'https://yourapp.com/success'
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
const stripePublishableKey = 'pk_test_...' // Your Stripe publishable key
|
|
118
|
+
const returnUrl = 'https://yourapp.com/payment/success'
|
|
119
|
+
|
|
120
|
+
const handleSuccess = (result: any) => {
|
|
121
|
+
console.log('Payment succeeded:', result)
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const handleError = (error: any) => {
|
|
125
|
+
console.error('Payment error:', error)
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const handleReady = () => {
|
|
129
|
+
console.log('Payment form ready')
|
|
130
|
+
}
|
|
131
|
+
</script>
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Adyen Payment Component
|
|
135
|
+
|
|
136
|
+
```vue
|
|
137
|
+
<template>
|
|
138
|
+
<AdyenPayment
|
|
139
|
+
:payment-id="payment.paymentId"
|
|
140
|
+
:client-data="payment.clientData"
|
|
141
|
+
:client-key="adyenClientKey"
|
|
142
|
+
:amount="99.99"
|
|
143
|
+
currency="EUR"
|
|
144
|
+
@success="handleSuccess"
|
|
145
|
+
@error="handleError"
|
|
146
|
+
@ready="handleReady"
|
|
147
|
+
/>
|
|
148
|
+
</template>
|
|
149
|
+
|
|
150
|
+
<script setup lang="ts">
|
|
151
|
+
import '@bcc-code/payment-client/styles/adyen.css'
|
|
152
|
+
import { PaymentClient } from '@bcc-code/payment-client'
|
|
153
|
+
import { AdyenPayment } from '@bcc-code/payment-client/components'
|
|
154
|
+
|
|
155
|
+
const paymentClient = new PaymentClient({
|
|
156
|
+
baseUrl: 'http://localhost:3200',
|
|
157
|
+
tenantId: 'your-tenant-uuid',
|
|
158
|
+
getAuthToken: async () => getBccAuthToken()
|
|
159
|
+
})
|
|
160
|
+
|
|
161
|
+
const payment = await paymentClient.createPayment({
|
|
162
|
+
amount: 99.99,
|
|
163
|
+
currency: 'EUR',
|
|
164
|
+
paymentMethodType: 'adyen',
|
|
165
|
+
returnUrl: 'https://yourapp.com/success'
|
|
166
|
+
})
|
|
167
|
+
|
|
168
|
+
const adyenClientKey = payment.clientKey || 'test_...' // From payment response
|
|
169
|
+
|
|
170
|
+
const handleSuccess = (result: any) => {
|
|
171
|
+
console.log('Payment succeeded:', result)
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
const handleError = (error: any) => {
|
|
175
|
+
console.error('Payment error:', error)
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
const handleReady = () => {
|
|
179
|
+
console.log('Payment form ready')
|
|
180
|
+
}
|
|
181
|
+
</script>
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### Component Props
|
|
185
|
+
|
|
186
|
+
#### StripePayment Props
|
|
187
|
+
|
|
188
|
+
- `paymentId` (string, required) - Payment ID from CreatePaymentResponse
|
|
189
|
+
- `clientData` (string, optional) - Client data from CreatePaymentResponse
|
|
190
|
+
- `clientKey` (string, optional) - Client key (alternative to publishableKey)
|
|
191
|
+
- `amount` (number, required) - Payment amount
|
|
192
|
+
- `currency` (string, required) - Currency code (EUR, USD, etc.)
|
|
193
|
+
- `publishableKey` (string, optional) - Stripe publishable key
|
|
194
|
+
- `appearance` (object, optional) - Stripe Elements appearance configuration
|
|
195
|
+
- `showPayButton` (boolean, default: true) - Show payment button
|
|
196
|
+
- `locale` (string, default: 'en') - Locale for Stripe Elements
|
|
197
|
+
- `loader` ('auto' | 'always' | 'never', default: 'auto') - Loading indicator
|
|
198
|
+
- `returnUrl` (string, optional) - Return URL after payment
|
|
199
|
+
|
|
200
|
+
#### AdyenPayment Props
|
|
201
|
+
|
|
202
|
+
- `paymentId` (string, required) - Payment ID from CreatePaymentResponse
|
|
203
|
+
- `clientData` (string, optional) - Client data from CreatePaymentResponse (contains session data)
|
|
204
|
+
- `clientKey` (string, required) - Adyen client key
|
|
205
|
+
- `amount` (number, optional) - Payment amount
|
|
206
|
+
- `currency` (string, optional) - Currency code
|
|
207
|
+
- `paymentData` (any, optional) - Additional payment data
|
|
208
|
+
- `onCancel` (function, optional) - Cancel callback
|
|
209
|
+
|
|
210
|
+
### Component Events
|
|
211
|
+
|
|
212
|
+
Both components emit the following events:
|
|
213
|
+
|
|
214
|
+
- `@success` - Payment completed successfully
|
|
215
|
+
- `@error` - Payment error occurred
|
|
216
|
+
- `@ready` - Payment form is ready
|
|
217
|
+
- `@submit` - Payment submitted (Stripe only)
|
|
218
|
+
- `@additionalDetails` - Additional details required (Adyen only)
|
|
219
|
+
|
|
220
|
+
### Tree-shaking
|
|
221
|
+
|
|
222
|
+
You can import only the components you need:
|
|
223
|
+
|
|
224
|
+
```typescript
|
|
225
|
+
// Import only Stripe component
|
|
226
|
+
import { StripePayment } from '@bcc-code/payment-client/components'
|
|
227
|
+
|
|
228
|
+
// Import only Adyen component
|
|
229
|
+
import { AdyenPayment } from '@bcc-code/payment-client/components'
|
|
230
|
+
|
|
231
|
+
// Import both
|
|
232
|
+
import { StripePayment, AdyenPayment } from '@bcc-code/payment-client/components'
|
|
233
|
+
|
|
234
|
+
// Note: Components must be imported from the '/components' entry point
|
|
235
|
+
// The main entry point only exports the API client and types
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
## TypeScript Types
|
|
239
|
+
|
|
240
|
+
```typescript
|
|
241
|
+
import type {
|
|
242
|
+
PaymentClient,
|
|
243
|
+
PaymentClientOptions,
|
|
244
|
+
CreatePaymentRequest,
|
|
245
|
+
CreatePaymentResponse,
|
|
246
|
+
PaymentResponse,
|
|
247
|
+
StripePaymentProps,
|
|
248
|
+
AdyenPaymentProps
|
|
249
|
+
} from '@bcc-code/payment-client'
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
## Examples
|
|
253
|
+
|
|
254
|
+
### Complete Payment Flow
|
|
255
|
+
|
|
256
|
+
```vue
|
|
257
|
+
<template>
|
|
258
|
+
<div>
|
|
259
|
+
<div v-if="loading">Creating payment...</div>
|
|
260
|
+
<div v-else-if="error">{{ error }}</div>
|
|
261
|
+
<StripePayment
|
|
262
|
+
v-else-if="payment && provider === 'stripe'"
|
|
263
|
+
:payment-id="payment.paymentId"
|
|
264
|
+
:client-data="payment.clientData"
|
|
265
|
+
:amount="amount"
|
|
266
|
+
:currency="currency"
|
|
267
|
+
:publishable-key="stripePublishableKey"
|
|
268
|
+
@success="handlePaymentSuccess"
|
|
269
|
+
@error="handlePaymentError"
|
|
270
|
+
/>
|
|
271
|
+
<AdyenPayment
|
|
272
|
+
v-else-if="payment && provider === 'adyen'"
|
|
273
|
+
:payment-id="payment.paymentId"
|
|
274
|
+
:client-data="payment.clientData"
|
|
275
|
+
:client-key="payment.clientKey"
|
|
276
|
+
:amount="amount"
|
|
277
|
+
:currency="currency"
|
|
278
|
+
@success="handlePaymentSuccess"
|
|
279
|
+
@error="handlePaymentError"
|
|
280
|
+
/>
|
|
281
|
+
</div>
|
|
282
|
+
</template>
|
|
283
|
+
|
|
284
|
+
<script setup lang="ts">
|
|
285
|
+
import { ref } from 'vue'
|
|
286
|
+
import '@bcc-code/payment-client/styles/adyen.css'
|
|
287
|
+
import { PaymentClient } from '@bcc-code/payment-client'
|
|
288
|
+
import { StripePayment, AdyenPayment } from '@bcc-code/payment-client/components'
|
|
289
|
+
import type { CreatePaymentResponse } from '@bcc-code/payment-client'
|
|
290
|
+
|
|
291
|
+
const paymentClient = new PaymentClient({
|
|
292
|
+
baseUrl: 'http://localhost:3200',
|
|
293
|
+
tenantId: 'your-tenant-uuid',
|
|
294
|
+
getAuthToken: async () => getBccAuthToken()
|
|
295
|
+
})
|
|
296
|
+
|
|
297
|
+
const amount = 99.99
|
|
298
|
+
const currency = 'EUR'
|
|
299
|
+
const provider = 'stripe' // or 'adyen'
|
|
300
|
+
const loading = ref(false)
|
|
301
|
+
const error = ref<string | null>(null)
|
|
302
|
+
const payment = ref<CreatePaymentResponse | null>(null)
|
|
303
|
+
const stripePublishableKey = 'pk_test_...'
|
|
304
|
+
|
|
305
|
+
const createPayment = async () => {
|
|
306
|
+
loading.value = true
|
|
307
|
+
error.value = null
|
|
308
|
+
|
|
309
|
+
try {
|
|
310
|
+
payment.value = await paymentClient.createPayment({
|
|
311
|
+
amount,
|
|
312
|
+
currency,
|
|
313
|
+
paymentMethodType: provider,
|
|
314
|
+
returnUrl: `${window.location.origin}/payment/success`
|
|
315
|
+
})
|
|
316
|
+
} catch (err) {
|
|
317
|
+
error.value = err instanceof Error ? err.message : 'Failed to create payment'
|
|
318
|
+
} finally {
|
|
319
|
+
loading.value = false
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
const handlePaymentSuccess = (result: any) => {
|
|
324
|
+
console.log('Payment successful:', result)
|
|
325
|
+
// Redirect or update UI
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
const handlePaymentError = (err: any) => {
|
|
329
|
+
console.error('Payment error:', err)
|
|
330
|
+
error.value = err.message || 'Payment failed'
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
// Create payment on mount
|
|
334
|
+
createPayment()
|
|
335
|
+
</script>
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
## Troubleshooting
|
|
339
|
+
|
|
340
|
+
### Peer Dependency Warnings
|
|
341
|
+
|
|
342
|
+
If you see peer dependency warnings, make sure you've installed the required packages:
|
|
343
|
+
|
|
344
|
+
```bash
|
|
345
|
+
pnpm add vue@^3.0.0 @stripe/stripe-js@^3.0.0 @adyen/adyen-web@^6.0.0
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
### CSS Not Loading (Adyen)
|
|
349
|
+
|
|
350
|
+
Make sure you import the Adyen CSS:
|
|
351
|
+
|
|
352
|
+
```typescript
|
|
353
|
+
import '@bcc-code/payment-client/styles/adyen.css'
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
### Component Not Rendering
|
|
357
|
+
|
|
358
|
+
1. Ensure Vue 3 is installed and properly configured
|
|
359
|
+
2. Check that you've installed the required peer dependencies
|
|
360
|
+
3. Verify that `clientData` or `clientKey` props are provided correctly
|
|
361
|
+
4. Check browser console for errors
|
|
362
|
+
|
|
363
|
+
### TypeScript Errors
|
|
364
|
+
|
|
365
|
+
If you see TypeScript errors about `.vue` files, ensure your `tsconfig.json` includes:
|
|
366
|
+
|
|
367
|
+
```json
|
|
368
|
+
{
|
|
369
|
+
"compilerOptions": {
|
|
370
|
+
"types": ["vite/client"]
|
|
371
|
+
},
|
|
372
|
+
"include": ["**/*.vue"]
|
|
373
|
+
}
|
|
374
|
+
```
|
|
375
|
+
|
|
49
376
|
|
|
50
377
|
|
|
51
378
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var w=Object.create;var _=Object.defineProperty;var A=Object.getOwnPropertyDescriptor;var B=Object.getOwnPropertyNames;var K=Object.getPrototypeOf,N=Object.prototype.hasOwnProperty;var F=(s,u,i,n)=>{if(u&&typeof u=="object"||typeof u=="function")for(let a of B(u))!N.call(s,a)&&a!==i&&_(s,a,{get:()=>u[a],enumerable:!(n=A(u,a))||n.enumerable});return s};var E=(s,u,i)=>(i=s!=null?w(K(s)):{},F(u||!s||!s.__esModule?_(i,"default",{value:s,enumerable:!0}):i,s));Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("vue"),R={class:"stripe-elements"},U={key:0,class:"elements-loading"},V={key:1,class:"elements-error"},M={key:2,class:"payment-button-container"},x=["disabled"],I=t.defineComponent({__name:"StripePayment",props:{paymentId:{},clientData:{default:void 0},clientKey:{default:void 0},amount:{},currency:{},publishableKey:{default:void 0},appearance:{default:void 0},showPayButton:{type:Boolean,default:!0},locale:{default:"en"},loader:{default:"auto"},returnUrl:{default:void 0}},emits:["submit","success","error","ready"],setup(s,{expose:u,emit:i}){const n=s,a=i,b=t.ref(),p=t.ref(!0),l=t.ref(!1),c=t.ref("");let d=null,f=null,m=null;const h=t.computed(()=>({EUR:"€",USD:"$",GBP:"£",CHF:"CHF",NOK:"kr",SEK:"kr",DKK:"kr",PLN:"zł",CZK:"Kč",HUF:"Ft"})[n.currency]||n.currency),P=t.computed(()=>n.amount.toFixed(2)),C=t.computed(()=>{if(n.clientData)try{const o=JSON.parse(n.clientData);return o.clientSecret||o.client_secret}catch{return}}),v=async()=>{if(!b.value)return;let o=n.publishableKey;if(!o&&n.clientData)try{const r=JSON.parse(n.clientData);o=r.publishableKey||r.publishable_key}catch{}if(!o){c.value="Publishable key is required",p.value=!1;return}try{p.value=!0,c.value="";const{loadStripe:r}=await import("@stripe/stripe-js");if(d=await r(o),!d)throw new Error("Failed to load Stripe");const e=C.value,y={appearance:n.appearance||{theme:"stripe",variables:{colorPrimary:"#0570de",colorBackground:"#ffffff",colorText:"#30313d",colorDanger:"#df1b41",fontFamily:'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',spacingUnit:"4px",borderRadius:"4px"}},loader:n.loader,locale:n.locale};e&&(y.clientSecret=e),f=d.elements(y),m=f.create("payment",{layout:"tabs",defaultValues:{billingDetails:{name:"",email:"",phone:""}}}),m.mount(b.value),m.on("ready",()=>{p.value=!1,a("ready")}),m.on("change",k=>{k.error?(c.value=k.error.message,a("error",k.error)):c.value=""})}catch(r){c.value=r instanceof Error?r.message:"Failed to initialize payment form",p.value=!1,a("error",r)}},D=async()=>{if(!(!d||!m)){l.value=!0,c.value="";try{const o=n.returnUrl||`${window.location.origin}/payment/return`,{error:r,paymentIntent:e}=await d.confirmPayment({elements:f,confirmParams:{return_url:o},redirect:"if_required"});r?(c.value=r.message||"Payment failed",a("error",r)):e?e.status==="succeeded"?a("success",{paymentIntent:e,status:"succeeded",message:"Payment completed successfully!"}):e.status==="processing"?a("success",{paymentIntent:e,status:"processing",message:"Payment is being processed..."}):a("submit",{paymentIntent:e,status:e.status}):a("submit",m)}catch(o){c.value=o instanceof Error?o.message:"Payment failed",a("error",o)}finally{l.value=!1}}},g=()=>{m&&(m.destroy(),m=null),f&&(f=null),d&&(d=null)};return t.onMounted(()=>{v()}),t.onUnmounted(()=>{g()}),t.watch(()=>n.currency,()=>{g(),v()}),t.watch([()=>n.publishableKey,()=>n.clientData],()=>{(n.publishableKey||n.clientData)&&(g(),v())}),u({destroyElements:g}),(o,r)=>(t.openBlock(),t.createElementBlock("div",R,[t.createElementVNode("div",{ref_key:"elementsContainer",ref:b,class:"elements-container"},null,512),p.value?(t.openBlock(),t.createElementBlock("div",U,[...r[0]||(r[0]=[t.createElementVNode("div",{class:"loading-spinner"},null,-1),t.createElementVNode("p",null,"Loading payment form...",-1)])])):t.createCommentVNode("",!0),c.value?(t.openBlock(),t.createElementBlock("div",V,[r[1]||(r[1]=t.createElementVNode("div",{class:"error-icon"}," ⚠️ ",-1)),t.createElementVNode("p",null,t.toDisplayString(c.value),1),t.createElementVNode("button",{class:"retry-btn",onClick:v}," Retry ")])):t.createCommentVNode("",!0),s.showPayButton&&!p.value&&!c.value?(t.openBlock(),t.createElementBlock("div",M,[t.createElementVNode("button",{disabled:l.value,class:"payment-button",onClick:D},t.toDisplayString(l.value?"Processing...":`Pay ${h.value}${P.value}`),9,x)])):t.createCommentVNode("",!0)]))}}),S=(s,u)=>{const i=s.__vccOpts||s;for(const[n,a]of u)i[n]=a;return i},O=S(I,[["__scopeId","data-v-adbdf3c5"]]),q=t.defineComponent({__name:"AdyenPayment",props:{paymentId:{},clientData:{},clientKey:{},amount:{},currency:{},paymentData:{},onCancel:{type:Function}},emits:["submit","additionalDetails","error","ready","success"],setup(s,{emit:u}){const i=s,n=u,a=t.ref(null),b=()=>{if(!i.clientData)return console.error("No clientData provided"),null;try{const l=JSON.parse(i.clientData);return console.log("Parsed Adyen session data:",l),{id:l.id,sessionData:l.sessionData,amount:l.amount,reference:l.reference,returnUrl:l.returnUrl,merchantAccount:l.merchantAccount}}catch(l){return console.error("Failed to parse clientData:",l),null}},p=async()=>{var c;if(!i.clientKey||!a.value){console.error("Initialization failed: Missing clientKey or container.");return}const l=b();if(!l){console.error("Failed to parse session data"),n("error",new Error("Failed to parse session data"));return}try{const{AdyenCheckout:d,Card:f,ApplePay:m,GooglePay:h,Klarna:P,Blik:C,Dropin:v}=await import("@adyen/adyen-web"),D={environment:"test",clientKey:i.clientKey,session:l,onPaymentCompleted:(e,y)=>{console.info("Payment Completed:",e,y),n("submit",e),e.resultCode==="Authorised"||e.resultCode==="Received"?(console.info("Payment Successful:",e),n("success",{status:"succeeded",message:"Payment completed successfully",resultCode:e.resultCode,pspReference:e.pspReference,paymentData:e})):e.resultCode==="Pending"?(console.info("Payment Pending:",e),n("success",{status:"processing",message:"Payment is being processed",resultCode:e.resultCode,pspReference:e.pspReference,paymentData:e})):(e.resultCode==="Refused"||e.resultCode==="Error")&&(console.error("Payment Failed:",e),n("error",{message:e.refusalReason||"Payment was declined",resultCode:e.resultCode,paymentData:e}))},onAdditionalDetails:(e,y)=>{console.info("Additional Details:",e,y),n("additionalDetails",e)},onError:(e,y)=>{console.error("Adyen Error:",e.name,e.message,e.stack,y),n("error",e)}},g={showPayButton:!0,paymentMethodComponents:[f,m,h,P,C],paymentMethodsConfiguration:{card:{hasHolderName:!0,holderNameRequired:!0,billingAddressRequired:!1,enableStoreDetails:!1},applePay:{showPayButton:!0},googlePay:{showPayButton:!0},klarna:{useKlarnaWidget:!0},blik:{}}},o=await d(D);console.log("Adyen Checkout created:",o),console.log("Available payment methods from session:",(c=o.paymentMethodsResponse)==null?void 0:c.paymentMethods);const r=new v(o,g);console.log("Adyen Drop-in created with session payment methods"),a.value&&(r.mount(a.value),console.log("Adyen Drop-in mounted successfully"),n("ready"))}catch(d){console.error("Error creating Adyen Drop-in:",d),n("error",d)}};return t.onMounted(()=>{p()}),t.watch(()=>i.clientData,()=>{a.value&&(a.value.innerHTML="",p())}),(l,c)=>(t.openBlock(),t.createElementBlock("div",{ref_key:"dropinContainer",ref:a,class:"payment-dropin"},null,512))}}),z=S(q,[["__scopeId","data-v-978cddfa"]]);exports.AdyenPayment=z;exports.StripePayment=O;
|
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
import { defineComponent as R, ref as h, computed as w, onMounted as B, onUnmounted as N, watch as E, createElementBlock as P, openBlock as D, createElementVNode as p, createCommentVNode as A, toDisplayString as F } from "vue";
|
|
2
|
+
const x = { class: "stripe-elements" }, M = {
|
|
3
|
+
key: 0,
|
|
4
|
+
class: "elements-loading"
|
|
5
|
+
}, I = {
|
|
6
|
+
key: 1,
|
|
7
|
+
class: "elements-error"
|
|
8
|
+
}, z = {
|
|
9
|
+
key: 2,
|
|
10
|
+
class: "payment-button-container"
|
|
11
|
+
}, H = ["disabled"], O = /* @__PURE__ */ R({
|
|
12
|
+
__name: "StripePayment",
|
|
13
|
+
props: {
|
|
14
|
+
paymentId: {},
|
|
15
|
+
clientData: { default: void 0 },
|
|
16
|
+
clientKey: { default: void 0 },
|
|
17
|
+
amount: {},
|
|
18
|
+
currency: {},
|
|
19
|
+
publishableKey: { default: void 0 },
|
|
20
|
+
appearance: { default: void 0 },
|
|
21
|
+
showPayButton: { type: Boolean, default: !0 },
|
|
22
|
+
locale: { default: "en" },
|
|
23
|
+
loader: { default: "auto" },
|
|
24
|
+
returnUrl: { default: void 0 }
|
|
25
|
+
},
|
|
26
|
+
emits: ["submit", "success", "error", "ready"],
|
|
27
|
+
setup(m, { expose: g, emit: c }) {
|
|
28
|
+
const t = m, o = c, b = h(), u = h(!0), r = h(!1), s = h("");
|
|
29
|
+
let l = null, y = null, i = null;
|
|
30
|
+
const C = w(() => ({
|
|
31
|
+
EUR: "€",
|
|
32
|
+
USD: "$",
|
|
33
|
+
GBP: "£",
|
|
34
|
+
CHF: "CHF",
|
|
35
|
+
NOK: "kr",
|
|
36
|
+
SEK: "kr",
|
|
37
|
+
DKK: "kr",
|
|
38
|
+
PLN: "zł",
|
|
39
|
+
CZK: "Kč",
|
|
40
|
+
HUF: "Ft"
|
|
41
|
+
})[t.currency] || t.currency), _ = w(() => t.amount.toFixed(2)), k = w(() => {
|
|
42
|
+
if (t.clientData)
|
|
43
|
+
try {
|
|
44
|
+
const n = JSON.parse(t.clientData);
|
|
45
|
+
return n.clientSecret || n.client_secret;
|
|
46
|
+
} catch {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
}), f = async () => {
|
|
50
|
+
if (!b.value) return;
|
|
51
|
+
let n = t.publishableKey;
|
|
52
|
+
if (!n && t.clientData)
|
|
53
|
+
try {
|
|
54
|
+
const a = JSON.parse(t.clientData);
|
|
55
|
+
n = a.publishableKey || a.publishable_key;
|
|
56
|
+
} catch {
|
|
57
|
+
}
|
|
58
|
+
if (!n) {
|
|
59
|
+
s.value = "Publishable key is required", u.value = !1;
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
try {
|
|
63
|
+
u.value = !0, s.value = "";
|
|
64
|
+
const { loadStripe: a } = await import("@stripe/stripe-js");
|
|
65
|
+
if (l = await a(n), !l)
|
|
66
|
+
throw new Error("Failed to load Stripe");
|
|
67
|
+
const e = k.value, d = {
|
|
68
|
+
appearance: t.appearance || {
|
|
69
|
+
theme: "stripe",
|
|
70
|
+
variables: {
|
|
71
|
+
colorPrimary: "#0570de",
|
|
72
|
+
colorBackground: "#ffffff",
|
|
73
|
+
colorText: "#30313d",
|
|
74
|
+
colorDanger: "#df1b41",
|
|
75
|
+
fontFamily: 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
|
|
76
|
+
spacingUnit: "4px",
|
|
77
|
+
borderRadius: "4px"
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
loader: t.loader,
|
|
81
|
+
locale: t.locale
|
|
82
|
+
};
|
|
83
|
+
e && (d.clientSecret = e), y = l.elements(d), i = y.create("payment", {
|
|
84
|
+
layout: "tabs",
|
|
85
|
+
defaultValues: {
|
|
86
|
+
billingDetails: {
|
|
87
|
+
name: "",
|
|
88
|
+
email: "",
|
|
89
|
+
phone: ""
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}), i.mount(b.value), i.on("ready", () => {
|
|
93
|
+
u.value = !1, o("ready");
|
|
94
|
+
}), i.on("change", (K) => {
|
|
95
|
+
K.error ? (s.value = K.error.message, o("error", K.error)) : s.value = "";
|
|
96
|
+
});
|
|
97
|
+
} catch (a) {
|
|
98
|
+
s.value = a instanceof Error ? a.message : "Failed to initialize payment form", u.value = !1, o("error", a);
|
|
99
|
+
}
|
|
100
|
+
}, S = async () => {
|
|
101
|
+
if (!(!l || !i)) {
|
|
102
|
+
r.value = !0, s.value = "";
|
|
103
|
+
try {
|
|
104
|
+
const n = t.returnUrl || `${window.location.origin}/payment/return`, { error: a, paymentIntent: e } = await l.confirmPayment({
|
|
105
|
+
elements: y,
|
|
106
|
+
confirmParams: {
|
|
107
|
+
return_url: n
|
|
108
|
+
},
|
|
109
|
+
redirect: "if_required"
|
|
110
|
+
});
|
|
111
|
+
a ? (s.value = a.message || "Payment failed", o("error", a)) : e ? e.status === "succeeded" ? o("success", {
|
|
112
|
+
paymentIntent: e,
|
|
113
|
+
status: "succeeded",
|
|
114
|
+
message: "Payment completed successfully!"
|
|
115
|
+
}) : e.status === "processing" ? o("success", {
|
|
116
|
+
paymentIntent: e,
|
|
117
|
+
status: "processing",
|
|
118
|
+
message: "Payment is being processed..."
|
|
119
|
+
}) : o("submit", { paymentIntent: e, status: e.status }) : o("submit", i);
|
|
120
|
+
} catch (n) {
|
|
121
|
+
s.value = n instanceof Error ? n.message : "Payment failed", o("error", n);
|
|
122
|
+
} finally {
|
|
123
|
+
r.value = !1;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}, v = () => {
|
|
127
|
+
i && (i.destroy(), i = null), y && (y = null), l && (l = null);
|
|
128
|
+
};
|
|
129
|
+
return B(() => {
|
|
130
|
+
f();
|
|
131
|
+
}), N(() => {
|
|
132
|
+
v();
|
|
133
|
+
}), E(() => t.currency, () => {
|
|
134
|
+
v(), f();
|
|
135
|
+
}), E([() => t.publishableKey, () => t.clientData], () => {
|
|
136
|
+
(t.publishableKey || t.clientData) && (v(), f());
|
|
137
|
+
}), g({
|
|
138
|
+
destroyElements: v
|
|
139
|
+
}), (n, a) => (D(), P("div", x, [
|
|
140
|
+
p("div", {
|
|
141
|
+
ref_key: "elementsContainer",
|
|
142
|
+
ref: b,
|
|
143
|
+
class: "elements-container"
|
|
144
|
+
}, null, 512),
|
|
145
|
+
u.value ? (D(), P("div", M, [...a[0] || (a[0] = [
|
|
146
|
+
p("div", { class: "loading-spinner" }, null, -1),
|
|
147
|
+
p("p", null, "Loading payment form...", -1)
|
|
148
|
+
])])) : A("", !0),
|
|
149
|
+
s.value ? (D(), P("div", I, [
|
|
150
|
+
a[1] || (a[1] = p("div", { class: "error-icon" }, " ⚠️ ", -1)),
|
|
151
|
+
p("p", null, F(s.value), 1),
|
|
152
|
+
p("button", {
|
|
153
|
+
class: "retry-btn",
|
|
154
|
+
onClick: f
|
|
155
|
+
}, " Retry ")
|
|
156
|
+
])) : A("", !0),
|
|
157
|
+
m.showPayButton && !u.value && !s.value ? (D(), P("div", z, [
|
|
158
|
+
p("button", {
|
|
159
|
+
disabled: r.value,
|
|
160
|
+
class: "payment-button",
|
|
161
|
+
onClick: S
|
|
162
|
+
}, F(r.value ? "Processing..." : `Pay ${C.value}${_.value}`), 9, H)
|
|
163
|
+
])) : A("", !0)
|
|
164
|
+
]));
|
|
165
|
+
}
|
|
166
|
+
}), U = (m, g) => {
|
|
167
|
+
const c = m.__vccOpts || m;
|
|
168
|
+
for (const [t, o] of g)
|
|
169
|
+
c[t] = o;
|
|
170
|
+
return c;
|
|
171
|
+
}, L = /* @__PURE__ */ U(O, [["__scopeId", "data-v-adbdf3c5"]]), $ = /* @__PURE__ */ R({
|
|
172
|
+
__name: "AdyenPayment",
|
|
173
|
+
props: {
|
|
174
|
+
paymentId: {},
|
|
175
|
+
clientData: {},
|
|
176
|
+
clientKey: {},
|
|
177
|
+
amount: {},
|
|
178
|
+
currency: {},
|
|
179
|
+
paymentData: {},
|
|
180
|
+
onCancel: { type: Function }
|
|
181
|
+
},
|
|
182
|
+
emits: ["submit", "additionalDetails", "error", "ready", "success"],
|
|
183
|
+
setup(m, { emit: g }) {
|
|
184
|
+
const c = m, t = g, o = h(null), b = () => {
|
|
185
|
+
if (!c.clientData)
|
|
186
|
+
return console.error("No clientData provided"), null;
|
|
187
|
+
try {
|
|
188
|
+
const r = JSON.parse(c.clientData);
|
|
189
|
+
return console.log("Parsed Adyen session data:", r), {
|
|
190
|
+
id: r.id,
|
|
191
|
+
sessionData: r.sessionData,
|
|
192
|
+
amount: r.amount,
|
|
193
|
+
reference: r.reference,
|
|
194
|
+
returnUrl: r.returnUrl,
|
|
195
|
+
merchantAccount: r.merchantAccount
|
|
196
|
+
};
|
|
197
|
+
} catch (r) {
|
|
198
|
+
return console.error("Failed to parse clientData:", r), null;
|
|
199
|
+
}
|
|
200
|
+
}, u = async () => {
|
|
201
|
+
var s;
|
|
202
|
+
if (!c.clientKey || !o.value) {
|
|
203
|
+
console.error("Initialization failed: Missing clientKey or container.");
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
const r = b();
|
|
207
|
+
if (!r) {
|
|
208
|
+
console.error("Failed to parse session data"), t("error", new Error("Failed to parse session data"));
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
try {
|
|
212
|
+
const { AdyenCheckout: l, Card: y, ApplePay: i, GooglePay: C, Klarna: _, Blik: k, Dropin: f } = await import("@adyen/adyen-web"), S = {
|
|
213
|
+
environment: "test",
|
|
214
|
+
clientKey: c.clientKey,
|
|
215
|
+
session: r,
|
|
216
|
+
onPaymentCompleted: (e, d) => {
|
|
217
|
+
console.info("Payment Completed:", e, d), t("submit", e), e.resultCode === "Authorised" || e.resultCode === "Received" ? (console.info("Payment Successful:", e), t("success", {
|
|
218
|
+
status: "succeeded",
|
|
219
|
+
message: "Payment completed successfully",
|
|
220
|
+
resultCode: e.resultCode,
|
|
221
|
+
pspReference: e.pspReference,
|
|
222
|
+
paymentData: e
|
|
223
|
+
})) : e.resultCode === "Pending" ? (console.info("Payment Pending:", e), t("success", {
|
|
224
|
+
status: "processing",
|
|
225
|
+
message: "Payment is being processed",
|
|
226
|
+
resultCode: e.resultCode,
|
|
227
|
+
pspReference: e.pspReference,
|
|
228
|
+
paymentData: e
|
|
229
|
+
})) : (e.resultCode === "Refused" || e.resultCode === "Error") && (console.error("Payment Failed:", e), t("error", {
|
|
230
|
+
message: e.refusalReason || "Payment was declined",
|
|
231
|
+
resultCode: e.resultCode,
|
|
232
|
+
paymentData: e
|
|
233
|
+
}));
|
|
234
|
+
},
|
|
235
|
+
onAdditionalDetails: (e, d) => {
|
|
236
|
+
console.info("Additional Details:", e, d), t("additionalDetails", e);
|
|
237
|
+
},
|
|
238
|
+
onError: (e, d) => {
|
|
239
|
+
console.error("Adyen Error:", e.name, e.message, e.stack, d), t("error", e);
|
|
240
|
+
}
|
|
241
|
+
}, v = {
|
|
242
|
+
showPayButton: !0,
|
|
243
|
+
paymentMethodComponents: [y, i, C, _, k],
|
|
244
|
+
paymentMethodsConfiguration: {
|
|
245
|
+
card: {
|
|
246
|
+
hasHolderName: !0,
|
|
247
|
+
holderNameRequired: !0,
|
|
248
|
+
billingAddressRequired: !1,
|
|
249
|
+
enableStoreDetails: !1
|
|
250
|
+
},
|
|
251
|
+
applePay: {
|
|
252
|
+
showPayButton: !0
|
|
253
|
+
},
|
|
254
|
+
googlePay: {
|
|
255
|
+
showPayButton: !0
|
|
256
|
+
},
|
|
257
|
+
klarna: {
|
|
258
|
+
useKlarnaWidget: !0
|
|
259
|
+
},
|
|
260
|
+
blik: {
|
|
261
|
+
// BLIK configuration for Polish market
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}, n = await l(S);
|
|
265
|
+
console.log("Adyen Checkout created:", n), console.log("Available payment methods from session:", (s = n.paymentMethodsResponse) == null ? void 0 : s.paymentMethods);
|
|
266
|
+
const a = new f(n, v);
|
|
267
|
+
console.log("Adyen Drop-in created with session payment methods"), o.value && (a.mount(o.value), console.log("Adyen Drop-in mounted successfully"), t("ready"));
|
|
268
|
+
} catch (l) {
|
|
269
|
+
console.error("Error creating Adyen Drop-in:", l), t("error", l);
|
|
270
|
+
}
|
|
271
|
+
};
|
|
272
|
+
return B(() => {
|
|
273
|
+
u();
|
|
274
|
+
}), E(() => c.clientData, () => {
|
|
275
|
+
o.value && (o.value.innerHTML = "", u());
|
|
276
|
+
}), (r, s) => (D(), P("div", {
|
|
277
|
+
ref_key: "dropinContainer",
|
|
278
|
+
ref: o,
|
|
279
|
+
class: "payment-dropin"
|
|
280
|
+
}, null, 512));
|
|
281
|
+
}
|
|
282
|
+
}), J = /* @__PURE__ */ U($, [["__scopeId", "data-v-978cddfa"]]);
|
|
283
|
+
export {
|
|
284
|
+
J as AdyenPayment,
|
|
285
|
+
L as StripePayment
|
|
286
|
+
};
|
package/dist/index.d.mts
CHANGED
|
@@ -106,4 +106,27 @@ declare class PaymentClient {
|
|
|
106
106
|
getReceipt(paymentId: string): Promise<PaymentReceiptResponse | null>;
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
-
|
|
109
|
+
interface StripePaymentProps {
|
|
110
|
+
paymentId: string;
|
|
111
|
+
clientData?: string;
|
|
112
|
+
clientKey?: string;
|
|
113
|
+
amount: number;
|
|
114
|
+
currency: string;
|
|
115
|
+
publishableKey?: string;
|
|
116
|
+
appearance?: any;
|
|
117
|
+
showPayButton?: boolean;
|
|
118
|
+
locale?: string;
|
|
119
|
+
loader?: 'auto' | 'always' | 'never';
|
|
120
|
+
returnUrl?: string;
|
|
121
|
+
}
|
|
122
|
+
interface AdyenPaymentProps {
|
|
123
|
+
paymentId: string;
|
|
124
|
+
clientData?: string;
|
|
125
|
+
clientKey?: string;
|
|
126
|
+
amount?: number;
|
|
127
|
+
currency?: string;
|
|
128
|
+
paymentData?: any;
|
|
129
|
+
onCancel?: () => void;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export { type AdyenPaymentProps, type CreatePaymentRequest, type CreatePaymentResponse, type LineItemRequest, type LineItemResponse, PaymentClient, type PaymentClientOptions, type PaymentReceiptResponse, type PaymentResponse, type PersonInfoRequest, type StripePaymentProps };
|