@agent-cards/sdk 0.23.7 → 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 CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ - 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.
6
+
5
7
  - 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
8
 
7
9
  - 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: 199c6a2402490c7085006c35fe525da2bcd7e99867170b09b5ad3c8caf8194fb
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,7 @@ 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}$/;
159
162
  var SA_EXPIRY = /^(?:0[1-9]|1[0-2])-[0-9]{4}$/;
160
163
  var saExact = (pattern, value) => typeof value === "string" && pattern.exec(value)?.[0] === value;
161
164
  var saControlFree = (value, min, max) => typeof value === "string" && value.length >= min && value.length <= max && !/[\u0000-\u001f\u007f]/.test(value);
@@ -232,13 +235,19 @@ function saSignedListAllowed(value) {
232
235
  const [state, postal] = SECURE_ACCEPTANCE_OPTIONAL_SIGNED_FIELDS;
233
236
  return [base, `${base},${state}`, `${base},${postal}`, `${base},${state},${postal}`].includes(value);
234
237
  }
238
+ function saUnsignedListAllowed(value) {
239
+ const base = SECURE_ACCEPTANCE_UNSIGNED_FIELDS.join(",");
240
+ const [reference] = SECURE_ACCEPTANCE_OPTIONAL_UNSIGNED_FIELDS;
241
+ return value === base || value === `${base},${reference}`;
242
+ }
235
243
  function saFieldListRefusal(form) {
236
244
  const signed = form.values.get("signed_field_names");
237
245
  if (!saSignedListAllowed(signed))
238
246
  return "signed_fields_unreviewed";
239
- if (form.values.get("unsigned_field_names") !== SECURE_ACCEPTANCE_UNSIGNED_FIELDS.join(","))
247
+ const unsigned = form.values.get("unsigned_field_names");
248
+ if (!saUnsignedListAllowed(unsigned))
240
249
  return "unsigned_fields_unreviewed";
241
- const expected = /* @__PURE__ */ new Set([...signed.split(","), ...SECURE_ACCEPTANCE_UNSIGNED_FIELDS, "signature"]);
250
+ const expected = /* @__PURE__ */ new Set([...signed.split(","), ...unsigned.split(","), "signature"]);
242
251
  if (form.pairs.length !== expected.size || form.pairs.some(({ name }) => !expected.has(name)))
243
252
  return "fields_unreviewed";
244
253
  return null;
@@ -360,6 +369,8 @@ function secureAcceptanceRequestRefusal(request, options) {
360
369
  return "keeps_card";
361
370
  if (v("merchant_defined_data7") !== "")
362
371
  return "edits_saved_card";
372
+ if (form.values.has("merchant_defined_data8") && !saExact(SA_MERCHANT_REFERENCE, v("merchant_defined_data8")))
373
+ return "merchant_reference";
363
374
  if (!SA_CARD_VALUES.get("card_type")(v("card_type")))
364
375
  return "card_type";
365
376
  if (!["card_number", "card_expiry_date", "card_cvn"].every((name) => SA_CARD_VALUES.get(name)(v(name))))
@@ -952,4 +963,4 @@ function secureAcceptanceRefusalCode(bodyText) {
952
963
  const code = page.fields.get("reason_code")?.value;
953
964
  return (decision === "DECLINE" || decision === "ERROR") && saExact(/^[0-9]{3}$/, code) ? code : null;
954
965
  }
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 };
966
+ 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.8",
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",