Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.ozura.com/llms.txt

Use this file to discover all available pages before exploring further.

The /preview endpoint renders a fully interactive checkout page backed by a stub session — no database round-trip, no API keys required. It is designed for embedding inside a dashboard theme editor so merchants can see appearance changes in real time.

URL

GET https://checkout.ozura.com/preview
No authentication headers are required. The page is publicly accessible.

Embed as an Iframe

<iframe
  id="checkout-preview"
  src="https://checkout.ozura.com/preview"
  style="width: 100%; height: 700px; border: none; border-radius: 12px;"
></iframe>

Sending Appearance Updates

Once the preview iframe loads, send appearance changes via postMessage. The preview page listens for ozura-preview-appearance messages and applies them live using the same applyAppearanceConfig function used by real checkout sessions.
const iframe = document.getElementById('checkout-preview');

function updatePreview(appearance) {
  iframe.contentWindow.postMessage(
    { type: 'ozura-preview-appearance', appearance },
    'https://checkout.ozura.com'
  );
}

// Example: change primary button colour
updatePreview({ primaryColor: '#8b5cf6', borderRadius: 'lg' });
Always specify the target origin ('https://checkout.ozura.com') as the second argument to postMessage. Passing '*' allows any page to intercept the message.

Appearance Message Shape

{
  "type": "ozura-preview-appearance",
  "appearance": {
    "primaryColor": "#8b5cf6",
    "backgroundColor": "#0f0a1a",
    "borderRadius": "lg",
    "fontFamily": "Inter, sans-serif"
  },
  "merchantName": "My Store"
}
FieldTypeRequiredDescription
typestringYesMust be "ozura-preview-appearance"
appearanceobjectNoAny fields from the Appearance Reference. Only the fields you include are updated; others stay at their current values
merchantNamestring (max 200 chars)NoUpdates the merchant name shown in the checkout header in real time. Omit to leave the current name unchanged

Ready Event

The preview page fires ozura-preview-ready as soon as it mounts. Listen for this event before sending appearance updates to avoid messages being dropped before the listener is registered.
window.addEventListener('message', (event) => {
  if (
    event.origin === 'https://checkout.ozura.com' &&
    event.data?.type === 'ozura-preview-ready'
  ) {
    // Safe to send appearance now
    updatePreview(myCurrentAppearance);
  }
});

Stub Session

The preview runs against a fixed in-memory session:
FieldValue
Amount$49.99
CurrencyUSD
Modepayment
CartSingle item — “Sample Product”
Merchant name"Your Store"
Statuspending (payment form is fully visible)
The Pay button is rendered and interactive but will fail gracefully if clicked — there is no real vault key or payment processor connection. This is intentional: the preview is for visual inspection only.

Limitations

  • Cannot test actual payments
  • successUrl, cancelUrl, errorUrl are set to # — no redirect occurs
  • The session ID is "preview" — it does not exist in the database
  • Changes made via postMessage are in-memory only and reset on page reload
  • The preview page ignores messages from opaque origins (null, file://, sandboxed iframes). The parent page must be served over HTTP/HTTPS with a real origin for postMessage to be accepted. The preview pins to the first origin it receives a message from — subsequent messages from a different origin are dropped.

Full Integration Example

<!DOCTYPE html>
<html>
<head>
  <title>Theme Editor</title>
</head>
<body>
  <label>
    Primary Color
    <input type="color" id="primaryColor" value="#9693FE" />
  </label>

  <iframe
    id="checkout-preview"
    src="https://checkout.ozura.com/preview"
    style="width: 480px; height: 700px; border: none;"
  ></iframe>

  <script>
    const iframe = document.getElementById('checkout-preview');
    const primaryColorInput = document.getElementById('primaryColor');

    // Wait for the preview to signal it is ready
    window.addEventListener('message', (event) => {
      if (
        event.origin !== 'https://checkout.ozura.com' ||
        event.data?.type !== 'ozura-preview-ready'
      ) return;

      // Send initial appearance
      sendAppearance();
    });

    primaryColorInput.addEventListener('input', sendAppearance);

    function sendAppearance() {
      iframe.contentWindow.postMessage(
        {
          type: 'ozura-preview-appearance',
          appearance: { primaryColor: primaryColorInput.value }
        },
        'https://checkout.ozura.com'
      );
    }
  </script>
</body>
</html>