Skip to navigation

Embed Events

Messages the embedded onboarding and information request iframes post to your page, and how to listen for them safely.

The onboarding and information request (RFI) iframes post messages to the page that frames them with window.postMessage. Use them to size the iframe and to react in your page while the sub-merchant works. For server-side updates, use onboarding webhooks.

How messages are sent

  • Messages are only posted to the parentOrigin the embed session was minted with, never to '*'.
  • Nothing is posted until the iframe has confirmed it’s running on an approved site.
  • Nothing is posted for link-only sessions, since there’s no parent page.
  • Payloads never contain form values or personal data.

Every message has the same envelope:

{
source: 'coinflow';
version: 1;
type: string; // one of the types below
payload: object; // depends on type
}

Listening safely

Check three things before you trust a message: that it comes from the Coinflow origin, from your own iframe, and has the Coinflow envelope.

Browser
const COINFLOW_ORIGIN = 'https://sandbox-merchant.coinflow.cash'; // https://merchant.coinflow.cash in production
const iframe = document.getElementById('coinflow-onboarding') as HTMLIFrameElement;
window.addEventListener('message', event => {
if (event.origin !== COINFLOW_ORIGIN) return;
if (event.source !== iframe.contentWindow) return;
const message = event.data;
if (message?.source !== 'coinflow' || message.version !== 1) return;
handleCoinflowMessage(message);
});

Ignore types you don’t recognize. New types and new payload fields can be added within the same version.

Onboarding events

Posted by /embed/onboarding.

typepayloadWhen
onboarding.heightChanged{height}The content height changed. height is in CSS pixels; set the iframe’s height to it.
onboarding.ready{status, stepKey?}Once each time onboarding loads. stepKey is the step it opened on. After the application is submitted, it’s the first step still needing action, such as wallet, and absent when there is none.
onboarding.stepChanged{status, stepKey, stepStatus}The sub-merchant moved to another step, or finished one (stepStatus: 'complete'). The iframe grows instead of scrolling, so scroll it into view here.
onboarding.submitted{status}The sub-merchant submitted its application during this visit.
onboarding.error{code, message}Something failed. message is a fixed, human-readable string.
  • status is the onboarding status, the same value Get Onboarding returns: not_started, in_progress, submitted, action_required, approved or declined.
  • stepKey is a step key from the same endpoint, such as profile, verification or wallet. stepStatus is that step’s status: blocked, action_required, in_review or complete.

Information request events

Posted by /embed/rfi/{rfiId}. See Information Requests.

typepayloadWhen
rfi.heightChanged{height}The content height changed. height is in CSS pixels; set the iframe’s height to it.
rfi.ready{rfiId, status}Once each time the RFI loads.
rfi.submitted{rfiId, status}The sub-merchant submitted its answers during this visit.
rfi.error{rfiId, code, message}Something failed. message is a fixed, human-readable string.

status is the RFI’s status, the same value List RFIs returns: open, reopened, submitted, completed or cancelled.

Error codes

codeMeaningWhat to do
session_expiredThe embed session reached its 8-hour limit or was revokedMint a new session and reload the iframe
load_failedThe page couldn’t load its dataOffer a retry that reloads the iframe
save_failedThe sub-merchant’s changes couldn’t be savedThe iframe shows the error; no action needed unless it repeats
not_foundRFI events only: the RFI doesn’t exist, isn’t this sub-merchant’s, or was never sentCheck the rfiId
unexpectedAny other failureOffer a retry that reloads the iframe

Treat any other code like unexpected.