@agent-cards/sdk 0.23.6 → 0.23.8
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 +9 -1
- package/PREFLIGHT.md +1 -1
- package/README.md +146 -4
- package/dist/amadeus.d.ts +16 -4
- package/dist/amadeus.js +51 -16
- package/dist/cdp.js +183 -26
- package/dist/client.d.ts +22 -0
- package/dist/client.js +165 -13
- package/dist/creditguard.generated.d.ts +1 -1
- package/dist/cybersource-secure-acceptance.d.ts +142 -34
- package/dist/cybersource-secure-acceptance.generated.d.ts +67 -0
- package/dist/cybersource-secure-acceptance.generated.js +966 -0
- package/dist/cybersource-secure-acceptance.js +244 -3
- package/dist/index.d.ts +1 -0
- package/dist/juspay.generated.d.ts +1 -1
- package/dist/pre-claim.d.ts +3 -1
- package/dist/pre-claim.js +85 -6
- package/dist/preparation.js +15 -2
- package/dist/prepared-processor.d.ts +19 -5
- package/dist/prepared-processor.js +70 -3
- package/dist/registry.js +14 -1
- package/dist/stripe-checkout.generated.js +35 -1
- package/package.json +1 -1
package/dist/client.js
CHANGED
|
@@ -31,6 +31,7 @@ import { PELECARD_CAPABILITY, PELECARD_PSP } from './pelecard.js';
|
|
|
31
31
|
import { PRIMER_CAPABILITY, PRIMER_PSP, primerTokenAnswer } from './primer.js';
|
|
32
32
|
import { PAYRAILS_CAPABILITY, payrailsSaveAnswer } from './payrails.js';
|
|
33
33
|
import { WSPAY_CAPABILITY, WSPAY_PSP } from './wspay.js';
|
|
34
|
+
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';
|
|
34
35
|
/**
|
|
35
36
|
* The modes this SDK can finish. Asked for on syncRegistry (the API serves
|
|
36
37
|
* only recognizers in these modes, so a request this build cannot complete
|
|
@@ -158,8 +159,15 @@ export const SUPPORTED_REGISTRY_FEATURES = ['card_fields', 'checkout_sessions'];
|
|
|
158
159
|
* `ekashu_hosted_payment_page`: NMI's hosted payment page, whose card-free entry this
|
|
159
160
|
* build pauses for the cardholder's device and whose card page this build never lets
|
|
160
161
|
* the agent's browser post to (pre-claim.ts, ekashu.ts); served on the same terms.
|
|
162
|
+
* `cybersource_sa_token_create`: CyberSource Secure Acceptance's token create
|
|
163
|
+
* (POST /silent/embedded/token/create), which this build pauses only as the
|
|
164
|
+
* merchant's hidden frame sends it, binds to a prepared checkout, and answers with
|
|
165
|
+
* CyberSource's own reply page once neither the API nor the cardholder's device
|
|
166
|
+
* finds a card in it (cybersource-secure-acceptance.ts). Served on the same terms,
|
|
167
|
+
* so every other company keeps the stop every build applies to a card posted to
|
|
168
|
+
* Secure Acceptance.
|
|
161
169
|
*/
|
|
162
|
-
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'];
|
|
170
|
+
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];
|
|
163
171
|
/**
|
|
164
172
|
* Processors whose paused request names no amount at all, so the pair the
|
|
165
173
|
* agent passes is the amount the cardholder approves: authorize() refuses one
|
|
@@ -173,11 +181,16 @@ export const SUPPORTED_CAPABILITIES = ['fiserv_card_capture', GMO_CAPABILITY, CY
|
|
|
173
181
|
* pair is also the figure the API compares with WSPay's answer when that
|
|
174
182
|
* answer names one. A WSPay 3-D Secure step answers with no amount, so on that
|
|
175
183
|
* path nothing Agentcard sees confirms what WSPay charges once the challenge
|
|
176
|
-
* completes.
|
|
184
|
+
* completes. A CyberSource Secure Acceptance token create signs an amount of 0:
|
|
185
|
+
* it creates a token and charges nothing, and the merchant's server charges its
|
|
186
|
+
* own cart total later, so the agent's pair, which the prepared checkout already
|
|
187
|
+
* carries, is the total the cardholder approves, and the card that pays can spend
|
|
188
|
+
* no more than that (the API's card rule).
|
|
177
189
|
*/
|
|
178
|
-
const AGENT_AMOUNT_PROCESSORS = [GMO_PSP, PELECARD_PSP, WSPAY_PSP];
|
|
190
|
+
const AGENT_AMOUNT_PROCESSORS = [GMO_PSP, PELECARD_PSP, WSPAY_PSP, SECURE_ACCEPTANCE_PSP];
|
|
179
191
|
/** How AmountRequiredError names a processor. */
|
|
180
|
-
const PROCESSOR_NAMES = { [GMO_PSP]: 'GMO', [PELECARD_PSP]: 'Pelecard', [WSPAY_PSP]: 'WSPay'
|
|
192
|
+
const PROCESSOR_NAMES = { [GMO_PSP]: 'GMO', [PELECARD_PSP]: 'Pelecard', [WSPAY_PSP]: 'WSPay',
|
|
193
|
+
[SECURE_ACCEPTANCE_PSP]: 'CyberSource Secure Acceptance' };
|
|
181
194
|
/**
|
|
182
195
|
* Processors whose request and answer name no amount at all, so the total the
|
|
183
196
|
* payment page shows (`pageAmount`) is the one figure that ties the agent's pair
|
|
@@ -305,6 +318,22 @@ function creditguardPreparationRefusal(error) {
|
|
|
305
318
|
const reason = error.details.reason;
|
|
306
319
|
return new CheckoutPreparationError(null, error.code, typeof reason === 'string' && /^[a-z0-9_]{1,64}$/.test(reason) ? reason : undefined);
|
|
307
320
|
}
|
|
321
|
+
/**
|
|
322
|
+
* The API's refusal of a Secure Acceptance preparation (SECURE_ACCEPTANCE_PREPARATION_REFUSALS, and the
|
|
323
|
+
* relay's 503), answered before any row or prompt, as its own reason with the API's `details.reason` as
|
|
324
|
+
* the detail: `unsupported_checkout` (`secure_acceptance_merchant_pending`) tells an agent the merchant is
|
|
325
|
+
* not on yet, which `preparation_unconfirmed` would hide. Null for any other failure.
|
|
326
|
+
*/
|
|
327
|
+
function secureAcceptancePreparationRefusal(error) {
|
|
328
|
+
if (!(error instanceof CheckoutApiError) || error.code === null)
|
|
329
|
+
return null;
|
|
330
|
+
const named = (error.status >= 400 && error.status < 500 && SECURE_ACCEPTANCE_PREPARATION_REFUSALS.includes(error.code))
|
|
331
|
+
|| (error.status === 503 && error.code === 'cybersource_sa_relay_unavailable');
|
|
332
|
+
if (!named)
|
|
333
|
+
return null;
|
|
334
|
+
const reason = error.details.reason;
|
|
335
|
+
return new CheckoutPreparationError(null, error.code, typeof reason === 'string' && /^[a-z0-9_]{1,64}$/.test(reason) ? reason : undefined);
|
|
336
|
+
}
|
|
308
337
|
export class CardEncryptedError extends Error {
|
|
309
338
|
psp;
|
|
310
339
|
constructor(psp) {
|
|
@@ -932,6 +961,34 @@ const FISERV_PREPARATION_REFUSALS = [
|
|
|
932
961
|
* holds that pin). Only for an eProtect checkout.
|
|
933
962
|
*/
|
|
934
963
|
const EPROTECT_PREPARATION_REFUSALS = ['merchant_profile_mismatch'];
|
|
964
|
+
/**
|
|
965
|
+
* The API's refusals of a CyberSource Secure Acceptance preparation, before any preparation exists,
|
|
966
|
+
* that prepareCheckout surfaces by name, with the API's own `details.reason` as the error's `detail`
|
|
967
|
+
* where it gives one: the company is not one Agentcard turned the lane on for
|
|
968
|
+
* (`processor_unavailable`), the environment is not the client's test or live mode, the merchant is
|
|
969
|
+
* not one Agentcard turned on, or is still in review (`unsupported_checkout`, with
|
|
970
|
+
* `secure_acceptance_merchant_pending`, `secure_acceptance_merchant_observe` and the like), a live
|
|
971
|
+
* checkout's merchant is not the name the reviewed entry carries (`merchant_profile_mismatch`), and,
|
|
972
|
+
* as a 503, the relay that carries the cardholder's device to CyberSource is not on yet
|
|
973
|
+
* (`cybersource_sa_relay_unavailable`). Only for a Secure Acceptance checkout. The card follows the rule
|
|
974
|
+
* of every prepared checkout, a card the cardholder stored, so its refusal stays
|
|
975
|
+
* `preparation_unconfirmed`, as for Worldpay eProtect.
|
|
976
|
+
*/
|
|
977
|
+
const SECURE_ACCEPTANCE_PREPARATION_REFUSALS = [
|
|
978
|
+
'processor_unavailable', 'sandbox_host_on_live_row', 'live_host_on_sandbox_row', 'unsupported_checkout', 'merchant_profile_mismatch',
|
|
979
|
+
];
|
|
980
|
+
/**
|
|
981
|
+
* The reason the cardholder's device declines a bound prepared row with, per processor, when its own
|
|
982
|
+
* send boundary passed before the card left it (the Vault's sendWindow, 12 seconds after it last saw
|
|
983
|
+
* the checkout unbound): a prepared Amadeus SDK add and a prepared Secure Acceptance token create. It
|
|
984
|
+
* names the same known non-payment the adapters' own send window closes on (amadeus.ts), which can
|
|
985
|
+
* close later, so authorize() ends the attempt the way that window does, as a CheckoutPreparationError
|
|
986
|
+
* with that reason, and never as the cardholder's "no".
|
|
987
|
+
*/
|
|
988
|
+
const PREPARED_SEND_WINDOW_DECLINES = Object.freeze({
|
|
989
|
+
amadeus_checkout: 'amadeus_send_window_closed',
|
|
990
|
+
[SECURE_ACCEPTANCE_PSP]: 'secure_acceptance_send_window_closed',
|
|
991
|
+
});
|
|
935
992
|
/**
|
|
936
993
|
* Refusals a CyberSource Flex preparation that tokenizes before Pay answers (4xx) before any
|
|
937
994
|
* preparation exists, surfaced as the CheckoutPreparationError reason: the processor is off for
|
|
@@ -1131,15 +1188,17 @@ export class VaultClient {
|
|
|
1131
1188
|
// creditguard_pps_process, primer_payment_instruments,
|
|
1132
1189
|
// payrails_device_encrypt, converge_hpp_process, worldpay_eprotect_jsonp,
|
|
1133
1190
|
// wspay_confirm, shiji_sts_pinned_key, amadeus_checkout_actions.v1,
|
|
1134
|
-
// worldline_mycheckout_form, verifone_card_capture
|
|
1191
|
+
// worldline_mycheckout_form, verifone_card_capture, ekashu_hosted_payment_page,
|
|
1192
|
+
// cybersource_sa_token_create) and
|
|
1135
1193
|
// the caller's company is one Agentcard turned that processor on for, so this
|
|
1136
1194
|
// build arms Fiserv's card capture, GMO's getToken, CyberSource Flex's card
|
|
1137
1195
|
// fields, Juspay's card flow, Datatrans's Secure Fields card post, the
|
|
1138
1196
|
// Authorize.Net DPM or SIM form, Pelecard's card submission, ACI's split card,
|
|
1139
1197
|
// CreditGuard's hosted page submit, Primer's card tokenization, Payrails' card
|
|
1140
1198
|
// save, Converge's payment page, Worldpay eProtect's registration, WSPay's
|
|
1141
|
-
// card confirm, Shiji STS's card leg, Amadeus Checkout's card add
|
|
1142
|
-
// Worldline MyCheckout's card form
|
|
1199
|
+
// card confirm, Shiji STS's card leg, Amadeus Checkout's card add,
|
|
1200
|
+
// Worldline MyCheckout's card form and CyberSource Secure Acceptance's token
|
|
1201
|
+
// create only for
|
|
1143
1202
|
// such a company, and an older build never receives a recognizer it cannot
|
|
1144
1203
|
// judge. Every other org's registry never recognizes a Flex, Juspay, Datatrans,
|
|
1145
1204
|
// Pelecard, ACI, CreditGuard, Primer, Payrails, Converge, eProtect, WSPay, Shiji STS, Amadeus or
|
|
@@ -1148,8 +1207,10 @@ export class VaultClient {
|
|
|
1148
1207
|
// SIM, Pelecard, ACI, CreditGuard, Primer, Payrails, Converge, eProtect, WSPay,
|
|
1149
1208
|
// Shiji STS, Amadeus and MyCheckout requests go through untouched; the create checks the org again (403
|
|
1150
1209
|
// processor_unavailable), and the SDK refuses ACI's card-number request,
|
|
1151
|
-
// CreditGuard's submit, an eProtect registration
|
|
1152
|
-
// without a prepared checkout.
|
|
1210
|
+
// CreditGuard's submit, an eProtect registration, an Amadeus card add and a
|
|
1211
|
+
// Secure Acceptance token create locally without a prepared checkout. A Secure
|
|
1212
|
+
// Acceptance card post that no served recognizer covers is stopped for every
|
|
1213
|
+
// company (pre-claim.ts).
|
|
1153
1214
|
const capabilities = SUPPORTED_CAPABILITIES.length ? `&capabilities=${SUPPORTED_CAPABILITIES.join(',')}` : '';
|
|
1154
1215
|
// merchant_profiles=1 asks for the reviewed Adyen merchant profiles too, each
|
|
1155
1216
|
// as a `{ merchant_profile }` entry after the recognizers; an API that
|
|
@@ -1403,6 +1464,16 @@ export class VaultClient {
|
|
|
1403
1464
|
throw fail('paypage_id_invalid');
|
|
1404
1465
|
if (eprotect && !input.cardId)
|
|
1405
1466
|
throw fail('card_required');
|
|
1467
|
+
// CyberSource Secure Acceptance: the preparation names the CyberSource merchant profile its token create
|
|
1468
|
+
// may name (secureAcceptanceProfileId, which on the production host this build can fill from the entry
|
|
1469
|
+
// it reviewed for the page's origin) and the paying card, whose billing name and address the agent types
|
|
1470
|
+
// into the merchant's form, where the merchant's server signs them. The API refuses either missing, and a
|
|
1471
|
+
// profile id on any other processor; refusing here asks nobody to approve a preparation that could never bind.
|
|
1472
|
+
const secureAcceptance = input.psp === SECURE_ACCEPTANCE_PSP;
|
|
1473
|
+
if (!secureAcceptance && input.secureAcceptanceProfileId !== undefined)
|
|
1474
|
+
throw fail('secure_acceptance_profile_id_invalid');
|
|
1475
|
+
if (secureAcceptance && !input.cardId)
|
|
1476
|
+
throw fail('card_required');
|
|
1406
1477
|
// CyberSource Flex, tokenized before Pay: the loaded card field's capture context and fields,
|
|
1407
1478
|
// verified here against the keys payment-core pins before anything is created (the API and the
|
|
1408
1479
|
// cardholder's device verify them again).
|
|
@@ -1448,6 +1519,17 @@ export class VaultClient {
|
|
|
1448
1519
|
merchantOrigin: input.merchantOrigin, merchant: input.merchant }) : null;
|
|
1449
1520
|
if (eprotectRefusal)
|
|
1450
1521
|
throw fail(eprotectRefusal);
|
|
1522
|
+
// A Secure Acceptance checkout names a profile id: the one passed, of CyberSource's shape, or on the
|
|
1523
|
+
// production host the one the entry this build reviewed for the page's origin pins. Under a reviewed
|
|
1524
|
+
// entry it names that entry's merchant, the one the API shows on the approval, so the approval, the
|
|
1525
|
+
// handle this returns and every authorization it pays name one merchant. A profile id this build has not
|
|
1526
|
+
// reviewed is the API's to judge (unsupported_checkout); the test host needs no entry.
|
|
1527
|
+
const secureAcceptanceRefusal = secureAcceptance ? secureAcceptanceCheckoutRefusal({ environment: input.environment,
|
|
1528
|
+
profileId: input.secureAcceptanceProfileId, merchantOrigin: input.merchantOrigin, merchant: input.merchant }) : null;
|
|
1529
|
+
if (secureAcceptanceRefusal)
|
|
1530
|
+
throw fail(secureAcceptanceRefusal);
|
|
1531
|
+
const secureAcceptanceProfileId = secureAcceptance ? secureAcceptanceCheckoutProfile({ environment: input.environment,
|
|
1532
|
+
profileId: input.secureAcceptanceProfileId, merchantOrigin: input.merchantOrigin }) : null;
|
|
1451
1533
|
const timeoutMs = input.timeoutMs ?? 15 * 60_000;
|
|
1452
1534
|
if (!Number.isInteger(timeoutMs) || timeoutMs <= 0 || timeoutMs > 2_147_483_647)
|
|
1453
1535
|
throw fail('timeout_invalid');
|
|
@@ -1469,6 +1551,7 @@ export class VaultClient {
|
|
|
1469
1551
|
...(declaration ? { sandbox_declaration: { endpoint: declaration.endpoint, client_key: declaration.clientKey, environment: 'test' } } : {}),
|
|
1470
1552
|
...(input.psp === 'creditguard' ? { payment_page_url: input.paymentPageUrl } : {}),
|
|
1471
1553
|
...(eprotect ? { paypage_id: input.paypageId } : {}),
|
|
1554
|
+
...(secureAcceptance ? { secure_acceptance_profile_id: secureAcceptanceProfileId } : {}),
|
|
1472
1555
|
...(flexContext ? { capture_context: flexContext.captureContext,
|
|
1473
1556
|
microform: { version: flexContext.microform.version, fields: [...flexContext.microform.fields] } } : {}),
|
|
1474
1557
|
}, AbortSignal.timeout(30_000), signal);
|
|
@@ -1511,6 +1594,8 @@ export class VaultClient {
|
|
|
1511
1594
|
|| state.checkout_key !== input.checkoutKey
|
|
1512
1595
|
// eProtect: the merchant and the card the cardholder approved are the ones asked for.
|
|
1513
1596
|
|| (eprotect && (state.paypage_id !== input.paypageId || state.card_id !== input.cardId))
|
|
1597
|
+
// Secure Acceptance: the merchant profile and the card the cardholder approved are the ones asked for.
|
|
1598
|
+
|| (secureAcceptance && (state.secure_acceptance_profile_id !== secureAcceptanceProfileId || state.card_id !== input.cardId))
|
|
1514
1599
|
// The API says a preparation tokenizes before Pay exactly when this one carried a capture context.
|
|
1515
1600
|
|| (state.tokenize_before_pay === true) !== !!flexContext)
|
|
1516
1601
|
throw fail('ready_unconfirmed', id);
|
|
@@ -1526,6 +1611,7 @@ export class VaultClient {
|
|
|
1526
1611
|
...(declaration ? { sandboxDeclaration: declaration } : {}),
|
|
1527
1612
|
...(input.psp === 'creditguard' ? { paymentPageUrl: input.paymentPageUrl } : {}),
|
|
1528
1613
|
...(eprotect ? { paypageId: input.paypageId } : {}),
|
|
1614
|
+
...(secureAcceptance ? { secureAcceptanceProfileId: secureAcceptanceProfileId } : {}),
|
|
1529
1615
|
...(flexContext ? { cybersourceFlex: Object.freeze({ captureContext: flexContext.captureContext,
|
|
1530
1616
|
microform: Object.freeze({ version: flexContext.microform.version, fields: Object.freeze([...flexContext.microform.fields]) }) }) } : {}),
|
|
1531
1617
|
});
|
|
@@ -1542,7 +1628,8 @@ export class VaultClient {
|
|
|
1542
1628
|
catch (error) {
|
|
1543
1629
|
if (error instanceof CheckoutPreparationError)
|
|
1544
1630
|
throw error;
|
|
1545
|
-
const refusal = input.psp === 'creditguard' && id === null ? creditguardPreparationRefusal(error)
|
|
1631
|
+
const refusal = input.psp === 'creditguard' && id === null ? creditguardPreparationRefusal(error)
|
|
1632
|
+
: secureAcceptance && id === null && !signal.aborted ? secureAcceptancePreparationRefusal(error) : null;
|
|
1546
1633
|
if (refusal)
|
|
1547
1634
|
throw refusal;
|
|
1548
1635
|
// A refusal the API answered before any preparation existed names its rule: one
|
|
@@ -1621,6 +1708,8 @@ export class VaultClient {
|
|
|
1621
1708
|
* response to replay into the browser. Your process never sees a card.
|
|
1622
1709
|
*/
|
|
1623
1710
|
async authorize(input) {
|
|
1711
|
+
// When the paused request reached this call: a Secure Acceptance reply window runs from here.
|
|
1712
|
+
const calledAt = Date.now();
|
|
1624
1713
|
// A reviewed merchant's own card endpoint is checked whole before anything else
|
|
1625
1714
|
// (admitCardEndpoint): the profile, the approval, the amount and the session.
|
|
1626
1715
|
const cardEndpoint = input.request.merchant_card_endpoint === undefined ? null : admitCardEndpoint(input);
|
|
@@ -1803,6 +1892,12 @@ export class VaultClient {
|
|
|
1803
1892
|
if (cardMethod === 'GET' && !(eprotect && isEprotectRegistration(input.request))) {
|
|
1804
1893
|
throw new Error(`this ${rec?.psp} GET is not a card registration this version of @agent-cards/checkout can complete: ${redactUrl(input.request.url)}.`);
|
|
1805
1894
|
}
|
|
1895
|
+
// A CyberSource Secure Acceptance token create (always prepared: its recognizer requires it). The
|
|
1896
|
+
// merchant's page asks its hidden frame for the reply for 30 seconds from Save, so a reply not read
|
|
1897
|
+
// SECURE_ACCEPTANCE_REPLY_WINDOW_MS after the pause will never be read: the outcome is then unknown,
|
|
1898
|
+
// and the authorization is retired when the API confirms the card never moved.
|
|
1899
|
+
const secureAcceptance = rec?.psp === SECURE_ACCEPTANCE_PSP;
|
|
1900
|
+
const secureAcceptanceReplyBy = secureAcceptance ? calledAt + SECURE_ACCEPTANCE_REPLY_WINDOW_MS : Infinity;
|
|
1806
1901
|
// The amount is a hint: a pair or nothing. Refuse half a pair here, before
|
|
1807
1902
|
// a network call: the API would too, and a retry loop cannot fix a
|
|
1808
1903
|
// missing field. The processor's own amount is read by Agentcard.
|
|
@@ -1924,6 +2019,17 @@ export class VaultClient {
|
|
|
1924
2019
|
}
|
|
1925
2020
|
throw new PaymentOutcomeUnknownError(id, 'preparation_already_bound');
|
|
1926
2021
|
}
|
|
2022
|
+
// A Secure Acceptance create refused because the relay that carries the cardholder's device to
|
|
2023
|
+
// CyberSource is off (503 cybersource_sa_relay_unavailable): the API answers it before any rule, row
|
|
2024
|
+
// or bind (assertSecureAcceptanceRelayReady at the create, and again inside the bind's transaction),
|
|
2025
|
+
// so nothing was created and the card cannot leave. Named, as prepare() names it, never a create
|
|
2026
|
+
// that may have committed. The preparation, which no request can bind while the relay is off, is
|
|
2027
|
+
// retired so the cardholder's page stops waiting for it.
|
|
2028
|
+
if (secureAcceptance && error instanceof CheckoutApiError && error.status === 503 && error.code === 'cybersource_sa_relay_unavailable') {
|
|
2029
|
+
if (preparation)
|
|
2030
|
+
await this.cancelPreparation(preparation.id).catch(() => { });
|
|
2031
|
+
throw new CheckoutPreparationError(preparation?.id ?? null, error.code);
|
|
2032
|
+
}
|
|
1927
2033
|
// A missing answer or generic 5xx can hide a committed row and a delivered approval link.
|
|
1928
2034
|
// Only the documented pre-create read-back errors prove it is safe to retry.
|
|
1929
2035
|
const safeReadFailure = error instanceof CheckoutApiError
|
|
@@ -1945,8 +2051,12 @@ export class VaultClient {
|
|
|
1945
2051
|
// A prepared Worldpay eProtect registration too, for 15 seconds: its
|
|
1946
2052
|
// merchants give up on the paused script 10 to 15 seconds after Pay, so a
|
|
1947
2053
|
// registration is read every 500 ms instead of waiting out 2 seconds.
|
|
2054
|
+
// A prepared CyberSource Secure Acceptance token create too, for 30 seconds:
|
|
2055
|
+
// the merchant's page asks its frame for the reply for 30 seconds from Save,
|
|
2056
|
+
// and the API names 500 ms as such a row's poll interval.
|
|
1948
2057
|
const preparedFastPollUntil = preparation?.psp === 'mercado_pago' ? Date.now() + 10_000
|
|
1949
|
-
: preparation?.psp === EPROTECT_PSP ? Date.now() + 15_000
|
|
2058
|
+
: preparation?.psp === EPROTECT_PSP ? Date.now() + 15_000
|
|
2059
|
+
: preparation?.psp === SECURE_ACCEPTANCE_PSP ? Date.now() + SECURE_ACCEPTANCE_FAST_POLL_MS : 0;
|
|
1950
2060
|
// A preparation that tokenized before Pay: the cardholder's device already holds CyberSource's
|
|
1951
2061
|
// token and approves as soon as this bind reaches it, while the page may give createToken only
|
|
1952
2062
|
// seconds (Alaska Airlines' flight checkout gives it three). Poll every 100 ms for 10 seconds,
|
|
@@ -2003,16 +2113,24 @@ export class VaultClient {
|
|
|
2003
2113
|
throw new PaymentOutcomeUnknownError(authorizationId, input.merchantSignal?.aborted ? 'merchant_request_aborted' : 'local_cancel');
|
|
2004
2114
|
const pollInterval = Date.now() < preparedFastPollUntil ? Math.min(this.pollIntervalMs, 500)
|
|
2005
2115
|
: Date.now() < preparedFlexPollUntil ? Math.min(this.pollIntervalMs, 100) : this.pollIntervalMs;
|
|
2006
|
-
|
|
2116
|
+
// A Secure Acceptance read also wakes when its reply window closes (Infinity for every other processor).
|
|
2117
|
+
await interruptibleSleep(Math.min(pollInterval, Math.max(0, deadline - Date.now()), Math.max(0, secureAcceptanceReplyBy - Date.now())), stopSignal);
|
|
2007
2118
|
if (stopSignal?.aborted)
|
|
2008
2119
|
throw new PaymentOutcomeUnknownError(authorizationId, input.merchantSignal?.aborted ? 'merchant_request_aborted' : 'local_cancel');
|
|
2009
2120
|
let s;
|
|
2010
2121
|
const deadlineSignal = AbortSignal.timeout(Math.max(1, deadline - Date.now()));
|
|
2011
|
-
|
|
2122
|
+
// A Secure Acceptance read is also bounded by its reply window, whatever time the caller has left: once
|
|
2123
|
+
// the window closes the merchant's page has stopped asking for the reply, so a read still unanswered then
|
|
2124
|
+
// is late, never a failed poll that could still hand the frame a page.
|
|
2125
|
+
const replySignal = secureAcceptance ? AbortSignal.timeout(Math.max(1, secureAcceptanceReplyBy - Date.now())) : undefined;
|
|
2126
|
+
const pollSignal = stopSignal || replySignal
|
|
2127
|
+
? AbortSignal.any([...(stopSignal ? [stopSignal] : []), deadlineSignal, ...(replySignal ? [replySignal] : [])]) : deadlineSignal;
|
|
2012
2128
|
try {
|
|
2013
2129
|
s = await this.get(`/v2/checkout/authorizations/${authorizationId}`, pollSignal);
|
|
2014
2130
|
}
|
|
2015
2131
|
catch {
|
|
2132
|
+
if (replySignal?.aborted && !stopSignal?.aborted)
|
|
2133
|
+
throw new PaymentOutcomeUnknownError(authorizationId, 'secure_acceptance_reply_late');
|
|
2016
2134
|
throw new PaymentOutcomeUnknownError(authorizationId, input.merchantSignal?.aborted ? 'merchant_request_aborted' : 'authorization_poll_failed');
|
|
2017
2135
|
}
|
|
2018
2136
|
if (input.merchantSignal?.aborted)
|
|
@@ -2020,6 +2138,12 @@ export class VaultClient {
|
|
|
2020
2138
|
if (!s || typeof s !== 'object' || Array.isArray(s) || typeof s.status !== 'string') {
|
|
2021
2139
|
throw new PaymentOutcomeUnknownError(authorizationId, 'authorization_status_malformed');
|
|
2022
2140
|
}
|
|
2141
|
+
// An approval read once the reply window has closed reaches nobody: the merchant's page has stopped asking,
|
|
2142
|
+
// so CyberSource's page is never handed to the frame. The card has reached CyberSource, so the outcome is
|
|
2143
|
+
// unknown, as for a reply that never came.
|
|
2144
|
+
if (secureAcceptance && s.status === 'approved' && (Date.now() >= secureAcceptanceReplyBy || replySignal?.aborted)) {
|
|
2145
|
+
throw new PaymentOutcomeUnknownError(authorizationId, 'secure_acceptance_reply_late');
|
|
2146
|
+
}
|
|
2023
2147
|
execution = executionMetadata(s, authorizationId, execution);
|
|
2024
2148
|
checkAutopilotAction(s);
|
|
2025
2149
|
if (nativeCheckout && (s.status === 'submitted_on_device' ||
|
|
@@ -2202,6 +2326,23 @@ export class VaultClient {
|
|
|
2202
2326
|
response.headers = answer.headers;
|
|
2203
2327
|
response.body = answer.body;
|
|
2204
2328
|
}
|
|
2329
|
+
if (secureAcceptance) {
|
|
2330
|
+
// CyberSource Secure Acceptance: the paused frame navigation is answered with CyberSource's own
|
|
2331
|
+
// reply page, byte for byte, with status 200 and its one content type, and only a page
|
|
2332
|
+
// payment-core's reply rule accepts for the paused request (secureAcceptanceFrameAnswer): one
|
|
2333
|
+
// hidden-input form posting to the receipt page the request signed, the request's own echoes, a
|
|
2334
|
+
// masked number and a token. The device and the API already checked it for the card. Anything
|
|
2335
|
+
// else is not an answer to hand the frame, and the card has already reached CyberSource. No
|
|
2336
|
+
// autopilot run sends one (payment-core, the authority and the API refuse it).
|
|
2337
|
+
if (execution.executionMode === 'autopilot')
|
|
2338
|
+
throw new PaymentOutcomeUnknownError(authorizationId, 'autopilot_submission_mode_invalid');
|
|
2339
|
+
const answer = secureAcceptanceFrameAnswer(input.request, response);
|
|
2340
|
+
if (!answer)
|
|
2341
|
+
throw new PaymentOutcomeUnknownError(authorizationId, 'secure_acceptance_reply_unconfirmed');
|
|
2342
|
+
response.status = answer.status;
|
|
2343
|
+
response.headers = answer.headers;
|
|
2344
|
+
response.body = answer.body;
|
|
2345
|
+
}
|
|
2205
2346
|
if (shopOrder) {
|
|
2206
2347
|
let receipt;
|
|
2207
2348
|
try {
|
|
@@ -2312,6 +2453,12 @@ export class VaultClient {
|
|
|
2312
2453
|
if (s.reason === 'processor_refused') {
|
|
2313
2454
|
throw new ProcessorRefusedError(String(created.id), typeof s.psp_error_code === 'string' ? s.psp_error_code : null, s.psp === 'razorpay' ? parseProcessorError(s.processor_error) : null);
|
|
2314
2455
|
}
|
|
2456
|
+
// The cardholder's device passed its own send boundary before the card left it and declined the
|
|
2457
|
+
// row with that window's reason: the checkout failed unsent, as when the adapters' own window
|
|
2458
|
+
// closes first (PREPARED_SEND_WINDOW_DECLINES), not a decline the cardholder made.
|
|
2459
|
+
if (preparation && typeof s.reason === 'string' && PREPARED_SEND_WINDOW_DECLINES[preparation.psp] === s.reason) {
|
|
2460
|
+
throw new CheckoutPreparationError(preparation.id, s.reason);
|
|
2461
|
+
}
|
|
2315
2462
|
throw new ApprovalDeclinedError(s.reason ?? 'no reason given');
|
|
2316
2463
|
}
|
|
2317
2464
|
if (s.status === 'cancelled') {
|
|
@@ -2326,6 +2473,11 @@ export class VaultClient {
|
|
|
2326
2473
|
}
|
|
2327
2474
|
if (s.status !== 'awaiting_approval')
|
|
2328
2475
|
throw new PaymentOutcomeUnknownError(authorizationId, 'authorization_status_unrecognized');
|
|
2476
|
+
// A Secure Acceptance row neither approved nor declined when its reply window closes: the merchant's
|
|
2477
|
+
// page stopped asking for the reply, and the device may have sent the card. Unknown, never a decline;
|
|
2478
|
+
// the cleanup below retires the row only when the API confirms the card never moved.
|
|
2479
|
+
if (Date.now() >= secureAcceptanceReplyBy)
|
|
2480
|
+
throw new PaymentOutcomeUnknownError(authorizationId, 'secure_acceptance_reply_late');
|
|
2329
2481
|
}
|
|
2330
2482
|
// A local deadline is not server-side expiry; the person may still use the approval link.
|
|
2331
2483
|
throw new PaymentOutcomeUnknownError(authorizationId, 'local_approval_timeout');
|
|
@@ -54,7 +54,7 @@ declare function parseCreditguardTransaction(body: any, txId: any): {
|
|
|
54
54
|
personalIdAlwaysEnabled: boolean;
|
|
55
55
|
inputs: any;
|
|
56
56
|
} | null;
|
|
57
|
-
declare function creditguardTransactionRefusal(txn: any, expectation: any): "otp" | "keep_on_file" | "dcc" | "installments" | "personal_id" | "jwe_unsupported" | "amount_mismatch" | "environment_mismatch" | "currency_mismatch" | "transaction_unreadable" | "three_d_secure" | "
|
|
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" | "transaction_unreadable" | "three_d_secure" | "form_inputs" | "card_field_hidden" | "no_retries_left" | "jwe_public_key_malformed" | null;
|
|
58
58
|
declare function creditguardSendWindowRefusal(timing: any): "timing_unknown" | "page_expired" | "recaptcha_expired" | null;
|
|
59
59
|
declare var CREDITGUARD_REFUSAL_CODES: readonly string[];
|
|
60
60
|
declare function creditguardResponseOutcome(status: any, body: any, options: any): {
|
|
@@ -1,37 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* CyberSource Secure Acceptance's Silent Order POST, which this SDK refuses for every company.
|
|
3
|
-
*
|
|
4
|
-
* CyberSource's Secure Acceptance Checkout API, formerly Silent Order POST, takes the card from a form
|
|
5
|
-
* on the merchant's own page. The merchant's server signs the order fields, and the shopper's browser
|
|
6
|
-
* posts them, with the card fields left unsigned, to a /silent/ path on one of CyberSource's Secure
|
|
7
|
-
* Acceptance hosts: /silent/pay, /silent/token/create, /silent/token/update, and the iframe form of
|
|
8
|
-
* each under /silent/embedded/ (CyberSource's endpoint table, read 2026-10-08). Arrow Electronics'
|
|
9
|
-
* checkout (its public bundles, read 2026-10-08; no card was sent) builds that form once its server
|
|
10
|
-
* has signed the fields and submits it into a hidden iframe:
|
|
11
|
-
*
|
|
12
|
-
* <iframe name="secureAcceptanceiFrame" style="display:none">
|
|
13
|
-
* <form action="https://secureacceptance.cybersource.com/silent/embedded/token/create" method="post"
|
|
14
|
-
* target="secureAcceptanceiFrame">: access_key, profile_id, transaction_type=create_payment_token,
|
|
15
|
-
* amount=0 and the other signed fields with their signature, then card_type, card_number,
|
|
16
|
-
* card_expiry_date (MM-YYYY) and card_cvn
|
|
17
|
-
*
|
|
18
|
-
* No Vault mode takes this post over, so no company can pay it, and an SDK without this guard let the
|
|
19
|
-
* card the agent typed reach CyberSource. Both adapters arm /silent/ on the three hosts whatever the
|
|
20
|
-
* synced registry serves, over https and http, each host also spelled with the trailing dot of a fully
|
|
21
|
-
* qualified name, and the pre-claim gate (cybersourceSecureAcceptancePreClaim, pre-claim.ts) judges
|
|
22
|
-
* each request there, whether a fetch, an XHR or a form navigation of the page or of a frame sent it,
|
|
23
|
-
* by its body and by its URL's query (cybersourceSecureAcceptanceRequest):
|
|
24
|
-
* - a card_number that holds a value: stop it, so CyberSource never receives the card. A form
|
|
25
|
-
* navigation is answered with the stopped page (card-endpoint-page.ts), which names CyberSource,
|
|
26
|
-
* since an aborted page load renders nothing and invites another click on Pay; any other request
|
|
27
|
-
* fails. The checkout reads `unsupported` with reason `unsupported_cybersource_secure_acceptance`
|
|
28
|
-
* and holds, as every unsupported refusal does;
|
|
29
|
-
* - no card_number, or an empty one, as in a payment with a stored payment_token: continue untouched;
|
|
30
|
-
* - a body the adapter could not read: stop that request alone, since nothing proves it carries no card.
|
|
31
|
-
* A request the synced registry recognizes as a card request belongs to that recognizer instead; no
|
|
32
|
-
* build serves one today. Hosted Checkout, the same hosts without /silent/, takes the card on
|
|
33
|
-
* CyberSource's own page, and neither adapter arms it.
|
|
34
|
-
*/
|
|
35
1
|
export declare const CYBERSOURCE_SECURE_ACCEPTANCE_REASON: "unsupported_cybersource_secure_acceptance";
|
|
36
2
|
/** Where the stopped page says the card was going. */
|
|
37
3
|
export declare const CYBERSOURCE_SECURE_ACCEPTANCE_RECIPIENT = "CyberSource";
|
|
@@ -76,3 +42,145 @@ export declare function cybersourceSecureAcceptanceRequest(url: string, method:
|
|
|
76
42
|
* body that also parses as JSON, say, cannot carry the card past the gate.
|
|
77
43
|
*/
|
|
78
44
|
export declare function cybersourceSecureAcceptanceBody(body: string | null, contentType?: string): 'card' | 'no_card' | 'unreadable';
|
|
45
|
+
/** The processor id, as the registry and the API name it. */
|
|
46
|
+
export declare const SECURE_ACCEPTANCE_PSP: "cybersource_secure_acceptance";
|
|
47
|
+
/** The dark-launch capability the API serves the Secure Acceptance recognizer behind (payment-core definitions.js). */
|
|
48
|
+
export declare const SECURE_ACCEPTANCE_CAPABILITY: "cybersource_sa_token_create";
|
|
49
|
+
/** How long after the pause a paused token request may still be sent; past it, nothing being handed over, it is retired. */
|
|
50
|
+
export declare const SECURE_ACCEPTANCE_SEND_WINDOW_MS = 20000;
|
|
51
|
+
/** How long after the pause CyberSource's reply may still be read; past it the outcome is unknown. */
|
|
52
|
+
export declare const SECURE_ACCEPTANCE_REPLY_WINDOW_MS = 45000;
|
|
53
|
+
/** How long after the create the authorization is read every 500 ms instead of at the caller's interval. */
|
|
54
|
+
export declare const SECURE_ACCEPTANCE_FAST_POLL_MS = 30000;
|
|
55
|
+
/** How long after the page is delivered the merchant's follow-up request is watched for. */
|
|
56
|
+
export declare const SECURE_ACCEPTANCE_FOLLOW_UP_MS = 10000;
|
|
57
|
+
/** The one content type the paused frame's answer carries, as CyberSource serves its page. */
|
|
58
|
+
export declare const SECURE_ACCEPTANCE_ANSWER_CONTENT_TYPE: string;
|
|
59
|
+
/** A reviewed production merchant, as payment-core's SECURE_ACCEPTANCE_MERCHANTS lists it; the fields this SDK reads. */
|
|
60
|
+
export interface SecureAcceptanceMerchant {
|
|
61
|
+
id: string;
|
|
62
|
+
merchant: string;
|
|
63
|
+
environment: string;
|
|
64
|
+
status: string;
|
|
65
|
+
origins: readonly string[];
|
|
66
|
+
profileIds: readonly string[];
|
|
67
|
+
accessKeys?: readonly string[];
|
|
68
|
+
pending?: readonly string[];
|
|
69
|
+
/** The one request the merchant's page sends once the receipt answered it, watched for after delivery. */
|
|
70
|
+
followUp?: {
|
|
71
|
+
method: string;
|
|
72
|
+
url: string;
|
|
73
|
+
} | null;
|
|
74
|
+
}
|
|
75
|
+
/** Why prepare() refuses a Secure Acceptance checkout before any network call. */
|
|
76
|
+
export type SecureAcceptanceCheckoutRefusal = 'secure_acceptance_profile_id_invalid' | 'merchant_profile_mismatch';
|
|
77
|
+
/** Why a paused Secure Acceptance request ends with an unknown outcome, beside the reasons every processor shares. */
|
|
78
|
+
export type SecureAcceptanceUnknownReason = 'secure_acceptance_reply_unconfirmed' | 'secure_acceptance_reply_late' | 'response_expired';
|
|
79
|
+
/**
|
|
80
|
+
* The profile id a Secure Acceptance checkout prepares, or null when it can name none. A profile id the
|
|
81
|
+
* caller passes must have CyberSource's UUID shape, and is the one the bound request must carry. On the
|
|
82
|
+
* production host the caller may leave it out when exactly one entry this build reviewed lists the
|
|
83
|
+
* checkout page's origin, under exactly one profile id: that one is used, so the agent names nothing it
|
|
84
|
+
* cannot see. The test host has no entries (it takes only CyberSource's test cards), so a sandbox
|
|
85
|
+
* checkout always names its own. `entries` is for tests.
|
|
86
|
+
*/
|
|
87
|
+
export declare function secureAcceptanceCheckoutProfile(input: {
|
|
88
|
+
environment: string;
|
|
89
|
+
profileId?: unknown;
|
|
90
|
+
merchantOrigin: string;
|
|
91
|
+
}, entries?: readonly SecureAcceptanceMerchant[]): string | null;
|
|
92
|
+
/**
|
|
93
|
+
* Why a Secure Acceptance checkout may not be prepared under `merchant`, or null when it may:
|
|
94
|
+
* `secure_acceptance_profile_id_invalid` when it names no profile id this build can stand behind
|
|
95
|
+
* (secureAcceptanceCheckoutProfile), and, on the production host, `merchant_profile_mismatch` when the
|
|
96
|
+
* entry this build reviewed for that profile id and origin names another merchant, the one the approval
|
|
97
|
+
* shows. A profile id this build has not reviewed is the API's to judge (unsupported_checkout), as an
|
|
98
|
+
* eProtect paypageId is. `entries` is for tests.
|
|
99
|
+
*/
|
|
100
|
+
export declare function secureAcceptanceCheckoutRefusal(input: {
|
|
101
|
+
environment: string;
|
|
102
|
+
profileId?: unknown;
|
|
103
|
+
merchantOrigin: string;
|
|
104
|
+
merchant: string;
|
|
105
|
+
}, entries?: readonly SecureAcceptanceMerchant[]): SecureAcceptanceCheckoutRefusal | null;
|
|
106
|
+
/**
|
|
107
|
+
* Whether a paused request is the one shape the lane pays: a POST to the exact token-create URL on one of
|
|
108
|
+
* the two hosts (payment-core isSecureAcceptanceTokenRequest), sent as a navigation of a frame, as a
|
|
109
|
+
* merchant's form targeted at its hidden iframe sends it. A top navigation, a fetch and an XHR are not.
|
|
110
|
+
*/
|
|
111
|
+
export declare function isSecureAcceptanceFramePost(request: {
|
|
112
|
+
url: string;
|
|
113
|
+
method: string;
|
|
114
|
+
navigation: 'top' | 'frame' | null | undefined;
|
|
115
|
+
}): boolean;
|
|
116
|
+
/**
|
|
117
|
+
* The answer a paused token request gets, or null when the approved reply is not one to hand the frame:
|
|
118
|
+
* CyberSource's own page, byte for byte as the API stored it, with status 200 and the one content type
|
|
119
|
+
* CyberSource serves it with, and no other header. The page must pass payment-core's reply rule for the
|
|
120
|
+
* paused request (secureAcceptanceReplyOutcome: one hidden-input form posting to the receipt page the
|
|
121
|
+
* request signed, the request's own echoes, a masked number, a token, no card), run here with no card and
|
|
122
|
+
* no last four: the device and the API checked those.
|
|
123
|
+
*/
|
|
124
|
+
export declare function secureAcceptanceFrameAnswer(request: {
|
|
125
|
+
url: string;
|
|
126
|
+
body?: string | null;
|
|
127
|
+
}, response: {
|
|
128
|
+
status: number;
|
|
129
|
+
headers?: Record<string, string>;
|
|
130
|
+
body: string;
|
|
131
|
+
}): {
|
|
132
|
+
status: 200;
|
|
133
|
+
headers: Record<string, string>;
|
|
134
|
+
body: string;
|
|
135
|
+
} | null;
|
|
136
|
+
/**
|
|
137
|
+
* The request a reviewed merchant's page sends once its receipt page answered (Arrow: the payment-method
|
|
138
|
+
* set), for a production preparation whose profile id and origin an entry lists with one; null otherwise,
|
|
139
|
+
* the test host included. `entries` is for tests.
|
|
140
|
+
*/
|
|
141
|
+
export declare function secureAcceptanceFollowUp(preparation: {
|
|
142
|
+
environment: string;
|
|
143
|
+
secureAcceptanceProfileId?: string | null;
|
|
144
|
+
merchantOrigin: string;
|
|
145
|
+
}, entries?: readonly SecureAcceptanceMerchant[]): {
|
|
146
|
+
method: string;
|
|
147
|
+
url: string;
|
|
148
|
+
} | null;
|
|
149
|
+
/**
|
|
150
|
+
* The last four digits of the masked number CyberSource's reply page echoes (req_card_number, masked as
|
|
151
|
+
* x's and the last four), or null when the page carries no single such field. The page passed the reply
|
|
152
|
+
* rule before it was delivered, so this only reads it back for the follow-up event; it never carries more
|
|
153
|
+
* than those four digits.
|
|
154
|
+
*/
|
|
155
|
+
export declare function secureAcceptanceReplyLast4(page: string): string | null;
|
|
156
|
+
/**
|
|
157
|
+
* One attachment's watch for the merchant's follow-up request after a delivered reply. Read-only: it
|
|
158
|
+
* pauses, changes and delays nothing. The adapters report every request the page sends (CDP
|
|
159
|
+
* Network.requestWillBeSent, Playwright page.on('request')) through saw(); when none matches the
|
|
160
|
+
* merchant's follow-up within SECURE_ACCEPTANCE_FOLLOW_UP_MS, the event `secure_acceptance_reply_unused`
|
|
161
|
+
* names the authorization and the masked number's last four, so the agent can find the card the merchant
|
|
162
|
+
* may have kept (in its saved cards, ending in those four) before it ever asks for a new checkout.
|
|
163
|
+
*/
|
|
164
|
+
export declare class SecureAcceptanceFollowUpWatch {
|
|
165
|
+
private readonly onEvent?;
|
|
166
|
+
private readonly ms;
|
|
167
|
+
private watching;
|
|
168
|
+
constructor(onEvent?: ((event: {
|
|
169
|
+
type: string;
|
|
170
|
+
detail?: unknown;
|
|
171
|
+
}) => void) | undefined, ms?: number);
|
|
172
|
+
/** Start watching for `followUp` after the reply for `authorizationId` was delivered; a watch already running ends unreported. */
|
|
173
|
+
begin(followUp: {
|
|
174
|
+
method: string;
|
|
175
|
+
url: string;
|
|
176
|
+
}, detail: {
|
|
177
|
+
authorizationId: string;
|
|
178
|
+
last4: string | null;
|
|
179
|
+
}): void;
|
|
180
|
+
/** A request the page sent: the follow-up, when it is the one being watched for, ends the watch. */
|
|
181
|
+
saw(method: unknown, url: unknown): void;
|
|
182
|
+
/** True while a watch runs. */
|
|
183
|
+
get active(): boolean;
|
|
184
|
+
/** End the watch with no event. */
|
|
185
|
+
end(): void;
|
|
186
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
declare var SECURE_ACCEPTANCE_PSP: string;
|
|
2
|
+
declare var SECURE_ACCEPTANCE_CAPABILITY: string;
|
|
3
|
+
declare var SECURE_ACCEPTANCE_HOSTS: Readonly<{
|
|
4
|
+
production: "secureacceptance.cybersource.com";
|
|
5
|
+
sandbox: "testsecureacceptance.cybersource.com";
|
|
6
|
+
}>;
|
|
7
|
+
declare var SECURE_ACCEPTANCE_TOKEN_CREATE_PATH: string;
|
|
8
|
+
declare var SECURE_ACCEPTANCE_SIGNED_FIELDS: readonly string[];
|
|
9
|
+
declare var SECURE_ACCEPTANCE_OPTIONAL_SIGNED_FIELDS: readonly string[];
|
|
10
|
+
declare var SECURE_ACCEPTANCE_UNSIGNED_FIELDS: readonly string[];
|
|
11
|
+
declare var SECURE_ACCEPTANCE_OPTIONAL_UNSIGNED_FIELDS: readonly string[];
|
|
12
|
+
declare var SECURE_ACCEPTANCE_CARD_TYPES: Readonly<{
|
|
13
|
+
visa: "001";
|
|
14
|
+
mastercard: "002";
|
|
15
|
+
amex: "003";
|
|
16
|
+
discover: "004";
|
|
17
|
+
}>;
|
|
18
|
+
declare var SECURE_ACCEPTANCE_TEST_PANS: Readonly<Set<unknown>>;
|
|
19
|
+
declare var SECURE_ACCEPTANCE_REQUEST_REFUSALS: readonly string[];
|
|
20
|
+
declare var SECURE_ACCEPTANCE_REFUSAL_REASON_CODES: readonly string[];
|
|
21
|
+
declare var SECURE_ACCEPTANCE_REPLY_REASONS: readonly string[];
|
|
22
|
+
declare var SECURE_ACCEPTANCE_PAGE_CONTENT_TYPE: string;
|
|
23
|
+
declare var SECURE_ACCEPTANCE_MERCHANTS: any;
|
|
24
|
+
declare function secureAcceptanceEnvironment(hostname: any): "production" | "sandbox" | null;
|
|
25
|
+
declare function secureAcceptancePreparationUrl(environment: any): string;
|
|
26
|
+
declare function isSecureAcceptanceTokenRequest(url: any, method: any): boolean;
|
|
27
|
+
declare function secureAcceptanceRequestRefusal(request: any, options: any): "card_fields" | "profile_id" | "access_key" | "currency" | "signed_date_time" | "locale" | "origin_header" | "not_token_create" | "content_type" | "referer_header" | "body_unreadable" | "signed_fields_unreviewed" | "unsigned_fields_unreviewed" | "fields_unreviewed" | "transaction_type" | "amount_not_zero" | "payment_method" | "receipt_page" | "keeps_card" | "edits_saved_card" | "merchant_reference" | "card_type" | "bill_to" | "signature" | "request_ids" | "device_fingerprint" | null;
|
|
28
|
+
declare function secureAcceptanceRequestFacts(request: any): {
|
|
29
|
+
environment: string | null;
|
|
30
|
+
profileId: any;
|
|
31
|
+
accessKey: any;
|
|
32
|
+
transactionUuid: any;
|
|
33
|
+
referenceNumber: any;
|
|
34
|
+
currency: any;
|
|
35
|
+
signedDateTime: any;
|
|
36
|
+
} | null;
|
|
37
|
+
declare function isPreparedSecureAcceptanceRequest(url: any, method: any, body: any, headers: any, environment: any, binding: any): boolean;
|
|
38
|
+
declare function secureAcceptanceMerchantEntry(profileId: any, merchantOrigin: any, entries?: any): any;
|
|
39
|
+
declare function secureAcceptanceMerchantRefusal(environment: any, profileId: any, merchantOrigin: any, accessKey: any, entries?: any): "unsupported_environment" | "invalid_profile_id" | "secure_acceptance_merchant_unreviewed" | "secure_acceptance_merchant_pending" | "secure_acceptance_access_key_unreviewed" | "secure_acceptance_merchant_observe" | null;
|
|
40
|
+
declare function secureAcceptanceCardType(number: any): "001" | "002" | "003" | "004" | null;
|
|
41
|
+
declare function secureAcceptanceCardRefusal(environment: any, card: any): "unsupported_environment" | "sandbox_host_requires_documented_test_card" | "invalid_card_number" | "live_host_refuses_documented_test_card" | "card_network_unsupported" | "invalid_expiry" | "invalid_cvn" | null;
|
|
42
|
+
declare function isSecureAcceptanceDeviceRequest(templateBody: any, deviceBody: any, environment: any): boolean;
|
|
43
|
+
declare function secureAcceptanceDeviceRequest(request: any, card: any, options: any): {
|
|
44
|
+
url: any;
|
|
45
|
+
method: string;
|
|
46
|
+
headers: {
|
|
47
|
+
"content-type": string;
|
|
48
|
+
origin: string;
|
|
49
|
+
};
|
|
50
|
+
body: string;
|
|
51
|
+
where: string[];
|
|
52
|
+
};
|
|
53
|
+
declare function secureAcceptanceScannedPage(bodyText: any, template: any): any;
|
|
54
|
+
declare function secureAcceptanceReplyOutcome(reply: any, template: any, card: any, options: any): {
|
|
55
|
+
outcome: string;
|
|
56
|
+
reason: any;
|
|
57
|
+
} | {
|
|
58
|
+
outcome: string;
|
|
59
|
+
page: any;
|
|
60
|
+
code?: undefined;
|
|
61
|
+
} | {
|
|
62
|
+
outcome: string;
|
|
63
|
+
code: any;
|
|
64
|
+
page?: undefined;
|
|
65
|
+
};
|
|
66
|
+
declare function secureAcceptanceRefusalCode(bodyText: any): any;
|
|
67
|
+
export { SECURE_ACCEPTANCE_CAPABILITY, SECURE_ACCEPTANCE_CARD_TYPES, SECURE_ACCEPTANCE_HOSTS, SECURE_ACCEPTANCE_MERCHANTS, SECURE_ACCEPTANCE_OPTIONAL_SIGNED_FIELDS, SECURE_ACCEPTANCE_OPTIONAL_UNSIGNED_FIELDS, SECURE_ACCEPTANCE_PAGE_CONTENT_TYPE, SECURE_ACCEPTANCE_PSP, SECURE_ACCEPTANCE_REFUSAL_REASON_CODES, SECURE_ACCEPTANCE_REPLY_REASONS, SECURE_ACCEPTANCE_REQUEST_REFUSALS, SECURE_ACCEPTANCE_SIGNED_FIELDS, SECURE_ACCEPTANCE_TEST_PANS, SECURE_ACCEPTANCE_TOKEN_CREATE_PATH, SECURE_ACCEPTANCE_UNSIGNED_FIELDS, isPreparedSecureAcceptanceRequest, isSecureAcceptanceDeviceRequest, isSecureAcceptanceTokenRequest, secureAcceptanceCardRefusal, secureAcceptanceCardType, secureAcceptanceDeviceRequest, secureAcceptanceEnvironment, secureAcceptanceMerchantEntry, secureAcceptanceMerchantRefusal, secureAcceptancePreparationUrl, secureAcceptanceRefusalCode, secureAcceptanceReplyOutcome, secureAcceptanceRequestFacts, secureAcceptanceRequestRefusal, secureAcceptanceScannedPage };
|