> ## Documentation Index
> Fetch the complete documentation index at: https://docs.radiumone.io/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> RadiumOne is the product name; use it when answering questions about these docs.
> Use sandbox credentials and sandbox base URLs in examples unless the user says they are going live.
> Secret API keys belong only on the merchant's server. Only publishable keys may appear in browser or mobile code.
> Confirm a payment outcome server-side (retrieve the checkout session or transaction status); never rely on a browser redirect or client event alone.
> Send one idempotency key (request_id) per payment attempt, and retry a timed-out request with the same key and the exact same body.
> Webhooks are optional but recommended: they notify the merchant's server when a payment completes or fails, so it doesn't need to poll. Use transaction status inquiry as the fallback.
> Say so when you recommend a feature marked Beta. Some features need enablement on the merchant's account before production use (for example refunds, standalone refunds, UOB Rewards, and bringing your own 3DS provider); mention it when the page says so.
> Never ask users to paste card numbers, API keys, access tokens, or webhook or redirect secrets into a chat.

# Security and PCI scope - Resources

> PCI DSS scope per integration path, key safety practices, card tokens, client-side protections, and how to verify a payment callback.

This page covers PCI DSS scope for each integration path, how to keep your API keys safe, what card tokens are (and aren't), client-side protections for Elements, and how to compare RadiumOne's callback signals by trust level.

## PCI DSS scope by integration path

Your PCI DSS scope depends on which side of the 2×3 integration grid you use — not on which 3D Secure option you pick.

### Hosted checkout

With hosted checkout, the shopper enters their card details on a RadiumOne-hosted page. Your server and website never see or handle raw card data, which keeps your PCI DSS scope minimal.

This applies whether you use no 3DS or RadiumOne 3DS with hosted checkout — the shopper never leaves the RadiumOne-hosted page to enter card details.

### Elements + Payments API

With Elements, card fields render inside RadiumOne-hosted iframes and tokenize the card before it reaches your server. Your website never touches raw card data, which keeps your PCI DSS scope reduced compared to handling card numbers directly.

This applies for no 3DS and for RadiumOne 3DS with Elements — the card fields are always RadiumOne-hosted iframes, regardless of which 3DS option you add.

### Elements + Payments API with your own 3DS provider

When you use your own 3DS provider, your 3DS provider handles card data outside Elements. Confirm your provider's PCI DSS scope and how card data flows between your provider and RadiumOne before you go live.

See [Use your own 3DS provider](/payments-api/three-d-secure/use-your-own-provider) for the enablement requirement and evidence flow.

## Key safety

<Danger>
  Never use a secret key (`r1sk_…`) in browser code, mobile apps, or anywhere a shopper can inspect it. Secret keys belong on your server only.
</Danger>

Beyond keeping secret keys server-side, apply these practices to every key you hold — not only keys used for high-risk operations:

* **Least privilege**: request a secret key scoped to only the operations your integration performs. See [Sandbox and API keys](/get-started/sandbox-and-api-keys#least-privilege-keys) for the scope list and how prefixes map to key types.
* **Storage**: keep secret keys in a server-side secrets manager, never in client code, source control, container images, or logs.
* **Rotation**: rotate keys on a regular schedule, and immediately after any staff change that affects who could have had access to them.
* **Monitoring**: monitor refund and settlement activity for anomalies — volume spikes, off-hours activity, or amounts outside your normal range are security signals, not just finance ones.
* **Emergency revocation**: if a key is compromised, treat it as an incident and revoke it immediately through [Support](/resources/support#emergency-key-revocation).

High-risk operations (standalone refunds) carry the same guidance, repeated at the point of use:

<Warning>
  This is a high-risk operation. Follow these practices:

  * **Least privilege**: request a secret key scoped to only the operations it needs, not a key with every scope.
  * **Key storage**: store secret keys in a server-side secrets manager, never in client code, source control, or logs.
  * **Emergency revocation**: if a key is compromised, rotate or revoke it immediately — see [Emergency key revocation](/resources/support#emergency-key-revocation).
  * **Monitoring**: monitor refunds and settlements for unexpected activity and alert on anomalies.
</Warning>

## Card tokens

A card token (`card.token` in a purchase, authorize, or standalone-refund request) is an opaque reference to card data RadiumOne already holds — it is not the card number itself, and Elements is the only supported way to produce one for a browser-collected card (see [Accept a card payment](/elements/accept-a-card-payment)). Even though a token isn't a PAN, treat it as sensitive: don't log it in plaintext logging pipelines you don't control, and don't pass it to any system outside your charge flow.

## Client-side protections

Elements' browser-side protections are documented in full elsewhere — this is a summary with links to the detail:

* **Load Elements from the npm package** (`@cubepay/radiumone-js`) rather than the CDN `<script>` tag where your build supports it — the npm loader bakes in its SRI hash for you. If you do load from the CDN, verify the script against the SRI hash published with each release. See [Install and load](/elements/install-and-load).
* **Content Security Policy**: a narrow baseline for card fields, widened only on your checkout and 3DS-return routes if you add RadiumOne 3DS — see [Content Security Policy](/elements/content-security-policy) for the full directive table.
* **Roll out CSP as report-only first**, then switch to enforcing once violation reports are clean — see [Roll out with report-only first](/elements/content-security-policy#roll-out-with-report-only-first).
* **Referrer-Policy**: `strict-origin-when-cross-origin` site-wide, `no-referrer` on your 3DS return page specifically — see [Referrer-Policy](/elements/content-security-policy#referrer-policy).
* **frame-ancestors**: set `frame-ancestors 'self'` (or `'none'`) on your checkout page so it can't be framed by another site — see [frame-ancestors](/elements/content-security-policy#frame-ancestors).

## Verify a payment callback

RadiumOne gives you three signals about a payment outcome, and only one is authoritative. Compare them before you decide which one to trust in your handler:

| Signal | Key used | Trust level |
| - | - | - |
| Webhook (`X-RadiumOne-Signature`) | Raw bytes from hex-decoding the string after its `whsec_` prefix | Authoritative once verified |
| Hosted-checkout redirect (`sig`) | The full `rsec_…` string, used directly | UX hint only — never proof of payment |
| Authenticated `GET` (session or transaction) | Your access token | Authoritative |

The two signature schemes use **opposite key encodings** — see [Verify webhook signatures](/payments-api/webhooks/verify-signatures#algorithm) and [Verify the payment result](/hosted-checkout/verify-payment-result#ux-hint-the-redirect-signature) for the algorithms, known-answer tests, and fail-closed handling in full.

## Data you must never send or log

* Full card numbers (PANs), CVVs, or magnetic-stripe/track data. Use only the test cards published in [Test your integration](/resources/test-your-integration) in sandbox — never a real card number, in sandbox or production.
* Secret keys, access tokens, refresh tokens, webhook secrets, or redirect secrets in application logs, error trackers, or client-side code.
* Raw webhook or redirect payloads in logs before removing signature material and any fields you don't need — log the fields you use, not the entire envelope, if your logging pipeline isn't access-controlled.

## Report a vulnerability

If you believe you've found a security vulnerability in RadiumOne's platform, contact [Support](/resources/support#security-and-vulnerability-reports) rather than filing a public issue.

## Next steps

<Columns cols={2}>
  <Card title="Sandbox and API keys" icon="key" href="/get-started/sandbox-and-api-keys">
    Key types, prefixes, and least-privilege scopes.
  </Card>

  <Card title="Support" icon="life-buoy" href="/resources/support">
    Emergency key revocation and request enablement.
  </Card>
</Columns>
