@agent-cards/sdk 0.23.7 → 0.23.9

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 CHANGED
@@ -2,6 +2,10 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ - Hand Arrow Electronics' token page to its frame when CyberSource's payment token is numeric. CyberSource gives a merchant set up before 2019 a `payment_token` of 22, 19 or 16 digits, and 0.23.8 judged every token but 32 hex characters as `token_shape`, so an approved Arrow save on 2026-10-10 ended `outcome_unknown` (`secure_acceptance_reply_late`) although CyberSource had answered it. The reply rule now takes each format CyberSource documents; a token of any other length or alphabet still reads `token_shape`. The card-free check skips a numeric token as it skips the instrument identifier, because CyberSource's 16- and 19-digit formats pass the card check digit; the device, which holds the card, still refuses a token equal to the card's number. A payment also needs the matching API and Vault releases.
6
+
7
+ - Pay Arrow Electronics' card save as its live checkout signs it. Arrow's server adds an id of its own, `merchant_defined_data8` (digits), to the form and to the end of `unsigned_field_names` when it signs the save, and 0.23.7 refused that request with `secure_acceptance_unsigned_fields_unreviewed` on 2026-10-10, after the cardholder approved and before any card was sent. The request now passes with that field or without it; a list that names it anywhere but last, names it twice or posts it unlisted is still refused, and a value other than at most 20 digits is refused as `secure_acceptance_merchant_reference`. Nothing else about Arrow's lists changed. A payment also needs the matching API and Vault releases.
8
+
5
9
  - Pause a Worldpay eProtect registration whatever Worldpay key its page names. Worldpay rotates its production eProtect key daily (`26457000011` on 2026-10-08), and 0.23.3 refused every registration whose `publicKeyId` was not `26455500012`, the key it shipped, so an attached checkout at any eProtect merchant read `unsupported`. The SDK now takes any key id in Worldpay's digits; the cardholder's device encrypts the card under the key it reads from Worldpay's own `eProtect-api3.js` and writes that key's id into its copy, so no later rotation needs an SDK release. SmartPak Equine (paypageId `zhs8KzuRAryaq4cs` at `https://www.smartpakequine.com`) and Nordstrom (`fL33BPkRvbRqJ29S` at `https://www.nordstrom.com`) are reviewed eProtect merchants: a live checkout there passes `merchant: 'SmartPak Equine'` or `merchant: 'Nordstrom'` exactly, and `prepare()` refuses another name with `merchant_profile_mismatch` before any network call. eProtect stays dark for every org Agentcard has not enabled, and a payment also needs the matching API and Vault releases.
6
10
 
7
11
  - Pay Arrow Electronics through the CyberSource Secure Acceptance lane, for a company Agentcard turned the lane on for. Arrow's reviewed entry, `arrow_token_create`, now ships enabled and pins the profile id and access key Arrow's checkout at `https://www.arrow.com` sends, read from Arrow's public page model. `prepare({ psp: 'cybersource_secure_acceptance', environment: 'production' })` at that page fills Arrow's profile id and needs `merchant: 'Arrow Electronics'`, or it fails with `merchant_profile_mismatch` before any call. Once CyberSource's page reaches Arrow's receipt, the SDK watches 10 seconds for Arrow's payment method request and emits `secure_acceptance_reply_unused` when none comes. The API still refuses any other profile id, access key or page on the production host (`unsupported_checkout`), and every company Agentcard has not turned the lane on for keeps the stop.
@@ -8,6 +8,7 @@ declare var SECURE_ACCEPTANCE_TOKEN_CREATE_PATH: string;
8
8
  declare var SECURE_ACCEPTANCE_SIGNED_FIELDS: readonly string[];
9
9
  declare var SECURE_ACCEPTANCE_OPTIONAL_SIGNED_FIELDS: readonly string[];
10
10
  declare var SECURE_ACCEPTANCE_UNSIGNED_FIELDS: readonly string[];
