@idonatedev/idonate-sdk 1.1.0-dev9 → 1.2.0-dev1

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.
Files changed (71) hide show
  1. package/README.md +308 -7
  2. package/dist/constants.d.ts +1 -1
  3. package/dist/constants.js +2 -6
  4. package/dist/esm/apple-pay.d.ts +12 -0
  5. package/dist/esm/apple-pay.js +74 -0
  6. package/dist/esm/cloudflare-challenge-handler.d.ts +5 -0
  7. package/dist/esm/cloudflare-challenge-handler.js +77 -0
  8. package/dist/esm/config-handler.d.ts +22 -0
  9. package/dist/esm/config-handler.js +47 -0
  10. package/dist/esm/constants.d.ts +18 -0
  11. package/dist/esm/constants.js +81 -0
  12. package/dist/esm/google-pay.d.ts +18 -0
  13. package/dist/esm/google-pay.js +140 -0
  14. package/dist/esm/idonate-client.d.ts +32 -0
  15. package/dist/esm/idonate-client.js +294 -0
  16. package/dist/esm/index.d.ts +11 -0
  17. package/dist/esm/index.js +11 -0
  18. package/dist/esm/recaptcha.d.ts +12 -0
  19. package/dist/esm/recaptcha.js +89 -0
  20. package/dist/esm/shared.d.ts +4 -0
  21. package/dist/esm/shared.js +21 -0
  22. package/dist/esm/test-utils.d.ts +81 -0
  23. package/dist/esm/test-utils.js +94 -0
  24. package/dist/esm/tokenize/CardConnectTokenizer.d.ts +51 -0
  25. package/dist/esm/tokenize/CardConnectTokenizer.js +726 -0
  26. package/dist/esm/tokenize/PayPalTokenizer.d.ts +76 -0
  27. package/dist/esm/tokenize/PayPalTokenizer.js +258 -0
  28. package/dist/esm/tokenize/SpreedlyTokenizer.d.ts +91 -0
  29. package/dist/esm/tokenize/SpreedlyTokenizer.js +1137 -0
  30. package/dist/esm/tokenize/Tokenizer.d.ts +39 -0
  31. package/dist/esm/tokenize/Tokenizer.js +164 -0
  32. package/dist/esm/tokenize/iats.d.ts +3 -0
  33. package/dist/esm/tokenize/iats.js +48 -0
  34. package/dist/esm/tokenize/index.d.ts +7 -0
  35. package/dist/esm/tokenize/index.js +7 -0
  36. package/dist/esm/tokenize/spreedly-secure.d.ts +8 -0
  37. package/dist/esm/tokenize/spreedly-secure.js +40 -0
  38. package/dist/esm/tokenize/styles.d.ts +4 -0
  39. package/dist/esm/tokenize/styles.js +46 -0
  40. package/dist/esm/tokenize/tokenizer-constants.d.ts +62 -0
  41. package/dist/esm/tokenize/tokenizer-constants.js +62 -0
  42. package/dist/esm/tokenize/tokenizer-utils.d.ts +19 -0
  43. package/dist/esm/tokenize/tokenizer-utils.js +139 -0
  44. package/dist/esm/tokenize/types.d.ts +146 -0
  45. package/dist/esm/tokenize/types.js +26 -0
  46. package/dist/esm/typeAdapters.d.ts +29 -0
  47. package/dist/esm/typeAdapters.js +189 -0
  48. package/dist/esm/types.d.ts +378 -0
  49. package/dist/esm/types.js +14 -0
  50. package/dist/esm/util.d.ts +17 -0
  51. package/dist/esm/util.js +113 -0
  52. package/dist/idonate-client.d.ts +6 -2
  53. package/dist/idonate-client.js +40 -2
  54. package/dist/shared.d.ts +2 -1
  55. package/dist/shared.js +9 -0
  56. package/dist/tokenize/CardConnectTokenizer.d.ts +1 -1
  57. package/dist/tokenize/CardConnectTokenizer.js +67 -86
  58. package/dist/tokenize/PayPalTokenizer.d.ts +76 -0
  59. package/dist/tokenize/PayPalTokenizer.js +262 -0
  60. package/dist/tokenize/SpreedlyTokenizer.d.ts +0 -1
  61. package/dist/tokenize/SpreedlyTokenizer.js +6 -9
  62. package/dist/tokenize/Tokenizer.d.ts +2 -0
  63. package/dist/tokenize/Tokenizer.js +20 -2
  64. package/dist/tokenize/index.d.ts +1 -0
  65. package/dist/tokenize/index.js +3 -1
  66. package/dist/tokenize/tokenizer-utils.js +1 -1
  67. package/dist/tokenize/types.d.ts +3 -7
  68. package/dist/typeAdapters.js +3 -2
  69. package/dist/types.d.ts +16 -5
  70. package/package.json +24 -3
  71. package/umd/idonate-sdk.js +1 -1
