@agent-cards/sdk 0.23.8 → 0.23.10

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.
Files changed (59) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/PREFLIGHT.md +7 -5
  3. package/README.md +181 -92
  4. package/dist/aci.d.ts +7 -5
  5. package/dist/aci.generated.d.ts +2 -1
  6. package/dist/aci.generated.js +14 -4
  7. package/dist/aci.js +28 -7
  8. package/dist/amadeus-checkout.generated.js +2 -2
  9. package/dist/builtin-registry.generated.js +1 -1
  10. package/dist/card-fields.generated.js +163 -9
  11. package/dist/cdp.js +79 -34
  12. package/dist/client.d.ts +61 -31
  13. package/dist/client.js +99 -42
  14. package/dist/creditguard.generated.d.ts +1 -1
  15. package/dist/creditguard.generated.js +1 -3
  16. package/dist/cse-body.d.ts +7 -6
  17. package/dist/cse-body.js +8 -7
  18. package/dist/cybersource-secure-acceptance.generated.js +4 -3
  19. package/dist/datatrans.generated.js +8 -5
  20. package/dist/elavon-converge.d.ts +1 -1
  21. package/dist/elavon-converge.generated.js +7 -4
  22. package/dist/elavon-converge.js +4 -3
  23. package/dist/fiserv.d.ts +9 -5
  24. package/dist/fiserv.generated.d.ts +3 -3
  25. package/dist/fiserv.generated.js +50 -20
  26. package/dist/fiserv.js +10 -6
  27. package/dist/payrails.d.ts +78 -18
  28. package/dist/payrails.generated.d.ts +12 -2
  29. package/dist/payrails.generated.js +213 -18
  30. package/dist/payrails.js +165 -44
  31. package/dist/pre-claim.js +51 -29
  32. package/dist/preflight-capabilities.generated.d.ts +0 -106
  33. package/dist/preflight-capabilities.generated.js +0 -153
  34. package/dist/preflight-catalog.json +61 -181
  35. package/dist/preflight-schemas.json +6 -6
  36. package/dist/preflight.generated.d.ts +0 -106
  37. package/dist/preflight.generated.js +27 -15
  38. package/dist/preparation.d.ts +2 -0
  39. package/dist/preparation.js +4 -2
  40. package/dist/prepared-processor.d.ts +19 -5
  41. package/dist/prepared-processor.js +21 -5
  42. package/dist/primer.generated.d.ts +5 -1
  43. package/dist/primer.generated.js +200 -33
  44. package/dist/registry.d.ts +18 -12
  45. package/dist/registry.js +11 -8
  46. package/dist/shiji-sts.d.ts +24 -22
  47. package/dist/shiji-sts.generated.d.ts +1 -1
  48. package/dist/shiji-sts.generated.js +12 -8
  49. package/dist/shiji-sts.js +49 -46
  50. package/dist/stripe-checkout.generated.js +146 -49
  51. package/dist/verifone.generated.js +192 -17
  52. package/dist/verifone.js +1 -1
  53. package/dist/wspay.d.ts +17 -16
  54. package/dist/wspay.generated.d.ts +6 -1
  55. package/dist/wspay.generated.js +13 -3
  56. package/dist/wspay.js +9 -11
  57. package/examples/preflight/kernel-native/README.md +1 -1
  58. package/examples/preflight/kernel-native/inventory.json +1 -19
  59. package/package.json +3 -3
@@ -1,6 +1,6 @@
1
1
  // @ts-nocheck
2
2
  // Generated from @agent-cards/payment-core. Do not edit.
3
- // artifact-sha256: ae602a804a759165b26cb804547bdc99792036a22cc355a6dba49cfb11e92897
3
+ // artifact-sha256: 57dffa8575e71c819c694d818e272c955303add0ed4b083d69bab1606cd6150f
4
4
  // src/deep-freeze.js
