Skip to main content
Guest checkout lets new customers buy crypto with Apple Pay or Google Pay before they have a MoonPay account. Customers buy first: MoonPay creates a guest account at transaction time and requests verification only when a purchase requires it, through a step-up challenge. This is the deferred-verification onboarding path, the alternative to verifying customers before their first purchase. You supply the customer’s email address and phone number when you create the session. Both are required: without them, guest checkout is not offered. MoonPay creates the guest account from the wallet sheet: Apple Pay billing contact, or Google Pay billing. Returning customers are recognized automatically and connect instead. Guest checkout is available for customers in the United States, excluding New York and Washington. See Going live for the requirements you must meet before taking this integration to production.

Prerequisites

  • Guest checkout enabled on your partner account. Contact your MoonPay account team.
  • A server that can create session tokens with your secret key.
  • A UI surface where you can render the Apple Pay frame, the Google Pay frame, and the challenge frame. Offer the wallet that matches the customer’s environment; you do not need both buttons on every surface.
  • The customer’s email address and phone number, captured in your own UI and passed when you create the session. Guest checkout requires both. MoonPay renders no field for either one in the payment flow.
  • Your responsibility. Confirm the customer owns the email address and the phone number by sending a one-time passcode before you create the session. Re-verify the phone number at least once every 30 days. MoonPay accepts both fields as partner-verified and does not re-verify them, so passing them is your attestation that verification occurred. See Verify phone numbers before you submit them.
  • The timestamp at which the customer accepted MoonPay’s terms (see Record terms acceptance).
You can test the full flow in test mode. Test mode uses simulated payments so no real assets are transferred. Apple Pay and Google Pay each have a dedicated mock button: Apple Pay and Google Pay.

How it works

  1. Your server creates a session that includes the customer’s email, phone number, and terms acceptance.
  2. You check the connection, which returns the customer’s capabilities. When capabilities.guestCheckout is present, offer Apple Pay or Google Pay on the guest path; otherwise connect the customer with the standard flow.
  3. You get a quote for apple_pay or google_pay. A quote that comes back executable: true is ready to use.
  4. A quote for more than the customer’s guest limit comes back executable: false, and carries a challenge when the customer can raise that limit without full verification. You render the challenge, then quote again. See Upgrade a guest account.
  5. You render the matching payment frame (Apple Pay at /platform/v1/apple-pay, or Google Pay at /platform/v1/google-pay).
  6. On the customer’s first purchase, MoonPay creates the guest account from the wallet billing details and processes the payment. If extra verification is needed, the frame emits a challenge that resolves the purchase.

Device and browser support

Offer the wallet the customer’s environment supports. When a wallet isn’t available, the frame emits unsupported — hide that button and offer the other wallet or a connected-customer flow.
Apple Pay is available in Safari on macOS and in every iOS browser. The customer also needs a card set up in Apple Pay.In other browsers, the frame reports Apple Pay as unavailable and renders nothing. It does not offer Apple’s cross-device QR flow. The widget does support that flow.In a native iOS app, embed the Apple Pay frame in a WKWebView and handle JavaScript dialogs through WKUIDelegate. See the frame requirements and the iOS manual integration guide.
For connected-customer Apple Pay and Google Pay (after login), see Pay with Apple Pay and Pay with Google Pay.

Record terms acceptance

Present MoonPay’s Terms of Use and Privacy Policy in your UI using one of the presentation methods, and capture the timestamp when the customer accepts. Pass it as termsAcceptedAt when you create the session: MoonPay records the live terms version at that moment and binds the acceptance to the guest account. For the rendering rules and the records you keep once customers accept, see Terms acceptance. termsAcceptedAt must be no more than 60 seconds ahead of server time. Capture it the moment the customer taps your accept control, then create the session immediately.

Create a session

Create the session on your server with your secret key. For guest checkout, include the customer’s email, phoneNumber, and termsAcceptedAt alongside the standard fields. The sessions endpoint accepts all three as optional fields, because the other onboarding paths do not need them. Guest checkout does. A session created without email or phoneNumber still returns 200, and capabilities.guestCheckout is absent from the connection in the next step.
See the sessions API reference for all fields and error responses.
Passing termsAcceptedAt requires the Identity or Guest Checkout account capability. Without one of those two, the session fails with 503 and the code service_unavailable. The message reads “This service is temporarily unavailable”. The cause is not temporary: the capability is not enabled on your account. Contact your MoonPay account team instead of retrying.
If the customer’s region is not supported, the session still succeeds. The guestCheckout capability is absent in the next step, and you connect the customer with the standard flow instead.

Check for guest checkout

Pass the sessionToken to the client and check the connection. The check runs in an invisible frame and returns the customer’s capabilities. When capabilities.guestCheckout is present, offer Apple Pay or Google Pay on the guest path. You can also check the session manually.
A returning customer whose email and phone match an existing MoonPay account is recognized at this step. Connect them with the standard flow: low-friction authentication prompts for a one-time passcode instead of a full login.
If mismatch is true on a connectionRequired result, the session’s email and phone number resolve to different MoonPay customers. Route the customer through the connect flow before rendering Apple Pay or Google Pay.