package/README.md CHANGED
@@ -4,6 +4,34 @@ Javascript libraries for integrating with iDonate services.
4
4
  A rough usage example can be found below the Changelog.
5
5
 
6
6
  # Changes
7
+ ## 1.2.0 (Upcoming)
8
+ ### PayPal and Venmo Support
9
+
10
+ #### New Features
11
+ * **PayPal Checkout Integration**: Native PayPal Orders API v2 support via `paypal_checkout` backend
12
+ * Direct PayPal integration (not through intermediaries like Spreedly)
13
+ * Auto-tokenization mode - token available immediately after user approval
14
+ * Button-based UI with PayPal and Venmo buttons
15
+ * Popup blocker prevention through synchronous order creation
16
+ * Full support for sandbox and production environments
17
+ * **Venmo Support**: Enable Venmo button alongside PayPal for mobile-first checkout
18
+ * **Enhanced Tokenizer API**: New configuration options for PayPal:
19
+ * `currency` parameter (required for PayPal)
20
+ * `amount` parameter (optional, for display purposes)
21
+ * `enableVenmo` parameter (defaults to true)
22
+ * **Auto-Loading Embed Configuration**: SDK automatically fetches gateway configurations from backend
23
+ * New `getEmbedConfig()` method to fetch and cache embed configuration
24
+ * New `getGateway(gatewayId)` method to fetch specific gateway by ID
25
+ * Constructor now accepts `EmbedConfig` object in addition to string to avoid duplicate fetches
26
+ * Lazy-loading pattern with instance-level caching for optimal performance
27
+ * Gateway configs include `client_id`, `auth_mode`, and other public settings
28
+
29
+ #### Important Notes
30
+ * PayPal tokenizer uses `backend_name: 'paypal_checkout'` (distinct from legacy Spreedly PayPal)
31
+ * PayPal order ID serves as the payment token in the SDK flow
32
+ * Backend capture happens via `createDonation` using the order ID token
33
+ * Gateway configuration is automatically fetched when using `getGateway()` - no manual config needed
34
+
7
35
  ## 1.1.0
8
36
  ### Major Tokenizer Improvements and Canadian Bank Account Support
9
37
 
@@ -147,8 +175,9 @@ A rough usage example can be found below the Changelog.
147
175
  <script>
148
176
  // config will usually be supplied statically, at the page level.
149
177
  const config = {
150
- organizationId: '2aa2e362-51aa-483d-bedd-645ae18cc1f3',
151
- paymentGatewayId: '12344321-e605-429e-b9a9-4516738635db',
178
+ organizationId: 'ff1f9f90-0cca-4623-963b-47cfdfcf11c5',
179
+ embedId: '88af6f97-5db6-40c9-9fde-bca3a2059583',
180
+ paymentGatewayId: '11111111-e605-429e-b9a9-4516738635db',
152
181
  enableSandboxMode: true, // the SDK client will use Staging resources if true
153
182
  recaptchaType: 'v2', // 'v2' and 'invisible' recaptcha types are supported.
154
183
  };
@@ -174,9 +203,13 @@ A rough usage example can be found below the Changelog.
174
203
  accountNumber: '123456789',
175
204
  }
176
205
 
177
- idonateClient = new idonate.Client(config.organizationId, {
178
- enableSandboxMode: config.enableSandboxMode,
179
- });
206
+ idonateClient = new idonate.Client(
207
+ config.organizationId,
208
+ config.embedId,
209
+ {
210
+ enableSandboxMode: config.enableSandboxMode,
211
+ }
212
+ );
180
213
 