11
+ declare var SECURE_ACCEPTANCE_OPTIONAL_UNSIGNED_FIELDS: readonly string[];
11
12
  declare var SECURE_ACCEPTANCE_CARD_TYPES: Readonly<{
12
13
  visa: "001";
13
14
  mastercard: "002";
@@ -23,7 +24,7 @@ declare var SECURE_ACCEPTANCE_MERCHANTS: any;
23
24
  declare function secureAcceptanceEnvironment(hostname: any): "production" | "sandbox" | null;
24
25
  declare function secureAcceptancePreparationUrl(environment: any): string;
25
26
  declare function isSecureAcceptanceTokenRequest(url: any, method: any): boolean;
26
- 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" | "card_type" | "bill_to" | "signature" | "request_ids" | "device_fingerprint" | null;
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;
27
28
  declare function secureAcceptanceRequestFacts(request: any): {
28
29
  environment: string | null;
29
30
  profileId: any;
@@ -63,4 +64,4 @@ declare function secureAcceptanceReplyOutcome(reply: any, template: any, card: a
63
64
  page?: undefined;
64
65
  };
65
66
  declare function secureAcceptanceRefusalCode(bodyText: any): any;
66
- export { SECURE_ACCEPTANCE_CAPABILITY, SECURE_ACCEPTANCE_CARD_TYPES, SECURE_ACCEPTANCE_HOSTS, SECURE_ACCEPTANCE_MERCHANTS, SECURE_ACCEPTANCE_OPTIONAL_SIGNED_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 };
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 };
@@ -1,6 +1,6 @@
1
1
  // @ts-nocheck
2
2
  // Generated from @agent-cards/payment-core. Do not edit.
3
- // artifact-sha256: bd26046b49ee14791e119bd7d6c8ebf370940ee2371099e13582566579c485d5
3
+ // artifact-sha256: 9151ab8e96dace64217197a15a2eb2083d454faca475564b96ddcabb2100fa0f
4
4
  // src/deep-freeze.js
5
5
  function deepFreeze(value) {
6
6
  if (value && typeof value === "object" && !Object.isFrozen(value)) {
@@ -67,6 +67,7 @@ var SECURE_ACCEPTANCE_UNSIGNED_FIELDS = /* @__PURE__ */ Object.freeze([
67
67
  "bill_to_address_line2",
68
68
  "card_cvn"
69
69
  ]);
70
+ var SECURE_ACCEPTANCE_OPTIONAL_UNSIGNED_FIELDS = /* @__PURE__ */ Object.freeze(["merchant_defined_data8"]);
70
71
  var SECURE_ACCEPTANCE_CARD_TYPES = /* @__PURE__ */ Object.freeze({ visa: "001", mastercard: "002", amex: "003", discover: "004" });
71
72
  var SECURE_ACCEPTANCE_TEST_PANS = /* @__PURE__ */ immutableSet([
72
73
  "4111111111111111",
@@ -102,6 +103,7 @@ var SECURE_ACCEPTANCE_REQUEST_REFUSALS = /* @__PURE__ */ Object.freeze([
102
103
  "receipt_page",
103
104
  "keeps_card",
104
105
  "edits_saved_card",
106
+ "merchant_reference",
105
107
  "card_type",
106
108
  "card_fields",
107
109
  "bill_to",
@@ -156,6 +158,8 @@ var SA_REQUEST_ID = /^[A-Za-z0-9-]{1,50}$/;
156
158
  var SA_SIGNED_DATE_TIME = /^[0-9]{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12][0-9]|3[01])T(?:[01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]Z$/;
157
159
  var SA_SIGNATURE = /^[A-Za-z0-9+/]{43}=$/;
158
160
  var SA_DEVICE_FINGERPRINT = /^[A-Za-z0-9_.:-]{1,88}$/;
161
+ var SA_MERCHANT_REFERENCE = /^[0-9]{0,20}$/;
162
+ var SA_PAYMENT_TOKEN = /^(?:[0-9A-Fa-f]{32}|[0-9]{22}|[0-9]{19}|[0-9]{16})$/;
159
163
  var SA_EXPIRY = /^(?:0[1-9]|1[0-2])-[0-9]{4}$/;
160
164
  var saExact = (pattern, value) => typeof value === "string" && pattern.exec(value)?.[0] === value;
161
165
  var saControlFree = (value, min, max) => typeof value === "string" && value.length >= min && value.length <= max && !/[\u0000-\u001f\u007f]/.test(value);
@@ -232,13 +236,19 @@ function saSignedListAllowed(value) {
232
236
  const [state, postal] = SECURE_ACCEPTANCE_OPTIONAL_SIGNED_FIELDS;
233
237
  return [base, `${base},${state}`, `${base},${postal}`, `${base},${state},${postal}`].includes(value);
234
238
  }
239
+ function saUnsignedListAllowed(value) {
240
+ const base = SECURE_ACCEPTANCE_UNSIGNED_FIELDS.join(",");
241
+ const [reference] = SECURE_ACCEPTANCE_OPTIONAL_UNSIGNED_FIELDS;
242
+ return value === base || value === `${base},${reference}`;
243
+ }
235
244
  function saFieldListRefusal(form) {
236
245
  const signed = form.values.get("signed_field_names");
237
246
  if (!saSignedListAllowed(signed))
238
247
  return "signed_fields_unreviewed";
239
- if (form.values.get("unsigned_field_names") !== SECURE_ACCEPTANCE_UNSIGNED_FIELDS.join(","))
248
+ const unsigned = form.values.get("unsigned_field_names");
249
+ if (!saUnsignedListAllowed(unsigned))
240
250
  return "unsigned_fields_unreviewed";
241
- const expected = /* @__PURE__ */ new Set([...signed.split(","), ...SECURE_ACCEPTANCE_UNSIGNED_FIELDS, "signature"]);
251
+ const expected = /* @__PURE__ */ new Set([...signed.split(","), ...unsigned.split(","), "signature"]);
242
252
  if (form.pairs.length !== expected.size || form.pairs.some(({ name }) => !expected.has(name)))
243
253
  return "fields_unreviewed";
244
254
  return null;
@@ -360,6 +370,8 @@ function secureAcceptanceRequestRefusal(request, options) {
360
370
  return "keeps_card";
361
371
  if (v("merchant_defined_data7") !== "")
362
372
  return "edits_saved_card";
373
+ if (form.values.has("merchant_defined_data8") && !saExact(SA_MERCHANT_REFERENCE, v("merchant_defined_data8")))
374
+ return "merchant_reference";
363
375
  if (!SA_CARD_VALUES.get("card_type")(v("card_type")))
364
376
  return "card_type";
365
377
  if (!["card_number", "card_expiry_date", "card_cvn"].every((name) => SA_CARD_VALUES.get(name)(v(name))))
@@ -760,7 +772,7 @@ function saTemplateFields(template) {
760
772
  }
761
773
  var SA_SCRUBBED = /* @__PURE__ */ new Map([
762
774
  ["signature", SA_SIGNATURE],
763
- ["payment_token", /^[0-9A-Fa-f]{32}$/],
775
+ ["payment_token", SA_PAYMENT_TOKEN],
764
776
  ["transaction_id", /^[0-9]{22}$/],
765
777
  ["request_token", /^[A-Za-z0-9+/]{16,512}={0,2}$/],
766
778
  ["payment_token_instrument_identifier_id", /^[0-9]{12,32}$/],
@@ -899,7 +911,7 @@ function secureAcceptanceReplyOutcome(reply, template, card, options) {
899
911
  return unknown("reply_fields");
900
912
  if (SA_MATCHED_ECHOES.some((name) => fields.has(`req_${name}`) && value(`req_${name}`) !== sent.values.get(name)))
901
913
  return unknown("reply_mismatch");
902
- if (!saExact(/^[0-9]{22}$/, value("transaction_id")) || fields.has("payment_token") && !saExact(/^[0-9A-Fa-f]{32}$/, value("payment_token"))) {
914
+ if (!saExact(/^[0-9]{22}$/, value("transaction_id")) || fields.has("payment_token") && !saExact(SA_PAYMENT_TOKEN, value("payment_token"))) {
903
915
  return unknown("token_shape");
904
916
  }
905
917
  const masked = value("req_card_number");
@@ -952,4 +964,4 @@ function secureAcceptanceRefusalCode(bodyText) {
952
964
  const code = page.fields.get("reason_code")?.value;
953
965
  return (decision === "DECLINE" || decision === "ERROR") && saExact(/^[0-9]{3}$/, code) ? code : null;
954
966
  }
955
- export { SECURE_ACCEPTANCE_CAPABILITY, SECURE_ACCEPTANCE_CARD_TYPES, SECURE_ACCEPTANCE_HOSTS, SECURE_ACCEPTANCE_MERCHANTS, SECURE_ACCEPTANCE_OPTIONAL_SIGNED_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 };
967
+ 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 };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-cards/sdk",
3
- "version": "0.23.7",
3
+ "version": "0.23.9",
4
4
  "description": "Agentcard's SDK: one client, Agentcard, with two modules. checkout pauses a browser purchase and pays it with the person's own card; voice connects a person to your product once and approves a purchase by voice inside it. Card data never enters your process.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",