@idonatedev/idonate-sdk 1.1.0-dev9 → 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.js +46 -79
- package/dist/tokenize/PayPalTokenizer.d.ts +77 -0
- package/dist/tokenize/PayPalTokenizer.js +272 -0
- package/dist/tokenize/SpreedlyTokenizer.js +6 -6
- 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/tokenizer-utils.js +1 -1
- package/dist/tokenize/types.d.ts +3 -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
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
export const SDK_VERSION = '1.2.0-dev0';
|
|
2
|
+
export const PRODUCTION_BASE_URL = 'https://secure-api.idonate.com';
|
|
3
|
+
export const SANDBOX_BASE_URL = 'https://api.qa-idonate.com';
|
|
4
|
+
export const PRODUCTION_CARD_CONNECT_BASE_URL = 'https://boltgw.cardconnect.com:8443';
|
|
5
|
+
export const SANDBOX_CARD_CONNECT_BASE_URL = 'https://boltgw-uat.cardconnect.com';
|
|
6
|
+
export const SPREEDLY_TOKENIZER_URL = 'https://core.spreedly.com/v1/payment_methods.json';
|
|
7
|
+
export const APPLE_PAY_URL = 'https://apple-pay-gateway.apple.com/paymentservices/paymentSession';
|
|
8
|
+
export const SANDBOX_APPLE_PAY_URL = 'https://apple-pay-gateway-cert.apple.com/paymentservices/paymentSession';
|
|
9
|
+
export const FALLBACK_PC_SCRIPT_URL = 'https://p.idonate.com/r';
|
|
10
|
+
export const FALLBACK_PC_SCRIPT_ID = '_3fd4dad26e8c277bc50fb2ddf8233b50bc8d9704';
|
|
11
|
+
export const FALLBACK_CF_TURNSTILE_SITE_KEY = '0x4AAAAAAAxuRxNZTvX8shIj';
|
|
12
|
+
export const DEFAULT_CF_TURNSTILE_CDN_EXPLICIT_URL = 'https://challenges.cloudflare.com/turnstile/v0/api.js';
|
|
13
|
+
export const DEFAULT_APP_NAME = 'unnamed-sdk-client';
|
|
14
|
+
export const CARD_CONNECT_DEFAULT_STYLE = `
|
|
15
|
+
body {
|
|
16
|
+
margin: 0;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
form {
|
|
20
|
+
display: flex;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
label#cccardlabel {
|
|
24
|
+
display: none;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
br {
|
|
28
|
+
display: none;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
label#cccvvlabel {
|
|
32
|
+
display: none;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
label#ccexpirylabel {
|
|
36
|
+
display: none;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
input {
|
|
40
|
+
padding: 10px;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
select {
|
|
44
|
+
padding: 10px;
|
|
45
|
+
font-size: 14px;
|
|
46
|
+
color: #8b959d;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
select#ccexpirymonth {
|
|
50
|
+
margin-right: -30px;
|
|
51
|
+
border: 1px solid #b6b8ba;
|
|
52
|
+
border-right: 0;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
input#ccnumfield {
|
|
56
|
+
width: 70%;
|
|
57
|
+
border: 1px solid #b6b8ba;
|
|
58
|
+
border-right: 0;
|
|
59
|
+
border-top-left-radius: 3px;
|
|
60
|
+
border-bottom-left-radius: 3px;
|
|
61
|
+
font-size: 14px;
|
|
62
|
+
color: #8b959d;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
select#ccexpiryyear {
|
|
66
|
+
border: 1px solid #b6b8ba;
|
|
67
|
+
border-right: 0;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
input#cccvvfield {
|
|
71
|
+
border: 1px solid #b6b8ba;
|
|
72
|
+
border-top-right-radius: 3px;
|
|
73
|
+
border-bottom-right-radius: 3px;
|
|
74
|
+
font-size: 14px;
|
|
75
|
+
color: #8b959d;
|
|
76
|
+
}
|
|
77
|
+
`.replace(/\s+/gi, ' ');
|
|
78
|
+
export const CLIENT_HEADERS = {
|
|
79
|
+
'User-Agent': navigator.userAgent + ` idonate-sdk@${SDK_VERSION}`,
|
|
80
|
+
'Content-Type': 'application/json',
|
|
81
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { TokenizeCardConnectGooglePayResult, GooglePayConfig } from './types';
|
|
2
|
+
export default class GooglePay {
|
|
3
|
+
private static resolveLib;
|
|
4
|
+
static injectScript(): void;
|
|
5
|
+
private baseRequest;
|
|
6
|
+
private baseCardPaymentMethod;
|
|
7
|
+
private transactionInfo;
|
|
8
|
+
private tokenizationSpecification;
|
|
9
|
+
private googlePayOptions;
|
|
10
|
+
private readonly paymentRequestDefaults;
|
|
11
|
+
private paymentRequest;
|
|
12
|
+
paymentsClient: google.payments.api.PaymentsClient | null;
|
|
13
|
+
constructor(googlePayConfig: GooglePayConfig);
|
|
14
|
+
getGoogleIsReadyToPayRequest(): google.payments.api.IsReadyToPayRequest;
|
|
15
|
+
getGooglePaymentClient(): Promise<google.payments.api.PaymentsClient>;
|
|
16
|
+
onGooglePaymentButtonClicked(transactionInfoUpdate: Partial<google.payments.api.TransactionInfo>): Promise<google.payments.api.PaymentData>;
|
|
17
|
+
tokenizeWithCardConnect(paymentToken: string, cardConnectBaseUrl: string): Promise<TokenizeCardConnectGooglePayResult>;
|
|
18
|
+
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
export default class GooglePay {
|
|
2
|
+
static resolveLib(options) {
|
|
3
|
+
const startWait = new Date();
|
|
4
|
+
return new Promise((resolve, reject) => {
|
|
5
|
+
function poll() {
|
|
6
|
+
if (window.google !== undefined &&
|
|
7
|
+
window.google.payments !== undefined) {
|
|
8
|
+
const paymentsClient = new google.payments.api.PaymentsClient(options);
|
|
9
|
+
resolve(paymentsClient);
|
|
10
|
+
}
|
|
11
|
+
else {
|
|
12
|
+
const elapsedMs = new Date().valueOf() - startWait.valueOf();
|
|
13
|
+
if (elapsedMs > 15000) {
|
|
14
|
+
reject(new Error('pay.js not loaded after 15 seconds'));
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
setTimeout(poll, 250);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
poll();
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
static injectScript() {
|
|
25
|
+
if (window.google !== undefined && window.google.payments !== undefined) {
|
|
26
|
+
throw new Error('google payments is already injected');
|
|
27
|
+
}
|
|
28
|
+
const script = document.createElement('script');
|
|
29
|
+
script.src = 'https://pay.google.com/gp/p/js/pay.js?render=explicit';
|
|
30
|
+
script.async = true;
|
|
31
|
+
script.defer = true;
|
|
32
|
+
document.body.appendChild(script);
|
|
33
|
+
}
|
|
34
|
+
constructor(googlePayConfig) {
|
|
35
|
+
this.baseRequest = {
|
|
36
|
+
apiVersion: 2,
|
|
37
|
+
apiVersionMinor: 0,
|
|
38
|
+
};
|
|
39
|
+
this.baseCardPaymentMethod = {
|
|
40
|
+
type: 'CARD',
|
|
41
|
+
parameters: {
|
|
42
|
+
allowedAuthMethods: ['PAN_ONLY', 'CRYPTOGRAM_3DS'],
|
|
43
|
+
allowedCardNetworks: [
|
|
44
|
+
'AMEX',
|
|
45
|
+
'DISCOVER',
|
|
46
|
+
'INTERAC',
|
|
47
|
+
'JCB',
|
|
48
|
+
'MASTERCARD',
|
|
49
|
+
'VISA',
|
|
50
|
+
],
|
|
51
|
+
billingAddressRequired: true,
|
|
52
|
+
billingAddressParameters: {
|
|
53
|
+
format: 'FULL',
|
|
54
|
+
phoneNumberRequired: true,
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
this.transactionInfo = {
|
|
59
|
+
countryCode: 'US',
|
|
60
|
+
currencyCode: 'USD',
|
|
61
|
+
totalPriceStatus: 'FINAL',
|
|
62
|
+
totalPrice: '',
|
|
63
|
+
};
|
|
64
|
+
this.tokenizationSpecification = {
|
|
65
|
+
type: 'PAYMENT_GATEWAY',
|
|
66
|
+
parameters: {
|
|
67
|
+
gateway: 'cardconnect',
|
|
68
|
+
gatewayMerchantId: '',
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
this.googlePayOptions = {
|
|
72
|
+
environment: 'PRODUCTION',
|
|
73
|
+
};
|
|
74
|
+
this.paymentRequestDefaults = Object.assign(Object.assign({}, this.baseRequest), { merchantInfo: {
|
|
75
|
+
merchantId: '',
|
|
76
|
+
}, transactionInfo: this.transactionInfo, emailRequired: true, allowedPaymentMethods: [
|
|
77
|
+
Object.assign(Object.assign({}, this.baseCardPaymentMethod), { tokenizationSpecification: this.tokenizationSpecification }),
|
|
78
|
+
] });
|
|
79
|
+
this.paymentsClient = null;
|
|
80
|
+
const { paymentOptions, cardConnectMerchantId, paymentDataRequest, baseCardPaymentMethodParameters = {}, } = googlePayConfig;
|
|
81
|
+
this.tokenizationSpecification.parameters.gatewayMerchantId =
|
|
82
|
+
cardConnectMerchantId;
|
|
83
|
+
this.paymentRequest = Object.assign({}, this.paymentRequestDefaults, paymentDataRequest);
|
|
84
|
+
this.googlePayOptions = Object.assign({}, this.googlePayOptions, Object.assign(Object.assign({}, paymentOptions), { merchantInfo: this.paymentRequest.merchantInfo }));
|
|
85
|
+
this.baseCardPaymentMethod.parameters = Object.assign(Object.assign({}, this.baseCardPaymentMethod.parameters), baseCardPaymentMethodParameters);
|
|
86
|
+
}
|
|
87
|
+
getGoogleIsReadyToPayRequest() {
|
|
88
|
+
return Object.assign({}, this.baseRequest, {
|
|
89
|
+
allowedPaymentMethods: [this.baseCardPaymentMethod],
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
getGooglePaymentClient() {
|
|
93
|
+
return new Promise((resolve, reject) => {
|
|
94
|
+
if (!this.paymentsClient) {
|
|
95
|
+
GooglePay.resolveLib(this.googlePayOptions)
|
|
96
|
+
.then((client) => {
|
|
97
|
+
this.paymentsClient = client;
|
|
98
|
+
resolve(client);
|
|
99
|
+
})
|
|
100
|
+
.catch((err) => reject(err));
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
resolve(this.paymentsClient);
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
onGooglePaymentButtonClicked(transactionInfoUpdate) {
|
|
108
|
+
const paymentDataRequest = this.paymentRequest;
|
|
109
|
+
this.transactionInfo = Object.assign({}, this.transactionInfo, transactionInfoUpdate);
|
|
110
|
+
paymentDataRequest.transactionInfo = this.transactionInfo;
|
|
111
|
+
return new Promise((resolve, reject) => {
|
|
112
|
+
if (!this.paymentsClient) {
|
|
113
|
+
reject(new Error('PaymentClient is not initialized'));
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
this.paymentsClient
|
|
117
|
+
.loadPaymentData(paymentDataRequest)
|
|
118
|
+
.then((paymentData) => {
|
|
119
|
+
resolve(paymentData);
|
|
120
|
+
})
|
|
121
|
+
.catch((err) => {
|
|
122
|
+
reject(err);
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
tokenizeWithCardConnect(paymentToken, cardConnectBaseUrl) {
|
|
128
|
+
return fetch(`${cardConnectBaseUrl}/cardsecure/api/v1/ccn/tokenize`, {
|
|
129
|
+
method: 'POST',
|
|
130
|
+
headers: {
|
|
131
|
+
'Content-Type': 'application/json',
|
|
132
|
+
},
|
|
133
|
+
body: JSON.stringify({
|
|
134
|
+
encryptionhandler: 'EC_GOOGLE_PAY',
|
|
135
|
+
devicedata: paymentToken,
|
|
136
|
+
unique: true,
|
|
137
|
+
}),
|
|
138
|
+
}).then((response) => response.json());
|
|
139
|
+
}
|
|
140
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { ClientOptions, Contact, Address, CreatePaymentMethodRequest, CreatePaymentMethodResult, CreateDonationRequest, CreateDonationResult, TokenizeApplePayResult, EmbedConfig } from './types';
|
|
2
|
+
import ConfigHandler from './config-handler';
|
|
3
|
+
import { Tokenizer, PaymentMethodType, PaymentGateway, TokenizerContainer } from './tokenize';
|
|
4
|
+
export default class iDonateClient {
|
|
5
|
+
private readonly clientKey;
|
|
6
|
+
private readonly embedId;
|
|
7
|
+
private currentOrganizationId;
|
|
8
|
+
private allowTransaction;
|
|
9
|
+
private embedConfigCache?;
|
|
10
|
+
private embedConfigPromise?;
|
|
11
|
+
get organizationId(): string;
|
|
12
|
+
readonly options: ClientOptions;
|
|
13
|
+
readonly config: ConfigHandler;
|
|
14
|
+
constructor(clientKey: string, embedId: string | EmbedConfig, options?: Partial<ClientOptions>);
|
|
15
|
+
createDonation(donation: CreateDonationRequest): Promise<CreateDonationResult>;
|
|
16
|
+
createTransaction(donation: CreateDonationRequest): Promise<{
|
|
17
|
+
transactionId: string | undefined;
|
|
18
|
+
_raw_response: any;
|
|
19
|
+
}>;
|
|
20
|
+
createPaymentMethod(paymentMethod: CreatePaymentMethodRequest): Promise<CreatePaymentMethodResult>;
|
|
21
|
+
setOrganizationId(organizationId: string): void;
|
|
22
|
+
waitForDonationResult(donationId: string, afterEachCheck?: () => void): Promise<any>;
|
|
23
|
+
tokenizeCardConnectApplePay(applePayRequest: Partial<ApplePayJS.ApplePayPaymentRequest>): Promise<TokenizeApplePayResult>;
|
|
24
|
+
createTokenizer(gateway: PaymentGateway, container: TokenizerContainer): Promise<Tokenizer>;
|
|
25
|
+
tokenizeSpreedlyPayPal(data: {
|
|
26
|
+
contact: Contact;
|
|
27
|
+
address: Address;
|
|
28
|
+
}): Promise<string>;
|
|
29
|
+
selectGateway(availableGateways: PaymentGateway[], paymentType: PaymentMethodType, preferredGatewayId?: string): PaymentGateway | undefined;
|
|
30
|
+
getEmbedConfig(): Promise<EmbedConfig>;
|
|
31
|
+
getGateway(gatewayId: string): Promise<PaymentGateway>;
|
|
32
|
+
}
|
|
@@ -0,0 +1,294 @@
|
|
|
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 { ClientError, } from './types';
|
|
11
|
+
import { buildDonationResult, buildCashPaymentPayload } from './typeAdapters';
|
|
12
|
+
import { CLIENT_HEADERS, SDK_VERSION } from './constants';
|
|
13
|
+
import { parseResponse } from './util';
|
|
14
|
+
import ApplePay from './apple-pay';
|
|
15
|
+
import ConfigHandler from './config-handler';
|
|
16
|
+
import { SpreedlyTokenizer } from './tokenize/SpreedlyTokenizer';
|
|
17
|
+
import * as shared from './shared';
|
|
18
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
19
|
+
import { handleCFChallenge } from './cloudflare-challenge-handler';
|
|
20
|
+
import { Tokenizer, } from './tokenize';
|
|
21
|
+
const clientDefaults = {
|
|
22
|
+
enableSandboxMode: false,
|
|
23
|
+
overrideBaseUrl: undefined,
|
|
24
|
+
enableDelay: false,
|
|
25
|
+
secondsToDelay: 0,
|
|
26
|
+
};
|
|
27
|
+
export default class iDonateClient {
|
|
28
|
+
get organizationId() {
|
|
29
|
+
if (!this.currentOrganizationId) {
|
|
30
|
+
throw new Error('organizationId undefined');
|
|
31
|
+
}
|
|
32
|
+
return this.currentOrganizationId;
|
|
33
|
+
}
|
|
34
|
+
constructor(clientKey, embedId, options) {
|
|
35
|
+
var _a;
|
|
36
|
+
this.clientKey = clientKey;
|
|
37
|
+
if (typeof embedId === 'string') {
|
|
38
|
+
this.embedId = embedId;
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
this.embedConfigCache = embedId;
|
|
42
|
+
this.embedId = embedId.embed_id || '';
|
|
43
|
+
if (embedId.organization_id) {
|
|
44
|
+
this.currentOrganizationId = embedId.organization_id;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
if (!this.currentOrganizationId) {
|
|
48
|
+
this.currentOrganizationId = clientKey;
|
|
49
|
+
}
|
|
50
|
+
this.options = Object.assign({}, clientDefaults, options);
|
|
51
|
+
this.allowTransaction = false;
|
|
52
|
+
this.config = new ConfigHandler(this.options);
|
|
53
|
+
const configEntries = Object.entries(this.config);
|
|
54
|
+
for (const [key, value] of configEntries) {
|
|
55
|
+
const descriptor = Object.getOwnPropertyDescriptor(this, key);
|
|
56
|
+
if (!descriptor || descriptor.set !== undefined) {
|
|
57
|
+
try {
|
|
58
|
+
this[key] = value;
|
|
59
|
+
}
|
|
60
|
+
catch (e) {
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
if (this.options.enableDelay && this.options.secondsToDelay) {
|
|
65
|
+
const delay = this.options.secondsToDelay * 1000;
|
|
66
|
+
setTimeout(() => {
|
|
67
|
+
this.allowTransaction = true;
|
|
68
|
+
}, delay);
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
this.allowTransaction = true;
|
|
72
|
+
}
|
|
73
|
+
if (this.options.enableSandboxMode && console !== undefined) {
|
|
74
|
+
console.info(`[Sandbox] iDonate SDK Configuration (v${SDK_VERSION}):`, JSON.parse(JSON.stringify(this)));
|
|
75
|
+
}
|
|
76
|
+
try {
|
|
77
|
+
const { pcScriptBase, pcScriptId } = this.config;
|
|
78
|
+
if (!pcScriptBase || !pcScriptId) {
|
|
79
|
+
throw new Error('missing config');
|
|
80
|
+
}
|
|
81
|
+
const uuid = uuidv4();
|
|
82
|
+
const script = window.document.createElement('script');
|
|
83
|
+
script.setAttribute('src', pcScriptBase + '/' + uuid + '.js');
|
|
84
|
+
script.setAttribute('id', pcScriptId);
|
|
85
|
+
let appended = false;
|
|
86
|
+
const appendScript = () => {
|
|
87
|
+
var _a;
|
|
88
|
+
try {
|
|
89
|
+
if (appended)
|
|
90
|
+
return;
|
|
91
|
+
window.document.body.append(script);
|
|
92
|
+
appended = true;
|
|
93
|
+
}
|
|
94
|
+
catch (e) {
|
|
95
|
+
(_a = console === null || console === void 0 ? void 0 : console.warn) === null || _a === void 0 ? void 0 : _a.call(console, 'not appended');
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
appendScript();
|
|
99
|
+
window.addEventListener('DOMContentLoaded', () => {
|
|
100
|
+
window.document.body.append(script);
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
catch (e) {
|
|
104
|
+
(_a = console === null || console === void 0 ? void 0 : console.warn) === null || _a === void 0 ? void 0 : _a.call(console, 'Warning, partial initialization: ', String(e));
|
|
105
|
+
}
|
|
106
|
+
if (!this.currentOrganizationId) {
|
|
107
|
+
this.setOrganizationId(this.clientKey);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
createDonation(donation) {
|
|
111
|
+
if (!this.allowTransaction) {
|
|
112
|
+
throw new Error('Wow, that was fast - try again');
|
|
113
|
+
}
|
|
114
|
+
if (!donation.embedId) {
|
|
115
|
+
donation.embedId = this.embedId;
|
|
116
|
+
}
|
|
117
|
+
const payload = buildCashPaymentPayload(this.organizationId, donation);
|
|
118
|
+
const fetchCall = (clearanceToken) => fetch(`${this.config.embedApiBaseUrl}/donate/cash-payment`, {
|
|
119
|
+
method: 'POST',
|
|
120
|
+
headers: Object.assign(Object.assign(Object.assign({}, CLIENT_HEADERS), (clearanceToken ? { 'cf-validation-token': clearanceToken } : {})), { 'User-Agent': CLIENT_HEADERS['User-Agent'] + ' source:' + this.config.client }),
|
|
121
|
+
body: JSON.stringify(payload),
|
|
122
|
+
credentials: 'include',
|
|
123
|
+
});
|
|
124
|
+
return (fetchCall()
|
|
125
|
+
.then((response) => __awaiter(this, void 0, void 0, function* () {
|
|
126
|
+
if (response.headers.get('cf-mitigated') === 'challenge') {
|
|
127
|
+
const clearance = yield handleCFChallenge(response, this);
|
|
128
|
+
return fetchCall(clearance === null || clearance === void 0 ? void 0 : clearance.token);
|
|
129
|
+
}
|
|
130
|
+
return response;
|
|
131
|
+
}))
|
|
132
|
+
.then((response) => parseResponse(response, { throwErrors: true }))
|
|
133
|
+
.then((response) => buildDonationResult(response)));
|
|
134
|
+
}
|
|
135
|
+
createTransaction(donation) {
|
|
136
|
+
return this.createDonation(donation).then((result) => {
|
|
137
|
+
var _a;
|
|
138
|
+
return {
|
|
139
|
+
transactionId: (_a = result.transaction) === null || _a === void 0 ? void 0 : _a.id,
|
|
140
|
+
_raw_response: result._raw_response,
|
|
141
|
+
};
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
createPaymentMethod(paymentMethod) {
|
|
145
|
+
if (!paymentMethod.embedId) {
|
|
146
|
+
paymentMethod.embedId = this.embedId;
|
|
147
|
+
}
|
|
148
|
+
return shared.createPaymentMethod(paymentMethod, this.config);
|
|
149
|
+
}
|
|
150
|
+
setOrganizationId(organizationId) {
|
|
151
|
+
this.currentOrganizationId = organizationId;
|
|
152
|
+
}
|
|
153
|
+
waitForDonationResult(donationId, afterEachCheck) {
|
|
154
|
+
function isReady(response) {
|
|
155
|
+
return !!response.processed && !!response.transaction;
|
|
156
|
+
}
|
|
157
|
+
return new Promise((resolve, reject) => {
|
|
158
|
+
setTimeout(() => {
|
|
159
|
+
let pollHandle;
|
|
160
|
+
pollHandle = setInterval(() => {
|
|
161
|
+
fetch(`${this.config.embedApiBaseUrl}/donate/cash-payment/${donationId}/payment_status`, {
|
|
162
|
+
method: 'GET',
|
|
163
|
+
headers: {
|
|
164
|
+
'Content-Type': 'application/json',
|
|
165
|
+
},
|
|
166
|
+
})
|
|
167
|
+
.then((response) => response.json())
|
|
168
|
+
.then((rawResponse) => rawResponse.result)
|
|
169
|
+
.then((response) => {
|
|
170
|
+
if (isReady(response)) {
|
|
171
|
+
if (pollHandle) {
|
|
172
|
+
clearInterval(pollHandle);
|
|
173
|
+
pollHandle = null;
|
|
174
|
+
}
|
|
175
|
+
if (response.error) {
|
|
176
|
+
reject(new ClientError(response.error));
|
|
177
|
+
}
|
|
178
|
+
resolve(buildDonationResult({
|
|
179
|
+
_raw_response: Object.assign({ campaign: null, designation: {}, donor: {}, form_data: {}, id: null, schedule: {}, transaction: {} }, response),
|
|
180
|
+
}));
|
|
181
|
+
}
|
|
182
|
+
else {
|
|
183
|
+
}
|
|
184
|
+
afterEachCheck === null || afterEachCheck === void 0 ? void 0 : afterEachCheck();
|
|
185
|
+
})
|
|
186
|
+
.catch((e) => {
|
|
187
|
+
if (pollHandle) {
|
|
188
|
+
clearInterval(pollHandle);
|
|
189
|
+
pollHandle = null;
|
|
190
|
+
}
|
|
191
|
+
reject(e);
|
|
192
|
+
});
|
|
193
|
+
}, 2000);
|
|
194
|
+
}, 2000);
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
tokenizeCardConnectApplePay(applePayRequest) {
|
|
198
|
+
const applePay = new ApplePay(applePayRequest);
|
|
199
|
+
let merchantSessionId = '';
|
|
200
|
+
const promiseStart = applePay.begin();
|
|
201
|
+
return new Promise((resolve, reject) => {
|
|
202
|
+
promiseStart
|
|
203
|
+
.then((session) => {
|
|
204
|
+
session.onvalidatemerchant = (event) => {
|
|
205
|
+
const validationPayload = {
|
|
206
|
+
apple_pay_url: this.config.applePayUrl,
|
|
207
|
+
organization_id: this.organizationId,
|
|
208
|
+
};
|
|
209
|
+
applePay
|
|
210
|
+
.createSession(validationPayload, this.config.embedApiBaseUrl)
|
|
211
|
+
.then((merchantSession) => {
|
|
212
|
+
merchantSessionId =
|
|
213
|
+
merchantSession.result.merchantSessionIdentifier;
|
|
214
|
+
session.completeMerchantValidation(merchantSession.result);
|
|
215
|
+
})
|
|
216
|
+
.catch((err) => {
|
|
217
|
+
session.abort();
|
|
218
|
+
reject(err);
|
|
219
|
+
});
|
|
220
|
+
};
|
|
221
|
+
session.onpaymentauthorized = (event) => {
|
|
222
|
+
applePay
|
|
223
|
+
.tokenizeWithCardConnect(event.payment, this.config.cardConnectBaseUrl)
|
|
224
|
+
.then((data) => {
|
|
225
|
+
var _a, _b;
|
|
226
|
+
const unifiedContact = Object.assign(Object.assign({}, event.payment.billingContact), { email: (_a = event.payment.shippingContact) === null || _a === void 0 ? void 0 : _a.emailAddress, phone: (_b = event.payment.shippingContact) === null || _b === void 0 ? void 0 : _b.phoneNumber });
|
|
227
|
+
const result = {
|
|
228
|
+
applePaySession: session,
|
|
229
|
+
cardConnectResponse: data,
|
|
230
|
+
billingContact: unifiedContact,
|
|
231
|
+
merchantSessionId,
|
|
232
|
+
};
|
|
233
|
+
resolve(result);
|
|
234
|
+
})
|
|
235
|
+
.catch((err) => {
|
|
236
|
+
session.abort();
|
|
237
|
+
reject(err);
|
|
238
|
+
});
|
|
239
|
+
};
|
|
240
|
+
session.oncancel = (event) => {
|
|
241
|
+
reject(new Error('Apple Pay has been closed'));
|
|
242
|
+
};
|
|
243
|
+
})
|
|
244
|
+
.catch((err) => reject(err));
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
createTokenizer(gateway, container) {
|
|
248
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
249
|
+
return Tokenizer.create(gateway, container, {
|
|
250
|
+
organizationId: this.organizationId,
|
|
251
|
+
embedId: this.embedId,
|
|
252
|
+
clientConfig: this.config,
|
|
253
|
+
});
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
tokenizeSpreedlyPayPal(data) {
|
|
257
|
+
return SpreedlyTokenizer.tokenizePayPal(data, this.config);
|
|
258
|
+
}
|
|
259
|
+
selectGateway(availableGateways, paymentType, preferredGatewayId) {
|
|
260
|
+
if (preferredGatewayId) {
|
|
261
|
+
const preferred = availableGateways.find((g) => g.id === preferredGatewayId);
|
|
262
|
+
if (preferred)
|
|
263
|
+
return preferred;
|
|
264
|
+
}
|
|
265
|
+
return availableGateways[0];
|
|
266
|
+
}
|
|
267
|
+
getEmbedConfig() {
|
|
268
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
269
|
+
if (this.embedConfigCache) {
|
|
270
|
+
return this.embedConfigCache;
|
|
271
|
+
}
|
|
272
|
+
if (this.embedConfigPromise) {
|
|
273
|
+
return this.embedConfigPromise;
|
|
274
|
+
}
|
|
275
|
+
this.embedConfigPromise = shared
|
|
276
|
+
.fetchEmbedConfig(this.embedId, this.config)
|
|
277
|
+
.then((config) => {
|
|
278
|
+
this.embedConfigCache = config;
|
|
279
|
+
return config;
|
|
280
|
+
});
|
|
281
|
+
return this.embedConfigPromise;
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
getGateway(gatewayId) {
|
|
285
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
286
|
+
const config = yield this.getEmbedConfig();
|
|
287
|
+
const gateway = config.available_gateways.find((g) => g.id === gatewayId);
|
|
288
|
+
if (!gateway) {
|
|
289
|
+
throw new Error(`Gateway ${gatewayId} not found in embed configuration. Available: ${config.available_gateways.map((g) => g.id).join(', ')}`);
|
|
290
|
+
}
|
|
291
|
+
return gateway;
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import * as tokenize from './tokenize';
|
|
2
|
+
import * as util from './util';
|
|
3
|
+
import * as recaptcha from './recaptcha';
|
|
4
|
+
import * as constants from './constants';
|
|
5
|
+
import * as shared from './shared';
|
|
6
|
+
import iDonateClient from './idonate-client';
|
|
7
|
+
import ConfigHandler from './config-handler';
|
|
8
|
+
import ApplePay from './apple-pay';
|
|
9
|
+
import GooglePay from './google-pay';
|
|
10
|
+
export * from './types';
|
|
11
|
+
export { tokenize, util, shared, iDonateClient as Client, ConfigHandler, recaptcha, constants, ApplePay, GooglePay, };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import * as tokenize from './tokenize';
|
|
2
|
+
import * as util from './util';
|
|
3
|
+
import * as recaptcha from './recaptcha';
|
|
4
|
+
import * as constants from './constants';
|
|
5
|
+
import * as shared from './shared';
|
|
6
|
+
import iDonateClient from './idonate-client';
|
|
7
|
+
import ConfigHandler from './config-handler';
|
|
8
|
+
import ApplePay from './apple-pay';
|
|
9
|
+
import GooglePay from './google-pay';
|
|
10
|
+
export * from './types';
|
|
11
|
+
export { tokenize, util, shared, iDonateClient as Client, ConfigHandler, recaptcha, constants, ApplePay, GooglePay, };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare function injectScript(callback?: () => void): void;
|
|
2
|
+
export declare class RecaptchaElement {
|
|
3
|
+
private readonly container;
|
|
4
|
+
private readonly params;
|
|
5
|
+
private widgetId;
|
|
6
|
+
private executeResolveQueue;
|
|
7
|
+
private resolvedToken;
|
|
8
|
+
constructor(container: string, params: ReCaptchaV2.Parameters);
|
|
9
|
+
render(): Promise<void>;
|
|
10
|
+
resolveToken(): Promise<string>;
|
|
11
|
+
}
|
|
12
|
+
export declare function wrapElement(container: string, sitekey: string, extraParams?: any): RecaptchaElement;
|