@agent-cards/sdk 0.23.22 → 0.23.23
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 +22 -0
- package/README.md +27 -4
- package/dist/aci.generated.js +3 -3
- package/dist/agent-amount.generated.d.ts +7 -0
- package/dist/agent-amount.generated.js +3 -0
- package/dist/capabilities.generated.d.ts +2 -0
- package/dist/capabilities.generated.js +3 -0
- package/dist/card-fields.generated.js +1125 -24
- package/dist/cdp.js +50 -11
- package/dist/client.d.ts +59 -5
- package/dist/client.js +165 -116
- package/dist/hosted-entry.js +2 -1
- package/dist/hosted-form.d.ts +5 -0
- package/dist/hosted-form.js +5 -0
- package/dist/paytrail.d.ts +58 -0
- package/dist/paytrail.js +98 -0
- package/dist/pre-claim.d.ts +4 -0
- package/dist/pre-claim.js +46 -2
- package/dist/primer.generated.js +1153 -52
- package/dist/registry.d.ts +4 -3
- package/dist/registry.js +12 -4
- package/dist/sbps.d.ts +57 -0
- package/dist/sbps.generated.d.ts +96 -0
- package/dist/sbps.generated.js +427 -0
- package/dist/sbps.js +90 -0
- package/dist/stripe-checkout.generated.js +456 -7
- package/dist/transbank.d.ts +33 -0
- package/dist/transbank.js +62 -0
- package/dist/url-mask-parts.d.ts +24 -0
- package/dist/url-mask-parts.js +22 -0
- package/dist/url-masks.generated.d.ts +3 -0
- package/dist/url-masks.generated.js +2 -0
- package/package.json +4 -4
package/dist/paytrail.js
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Paytrail's card method (the Visa and Mastercard method on the payment wall most Finnish webshops send the buyer
|
|
3
|
+
* to), as this SDK reads it.
|
|
4
|
+
*
|
|
5
|
+
* The merchant's page, or Paytrail's own wall, posts a card-free entry top-level to
|
|
6
|
+
* https://services.paytrail.com/payments/<transaction>/click-to-pay/loading-and-redirect: seven fields Paytrail signed
|
|
7
|
+
* for the merchant, and no card and no amount. Paytrail answers with a loading page whose one form posts the same
|
|
8
|
+
* fields to .../click-to-pay/initialize-payment, which sends the browser to Payment Highway's card page
|
|
9
|
+
* (v1.api.paymenthighway.io, Paytrail's card platform) under a session of its own. The entry is the one request this
|
|
10
|
+
* SDK pauses: the cardholder's device repeats it over the end-to-end TLS relay and follows it to the card page
|
|
11
|
+
* (payment-core processors/paytrail.js). Everything after it in the agent's browser leads to the card the agent
|
|
12
|
+
* typed: the loading page's own post opens the card page, and on Payment Highway's host the card post (/card), the
|
|
13
|
+
* Click to Pay posts (/visa, /mastercard), the 3-D Secure step (/continue), the older card form's post and the card
|
|
14
|
+
* page's lookup of the typed card's first digits (GET .../acquirerData?bin=...). This SDK aborts every one of them,
|
|
15
|
+
* so a placeholder card never reaches Payment Highway.
|
|
16
|
+
*
|
|
17
|
+
* The hosts are payment-core's PAYTRAIL_HOSTS and PAYMENT_HIGHWAY_HOSTS; paytrail.test.mjs pins the lists together.
|
|
18
|
+
*/
|
|
19
|
+
export const PAYTRAIL_PSP = 'paytrail';
|
|
20
|
+
export const PAYTRAIL_HOSTS = Object.freeze(['services.paytrail.com']);
|
|
21
|
+
export const PAYMENT_HIGHWAY_HOSTS = Object.freeze(['v1.api.paymenthighway.io']);
|
|
22
|
+
const UUID = '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}';
|
|
23
|
+
const ENTRY_PATH = new RegExp(`^/payments/${UUID}/click-to-pay/loading-and-redirect$`);
|
|
24
|
+
// The card method's entry on a transaction no payment holds: the URL this build asks its registry about to learn
|
|
25
|
+
// whether the API serves Paytrail's recognizer, which takes any transaction (payment-core isPaytrailEntryUrl).
|
|
26
|
+
const ENTRY_PROBE = 'https://services.paytrail.com/payments/00000000-0000-4000-8000-000000000000/click-to-pay/loading-and-redirect';
|
|
27
|
+
function onHosts(url, hosts) {
|
|
28
|
+
let parsed;
|
|
29
|
+
try {
|
|
30
|
+
parsed = new URL(url);
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
return parsed.protocol === 'https:' && !parsed.username && !parsed.password
|
|
36
|
+
&& hosts.includes(parsed.hostname.toLowerCase().replace(/\.$/, '')) ? parsed : null;
|
|
37
|
+
}
|
|
38
|
+
/** Whether this URL is on Paytrail's entry host (https, no credentials, any port, a trailing dot or not). */
|
|
39
|
+
export function isPaytrailHost(url) {
|
|
40
|
+
return onHosts(url, PAYTRAIL_HOSTS) !== null;
|
|
41
|
+
}
|
|
42
|
+
/** Whether this URL is on Payment Highway's card page host (https, no credentials, any port, a trailing dot or not). */
|
|
43
|
+
export function isPaymentHighwayHost(url) {
|
|
44
|
+
return onHosts(url, PAYMENT_HIGHWAY_HOSTS) !== null;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* The only request that is the merchant's entry: a POST to the card method's loading-and-redirect route for one
|
|
48
|
+
* transaction, written exactly as the method's form action writes it, with the transaction in lowercase and no port,
|
|
49
|
+
* query, fragment or credentials (payment-core isPaytrailEntryUrl). The entry the SDK pauses; the gate aborts every
|
|
50
|
+
* other post of the card method.
|
|
51
|
+
*/
|
|
52
|
+
export function isPaytrailEntry(url, method) {
|
|
53
|
+
if (String(method).toUpperCase() !== 'POST' || typeof url !== 'string')
|
|
54
|
+
return false;
|
|
55
|
+
let parsed;
|
|
56
|
+
try {
|
|
57
|
+
parsed = new URL(url);
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
return parsed.protocol === 'https:' && PAYTRAIL_HOSTS.includes(parsed.hostname) && ENTRY_PATH.test(parsed.pathname)
|
|
63
|
+
&& !parsed.port && !parsed.username && !parsed.password && parsed.href === url && !/[?#]/.test(url);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Whether a request on Paytrail's host belongs to the card method (a /click-to-pay/ route of a payment, in any letter
|
|
67
|
+
* case): the entry, the loading page's post to initialize-payment, which opens Payment Highway's card page for the
|
|
68
|
+
* transaction, and any other spelling of either. Another method's form (a bank's) is not.
|
|
69
|
+
*/
|
|
70
|
+
export function isPaytrailCardMethodUrl(url) {
|
|
71
|
+
const parsed = onHosts(url, PAYTRAIL_HOSTS);
|
|
72
|
+
return parsed !== null && /^\/payments\/[^/]+\/click-to-pay(?:\/|$)/i.test(parsed.pathname);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* The card page's card lookup: a GET on Payment Highway's host to .../acquirerData, which names the first digits of
|
|
76
|
+
* the card typed so far in its `bin` query. Any other GET there (the card page itself, its scripts and images) is not
|
|
77
|
+
* a card request.
|
|
78
|
+
*/
|
|
79
|
+
export function isPaymentHighwayCardLookup(url, method) {
|
|
80
|
+
if (String(method).toUpperCase() !== 'GET')
|
|
81
|
+
return false;
|
|
82
|
+
const parsed = onHosts(url, PAYMENT_HIGHWAY_HOSTS);
|
|
83
|
+
return parsed !== null && (/\/acquirerData\/?$/i.test(parsed.pathname) || parsed.searchParams.has('bin'));
|
|
84
|
+
}
|
|
85
|
+
/** Whether this build's registry serves Paytrail's entry, asked with an entry on a transaction no payment holds. */
|
|
86
|
+
export function isPaytrailServed(vault) {
|
|
87
|
+
return vault.isCardRequest(ENTRY_PROBE, 'POST');
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Whether an adapter must hand this request to the pre-claim gates: it is on Paytrail's host or Payment Highway's, and
|
|
91
|
+
* this build's registry serves Paytrail's entry. The loading page's post and Payment Highway's card requests are not
|
|
92
|
+
* the entry, so the registry's card-request test does not name them; the CDP adapter still pauses them through the
|
|
93
|
+
* recognizer's host and its abort host, and attachToPlaywright's route predicate asks this, so both adapters show the
|
|
94
|
+
* gates every request to either host once Paytrail is armed.
|
|
95
|
+
*/
|
|
96
|
+
export function isArmedPaytrailUrl(vault, url) {
|
|
97
|
+
return (isPaytrailHost(url) || isPaymentHighwayHost(url)) && isPaytrailServed(vault);
|
|
98
|
+
}
|
package/dist/pre-claim.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ import { DatatransRepeats } from './datatrans.js';
|
|
|
5
5
|
import { TokenexIframeRepeats } from './tokenex-iframe.js';
|
|
6
6
|
import { type AciGate } from './aci.js';
|
|
7
7
|
import type { EprotectGate } from './eprotect.js';
|
|
8
|
+
import type { SbpsGate } from './sbps.js';
|
|
8
9
|
import { type ShijiStsCompanions } from './shiji-sts.js';
|
|
9
10
|
import type { CheckoutLifecycle } from './lifecycle.js';
|
|
10
11
|
import { type MerchantProfile } from './merchant-hosted.js';
|
|
@@ -148,6 +149,8 @@ export interface PreClaimContext {
|
|
|
148
149
|
replacesNavigationBody?: () => Promise<boolean>;
|
|
149
150
|
/** Worldpay eProtect's hosts; absent or inert until the registry serves eProtect. */
|
|
150
151
|
eprotect?: EprotectGate;
|
|
152
|
+
/** SB Payment Service's token hosts; absent or inert until the registry serves SBPS. */
|
|
153
|
+
sbps?: SbpsGate;
|
|
151
154
|
readDocumentUrl: () => Promise<string>;
|
|
152
155
|
lifecycle: CheckoutLifecycle;
|
|
153
156
|
/**
|
|
@@ -278,6 +281,7 @@ export declare function isArmedCreditguardCall(vault: {
|
|
|
278
281
|
export declare const przelewy24PreClaim: PreClaimGate;
|
|
279
282
|
export declare const ekashuPreClaim: PreClaimGate;
|
|
280
283
|
export declare const transbankPreClaim: PreClaimGate;
|
|
284
|
+
export declare const paytrailPreClaim: PreClaimGate;
|
|
281
285
|
export declare const redsysPreClaim: PreClaimGate;
|
|
282
286
|
export declare const quickpayPreClaim: PreClaimGate;
|
|
283
287
|
export declare const comgatePreClaim: PreClaimGate;
|
package/dist/pre-claim.js
CHANGED
|
@@ -80,6 +80,7 @@ import { cardEndpointCarriesCard, cardEndpointDetail, cardEndpointFor, cardEndpo
|
|
|
80
80
|
import { cardEndpointStoppedPage, refusedNavigationOutcome } from './card-endpoint-page.js';
|
|
81
81
|
import { PAYRAILS_HOLDING_REASONS, PAYRAILS_SESSION_MESSAGE, isPayrailsHost, isPayrailsPaymentUrl, isPayrailsStaticHost, payrailsKeyRefusal, payrailsPaymentRefusal, payrailsRequestKind, payrailsSaveRefusal, } from './payrails.js';
|
|
82
82
|
import { classifyVerifoneProfileRequest, verifoneTemplatedUrl } from './verifone.js';
|
|
83
|
+
import { isPaymentHighwayCardLookup, isPaymentHighwayHost, isPaytrailCardMethodUrl, isPaytrailEntry, isPaytrailServed } from './paytrail.js';
|
|
83
84
|
import { ekashuEntryUrl, isEkashuEntry, isEkashuHost } from './ekashu.js';
|
|
84
85
|
import { isArmedTransbankUrl } from './transbank.js';
|
|
85
86
|
import { isRedsysEntry, isRedsysHost, redsysEntryUrl } from './redsys.js';
|
|
@@ -1509,6 +1510,23 @@ const eprotectPreClaim = (ctx) => {
|
|
|
1509
1510
|
return eprotectFailoverAbort(ctx);
|
|
1510
1511
|
return unsupportedAbort(ctx);
|
|
1511
1512
|
};
|
|
1513
|
+
// SB Payment Service, once the registry serves it (a synced build that declares its capability, for
|
|
1514
|
+
// an org the API enabled); for every other client the gate defers on everything, so nothing changes.
|
|
1515
|
+
// On SBPS's token hosts:
|
|
1516
|
+
// - the token request GET the recognizer admits defers to the arbiter, which pauses it for the vault
|
|
1517
|
+
// claim flow; one the registry does not cover aborts as unsupported instead of reaching SBPS;
|
|
1518
|
+
// - any other request on /token/generateToken (another method, query or spelling) aborts as an
|
|
1519
|
+
// unsupported checkout, so the placeholder's ciphertext never leaves;
|
|
1520
|
+
// - everything else there (the scripts, the 3-D Secure info request) continues.
|
|
1521
|
+
// Synchronous for a token request, so it pauses in the microtask it paused in.
|
|
1522
|
+
const sbpsPreClaim = (ctx) => {
|
|
1523
|
+
const request = ctx.sbps?.classify(ctx.request.url, ctx.request.method);
|
|
1524
|
+
if (!request || request.kind === 'sibling')
|
|
1525
|
+
return undefined;
|
|
1526
|
+
if (request.kind === 'token_request')
|
|
1527
|
+
return ctx.vault.isCardRequest(ctx.request.url, ctx.request.method) ? undefined : unsupportedAbort(ctx);
|
|
1528
|
+
return unsupportedAbort(ctx);
|
|
1529
|
+
};
|
|
1512
1530
|
async function eprotectFailoverAbort(ctx) {
|
|
1513
1531
|
ctx.onEvent?.({ type: 'blocked', detail: 'eprotect_failover_aborted' });
|
|
1514
1532
|
await ctx.effects.abort();
|
|
@@ -1699,6 +1717,32 @@ export const transbankPreClaim = (ctx) => {
|
|
|
1699
1717
|
return undefined;
|
|
1700
1718
|
return processorPageAbort(ctx);
|
|
1701
1719
|
};
|
|
1720
|
+
// Paytrail's card method (paytrail.ts). Once this build's registry serves Paytrail's entry (a capability the API serves
|
|
1721
|
+
// only to a company Agentcard turned Paytrail on for), every request to Paytrail's entry host and to Payment Highway's
|
|
1722
|
+
// card page host pauses, and this gate judges the card method's posts and the card page's card lookup:
|
|
1723
|
+
// - the merchant's entry (the card method's loading-and-redirect route for one transaction, exactly) defers, and the
|
|
1724
|
+
// terminal arbiter pauses it for the claim flow like any card request: the cardholder's device pays it;
|
|
1725
|
+
// - every other post of the card method on Paytrail's host (the loading page's post to initialize-payment, which
|
|
1726
|
+
// opens Payment Highway's card page, or the entry in another spelling) aborts as an unsupported checkout, and so do
|
|
1727
|
+
// every POST to Payment Highway (the card post, the Click to Pay posts, the 3-D Secure step, the older card form's
|
|
1728
|
+
// post) and the card page's GET that looks up the typed card's first digits, so Payment Highway never sees the card
|
|
1729
|
+
// the agent typed. The agent's browser reaches Payment Highway only when the entry was not paused (an attachment
|
|
1730
|
+
// made too late, say), and then only the cardholder's device can pay.
|
|
1731
|
+
// Any other request (another payment method's form, the card page itself, its scripts and images) is not this gate's
|
|
1732
|
+
// and continues. With Paytrail not served, the entry is no card request, the gate defers, and every request continues
|
|
1733
|
+
// as before. Synchronous until it must abort, like every gate. Exported for the gate registry's tests.
|
|
1734
|
+
export const paytrailPreClaim = (ctx) => {
|
|
1735
|
+
const { url, method } = ctx.request;
|
|
1736
|
+
const post = String(method).toUpperCase() === 'POST';
|
|
1737
|
+
const paymentHighway = isPaymentHighwayHost(url) && (post || isPaymentHighwayCardLookup(url, method));
|
|
1738
|
+
if (!paymentHighway && !(post && isPaytrailCardMethodUrl(url)))
|
|
1739
|
+
return undefined;
|
|
1740
|
+
if (!isPaytrailServed(ctx.vault))
|
|
1741
|
+
return undefined;
|
|
1742
|
+
if (isPaytrailEntry(url, method))
|
|
1743
|
+
return undefined;
|
|
1744
|
+
return processorPageAbort(ctx);
|
|
1745
|
+
};
|
|
1702
1746
|
// Redsys's hosted payment page (redsys.ts). Once this build's registry serves Redsys's entry (a
|
|
1703
1747
|
// capability the API serves only to a company Agentcard turned Redsys on for), every request to
|
|
1704
1748
|
// Redsys's hosts pauses, and this gate judges the POSTs:
|
|
@@ -2438,8 +2482,8 @@ async function unsupportedContinue(ctx) {
|
|
|
2438
2482
|
* arbiter runs after all of them and is not part of this list. A gate appended
|
|
2439
2483
|
* after Stripe is never offered a step Stripe claimed: Stripe answers, aborts or
|
|
2440
2484
|
* pauses each one itself. */
|
|
2441
|
-
export const PSP_PRE_CLAIM_GATES = [cardEndpointResendPreClaim, cardEndpointPreClaim, mercadoPreClaim, juspayPreClaim, braintreePreClaim, stripePreClaim, merchantHostedPreClaim, verifonePreClaim, fiservPreClaim, gmoPreClaim, cybersourceFlexPreClaim, datatransPreClaim, tokenexIframePreClaim, pelecardPreClaim, aciPreClaim, creditguardPreClaim, primerPreClaim, payrailsPreClaim, convergePreClaim, eprotectPreClaim, wspayPreClaim, shijiStsPreClaim, ekashuPreClaim, redsysPreClaim, quickpayPreClaim, comgatePreClaim, przelewy24PreClaim, transbankPreClaim, eximbayPreClaim, paypalHostedFieldsPreClaim,
|
|
2442
|
-
paypalCardFormsPreClaim, cybersourceSecureAcceptancePreClaim, worldlineMyCheckoutPreClaim, paddleVgsPayPreClaim, ebanxPreClaim, payrexxPreClaim, hipayPreClaim];
|
|
2485
|
+
export const PSP_PRE_CLAIM_GATES = [cardEndpointResendPreClaim, cardEndpointPreClaim, mercadoPreClaim, juspayPreClaim, braintreePreClaim, stripePreClaim, merchantHostedPreClaim, verifonePreClaim, fiservPreClaim, gmoPreClaim, cybersourceFlexPreClaim, datatransPreClaim, tokenexIframePreClaim, pelecardPreClaim, aciPreClaim, creditguardPreClaim, primerPreClaim, payrailsPreClaim, convergePreClaim, eprotectPreClaim, sbpsPreClaim, wspayPreClaim, shijiStsPreClaim, ekashuPreClaim, redsysPreClaim, quickpayPreClaim, comgatePreClaim, przelewy24PreClaim, transbankPreClaim, eximbayPreClaim, paypalHostedFieldsPreClaim,
|
|
2486
|
+
paypalCardFormsPreClaim, cybersourceSecureAcceptancePreClaim, worldlineMyCheckoutPreClaim, paddleVgsPayPreClaim, ebanxPreClaim, payrexxPreClaim, hipayPreClaim, paytrailPreClaim];
|
|
2443
2487
|
/** Run each gate in order; the first to return a decision wins. If none does,
|
|
2444
2488
|
* the terminal arbiter decides between continue, abort (unsupported) and pause.
|
|
2445
2489
|
* Returns synchronously while every gate defers synchronously (an ordinary card
|