@idonatedev/idonate-sdk 1.1.0-dev8 → 1.2.0-dev0
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 +308 -7
- package/dist/constants.d.ts +1 -1
- package/dist/constants.js +2 -6
- package/dist/esm/apple-pay.d.ts +12 -0
- package/dist/esm/apple-pay.js +74 -0
- package/dist/esm/cloudflare-challenge-handler.d.ts +5 -0
- package/dist/esm/cloudflare-challenge-handler.js +77 -0
- package/dist/esm/config-handler.d.ts +22 -0
- package/dist/esm/config-handler.js +47 -0
- package/dist/esm/constants.d.ts +18 -0
- package/dist/esm/constants.js +81 -0
- package/dist/esm/google-pay.d.ts +18 -0
- package/dist/esm/google-pay.js +140 -0
- package/dist/esm/idonate-client.d.ts +32 -0
- package/dist/esm/idonate-client.js +294 -0
- package/dist/esm/index.d.ts +11 -0
- package/dist/esm/index.js +11 -0
- package/dist/esm/recaptcha.d.ts +12 -0
- package/dist/esm/recaptcha.js +89 -0
- package/dist/esm/shared.d.ts +4 -0
- package/dist/esm/shared.js +21 -0
- package/dist/esm/test-utils.d.ts +81 -0
- package/dist/esm/test-utils.js +94 -0
- package/dist/esm/tokenize/CardConnectTokenizer.d.ts +51 -0
- package/dist/esm/tokenize/CardConnectTokenizer.js +712 -0
- package/dist/esm/tokenize/PayPalTokenizer.d.ts +77 -0
- package/dist/esm/tokenize/PayPalTokenizer.js +268 -0
- package/dist/esm/tokenize/SpreedlyTokenizer.d.ts +92 -0
- package/dist/esm/tokenize/SpreedlyTokenizer.js +1140 -0
- package/dist/esm/tokenize/Tokenizer.d.ts +37 -0
- package/dist/esm/tokenize/Tokenizer.js +150 -0
- package/dist/esm/tokenize/iats.d.ts +3 -0
- package/dist/esm/tokenize/iats.js +48 -0
- package/dist/esm/tokenize/index.d.ts +7 -0
- package/dist/esm/tokenize/index.js +7 -0
- package/dist/esm/tokenize/spreedly-secure.d.ts +8 -0
- package/dist/esm/tokenize/spreedly-secure.js +40 -0
- package/dist/esm/tokenize/styles.d.ts +4 -0
- package/dist/esm/tokenize/styles.js +46 -0
- package/dist/esm/tokenize/tokenizer-constants.d.ts +62 -0
- package/dist/esm/tokenize/tokenizer-constants.js +62 -0
- package/dist/esm/tokenize/tokenizer-utils.d.ts +19 -0
- package/dist/esm/tokenize/tokenizer-utils.js +139 -0
- package/dist/esm/tokenize/types.d.ts +146 -0
- package/dist/esm/tokenize/types.js +26 -0
- package/dist/esm/typeAdapters.d.ts +29 -0
- package/dist/esm/typeAdapters.js +189 -0
- package/dist/esm/types.d.ts +378 -0
- package/dist/esm/types.js +14 -0
- package/dist/esm/util.d.ts +17 -0
- package/dist/esm/util.js +113 -0
- package/dist/idonate-client.d.ts +6 -2
- package/dist/idonate-client.js +40 -2
- package/dist/shared.d.ts +2 -1
- package/dist/shared.js +9 -0
- package/dist/tokenize/CardConnectTokenizer.d.ts +1 -0
- package/dist/tokenize/CardConnectTokenizer.js +127 -104
- package/dist/tokenize/PayPalTokenizer.d.ts +77 -0
- package/dist/tokenize/PayPalTokenizer.js +272 -0
- package/dist/tokenize/SpreedlyTokenizer.d.ts +1 -0
- package/dist/tokenize/SpreedlyTokenizer.js +276 -135
- package/dist/tokenize/Tokenizer.js +6 -2
- package/dist/tokenize/index.d.ts +1 -0
- package/dist/tokenize/index.js +3 -1
- package/dist/tokenize/styles.d.ts +1 -0
- package/dist/tokenize/styles.js +9 -0
- package/dist/tokenize/tokenizer-utils.js +1 -1
- package/dist/tokenize/types.d.ts +6 -7
- package/dist/typeAdapters.js +3 -2
- package/dist/types.d.ts +16 -5
- package/package.json +14 -3
- 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: '
|
|
151
|
-
|
|
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(
|
|
178
|
-
|
|
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:
|
|
196
|
-
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
|
+
```
|
package/dist/constants.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const SDK_VERSION
|
|
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
|
-
|
|
8
|
-
exports.SDK_VERSION = package_json_1.default.version;
|
|
4
|
+
exports.SDK_VERSION = '1.2.0-dev0';
|
|
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@${
|
|
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,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
|
+
};
|