@agent-cards/sdk 0.23.9 → 0.23.11

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 (65) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/PREFLIGHT.md +7 -5
  3. package/README.md +211 -102
  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 +165 -10
  11. package/dist/cdp.js +86 -34
  12. package/dist/client.d.ts +73 -33
  13. package/dist/client.js +136 -45
  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/datatrans.generated.js +8 -5
  19. package/dist/elavon-converge.d.ts +5 -2
  20. package/dist/elavon-converge.generated.js +9 -5
  21. package/dist/elavon-converge.js +8 -4
  22. package/dist/fiserv.d.ts +9 -5
  23. package/dist/fiserv.generated.d.ts +3 -3
  24. package/dist/fiserv.generated.js +50 -20
  25. package/dist/fiserv.js +10 -6
  26. package/dist/lifecycle.d.ts +9 -1
  27. package/dist/lifecycle.js +34 -0
  28. package/dist/payrails.d.ts +78 -18
  29. package/dist/payrails.generated.d.ts +12 -2
  30. package/dist/payrails.generated.js +213 -18
  31. package/dist/payrails.js +165 -44
  32. package/dist/pre-claim.d.ts +7 -0
  33. package/dist/pre-claim.js +98 -36
  34. package/dist/preflight-capabilities.generated.d.ts +0 -106
  35. package/dist/preflight-capabilities.generated.js +0 -153
  36. package/dist/preflight-catalog.json +61 -181
  37. package/dist/preflight-schemas.json +6 -6
  38. package/dist/preflight.generated.d.ts +0 -106
  39. package/dist/preflight.generated.js +27 -15
  40. package/dist/preparation.d.ts +2 -0
  41. package/dist/preparation.js +4 -2
  42. package/dist/prepared-processor.d.ts +19 -5
  43. package/dist/prepared-processor.js +21 -5
  44. package/dist/primer.generated.d.ts +5 -1
  45. package/dist/primer.generated.js +202 -34
  46. package/dist/registry.d.ts +18 -12
  47. package/dist/registry.js +11 -8
  48. package/dist/shiji-sts.d.ts +24 -22
  49. package/dist/shiji-sts.generated.d.ts +1 -1
  50. package/dist/shiji-sts.generated.js +12 -8
  51. package/dist/shiji-sts.js +49 -46
  52. package/dist/stripe-checkout.generated.js +157 -49
  53. package/dist/verifone.generated.js +192 -17
  54. package/dist/verifone.js +1 -1
  55. package/dist/worldline-mycheckout.d.ts +27 -0
  56. package/dist/worldline-mycheckout.generated.d.ts +29 -0
  57. package/dist/worldline-mycheckout.generated.js +162 -0
  58. package/dist/worldline-mycheckout.js +93 -0
  59. package/dist/wspay.d.ts +17 -16
  60. package/dist/wspay.generated.d.ts +6 -1
  61. package/dist/wspay.generated.js +13 -3
  62. package/dist/wspay.js +9 -11
  63. package/examples/preflight/kernel-native/README.md +1 -1
  64. package/examples/preflight/kernel-native/inventory.json +1 -19
  65. 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: 0abf1d62c20303c4496e1d26b64b1c36ad517919d23f2d14e3f0b6763694551f
4
4
  // src/deep-freeze.js
5
5
  function deepFreeze(value) {
6
6
  if (value && typeof value === "object" && !Object.isFrozen(value)) {
@@ -169,15 +169,60 @@ 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"],
215
+ // Tranzila's own ALTCHA proof of work, on every card form read on both
216
+ // hosts on 2026-10-10 (altcha 1.0.7, SHA-256, searched up to 50,000):
217
+ // Tranzila's script hashes the page's challenge until it finds the
218
+ // number, writes base64 JSON {algorithm, challenge, number, salt,
219
+ // signature, took} into `altcha`, and only then submits the form.
220
+ // Nobody answers anything and the proof names no browser, cookie or
221
+ // address, so it rides the device's one send as the page wrote it, once
222
+ // the create finds it is one solved proof (backend.js isAltchaProof).
223
+ // Every other challenge field is still refused (hosted_form_gated).
224
+ // Removing this line refuses `altcha` again.
225
+ proofOfWork: "altcha"
181
226
  }
182
227
  },