When guestCheckout is absent

In every condition below, the session and the connection check both succeed. Nothing errors, so there is no error message to inspect. Check these in order: Region eligibility comes from the deviceIp you pass when you create the session. Pass the customer’s real client IP, not your server’s. An IP that MoonPay cannot resolve to a supported state counts as unsupported, so guestCheckout is absent. It is also absent for a phone number from outside the United States, even when the IP resolves to a supported state. Gate the wallet buttons on capabilities.guestCheckout being present. Rendering them on the guest path without it fails the transaction.

Get a quote

Request an executable quote for the wallet you will render. Only quotes with executable: true can be used to execute a transaction.
A quote for more than the customer’s guest limit comes back executable: false. When the customer can raise that limit by verifying a little more about themselves, the quote also carries a challenge. Do not render the payment frame with that quote. Resolve the challenge first, then quote again. See Upgrade a guest account.

Render the payment frame

Render the Apple Pay or Google Pay frame with the quote signature. When the customer taps the button and authorizes, MoonPay creates the guest account from the wallet name and billing address, then processes the payment. /platform/v1/google-pay is the primary Google Pay URL for this flow. Do not use the buy button for guest checkout: that path expects a connected customer.
Apple Pay

Handle verification

This section covers the challenge the payment frame emits after the customer authorizes. A quote can carry a challenge of its own, before you render a payment frame at all. That one is a limit upgrade, covered in Upgrade a guest account. Some guest purchases need the customer to complete an extra step before the payment goes through. Second-factor authentication (for example, confirming identity when email and phone match an existing account, or authenticating when the purchase is larger than the guest limit allows) and KYC step-up (providing more identity details) both surface as the same challenge event. You render the challenge frame the same way in every case. See Handle challenges for the full flow. The payment frame emits challenge with a URL. Render the challenge frame at that URL. The challenge frame guides the customer through the required steps and completes the purchase itself, then emits complete. You do not re-render the Apple Pay or Google Pay button. An amount above the customer’s maximum limit that verification cannot raise is terminal. The frame emits complete with status: "failed" and failureCode: "transactionNotAllowed". Prompt the customer to try a smaller amount.

Upgrade a guest account

A guest account is a real MoonPay account with lower limits. There are two ways to raise them. A step-up lifts the guest limit in place and keeps the customer on the guest path. Full verification lifts the limits further and moves the customer off the guest path entirely.

Raise the limit with a step-up

When a customer quotes for more than their guest limit allows, MoonPay can offer to raise that limit in exchange for their date of birth and the last four digits of their Social Security number. The customer stays a guest and never completes full verification. MoonPay decides who qualifies. Eligibility depends on the amount the customer is quoting for, on their history with MoonPay, and on the capability being enabled for your account. The rules shift with MoonPay’s compliance decisions, so do not model them yourself: the quote tells you.
The step-up is enabled per partner, and separately from guest checkout itself. To request it, contact your MoonPay account team at team@moonpay.com. Without it, quotes never carry a challenge, and an over-limit purchase fails with failureCode: "transactionNotAllowed".
The step-up needs @moonpay/platform-sdk-web or @moonpay/platform-sdk-react-native 1.15.2 or later. Earlier versions omit the client token from the challenge frame URL and the frame fails to load. Detect the limit on the quote. An eligible over-limit quote returns executable: false and a challenge object. Branch on challenge being present rather than comparing the amount against a limit yourself. Render the challenge frame. Pass challenge.url to setupChallenge() unchanged. This is the same challenge frame the card and identity flows use, running its guest_checkout_limit_upgrade flow. MoonPay collects and validates the date of birth and the SSN digits inside the frame, so neither value passes through your code. Act on the result. The frame emits complete with a status: Tear the frame down. Call dispose() on complete, cancelled, and error. On rejected the frame keeps its own message on screen, so removing it is your call.
On cancelled, nothing was submitted. Offer a retry: render the frame again at the same URL, or quote again for a fresh challenge.url if the old one has expired.

Complete full verification

To lift the limits beyond what a step-up reaches, connect the customer and have them complete full identity verification. The limits lift on the same account, with no migration. Use the connect flow, then guide the customer through verification. You can prompt this after a completed guest purchase, when a purchase exceeds the guest limit, or when a step-up comes back rejected.

Transaction statuses

Transactions have the following statuses:
  • Pending: The transaction has been initiated and the payment accepted. The assets are being transferred.
  • Complete: The transaction is finalized. The payment is complete and the assets have been delivered to their destination.
  • Failed: The transaction has failed. The payment was not executed and funds were not transferred.

Next steps

Pay with Apple Pay

Connected-customer Apple Pay after login.

Pay with Google Pay

Connected-customer Google Pay after login.

Apple Pay frame

Frame URL, size, permissions, and events.

Google Pay frame

Frame URL, size, permissions, and events.

Handle challenges

Render the challenge frame when a quote or a purchase needs extra verification.

Challenge frame

Frame URL, events, and the guest_checkout_limit_upgrade payloads.

Terms acceptance

Present terms and record termsAcceptedAt.