Skip to main content
This integration is currently in preview and subject to change.
Connect a customer’s MoonPay account so you can list payment methods, get executable quotes, and execute transactions. Before you start, review the requirements.

Prerequisites

  • A server that can create session tokens with your secret key.
  • A client that can render frames (SDK or manual integration).
Connecting is a one or two-step process depending on whether the customer is new or returning:
  • If the customer has never connected, render the co-branded connect frame.
  • If the customer has connected before, first check whether their connection is still valid. You only need to render UI again if the connection has expired.
For all cases, first create a session, then check if a connection exists. If a connection is required, initialize the connect flow.

Create a session

To initiate a session on your server, provide:
  1. A unique identifier from your system for the customer.
  2. The IP address of the customer’s device. This is used across frames to ensure the integrity of the session.
Once initiated, you receive a sessionToken to send to your frontend.
// Server-side code example
const url = "https://api.moonpay.com/platform/v1/session";

const res = await fetch(url, {
  headers: {
    "Content-Type": "application/json",
    Authorization: "Api-Key sk_test_123",
  },
  method: "POST",
  body: JSON.stringify({
    externalCustomerId: "your_user_id",
    deviceIp: "...ip address from client",
  }),
});

console.log(await res.json());
Check the API reference for detailed usage.

Check connection

Using the sessionToken, check if the customer already has an active connection. No UI appears in this step, but it runs in a frame. You can check the session using the SDK or manually.
import { createClient } from "@moonpay/platform";

// Create the client with your session token
const clientResult = createClient({
  sessionToken: "c3N0XzAwMQ==", // The session token from your server
});

if (!clientResult.ok) {
  // Handle error creating client
}

const client = clientResult.value;

// Check if the customer has an active connection
const connectionResult = await client.getConnection();

if (!connectionResult.ok) {
  // Handle error
}

console.log(connectionResult.value);
The SDK injects an invisible frame to check the connection. If you are integrating without the SDK, load the frame directly and listen for the postMessage events.

Connect flow

If you need to create or revalidate a connection, initialize the connect flow with your sessionToken. The SDK provides hooks to coordinate rendering the connect UI (for example, to animate a modal or sheet). You can also do this manually. The resulting connection has one of the following statuses: active, pending, unavailable, or failed.
In mobile apps, present the connect flow as a full sheet. See presentation and appearance for UI guidance.
import { createClient, type ConnectEvent } from "@moonpay/platform";

// Create the client
const clientResult = createClient({
  sessionToken: "c3N0XzAwMQ==", // The session token from your server
});

if (!clientResult.ok) {
  // Handle error creating client
}

const client = clientResult.value;

// Initialize the connect flow
const connectResult = await client.connect({
  container: connectContainer, // DOM element to render the connect frame

  theme: { appearance: "dark" }, // Optional: force dark or light mode

  onEvent: (event: ConnectEvent) => {
    switch (event.kind) {
      case "ready":
        // The frame is ready and rendered
        break;

      case "complete":
        // The connection is complete
        console.log(event.connection);
        // { status: "active", credentials: { accessToken: "...", clientToken: "..." } }

        // You can unmount the frame using the reference in the payload
        event.payload.frame.dispose();
        break;

      case "error":
        // Handle error
        console.error(event.payload.message);
        break;
    }
  },
});

// If there is an error setting up the connect frame, no events will be
// dispatched via the `onEvent` callback and you will receive an error here.
if (!connectResult.ok) {
  // Handle error
}

// If the frame is successfully mounted, the returned value provides a reference for disposal at any time.
connectResult.value.dispose();
When you receive the complete event, the payload includes the client credentials you use for the rest of the integration. These credentials let you make scoped API calls from your frontend (for example, listing payment methods and getting quotes). See Pay with Apple Pay for a complete example flow.
Client credentials should never be persisted and should only be held in memory as this could pose a security risk.

Connection statuses

Active

An active status means the connection is valid and can be used. Active connections typically remain live for 180 days without revalidation. If the connection expires, refresh it via the connect flow.

Unavailable

An unavailable status means the connection cannot be used at the current time. This typically occurs when a KYC-verified customer is using a device or application from a restricted location.

Pending

A pending status typically occurs for customers whose KYC decisions are delayed. Often these cases are resolved out of band and the customer can connect on a subsequent visit to your app.

Failed

A failed status is a terminal state. This usually happens if the customer fails KYC or cannot be onboarded to MoonPay. It can also happen if the customer rejects the connection. In these cases, direct the customer to an alternate flow in your app.

Connection required

The connectionRequired status is returned from the check frame as a signal to guide the customer through the full connect flow. This status is returned for new customers who have not connected to your app, or returning customers whose connections have expired.