5
5
  function deepFreeze(value) {
6
6
  if (value && typeof value === "object" && !Object.isFrozen(value)) {
@@ -169,15 +169,49 @@ var PROCESSOR_DEFINITIONS = deepFreeze([
169
169
  // supplier (the terminal) + benid (the iframe session) + the amount:
170
170
  // one submission, whatever nonce the form regenerated on a re-click.
171
171
  dedupe: ["supplier", "benid", "sum", "currency"],
172
+ // Tranzila's servers are PHP (PHPSESSID on direct, CodeIgniter's
173
+ // ci_session on directng): of a field posted twice they act on the last
174
+ // copy, and they read `cred.type` as cred_type and `sum[]` as sum. Every
175
+ // rule here reads the first copy under the name as written, so such a
176
+ // form is refused before them (backend.js phpFormKeyRefusal).
177
+ serverKeys: "php",
172
178
  // One plain sale, reporting to the merchant the person sees: tranmode
173
179
  // A (or absent) only (V verifies, K charges a token, C refunds, D
174
180
  // forces), no TranzilaTK in either direction (`1` asks for a reusable
175
- // token back, a token charges one), and every *_url_address on the
176
- // merchant's host (Tranzila redirects the device there and POSTs the
177
- // result there with the card's last four, expiry and ID number).
181
+ // token back, a token charges one), and every callback URL on the
182
+ // merchant's host or on Tranzila's own result page (Tranzila redirects
183
+ // the device there and POSTs the result there with the card's last
184
+ // four, expiry and ID number).
178
185
  sale: { key: "tranmode", values: ["A"] },
179
186
  token: "TranzilaTK",
180
- callbackUrls: ["success_url_address", "fail_url_address", "notify_url_address"]
187
+ // One charge, never a plan: cred_type 1 (one payment, Tranzila's
188
+ // default; 6 is credit installments, 8 installments), tash 1 (a
189
+ // merchant page posts it beside cred_type 8 as the installment count,
190
+ // and Tranzila copies both into its card form: Mehubarim La'am's
191
+ // donation page, 2026-10-10), npay 0 (payments after the first), no
192
+ // installment amounts, and no My Billing recurring charge (recur_*, and
193
+ // the legacy page's make_recur_transaction box). A value outside a key's
194
+ // list is refused as special_flow; an empty list takes no value at all.
195
+ singleCharge: {
196
+ cred_type: ["1"],
197
+ tash: ["1"],
198
+ npay: ["0"],
199
+ fpay: [],
200
+ spay: [],
201
+ recur_transaction: [],
202
+ recur_sum: [],
203
+ recur_payments: [],
204
+ recur_start_date: [],
205
+ make_recur_transaction: []
206
+ },
207
+ // The merchant posts success_url_address, fail_url_address and
208
+ // notify_url_address to iframenew.php, and Tranzila's own card form, on
209
+ // both hosts, carries them as success_url, fail_url and notify_url.
210
+ callbackUrls: ["success_url_address", "fail_url_address", "notify_url_address", "success_url", "fail_url", "notify_url"],
211
+ // The result page Tranzila's card form names when the terminal set no
212
+ // return URL of its own (read on both hosts on 2026-10-10): the result
213
+ // goes back to Tranzila, which already holds it. Matched exactly.
214
+ processorResultUrls: ["https://direct.tranzila.com/done/", "https://directng.tranzila.com/process/fail"]
181
215
  }
182
216
  },
183
217
  {
@@ -187,7 +221,7 @@ var PROCESSOR_DEFINITIONS = deepFreeze([
187
221
  // The merchant's page posts an ENTRY form top-level to live.ekashu.com/ (test:
188
222
  // test.ekashu.com/) with the amount, the result URLs and a SHA256HMAC over them (hash
189
223
  // code 2.0.0), and no card. NMI answers with its own card page under an HttpOnly session
190
- // cookie and an anti-forgery token, so a card form rebuilt away from that session is
224
+ // cookie and session fields of its own, so a card form rebuilt away from that session is
191
225
  // refused by NMI (processors/ekashu.js has the recorded shapes). The paused request is
192
226
  // therefore the entry, a Document navigation that carries no card: the cardholder's
193
227
  // device repeats it over the end-to-end TLS relay, fills the card into the page NMI
@@ -207,11 +241,20 @@ var PROCESSOR_DEFINITIONS = deepFreeze([
207
241
  encoding: "form",
208
242
  passthroughHeaders: [],
209
243
  mode: "hosted_form",
244
+ // NMI sends the merchant's server a reusable card reference (EKASHU_CARD_REFERENCE) with every
245
+ // payment, so the merchant keeps the card that pays. Only a card the person stored pays such a
246
+ // checkout: the API refuses a company's added card at create, card choice and lease (409
247
+ // card_not_stored), and the approval page never offers one and says the merchant can keep it.
248
+ keepsCardOnFile: true,
210
249
  hostedForm: {
211
250
  // The card goes into the page NMI returns to the device, not into the paused entry,
212
251
  // which must carry none (processors/ekashu.js checkEkashuEntry). The device never
213
252
  // posts a form of its own: the Vault's form-action policy leaves these hosts out.
214
253
  cardIn: "processor_page",
254
+ // The entry's own rules (processors/ekashu.js checkEkashuEntry), the reviewed sellers among
255
+ // them: the create runs them, and naming them here makes the cardholder's device run them
256
+ // again on the entry it is about to repeat (forms.js hostedFormTemplateRefusal).
257
+ policy: "ekashu",
215
258
  // The server callback too: the device never returns the buyer's browser to the merchant,
216
259
  // so a merchant NMI tells of a payment only through that return never records it.
217
260
  required: [
@@ -558,16 +601,24 @@ var PROCESSOR_DEFINITIONS = deepFreeze([
558
601
  },
559
602
  {
560
603
  psp: "moneris",
561
- compose: { input_exp: "MMYY" },
562
604
  // Hosted Tokenization. VERIFIED live against hpp_common.js on all six
563
605
  // hosts: the iframe does `request.open('POST', 'request.php')` (XHR, relative to
564
606
  // /HPPtoken/index.php) with Content-Type application/x-www-form-urlencoded and
565
- // PAN@ input_data. It sets no auth header (the HT profile is the ?id= on the iframe
566
- // URL), so passthroughHeaders is correctly empty. hpp_common.js references exactly
567
- // one URL and one method, so there is no second tokenization path to cover.
607
+ // PAN@ input_data, expiry@ input_exp (MMYY) and CVD@ input_cvd. moneris.js holds the body
608
+ // rules and the card fill (read from the live frame on 2026-10-10). It sets no auth header (the
609
+ // HT profile rides in the body as hpt_id), so passthroughHeaders is correctly empty. hpp_common.js
610
+ // references exactly one URL and one method, so there is no second tokenization path to cover.
568
611
  // NOTE: do NOT add Moneris Checkout (chkt/) as a separate entry. It shares these
569
612
  // hosts and resolveRecognizerForUrl .find()s on host first, so one would permanently
570
613
  // shadow the other; chkt/ instead falls out at the path check (refused, not leaked).
614
+ // request.php answers no browser origin, so the card leaves the cardholder's device only through
615
+ // the checkout relay, which carries www3 and gateway for a live row and esqa for a test row
616
+ // (moneris.js MONERIS_TOKENIZE_HOSTS), and Moneris's answer is judged by moneris.js
617
+ // monerisAnswerOutcome, since its refusals arrive inside HTTP 200.
618
+ // Ships dark: served only to a client that declares `moneris_hosted_tokenization`, gated off for
619
+ // every org until an operator lists it (`moneris:<org>`, or `moneris:*` once a live purchase proved
620
+ // it), and the internal spine never mints a Moneris row.
621
+ capability: "moneris_hosted_tokenization",
571
622
  match: "(www3|esqa|gateway|gatewayqa|gatewayt|gatewaydev)\\.moneris\\.com/HPPtoken/request\\.php",
572
623
  hosts: [
573
624
  "^www3\\.moneris\\.com$",
@@ -577,8 +628,11 @@ var PROCESSOR_DEFINITIONS = deepFreeze([
577
628
  "^gatewayt\\.moneris\\.com$",
578
629
  "^gatewaydev\\.moneris\\.com$"
579
630
  ],
580
- // Live: www3, gateway. Test/QA/dev: esqa, gatewayqa, gatewayt, gatewaydev.
631
+ // Live: www3, gateway. Test/QA/dev: esqa, gatewayqa, gatewayt, gatewaydev. Pinned (S7): a create
632
+ // refuses a test host on a live row and a live host on a test row, and the device sends a test host
633
+ // only the shared documented test cards (test-pans.js), never a real card.
581
634
  sandboxHosts: ["^esqa\\.moneris\\.com$", "^gatewayqa\\.moneris\\.com$", "^gatewayt\\.moneris\\.com$", "^gatewaydev\\.moneris\\.com$"],
635
+ hostEnvironmentPinned: true,
582
636
  encoding: "form",
583
637
  passthroughHeaders: []
584
638
  },
@@ -702,8 +756,8 @@ var PROCESSOR_DEFINITIONS = deepFreeze([
702
756
  // points at it. The request names no amount: the token is charged later.
703
757
  // Ships dark: served only to a client that declares `primer_payment_instruments`, gated off for every
704
758
  // org until an operator allowlists one, and never replayed by autopilot (EXCLUDED_OPERATIONS). A client
705
- // session can save the card with no sign in the request, so the API also refuses every live row at
706
- // create until the cardholder can consent to that save; only a test row pays.
759
+ // session can save the card with no sign in the request, so a live row pays only with a card the person
760
+ // stored, on an approval that shows the keep-on-file note (primer.js PRIMER_SESSION_CARD_ON_FILE).
707
761
  capability: "primer_payment_instruments",
708
762
  match: "sdk\\.api(?:\\.sandbox)?\\.primer\\.io/payment-instruments(?![\\w/.-])",
709
763
  hosts: ["^sdk\\.api\\.primer\\.io$", "^sdk\\.api\\.sandbox\\.primer\\.io$"],
@@ -848,34 +902,50 @@ var PROCESSOR_DEFINITIONS = deepFreeze([
848
902
  {
849
903
  psp: "gravy",
850
904
  // Gravy (Gr4vy) payment orchestration, Secure Fields. PAN@ payment_method.number,
851
- // expiry@ payment_method.expiration_date as ONE `MM/YY` string (hence `compose`), CVC@
852
- // payment_method.security_code. The merchant page never sees the card: Secure Fields
853
- // renders each input in a frame Gravy serves and sends the request from there, so an
854
- // in-page hook cannot observe it and only the CDP and Playwright transports can pause it.
905
+ // expiry@ payment_method.expiration_date as ONE `MM/YY` string, CVC@
906
+ // payment_method.security_code. gravy.js holds the body rule, the card fill and the answer
907
+ // judge: the pause decision, the API's create and the device read one verdict on the whole
908
+ // body (payment_method's new card in the controller's shape, at most a postal_code beside it,
909
+ // nothing card-shaped anywhere else), and the device writes the card into those three fields
910
+ // alone, never through the generic walk; there is no `compose` on purpose (it widens what the
911
+ // generic walk would call a card). Only Gravy's empty answer is approved.
912
+ // The merchant page never sees the card: Secure Fields renders each input in a frame Gravy
913
+ // serves and sends the request from its hidden controller frame
914
+ // (secure-fields.<merchant id>.gr4vy.app/controller.html), so an in-page hook cannot observe
915
+ // it and only the CDP and Playwright transports can pause it.
855
916
  // Every merchant on Gravy gets its OWN API host, api.<merchant id>.gr4vy.app, with
856
917
  // api.sandbox.<merchant id>.gr4vy.app for test. The merchant label is a bounded wildcard
857
918
  // on purpose, the same footing as deposit.<shop>.shopifycs.com and <prefix>.adyenpayments.com
858
919
  // above: Gravy assigns the label under a domain only Gravy controls, so no third party can
859
920
  // register a host that satisfies it. Only the `api.` host ever carries a card; cdn.<id>
860
- // serves secure-fields.js and embed.<id> the hosted Embed frame, and both fall out of `hosts`.
861
- // The card request is Secure Fields' "update checkout session fields" call,
862
- // /checkout/sessions/<session id>/fields. The id segment is pinned to UUID shape so neither
863
- // a sibling (the session itself at /checkout/sessions/<id>, which carries no card) nor any
864
- // extension of the path is admitted. The session id IS the credential: the request carries
865
- // no auth header, so passthroughHeaders is empty on purpose.
866
- // Gravy publishes this request as an HTTP PUT. Every card gate here and in the SDK admits
867
- // POST only (isCardRequest, prepareDeviceReplay, the enclave dispatcher), so this entry
868
- // recognizes the destination and fills the body but pauses NOTHING until a recognizer can
869
- // declare its method. Inert, never leaky: a PUT on this host continues to Gravy untouched.
870
- // The shape is taken from Gravy's published Secure Fields contract and pinned in
871
- // test/fixtures/gravy-secure-fields.json; a capture from a live merchant form
872
- // (payments.wikimedia.org) has not yet confirmed it.
921
+ // serves secure-fields.js, secure-fields.<id> the input and controller frames and embed.<id>
922
+ // the hosted Embed frame, and all three fall out of `hosts`.
923
+ // The card request is Secure Fields' "update checkout session fields" call, an HTTP PUT to
924
+ // /checkout/sessions/<session id>/fields, and the one card request here that is a PUT
925
+ // (`request.method`, read through recognizerRequestMethod): the SDK pauses the PUT, the API
926
+ // stores it as a PUT and the cardholder's device sends it as one, while a POST to the same URL
927
+ // is not this request and pauses nothing. Gravy answers 204 with no body. The id segment is
928
+ // pinned to UUID shape so neither a sibling (the session itself at /checkout/sessions/<id>,
929
+ // which carries no card) nor any extension of the path is admitted. The session id IS the
930
+ // credential: the request carries no auth header, so passthroughHeaders is empty on purpose.
931
+ // The shape was read on 2026-10-10 from the controller bundle Trek Bicycle and the Wikimedia
932
+ // Foundation both load (controller.d3ca784d5a714143771d.js) and is pinned in
933
+ // test/fixtures/gravy-secure-fields.json: payment_method.method 'card', and Content-Type
934
+ // application/json as the request's only header of its own.
935
+ // Ships dark: served only to an SDK that declares this capability, and gated off for every
936
+ // org until an operator lists one in CHECKOUT_GATED_PROCESSOR_ORGS (`gravy:*` once a live
937
+ // purchase proves the lane). The request names no amount and gravy is not on the
938
+ // reviewed autopilot list, so the cardholder approves every payment. The environment is
939
+ // pinned (S7), as every dark lane pins it: api.sandbox.<id> only on sandbox rows and only
940
+ // with documented test cards, and the live host only on live rows.
941
+ capability: "gravy_session_fields_put",
873
942
  match: "api(\\.sandbox)?\\.[a-z0-9-]+\\.gr4vy\\.app/checkout/sessions/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/fields",
874
943
  hosts: ["^api\\.[a-z0-9-]+\\.gr4vy\\.app$", "^api\\.sandbox\\.[a-z0-9-]+\\.gr4vy\\.app$"],
875
944
  sandboxHosts: ["^api\\.sandbox\\.[a-z0-9-]+\\.gr4vy\\.app$"],
945
+ hostEnvironmentPinned: true,
876
946
  encoding: "json",
877
947
  passthroughHeaders: [],
878
- compose: { expiration_date: "MM/YY" }
948
+ request: { method: "PUT", cardIn: "body", response: "no_content" }
879
949
  },
880
950
  // ── Dark entries (a `capability` gates discovery, the SDK fallback and every org) ──
881
951
  {
@@ -1009,7 +1079,9 @@ var PROCESSOR_DEFINITIONS = deepFreeze([
1009
1079
  // cardNumber: cardFields and passWithoutCard let them continue untouched. The GET that loads the
1010
1080
  // iframe document shares the path, and the POST gate keeps it out. datatrans.js judges the whole
1011
1081
  // request, refuses usage=REGISTRATION (card on file) until that decision is made and a
1012
- // paymentMethod that is not the card's own, and writes only cardNumber, cvv, expm and expy.
1082
+ // paymentMethod that is not the card's own, and writes only cardNumber, cvv, expm and expy; a post
1083
+ // whose expiry the merchant's own form keeps (RaiseNow's Tamaro: no expm or expy) gets cardNumber
1084
+ // and cvv only.
1013
1085
  // Hosts are the two literal labels (never *.datatrans.com: api., 3d. and admin. are other
1014
1086
  // services, and PCI Proxy's custom domains are not recognized); the sandbox host is pinned (S7):
1015
1087
  // it takes only documented test cards, and a live row never points at it.
@@ -1149,23 +1221,35 @@ var PROCESSOR_DEFINITIONS = deepFreeze([
1149
1221
  // device encrypts the real card and sends this request itself (payrails-replay.js), and the
1150
1222
  // ciphertext never returns to the page. Dynamic payment-method forms save non-card instruments
1151
1223
  // on the same URL with no data.encryptedData: jsonCardFields claims only a card save and
1152
- // passWithoutCard lets the rest continue untouched. payrails.js holds the request guard, the
1153
- // card-on-file policy, the session-key and workspace checks and the answer rules. NOT here:
1154
- // /public/payment/instruments/tokenize (web-cse used directly), api.payrails.io and the
1155
- // execution authorize links (card-form payments, stored-card CVC), and assets.payrails.io.
1224
+ // passWithoutCard lets the rest continue untouched. The card form's Pay button (FlixBus's guest
1225
+ // checkout, web SDK 5.50.0) pays through the execution's authorize link instead,
1226
+ // /public/merchant/workflows/payment-acceptance/executions/<uuid>/authorize, with the same JWE at
1227
+ // paymentComposition[0].paymentInstrumentData.encryptedData; a wallet, a stored card or a
1228
+ // redirect method authorizes on the same link with none and continues untouched. Both links sit
1229
+ // on Payrails' public API: the shared api-pub.payrails.io or a merchant's own
1230
+ // api-pub.<merchant>.payrails.io (FlixBus: api-pub.flix.payrails.io), the one-label pattern in
1231
+ // `hosts`; the backend's reviewed pin names the hosts each merchant may use. payrails.js holds the
1232
+ // request guards, the card-on-file policy, the session-key and workspace checks and the answer
1233
+ // rules. NOT here: /public/payment/instruments/tokenize (web-cse used directly), api.payrails.io,
1234
+ // the other execution links, and assets.payrails.io.
1156
1235
  // `capability` keeps the entry out of BUILTIN_REGISTRY and every org until one opts in; the API
1157
1236
  // serves it only to a client that also asks for modes=device_encrypt. The two staging hosts are
1158
1237
  // pinned to sandbox rows (S7). Autopilot refuses it by operation (payrails.device_encrypted_card).
1159
1238
  capability: "payrails_device_encrypt",
1160
- match: "(?:api-pub|api-pub\\.staging|sandbox-api-pub\\.staging)\\.payrails\\.io/public/payment/instruments(?![\\w/.-])",
1161
- hosts: ["^api-pub\\.payrails\\.io$", "^api-pub\\.staging\\.payrails\\.io$", "^sandbox-api-pub\\.staging\\.payrails\\.io$"],
1239
+ match: "(?:api-pub(?:\\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)?|sandbox-api-pub\\.staging)\\.payrails\\.io/public/(?:payment/instruments|merchant/workflows/payment-acceptance/executions/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/authorize)(?![\\w/.-])",
1240
+ hosts: [
1241
+ "^api-pub\\.payrails\\.io$",
1242
+ "^api-pub\\.staging\\.payrails\\.io$",
1243
+ "^sandbox-api-pub\\.staging\\.payrails\\.io$",
1244
+ "^api-pub\\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\\.payrails\\.io$"
1245
+ ],
1162
1246
  sandboxHosts: ["^api-pub\\.staging\\.payrails\\.io$", "^sandbox-api-pub\\.staging\\.payrails\\.io$"],
1163
1247
  hostEnvironmentPinned: true,
1164
1248
  encoding: "json",
1165
1249
  // body shape; the SDK sends text/plain, replayed verbatim
1166
1250
  passthroughHeaders: ["^authorization$", "^x-idempotency-key$", "^x-client-version$", "^x-client-type$"],
1167
- jsonCardFields: [["data", "encryptedData"]],
1168
- passWithoutCard: "(?:api-pub|api-pub\\.staging|sandbox-api-pub\\.staging)\\.payrails\\.io/public/payment/instruments",
1251
+ jsonCardFields: [["data", "encryptedData"], ["paymentComposition", 0, "paymentInstrumentData", "encryptedData"]],
1252
+ passWithoutCard: "(?:api-pub(?:\\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)?|sandbox-api-pub\\.staging)\\.payrails\\.io/public/(?:payment/instruments|merchant/workflows/payment-acceptance/executions/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/authorize)",
1169
1253
  clientSideEncrypted: true,
1170
1254
  // older SDKs read this and refuse locally
1171
1255
  mode: "device_encrypt",
@@ -1188,20 +1272,21 @@ var PROCESSOR_DEFINITIONS = deepFreeze([
1188
1272
  // own AngularJS page posts the card as same-origin JSON to /hosted-payments/service/payment/hpp/process.
1189
1273
  // PAN@ paymentData.ssl_card_number (digits), expiry@ paymentData.ssl_exp_date (MMYY), CVC@
1190
1274
  // paymentData.ssl_cvv2cvc2. No client-side encryption; the session rides in the body (`context`).
1191
- // Sources: assets/hpp-2.505.07.js, byte-identical on both hosts, reviewed 2026-09-25. The same URL
1275
+ // Sources: assets/hpp-2.505.07.js, byte-identical on all three hosts, reviewed 2026-09-25. The same URL
1192
1276
  // carries wallet, ACH and loan payments and the follow-ups after 3DS2, Pay Defense or a surcharge
1193
1277
  // quote: the Converge body gate decides (elavon-converge.js convergeBodyVerdict, which card-fields.js
1194
1278
  // asks first, so the SDK's generated copy carries it). The lightbox (hpm/process), Checkout.js
1195
1279
  // (hpe/process) and every other hpp/ call fall out at the exact path; (?![\w/.%-]) is the right edge
1196
- // for the SDK's unanchored test. Hosts are two literal labels, never *.convergepay.com (www and demo
1197
- // are the merchant web UI).
1280
+ // for the SDK's unanchored test. Hosts are three literal labels, never *.convergepay.com: api, its demo,
1281
+ // and www, where every Buy Button and pay link opens the same page and bundle, which post the card to
1282
+ // www's own origin (read 2026-10-10). demo.convergepay.com is the merchant web UI.
1198
1283
  // Ships dark: served only to a client that declares `converge_hpp_process`, gated off for every org
1199
1284
  // until an operator allowlists one, never replayed by autopilot (EXCLUDED_OPERATIONS).
1200
1285
  capability: "converge_hpp_process",
1201
- match: "api(?:\\.demo)?\\.convergepay\\.com/hosted-payments/service/payment/hpp/process(?![\\w/.%-])",
1202
- hosts: ["^api\\.convergepay\\.com$", "^api\\.demo\\.convergepay\\.com$"],
1286
+ match: "(?:api(?:\\.demo)?|www)\\.convergepay\\.com/hosted-payments/service/payment/hpp/process(?![\\w/.%-])",
1287
+ hosts: ["^api\\.convergepay\\.com$", "^api\\.demo\\.convergepay\\.com$", "^www\\.convergepay\\.com$"],
1203
1288
  // api.demo is Converge's demo environment. Pinned (S7): a create refuses it on a live row and the
1204
- // production host on a test row, and the device sends only documented test cards to it.
1289
+ // production hosts, api and www, on a test row, and the device sends only documented test cards to it.
1205
1290
  sandboxHosts: ["^api\\.demo\\.convergepay\\.com$"],
1206
1291
  hostEnvironmentPinned: true,
1207
1292
  encoding: "json",
@@ -1209,7 +1294,7 @@ var PROCESSOR_DEFINITIONS = deepFreeze([
1209
1294
  passthroughHeaders: [],
1210
1295
  jsonCardFields: [["paymentData", "ssl_card_number"]],
1211
1296
  // An electronic check or financing payment on the same URL carries no card and continues untouched.
1212
- passWithoutCard: "api(?:\\.demo)?\\.convergepay\\.com/hosted-payments/service/payment/hpp/process"
1297
+ passWithoutCard: "(?:api(?:\\.demo)?|www)\\.convergepay\\.com/hosted-payments/service/payment/hpp/process"
1213
1298
  },
1214
1299
  {
1215
1300
  psp: "wspay",
@@ -1263,8 +1348,9 @@ var PROCESSOR_DEFINITIONS = deepFreeze([
1263
1348
  // browser's host). `capability` keeps the entry out of BUILTIN_REGISTRY, serves it only to a client
1264
1349
  // that declares shiji_sts_pinned_key, and leaves it off for every org until one is opted in. The UAT
1265
1350
  // host is the sandbox host and the environment is pinned (S7): UAT only on sandbox rows, with
1266
- // documented test cards. Every getTokenId is refused as card on file (a hotel guarantee) until the
1267
- // consent decision is made (shiji-sts.js SHIJI_STS_KEEP_ON_FILE). `(?![\w/-])` ends the path as
1351
+ // documented test cards. Every getTokenId keeps the card on file (a hotel guarantee), which the
1352
+ // cardholder consents to on the approval screen (shiji-sts.js SHIJI_STS_KEEP_ON_FILE: 'ask', and
1353
+ // 'refuse' is the kill switch that refuses each one before any prompt). `(?![\w/-])` ends the path as
1268
1354
  // on mercado_pago and paysafe: a consumer that tests `match` unanchored never takes
1269
1355
  // /v1/token/getTokenIdX or /v1/token/getTokenId/x for a card request.
1270
1356
  capability: "shiji_sts_pinned_key",
@@ -1345,6 +1431,8 @@ var PSP_CLIENT_TABLE = deepFreeze(PROCESSOR_DEFINITIONS.map((definition) => ({
1345
1431
  ...definition.hostedForm.optional ? { optional: definition.hostedForm.optional } : {}
1346
1432
  } } : {},
1347
1433
  ...definition.hostedForm?.cardIn ? { formCardIn: definition.hostedForm.cardIn } : {},
1434
+ // The page's copy of the rule that only the person's own stored card pays (the API holds the same).
1435
+ ...definition.keepsCardOnFile ? { keepsCardOnFile: true } : {},
1348
1436
  ...definition.deviceSteps ? { deviceSteps: Object.fromEntries(Object.entries(definition.deviceSteps).map(([step, source]) => [step, new RegExp(source, "i")])) } : {},
1349
1437
  ...definition.deviceEncrypt ? { deviceEncrypt: definition.deviceEncrypt } : {}
1350
1438
  })));
@@ -1412,6 +1500,15 @@ var DATATRANS_TEST_PANS = Object.freeze([
1412
1500
  "36000010000022",
1413
1501
  "3550998599961037"
1414
1502
  ]);
1503
+ // src/moneris.js
1504
+ var MONERIS_TOKENIZE_HOSTS = /* @__PURE__ */ Object.freeze({
1505
+ production: Object.freeze(["www3.moneris.com", "gateway.moneris.com"]),
1506
+ sandbox: Object.freeze(["esqa.moneris.com"])
1507
+ });
1508
+ var pin = (fields) => Object.freeze({ ...fields, origins: Object.freeze([...fields.origins]), profileIds: Object.freeze([...fields.profileIds]) });
1509
+ var MONERIS_MERCHANT_PINS = /* @__PURE__ */ Object.freeze([
1510
+ pin({ id: "jack_org_raisin", merchant: "Jack.org", origins: ["https://jack.akaraisin.com"], profileIds: ["htL7TR9H7ICYN2B"] })
1511
+ ]);
1415
1512
  // src/cybersource-secure-acceptance.js
1416
1513
  var SA_BODY_LIMIT = 32 * 1024;
1417
1514
  var SA_REPLY_LIMIT = 64 * 1024;