Skip to main content

CDN bundle

The CDN bundle is the zero-framework integration path. Add a single <script> tag to your storefront page; the loader scans for offer elements, mounts an inline Pay With Agent button, and on click opens the hosted wallet approve page so the shopper's agent can complete the purchase.

Install

There is no npm or build step for the browser bundle. Add one <script> tag pointing at the loader on cdn.oid4pay.com:

<script
  src="https://cdn.oid4pay.com/oid4ac-merchant/v1/loader.js"
  data-merchant-id="merchant_abc123"
></script>

The bundle source also ships on npm as @oid4pay/cdn-oid4ac-merchant (v0.1.0, MIT) for teams that want to self-host the bundle.

Element contract

Mark each purchasable item with a data-oid4ac-offer element. If the element already contains a <button> the loader wires it; otherwise it appends its own Pay With Agent button.

<div data-oid4ac-offer
  data-sku="demo-tote"
  data-amount-minor="1250"
  data-currency="EUR"
>
  <button>Pay with Agent</button>
</div>

The bundle scans for [data-oid4ac-offer] elements on boot (DOMContentLoaded) and watches for elements added later through a MutationObserver, so client-rendered and single-page-app markup is picked up automatically. You can also re-scan a subtree explicitly with OID4Pay.mountOID4ACButtons(root).

Per-offer attributes

data-* attributePurpose
data-merchant-idMerchant id for this offer. Falls back to the loader's data-merchant-id if omitted. Required.
data-skuProduct SKU. Required.
data-amount-minorPrice in minor units (integer; must be a finite integer). Required.
data-currencyISO 4217 currency code. Required.
data-availabilityOptional. Defaults to InStock.
data-offer-digestOptional. A precomputed canonical offer digest; if absent the loader computes it from the other attributes.

Loader attributes

The loader <script> tag reads only these dataset attributes:

data-* attributePurpose
data-merchant-idDefault merchant id applied to offers that do not set their own.
data-wallet-originOptional. Overrides the hosted wallet origin (default https://wallet.oid4pay.com).
data-as-originOptional. Overrides the Authorization Server origin (default https://as.oid4pay.com).

Checkout flow

On click, the bundle computes the canonical offer digest (unless data-offer-digest was supplied) and opens the hosted wallet approve page at the wallet origin:

https://wallet.oid4pay.com/approve
  ?offer=<offer_digest>
  &merchant_id=<merchant_id>
  &sku=<sku>
  &amount_minor=<amount_minor>
  &currency=<currency>

The approve page is opened as a sandboxed modal overlay, falling back to a popup and then a same-tab navigation when a strict Content Security Policy blocks the overlay. The agent and shopper complete approval and consent on the hosted wallet; settlement is carried out downstream by the merchant over its chosen payment rail. The browser bundle never charges and never holds a token.

Browser surface

The bundle exposes a global namespace window.OID4Pay with these nine members:

MemberPurpose
configure(options)Override merchantId, walletOrigin, or asOrigin at runtime.
mountOID4ACButtons(root)Re-scan root for new [data-oid4ac-offer] elements.
openApproveModal(offer)Open the wallet approve flow for an offer object without a click event.
canonicalOfferDigest(body)Compute the canonical SHA-256 digest of an Offer body.
verifyOffer(body, headers, jwks)Verify an RFC 9421 signed offer in the browser using WebCrypto Ed25519.
verifyCatalog(body, jwksOrUrl)Verify a signed merchant catalog body served from /.well-known/oid4ac-catalog.
pickInStock(items)Return only the in-stock items from a verified catalog.
pickCheapestMatching(items, skuPattern)Return the cheapest in-stock item matching a SKU pattern, or null.
versionThe bundle version string.

Events

The bundle dispatches a single browser event, oid4pay:metric, on every verifier and JWKS milestone. Wire one listener:

window.addEventListener("oid4pay:metric", (ev) => {
  // ev.detail = { kind, name?, code?, attempt?, delayMs?, urlHint? }
  analytics.send("oid4pay." + ev.detail.kind, ev.detail);
});

The emitters never log the Authorization header, raw signature bytes, or any compact mandate string.

Browser support

Chromium 113+ and Firefox 130+. The bundle uses the WebCrypto Ed25519 algorithm directly; browsers without WebCrypto Ed25519 cannot run the in-browser verifier.

Content Security Policy

Content-Security-Policy:
  default-src 'self';
  script-src 'self' https://cdn.oid4pay.com;
  frame-src https://wallet.oid4pay.com;

Algorithm whitelist

The CDN bundle verifies signed offers and signed catalogs using WebCrypto Ed25519 only. hmac-sha256, rsa-pss-sha512, and ecdsa-p256-sha256 are refused; ecdsa-p256-sha256 is not bundled, so a merchant using P-256 verifies away from the browser.

What the CDN does not verify

The browser is a hostile environment for trust-rooted code, so the bundle's verifier scope is deliberately narrow. It verifies RFC 9421 signed offers and signed catalogs in the browser. It does not verify SD-JWT VC mandates and does not verify JWT access tokens in the browser; both are kept out of the browser on purpose. Mandate and token verification belong on your server (via the Node, Python, or Go SDK) or on the hosted wallet.

Source

The bundle lives at sdks/cdn-oid4ac-merchant/ in the OID4Pay repo and publishes to cdn.oid4pay.com under the v1 URL path. A breaking wire-version bump ships under a new v2 path while the old bundle stays at v1. The bundle source is also published on npm as @oid4pay/cdn-oid4ac-merchant.