Skip to main content

addCoinbaseOnrampOrderEventListener

Adds a listener for Coinbase onramp order events. This function listens for postMessage events from the Coinbase payment iframe, allowing you to track the order status in real-time. This function is designed to be used with createCoinbaseOnrampOrder when displaying the payment flow in an embedded iframe.

Usage

import { addCoinbaseOnrampOrderEventListener } from "@dynamic-labs-sdk/client";

const removeListener = addCoinbaseOnrampOrderEventListener({
  listener: (event) => {
    console.log("Event:", event.eventName, event.data);
  },
});

// Later, remove the listener when done
removeListener();

Parameters

ParameterTypeDescription
listener(event: { eventName: string; data: Record<string, unknown> }) => voidCallback function called when an event is received from the Coinbase iframe.
clientDynamicClient (optional)The Dynamic client instance. Only required when using multiple clients.

Returns

() => void - A function to remove the event listener. Always call this when cleaning up to prevent memory leaks.

Event Names

The following events are emitted by the Coinbase payment iframe:
Event NameDescription
onramp_api.cancelUser cancelled the payment flow.
onramp_api.commit_successPayment was authorized successfully. Transaction is being processed.
onramp_api.commit_errorPayment authorization failed. event.data.errorMessage contains details.
onramp_api.polling_successTransaction completed successfully. Crypto has been sent.
onramp_api.polling_failedTransaction failed after payment. event.data.errorMessage contains details.
For a complete list of events, see the Coinbase Onramp documentation.

Complete Example

Here’s how to use this function with createCoinbaseOnrampOrder:
import { useState, useRef, useEffect } from "react";
import {
  createCoinbaseOnrampOrder,
  addCoinbaseOnrampOrderEventListener,
} from "@dynamic-labs-sdk/client";

const CoinbasePayment = ({ walletAddress }) => {
  const [paymentUrl, setPaymentUrl] = useState(null);
  const [message, setMessage] = useState("");
  const removeListenerRef = useRef(null);

  const startPayment = async () => {
    // Create the order
    const order = await createCoinbaseOnrampOrder({
      agreementAcceptedAt: new Date(),
      destinationAddress: walletAddress,
      destinationNetwork: "base",
      paymentCurrency: "USD",
      paymentMethod: "GUEST_CHECKOUT_APPLE_PAY",
      purchaseAmount: "50",
      purchaseCurrency: "USDC",
      isSandbox: true,
    });

    if (order.paymentLink?.url) {
      setPaymentUrl(order.paymentLink.url);

      // Set up event listener AFTER creating the order
      removeListenerRef.current = addCoinbaseOnrampOrderEventListener({
        listener: (event) => {
          switch (event.eventName) {
            case "onramp_api.cancel":
              setMessage("Payment cancelled");
              cleanup();
              break;

            case "onramp_api.commit_success":
              setMessage("Payment authorized! Processing transaction...");
              break;

            case "onramp_api.commit_error":
              setMessage(`Payment failed: ${event.data.errorMessage}`);
              cleanup();
              break;

            case "onramp_api.polling_success":
              setMessage("Transaction complete! Crypto sent to your wallet.");
              cleanup();
              break;

            case "onramp_api.polling_failed":
              setMessage(`Transaction failed: ${event.data.errorMessage}`);
              cleanup();
              break;
          }
        },
      });
    }
  };

  const cleanup = () => {
    removeListenerRef.current?.();
    removeListenerRef.current = null;
    setPaymentUrl(null);
  };

  // Always cleanup on unmount
  useEffect(() => {
    return () => {
      removeListenerRef.current?.();
    };
  }, []);

  return (
    <div>
      {message && <p>{message}</p>}

      {!paymentUrl ? (
        <button onClick={startPayment}>Buy USDC</button>
      ) : (
        <div>
          <iframe
            src={paymentUrl}
            width="100%"
            height="500px"
            allow="payment"
            title="Coinbase Payment"
          />
          <button onClick={cleanup}>Cancel</button>
        </div>
      )}
    </div>
  );
};

Important Notes

  1. Always remove the listener - Call the returned cleanup function when the payment flow ends (success, error, or cancel) and when your component unmounts.
  2. Set up listener after creating order - Add the event listener after calling createCoinbaseOnrampOrder and before displaying the iframe.
  3. Browser only - This function only works in browser environments. It will throw an error if window is not available (e.g., during SSR).
  4. Events come from pay.coinbase.com - The listener only processes events from Coinbase’s payment domain for security.