181
214
  function recaptchaCallback(recaptchaToken) {
182
215
  /**
@@ -192,8 +225,10 @@ A rough usage example can be found below the Changelog.
192
225
  */
193
226
  idonateClient
194
227
  .tokenizeCardConnectBankAccount({
195
- routingNumber: bankPaymentInput.routingNumber,
196
- accountNumber: bankPaymentInput.accountNumber
228
+ routingNumber: bankAccountInput.routingNumber,
229
+ accountNumber: bankAccountInput.accountNumber,
230
+ accountHolderType: 'personal',
231
+ accountType: 'checking',
197
232
  })
198
233
  .then((tokenResult) => {
199
234
  console.log('received tokenResult', tokenResult);
@@ -241,3 +276,269 @@ A rough usage example can be found below the Changelog.
241
276
  </script>
242
277
  </html>
243
278
  ```
279
+
280
+ # Example: PayPal Checkout with Unified Tokenizer
281
+ ```html
282
+ <!DOCTYPE html>
283
+ <html lang="en">
284
+ <head>
285
+ <meta charset="UTF-8" />
286
+ <title>PayPal Checkout Demo</title>
287
+ <script src="https://unpkg.com/@idonatedev/idonate-sdk@latest"></script>
288
+ <style>
289
+ #paypal-container {
290
+ max-width: 400px;
291
+ margin: 20px auto;
292
+ }
293
+ </style>
294
+ </head>
295
+ <body>
296
+ <h1>PayPal & Venmo Checkout</h1>
297
+
298
+ <!-- Container for PayPal/Venmo buttons -->
299
+ <div id="paypal-container"></div>
300
+
301
+ <div id="status"></div>
302
+ </body>
303
+ <script>
304
+ // Configuration (example uses dev environment)
305
+ const config = {
306
+ organizationId: 'ff1f9f90-0cca-4623-963b-47cfdfcf11c5',
307
+ embedId: '88af6f97-5db6-40c9-9fde-bca3a2059583',
308
+ paymentGatewayId: 'a1ef1db0-6a60-4e33-b5e9-e1e963c35cd8',
309
+ enableSandboxMode: true, // Use sandbox for testing
310
+ };
311
+
312
+ const donationAmount = 25.00;
313
+
314
+ // Initialize client
315
+ const client = new idonate.Client(
316
+ config.organizationId,
317
+ config.embedId,
318
+ {
319
+ enableSandboxMode: config.enableSandboxMode,
320
+ }
321
+ );
322
+
323
+ // Initialize PayPal tokenizer
324
+ async function initializePayPal() {
325
+ try {
326
+ // Fetch gateway configuration automatically from backend
327
+ // This includes client_id, auth_mode, and other settings
328
+ const gateway = await client.getGateway(config.paymentGatewayId);
329
+
330
+ // Create PayPal tokenizer
331
+ const tokenizer = await client.createTokenizer(gateway, {
332
+ containerId: 'paypal-container',
333
+ currency: 'USD', // Required for PayPal
334
+ amount: donationAmount, // Optional, for display
335
+ enableVenmo: true, // Enable Venmo button (default: true)
336
+ });
337
+
338
+ // Listen for tokenReady event
339
+ tokenizer.on('tokenReady', async (token) => {
340
+ console.log('PayPal order approved:', token);
341
+ document.getElementById('status').textContent =
342
+ 'Payment approved! Order ID: ' + token.token;
343
+
344
+ // Complete the donation
345
+ // Backend already created payment method and pending transaction
346
+ try {
347
+ const donation = await client.createDonation({
348
+ paymentGatewayId: config.paymentGatewayId,
349
+ paymentMethodId: token.paymentMethodId, // From backend
350
+ paymentTransactionId: token.paymentTransactionId, // Links to pending transaction
351
+
352
+ paymentAmount: donationAmount,
353
+ currency: 'USD',
354
+ recurringFrequency: 'once',
355
+
356
+ billingContact: {
357
+ firstName: 'John',
358
+ lastName: 'Doe',
359
+ email: 'john.doe@example.com',
360
+ },
361
+ billingAddress: {
362
+ address1: '123 Main St',
363
+ city: 'Anytown',
364
+ state: 'CA',
365
+ zip: '12345',
366
+ country: 'US',
367
+ },
368
+
369
+ recaptchaType: 'organization',
370
+ recaptchaToken: 'dummy-token', // Use actual reCAPTCHA in production
371
+ });
372
+
373
+ console.log('Donation created:', donation);
374
+ document.getElementById('status').textContent =
375
+ 'Donation successful! Transaction ID: ' + donation.transaction?.id;
376
+
377
+ } catch (error) {
378
+ console.error('Donation failed:', error);
379
+ document.getElementById('status').textContent =
380
+ 'Donation failed: ' + error.message;
381
+ }
382
+ });
383
+
384
+ // Listen for errors
385
+ tokenizer.on('error', (error) => {
386
+ console.error('PayPal error:', error);
387
+ document.getElementById('status').textContent =
388
+ 'Error: ' + error.message;
389
+ });
390
+
391
+ // Listen for ready event
392
+ tokenizer.on('ready', () => {
393
+ console.log('PayPal tokenizer ready');
394
+ document.getElementById('status').textContent =
395
+ 'Ready - Click PayPal or Venmo button to donate $' + donationAmount;
396
+ });
397
+
398
+ } catch (error) {
399
+ console.error('Failed to initialize PayPal:', error);
400
+ document.getElementById('status').textContent =
401
+ 'Initialization failed: ' + error.message;
402
+ }
403
+ }
404
+
405
+ // Initialize when page loads
406
+ initializePayPal();
407
+ </script>
408
+ </html>
409
+ ```
410
+
411
+ ## Embed Configuration & Gateway Management
412
+
413
+ ### Automatic Gateway Configuration (Recommended)
414
+ The SDK can automatically fetch gateway configurations from the backend:
415
+
416
+ ```javascript
417
+ const client = new idonate.Client(organizationId, embedId, options);
418
+
419
+ // Fetch a specific gateway by ID - includes client_id and all settings
420
+ const gateway = await client.getGateway('gateway-id-here');
421
+
422
+ // Use with tokenizer
423
+ const tokenizer = await client.createTokenizer(gateway, {
424
+ containerId: 'payment-container',
425
+ // ... other options
426
+ });
427
+ ```
428
+
429
+ **Benefits:**
430
+ - No need to hardcode sensitive credentials
431
+ - Configuration managed centrally in backend
432
+ - Automatic updates when gateway settings change
433
+ - Supports both sandbox and production modes
434
+
435
+ ### Fetching All Available Gateways
436
+ ```javascript
437
+ // Get complete embed configuration
438
+ const embedConfig = await client.getEmbedConfig();
439
+
440
+ console.log(embedConfig.available_gateways);
441
+ // Returns array of all gateways configured for this embed
442
+ ```
443
+
444
+ ### Using Pre-Fetched Configuration
445
+ If you already have embed configuration (e.g., from a separate API call), pass it directly to avoid duplicate requests:
446
+
447
+ ```javascript
448
+ const embedConfig = {
449
+ embed_id: '88af6f97-5db6-40c9-9fde-bca3a2059583',
450
+ organization_id: 'ff1f9f90-0cca-4623-963b-47cfdfcf11c5',
451
+ available_gateways: [/* ... */]
452
+ };
453
+
454
+ // Pass config object instead of embed ID string
455
+ const client = new idonate.Client(organizationId, embedConfig, options);
456
+
457
+ // No fetch needed - uses cached config
458
+ const gateway = await client.getGateway('gateway-id');
459
+ ```
460
+
461
+ ## PayPal Configuration Notes
462
+
463
+ ### Gateway Setup
464
+
465
+ #### Automatic Configuration (Recommended)
466
+ The SDK fetches PayPal configuration automatically from your backend:
467
+
468
+ ```javascript
469
+ // Gateway config is fetched automatically - no hardcoding needed
470
+ const gateway = await client.getGateway(paypalGatewayId);
471
+
472
+ // gateway.config includes:
473
+ // - client_id (from your PayPal app)
474
+ // - auth_mode ('manual' or 'partner')
475
+ // - sandbox_mode (true/false)
476
+ ```
477
+
478
+ #### Manual Configuration (Advanced)
479
+ For advanced use cases, you can provide gateway configuration manually:
480
+
481
+ ```javascript
482
+ const gateway = {
483
+ id: 'gateway-id',
484
+ name: 'PayPal Gateway',
485
+ backend_name: 'paypal_checkout', // Use this backend name for native PayPal
486
+ config: {
487
+ client_id: 'your-paypal-client-id',
488
+ auth_mode: 'manual',
489
+ sandbox_mode: 'true' // String 'true' or 'false'
490
+ }
491
+ };
492
+ ```
493
+
494
+ **Note:** Manual configuration requires you to manage credentials. Get your PayPal app credentials from https://developer.paypal.com/dashboard/
495
+
496
+ ### Container Configuration
497
+ PayPal tokenizer requires specific configuration:
498
+
499
+ ```javascript
500
+ const containerConfig = {
501
+ containerId: 'paypal-container', // Required: DOM element ID
502
+ currency: 'USD', // Required: ISO 4217 currency code
503
+ amount: 25.00, // Optional: Amount for display
504
+ enableVenmo: true, // Optional: Enable Venmo (default: true)
505
+ };
506
+ ```
507
+
508
+ ### Auto-Tokenization Mode
509
+ Unlike card tokenizers, PayPal operates in auto-tokenization mode:
510
+ - Token becomes available automatically when user approves payment
511
+ - No need to call `tokenize()` explicitly
512
+ - Listen for `tokenReady` event to receive token with payment details
513
+ - Backend pre-creates payment method and pending transaction during order creation
514
+ - Token includes `paymentMethodId` and `paymentTransactionId` for linking
515
+ - Pass both IDs to `createDonation()` to complete the payment
516
+
517
+ ### Popup Blocker Prevention
518
+ The PayPal tokenizer is designed to prevent popup blockers:
519
+ - Order creation starts synchronously in user's click event
520
+ - Network request happens during browser's "grace period" for popups
521
+ - No additional user interaction required
522
+
523
+ ### Venmo Support
524
+ Venmo button appears when:
525
+ - `enableVenmo` is set to `true` (defaults to `true`)
526
+ - User is on a supported platform (primarily mobile)
527
+ - Venmo is enabled in your PayPal account
528
+
529
+ When `enableVenmo: false`, Venmo is **explicitly disabled** and will not appear.
530
+
531
+ **⚠️ Important Venmo Sandbox Limitation:**
532
+ - **Venmo does NOT work in PayPal sandbox mode**
533
+ - Venmo button will appear but redirects to production Venmo
534
+ - Sandbox test accounts cannot be used with Venmo
535
+ - To test Venmo: use production mode with real accounts
536
+ - **For sandbox testing: set `enableVenmo: false`** to hide Venmo button
537
+
538
+ ### Testing
539
+ Use PayPal Sandbox accounts for testing:
540
+ 1. Create sandbox account at https://developer.paypal.com
541
+ 2. Use sandbox client ID in gateway configuration
542
+ 3. Set `sandbox_mode: true` in gateway config
543
+ 4. Use sandbox buyer account for test transactions
544
+ ```
@@ -1,4 +1,4 @@
1
- export declare const SDK_VERSION: string;
1
+ export declare const SDK_VERSION = "__SDK_VERSION__";
2
2
  export declare const PRODUCTION_BASE_URL = "https://secure-api.idonate.com";
3
3
  export declare const SANDBOX_BASE_URL = "https://api.qa-idonate.com";
4
4
  export declare const PRODUCTION_CARD_CONNECT_BASE_URL = "https://boltgw.cardconnect.com:8443";
package/dist/constants.js CHANGED
@@ -1,11 +1,7 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.CLIENT_HEADERS = exports.CARD_CONNECT_DEFAULT_STYLE = exports.DEFAULT_APP_NAME = exports.DEFAULT_CF_TURNSTILE_CDN_EXPLICIT_URL = exports.FALLBACK_CF_TURNSTILE_SITE_KEY = exports.FALLBACK_PC_SCRIPT_ID = exports.FALLBACK_PC_SCRIPT_URL = exports.SANDBOX_APPLE_PAY_URL = exports.APPLE_PAY_URL = exports.SPREEDLY_TOKENIZER_URL = exports.SANDBOX_CARD_CONNECT_BASE_URL = exports.PRODUCTION_CARD_CONNECT_BASE_URL = exports.SANDBOX_BASE_URL = exports.PRODUCTION_BASE_URL = exports.SDK_VERSION = void 0;
7
- const package_json_1 = __importDefault(require("../package.json"));
8
- exports.SDK_VERSION = package_json_1.default.version;
4
+ exports.SDK_VERSION = '1.2.0-dev1';
9
5
  exports.PRODUCTION_BASE_URL = 'https://secure-api.idonate.com';
10
6
  exports.SANDBOX_BASE_URL = 'https://api.qa-idonate.com';
11
7
  exports.PRODUCTION_CARD_CONNECT_BASE_URL = 'https://boltgw.cardconnect.com:8443';
@@ -83,6 +79,6 @@ input#cccvvfield {
83
79
  }
84
80
  `.replace(/\s+/gi, ' ');
85
81
  exports.CLIENT_HEADERS = {
86
- 'User-Agent': navigator.userAgent + ` idonate-sdk@${package_json_1.default.version}`,
82
+ 'User-Agent': navigator.userAgent + ` idonate-sdk@${exports.SDK_VERSION}`,
87
83
  'Content-Type': 'application/json',
88
84
  };
@@ -0,0 +1,12 @@
1
+ import { ApplePayMerchantValidationPayload, MerchantSession, TokenizeCardConnectApplePayResult } from './types';
2
+ export default class ApplePay {
3
+ private appleSession;
4
+ private paymentRequest;
5
+ private readonly paymentRequestDefaults;
6
+ private static readonly ApplePayApiVersion;
7
+ constructor(paymentRequest: Partial<ApplePayJS.ApplePayPaymentRequest>);
8
+ static isSupported(): boolean;
9
+ begin(): Promise<ApplePaySession>;
10
+ createSession(payload: ApplePayMerchantValidationPayload, embedApiBaseUrl: string): Promise<MerchantSession>;
11
+ tokenizeWithCardConnect(applePaymentMethod: ApplePayJS.ApplePayPayment, cardConnectBaseUrl: string): Promise<TokenizeCardConnectApplePayResult>;
12
+ }
@@ -0,0 +1,74 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { CLIENT_HEADERS } from './constants';
11
+ class ApplePay {
12
+ constructor(paymentRequest) {
13
+ this.appleSession = null;
14
+ this.paymentRequestDefaults = {
15
+ currencyCode: 'USD',
16
+ countryCode: 'US',
17
+ merchantCapabilities: ['supports3DS', 'supportsCredit', 'supportsDebit'],
18
+ supportedNetworks: ['amex', 'masterCard', 'visa', 'discover'],
19
+ requiredBillingContactFields: ['postalAddress', 'name'],
20
+ requiredShippingContactFields: ['email', 'phone'],
21
+ total: {
22
+ label: 'iDonate',
23
+ amount: '',
24
+ type: 'final',
25
+ },
26
+ };
27
+ this.paymentRequest = Object.assign({}, this.paymentRequestDefaults, paymentRequest);
28
+ }
29
+ static isSupported() {
30
+ return (window.ApplePaySession &&
31
+ ApplePaySession.canMakePayments() &&
32
+ ApplePaySession.supportsVersion(ApplePay.ApplePayApiVersion));
33
+ }
34
+ begin() {
35
+ return __awaiter(this, void 0, void 0, function* () {
36
+ if (!ApplePay.isSupported()) {
37
+ throw new Error('Apple Pay Not Supported');
38
+ }
39
+ this.appleSession = new ApplePaySession(ApplePay.ApplePayApiVersion, this.paymentRequest);
40
+ this.appleSession.begin();
41
+ return this.appleSession;
42
+ });
43
+ }
44
+ createSession(payload, embedApiBaseUrl) {
45
+ return fetch(`${embedApiBaseUrl}/payment/create-session`, {
46
+ method: 'POST',
47
+ headers: CLIENT_HEADERS,
48
+ body: JSON.stringify(payload),
49
+ }).then((response) => response.json());
50
+ }
51
+ tokenizeWithCardConnect(applePaymentMethod, cardConnectBaseUrl) {
52
+ const paymentData = applePaymentMethod.token.paymentData;
53
+ const token = paymentData.data;
54
+ const ectype = 'apple';
55
+ const ecsig = paymentData.signature;
56
+ const eckey = paymentData.header.ephemeralPublicKey;
57
+ const ectid = paymentData.header.transactionId;
58
+ const ecpublickeyhash = paymentData.header.publicKeyHash;
59
+ const dataString = `${token}&ectype=${ectype}&ecsig=${ecsig}&eckey=${eckey}&ectid=${ectid}&echash=&ecpublickeyhash=${ecpublickeyhash}`;
60
+ return fetch(`${cardConnectBaseUrl}/cardsecure/api/v1/ccn/tokenize`, {
61
+ method: 'POST',
62
+ headers: {
63
+ 'Content-Type': 'application/json',
64
+ },
65
+ body: JSON.stringify({
66
+ encryptionhandler: 'EC_APPLE_PAY',
67
+ devicedata: dataString,
68
+ unique: true,
69
+ }),
70
+ }).then((response) => response.json());
71
+ }
72
+ }
73
+ ApplePay.ApplePayApiVersion = 6;
74
+ export default ApplePay;
@@ -0,0 +1,5 @@
1
+ import iDonateClient from './idonate-client';
2
+ export declare const handleCFChallenge: (challengeResponse: Response, sdkClient: iDonateClient) => Promise<{
3
+ token: string;
4
+ preClearance?: boolean;
5
+ } | null>;
@@ -0,0 +1,77 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ let turnstileInstance = null;
11
+ export const handleCFChallenge = (challengeResponse, sdkClient) => new Promise((resolve, reject) => __awaiter(void 0, void 0, void 0, function* () {
12
+ var _a, _b, _c;
13
+ try {
14
+ const document = window === null || window === void 0 ? void 0 : window.document;
15
+ if (!document || !window) {
16
+ throw new Error('document is not present on window');
17
+ }
18
+ const challengeWrapper = document.createElement('div');
19
+ const challengeDiv = document.createElement('div');
20
+ const showChallenge = (turnstile) => {
21
+ var _a;
22
+ (_a = turnstile === null || turnstile === void 0 ? void 0 : turnstile.render) === null || _a === void 0 ? void 0 : _a.call(turnstile, '#iDonateTurnstileBox', {
23
+ sitekey: sdkClient.config.turnstileSiteKey,
24
+ callback(token, preClearance) {
25
+ challengeWrapper.remove();
26
+ resolve({ token, preClearance });
27
+ },
28
+ });
29
+ };
30
+ window.idonateTurnstileLoadedHandler = () => {
31
+ const turnstile = window.turnstile;
32
+ challengeDiv.innerHTML = '';
33
+ if (turnstile) {
34
+ turnstileInstance = turnstile;
35
+ }
36
+ showChallenge(turnstile);
37
+ };
38
+ challengeWrapper.setAttribute('id', 'idonateTurnstileWrapper');
39
+ challengeWrapper.style.position = 'fixed';
40
+ challengeWrapper.style.top = '0';
41
+ challengeWrapper.style.bottom = '0';
42
+ challengeWrapper.style.left = '0';
43
+ challengeWrapper.style.right = '0';
44
+ challengeWrapper.style.backgroundColor = 'rgba(0,0,0,0.9)';
45
+ challengeWrapper.style.transition = 'all 400ms';
46
+ challengeWrapper.style.display = 'flex';
47
+ challengeWrapper.style.flexDirection = 'column';
48
+ challengeWrapper.style.padding = '40px 30px';
49
+ challengeWrapper.style.opacity = '0';
50
+ challengeWrapper.style.color = 'white';
51
+ challengeWrapper.style.fontFamily = 'sans-serif';
52
+ challengeWrapper.style.zIndex = '1000';
53
+ challengeWrapper.innerHTML =
54
+ '<h1 id="idonateTurnstileVerificationHeader">Last tiny step before we submit your payment:</h1>';
55
+ challengeDiv.setAttribute('id', 'iDonateTurnstileBox');
56
+ challengeWrapper.append(challengeDiv);
57
+ document.body.append(challengeWrapper);
58
+ if (turnstileInstance) {
59
+ showChallenge(turnstileInstance);
60
+ }
61
+ else {
62
+ const cloudflareScript = document.createElement('script');
63
+ challengeDiv.innerHTML = 'loading ...';
64
+ cloudflareScript.src =
65
+ sdkClient.config.turnstileCdnUrl +
66
+ '?render=explicit&onload=idonateTurnstileLoadedHandler';
67
+ document.body.append(cloudflareScript);
68
+ }
69
+ (_a = challengeDiv.scrollIntoView) === null || _a === void 0 ? void 0 : _a.call(challengeDiv);
70
+ challengeWrapper.style.opacity = '1';
71
+ }
72
+ catch (e) {
73
+ (_b = console === null || console === void 0 ? void 0 : console.error) === null || _b === void 0 ? void 0 : _b.call(console, e);
74
+ (_c = console === null || console === void 0 ? void 0 : console.warn) === null || _c === void 0 ? void 0 : _c.call(console, 'iDonate SDK: Could not handle request, please reload the page and try again');
75
+ reject(null);
76
+ }
77
+ }));
@@ -0,0 +1,22 @@
1
+ import { ClientOptions } from './types';
2
+ export default class ConfigHandler {
3
+ readonly apiBaseUrl: string;
4
+ readonly embedApiBaseUrl: string;
5
+ readonly cardConnectBaseUrl: string;
6
+ readonly cardConnectTokenizerUrl: string;
7
+ readonly authApiBaseUrl: string;
8
+ readonly donorApiBaseUrl: string;
9
+ readonly spreedlyEnvironmentKey: string | undefined;
10
+ readonly applePayUrl: string;
11
+ readonly pcScriptBase: string;
12
+ readonly pcScriptId: string;
13
+ readonly enableDelay: boolean;
14
+ readonly secondsToDelay: number;
15
+ readonly turnstileCdnUrl: string;
16
+ readonly turnstileSiteKey: string;
17
+ readonly client: string;
18
+ readonly enableSpreedlySecureTokenization: boolean;
19
+ readonly organizationId: number | undefined;
20
+ readonly embedId: string | undefined;
21
+ constructor(options: Partial<ClientOptions>);
22
+ }
@@ -0,0 +1,47 @@
1
+ import { SANDBOX_BASE_URL, PRODUCTION_CARD_CONNECT_BASE_URL, PRODUCTION_BASE_URL, SANDBOX_CARD_CONNECT_BASE_URL, SANDBOX_APPLE_PAY_URL, APPLE_PAY_URL, FALLBACK_PC_SCRIPT_URL, FALLBACK_PC_SCRIPT_ID, FALLBACK_CF_TURNSTILE_SITE_KEY, DEFAULT_CF_TURNSTILE_CDN_EXPLICIT_URL, DEFAULT_APP_NAME, } from './constants';
2
+ export default class ConfigHandler {
3
+ constructor(options) {
4
+ if (options.enableSandboxMode) {
5
+ this.apiBaseUrl = SANDBOX_BASE_URL;
6
+ this.cardConnectBaseUrl = SANDBOX_CARD_CONNECT_BASE_URL;
7
+ this.applePayUrl = SANDBOX_APPLE_PAY_URL;
8
+ }
9
+ else {
10
+ this.apiBaseUrl = PRODUCTION_BASE_URL;
11
+ this.cardConnectBaseUrl = PRODUCTION_CARD_CONNECT_BASE_URL;
12
+ this.applePayUrl = APPLE_PAY_URL;
13
+ }
14
+ this.client = options.sdkClientName || DEFAULT_APP_NAME;
15
+ if (options.overrideBaseUrl) {
16
+ this.apiBaseUrl = options.overrideBaseUrl;
17
+ }
18
+ this.authApiBaseUrl =
19
+ options.overrideAuthApiBaseUrl || `${this.apiBaseUrl}/auth`;
20
+ this.donorApiBaseUrl =
21
+ options.overrideDonorApiBaseUrl || `${this.apiBaseUrl}/donor`;
22
+ this.embedApiBaseUrl =
23
+ options.overrideEmbedApiBaseUrl || `${this.apiBaseUrl}/embed`;
24
+ if (options.overrideApplePayUrl) {
25
+ this.applePayUrl = options.overrideApplePayUrl;
26
+ }
27
+ if (options.overrideCardConnectBaseUrl) {
28
+ this.cardConnectBaseUrl = options.overrideCardConnectBaseUrl;
29
+ }
30
+ this.pcScriptBase = options.pcScriptBase || FALLBACK_PC_SCRIPT_URL;
31
+ this.pcScriptId = options.pcScriptId || FALLBACK_PC_SCRIPT_ID;
32
+ this.turnstileCdnUrl =
33
+ options.turnstileCdnUrl || DEFAULT_CF_TURNSTILE_CDN_EXPLICIT_URL;
34
+ this.turnstileSiteKey =
35
+ options.turnstileSiteKey || FALLBACK_CF_TURNSTILE_SITE_KEY;
36
+ if (options === null || options === void 0 ? void 0 : options.spreedlyEnvironmentKey) {
37
+ this.spreedlyEnvironmentKey = options.spreedlyEnvironmentKey;
38
+ }
39
+ this.enableDelay = options.enableDelay || false;
40
+ this.secondsToDelay = options.secondsToDelay || 0;
41
+ this.enableSpreedlySecureTokenization =
42
+ options.enableSpreedlySecureTokenization || false;
43
+ this.organizationId = options.organizationId;
44
+ this.embedId = options.embedId;
45
+ this.cardConnectTokenizerUrl = `${this.cardConnectBaseUrl}/itoke/ajax-tokenizer.html`;
46
+ }
47
+ }
@@ -0,0 +1,18 @@
1
+ export declare const SDK_VERSION = "__SDK_VERSION__";
2
+ export declare const PRODUCTION_BASE_URL = "https://secure-api.idonate.com";
3
+ export declare const SANDBOX_BASE_URL = "https://api.qa-idonate.com";
4
+ export declare const PRODUCTION_CARD_CONNECT_BASE_URL = "https://boltgw.cardconnect.com:8443";
5
+ export declare const SANDBOX_CARD_CONNECT_BASE_URL = "https://boltgw-uat.cardconnect.com";
6
+ export declare const SPREEDLY_TOKENIZER_URL = "https://core.spreedly.com/v1/payment_methods.json";
7
+ export declare const APPLE_PAY_URL = "https://apple-pay-gateway.apple.com/paymentservices/paymentSession";
8
+ export declare const SANDBOX_APPLE_PAY_URL = "https://apple-pay-gateway-cert.apple.com/paymentservices/paymentSession";
9
+ export declare const FALLBACK_PC_SCRIPT_URL = "https://p.idonate.com/r";
10
+ export declare const FALLBACK_PC_SCRIPT_ID = "_3fd4dad26e8c277bc50fb2ddf8233b50bc8d9704";
11
+ export declare const FALLBACK_CF_TURNSTILE_SITE_KEY = "0x4AAAAAAAxuRxNZTvX8shIj";
12
+ export declare const DEFAULT_CF_TURNSTILE_CDN_EXPLICIT_URL = "https://challenges.cloudflare.com/turnstile/v0/api.js";
13
+ export declare const DEFAULT_APP_NAME = "unnamed-sdk-client";
14
+ export declare const CARD_CONNECT_DEFAULT_STYLE: string;
15
+ export declare const CLIENT_HEADERS: {
16
+ 'User-Agent': string;
17
+ 'Content-Type': string;
18
+ };