Script-tag integration — auto-update vs pinned (SRI)
vora.js is the only script you reference: it is code-split internally and loads its own sub-chunks on demand at session-load time. Do not load a payment processor's SDK yourself — the card field is rendered inside vora.js's iframe.
The bundle ships from https://js.vonpay.com/ through two channels:
| Channel | URL shape | Updates | Supply-chain check |
|---|---|---|---|
| Auto-update | /v1/vora.js | Tracks the latest v1.x.x automatically | Continuous integrity monitoring by Von Payments |
| Pinned (SRI) | /vX.Y.Z/vora.js + integrity="sha384-…" | Byte-exact: stays on the build you tested | Browser-enforced — refuses to execute if the bytes don't match |
Auto-update channel (default)
<script src="https://js.vonpay.com/v1/vora.js" crossorigin="anonymous"></script>
New features, bug fixes and security patches reach your checkout as they ship; Von Payments polls the served bytes against the registry continuously (minutes, not per request). crossorigin="anonymous" is required once you add integrity, so set it now.
Pinned channel (SRI)
<script
src="https://js.vonpay.com/vX.Y.Z/vora.js"
integrity="sha384-…"
crossorigin="anonymous"></script>
vX.Y.Z is a placeholder. Copy both the current version number and its matching integrity hash from the live registry at https://js.vonpay.com/integrity.json; never transcribe either from this page. You bump both on each release — a stale pin keeps working but misses new features.
integrity= does not covervora.js is a loader. Once it runs it fetches the Elements UI runtime (every session) and one processor adapter chunk from /{version}/adapters/ with a dynamic import() — the full set is artifacts[] in the registry — and a dynamic import() cannot carry an integrity attribute, a browser limitation. Pinning gives you a fixed, verified entry point and a fixed version of everything downstream; it is not browser-enforced byte verification of every script involved in a render.
Where the hashes come from
The registry at https://js.vonpay.com/integrity.json (one version shown; the sha384-… values are placeholders):
{
"versions": {
"vX.Y.Z": {
"builtAt": "2026-06-04T08:35:21.677Z",
"sha384": "sha384-…",
"bytes": 77756,
"artifacts": [
{
"role": "core",
"path": "vora.js",
"sha384": "sha384-…",
"bytes": 77756
}
]
}
}
}
sha384at the top level is the core-bundle hash — the value you pin.artifacts[]carries per-file hashes for the core bundle and its internal sub-chunks.builtAtis the publish timestamp;byteslets you sanity-check before pinning (a 0-byte entry is the signal the registry is corrupted).- The registry is append-only — old entries stay published, so pinned snippets in deployed code keep working.
Automating updates
Check the version and hash into source control with the snippet. When you move to a version you have tested, your pipeline fetches integrity.json, reads that version's versions.{v} entry, rewrites the <script> tag's src and integrity, and redeploys — at whatever cadence your change control sets.
Content Security Policy
script-src must allowlist js.vonpay.com on either channel, plus your active binder's CDN (Errors → CSP requirements):
script-src 'self' js.vonpay.com;
Pinning does not change the CSP: the browser applies integrity after fetching from the same js.vonpay.com origin.
When to pick which
| Posture | Pick |
|---|---|
| Most integrations | Auto-update. |
| Change control requires that no code updates without operator action, or byte-exact reproducibility of every checkout render | Pinned. Update the version and hash on each release through your normal process. |
Your pipeline writes the script tag and can read integrity.json | Pinned with automated update. |
What's next
- Quickstart — minimal end-to-end card-only integration
- Errors → CSP requirements — full CSP allowlist
integrity.json— the published registry