183
228
  {
@@ -187,7 +232,7 @@ var PROCESSOR_DEFINITIONS = deepFreeze([
187
232
  // The merchant's page posts an ENTRY form top-level to live.ekashu.com/ (test:
188
233
  // test.ekashu.com/) with the amount, the result URLs and a SHA256HMAC over them (hash
189
234
  // 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
235
+ // cookie and session fields of its own, so a card form rebuilt away from that session is
191
236
  // refused by NMI (processors/ekashu.js has the recorded shapes). The paused request is
192
237
  // therefore the entry, a Document navigation that carries no card: the cardholder's
193
238
  // device repeats it over the end-to-end TLS relay, fills the card into the page NMI
@@ -207,11 +252,20 @@ var PROCESSOR_DEFINITIONS = deepFreeze([
207
252
  encoding: "form",
208
253
  passthroughHeaders: [],
209
254
  mode: "hosted_form",
255
+ // NMI sends the merchant's server a reusable card reference (EKASHU_CARD_REFERENCE) with every
256
+ // payment, so the merchant keeps the card that pays. Only a card the person stored pays such a
257
+ // checkout: the API refuses a company's added card at create, card choice and lease (409
258
+ // card_not_stored), and the approval page never offers one and says the merchant can keep it.
259
+ keepsCardOnFile: true,
210
260
  hostedForm: {
211
261
  // The card goes into the page NMI returns to the device, not into the paused entry,
212
262
  // which must carry none (processors/ekashu.js checkEkashuEntry). The device never
213
263
  // posts a form of its own: the Vault's form-action policy leaves these hosts out.
214
264
  cardIn: "processor_page",
265
+ // The entry's own rules (processors/ekashu.js checkEkashuEntry), the reviewed sellers among
266
+ // them: the create runs them, and naming them here makes the cardholder's device run them
267
+ // again on the entry it is about to repeat (forms.js hostedFormTemplateRefusal).
268
+ policy: "ekashu",
215
269
  // The server callback too: the device never returns the buyer's browser to the merchant,
216
270
  // so a merchant NMI tells of a payment only through that return never records it.
217
271
  required: [
@@ -558,16 +612,24 @@ var PROCESSOR_DEFINITIONS = deepFreeze([
558
612
  },
559
613
  {
560
614
  psp: "moneris",
561
- compose: { input_exp: "MMYY" },
562
615
  // Hosted Tokenization. VERIFIED live against hpp_common.js on all six
563
616
  // hosts: the iframe does `request.open('POST', 'request.php')` (XHR, relative to
564
617
  // /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.
618
+ // PAN@ input_data, expiry@ input_exp (MMYY) and CVD@ input_cvd. moneris.js holds the body
619
+ // rules and the card fill (read from the live frame on 2026-10-10). It sets no auth header (the
620
+ // HT profile rides in the body as hpt_id), so passthroughHeaders is correctly empty. hpp_common.js
621
+ // references exactly one URL and one method, so there is no second tokenization path to cover.
568
622
  // NOTE: do NOT add Moneris Checkout (chkt/) as a separate entry. It shares these
569
623
  // hosts and resolveRecognizerForUrl .find()s on host first, so one would permanently
570
624
  // shadow the other; chkt/ instead falls out at the path check (refused, not leaked).
625
+ // request.php answers no browser origin, so the card leaves the cardholder's device only through
626
+ // the checkout relay, which carries www3 and gateway for a live row and esqa for a test row
627
+ // (moneris.js MONERIS_TOKENIZE_HOSTS), and Moneris's answer is judged by moneris.js
628
+ // monerisAnswerOutcome, since its refusals arrive inside HTTP 200.
629
+ // Ships dark: served only to a client that declares `moneris_hosted_tokenization`, gated off for
630
+ // every org until an operator lists it (`moneris:<org>`, or `moneris:*` once a live purchase proved
631
+ // it), and the internal spine never mints a Moneris row.
632
+ capability: "moneris_hosted_tokenization",
571
633
  match: "(www3|esqa|gateway|gatewayqa|gatewayt|gatewaydev)\\.moneris\\.com/HPPtoken/request\\.php",
572
634
  hosts: [
573
635
  "^www3\\.moneris\\.com$",
@@ -577,8 +639,11 @@ var PROCESSOR_DEFINITIONS = deepFreeze([
577
639
  "^gatewayt\\.moneris\\.com$",
578
640
  "^gatewaydev\\.moneris\\.com$"
579
641
  ],
580
- // Live: www3, gateway. Test/QA/dev: esqa, gatewayqa, gatewayt, gatewaydev.
642
+ // Live: www3, gateway. Test/QA/dev: esqa, gatewayqa, gatewayt, gatewaydev. Pinned (S7): a create
643
+ // refuses a test host on a live row and a live host on a test row, and the device sends a test host
644
+ // only the shared documented test cards (test-pans.js), never a real card.
581
645
  sandboxHosts: ["^esqa\\.moneris\\.com$", "^gatewayqa\\.moneris\\.com$", "^gatewayt\\.moneris\\.com$", "^gatewaydev\\.moneris\\.com$"],
646
+ hostEnvironmentPinned: true,
582
647
  encoding: "form",
583
648
  passthroughHeaders: []
584
649
  },
@@ -702,8 +767,8 @@ var PROCESSOR_DEFINITIONS = deepFreeze([
702
767
  // points at it. The request names no amount: the token is charged later.
703
768
  // Ships dark: served only to a client that declares `primer_payment_instruments`, gated off for every
704
769
  // 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.
770
+ // session can save the card with no sign in the request, so a live row pays only with a card the person
771
+ // stored, on an approval that shows the keep-on-file note (primer.js PRIMER_SESSION_CARD_ON_FILE).
707
772
  capability: "primer_payment_instruments",
708
773
  match: "sdk\\.api(?:\\.sandbox)?\\.primer\\.io/payment-instruments(?![\\w/.-])",
709
774
  hosts: ["^sdk\\.api\\.primer\\.io$", "^sdk\\.api\\.sandbox\\.primer\\.io$"],
@@ -848,34 +913,50 @@ var PROCESSOR_DEFINITIONS = deepFreeze([
848
913
  {
849
914
  psp: "gravy",
850
915
  // 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.
916
+ // expiry@ payment_method.expiration_date as ONE `MM/YY` string, CVC@
917
+ // payment_method.security_code. gravy.js holds the body rule, the card fill and the answer
918
+ // judge: the pause decision, the API's create and the device read one verdict on the whole
919
+ // body (payment_method's new card in the controller's shape, at most a postal_code beside it,
920
+ // nothing card-shaped anywhere else), and the device writes the card into those three fields
921
+ // alone, never through the generic walk; there is no `compose` on purpose (it widens what the
922
+ // generic walk would call a card). Only Gravy's empty answer is approved.
923
+ // The merchant page never sees the card: Secure Fields renders each input in a frame Gravy
924
+ // serves and sends the request from its hidden controller frame
925
+ // (secure-fields.<merchant id>.gr4vy.app/controller.html), so an in-page hook cannot observe
926
+ // it and only the CDP and Playwright transports can pause it.
855
927
  // Every merchant on Gravy gets its OWN API host, api.<merchant id>.gr4vy.app, with
856
928
  // api.sandbox.<merchant id>.gr4vy.app for test. The merchant label is a bounded wildcard
857
929
  // on purpose, the same footing as deposit.<shop>.shopifycs.com and <prefix>.adyenpayments.com
858
930
  // above: Gravy assigns the label under a domain only Gravy controls, so no third party can
859
931
  // 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.
932
+ // serves secure-fields.js, secure-fields.<id> the input and controller frames and embed.<id>
933
+ // the hosted Embed frame, and all three fall out of `hosts`.
934
+ // The card request is Secure Fields' "update checkout session fields" call, an HTTP PUT to
935
+ // /checkout/sessions/<session id>/fields, and the one card request here that is a PUT
936
+ // (`request.method`, read through recognizerRequestMethod): the SDK pauses the PUT, the API
937
+ // stores it as a PUT and the cardholder's device sends it as one, while a POST to the same URL
938
+ // is not this request and pauses nothing. Gravy answers 204 with no body. The id segment is
939
+ // pinned to UUID shape so neither a sibling (the session itself at /checkout/sessions/<id>,
940
+ // which carries no card) nor any extension of the path is admitted. The session id IS the
941
+ // credential: the request carries no auth header, so passthroughHeaders is empty on purpose.
942
+ // The shape was read on 2026-10-10 from the controller bundle Trek Bicycle and the Wikimedia
943
+ // Foundation both load (controller.d3ca784d5a714143771d.js) and is pinned in
944
+ // test/fixtures/gravy-secure-fields.json: payment_method.method 'card', and Content-Type
945
+ // application/json as the request's only header of its own.
946
+ // Ships dark: served only to an SDK that declares this capability, and gated off for every
947
+ // org until an operator lists one in CHECKOUT_GATED_PROCESSOR_ORGS (`gravy:*` once a live
948
+ // purchase proves the lane). The request names no amount and gravy is not on the
949
+ // reviewed autopilot list, so the cardholder approves every payment. The environment is
950
+ // pinned (S7), as every dark lane pins it: api.sandbox.<id> only on sandbox rows and only
951
+ // with documented test cards, and the live host only on live rows.
952
+ capability: "gravy_session_fields_put",
873
953
  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
954
  hosts: ["^api\\.[a-z0-9-]+\\.gr4vy\\.app$", "^api\\.sandbox\\.[a-z0-9-]+\\.gr4vy\\.app$"],
875
955
  sandboxHosts: ["^api\\.sandbox\\.[a-z0-9-]+\\.gr4vy\\.app$"],
956
+ hostEnvironmentPinned: true,
876
957
  encoding: "json",
877
958
  passthroughHeaders: [],
878
- compose: { expiration_date: "MM/YY" }
959
+ request: { method: "PUT", cardIn: "body", response: "no_content" }
879
960
  },
880
961
  // ── Dark entries (a `capability` gates discovery, the SDK fallback and every org) ──
881
962
  {
@@ -1009,7 +1090,9 @@ var PROCESSOR_DEFINITIONS = deepFreeze([
1009
1090
  // cardNumber: cardFields and passWithoutCard let them continue untouched. The GET that loads the
1010
1091
  // iframe document shares the path, and the POST gate keeps it out. datatrans.js judges the whole
1011
1092
  // 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.
1093
+ // paymentMethod that is not the card's own, and writes only cardNumber, cvv, expm and expy; a post
1094
+ // whose expiry the merchant's own form keeps (RaiseNow's Tamaro: no expm or expy) gets cardNumber
1095
+ // and cvv only.
1013
1096
  // Hosts are the two literal labels (never *.datatrans.com: api., 3d. and admin. are other
1014
1097
  // services, and PCI Proxy's custom domains are not recognized); the sandbox host is pinned (S7):
1015
1098
  // it takes only documented test cards, and a live row never points at it.
@@ -1149,23 +1232,35 @@ var PROCESSOR_DEFINITIONS = deepFreeze([
1149
1232
  // device encrypts the real card and sends this request itself (payrails-replay.js), and the
1150
1233
  // ciphertext never returns to the page. Dynamic payment-method forms save non-card instruments
1151
1234
  // 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.
1235
+ // passWithoutCard lets the rest continue untouched. The card form's Pay button (FlixBus's guest
1236
+ // checkout, web SDK 5.50.0) pays through the execution's authorize link instead,
1237
+ // /public/merchant/workflows/payment-acceptance/executions/<uuid>/authorize, with the same JWE at
1238
+ // paymentComposition[0].paymentInstrumentData.encryptedData; a wallet, a stored card or a
1239
+ // redirect method authorizes on the same link with none and continues untouched. Both links sit
1240
+ // on Payrails' public API: the shared api-pub.payrails.io or a merchant's own
1241
+ // api-pub.<merchant>.payrails.io (FlixBus: api-pub.flix.payrails.io), the one-label pattern in
1242
+ // `hosts`; the backend's reviewed pin names the hosts each merchant may use. payrails.js holds the
1243
+ // request guards, the card-on-file policy, the session-key and workspace checks and the answer
1244
+ // rules. NOT here: /public/payment/instruments/tokenize (web-cse used directly), api.payrails.io,
1245
+ // the other execution links, and assets.payrails.io.
1156
1246
  // `capability` keeps the entry out of BUILTIN_REGISTRY and every org until one opts in; the API
1157
1247
  // serves it only to a client that also asks for modes=device_encrypt. The two staging hosts are
1158
1248
  // pinned to sandbox rows (S7). Autopilot refuses it by operation (payrails.device_encrypted_card).
1159
1249
  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$"],
1250
+ 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/.-])",
1251
+ hosts: [
1252
+ "^api-pub\\.payrails\\.io$",
1253
+ "^api-pub\\.staging\\.payrails\\.io$",
1254
+ "^sandbox-api-pub\\.staging\\.payrails\\.io$",
1255
+ "^api-pub\\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\\.payrails\\.io$"
1256
+ ],
1162
1257
  sandboxHosts: ["^api-pub\\.staging\\.payrails\\.io$", "^sandbox-api-pub\\.staging\\.payrails\\.io$"],
1163
1258
  hostEnvironmentPinned: true,
1164
1259
  encoding: "json",
1165
1260
  // body shape; the SDK sends text/plain, replayed verbatim
1166
1261
  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",
1262
+ jsonCardFields: [["data", "encryptedData"], ["paymentComposition", 0, "paymentInstrumentData", "encryptedData"]],
1263
+ 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
1264
  clientSideEncrypted: true,
1170
1265
  // older SDKs read this and refuse locally
1171
1266
  mode: "device_encrypt",
@@ -1188,20 +1283,21 @@ var PROCESSOR_DEFINITIONS = deepFreeze([
1188
1283
  // own AngularJS page posts the card as same-origin JSON to /hosted-payments/service/payment/hpp/process.
1189
1284
  // PAN@ paymentData.ssl_card_number (digits), expiry@ paymentData.ssl_exp_date (MMYY), CVC@
1190
1285
  // 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
1286
+ // Sources: assets/hpp-2.505.07.js, byte-identical on all three hosts, reviewed 2026-09-25. The same URL
1192
1287
  // carries wallet, ACH and loan payments and the follow-ups after 3DS2, Pay Defense or a surcharge
1193
1288
  // quote: the Converge body gate decides (elavon-converge.js convergeBodyVerdict, which card-fields.js
1194
1289
  // asks first, so the SDK's generated copy carries it). The lightbox (hpm/process), Checkout.js
1195
1290
  // (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).
1291
+ // for the SDK's unanchored test. Hosts are three literal labels, never *.convergepay.com: api, its demo,
1292
+ // and www, where every Buy Button and pay link opens the same page and bundle, which post the card to
1293
+ // www's own origin (read 2026-10-10). demo.convergepay.com is the merchant web UI.
1198
1294
  // Ships dark: served only to a client that declares `converge_hpp_process`, gated off for every org
1199
1295
  // until an operator allowlists one, never replayed by autopilot (EXCLUDED_OPERATIONS).
1200
1296
  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$"],
1297
+ match: "(?:api(?:\\.demo)?|www)\\.convergepay\\.com/hosted-payments/service/payment/hpp/process(?![\\w/.%-])",
1298
+ hosts: ["^api\\.convergepay\\.com$", "^api\\.demo\\.convergepay\\.com$", "^www\\.convergepay\\.com$"],
1203
1299
  // 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.
1300
+ // production hosts, api and www, on a test row, and the device sends only documented test cards to it.
1205
1301
  sandboxHosts: ["^api\\.demo\\.convergepay\\.com$"],
1206
1302
  hostEnvironmentPinned: true,
1207
1303
  encoding: "json",
@@ -1209,7 +1305,7 @@ var PROCESSOR_DEFINITIONS = deepFreeze([
1209
1305
  passthroughHeaders: [],
1210
1306
  jsonCardFields: [["paymentData", "ssl_card_number"]],
1211
1307
  // 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"
1308
+ passWithoutCard: "(?:api(?:\\.demo)?|www)\\.convergepay\\.com/hosted-payments/service/payment/hpp/process"
1213
1309
  },
1214
1310
  {
1215
1311
  psp: "wspay",
@@ -1263,8 +1359,9 @@ var PROCESSOR_DEFINITIONS = deepFreeze([
1263
1359
  // browser's host). `capability` keeps the entry out of BUILTIN_REGISTRY, serves it only to a client
1264
1360
  // that declares shiji_sts_pinned_key, and leaves it off for every org until one is opted in. The UAT
1265
1361
  // 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
1362
+ // documented test cards. Every getTokenId keeps the card on file (a hotel guarantee), which the
1363
+ // cardholder consents to on the approval screen (shiji-sts.js SHIJI_STS_KEEP_ON_FILE: 'ask', and
1364
+ // 'refuse' is the kill switch that refuses each one before any prompt). `(?![\w/-])` ends the path as
1268
1365
  // on mercado_pago and paysafe: a consumer that tests `match` unanchored never takes
1269
1366
  // /v1/token/getTokenIdX or /v1/token/getTokenId/x for a card request.
1270
1367
  capability: "shiji_sts_pinned_key",
@@ -1345,6 +1442,8 @@ var PSP_CLIENT_TABLE = deepFreeze(PROCESSOR_DEFINITIONS.map((definition) => ({
1345
1442
  ...definition.hostedForm.optional ? { optional: definition.hostedForm.optional } : {}
1346
1443
  } } : {},
1347
1444
  ...definition.hostedForm?.cardIn ? { formCardIn: definition.hostedForm.cardIn } : {},
1445
+ // The page's copy of the rule that only the person's own stored card pays (the API holds the same).
1446
+ ...definition.keepsCardOnFile ? { keepsCardOnFile: true } : {},
1348
1447
  ...definition.deviceSteps ? { deviceSteps: Object.fromEntries(Object.entries(definition.deviceSteps).map(([step, source]) => [step, new RegExp(source, "i")])) } : {},
1349
1448
  ...definition.deviceEncrypt ? { deviceEncrypt: definition.deviceEncrypt } : {}
1350
1449
  })));
@@ -1412,6 +1511,15 @@ var DATATRANS_TEST_PANS = Object.freeze([
1412
1511
  "36000010000022",
1413
1512
  "3550998599961037"
1414
1513
  ]);
1514
+ // src/moneris.js
1515
+ var MONERIS_TOKENIZE_HOSTS = /* @__PURE__ */ Object.freeze({
1516
+ production: Object.freeze(["www3.moneris.com", "gateway.moneris.com"]),
1517
+ sandbox: Object.freeze(["esqa.moneris.com"])
1518
+ });
1519
+ var pin = (fields) => Object.freeze({ ...fields, origins: Object.freeze([...fields.origins]), profileIds: Object.freeze([...fields.profileIds]) });
1520
+ var MONERIS_MERCHANT_PINS = /* @__PURE__ */ Object.freeze([
1521
+ pin({ id: "jack_org_raisin", merchant: "Jack.org", origins: ["https://jack.akaraisin.com"], profileIds: ["htL7TR9H7ICYN2B"] })
1522
+ ]);
1415
1523
  // src/cybersource-secure-acceptance.js
1416
1524
  var SA_BODY_LIMIT = 32 * 1024;
1417
1525
  var SA_REPLY_LIMIT = 64 * 1024;