@agent-cards/sdk 0.23.13 → 0.23.15
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/CHANGELOG.md +39 -0
- package/PREFLIGHT.md +3 -1
- package/README.md +54 -13
- package/dist/adyen-merchant-hosted.generated.js +2 -2
- package/dist/amadeus.d.ts +5 -2
- package/dist/amadeus.js +17 -3
- package/dist/card-fields.generated.js +924 -3
- package/dist/cdp.js +83 -19
- package/dist/client.d.ts +97 -1
- package/dist/client.js +235 -16
- package/dist/creditguard.generated.d.ts +100 -2
- package/dist/creditguard.generated.js +333 -3
- package/dist/datatrans.generated.d.ts +19 -4
- package/dist/datatrans.generated.js +15 -3
- package/dist/ebanx.d.ts +107 -0
- package/dist/ebanx.generated.d.ts +78 -0
- package/dist/ebanx.generated.js +577 -0
- package/dist/ebanx.js +159 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -0
- package/dist/lifecycle.d.ts +32 -5
- package/dist/lifecycle.js +40 -5
- package/dist/paddle-tokenex.d.ts +56 -0
- package/dist/paddle-tokenex.generated.d.ts +67 -0
- package/dist/paddle-tokenex.generated.js +951 -0
- package/dist/paddle-tokenex.js +95 -0
- package/dist/paypal-card-forms.d.ts +73 -0
- package/dist/paypal-card-forms.js +126 -0
- package/dist/pre-claim.d.ts +39 -1
- package/dist/pre-claim.js +348 -18
- package/dist/preparation.d.ts +13 -0
- package/dist/preparation.js +22 -0
- package/dist/prepared-processor.d.ts +5 -1
- package/dist/prepared-processor.js +17 -2
- package/dist/primer.generated.js +960 -39
- package/dist/redsys.d.ts +42 -0
- package/dist/redsys.js +68 -0
- package/dist/stripe-checkout.generated.js +494 -9
- package/dist/wix-payments.generated.d.ts +42 -0
- package/dist/wix-payments.generated.js +241 -0
- package/package.json +8 -5
package/dist/client.js
CHANGED
|
@@ -15,6 +15,8 @@ import { CONVERGE_CAPABILITY } from './elavon-converge.js';
|
|
|
15
15
|
import { SHIJI_STS_CAPABILITY, SHIJI_STS_PSP, isShijiStsServedCompanion, isShijiStsServedSubstitution } from './shiji-sts.js';
|
|
16
16
|
import { AMADEUS_CHECKOUT_CAPABILITY, AMADEUS_CHECKOUT_PSP } from './amadeus-checkout.generated.js';
|
|
17
17
|
import { PADDLE_VGS_CAPABILITY, PADDLE_VGS_PSP, paddleVgsCardFactsOf } from './paddle-vgs.generated.js';
|
|
18
|
+
import { PADDLE_TOKENEX_CAPABILITY, PADDLE_TOKENEX_PSP, isPaddleTokenexServedFacts, isPaddleTokenexServedSubstitution } from './paddle-tokenex.js';
|
|
19
|
+
import { WIX_PAYMENTS_CAPABILITY, WIX_PAYMENTS_PSP } from './wix-payments.generated.js';
|
|
18
20
|
import { classifyStripeCheckoutRequest, encodeStripeCheckoutContext, hasStripeCheckoutMarker, parseStripeCheckoutContext, parseStripeCheckoutResponse, STRIPE_CHECKOUT_CONTEXT_HEADER, } from './stripe-checkout.generated.js';
|
|
19
21
|
import { VoiceModule } from './voice.js';
|
|
20
22
|
import { BuyModule } from './buy.js';
|
|
@@ -32,6 +34,7 @@ import { PELECARD_CAPABILITY, PELECARD_PSP } from './pelecard.js';
|
|
|
32
34
|
import { PRIMER_CAPABILITY, PRIMER_PSP, primerTokenAnswer } from './primer.js';
|
|
33
35
|
import { PAYRAILS_CAPABILITY, isPayrailsPaymentUrl, payrailsAnswer } from './payrails.js';
|
|
34
36
|
import { WSPAY_CAPABILITY, WSPAY_PSP } from './wspay.js';
|
|
37
|
+
import { EbanxFollowUpError } from './ebanx.js';
|
|
35
38
|
import { SECURE_ACCEPTANCE_CAPABILITY, SECURE_ACCEPTANCE_FAST_POLL_MS, SECURE_ACCEPTANCE_PSP, SECURE_ACCEPTANCE_REPLY_WINDOW_MS, secureAcceptanceCheckoutProfile, secureAcceptanceCheckoutRefusal, secureAcceptanceFrameAnswer, } from './cybersource-secure-acceptance.js';
|
|
36
39
|
/**
|
|
37
40
|
* The modes this SDK can finish. Asked for on syncRegistry (the API serves
|
|
@@ -187,6 +190,11 @@ export const SUPPORTED_REGISTRY_FEATURES = ['card_fields', 'checkout_sessions'];
|
|
|
187
190
|
* Moneris on for. A gated recognizer never sits in BUILTIN_REGISTRY, so it is paused
|
|
188
191
|
* only after a sync.
|
|
189
192
|
*
|
|
193
|
+
* `redsys_hosted_payment_page`: Redsys's hosted payment page (the TPV Virtual redirect), whose
|
|
194
|
+
* card-free signed entry this build pauses for the cardholder's device and whose card page this build
|
|
195
|
+
* never lets the agent's browser post to (pre-claim.ts, redsys.ts). Served on the same terms as NMI's: only
|
|
196
|
+
* to a build that lists it, for a company Agentcard turned Redsys on for.
|
|
197
|
+
*
|
|
190
198
|
* `paddle_vgs_cards`: the card request Paddle's checkout frame sends to its VGS card
|
|
191
199
|
* vault (vault.paddle.com/cards) on a checkout that names VGS, only through a prepared
|
|
192
200
|
* checkout: the frame aborts the request 10 seconds after Pay and sends it once more,
|
|
@@ -194,8 +202,40 @@ export const SUPPORTED_REGISTRY_FEATURES = ['card_fields', 'checkout_sessions'];
|
|
|
194
202
|
* device sends the card itself and the frame gets back the stored card's id alone.
|
|
195
203
|
* Served on the same terms: only to a build that lists it, for a company Agentcard
|
|
196
204
|
* turned Paddle on for.
|
|
205
|
+
*
|
|
206
|
+
* `paddle_tokenex_pay`: the /pay Paddle's checkout frame sends to its checkout service
|
|
207
|
+
* (checkout-service.paddle.com) on a checkout that names TokenEx. The frame encrypts the
|
|
208
|
+
* card in the page under the account's TokenEx key, so /pay carries the placeholder's two
|
|
209
|
+
* ciphertexts and facts; this build pauses it and writes over them the device's own, under
|
|
210
|
+
* the key payment-core pins (paddle-tokenex.ts). Served on the same terms: only to a build
|
|
211
|
+
* that lists it, for a company Agentcard turned Paddle on for.
|
|
212
|
+
*
|
|
213
|
+
* `lyra_krypton_payment`: the card payment Lyra's Krypton form (PayZen, Systempay,
|
|
214
|
+
* Sogecommerce) sends from its hidden checkout frame to ProcessPayment/2 on the brand's API
|
|
215
|
+
* host. This build pauses only the frame's card body under a form token that pays once; the
|
|
216
|
+
* cardholder's device sends the card through the checkout relay, and the frame gets Lyra's
|
|
217
|
+
* answer byte for byte with Lyra's payment id, so it runs any 3-D Secure step itself and its
|
|
218
|
+
* card-free follow-up passes untouched. Served on the same terms: only to a build that lists
|
|
219
|
+
* it, for a company Agentcard turned Lyra on for.
|
|
220
|
+
*
|
|
221
|
+
* `payfast_card_pay`: the card tab's pay on Payfast's hosted payment page (POST
|
|
222
|
+
* /eng/method/CreditCard/<uuid>/pay on payment.payfast.io, www.payfast.co.za or the sandbox),
|
|
223
|
+
* which this build pauses only as the card tab's own form body and answers with Payfast's own
|
|
224
|
+
* answer as the API recorded it: `[true]` once the payment is done, or the 3-D Secure step the
|
|
225
|
+
* card tab then runs in the agent's browser. The cardholder's device sends the card through the
|
|
226
|
+
* checkout relay. Served on the same terms: only to a build that lists it, for a company
|
|
227
|
+
* Agentcard turned Payfast on for.
|
|
228
|
+
*
|
|
229
|
+
* `wix_payments_tokenize`: the card request Wix Cashier's card frame sends to Wix's
|
|
230
|
+
* tokenizer (cashier-pci.wixapps.net), only through a prepared checkout: Wix's payment
|
|
231
|
+
* widget fails the payment 30 seconds after it asks the frame for a token. The
|
|
232
|
+
* cardholder's device sends the card through the checkout relay and the frame gets back
|
|
233
|
+
* Wix's token. A second card request from the frame, which Wix's frame sends after a 401
|
|
234
|
+
* or 403 under a fresh instance, is never answered from the same approval. Served on the
|
|
235
|
+
* same terms: only to a build that lists it, for a company Agentcard turned Wix on for.
|
|
197
236
|
*/
|
|
198
|
-
export const SUPPORTED_CAPABILITIES = ['fiserv_card_capture', GMO_CAPABILITY, CYBERSOURCE_FLEX_CAPABILITY, JUSPAY_CAPABILITY, DATATRANS_CAPABILITY, 'authorize_net_dpm_form', PELECARD_CAPABILITY, ACI_CAPABILITY, 'creditguard_pps_process', PRIMER_CAPABILITY, PAYRAILS_CAPABILITY, CONVERGE_CAPABILITY, EPROTECT_CAPABILITY, WSPAY_CAPABILITY, SHIJI_STS_CAPABILITY, AMADEUS_CHECKOUT_CAPABILITY, 'worldline_mycheckout_form', 'verifone_card_capture', 'ekashu_hosted_payment_page', SECURE_ACCEPTANCE_CAPABILITY, 'gravy_session_fields_put', 'moneris_hosted_tokenization', PADDLE_VGS_CAPABILITY
|
|
237
|
+
export const SUPPORTED_CAPABILITIES = ['fiserv_card_capture', GMO_CAPABILITY, CYBERSOURCE_FLEX_CAPABILITY, JUSPAY_CAPABILITY, DATATRANS_CAPABILITY, 'authorize_net_dpm_form', PELECARD_CAPABILITY, ACI_CAPABILITY, 'creditguard_pps_process', PRIMER_CAPABILITY, PAYRAILS_CAPABILITY, CONVERGE_CAPABILITY, EPROTECT_CAPABILITY, WSPAY_CAPABILITY, SHIJI_STS_CAPABILITY, AMADEUS_CHECKOUT_CAPABILITY, 'worldline_mycheckout_form', 'verifone_card_capture', 'ekashu_hosted_payment_page', SECURE_ACCEPTANCE_CAPABILITY, 'gravy_session_fields_put', 'moneris_hosted_tokenization', PADDLE_VGS_CAPABILITY, PADDLE_TOKENEX_CAPABILITY,
|
|
238
|
+
'redsys_hosted_payment_page', 'lyra_krypton_payment', 'payfast_card_pay', WIX_PAYMENTS_CAPABILITY];
|
|
199
239
|
/**
|
|
200
240
|
* Processors whose paused request names no amount at all, so the pair the
|
|
201
241
|
* agent passes is the amount the cardholder approves: authorize() refuses one
|
|
@@ -218,13 +258,19 @@ export const SUPPORTED_CAPABILITIES = ['fiserv_card_capture', GMO_CAPABILITY, CY
|
|
|
218
258
|
* token later, so the agent's pair, above zero (MONERIS_PSP below), is the one
|
|
219
259
|
* figure the approval shows. Paddle VGS's card request carries none either: Paddle
|
|
220
260
|
* charges the stored card at /pay for what the checkout says, so the agent's pair,
|
|
221
|
-
* which the prepared checkout carries, is the total the cardholder approves.
|
|
261
|
+
* which the prepared checkout carries, is the total the cardholder approves. Payfast's
|
|
262
|
+
* card pay carries none either: the merchant's entry bound the total to the payment,
|
|
263
|
+
* so the agent sends the total Payfast's page shows, above zero (PAYFAST_PSP below),
|
|
264
|
+
* and the API holds it to the payment Payfast itself reports. Wix's tokenize request
|
|
265
|
+
* carries none either: the merchant's page charges Wix's token for its own order, so the
|
|
266
|
+
* agent's pair, which the prepared checkout carries, is the total the cardholder approves.
|
|
222
267
|
*/
|
|
223
268
|
const MONERIS_PSP = 'moneris';
|
|
224
|
-
const
|
|
269
|
+
const PAYFAST_PSP = 'payfast';
|
|
270
|
+
const AGENT_AMOUNT_PROCESSORS = [GMO_PSP, PELECARD_PSP, WSPAY_PSP, SECURE_ACCEPTANCE_PSP, MONERIS_PSP, PADDLE_VGS_PSP, PAYFAST_PSP, WIX_PAYMENTS_PSP];
|
|
225
271
|
/** How AmountRequiredError names a processor. */
|
|
226
272
|
const PROCESSOR_NAMES = { [GMO_PSP]: 'GMO', [PELECARD_PSP]: 'Pelecard', [WSPAY_PSP]: 'WSPay',
|
|
227
|
-
[SECURE_ACCEPTANCE_PSP]: 'CyberSource Secure Acceptance', [MONERIS_PSP]: 'Moneris', [PADDLE_VGS_PSP]: 'Paddle' };
|
|
273
|
+
[SECURE_ACCEPTANCE_PSP]: 'CyberSource Secure Acceptance', [MONERIS_PSP]: 'Moneris', [PADDLE_VGS_PSP]: 'Paddle', [PAYFAST_PSP]: 'Payfast', [WIX_PAYMENTS_PSP]: 'Wix' };
|
|
228
274
|
/**
|
|
229
275
|
* Processors whose request and answer name no amount at all, so the total the
|
|
230
276
|
* payment page shows (`pageAmount`) is the one figure that ties the agent's pair
|
|
@@ -840,6 +886,14 @@ function refusalsOf(v) {
|
|
|
840
886
|
}
|
|
841
887
|
return out;
|
|
842
888
|
}
|
|
889
|
+
/**
|
|
890
|
+
* How often sendEbanxFollowUp reads a send back while the cardholder's device has it: every half second, whatever the
|
|
891
|
+
* client's own `pollIntervalMs`. One send is out at a time per approval, so this is 120 reads a minute, inside the
|
|
892
|
+
* API's 240 a minute per caller and authorization (routes/api/v2/checkout-follow-ups.ts).
|
|
893
|
+
*/
|
|
894
|
+
export const EBANX_FOLLOW_UP_READ_MS = 500;
|
|
895
|
+
/** The longest sendEbanxFollowUp waits after reads the API refused as too many (429): 1, 2, 4, 8, then 15 seconds. */
|
|
896
|
+
export const EBANX_FOLLOW_UP_BACKOFF_MAX_MS = 15_000;
|
|
843
897
|
export class CheckoutApiError extends Error {
|
|
844
898
|
status;
|
|
845
899
|
path;
|
|
@@ -1012,18 +1066,81 @@ const ACI_CHECKOUT_ID = /[0-9a-f]{32}\.[a-z0-9]{1,16}-vm-tx[0-9]{1,3}/gi;
|
|
|
1012
1066
|
function maskAciCheckout(path) {
|
|
1013
1067
|
return path.replace(ACI_CHECKOUT, '$1{checkoutId}').replace(ACI_CHECKOUT_ID, '{checkoutId}');
|
|
1014
1068
|
}
|
|
1069
|
+
/**
|
|
1070
|
+
* Payfast's hosted payment page sends the card to /eng/method/CreditCard/<uuid>/pay on its own host
|
|
1071
|
+
* with no auth header and no CSRF token (payment-core payfast.js): the payment's uuid is the
|
|
1072
|
+
* request's only credential, and with it anyone can read that payment page, its amount and its
|
|
1073
|
+
* merchant. Every route of the page carries the same uuid, so on every host Payfast owns (payfast.io and
|
|
1074
|
+
* payfast.co.za and any name under them) any id of its shape, in any case or after an escaped slash,
|
|
1075
|
+
* reads {uuid}.
|
|
1076
|
+
*/
|
|
1077
|
+
const PAYFAST_HOST = /(?:^|\.)payfast\.(?:io|co\.za)\.?$/i;
|
|
1078
|
+
const PAYFAST_UUID = /[0-9a-f]{8}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{12}/gi;
|
|
1079
|
+
function maskPayfastUuid(path) {
|
|
1080
|
+
return path.replace(PAYFAST_UUID, '{uuid}');
|
|
1081
|
+
}
|
|
1082
|
+
/**
|
|
1083
|
+
* Paddle's checkout frame pays a TokenEx checkout with its own /pay on checkout-service.paddle.com
|
|
1084
|
+
* (sandbox-checkout-service in test), and the checkout id in that path is the checkout's only
|
|
1085
|
+
* credential there, no cookies (payment-core paddle-tokenex.js): with it, and the card in the body,
|
|
1086
|
+
* a payment reaches that checkout. On those hosts the segment between /checkout/ or
|
|
1087
|
+
* /transaction-checkout/ and /pay, in any case or after an escaped slash, reads {checkout}.
|
|
1088
|
+
*/
|
|
1089
|
+
const PADDLE_CHECKOUT_HOST = /^(?:sandbox-)?checkout-service\.paddle\.com\.?$/i;
|
|
1090
|
+
const PADDLE_PAY = /(\/(?:checkout|transaction-checkout)(?:\/|%2f))[^/]*(\/pay)/gi;
|
|
1091
|
+
function maskPaddleCheckout(path) {
|
|
1092
|
+
return path.replace(PADDLE_PAY, '$1{checkout}$2');
|
|
1093
|
+
}
|
|
1094
|
+
/**
|
|
1095
|
+
* Lyra's Krypton frame sends its payment to ProcessPayment/2 on the brand's API host with the form
|
|
1096
|
+
* token's session id as a `;jsessionid=` path parameter (payment-core lyra.js). With the form token the
|
|
1097
|
+
* body carries, that id continues the payment on Lyra's side, so on Lyra's hosts it reads `{session}`,
|
|
1098
|
+
* in any case: https://api.systempay.fr/api-payment/V4/Charge/Public/ProcessPayment/2;jsessionid={session}.
|
|
1099
|
+
*/
|
|
1100
|
+
const LYRA_HOST = /^(?:api\.payzen\.eu|api\.systempay\.fr|api-sogecommerce\.societegenerale\.eu|api\.lyra\.com)\.?$/i;
|
|
1101
|
+
const LYRA_SESSION = /;jsessionid=[^/;?#]*/gi;
|
|
1102
|
+
function maskLyraSession(path) {
|
|
1103
|
+
return path.replace(LYRA_SESSION, ';jsessionid={session}');
|
|
1104
|
+
}
|
|
1015
1105
|
/**
|
|
1016
1106
|
* The processors whose card request carries its own credential in the URL path, with the hosts
|
|
1017
1107
|
* that send it, the text that names those hosts in a string that is not a URL, and the mask. The
|
|
1018
1108
|
* guard in redact-url.test.mjs fails for a payment-core recognizer that no one has sorted into
|
|
1019
1109
|
* this list or out of it.
|
|
1020
1110
|
*/
|
|
1111
|
+
/**
|
|
1112
|
+
* Redsys's hosted payment page names its session in the path of every page and post after the entry
|
|
1113
|
+
* (/sis/pagoTarjeta;jsessionid=<id>), and that id is what carries a card post into the session the
|
|
1114
|
+
* merchant's signed entry opened. On Redsys's hosts the session id, in any case or escaped, reads
|
|
1115
|
+
* {session}. The entry itself carries none.
|
|
1116
|
+
*/
|
|
1117
|
+
const REDSYS_HOST = /^sis(?:-t)?\.redsys\.es\.?$/i;
|
|
1118
|
+
const REDSYS_SESSION = /((?:;|%3b)jsessionid(?:=|%3d))[^/?#;]*/gi;
|
|
1119
|
+
function maskRedsysSession(path) {
|
|
1120
|
+
return path.replace(REDSYS_SESSION, '$1{session}');
|
|
1121
|
+
}
|
|
1122
|
+
/**
|
|
1123
|
+
* A PayPal order id opens PayPal's own checkout page for that order (/checkoutnow?token=<order id>) to
|
|
1124
|
+
* anyone who holds it, and PayPal's card confirms carry it in the path:
|
|
1125
|
+
* /v2/checkout/orders/<order id>/confirm-payment-source on www, api-m and cors.api. On PayPal's hosts the
|
|
1126
|
+
* segment after /orders/, in any case or after an escaped slash, reads {order}.
|
|
1127
|
+
*/
|
|
1128
|
+
const PAYPAL_HOST = /(?:^|\.)paypal\.com\.?$/i;
|
|
1129
|
+
const PAYPAL_ORDER = /(\/orders(?:\/|%2f))[^/]*/gi;
|
|
1130
|
+
function maskPaypalOrder(path) {
|
|
1131
|
+
return path.replace(PAYPAL_ORDER, '$1{order}');
|
|
1132
|
+
}
|
|
1021
1133
|
const PATH_CREDENTIALS = [
|
|
1022
1134
|
{ host: CREDITGUARD_HOST, named: /creditguard\.co\.il/i, mask: maskCreditguardTxId },
|
|
1023
1135
|
{ host: GRAVY_HOST, named: /gr4vy\.app/i, mask: maskGravySession },
|
|
1024
1136
|
{ host: RAPYD_HOST, named: /rapyd\.net/i, mask: maskRapydToken },
|
|
1025
1137
|
{ host: STRIPE_API_HOST, named: /api\.stripe\.com/i, mask: maskStripeSession },
|
|
1026
1138
|
{ host: ACI_HOST, named: /oppwa\.com/i, mask: maskAciCheckout },
|
|
1139
|
+
{ host: PAYFAST_HOST, named: /payfast\.(?:io|co\.za)/i, mask: maskPayfastUuid },
|
|
1140
|
+
{ host: PADDLE_CHECKOUT_HOST, named: /checkout-service\.paddle\.com/i, mask: maskPaddleCheckout },
|
|
1141
|
+
{ host: REDSYS_HOST, named: /redsys\.es/i, mask: maskRedsysSession },
|
|
1142
|
+
{ host: LYRA_HOST, named: /(?:payzen\.eu|systempay\.fr|societegenerale\.eu|lyra\.com)/i, mask: maskLyraSession },
|
|
1143
|
+
{ host: PAYPAL_HOST, named: /paypal\.com/i, mask: maskPaypalOrder },
|
|
1027
1144
|
];
|
|
1028
1145
|
/**
|
|
1029
1146
|
* A URL as it may appear in an error message: origin + path only. A paused
|
|
@@ -1039,6 +1156,13 @@ const PATH_CREDENTIALS = [
|
|
|
1039
1156
|
* On Rapyd's hosts the hosted page's id reads `{token}`: https://api.rapyd.net/v1/checkout/{token}.
|
|
1040
1157
|
* On api.stripe.com a Checkout Session id reads `{session}`:
|
|
1041
1158
|
* https://api.stripe.com/v1/payment_pages/{session}/confirm.
|
|
1159
|
+
* On Payfast's hosts the payment's uuid reads `{uuid}`:
|
|
1160
|
+
* https://payment.payfast.io/eng/method/CreditCard/{uuid}/pay.
|
|
1161
|
+
* On Redsys's hosts the session id after `;jsessionid=` reads `{session}`:
|
|
1162
|
+
* https://sis.redsys.es/sis/pagoTarjeta;jsessionid={session}.
|
|
1163
|
+
* On Lyra's API hosts the form token's session id reads `{session}`.
|
|
1164
|
+
* On PayPal's hosts an order id reads `{order}`:
|
|
1165
|
+
* https://www.paypal.com/v2/checkout/orders/{order}/confirm-payment-source.
|
|
1042
1166
|
* A string that is not a URL keeps the part before any `?` or `#`, with the
|
|
1043
1167
|
* same segments masked.
|
|
1044
1168
|
*/
|
|
@@ -1127,17 +1251,26 @@ const SECURE_ACCEPTANCE_PREPARATION_REFUSALS = [
|
|
|
1127
1251
|
const PADDLE_VGS_PREPARATION_REFUSALS = [
|
|
1128
1252
|
'processor_unavailable', 'sandbox_host_on_live_row', 'live_host_on_sandbox_row', 'merchant_profile_mismatch', 'paddle_vgs_card_unsupported',
|
|
1129
1253
|
];
|
|
1254
|
+
/**
|
|
1255
|
+
* The API's refusals of a Wix Payments preparation, before any preparation exists, that prepareCheckout
|
|
1256
|
+
* surfaces by name: the lane is held to Agentcard's own account (`processor_unavailable`), a test client
|
|
1257
|
+
* asked for it (`live_host_on_sandbox_row`: Wix has no test environment), and a checkout's merchant is not
|
|
1258
|
+
* the name the reviewed store pin carries (`merchant_profile_mismatch`). An unreviewed store answers
|
|
1259
|
+
* `unsupported_checkout`, which PREPARATION_REFUSALS names for every checkout. Only for a Wix checkout.
|
|
1260
|
+
*/
|
|
1261
|
+
const WIX_PAYMENTS_PREPARATION_REFUSALS = ['processor_unavailable', 'live_host_on_sandbox_row', 'merchant_profile_mismatch'];
|
|
1130
1262
|
/**
|
|
1131
1263
|
* The reason the cardholder's device declines a bound prepared row with, per processor, when its own
|
|
1132
1264
|
* send boundary passed before the card left it (the Vault's sendWindow, 12 seconds after it last saw
|
|
1133
|
-
* the checkout unbound): a prepared Amadeus SDK add
|
|
1134
|
-
* names the same known non-payment the adapters' own send window
|
|
1135
|
-
* close later, so authorize() ends the attempt the way that window
|
|
1136
|
-
* with that reason, and never as the cardholder's "no".
|
|
1265
|
+
* the checkout unbound): a prepared Amadeus SDK add, a prepared Secure Acceptance token create and a
|
|
1266
|
+
* prepared Wix tokenize request. It names the same known non-payment the adapters' own send window
|
|
1267
|
+
* closes on (amadeus.ts), which can close later, so authorize() ends the attempt the way that window
|
|
1268
|
+
* does, as a CheckoutPreparationError with that reason, and never as the cardholder's "no".
|
|
1137
1269
|
*/
|
|
1138
1270
|
const PREPARED_SEND_WINDOW_DECLINES = Object.freeze({
|
|
1139
1271
|
amadeus_checkout: 'amadeus_send_window_closed',
|
|
1140
1272
|
[SECURE_ACCEPTANCE_PSP]: 'secure_acceptance_send_window_closed',
|
|
1273
|
+
[WIX_PAYMENTS_PSP]: 'wix_payments_send_window_closed',
|
|
1141
1274
|
});
|
|
1142
1275
|
/**
|
|
1143
1276
|
* Refusals a CyberSource Flex preparation that tokenizes before Pay answers (4xx) before any
|
|
@@ -1341,7 +1474,7 @@ export class VaultClient {
|
|
|
1341
1474
|
// wspay_confirm, shiji_sts_pinned_key, amadeus_checkout_actions.v1,
|
|
1342
1475
|
// worldline_mycheckout_form, verifone_card_capture, ekashu_hosted_payment_page,
|
|
1343
1476
|
// cybersource_sa_token_create, gravy_session_fields_put,
|
|
1344
|
-
// moneris_hosted_tokenization) and
|
|
1477
|
+
// moneris_hosted_tokenization, paddle_vgs_cards, redsys_hosted_payment_page) and
|
|
1345
1478
|
// the caller's company is one Agentcard turned that processor on for, so this
|
|
1346
1479
|
// build arms Fiserv's card capture, GMO's getToken, CyberSource Flex's card
|
|
1347
1480
|
// fields, Juspay's card flow, Datatrans's Secure Fields card post, the
|
|
@@ -1720,7 +1853,10 @@ export class VaultClient {
|
|
|
1720
1853
|
...(fiservPin ? { merchant_profile: fiservPin.id } : {}),
|
|
1721
1854
|
...(verifone ? { merchant_profile: verifone.id } : {}),
|
|
1722
1855
|
...(declaration ? { sandbox_declaration: { endpoint: declaration.endpoint, client_key: declaration.clientKey, environment: 'test' } } : {}),
|
|
1723
|
-
|
|
1856
|
+
// CreditGuard: this build answers the hosted page's own 3-D Secure calls (pre-claim.ts), so the
|
|
1857
|
+
// cardholder's device can run 3-D Secure before the submit; the API admits such a transaction
|
|
1858
|
+
// only for a build that says so.
|
|
1859
|
+
...(input.psp === 'creditguard' ? { payment_page_url: input.paymentPageUrl, three_d_secure: 'device' } : {}),
|
|
1724
1860
|
...(eprotect ? { paypage_id: input.paypageId } : {}),
|
|
1725
1861
|
...(secureAcceptance ? { secure_acceptance_profile_id: secureAcceptanceProfileId } : {}),
|
|
1726
1862
|
...(flexContext ? { capture_context: flexContext.captureContext,
|
|
@@ -1816,6 +1952,7 @@ export class VaultClient {
|
|
|
1816
1952
|
|| (input.psp === 'fiserv' && FISERV_PREPARATION_REFUSALS.includes(error.code))
|
|
1817
1953
|
|| (input.psp === EPROTECT_PSP && EPROTECT_PREPARATION_REFUSALS.includes(error.code))
|
|
1818
1954
|
|| (input.psp === PADDLE_VGS_PSP && PADDLE_VGS_PREPARATION_REFUSALS.includes(error.code))
|
|
1955
|
+
|| (input.psp === WIX_PAYMENTS_PSP && WIX_PAYMENTS_PREPARATION_REFUSALS.includes(error.code))
|
|
1819
1956
|
|| (!!flexContext && CYBERSOURCE_FLEX_PREPARATION_REFUSALS.includes(error.code))))
|
|
1820
1957
|
|| (input.psp === 'fiserv' && error.status === 502 && error.code === 'cse_key_unavailable')))
|
|
1821
1958
|
throw fail(error.code);
|
|
@@ -2099,9 +2236,10 @@ export class VaultClient {
|
|
|
2099
2236
|
// amount_required.
|
|
2100
2237
|
if (!hasAmount && rec && AGENT_AMOUNT_PROCESSORS.includes(rec.psp))
|
|
2101
2238
|
throw new AmountRequiredError(rec.psp);
|
|
2102
|
-
// A Moneris token is charged later for whatever the merchant's server decides,
|
|
2103
|
-
//
|
|
2104
|
-
|
|
2239
|
+
// A Moneris token is charged later for whatever the merchant's server decides, and a Payfast pay
|
|
2240
|
+
// charges the total its payment already holds, so a zero pair would show the cardholder no price
|
|
2241
|
+
// at all: it is refused like a missing one.
|
|
2242
|
+
if (hasAmount && rec && (rec.psp === MONERIS_PSP || rec.psp === PAYFAST_PSP) && Number(input.amount) <= 0)
|
|
2105
2243
|
throw new AmountRequiredError(rec.psp);
|
|
2106
2244
|
// Nor is the agent's pair tied to the page by anything but the total the
|
|
2107
2245
|
// page shows: without it the cardholder could approve one figure while the
|
|
@@ -2420,10 +2558,14 @@ export class VaultClient {
|
|
|
2420
2558
|
// the page's reviewed getCvvId keys (no keys, no continuation);
|
|
2421
2559
|
// every other processor names a holder path, as before.
|
|
2422
2560
|
const shiji = rec?.psp === SHIJI_STS_PSP;
|
|
2561
|
+
// Paddle TokenEx carries the two ciphertexts at tokenex_card and the five facts beside them in
|
|
2562
|
+
// `paddle_tokenex_facts` (the expiry parts are numbers, so they cannot ride `fields`).
|
|
2563
|
+
const paddleTokenex = rec?.psp === PADDLE_TOKENEX_PSP;
|
|
2423
2564
|
const fieldsOk = shiji ? isShijiStsServedSubstitution(sub) && isShijiStsServedCompanion(s.shiji_sts_companion)
|
|
2424
|
-
:
|
|
2425
|
-
&& sub.
|
|
2426
|
-
|
|
2565
|
+
: paddleTokenex ? isPaddleTokenexServedSubstitution(sub) && isPaddleTokenexServedFacts(s.paddle_tokenex_facts)
|
|
2566
|
+
: sub && typeof sub === 'object' && sub.encoding === 'json' && typeof sub.at === 'string' && sub.at
|
|
2567
|
+
&& sub.fields && typeof sub.fields === 'object' && !Array.isArray(sub.fields)
|
|
2568
|
+
&& Object.values(sub.fields).every((v) => typeof v === 'string' && v.length > 0);
|
|
2427
2569
|
if (!fieldsOk)
|
|
2428
2570
|
throw new PaymentOutcomeUnknownError(authorizationId, 'cse_substitutions_malformed');
|
|
2429
2571
|
// A Fiserv approval carries exactly its envelope's four members at
|
|
@@ -2448,6 +2590,7 @@ export class VaultClient {
|
|
|
2448
2590
|
...(removeRaw ? { remove: [...removeRaw] } : {}),
|
|
2449
2591
|
},
|
|
2450
2592
|
...(shiji ? { shijiStsCompanion: Object.freeze({ keySequenceSha256: Object.freeze([...s.shiji_sts_companion.key_sequence_sha256]) }) } : {}),
|
|
2593
|
+
...(paddleTokenex ? { paddleTokenexFacts: Object.freeze({ ...s.paddle_tokenex_facts }) } : {}),
|
|
2451
2594
|
...amountAuthority,
|
|
2452
2595
|
...execution,
|
|
2453
2596
|
};
|
|
@@ -2641,6 +2784,9 @@ export class VaultClient {
|
|
|
2641
2784
|
chargedAmount: typeof s.charged_amount === 'number' ? s.charged_amount : null,
|
|
2642
2785
|
chargedCurrency: typeof s.charged_currency === 'string' ? s.charged_currency : null,
|
|
2643
2786
|
chargedKind: s.charged_kind === 'captured' || s.charged_kind === 'authorized' || s.charged_kind === 'none' ? s.charged_kind : null,
|
|
2787
|
+
// An EBANX token approval that covers the sends after it names until when (ebanx.ts EbanxFollowUps).
|
|
2788
|
+
...(rec?.psp === 'ebanx' && typeof s.follow_ups?.until === 'string' && Number.isFinite(Date.parse(s.follow_ups.until))
|
|
2789
|
+
? { followUpsUntil: s.follow_ups.until } : {}),
|
|
2644
2790
|
...amountAuthority,
|
|
2645
2791
|
...execution,
|
|
2646
2792
|
};
|
|
@@ -2838,6 +2984,79 @@ export class VaultClient {
|
|
|
2838
2984
|
}
|
|
2839
2985
|
return { setupIntentId: confirmed };
|
|
2840
2986
|
}
|
|
2987
|
+
/**
|
|
2988
|
+
* Send one request an approved EBANX token request covers (ebanx.ts says which: EBANX's 3-D Secure calls and the
|
|
2989
|
+
* hosted page's confirm, bound to that approval) from the cardholder's device, and resolve with EBANX's answer for
|
|
2990
|
+
* the paused request: POST /v2/checkout/authorizations/:id/follow_ups with the request as the page sent it, the
|
|
2991
|
+
* agent's placeholder card in it, then the send read back every half second until the device answered
|
|
2992
|
+
* (EBANX_FOLLOW_UP_READ_MS, whatever `pollIntervalMs` says, so the reads stay inside the API's per-approval budget).
|
|
2993
|
+
* A read the API refuses as too many (429) waits longer each time, doubling from a second up to
|
|
2994
|
+
* EBANX_FOLLOW_UP_BACKOFF_MAX_MS, inside the same deadline, and the next answered read goes back to the half second.
|
|
2995
|
+
* No prompt: the cardholder approved the token request, and the Vault page that sent it sends these while it stays
|
|
2996
|
+
* open. Rejects with an EbanxFollowUpError naming why there is no answer and whether the card may have reached
|
|
2997
|
+
* EBANX: the API refused the send (nothing sent), no device started it in time, the device refused it or withheld
|
|
2998
|
+
* an answer that carried the card, or `options.until` (the approval's window, plus the API's own clocks) passed.
|
|
2999
|
+
*/
|
|
3000
|
+
async sendEbanxFollowUp(authorizationId, request, options = {}) {
|
|
3001
|
+
if (!/^cauth_[A-Za-z0-9_-]{1,128}$/.test(authorizationId))
|
|
3002
|
+
throw new Error('Invalid authorization ID.');
|
|
3003
|
+
const base = `/v2/checkout/authorizations/${authorizationId}/follow_ups`;
|
|
3004
|
+
// The API's own clocks: a minute for a device to start a send and a minute for its answer.
|
|
3005
|
+
const deadline = Math.min(Date.now() + 3 * 60_000, (options.until ?? Number.POSITIVE_INFINITY) + 2 * 60_000);
|
|
3006
|
+
const signal = options.signal ? AbortSignal.any([options.signal, AbortSignal.timeout(Math.max(1, deadline - Date.now()))]) : AbortSignal.timeout(Math.max(1, deadline - Date.now()));
|
|
3007
|
+
let created;
|
|
3008
|
+
try {
|
|
3009
|
+
created = await this.post(base, { request: { url: request.url, method: 'POST', headers: pickHeaders(request.headers, []), body: request.body } }, AbortSignal.any([signal, AbortSignal.timeout(15_000)]));
|
|
3010
|
+
}
|
|
3011
|
+
catch (error) {
|
|
3012
|
+
// A refusal (a 4xx answer) stored no send, so nothing left. Any other failure (a 5xx, a timeout, a dropped
|
|
3013
|
+
// connection, an unreadable 201) may have come after the API stored the send, which the device then sends:
|
|
3014
|
+
// the card may reach EBANX, and for a confirm that is a payment whose outcome is unknown.
|
|
3015
|
+
const refused = error instanceof CheckoutApiError && error.status >= 400 && error.status < 500;
|
|
3016
|
+
const reason = error instanceof CheckoutApiError
|
|
3017
|
+
? (typeof error.details.reason === 'string' && /^[a-z_]{1,64}$/.test(error.details.reason) ? error.details.reason : error.code ?? `http_${error.status}`)
|
|
3018
|
+
: 'follow_up_unavailable';
|
|
3019
|
+
throw new EbanxFollowUpError(reason, !refused, authorizationId);
|
|
3020
|
+
}
|
|
3021
|
+
const id = created?.id;
|
|
3022
|
+
if (typeof id !== 'string' || !/^cfu_[0-9a-f]{24}$/.test(id) || created.authorization !== authorizationId) {
|
|
3023
|
+
throw new EbanxFollowUpError('follow_up_unrecognized', true, authorizationId);
|
|
3024
|
+
}
|
|
3025
|
+
// Reads the API refused in a row as too many (429): each waits twice as long as the last before the next read.
|
|
3026
|
+
let limited = 0;
|
|
3027
|
+
for (;;) {
|
|
3028
|
+
let read = null;
|
|
3029
|
+
try {
|
|
3030
|
+
read = await this.get(`${base}/${id}`, AbortSignal.any([signal, AbortSignal.timeout(15_000)]));
|
|
3031
|
+
limited = 0;
|
|
3032
|
+
}
|
|
3033
|
+
catch (error) {
|
|
3034
|
+
if (signal.aborted)
|
|
3035
|
+
throw new EbanxFollowUpError('answer_late', true, authorizationId);
|
|
3036
|
+
if (error instanceof CheckoutApiError && error.status === 429)
|
|
3037
|
+
limited += 1;
|
|
3038
|
+
}
|
|
3039
|
+
if (read?.status === 'answered') {
|
|
3040
|
+
const r = read.response;
|
|
3041
|
+
if (!r || !Number.isInteger(r.status) || r.status < 200 || r.status > 599 || typeof r.body !== 'string' || !r.headers || typeof r.headers !== 'object') {
|
|
3042
|
+
throw new EbanxFollowUpError('follow_up_unrecognized', true, authorizationId);
|
|
3043
|
+
}
|
|
3044
|
+
const headers = {};
|
|
3045
|
+
for (const [name, value] of Object.entries(r.headers))
|
|
3046
|
+
if (name.toLowerCase() === 'content-type' && typeof value === 'string')
|
|
3047
|
+
headers['content-type'] = value;
|
|
3048
|
+
return { status: r.status, headers: headers['content-type'] ? headers : { 'content-type': 'application/json' }, body: r.body };
|
|
3049
|
+
}
|
|
3050
|
+
if (read?.status === 'failed' || read?.status === 'expired') {
|
|
3051
|
+
const reason = typeof read.failure_reason === 'string' && /^[a-z_]{1,64}$/.test(read.failure_reason) ? read.failure_reason : read.status;
|
|
3052
|
+
throw new EbanxFollowUpError(reason, read.card_sent !== false, authorizationId);
|
|
3053
|
+
}
|
|
3054
|
+
if (signal.aborted || Date.now() >= deadline)
|
|
3055
|
+
throw new EbanxFollowUpError('answer_late', true, authorizationId);
|
|
3056
|
+
const wait = limited === 0 ? EBANX_FOLLOW_UP_READ_MS : Math.min(EBANX_FOLLOW_UP_BACKOFF_MAX_MS, 1000 * 2 ** (limited - 1));
|
|
3057
|
+
await interruptibleSleep(Math.max(1, Math.min(wait, deadline - Date.now())), signal);
|
|
3058
|
+
}
|
|
3059
|
+
}
|
|
2841
3060
|
/**
|
|
2842
3061
|
* Create a merchant-session probe, the phase-0 read of the deterministic merchant total:
|
|
2843
3062
|
* `user` is the org's connected user, who opens the returned Vault link and reads the
|
|
@@ -51,11 +51,13 @@ declare function parseCreditguardTransaction(body: any, txId: any): {
|
|
|
51
51
|
dccActive: boolean;
|
|
52
52
|
recaptcha: boolean;
|
|
53
53
|
jwePublicKey: string;
|
|
54
|
+
jwePublicKeyJson: any;
|
|
54
55
|
personalIdAlwaysEnabled: boolean;
|
|
55
56
|
inputs: any;
|
|
56
57
|
} | null;
|
|
57
|
-
declare function creditguardTransactionRefusal(txn: any, expectation: any): "otp" | "keep_on_file" | "dcc" | "installments" | "personal_id" | "jwe_unsupported" | "transaction_type" | "amount_mismatch" | "environment_mismatch" | "currency_mismatch" | "
|
|
58
|
+
declare function creditguardTransactionRefusal(txn: any, expectation: any): "otp" | "keep_on_file" | "dcc" | "installments" | "personal_id" | "jwe_unsupported" | "transaction_type" | "amount_mismatch" | "environment_mismatch" | "currency_mismatch" | "three_d_secure" | "transaction_unreadable" | "form_inputs" | "card_field_hidden" | "jwe_public_key_malformed" | null;
|
|
58
59
|
declare function creditguardSendWindowRefusal(timing: any): "timing_unknown" | "page_expired" | "recaptcha_expired" | null;
|
|
60
|
+
declare function creditguardBodyTransactionRefusal(body: any, txn: any): "jwe_mismatch" | null;
|
|
59
61
|
declare var CREDITGUARD_REFUSAL_CODES: readonly string[];
|
|
60
62
|
declare function creditguardResponseOutcome(status: any, body: any, options: any): {
|
|
61
63
|
outcome: string;
|
|
@@ -76,4 +78,100 @@ declare function creditguardFacts(status: any, body: any): {
|
|
|
76
78
|
errorCode: any;
|
|
77
79
|
refusalCode: any;
|
|
78
80
|
};
|
|
79
|
-
|
|
81
|
+
declare var CREDITGUARD_COMPANION_PATHS: Readonly<{
|
|
82
|
+
card_details: "/card/details";
|
|
83
|
+
ddc_init: "/cc/ddc/init";
|
|
84
|
+
threeds_init: "/cg3ds/process/init";
|
|
85
|
+
threeds_outcome: "/cg3ds/process/outcome";
|
|
86
|
+
}>;
|
|
87
|
+
declare var CREDITGUARD_DEVICE_STEPS: readonly string[];
|
|
88
|
+
declare var CREDITGUARD_CARDINAL_HOSTS: Readonly<{
|
|
89
|
+
production: readonly string[];
|
|
90
|
+
sandbox: readonly string[];
|
|
91
|
+
}>;
|
|
92
|
+
declare var CREDITGUARD_CARDINAL_COLLECT_URLS: Readonly<{
|
|
93
|
+
production: "https://client.cardinaltrusted.com/centinelapi/V2/Cruise/Collect";
|
|
94
|
+
sandbox: "https://cas.client.cardinaltrusted.com/centinelapi/V2/Cruise/Collect";
|
|
95
|
+
}>;
|
|
96
|
+
declare function creditguardCompanionStep(url: any): {
|
|
97
|
+
step: string;
|
|
98
|
+
txId: string;
|
|
99
|
+
} | null;
|
|
100
|
+
declare function creditguardDeviceStepUrl(processUrl: any, step: any): string | null;
|
|
101
|
+
declare function creditguardCompanionCall(url: any, method: any, body: any): {
|
|
102
|
+
step: null;
|
|
103
|
+
txId: null;
|
|
104
|
+
refusal: string;
|
|
105
|
+
} | {
|
|
106
|
+
refusal: string | null;
|
|
107
|
+
step: string;
|
|
108
|
+
txId: string;
|
|
109
|
+
} | null;
|
|
110
|
+
declare function creditguardCompanionAnswer(step: any): {
|
|
111
|
+
status: number;
|
|
112
|
+
headers: {
|
|
113
|
+
"content-type": string;
|
|
114
|
+
};
|
|
115
|
+
body: any;
|
|
116
|
+
} | null;
|
|
117
|
+
declare function creditguardDeviceDdcRequest(processUrl: any, card: any, options?: {}): Promise<{
|
|
118
|
+
url: string;
|
|
119
|
+
method: string;
|
|
120
|
+
headers: {
|
|
121
|
+
"content-type": "application/json";
|
|
122
|
+
accept: "application/json";
|
|
123
|
+
};
|
|
124
|
+
body: string;
|
|
125
|
+
}>;
|
|
126
|
+
declare function creditguardDeviceThreeDSInitRequest(processUrl: any, card: any, options?: {}): {
|
|
127
|
+
url: string;
|
|
128
|
+
method: string;
|
|
129
|
+
headers: {
|
|
130
|
+
"content-type": "application/json";
|
|
131
|
+
accept: "application/json";
|
|
132
|
+
};
|
|
133
|
+
body: string;
|
|
134
|
+
};
|
|
135
|
+
declare function creditguardDeviceThreeDSOutcomeRequest(processUrl: any): {
|
|
136
|
+
url: string;
|
|
137
|
+
method: string;
|
|
138
|
+
headers: {
|
|
139
|
+
"content-type": "application/json";
|
|
140
|
+
accept: "application/json";
|
|
141
|
+
};
|
|
142
|
+
body: string;
|
|
143
|
+
};
|
|
144
|
+
declare function creditguardDeviceStepRefusal(request: any, processUrl: any): "headers" | "malformed_body" | "wallet" | "unexpected_field" | "gift_card" | "dcc" | "txid_mismatch" | "card_fields" | "not_companion_request" | null;
|
|
145
|
+
declare function creditguardCardinalUrl(url: any, purpose: any, environment: any): string | null;
|
|
146
|
+
declare function isCreditguardCardinalOrigin(origin: any): boolean;
|
|
147
|
+
declare function creditguardCardinalMessage(data: any): {
|
|
148
|
+
sessionId: any;
|
|
149
|
+
} | null;
|
|
150
|
+
declare function creditguardDdcAnswer(status: any, body: any, environment: any): {
|
|
151
|
+
collectUrl: any;
|
|
152
|
+
ddcJwt: any;
|
|
153
|
+
} | null;
|
|
154
|
+
declare function creditguardThreeDSInitAnswer(status: any, body: any, environment: any): {
|
|
155
|
+
outcome: string;
|
|
156
|
+
reason: string;
|
|
157
|
+
stepUpUrl?: undefined;
|
|
158
|
+
stepUpJwt?: undefined;
|
|
159
|
+
} | {
|
|
160
|
+
outcome: string;
|
|
161
|
+
reason?: undefined;
|
|
162
|
+
stepUpUrl?: undefined;
|
|
163
|
+
stepUpJwt?: undefined;
|
|
164
|
+
} | {
|
|
165
|
+
outcome: string;
|
|
166
|
+
stepUpUrl: string;
|
|
167
|
+
stepUpJwt: any;
|
|
168
|
+
reason?: undefined;
|
|
169
|
+
};
|
|
170
|
+
declare function creditguardThreeDSOutcomeAnswer(status: any, body: any): {
|
|
171
|
+
outcome: string;
|
|
172
|
+
reason: string;
|
|
173
|
+
} | {
|
|
174
|
+
outcome: string;
|
|
175
|
+
reason?: undefined;
|
|
176
|
+
};
|
|
177
|
+
export { CREDITGUARD_CARDINAL_COLLECT_URLS, CREDITGUARD_CARDINAL_HOSTS, CREDITGUARD_COMPANION_PATHS, CREDITGUARD_DEVICE_STEPS, CREDITGUARD_JWE_HEADER, CREDITGUARD_OPERATION, CREDITGUARD_PAGE_WINDOW_MS, CREDITGUARD_PPS_HOSTS, CREDITGUARD_RECAPTCHA_WINDOW_MS, CREDITGUARD_REFUSAL_CODES, CREDITGUARD_SANDBOX_HOST, classifyCreditguardRequest, creditguardBodyRefusal, creditguardBodyTransactionRefusal, creditguardCardinalMessage, creditguardCardinalUrl, creditguardCompanionAnswer, creditguardCompanionCall, creditguardCompanionStep, creditguardDdcAnswer, creditguardDeviceDdcRequest, creditguardDeviceStepRefusal, creditguardDeviceStepUrl, creditguardDeviceThreeDSInitRequest, creditguardDeviceThreeDSOutcomeRequest, creditguardFacts, creditguardNuveiRefusal, creditguardPageProcessUrl, creditguardPpDomainHost, creditguardPreparationEnvironment, creditguardProcessRefusal, creditguardProcessTxId, creditguardRefusalMessage, creditguardReplayRefusal, creditguardResponseOutcome, creditguardSendWindowRefusal, creditguardThreeDSInitAnswer, creditguardThreeDSOutcomeAnswer, creditguardTransactionReadUrl, creditguardTransactionRefusal, encryptCreditguardJwe, injectCreditguardCard, injectCreditguardJweCard, isCreditguardCardinalOrigin, isCreditguardJweCompact, isCreditguardPpsDocument, isCreditguardProcessRequest, isCreditguardProcessUrl, parseCreditguardJwePublicKey, parseCreditguardTransaction, readCreditguardJson, sanitizeCreditguardResponse };
|