@zahlen/checkout-angular 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,231 @@
1
+ # @zahlen/checkout-angular
2
+
3
+ <p align="center">
4
+ <img src="https://img.shields.io/npm/v/@zahlen/checkout-angular?style=flat-square" alt="npm version" />
5
+ <img src="https://img.shields.io/npm/l/@zahlen/checkout-angular?style=flat-square" alt="license" />
6
+ </p>
7
+
8
+ <p align="center">
9
+ <strong>Angular module for Zahlen Checkout</strong>
10
+ <br />
11
+ Module • Service • Components • Directives
12
+ </p>
13
+
14
+ ---
15
+
16
+ ## 🚀 Installation
17
+
18
+ ```bash
19
+ npm install @zahlen/checkout-angular @zahlen/checkout
20
+ # or
21
+ yarn add @zahlen/checkout-angular @zahlen/checkout
22
+ ```
23
+
24
+ ---
25
+
26
+ ## 📖 Quick Start
27
+
28
+ ### Step 1: Import the Module
29
+
30
+ ```typescript
31
+ // app.module.ts
32
+ import { ZahlenModule } from '@zahlen/checkout-angular';
33
+
34
+ @NgModule({
35
+ imports: [
36
+ ZahlenModule.forRoot({
37
+ apiKey: 'pk_live_your_api_key',
38
+ theme: 'dark'
39
+ })
40
+ ]
41
+ })
42
+ export class AppModule {}
43
+ ```
44
+
45
+ ### Step 2: Use in Your Component
46
+
47
+ #### Option 1: Button Component (Easiest)
48
+
49
+ ```html
50
+ <!-- product.component.html -->
51
+ <zahlen-button
52
+ [amount]="499900"
53
+ [currency]="'NGN'"
54
+ [description]="'Premium Plan'"
55
+ (success)="onPaymentSuccess($event)"
56
+ (error)="onPaymentError($event)"
57
+ >
58
+ 💳 Pay ₦4,999
59
+ </zahlen-button>
60
+ ```
61
+
62
+ ```typescript
63
+ // product.component.ts
64
+ import { PaymentResult, PaymentError } from '@zahlen/checkout-angular';
65
+
66
+ @Component({ ... })
67
+ export class ProductComponent {
68
+ onPaymentSuccess(result: PaymentResult) {
69
+ console.log('Payment successful!', result);
70
+ this.router.navigate(['/success']);
71
+ }
72
+
73
+ onPaymentError(error: PaymentError) {
74
+ console.error('Payment failed:', error);
75
+ this.toast.error(error.message);
76
+ }
77
+ }
78
+ ```
79
+
80
+ #### Option 2: Directive (Any Element)
81
+
82
+ ```html
83
+ <!-- Attach checkout to any element -->
84
+ <button
85
+ zahlenCheckout
86
+ [zahlenAmount]="499900"
87
+ [zahlenCurrency]="'NGN'"
88
+ [zahlenDescription]="'Premium Plan'"
89
+ (zahlenSuccess)="onSuccess($event)"
90
+ (zahlenError)="onError($event)"
91
+ class="my-custom-button"
92
+ >
93
+ Buy Now
94
+ </button>
95
+ ```
96
+
97
+ #### Option 3: Service (Programmatic)
98
+
99
+ ```typescript
100
+ // product.component.ts
101
+ import { ZahlenService, PaymentResult } from '@zahlen/checkout-angular';
102
+
103
+ @Component({ ... })
104
+ export class ProductComponent {
105
+ constructor(private zahlenService: ZahlenService) {}
106
+
107
+ async checkout() {
108
+ try {
109
+ const result: PaymentResult = await this.zahlenService.openCheckout({
110
+ amount: 499900, // ₦4,999 in kobo
111
+ currency: 'NGN',
112
+ description: 'Premium Plan',
113
+ customerEmail: 'user@example.com'
114
+ });
115
+
116
+ console.log('Payment successful!', result);
117
+ this.router.navigate(['/success']);
118
+ } catch (error) {
119
+ console.error('Payment failed:', error);
120
+ }
121
+ }
122
+ }
123
+ ```
124
+
125
+ ---
126
+
127
+ ## 📚 API Reference
128
+
129
+ ### `ZahlenModule.forRoot(config)`
130
+
131
+ Configure the module in your app's root module.
132
+
133
+ ```typescript
134
+ interface ZahlenConfig {
135
+ apiKey: string; // Required
136
+ theme?: 'dark' | 'light' | 'auto'; // Default: 'dark'
137
+ }
138
+ ```
139
+
140
+ ### `ZahlenService`
141
+
142
+ Injectable service for programmatic control.
143
+
144
+ | Method | Returns | Description |
145
+ |--------|---------|-------------|
146
+ | `init(config)` | `void` | Initialize SDK (auto-called by forRoot) |
147
+ | `openCheckout(options)` | `Promise<PaymentResult>` | Open checkout and await result |
148
+ | `checkout(options, onSuccess, onError, onClose?)` | `void` | Open checkout with callbacks |
149
+ | `closeCheckout()` | `void` | Close the modal |
150
+ | `setTheme(theme)` | `void` | Change theme |
151
+ | `isInitialized` | `boolean` | Check if SDK is ready |
152
+
153
+ ### `<zahlen-button>`
154
+
155
+ Pre-styled checkout button component.
156
+
157
+ | Input | Type | Required | Description |
158
+ |-------|------|----------|-------------|
159
+ | `amount` | `number` | ✅ | Amount in smallest unit |
160
+ | `currency` | `string` | | Currency code (default: 'NGN') |
161
+ | `description` | `string` | | Payment description |
162
+ | `customerEmail` | `string` | | Customer email |
163
+ | `metadata` | `object` | | Custom metadata |
164
+ | `className` | `string` | | Additional CSS class |
165
+ | `disabled` | `boolean` | | Disable button |
166
+
167
+ | Output | Type | Description |
168
+ |--------|------|-------------|
169
+ | `success` | `PaymentResult` | Emitted on successful payment |
170
+ | `error` | `PaymentError` | Emitted on payment error |
171
+ | `closed` | `void` | Emitted when modal closes |
172
+
173
+ ### `[zahlenCheckout]`
174
+
175
+ Directive to attach checkout behavior to any element.
176
+
177
+ | Input | Type | Description |
178
+ |-------|------|-------------|
179
+ | `zahlenAmount` | `number` | Amount in smallest unit |
180
+ | `zahlenCurrency` | `string` | Currency code |
181
+ | `zahlenDescription` | `string` | Payment description |
182
+ | `zahlenEmail` | `string` | Customer email |
183
+ | `zahlenMetadata` | `object` | Custom metadata |
184
+
185
+ | Output | Type | Description |
186
+ |--------|------|-------------|
187
+ | `zahlenSuccess` | `PaymentResult` | Emitted on success |
188
+ | `zahlenError` | `PaymentError` | Emitted on error |
189
+ | `zahlenClose` | `void` | Emitted on close |
190
+
191
+ ---
192
+
193
+ ## 🎨 Customization
194
+
195
+ Customize via the core SDK:
196
+
197
+ ```typescript
198
+ // main.ts or app.component.ts
199
+ import { Zahlen } from '@zahlen/checkout';
200
+
201
+ Zahlen.init({
202
+ apiKey: 'pk_live_xxx',
203
+ customStyles: {
204
+ '--zahlen-primary': '#FF6B6B',
205
+ '--zahlen-bg': '#1A1A2E',
206
+ }
207
+ });
208
+ ```
209
+
210
+ ---
211
+
212
+ ## ⚡ Standalone Components (Angular 17+)
213
+
214
+ All components are standalone and can be imported directly:
215
+
216
+ ```typescript
217
+ import { ZahlenButtonComponent, ZahlenCheckoutDirective } from '@zahlen/checkout-angular';
218
+
219
+ @Component({
220
+ standalone: true,
221
+ imports: [ZahlenButtonComponent, ZahlenCheckoutDirective],
222
+ template: `<zahlen-button [amount]="4999" (success)="onPaid($event)"/>`
223
+ })
224
+ export class ProductComponent {}
225
+ ```
226
+
227
+ ---
228
+
229
+ ## 📄 License
230
+
231
+ MIT © Zahlen
@@ -0,0 +1,411 @@
1
+ import * as i0 from '@angular/core';
2
+ import { InjectionToken, Optional, Inject, Injectable, EventEmitter, Output, Input, ChangeDetectionStrategy, Component, HostListener, Directive, NgModule } from '@angular/core';
3
+ import * as i2 from '@angular/common';
4
+ import { CommonModule } from '@angular/common';
5
+
6
+ /**
7
+ * Zahlen Checkout Angular - Configuration
8
+ */
9
+ /**
10
+ * Injection token for Zahlen configuration
11
+ */
12
+ const ZAHLEN_CONFIG = new InjectionToken('ZAHLEN_CONFIG');
13
+
14
+ /**
15
+ * Zahlen Service - Injectable service for programmatic checkout control
16
+ */
17
+ class ZahlenService {
18
+ config;
19
+ initialized = false;
20
+ constructor(config) {
21
+ this.config = config;
22
+ // Auto-initialize if config is provided via forRoot
23
+ if (this.config?.apiKey) {
24
+ this.init(this.config);
25
+ }
26
+ }
27
+ /**
28
+ * Initialize Zahlen SDK
29
+ * @param config - Configuration with API key
30
+ */
31
+ init(config) {
32
+ if (this.initialized)
33
+ return;
34
+ if (typeof Zahlen !== 'undefined') {
35
+ Zahlen.init(config);
36
+ this.initialized = true;
37
+ }
38
+ else {
39
+ console.error('[ZahlenService] Zahlen SDK not loaded. Make sure @zahlen/checkout is imported.');
40
+ }
41
+ }
42
+ /**
43
+ * Open checkout modal with promise interface
44
+ * @param options - Checkout options
45
+ * @returns Promise resolving to PaymentResult or rejecting with PaymentError
46
+ *
47
+ * @example
48
+ * ```typescript
49
+ * async checkout() {
50
+ * try {
51
+ * const result = await this.zahlenService.openCheckout({
52
+ * amount: 499900,
53
+ * currency: 'NGN',
54
+ * description: 'Premium Plan'
55
+ * });
56
+ * console.log('Payment successful!', result);
57
+ * } catch (error) {
58
+ * console.error('Payment failed:', error);
59
+ * }
60
+ * }
61
+ * ```
62
+ */
63
+ openCheckout(options) {
64
+ return new Promise((resolve, reject) => {
65
+ if (!this.initialized) {
66
+ reject({
67
+ code: 'NOT_INITIALIZED',
68
+ message: 'Zahlen SDK not initialized. Call init() or use ZahlenModule.forRoot()',
69
+ recoverable: false
70
+ });
71
+ return;
72
+ }
73
+ Zahlen.checkout({
74
+ ...options,
75
+ onSuccess: (result) => resolve(result),
76
+ onError: (error) => reject(error),
77
+ });
78
+ });
79
+ }
80
+ /**
81
+ * Open checkout modal with callbacks
82
+ * @param options - Checkout options with callbacks
83
+ */
84
+ checkout(options, onSuccess, onError, onClose) {
85
+ if (!this.initialized) {
86
+ onError({
87
+ code: 'NOT_INITIALIZED',
88
+ message: 'Zahlen SDK not initialized',
89
+ recoverable: false
90
+ });
91
+ return;
92
+ }
93
+ Zahlen.checkout({
94
+ ...options,
95
+ onSuccess,
96
+ onError,
97
+ onClose
98
+ });
99
+ }
100
+ /**
101
+ * Close the checkout modal
102
+ */
103
+ closeCheckout() {
104
+ if (typeof Zahlen !== 'undefined') {
105
+ Zahlen.closeModal();
106
+ }
107
+ }
108
+ /**
109
+ * Change the theme
110
+ * @param theme - 'dark', 'light', or 'auto'
111
+ */
112
+ setTheme(theme) {
113
+ if (typeof Zahlen !== 'undefined') {
114
+ Zahlen.setTheme(theme);
115
+ }
116
+ }
117
+ /**
118
+ * Check if SDK is initialized
119
+ */
120
+ get isInitialized() {
121
+ return this.initialized;
122
+ }
123
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: ZahlenService, deps: [{ token: ZAHLEN_CONFIG, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
124
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: ZahlenService, providedIn: 'root' });
125
+ }
126
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: ZahlenService, decorators: [{
127
+ type: Injectable,
128
+ args: [{
129
+ providedIn: 'root'
130
+ }]
131
+ }], ctorParameters: () => [{ type: undefined, decorators: [{
132
+ type: Optional
133
+ }, {
134
+ type: Inject,
135
+ args: [ZAHLEN_CONFIG]
136
+ }] }] });
137
+
138
+ /**
139
+ * ZahlenButton Component - Pre-styled checkout button
140
+ */
141
+ class ZahlenButtonComponent {
142
+ zahlenService;
143
+ /** Payment amount in smallest currency unit (e.g., kobo) */
144
+ amount;
145
+ /** Currency code (e.g., 'NGN', 'USD') */
146
+ currency = 'NGN';
147
+ /** Payment description */
148
+ description;
149
+ /** Customer email */
150
+ customerEmail;
151
+ /** Additional metadata */
152
+ metadata;
153
+ /** Additional CSS class */
154
+ className = '';
155
+ /** Disable the button */
156
+ disabled = false;
157
+ /** Emitted on successful payment */
158
+ success = new EventEmitter();
159
+ /** Emitted on payment error */
160
+ error = new EventEmitter();
161
+ /** Emitted when modal closes */
162
+ closed = new EventEmitter();
163
+ isProcessing = false;
164
+ constructor(zahlenService) {
165
+ this.zahlenService = zahlenService;
166
+ }
167
+ get buttonStyles() {
168
+ return {};
169
+ }
170
+ async handleClick() {
171
+ if (this.disabled || this.isProcessing)
172
+ return;
173
+ this.isProcessing = true;
174
+ try {
175
+ const result = await this.zahlenService.openCheckout({
176
+ amount: this.amount,
177
+ currency: this.currency,
178
+ description: this.description,
179
+ customerEmail: this.customerEmail,
180
+ metadata: this.metadata,
181
+ });
182
+ this.success.emit(result);
183
+ }
184
+ catch (err) {
185
+ this.error.emit(err);
186
+ }
187
+ finally {
188
+ this.isProcessing = false;
189
+ this.closed.emit();
190
+ }
191
+ }
192
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: ZahlenButtonComponent, deps: [{ token: ZahlenService }], target: i0.ɵɵFactoryTarget.Component });
193
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.9", type: ZahlenButtonComponent, isStandalone: true, selector: "zahlen-button", inputs: { amount: "amount", currency: "currency", description: "description", customerEmail: "customerEmail", metadata: "metadata", className: "className", disabled: "disabled" }, outputs: { success: "success", error: "error", closed: "closed" }, ngImport: i0, template: `
194
+ <button
195
+ type="button"
196
+ [disabled]="disabled || isProcessing"
197
+ [class]="'zahlen-btn ' + className"
198
+ [style]="buttonStyles"
199
+ (click)="handleClick()"
200
+ >
201
+ <ng-container *ngIf="isProcessing; else content">
202
+ <span class="zahlen-spinner"></span>
203
+ Processing...
204
+ </ng-container>
205
+ <ng-template #content>
206
+ <ng-content>💳 Pay {{ currency }} {{ amount / 100 | number:'1.2-2' }}</ng-content>
207
+ </ng-template>
208
+ </button>
209
+ `, isInline: true, styles: [".zahlen-btn{padding:14px 28px;background:linear-gradient(135deg,#7c3aed,#4f46e5);border:none;border-radius:10px;color:#fff;font-size:1rem;font-weight:600;font-family:inherit;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;gap:8px;transition:all .15s ease}.zahlen-btn:hover:not(:disabled){transform:translateY(-2px);box-shadow:0 10px 30px #7c3aed66}.zahlen-btn:disabled{opacity:.6;cursor:not-allowed}.zahlen-spinner{width:16px;height:16px;border:2px solid rgba(255,255,255,.3);border-top-color:#fff;border-radius:50%;animation:zahlen-spin .8s linear infinite}@keyframes zahlen-spin{to{transform:rotate(360deg)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i2.DecimalPipe, name: "number" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
210
+ }
211
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: ZahlenButtonComponent, decorators: [{
212
+ type: Component,
213
+ args: [{ selector: 'zahlen-button', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, template: `
214
+ <button
215
+ type="button"
216
+ [disabled]="disabled || isProcessing"
217
+ [class]="'zahlen-btn ' + className"
218
+ [style]="buttonStyles"
219
+ (click)="handleClick()"
220
+ >
221
+ <ng-container *ngIf="isProcessing; else content">
222
+ <span class="zahlen-spinner"></span>
223
+ Processing...
224
+ </ng-container>
225
+ <ng-template #content>
226
+ <ng-content>💳 Pay {{ currency }} {{ amount / 100 | number:'1.2-2' }}</ng-content>
227
+ </ng-template>
228
+ </button>
229
+ `, styles: [".zahlen-btn{padding:14px 28px;background:linear-gradient(135deg,#7c3aed,#4f46e5);border:none;border-radius:10px;color:#fff;font-size:1rem;font-weight:600;font-family:inherit;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;gap:8px;transition:all .15s ease}.zahlen-btn:hover:not(:disabled){transform:translateY(-2px);box-shadow:0 10px 30px #7c3aed66}.zahlen-btn:disabled{opacity:.6;cursor:not-allowed}.zahlen-spinner{width:16px;height:16px;border:2px solid rgba(255,255,255,.3);border-top-color:#fff;border-radius:50%;animation:zahlen-spin .8s linear infinite}@keyframes zahlen-spin{to{transform:rotate(360deg)}}\n"] }]
230
+ }], ctorParameters: () => [{ type: ZahlenService }], propDecorators: { amount: [{
231
+ type: Input
232
+ }], currency: [{
233
+ type: Input
234
+ }], description: [{
235
+ type: Input
236
+ }], customerEmail: [{
237
+ type: Input
238
+ }], metadata: [{
239
+ type: Input
240
+ }], className: [{
241
+ type: Input
242
+ }], disabled: [{
243
+ type: Input
244
+ }], success: [{
245
+ type: Output
246
+ }], error: [{
247
+ type: Output
248
+ }], closed: [{
249
+ type: Output
250
+ }] } });
251
+
252
+ /**
253
+ * ZahlenCheckout Directive - Attach checkout behavior to any element
254
+ */
255
+ class ZahlenCheckoutDirective {
256
+ zahlenService;
257
+ /** Payment amount in smallest currency unit */
258
+ amount;
259
+ /** Currency code (e.g., 'NGN', 'USD') */
260
+ currency = 'NGN';
261
+ /** Payment description */
262
+ description;
263
+ /** Customer email */
264
+ customerEmail;
265
+ /** Additional metadata */
266
+ metadata;
267
+ /** Emitted on successful payment */
268
+ success = new EventEmitter();
269
+ /** Emitted on payment error */
270
+ error = new EventEmitter();
271
+ /** Emitted when modal closes */
272
+ closed = new EventEmitter();
273
+ constructor(zahlenService) {
274
+ this.zahlenService = zahlenService;
275
+ }
276
+ async onClick() {
277
+ try {
278
+ const result = await this.zahlenService.openCheckout({
279
+ amount: this.amount,
280
+ currency: this.currency,
281
+ description: this.description,
282
+ customerEmail: this.customerEmail,
283
+ metadata: this.metadata,
284
+ });
285
+ this.success.emit(result);
286
+ }
287
+ catch (err) {
288
+ this.error.emit(err);
289
+ }
290
+ finally {
291
+ this.closed.emit();
292
+ }
293
+ }
294
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: ZahlenCheckoutDirective, deps: [{ token: ZahlenService }], target: i0.ɵɵFactoryTarget.Directive });
295
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.0.9", type: ZahlenCheckoutDirective, isStandalone: true, selector: "[zahlenCheckout]", inputs: { amount: ["zahlenAmount", "amount"], currency: ["zahlenCurrency", "currency"], description: ["zahlenDescription", "description"], customerEmail: ["zahlenEmail", "customerEmail"], metadata: ["zahlenMetadata", "metadata"] }, outputs: { success: "zahlenSuccess", error: "zahlenError", closed: "zahlenClose" }, host: { listeners: { "click": "onClick()" } }, ngImport: i0 });
296
+ }
297
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: ZahlenCheckoutDirective, decorators: [{
298
+ type: Directive,
299
+ args: [{
300
+ selector: '[zahlenCheckout]',
301
+ standalone: true
302
+ }]
303
+ }], ctorParameters: () => [{ type: ZahlenService }], propDecorators: { amount: [{
304
+ type: Input,
305
+ args: ['zahlenAmount']
306
+ }], currency: [{
307
+ type: Input,
308
+ args: ['zahlenCurrency']
309
+ }], description: [{
310
+ type: Input,
311
+ args: ['zahlenDescription']
312
+ }], customerEmail: [{
313
+ type: Input,
314
+ args: ['zahlenEmail']
315
+ }], metadata: [{
316
+ type: Input,
317
+ args: ['zahlenMetadata']
318
+ }], success: [{
319
+ type: Output,
320
+ args: ['zahlenSuccess']
321
+ }], error: [{
322
+ type: Output,
323
+ args: ['zahlenError']
324
+ }], closed: [{
325
+ type: Output,
326
+ args: ['zahlenClose']
327
+ }], onClick: [{
328
+ type: HostListener,
329
+ args: ['click']
330
+ }] } });
331
+
332
+ /**
333
+ * ZahlenModule - Angular module for Zahlen Checkout
334
+ */
335
+ class ZahlenModule {
336
+ /**
337
+ * Configure the Zahlen module with your API key
338
+ *
339
+ * @example
340
+ * ```typescript
341
+ * import { ZahlenModule } from '@zahlen/checkout-angular';
342
+ *
343
+ * @NgModule({
344
+ * imports: [
345
+ * ZahlenModule.forRoot({
346
+ * apiKey: 'pk_live_your_api_key',
347
+ * theme: 'dark'
348
+ * })
349
+ * ]
350
+ * })
351
+ * export class AppModule {}
352
+ * ```
353
+ */
354
+ static forRoot(config) {
355
+ return {
356
+ ngModule: ZahlenModule,
357
+ providers: [
358
+ { provide: ZAHLEN_CONFIG, useValue: config },
359
+ ZahlenService
360
+ ]
361
+ };
362
+ }
363
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: ZahlenModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
364
+ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.0.9", ngImport: i0, type: ZahlenModule, imports: [CommonModule,
365
+ ZahlenButtonComponent,
366
+ ZahlenCheckoutDirective], exports: [ZahlenButtonComponent,
367
+ ZahlenCheckoutDirective] });
368
+ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: ZahlenModule, imports: [CommonModule,
369
+ ZahlenButtonComponent] });
370
+ }
371
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: ZahlenModule, decorators: [{
372
+ type: NgModule,
373
+ args: [{
374
+ imports: [
375
+ CommonModule,
376
+ ZahlenButtonComponent,
377
+ ZahlenCheckoutDirective
378
+ ],
379
+ exports: [
380
+ ZahlenButtonComponent,
381
+ ZahlenCheckoutDirective
382
+ ]
383
+ }]
384
+ }] });
385
+
386
+ /**
387
+ * @zahlen/checkout-angular - Angular module for Zahlen Checkout
388
+ *
389
+ * @example
390
+ * ```typescript
391
+ * import { ZahlenModule } from '@zahlen/checkout-angular';
392
+ *
393
+ * @NgModule({
394
+ * imports: [
395
+ * ZahlenModule.forRoot({
396
+ * apiKey: 'pk_live_xxx',
397
+ * theme: 'dark'
398
+ * })
399
+ * ]
400
+ * })
401
+ * export class AppModule {}
402
+ * ```
403
+ */
404
+ // Module
405
+
406
+ /**
407
+ * Generated bundle index. Do not edit.
408
+ */
409
+
410
+ export { ZAHLEN_CONFIG, ZahlenButtonComponent, ZahlenCheckoutDirective, ZahlenModule, ZahlenService };
411
+ //# sourceMappingURL=zahlen-checkout-angular.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zahlen-checkout-angular.mjs","sources":["../../../../libs/zahlen-checkout-angular/src/lib/zahlen.config.ts","../../../../libs/zahlen-checkout-angular/src/lib/zahlen.service.ts","../../../../libs/zahlen-checkout-angular/src/lib/zahlen-button.component.ts","../../../../libs/zahlen-checkout-angular/src/lib/zahlen-checkout.directive.ts","../../../../libs/zahlen-checkout-angular/src/lib/zahlen.module.ts","../../../../libs/zahlen-checkout-angular/src/index.ts","../../../../libs/zahlen-checkout-angular/src/zahlen-checkout-angular.ts"],"sourcesContent":["/**\n * Zahlen Checkout Angular - Configuration\n */\n\nimport { InjectionToken } from '@angular/core';\n\n/**\n * Configuration for Zahlen Module\n */\nexport interface ZahlenConfig {\n /** Your Zahlen API key (starts with pk_live_ or pk_test_) */\n apiKey: string;\n /** Theme mode: 'dark' (default), 'light', or 'auto' */\n theme?: 'dark' | 'light' | 'auto';\n}\n\n/**\n * Injection token for Zahlen configuration\n */\nexport const ZAHLEN_CONFIG = new InjectionToken<ZahlenConfig>('ZAHLEN_CONFIG');\n\n/**\n * Checkout options for opening the payment modal\n */\nexport interface CheckoutOptions {\n /** Payment amount in smallest currency unit (e.g., kobo for NGN) */\n amount: number;\n /** ISO 4217 currency code (e.g., 'NGN', 'USD') */\n currency: string;\n /** Short description of the payment */\n description?: string;\n /** Customer's email address */\n customerEmail?: string;\n /** Additional metadata */\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Result returned on successful payment\n */\nexport interface PaymentResult {\n /** Unique payment ID */\n id: string;\n /** Payment status */\n status: 'success' | 'pending';\n /** Amount charged in smallest currency unit */\n amount: number;\n /** Currency code */\n currency: string;\n /** ISO timestamp of the payment */\n timestamp: string;\n /** Transaction reference */\n reference?: string;\n}\n\n/**\n * Error returned on payment failure\n */\nexport interface PaymentError {\n /** Error code */\n code: string;\n /** Human-readable error message */\n message: string;\n /** Whether the error is recoverable */\n recoverable?: boolean;\n}\n","/**\n * Zahlen Service - Injectable service for programmatic checkout control\n */\n\nimport { Injectable, Inject, Optional } from '@angular/core';\nimport { ZAHLEN_CONFIG, ZahlenConfig, CheckoutOptions, PaymentResult, PaymentError } from './zahlen.config';\n\n// Declare Zahlen as a global (loaded from @zahlen/checkout)\ndeclare const Zahlen: {\n init: (config: ZahlenConfig) => void;\n checkout: (options: CheckoutOptions & {\n onSuccess: (result: PaymentResult) => void;\n onError: (error: PaymentError) => void;\n onClose?: () => void;\n }) => void;\n closeModal: () => void;\n setTheme: (theme: 'dark' | 'light' | 'auto') => void;\n isInitialized: boolean;\n};\n\n@Injectable({\n providedIn: 'root'\n})\nexport class ZahlenService {\n private initialized = false;\n\n constructor(\n @Optional() @Inject(ZAHLEN_CONFIG) private config: ZahlenConfig | null\n ) {\n // Auto-initialize if config is provided via forRoot\n if (this.config?.apiKey) {\n this.init(this.config);\n }\n }\n\n /**\n * Initialize Zahlen SDK\n * @param config - Configuration with API key\n */\n init(config: ZahlenConfig): void {\n if (this.initialized) return;\n\n if (typeof Zahlen !== 'undefined') {\n Zahlen.init(config);\n this.initialized = true;\n } else {\n console.error('[ZahlenService] Zahlen SDK not loaded. Make sure @zahlen/checkout is imported.');\n }\n }\n\n /**\n * Open checkout modal with promise interface\n * @param options - Checkout options\n * @returns Promise resolving to PaymentResult or rejecting with PaymentError\n * \n * @example\n * ```typescript\n * async checkout() {\n * try {\n * const result = await this.zahlenService.openCheckout({\n * amount: 499900,\n * currency: 'NGN',\n * description: 'Premium Plan'\n * });\n * console.log('Payment successful!', result);\n * } catch (error) {\n * console.error('Payment failed:', error);\n * }\n * }\n * ```\n */\n openCheckout(options: CheckoutOptions): Promise<PaymentResult> {\n return new Promise((resolve, reject) => {\n if (!this.initialized) {\n reject({\n code: 'NOT_INITIALIZED',\n message: 'Zahlen SDK not initialized. Call init() or use ZahlenModule.forRoot()',\n recoverable: false\n } as PaymentError);\n return;\n }\n\n Zahlen.checkout({\n ...options,\n onSuccess: (result) => resolve(result),\n onError: (error) => reject(error),\n });\n });\n }\n\n /**\n * Open checkout modal with callbacks\n * @param options - Checkout options with callbacks\n */\n checkout(\n options: CheckoutOptions,\n onSuccess: (result: PaymentResult) => void,\n onError: (error: PaymentError) => void,\n onClose?: () => void\n ): void {\n if (!this.initialized) {\n onError({\n code: 'NOT_INITIALIZED',\n message: 'Zahlen SDK not initialized',\n recoverable: false\n });\n return;\n }\n\n Zahlen.checkout({\n ...options,\n onSuccess,\n onError,\n onClose\n });\n }\n\n /**\n * Close the checkout modal\n */\n closeCheckout(): void {\n if (typeof Zahlen !== 'undefined') {\n Zahlen.closeModal();\n }\n }\n\n /**\n * Change the theme\n * @param theme - 'dark', 'light', or 'auto'\n */\n setTheme(theme: 'dark' | 'light' | 'auto'): void {\n if (typeof Zahlen !== 'undefined') {\n Zahlen.setTheme(theme);\n }\n }\n\n /**\n * Check if SDK is initialized\n */\n get isInitialized(): boolean {\n return this.initialized;\n }\n}\n","/**\n * ZahlenButton Component - Pre-styled checkout button\n */\n\nimport { Component, Input, Output, EventEmitter, ChangeDetectionStrategy } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { ZahlenService } from './zahlen.service';\nimport { PaymentResult, PaymentError } from './zahlen.config';\n\n@Component({\n selector: 'zahlen-button',\n standalone: true,\n imports: [CommonModule],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <button\n type=\"button\"\n [disabled]=\"disabled || isProcessing\"\n [class]=\"'zahlen-btn ' + className\"\n [style]=\"buttonStyles\"\n (click)=\"handleClick()\"\n >\n <ng-container *ngIf=\"isProcessing; else content\">\n <span class=\"zahlen-spinner\"></span>\n Processing...\n </ng-container>\n <ng-template #content>\n <ng-content>💳 Pay {{ currency }} {{ amount / 100 | number:'1.2-2' }}</ng-content>\n </ng-template>\n </button>\n `,\n styles: [`\n .zahlen-btn {\n padding: 14px 28px;\n background: linear-gradient(135deg, #7C3AED, #4F46E5);\n border: none;\n border-radius: 10px;\n color: white;\n font-size: 1rem;\n font-weight: 600;\n font-family: inherit;\n cursor: pointer;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n transition: all 0.15s ease;\n }\n\n .zahlen-btn:hover:not(:disabled) {\n transform: translateY(-2px);\n box-shadow: 0 10px 30px rgba(124, 58, 237, 0.4);\n }\n\n .zahlen-btn:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n\n .zahlen-spinner {\n width: 16px;\n height: 16px;\n border: 2px solid rgba(255,255,255,0.3);\n border-top-color: white;\n border-radius: 50%;\n animation: zahlen-spin 0.8s linear infinite;\n }\n\n @keyframes zahlen-spin {\n to { transform: rotate(360deg); }\n }\n `]\n})\nexport class ZahlenButtonComponent {\n /** Payment amount in smallest currency unit (e.g., kobo) */\n @Input() amount!: number;\n\n /** Currency code (e.g., 'NGN', 'USD') */\n @Input() currency = 'NGN';\n\n /** Payment description */\n @Input() description?: string;\n\n /** Customer email */\n @Input() customerEmail?: string;\n\n /** Additional metadata */\n @Input() metadata?: Record<string, unknown>;\n\n /** Additional CSS class */\n @Input() className = '';\n\n /** Disable the button */\n @Input() disabled = false;\n\n /** Emitted on successful payment */\n @Output() success = new EventEmitter<PaymentResult>();\n\n /** Emitted on payment error */\n @Output() error = new EventEmitter<PaymentError>();\n\n /** Emitted when modal closes */\n @Output() closed = new EventEmitter<void>();\n\n isProcessing = false;\n\n constructor(private zahlenService: ZahlenService) { }\n\n get buttonStyles(): Record<string, string> {\n return {};\n }\n\n async handleClick(): Promise<void> {\n if (this.disabled || this.isProcessing) return;\n\n this.isProcessing = true;\n\n try {\n const result = await this.zahlenService.openCheckout({\n amount: this.amount,\n currency: this.currency,\n description: this.description,\n customerEmail: this.customerEmail,\n metadata: this.metadata,\n });\n\n this.success.emit(result);\n } catch (err) {\n this.error.emit(err as PaymentError);\n } finally {\n this.isProcessing = false;\n this.closed.emit();\n }\n }\n}\n","/**\n * ZahlenCheckout Directive - Attach checkout behavior to any element\n */\n\nimport { Directive, Input, Output, EventEmitter, HostListener } from '@angular/core';\nimport { ZahlenService } from './zahlen.service';\nimport { PaymentResult, PaymentError } from './zahlen.config';\n\n@Directive({\n selector: '[zahlenCheckout]',\n standalone: true\n})\nexport class ZahlenCheckoutDirective {\n /** Payment amount in smallest currency unit */\n @Input('zahlenAmount') amount!: number;\n\n /** Currency code (e.g., 'NGN', 'USD') */\n @Input('zahlenCurrency') currency = 'NGN';\n\n /** Payment description */\n @Input('zahlenDescription') description?: string;\n\n /** Customer email */\n @Input('zahlenEmail') customerEmail?: string;\n\n /** Additional metadata */\n @Input('zahlenMetadata') metadata?: Record<string, unknown>;\n\n /** Emitted on successful payment */\n @Output('zahlenSuccess') success = new EventEmitter<PaymentResult>();\n\n /** Emitted on payment error */\n @Output('zahlenError') error = new EventEmitter<PaymentError>();\n\n /** Emitted when modal closes */\n @Output('zahlenClose') closed = new EventEmitter<void>();\n\n constructor(private zahlenService: ZahlenService) { }\n\n @HostListener('click')\n async onClick(): Promise<void> {\n try {\n const result = await this.zahlenService.openCheckout({\n amount: this.amount,\n currency: this.currency,\n description: this.description,\n customerEmail: this.customerEmail,\n metadata: this.metadata,\n });\n\n this.success.emit(result);\n } catch (err) {\n this.error.emit(err as PaymentError);\n } finally {\n this.closed.emit();\n }\n }\n}\n","/**\n * ZahlenModule - Angular module for Zahlen Checkout\n */\n\nimport { NgModule, ModuleWithProviders } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { ZahlenService } from './zahlen.service';\nimport { ZahlenButtonComponent } from './zahlen-button.component';\nimport { ZahlenCheckoutDirective } from './zahlen-checkout.directive';\nimport { ZAHLEN_CONFIG, ZahlenConfig } from './zahlen.config';\n\n@NgModule({\n imports: [\n CommonModule,\n ZahlenButtonComponent,\n ZahlenCheckoutDirective\n ],\n exports: [\n ZahlenButtonComponent,\n ZahlenCheckoutDirective\n ]\n})\nexport class ZahlenModule {\n /**\n * Configure the Zahlen module with your API key\n * \n * @example\n * ```typescript\n * import { ZahlenModule } from '@zahlen/checkout-angular';\n * \n * @NgModule({\n * imports: [\n * ZahlenModule.forRoot({\n * apiKey: 'pk_live_your_api_key',\n * theme: 'dark'\n * })\n * ]\n * })\n * export class AppModule {}\n * ```\n */\n static forRoot(config: ZahlenConfig): ModuleWithProviders<ZahlenModule> {\n return {\n ngModule: ZahlenModule,\n providers: [\n { provide: ZAHLEN_CONFIG, useValue: config },\n ZahlenService\n ]\n };\n }\n}\n","/**\n * @zahlen/checkout-angular - Angular module for Zahlen Checkout\n * \n * @example\n * ```typescript\n * import { ZahlenModule } from '@zahlen/checkout-angular';\n * \n * @NgModule({\n * imports: [\n * ZahlenModule.forRoot({\n * apiKey: 'pk_live_xxx',\n * theme: 'dark'\n * })\n * ]\n * })\n * export class AppModule {}\n * ```\n */\n\n// Module\nexport { ZahlenModule } from './lib/zahlen.module';\n\n// Service\nexport { ZahlenService } from './lib/zahlen.service';\n\n// Components\nexport { ZahlenButtonComponent } from './lib/zahlen-button.component';\nexport { ZahlenCheckoutDirective } from './lib/zahlen-checkout.directive';\n\n// Config & Types\nexport {\n ZAHLEN_CONFIG\n} from './lib/zahlen.config';\n\nexport type {\n ZahlenConfig,\n CheckoutOptions,\n PaymentResult,\n PaymentError\n} from './lib/zahlen.config';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["i1.ZahlenService"],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "@zahlen/checkout-angular",
3
+ "version": "0.1.0",
4
+ "description": "Angular module for Zahlen Checkout - Modern payment modal",
5
+ "author": "Zahlen",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/Havenix-Technologies-LTD/zahlen.git",
10
+ "directory": "libs/zahlen-checkout-angular"
11
+ },
12
+ "bugs": {
13
+ "url": "https://github.com/Havenix-Technologies-LTD/zahlen/issues"
14
+ },
15
+ "peerDependencies": {
16
+ "@angular/common": "^17.0.0 || ^18.0.0 || ^19.0.0",
17
+ "@angular/core": "^17.0.0 || ^18.0.0 || ^19.0.0",
18
+ "@zahlen/checkout": ">=0.1.0"
19
+ },
20
+ "sideEffects": false,
21
+ "module": "fesm2022/zahlen-checkout-angular.mjs",
22
+ "typings": "types/zahlen-checkout-angular.d.ts",
23
+ "exports": {
24
+ "./package.json": {
25
+ "default": "./package.json"
26
+ },
27
+ ".": {
28
+ "types": "./types/zahlen-checkout-angular.d.ts",
29
+ "default": "./fesm2022/zahlen-checkout-angular.mjs"
30
+ }
31
+ },
32
+ "dependencies": {
33
+ "tslib": "^2.3.0"
34
+ }
35
+ }
@@ -0,0 +1,211 @@
1
+ import * as i0 from '@angular/core';
2
+ import { InjectionToken, EventEmitter, ModuleWithProviders } from '@angular/core';
3
+ import * as i1 from '@angular/common';
4
+
5
+ /**
6
+ * Zahlen Checkout Angular - Configuration
7
+ */
8
+
9
+ /**
10
+ * Configuration for Zahlen Module
11
+ */
12
+ interface ZahlenConfig {
13
+ /** Your Zahlen API key (starts with pk_live_ or pk_test_) */
14
+ apiKey: string;
15
+ /** Theme mode: 'dark' (default), 'light', or 'auto' */
16
+ theme?: 'dark' | 'light' | 'auto';
17
+ }
18
+ /**
19
+ * Injection token for Zahlen configuration
20
+ */
21
+ declare const ZAHLEN_CONFIG: InjectionToken<ZahlenConfig>;
22
+ /**
23
+ * Checkout options for opening the payment modal
24
+ */
25
+ interface CheckoutOptions {
26
+ /** Payment amount in smallest currency unit (e.g., kobo for NGN) */
27
+ amount: number;
28
+ /** ISO 4217 currency code (e.g., 'NGN', 'USD') */
29
+ currency: string;
30
+ /** Short description of the payment */
31
+ description?: string;
32
+ /** Customer's email address */
33
+ customerEmail?: string;
34
+ /** Additional metadata */
35
+ metadata?: Record<string, unknown>;
36
+ }
37
+ /**
38
+ * Result returned on successful payment
39
+ */
40
+ interface PaymentResult {
41
+ /** Unique payment ID */
42
+ id: string;
43
+ /** Payment status */
44
+ status: 'success' | 'pending';
45
+ /** Amount charged in smallest currency unit */
46
+ amount: number;
47
+ /** Currency code */
48
+ currency: string;
49
+ /** ISO timestamp of the payment */
50
+ timestamp: string;
51
+ /** Transaction reference */
52
+ reference?: string;
53
+ }
54
+ /**
55
+ * Error returned on payment failure
56
+ */
57
+ interface PaymentError {
58
+ /** Error code */
59
+ code: string;
60
+ /** Human-readable error message */
61
+ message: string;
62
+ /** Whether the error is recoverable */
63
+ recoverable?: boolean;
64
+ }
65
+
66
+ declare class ZahlenService {
67
+ private config;
68
+ private initialized;
69
+ constructor(config: ZahlenConfig | null);
70
+ /**
71
+ * Initialize Zahlen SDK
72
+ * @param config - Configuration with API key
73
+ */
74
+ init(config: ZahlenConfig): void;
75
+ /**
76
+ * Open checkout modal with promise interface
77
+ * @param options - Checkout options
78
+ * @returns Promise resolving to PaymentResult or rejecting with PaymentError
79
+ *
80
+ * @example
81
+ * ```typescript
82
+ * async checkout() {
83
+ * try {
84
+ * const result = await this.zahlenService.openCheckout({
85
+ * amount: 499900,
86
+ * currency: 'NGN',
87
+ * description: 'Premium Plan'
88
+ * });
89
+ * console.log('Payment successful!', result);
90
+ * } catch (error) {
91
+ * console.error('Payment failed:', error);
92
+ * }
93
+ * }
94
+ * ```
95
+ */
96
+ openCheckout(options: CheckoutOptions): Promise<PaymentResult>;
97
+ /**
98
+ * Open checkout modal with callbacks
99
+ * @param options - Checkout options with callbacks
100
+ */
101
+ checkout(options: CheckoutOptions, onSuccess: (result: PaymentResult) => void, onError: (error: PaymentError) => void, onClose?: () => void): void;
102
+ /**
103
+ * Close the checkout modal
104
+ */
105
+ closeCheckout(): void;
106
+ /**
107
+ * Change the theme
108
+ * @param theme - 'dark', 'light', or 'auto'
109
+ */
110
+ setTheme(theme: 'dark' | 'light' | 'auto'): void;
111
+ /**
112
+ * Check if SDK is initialized
113
+ */
114
+ get isInitialized(): boolean;
115
+ static ɵfac: i0.ɵɵFactoryDeclaration<ZahlenService, [{ optional: true; }]>;
116
+ static ɵprov: i0.ɵɵInjectableDeclaration<ZahlenService>;
117
+ }
118
+
119
+ /**
120
+ * ZahlenButton Component - Pre-styled checkout button
121
+ */
122
+
123
+ declare class ZahlenButtonComponent {
124
+ private zahlenService;
125
+ /** Payment amount in smallest currency unit (e.g., kobo) */
126
+ amount: number;
127
+ /** Currency code (e.g., 'NGN', 'USD') */
128
+ currency: string;
129
+ /** Payment description */
130
+ description?: string;
131
+ /** Customer email */
132
+ customerEmail?: string;
133
+ /** Additional metadata */
134
+ metadata?: Record<string, unknown>;
135
+ /** Additional CSS class */
136
+ className: string;
137
+ /** Disable the button */
138
+ disabled: boolean;
139
+ /** Emitted on successful payment */
140
+ success: EventEmitter<PaymentResult>;
141
+ /** Emitted on payment error */
142
+ error: EventEmitter<PaymentError>;
143
+ /** Emitted when modal closes */
144
+ closed: EventEmitter<void>;
145
+ isProcessing: boolean;
146
+ constructor(zahlenService: ZahlenService);
147
+ get buttonStyles(): Record<string, string>;
148
+ handleClick(): Promise<void>;
149
+ static ɵfac: i0.ɵɵFactoryDeclaration<ZahlenButtonComponent, never>;
150
+ static ɵcmp: i0.ɵɵComponentDeclaration<ZahlenButtonComponent, "zahlen-button", never, { "amount": { "alias": "amount"; "required": false; }; "currency": { "alias": "currency"; "required": false; }; "description": { "alias": "description"; "required": false; }; "customerEmail": { "alias": "customerEmail"; "required": false; }; "metadata": { "alias": "metadata"; "required": false; }; "className": { "alias": "className"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; }, { "success": "success"; "error": "error"; "closed": "closed"; }, never, ["*"], true, never>;
151
+ }
152
+
153
+ /**
154
+ * ZahlenCheckout Directive - Attach checkout behavior to any element
155
+ */
156
+
157
+ declare class ZahlenCheckoutDirective {
158
+ private zahlenService;
159
+ /** Payment amount in smallest currency unit */
160
+ amount: number;
161
+ /** Currency code (e.g., 'NGN', 'USD') */
162
+ currency: string;
163
+ /** Payment description */
164
+ description?: string;
165
+ /** Customer email */
166
+ customerEmail?: string;
167
+ /** Additional metadata */
168
+ metadata?: Record<string, unknown>;
169
+ /** Emitted on successful payment */
170
+ success: EventEmitter<PaymentResult>;
171
+ /** Emitted on payment error */
172
+ error: EventEmitter<PaymentError>;
173
+ /** Emitted when modal closes */
174
+ closed: EventEmitter<void>;
175
+ constructor(zahlenService: ZahlenService);
176
+ onClick(): Promise<void>;
177
+ static ɵfac: i0.ɵɵFactoryDeclaration<ZahlenCheckoutDirective, never>;
178
+ static ɵdir: i0.ɵɵDirectiveDeclaration<ZahlenCheckoutDirective, "[zahlenCheckout]", never, { "amount": { "alias": "zahlenAmount"; "required": false; }; "currency": { "alias": "zahlenCurrency"; "required": false; }; "description": { "alias": "zahlenDescription"; "required": false; }; "customerEmail": { "alias": "zahlenEmail"; "required": false; }; "metadata": { "alias": "zahlenMetadata"; "required": false; }; }, { "success": "zahlenSuccess"; "error": "zahlenError"; "closed": "zahlenClose"; }, never, never, true, never>;
179
+ }
180
+
181
+ /**
182
+ * ZahlenModule - Angular module for Zahlen Checkout
183
+ */
184
+
185
+ declare class ZahlenModule {
186
+ /**
187
+ * Configure the Zahlen module with your API key
188
+ *
189
+ * @example
190
+ * ```typescript
191
+ * import { ZahlenModule } from '@zahlen/checkout-angular';
192
+ *
193
+ * @NgModule({
194
+ * imports: [
195
+ * ZahlenModule.forRoot({
196
+ * apiKey: 'pk_live_your_api_key',
197
+ * theme: 'dark'
198
+ * })
199
+ * ]
200
+ * })
201
+ * export class AppModule {}
202
+ * ```
203
+ */
204
+ static forRoot(config: ZahlenConfig): ModuleWithProviders<ZahlenModule>;
205
+ static ɵfac: i0.ɵɵFactoryDeclaration<ZahlenModule, never>;
206
+ static ɵmod: i0.ɵɵNgModuleDeclaration<ZahlenModule, never, [typeof i1.CommonModule, typeof ZahlenButtonComponent, typeof ZahlenCheckoutDirective], [typeof ZahlenButtonComponent, typeof ZahlenCheckoutDirective]>;
207
+ static ɵinj: i0.ɵɵInjectorDeclaration<ZahlenModule>;
208
+ }
209
+
210
+ export { ZAHLEN_CONFIG, ZahlenButtonComponent, ZahlenCheckoutDirective, ZahlenModule, ZahlenService };
211
+ export type { CheckoutOptions, PaymentError, PaymentResult, ZahlenConfig };