angular-klasha 0.0.1 → 1.0.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.
@@ -0,0 +1,545 @@
1
+ import * as i0 from '@angular/core';
2
+ import { InjectionToken, inject, PLATFORM_ID, Injectable, EventEmitter, Output, Input, Directive, ChangeDetectionStrategy, Component, HostListener, makeEnvironmentProviders, NgModule } from '@angular/core';
3
+ import { DOCUMENT, isPlatformBrowser, NgClass, NgStyle } from '@angular/common';
4
+
5
+ /**
6
+ * The URL of the Klasha inline checkout script.
7
+ *
8
+ * The buckets used by `angular-klasha@0.0.x`
9
+ * (`https://klastatic.fra1.digitaloceanspaces.com/{test,prod}/js/klasha-integration.js`)
10
+ * have been deleted and return `NoSuchBucket`. There is now a single script for
11
+ * both environments; the environment is selected by the `isTestMode`
12
+ * constructor argument instead of by the script URL.
13
+ */
14
+ const KLASHA_SCRIPT_URL = 'https://js.klasha.com/pay.js';
15
+ /**
16
+ * Merchant API key used when a component/directive does not supply its own.
17
+ */
18
+ const MERCHANT_KEY = new InjectionToken('klasha.merchantKey', {
19
+ providedIn: 'root',
20
+ factory: () => '',
21
+ });
22
+ /**
23
+ * Merchant business id used when a component/directive does not supply its own.
24
+ */
25
+ const BUSINESS_ID = new InjectionToken('klasha.businessId', {
26
+ providedIn: 'root',
27
+ factory: () => '',
28
+ });
29
+ /**
30
+ * Whether to use the Klasha sandbox. Defaults to `false` (live gateway).
31
+ */
32
+ const IS_TEST_MODE = new InjectionToken('klasha.isTestMode', {
33
+ providedIn: 'root',
34
+ factory: () => false,
35
+ });
36
+
37
+ /** Marks script tags and container divs created by this library. */
38
+ const SCRIPT_MARKER = 'data-angular-klasha';
39
+ const CONTAINER_MARKER = 'data-angular-klasha-container';
40
+ let containerSequence = 0;
41
+ /**
42
+ * Returns a process-unique DOM id for a checkout container. Each component or
43
+ * directive instance owns exactly one, so two payment buttons on the same page
44
+ * can never collide (0.0.x hardcoded `ktest` for every instance).
45
+ */
46
+ function nextKlashaContainerId() {
47
+ containerSequence += 1;
48
+ return `klasha-container-${containerSequence}`;
49
+ }
50
+ class AngularKlashaService {
51
+ merchantKey = inject(MERCHANT_KEY, { optional: true });
52
+ businessId = inject(BUSINESS_ID, { optional: true });
53
+ isTestMode = inject(IS_TEST_MODE, { optional: true });
54
+ document = inject(DOCUMENT);
55
+ isBrowser = isPlatformBrowser(inject(PLATFORM_ID));
56
+ scriptPromise = null;
57
+ /**
58
+ * The window the checkout script is loaded into. `null` on the server.
59
+ */
60
+ get window() {
61
+ return this.isBrowser
62
+ ? this.document.defaultView
63
+ : null;
64
+ }
65
+ /**
66
+ * Loads `https://js.klasha.com/pay.js` exactly once and resolves when
67
+ * `window.KlashaClient` is available.
68
+ *
69
+ * jQuery is deliberately not loaded: `pay.js` does not use it.
70
+ */
71
+ loadScript() {
72
+ if (!this.isBrowser) {
73
+ return Promise.reject(new Error('angular-klasha: Klasha checkout can only be loaded in a browser'));
74
+ }
75
+ if (typeof this.window?.KlashaClient === 'function') {
76
+ return Promise.resolve();
77
+ }
78
+ if (this.scriptPromise) {
79
+ return this.scriptPromise;
80
+ }
81
+ this.scriptPromise = new Promise((resolve, reject) => {
82
+ const doc = this.document;
83
+ const existing = doc.querySelector(`script[${SCRIPT_MARKER}]`);
84
+ const script = existing ?? doc.createElement('script');
85
+ const onLoad = () => {
86
+ cleanup();
87
+ resolve();
88
+ };
89
+ const onError = () => {
90
+ cleanup();
91
+ this.scriptPromise = null;
92
+ script.remove();
93
+ reject(new Error(`angular-klasha: failed to load ${KLASHA_SCRIPT_URL}`));
94
+ };
95
+ const cleanup = () => {
96
+ script.removeEventListener('load', onLoad);
97
+ script.removeEventListener('error', onError);
98
+ };
99
+ script.addEventListener('load', onLoad);
100
+ script.addEventListener('error', onError);
101
+ if (!existing) {
102
+ script.setAttribute(SCRIPT_MARKER, '');
103
+ script.async = true;
104
+ script.src = KLASHA_SCRIPT_URL;
105
+ doc.head.appendChild(script);
106
+ }
107
+ });
108
+ return this.scriptPromise;
109
+ }
110
+ /**
111
+ * Returns the checkout container for `containerId`, creating it only when it
112
+ * does not already exist. Repeated calls never append a second element with
113
+ * the same id.
114
+ */
115
+ ensureContainer(containerId) {
116
+ if (!this.isBrowser) {
117
+ return null;
118
+ }
119
+ const existing = this.document.getElementById(containerId);
120
+ if (existing) {
121
+ return existing;
122
+ }
123
+ const container = this.document.createElement('div');
124
+ container.id = containerId;
125
+ container.setAttribute(CONTAINER_MARKER, '');
126
+ this.document.body.appendChild(container);
127
+ return container;
128
+ }
129
+ /**
130
+ * Removes a container previously created by {@link ensureContainer}. Called
131
+ * from `ngOnDestroy` so remounting does not leak DOM nodes.
132
+ */
133
+ removeContainer(containerId) {
134
+ if (!this.isBrowser) {
135
+ return;
136
+ }
137
+ const container = this.document.getElementById(containerId);
138
+ if (container?.hasAttribute(CONTAINER_MARKER)) {
139
+ container.remove();
140
+ }
141
+ }
142
+ /**
143
+ * Instantiates `KlashaClient` and opens the checkout.
144
+ *
145
+ * The 9th argument (`isTestMode`) is the fix for the headline bug in
146
+ * `angular-klasha@0.0.x`: it was never passed, so `isTestMode` was
147
+ * `undefined` inside `pay.js` and every sandbox payment hit the LIVE gateway.
148
+ * It is coerced with `Boolean()` because `pay.js` only branches on
149
+ * truthiness — the string `'false'` would otherwise select production.
150
+ */
151
+ launch(options, containerId) {
152
+ const KlashaClient = this.window?.KlashaClient;
153
+ if (typeof KlashaClient !== 'function') {
154
+ throw new Error('angular-klasha: window.KlashaClient is not available — call loadScript() first');
155
+ }
156
+ this.ensureContainer(containerId);
157
+ const client = new KlashaClient(options.merchantKey, options.businessId || 1, options.amount, containerId, options.callbackUrl ?? '', options.destinationCurrency, options.sourceCurrency, options.kit, Boolean(options.isTestMode));
158
+ client.init();
159
+ return client;
160
+ }
161
+ /**
162
+ * Validates the merchant supplied options. Returns an empty string when the
163
+ * options are usable, otherwise a human readable error message.
164
+ */
165
+ checkInput(obj) {
166
+ if (!obj.merchantKey && !this.merchantKey) {
167
+ return 'angular-klasha: Klasha merchantKey cannot be empty';
168
+ }
169
+ if (!obj.businessId && !this.businessId) {
170
+ return 'angular-klasha: Klasha businessId cannot be empty';
171
+ }
172
+ if (!obj.email) {
173
+ return 'angular-klasha: Klasha email cannot be empty';
174
+ }
175
+ if (!obj.fullname) {
176
+ return 'angular-klasha: Klasha name cannot be empty';
177
+ }
178
+ if (!obj.phone && !obj.phone_number) {
179
+ return 'angular-klasha: Klasha phone cannot be empty';
180
+ }
181
+ if (!obj.amount) {
182
+ return 'angular-klasha: Klasha amount cannot be empty';
183
+ }
184
+ return '';
185
+ }
186
+ /**
187
+ * Resolves merchant supplied options against the globally configured
188
+ * merchant key / business id / test mode, and builds a **fresh** `kit`
189
+ * object (`pay.js` mutates the kit it is given).
190
+ */
191
+ getKlashaOptions(obj) {
192
+ const kit = obj.kit ?? {};
193
+ const sourceCurrency = obj.sourceCurrency || 'NGN';
194
+ const destinationCurrency = obj.destinationCurrency || 'NGN';
195
+ const phone = obj.phone || obj.phone_number || kit.phone || kit.phone_number || '';
196
+ const email = obj.email || kit.email || '';
197
+ const fullname = obj.fullname || kit.fullname || '';
198
+ const txRef = obj.tx_ref || kit.tx_ref || this.makeId(8);
199
+ const productType = kit.productType || kit.paymentType || '';
200
+ const resolved = {
201
+ isTestMode: Boolean(obj.isTestMode ?? this.isTestMode ?? false),
202
+ merchantKey: obj.merchantKey || this.merchantKey || '',
203
+ businessId: obj.businessId || this.businessId || '',
204
+ amount: obj.amount,
205
+ tx_ref: txRef,
206
+ sourceCurrency,
207
+ destinationCurrency,
208
+ fullname,
209
+ email,
210
+ phone,
211
+ // Retained for backwards compatibility with 0.0.x integrations.
212
+ phone_number: phone,
213
+ paymentDescription: obj.paymentDescription || '',
214
+ callbackUrl: obj.callbackUrl || '',
215
+ metadata: obj.metadata ?? {},
216
+ kit: this.clean({
217
+ currency: kit.currency || sourceCurrency,
218
+ // `pay.js` reads `phone`; `phone_number` is never read by it.
219
+ phone,
220
+ phone_number: phone,
221
+ email,
222
+ fullname,
223
+ tx_ref: txRef,
224
+ productType,
225
+ // Retained for backwards compatibility with 0.0.x integrations.
226
+ paymentType: productType,
227
+ amount: kit.amount ?? obj.amount,
228
+ sourceAmount: kit.sourceAmount,
229
+ }),
230
+ };
231
+ return this.clean(resolved);
232
+ }
233
+ /**
234
+ * Removes `null`/`undefined` entries so they are not serialised into the
235
+ * request `pay.js` makes.
236
+ */
237
+ clean(obj) {
238
+ const record = obj;
239
+ for (const propName of Object.keys(record)) {
240
+ if (record[propName] === null || record[propName] === undefined) {
241
+ delete record[propName];
242
+ }
243
+ }
244
+ return obj;
245
+ }
246
+ /** Generates a random alphanumeric transaction reference. */
247
+ makeId(length = 8) {
248
+ const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
249
+ let result = '';
250
+ for (let i = 0; i < length; i++) {
251
+ result += characters.charAt(Math.floor(Math.random() * characters.length));
252
+ }
253
+ return result;
254
+ }
255
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.26", ngImport: i0, type: AngularKlashaService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
256
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.26", ngImport: i0, type: AngularKlashaService, providedIn: 'root' });
257
+ }
258
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.26", ngImport: i0, type: AngularKlashaService, decorators: [{
259
+ type: Injectable,
260
+ args: [{ providedIn: 'root' }]
261
+ }] });
262
+
263
+ /**
264
+ * Shared implementation behind {@link AngularKlashaComponent} and
265
+ * {@link AngularKlashaDirective}. Not usable on its own — it has no selector.
266
+ */
267
+ class AngularKlashaBase {
268
+ /** Merchant API key. Overrides the value given to `provideKlasha()`/`forRoot()`. */
269
+ merchantKey;
270
+ /** `true` uses the Klasha sandbox, `false` the live gateway. */
271
+ isTestMode;
272
+ /** Merchant business id. Overrides the globally configured one. */
273
+ businessId;
274
+ /** Amount to charge. */
275
+ amount;
276
+ /** Free-form extra data. */
277
+ metadata;
278
+ /** Unique transaction reference. Generated when omitted. */
279
+ tx_ref;
280
+ /** @deprecated Use `sourceCurrency`/`destinationCurrency`. */
281
+ currency;
282
+ /** Customer full name. */
283
+ fullname;
284
+ /** Customer email address. */
285
+ email;
286
+ /** Customer phone number. */
287
+ phone;
288
+ /** @deprecated Use `phone`. */
289
+ phone_number;
290
+ /** Currency the merchant prices in. Defaults to `NGN`. */
291
+ sourceCurrency;
292
+ /** Currency the customer is charged in. Defaults to `NGN`. */
293
+ destinationCurrency;
294
+ /** Human readable description of the payment. */
295
+ paymentDescription;
296
+ /** URL the customer returns to after paying. */
297
+ callbackUrl;
298
+ /** @deprecated Use `callbackUrl`. */
299
+ redirectUrl;
300
+ /** Supply every option in one object instead of as individual inputs. */
301
+ klashaOptions;
302
+ /** CSS classes applied to the rendered button (component only). */
303
+ class;
304
+ /** Inline styles applied to the rendered button (component only). */
305
+ style;
306
+ /** Emitted right before the Klasha checkout is opened. */
307
+ paymentInit = new EventEmitter();
308
+ /** Emitted with the Klasha response once the payment flow finishes. */
309
+ callBack = new EventEmitter();
310
+ /**
311
+ * DOM id of the checkout container owned by this instance. Unique per
312
+ * instance, so several payment buttons can coexist on one page.
313
+ */
314
+ containerId = nextKlashaContainerId();
315
+ klashaService = inject(AngularKlashaService);
316
+ /** The options last handed to `KlashaClient`. Exposed for debugging/tests. */
317
+ _KlashaOptions;
318
+ /**
319
+ * Validates, loads `pay.js`, then opens the Klasha checkout.
320
+ *
321
+ * @returns `undefined` on success, or the validation error message.
322
+ */
323
+ async pay() {
324
+ const source = this.klashaOptions && Object.keys(this.klashaOptions).length >= 2
325
+ ? this.klashaOptions
326
+ : this;
327
+ this._KlashaOptions = this.buildOptions(source);
328
+ const errorText = this.validateInput(source);
329
+ if (errorText) {
330
+ console.error(errorText);
331
+ return errorText;
332
+ }
333
+ await this.klashaService.loadScript();
334
+ if (this.paymentInit.observed) {
335
+ this.paymentInit.emit();
336
+ }
337
+ this.klashaService.launch(this._KlashaOptions, this.containerId);
338
+ return undefined;
339
+ }
340
+ /** @internal */
341
+ validateInput(obj) {
342
+ if (!this.callBack.observed) {
343
+ return 'angular-klasha: Insert a callBack output like so (callBack)=\'PaymentComplete($event)\' to check payment status';
344
+ }
345
+ return this.klashaService.checkInput(obj);
346
+ }
347
+ /** @internal */
348
+ buildOptions(obj) {
349
+ const resolved = this.klashaService.getKlashaOptions({
350
+ ...obj,
351
+ isTestMode: obj.isTestMode ?? this.isTestMode,
352
+ callbackUrl: obj.callbackUrl ?? this.callbackUrl ?? this.redirectUrl,
353
+ sourceCurrency: obj.sourceCurrency ?? this.sourceCurrency ?? this.currency,
354
+ });
355
+ const emit = (response) => this.callBack.emit(response);
356
+ resolved.kit.callBack = emit;
357
+ resolved.callBack = emit;
358
+ return resolved;
359
+ }
360
+ ngOnDestroy() {
361
+ this.klashaService.removeContainer(this.containerId);
362
+ }
363
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.26", ngImport: i0, type: AngularKlashaBase, deps: [], target: i0.ɵɵFactoryTarget.Directive });
364
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.26", type: AngularKlashaBase, isStandalone: true, inputs: { merchantKey: "merchantKey", isTestMode: "isTestMode", businessId: "businessId", amount: "amount", metadata: "metadata", tx_ref: "tx_ref", currency: "currency", fullname: "fullname", email: "email", phone: "phone", phone_number: "phone_number", sourceCurrency: "sourceCurrency", destinationCurrency: "destinationCurrency", paymentDescription: "paymentDescription", callbackUrl: "callbackUrl", redirectUrl: "redirectUrl", klashaOptions: "klashaOptions", class: "class", style: "style" }, outputs: { paymentInit: "paymentInit", callBack: "callBack" }, ngImport: i0 });
365
+ }
366
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.26", ngImport: i0, type: AngularKlashaBase, decorators: [{
367
+ type: Directive
368
+ }], propDecorators: { merchantKey: [{
369
+ type: Input
370
+ }], isTestMode: [{
371
+ type: Input
372
+ }], businessId: [{
373
+ type: Input
374
+ }], amount: [{
375
+ type: Input
376
+ }], metadata: [{
377
+ type: Input
378
+ }], tx_ref: [{
379
+ type: Input
380
+ }], currency: [{
381
+ type: Input
382
+ }], fullname: [{
383
+ type: Input
384
+ }], email: [{
385
+ type: Input
386
+ }], phone: [{
387
+ type: Input
388
+ }], phone_number: [{
389
+ type: Input
390
+ }], sourceCurrency: [{
391
+ type: Input
392
+ }], destinationCurrency: [{
393
+ type: Input
394
+ }], paymentDescription: [{
395
+ type: Input
396
+ }], callbackUrl: [{
397
+ type: Input
398
+ }], redirectUrl: [{
399
+ type: Input
400
+ }], klashaOptions: [{
401
+ type: Input
402
+ }], class: [{
403
+ type: Input
404
+ }], style: [{
405
+ type: Input
406
+ }], paymentInit: [{
407
+ type: Output
408
+ }], callBack: [{
409
+ type: Output
410
+ }] } });
411
+
412
+ /**
413
+ * Renders a button that opens the Klasha inline checkout when clicked.
414
+ *
415
+ * Standalone — import it directly:
416
+ *
417
+ * ```ts
418
+ * @Component({ imports: [AngularKlashaComponent], ... })
419
+ * ```
420
+ */
421
+ class AngularKlashaComponent extends AngularKlashaBase {
422
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.26", ngImport: i0, type: AngularKlashaComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
423
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.26", type: AngularKlashaComponent, isStandalone: true, selector: "angular-klasha", usesInheritance: true, ngImport: i0, template: `<button type="button" [ngClass]="class || ''" [ngStyle]="style || null" (click)="pay()">
424
+ <ng-content></ng-content>
425
+ </button>`, isInline: true, dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
426
+ }
427
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.26", ngImport: i0, type: AngularKlashaComponent, decorators: [{
428
+ type: Component,
429
+ args: [{
430
+ selector: 'angular-klasha',
431
+ standalone: true,
432
+ imports: [NgClass, NgStyle],
433
+ changeDetection: ChangeDetectionStrategy.OnPush,
434
+ template: `<button type="button" [ngClass]="class || ''" [ngStyle]="style || null" (click)="pay()">
435
+ <ng-content></ng-content>
436
+ </button>`,
437
+ }]
438
+ }] });
439
+
440
+ /**
441
+ * Opens the Klasha inline checkout when the host element is clicked. Use it on
442
+ * your own button so you keep full control of the markup.
443
+ *
444
+ * Standalone — import it directly:
445
+ *
446
+ * ```ts
447
+ * @Component({ imports: [AngularKlashaDirective], ... })
448
+ * ```
449
+ */
450
+ class AngularKlashaDirective extends AngularKlashaBase {
451
+ onHostClick() {
452
+ void this.pay();
453
+ }
454
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.26", ngImport: i0, type: AngularKlashaDirective, deps: null, target: i0.ɵɵFactoryTarget.Directive });
455
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.26", type: AngularKlashaDirective, isStandalone: true, selector: "[angular-klasha]", host: { listeners: { "click": "onHostClick()" } }, usesInheritance: true, ngImport: i0 });
456
+ }
457
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.26", ngImport: i0, type: AngularKlashaDirective, decorators: [{
458
+ type: Directive,
459
+ args: [{
460
+ selector: '[angular-klasha]',
461
+ standalone: true,
462
+ }]
463
+ }], propDecorators: { onHostClick: [{
464
+ type: HostListener,
465
+ args: ['click']
466
+ }] } });
467
+
468
+ /** @internal Shared by `provideKlasha()` and `AngularKlashaModule.forRoot()`. */
469
+ function klashaProviders(config) {
470
+ return [
471
+ { provide: MERCHANT_KEY, useValue: config.merchantKey },
472
+ { provide: BUSINESS_ID, useValue: config.businessId },
473
+ { provide: IS_TEST_MODE, useValue: Boolean(config.isTestMode) },
474
+ ];
475
+ }
476
+ /**
477
+ * Configures Klasha for a standalone application.
478
+ *
479
+ * ```ts
480
+ * bootstrapApplication(AppComponent, {
481
+ * providers: [
482
+ * provideKlasha({ merchantKey: 'xxx', businessId: '1', isTestMode: true }),
483
+ * ],
484
+ * });
485
+ * ```
486
+ *
487
+ * `isTestMode` is forwarded to `KlashaClient` as its 9th constructor argument
488
+ * and is the only thing that selects the sandbox over the live gateway.
489
+ */
490
+ function provideKlasha(config) {
491
+ return makeEnvironmentProviders(klashaProviders(config));
492
+ }
493
+
494
+ /**
495
+ * NgModule wrapper around the standalone {@link AngularKlashaComponent} and
496
+ * {@link AngularKlashaDirective}.
497
+ *
498
+ * New applications can skip this entirely and use `provideKlasha()` plus the
499
+ * standalone component/directive imports.
500
+ */
501
+ class AngularKlashaModule {
502
+ /**
503
+ * Registers the merchant credentials for the whole application.
504
+ *
505
+ * ```ts
506
+ * AngularKlashaModule.forRoot('merchantKey', 'businessId', true)
507
+ * // or
508
+ * AngularKlashaModule.forRoot({ merchantKey: 'x', businessId: '1', isTestMode: true })
509
+ * ```
510
+ *
511
+ * @param merchantKeyOrConfig Merchant API key, or a {@link KlashaConfig}.
512
+ * @param businessId Merchant business id (when passing positional arguments).
513
+ * @param isTestMode `true` for the Klasha sandbox. Defaults to `false`.
514
+ */
515
+ static forRoot(merchantKeyOrConfig, businessId = '', isTestMode = false) {
516
+ const config = typeof merchantKeyOrConfig === 'string'
517
+ ? { merchantKey: merchantKeyOrConfig, businessId, isTestMode }
518
+ : merchantKeyOrConfig;
519
+ return {
520
+ ngModule: AngularKlashaModule,
521
+ providers: klashaProviders(config),
522
+ };
523
+ }
524
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.26", ngImport: i0, type: AngularKlashaModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
525
+ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.26", ngImport: i0, type: AngularKlashaModule, imports: [AngularKlashaComponent, AngularKlashaDirective], exports: [AngularKlashaComponent, AngularKlashaDirective] });
526
+ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.26", ngImport: i0, type: AngularKlashaModule });
527
+ }
528
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.26", ngImport: i0, type: AngularKlashaModule, decorators: [{
529
+ type: NgModule,
530
+ args: [{
531
+ imports: [AngularKlashaComponent, AngularKlashaDirective],
532
+ exports: [AngularKlashaComponent, AngularKlashaDirective],
533
+ }]
534
+ }] });
535
+
536
+ /*
537
+ * Public API Surface of angular-klasha
538
+ */
539
+
540
+ /**
541
+ * Generated bundle index. Do not edit.
542
+ */
543
+
544
+ export { AngularKlashaBase, AngularKlashaComponent, AngularKlashaDirective, AngularKlashaModule, AngularKlashaService, BUSINESS_ID, IS_TEST_MODE, KLASHA_SCRIPT_URL, MERCHANT_KEY, klashaProviders, nextKlashaContainerId, provideKlasha };
545
+ //# sourceMappingURL=angular-klasha.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"angular-klasha.mjs","sources":["../../../project/angular-klasha/src/lib/klasha-keys.ts","../../../project/angular-klasha/src/lib/angular-klasha.service.ts","../../../project/angular-klasha/src/lib/angular-klasha.base.ts","../../../project/angular-klasha/src/lib/angular-klasha.component.ts","../../../project/angular-klasha/src/lib/angular-klasha.directive.ts","../../../project/angular-klasha/src/lib/klasha.providers.ts","../../../project/angular-klasha/src/lib/angular-klasha.module.ts","../../../project/angular-klasha/src/public_api.ts","../../../project/angular-klasha/src/angular-klasha.ts"],"sourcesContent":["import { InjectionToken } from '@angular/core';\n\n/**\n * The URL of the Klasha inline checkout script.\n *\n * The buckets used by `angular-klasha@0.0.x`\n * (`https://klastatic.fra1.digitaloceanspaces.com/{test,prod}/js/klasha-integration.js`)\n * have been deleted and return `NoSuchBucket`. There is now a single script for\n * both environments; the environment is selected by the `isTestMode`\n * constructor argument instead of by the script URL.\n */\nexport const KLASHA_SCRIPT_URL = 'https://js.klasha.com/pay.js';\n\n/**\n * Merchant API key used when a component/directive does not supply its own.\n */\nexport const MERCHANT_KEY = new InjectionToken<string>('klasha.merchantKey', {\n providedIn: 'root',\n factory: () => '',\n});\n\n/**\n * Merchant business id used when a component/directive does not supply its own.\n */\nexport const BUSINESS_ID = new InjectionToken<string>('klasha.businessId', {\n providedIn: 'root',\n factory: () => '',\n});\n\n/**\n * Whether to use the Klasha sandbox. Defaults to `false` (live gateway).\n */\nexport const IS_TEST_MODE = new InjectionToken<boolean>('klasha.isTestMode', {\n providedIn: 'root',\n factory: () => false,\n});\n","import { DOCUMENT, isPlatformBrowser } from '@angular/common';\nimport { inject, Injectable, PLATFORM_ID } from '@angular/core';\n\nimport {\n KlashaKitOptions,\n KlashaOptions,\n ResolvedKlashaOptions,\n} from '../model/klasha-options';\nimport {\n BUSINESS_ID,\n IS_TEST_MODE,\n KLASHA_SCRIPT_URL,\n MERCHANT_KEY,\n} from './klasha-keys';\n\n/**\n * Shape of the global installed by `https://js.klasha.com/pay.js`.\n *\n * ```js\n * function KlashaClient(merchantKey, businessId, amount, containerId,\n * callbackUrl, countryCode, sourceCurrency, kit, isTestMode)\n * ```\n */\nexport type KlashaClientConstructor = new (\n merchantKey: string,\n businessId: string | number,\n amount: number,\n containerId: string,\n callbackUrl: string,\n countryCode: string,\n sourceCurrency: string,\n kit: KlashaKitOptions,\n isTestMode: boolean,\n) => { init: () => void };\n\n/** Marks script tags and container divs created by this library. */\nconst SCRIPT_MARKER = 'data-angular-klasha';\nconst CONTAINER_MARKER = 'data-angular-klasha-container';\n\nlet containerSequence = 0;\n\n/**\n * Returns a process-unique DOM id for a checkout container. Each component or\n * directive instance owns exactly one, so two payment buttons on the same page\n * can never collide (0.0.x hardcoded `ktest` for every instance).\n */\nexport function nextKlashaContainerId(): string {\n containerSequence += 1;\n return `klasha-container-${containerSequence}`;\n}\n\n@Injectable({ providedIn: 'root' })\nexport class AngularKlashaService {\n private readonly merchantKey = inject(MERCHANT_KEY, { optional: true });\n private readonly businessId = inject(BUSINESS_ID, { optional: true });\n private readonly isTestMode = inject(IS_TEST_MODE, { optional: true });\n private readonly document = inject(DOCUMENT);\n private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n private scriptPromise: Promise<void> | null = null;\n\n /**\n * The window the checkout script is loaded into. `null` on the server.\n */\n private get window(): (Window & { KlashaClient?: KlashaClientConstructor }) | null {\n return this.isBrowser\n ? (this.document.defaultView as Window & { KlashaClient?: KlashaClientConstructor } | null)\n : null;\n }\n\n /**\n * Loads `https://js.klasha.com/pay.js` exactly once and resolves when\n * `window.KlashaClient` is available.\n *\n * jQuery is deliberately not loaded: `pay.js` does not use it.\n */\n loadScript(): Promise<void> {\n if (!this.isBrowser) {\n return Promise.reject(\n new Error('angular-klasha: Klasha checkout can only be loaded in a browser'),\n );\n }\n if (typeof this.window?.KlashaClient === 'function') {\n return Promise.resolve();\n }\n if (this.scriptPromise) {\n return this.scriptPromise;\n }\n\n this.scriptPromise = new Promise<void>((resolve, reject) => {\n const doc = this.document;\n const existing = doc.querySelector<HTMLScriptElement>(`script[${SCRIPT_MARKER}]`);\n const script = existing ?? doc.createElement('script');\n\n const onLoad = (): void => {\n cleanup();\n resolve();\n };\n const onError = (): void => {\n cleanup();\n this.scriptPromise = null;\n script.remove();\n reject(new Error(`angular-klasha: failed to load ${KLASHA_SCRIPT_URL}`));\n };\n const cleanup = (): void => {\n script.removeEventListener('load', onLoad);\n script.removeEventListener('error', onError);\n };\n\n script.addEventListener('load', onLoad);\n script.addEventListener('error', onError);\n\n if (!existing) {\n script.setAttribute(SCRIPT_MARKER, '');\n script.async = true;\n script.src = KLASHA_SCRIPT_URL;\n doc.head.appendChild(script);\n }\n });\n\n return this.scriptPromise;\n }\n\n /**\n * Returns the checkout container for `containerId`, creating it only when it\n * does not already exist. Repeated calls never append a second element with\n * the same id.\n */\n ensureContainer(containerId: string): HTMLElement | null {\n if (!this.isBrowser) {\n return null;\n }\n const existing = this.document.getElementById(containerId);\n if (existing) {\n return existing;\n }\n const container = this.document.createElement('div');\n container.id = containerId;\n container.setAttribute(CONTAINER_MARKER, '');\n this.document.body.appendChild(container);\n return container;\n }\n\n /**\n * Removes a container previously created by {@link ensureContainer}. Called\n * from `ngOnDestroy` so remounting does not leak DOM nodes.\n */\n removeContainer(containerId: string): void {\n if (!this.isBrowser) {\n return;\n }\n const container = this.document.getElementById(containerId);\n if (container?.hasAttribute(CONTAINER_MARKER)) {\n container.remove();\n }\n }\n\n /**\n * Instantiates `KlashaClient` and opens the checkout.\n *\n * The 9th argument (`isTestMode`) is the fix for the headline bug in\n * `angular-klasha@0.0.x`: it was never passed, so `isTestMode` was\n * `undefined` inside `pay.js` and every sandbox payment hit the LIVE gateway.\n * It is coerced with `Boolean()` because `pay.js` only branches on\n * truthiness — the string `'false'` would otherwise select production.\n */\n launch(options: ResolvedKlashaOptions, containerId: string): { init: () => void } {\n const KlashaClient = this.window?.KlashaClient;\n if (typeof KlashaClient !== 'function') {\n throw new Error(\n 'angular-klasha: window.KlashaClient is not available — call loadScript() first',\n );\n }\n\n this.ensureContainer(containerId);\n\n const client = new KlashaClient(\n options.merchantKey,\n options.businessId || 1,\n options.amount,\n containerId,\n options.callbackUrl ?? '',\n options.destinationCurrency,\n options.sourceCurrency,\n options.kit,\n Boolean(options.isTestMode),\n );\n client.init();\n return client;\n }\n\n /**\n * Validates the merchant supplied options. Returns an empty string when the\n * options are usable, otherwise a human readable error message.\n */\n checkInput(obj: Partial<KlashaOptions>): string {\n if (!obj.merchantKey && !this.merchantKey) {\n return 'angular-klasha: Klasha merchantKey cannot be empty';\n }\n if (!obj.businessId && !this.businessId) {\n return 'angular-klasha: Klasha businessId cannot be empty';\n }\n if (!obj.email) {\n return 'angular-klasha: Klasha email cannot be empty';\n }\n if (!obj.fullname) {\n return 'angular-klasha: Klasha name cannot be empty';\n }\n if (!obj.phone && !obj.phone_number) {\n return 'angular-klasha: Klasha phone cannot be empty';\n }\n if (!obj.amount) {\n return 'angular-klasha: Klasha amount cannot be empty';\n }\n return '';\n }\n\n /**\n * Resolves merchant supplied options against the globally configured\n * merchant key / business id / test mode, and builds a **fresh** `kit`\n * object (`pay.js` mutates the kit it is given).\n */\n getKlashaOptions(obj: Partial<KlashaOptions>): ResolvedKlashaOptions {\n const kit: KlashaKitOptions = obj.kit ?? {};\n const sourceCurrency = obj.sourceCurrency || 'NGN';\n const destinationCurrency = obj.destinationCurrency || 'NGN';\n const phone = obj.phone || obj.phone_number || kit.phone || kit.phone_number || '';\n const email = obj.email || kit.email || '';\n const fullname = obj.fullname || kit.fullname || '';\n const txRef = obj.tx_ref || kit.tx_ref || this.makeId(8);\n const productType = kit.productType || kit.paymentType || '';\n\n const resolved: ResolvedKlashaOptions = {\n isTestMode: Boolean(obj.isTestMode ?? this.isTestMode ?? false),\n merchantKey: obj.merchantKey || this.merchantKey || '',\n businessId: obj.businessId || this.businessId || '',\n amount: obj.amount as number,\n tx_ref: txRef,\n sourceCurrency,\n destinationCurrency,\n fullname,\n email,\n phone,\n // Retained for backwards compatibility with 0.0.x integrations.\n phone_number: phone,\n paymentDescription: obj.paymentDescription || '',\n callbackUrl: obj.callbackUrl || '',\n metadata: obj.metadata ?? {},\n kit: this.clean({\n currency: kit.currency || sourceCurrency,\n // `pay.js` reads `phone`; `phone_number` is never read by it.\n phone,\n phone_number: phone,\n email,\n fullname,\n tx_ref: txRef,\n productType,\n // Retained for backwards compatibility with 0.0.x integrations.\n paymentType: productType,\n amount: kit.amount ?? obj.amount,\n sourceAmount: kit.sourceAmount,\n }),\n };\n\n return this.clean(resolved);\n }\n\n /**\n * Removes `null`/`undefined` entries so they are not serialised into the\n * request `pay.js` makes.\n */\n clean<T extends object>(obj: T): T {\n const record = obj as Record<string, unknown>;\n for (const propName of Object.keys(record)) {\n if (record[propName] === null || record[propName] === undefined) {\n delete record[propName];\n }\n }\n return obj;\n }\n\n /** Generates a random alphanumeric transaction reference. */\n makeId(length = 8): string {\n const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\n let result = '';\n for (let i = 0; i < length; i++) {\n result += characters.charAt(Math.floor(Math.random() * characters.length));\n }\n return result;\n }\n}\n","import { Directive, EventEmitter, inject, Input, OnDestroy, Output } from '@angular/core';\n\nimport { KlashaOptions, ResolvedKlashaOptions } from '../model/klasha-options';\nimport { AngularKlashaService, nextKlashaContainerId } from './angular-klasha.service';\n\n/**\n * Shared implementation behind {@link AngularKlashaComponent} and\n * {@link AngularKlashaDirective}. Not usable on its own — it has no selector.\n */\n@Directive()\nexport abstract class AngularKlashaBase implements OnDestroy {\n /** Merchant API key. Overrides the value given to `provideKlasha()`/`forRoot()`. */\n @Input() merchantKey?: string;\n /** `true` uses the Klasha sandbox, `false` the live gateway. */\n @Input() isTestMode?: boolean;\n /** Merchant business id. Overrides the globally configured one. */\n @Input() businessId?: string;\n /** Amount to charge. */\n @Input() amount?: number;\n /** Free-form extra data. */\n @Input() metadata?: unknown;\n /** Unique transaction reference. Generated when omitted. */\n @Input() tx_ref?: string;\n /** @deprecated Use `sourceCurrency`/`destinationCurrency`. */\n @Input() currency?: string;\n /** Customer full name. */\n @Input() fullname?: string;\n /** Customer email address. */\n @Input() email?: string;\n /** Customer phone number. */\n @Input() phone?: string;\n /** @deprecated Use `phone`. */\n @Input() phone_number?: string;\n /** Currency the merchant prices in. Defaults to `NGN`. */\n @Input() sourceCurrency?: string;\n /** Currency the customer is charged in. Defaults to `NGN`. */\n @Input() destinationCurrency?: string;\n /** Human readable description of the payment. */\n @Input() paymentDescription?: string;\n /** URL the customer returns to after paying. */\n @Input() callbackUrl?: string;\n /** @deprecated Use `callbackUrl`. */\n @Input() redirectUrl?: string;\n /** Supply every option in one object instead of as individual inputs. */\n @Input() klashaOptions?: KlashaOptions;\n /** CSS classes applied to the rendered button (component only). */\n @Input() class?: string;\n /** Inline styles applied to the rendered button (component only). */\n @Input() style?: Record<string, unknown> | null;\n\n /** Emitted right before the Klasha checkout is opened. */\n @Output() paymentInit = new EventEmitter<unknown>();\n /** Emitted with the Klasha response once the payment flow finishes. */\n @Output() callBack = new EventEmitter<unknown>();\n\n /**\n * DOM id of the checkout container owned by this instance. Unique per\n * instance, so several payment buttons can coexist on one page.\n */\n readonly containerId = nextKlashaContainerId();\n\n protected readonly klashaService = inject(AngularKlashaService);\n\n /** The options last handed to `KlashaClient`. Exposed for debugging/tests. */\n _KlashaOptions?: ResolvedKlashaOptions;\n\n /**\n * Validates, loads `pay.js`, then opens the Klasha checkout.\n *\n * @returns `undefined` on success, or the validation error message.\n */\n async pay(): Promise<string | undefined> {\n const source: Partial<KlashaOptions> =\n this.klashaOptions && Object.keys(this.klashaOptions).length >= 2\n ? this.klashaOptions\n : (this as Partial<KlashaOptions>);\n\n this._KlashaOptions = this.buildOptions(source);\n\n const errorText = this.validateInput(source);\n if (errorText) {\n console.error(errorText);\n return errorText;\n }\n\n await this.klashaService.loadScript();\n\n if (this.paymentInit.observed) {\n this.paymentInit.emit();\n }\n\n this.klashaService.launch(this._KlashaOptions, this.containerId);\n return undefined;\n }\n\n /** @internal */\n validateInput(obj: Partial<KlashaOptions>): string {\n if (!this.callBack.observed) {\n return 'angular-klasha: Insert a callBack output like so (callBack)=\\'PaymentComplete($event)\\' to check payment status';\n }\n return this.klashaService.checkInput(obj);\n }\n\n /** @internal */\n protected buildOptions(obj: Partial<KlashaOptions>): ResolvedKlashaOptions {\n const resolved = this.klashaService.getKlashaOptions({\n ...obj,\n isTestMode: obj.isTestMode ?? this.isTestMode,\n callbackUrl: obj.callbackUrl ?? this.callbackUrl ?? this.redirectUrl,\n sourceCurrency: obj.sourceCurrency ?? this.sourceCurrency ?? this.currency,\n });\n const emit = (response?: unknown): void => this.callBack.emit(response);\n resolved.kit.callBack = emit;\n resolved.callBack = emit;\n return resolved;\n }\n\n ngOnDestroy(): void {\n this.klashaService.removeContainer(this.containerId);\n }\n}\n","import { NgClass, NgStyle } from '@angular/common';\nimport { ChangeDetectionStrategy, Component } from '@angular/core';\n\nimport { AngularKlashaBase } from './angular-klasha.base';\n\n/**\n * Renders a button that opens the Klasha inline checkout when clicked.\n *\n * Standalone — import it directly:\n *\n * ```ts\n * @Component({ imports: [AngularKlashaComponent], ... })\n * ```\n */\n@Component({\n selector: 'angular-klasha',\n standalone: true,\n imports: [NgClass, NgStyle],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `<button type=\"button\" [ngClass]=\"class || ''\" [ngStyle]=\"style || null\" (click)=\"pay()\">\n <ng-content></ng-content>\n </button>`,\n})\nexport class AngularKlashaComponent extends AngularKlashaBase {}\n","import { Directive, HostListener } from '@angular/core';\n\nimport { AngularKlashaBase } from './angular-klasha.base';\n\n/**\n * Opens the Klasha inline checkout when the host element is clicked. Use it on\n * your own button so you keep full control of the markup.\n *\n * Standalone — import it directly:\n *\n * ```ts\n * @Component({ imports: [AngularKlashaDirective], ... })\n * ```\n */\n@Directive({\n selector: '[angular-klasha]',\n standalone: true,\n})\nexport class AngularKlashaDirective extends AngularKlashaBase {\n @HostListener('click')\n onHostClick(): void {\n void this.pay();\n }\n}\n","import { EnvironmentProviders, makeEnvironmentProviders, Provider } from '@angular/core';\n\nimport { KlashaConfig } from '../model/klasha-options';\nimport { BUSINESS_ID, IS_TEST_MODE, MERCHANT_KEY } from './klasha-keys';\n\n/** @internal Shared by `provideKlasha()` and `AngularKlashaModule.forRoot()`. */\nexport function klashaProviders(config: KlashaConfig): Provider[] {\n return [\n { provide: MERCHANT_KEY, useValue: config.merchantKey },\n { provide: BUSINESS_ID, useValue: config.businessId },\n { provide: IS_TEST_MODE, useValue: Boolean(config.isTestMode) },\n ];\n}\n\n/**\n * Configures Klasha for a standalone application.\n *\n * ```ts\n * bootstrapApplication(AppComponent, {\n * providers: [\n * provideKlasha({ merchantKey: 'xxx', businessId: '1', isTestMode: true }),\n * ],\n * });\n * ```\n *\n * `isTestMode` is forwarded to `KlashaClient` as its 9th constructor argument\n * and is the only thing that selects the sandbox over the live gateway.\n */\nexport function provideKlasha(config: KlashaConfig): EnvironmentProviders {\n return makeEnvironmentProviders(klashaProviders(config));\n}\n","import { ModuleWithProviders, NgModule } from '@angular/core';\n\nimport { KlashaConfig } from '../model/klasha-options';\nimport { AngularKlashaComponent } from './angular-klasha.component';\nimport { AngularKlashaDirective } from './angular-klasha.directive';\nimport { klashaProviders } from './klasha.providers';\n\n/**\n * NgModule wrapper around the standalone {@link AngularKlashaComponent} and\n * {@link AngularKlashaDirective}.\n *\n * New applications can skip this entirely and use `provideKlasha()` plus the\n * standalone component/directive imports.\n */\n@NgModule({\n imports: [AngularKlashaComponent, AngularKlashaDirective],\n exports: [AngularKlashaComponent, AngularKlashaDirective],\n})\nexport class AngularKlashaModule {\n /**\n * Registers the merchant credentials for the whole application.\n *\n * ```ts\n * AngularKlashaModule.forRoot('merchantKey', 'businessId', true)\n * // or\n * AngularKlashaModule.forRoot({ merchantKey: 'x', businessId: '1', isTestMode: true })\n * ```\n *\n * @param merchantKeyOrConfig Merchant API key, or a {@link KlashaConfig}.\n * @param businessId Merchant business id (when passing positional arguments).\n * @param isTestMode `true` for the Klasha sandbox. Defaults to `false`.\n */\n static forRoot(\n merchantKeyOrConfig: string | KlashaConfig,\n businessId = '',\n isTestMode = false,\n ): ModuleWithProviders<AngularKlashaModule> {\n const config: KlashaConfig =\n typeof merchantKeyOrConfig === 'string'\n ? { merchantKey: merchantKeyOrConfig, businessId, isTestMode }\n : merchantKeyOrConfig;\n\n return {\n ngModule: AngularKlashaModule,\n providers: klashaProviders(config),\n };\n }\n}\n","/*\n * Public API Surface of angular-klasha\n */\n\nexport * from './lib/angular-klasha.base';\nexport * from './lib/angular-klasha.component';\nexport * from './lib/angular-klasha.directive';\nexport * from './lib/angular-klasha.module';\nexport * from './lib/angular-klasha.service';\nexport * from './lib/klasha-keys';\nexport * from './lib/klasha.providers';\nexport * from './model/klasha-options';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":"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"}