> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dynamic.xyz/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Coinbase Onramp (Apple Pay, No KYC)

> Enable users to purchase up to $500 in cryptocurrency using Coinbase's Apple Pay Guest Checkout without KYC

<Card title="Recommended: JavaScript SDK with React Hooks" icon="react" color="#4779FE">
  For new React apps, we recommend the JavaScript SDK with React Hooks (`@dynamic-labs-sdk/react-hooks`) instead of the legacy React SDK documented here. The JS SDK comes with many benefits such as a much smaller bundle size and other optimizations. Use the [React quickstart (JavaScript SDK)](/javascript/reference/react-quickstart) to get started.
</Card>

<Note>
  This guide covers Coinbase's Apple Pay Guest Checkout for purchases under \$500 without KYC. For the default Coinbase onramp experience with full features, see [Default Onramps](/react/money-and-funding/default-onramps) and [Customizing the Onramp Experience](/react/money-and-funding/customizing-the-onramp-experience).
</Note>

<Note>
  This guide is for JavaScript only.
</Note>

## Overview

Coinbase onramp integration allows users to purchase cryptocurrency directly within your application using Coinbase's payment infrastructure. This integration supports Apple Pay Guest Checkout, enabling US users without a Coinbase account to deposit up to \$500 per week.

## Dashboard setup

To enable Coinbase onramp:

1. Go to [the Funding tab in your Dynamic developer dashboard](https://app.dynamic.xyz/dashboard/funding)
2. Under "Fiat on-ramps", toggle on Coinbase
3. Accept any additional terms and conditions
4. Save the settings

## Coinbase-specific functions

The following functions are specific to Coinbase onramp and provide advanced control over the onramp flow.

### createCoinbaseOnrampOrder

Creates a Coinbase onramp order programmatically. This function is useful when you want full control over the order creation process, such as for Apple Pay Guest Checkout.

<Note>
  See Coinbase's [create an onramp order](https://docs.cdp.coinbase.com/api-reference/v2/rest-api/onramp/create-an-onramp-order) documentation for reference.
</Note>

<Warning>
  Call `getMissingVerificationForCoinbaseOnrampOrder` before creating an order to check if any user data needs to be collected or verified. If required information is missing (like a verified phone number), the order will fail.
</Warning>

```javascript theme={"system"}
import { createCoinbaseOnrampOrder } from '@dynamic-labs-sdk/client'

const createOrder = async () => {
  const order = await createCoinbaseOnrampOrder({
    agreementAcceptedAt: new Date(),
    destinationAddress: '0x1234567890123456789012345678901234567890',
    destinationNetwork: 'base',
    paymentCurrency: 'USD',
    paymentMethod: 'GUEST_CHECKOUT_APPLE_PAY',
    purchaseCurrency: 'USDC',
    paymentAmount: '100.00',
    isSandbox: false,
  })

  // order.paymentLink.url contains the URL to redirect the user to
  // or you can embedded the url in an iframe
  if (order.paymentLink) {
    window.open(order.paymentLink.url, '_blank')
  }
}
```

#### Parameters

| Parameter             | Type    | Required | Description                                                                     |
| --------------------- | ------- | -------- | ------------------------------------------------------------------------------- |
| `agreementAcceptedAt` | Date    | Yes      | Timestamp when user accepted Coinbase Terms, User Agreement, and Privacy Policy |
| `destinationAddress`  | string  | Yes      | Wallet address where purchased crypto will be sent                              |
| `destinationNetwork`  | string  | Yes      | Network name (e.g., "base", "ethereum")                                         |
| `paymentCurrency`     | string  | Yes      | Fiat currency code (e.g., "USD")                                                |
| `paymentMethod`       | string  | Yes      | Payment method type (e.g., "GUEST\_CHECKOUT\_APPLE\_PAY")                       |
| `purchaseCurrency`    | string  | Yes      | Crypto ticker or Coinbase UUID (e.g., "USDC", "ETH")                            |
| `paymentAmount`       | string  | No       | Fiat amount to pay (inclusive of fees)                                          |
| `purchaseAmount`      | string  | No       | Crypto amount to receive (exclusive of fees)                                    |
| `isSandbox`           | boolean | No       | Create a sandbox order for testing                                              |
| `partnerUserRef`      | string  | No       | Unique user identifier for transaction linking                                  |
| `domain`              | string  | No       | Domain for Apple Pay button rendering in iframes                                |
| `isQuote`             | boolean | No       | Return a quote without creating a transaction                                   |

#### Response

```typescript theme={"system"}
type CoinbaseOnrampOrderResponse = {
  order: {
    orderId: string
    status: CoinbaseOnrampOrderStatus
    destinationAddress: string
    destinationNetwork: string
    purchaseCurrency: string
    purchaseAmount: string
    paymentCurrency: string
    paymentSubtotal: string
    paymentTotal: string
    exchangeRate: string
    fees: CoinbaseOnrampFee[]
    createdAt: Date
    updatedAt: Date
    txHash?: string
    partnerUserRef?: string
    paymentMethod: CoinbaseOnrampOrderPaymentMethod
  }
  paymentLink?: {
    paymentLinkType: CoinbaseOnrampOrderPaymentLinkType
    url: string
  }
}
```

### getMissingVerificationForCoinbaseOnrampOrder

Checks if the user has the required verified credentials (email and phone number) to create a Coinbase onramp order. This is useful for pre-validating users before attempting to create an order.

```javascript theme={"system"}
import { getMissingVerificationForCoinbaseOnrampOrder } from '@dynamic-labs-sdk/client'

const checkUserVerification = () => {
  const missingFields = getMissingVerificationForCoinbaseOnrampOrder({
    paymentMethod: 'GUEST_CHECKOUT_APPLE_PAY',
  })

  if (missingFields.length > 0) {
    missingFields.forEach((field) => {
      if (field.errorCode === 'MISSING_INFORMATION') {
        console.log(`User needs to provide ${field.field}`)
      } else if (field.errorCode === 'MISSING_VERIFICATION') {
        console.log(`User needs to verify ${field.field}: ${field.data}`)
      } else if (field.errorCode === 'VERIFICATION_EXPIRED') {
        console.log(`User needs to re-verify ${field.field}: ${field.data}`)
      }
    })
  }

  return missingFields.length === 0
}
```

#### Error codes

| Error Code             | Description                                                                                              |
| ---------------------- | -------------------------------------------------------------------------------------------------------- |
| `MISSING_INFORMATION`  | The data still needs to be collected from the user                                                       |
| `MISSING_VERIFICATION` | The data has been collected but not verified                                                             |
| `VERIFICATION_EXPIRED` | The data was verified but needs re-verification (phone numbers must be verified within the last 60 days) |

### addCoinbaseOnrampOrderEventListener

Listens to Coinbase onramp order events to track when an order is canceled, confirmed, completed, or fails. Use this after triggering an order to provide real-time feedback to users.

```javascript theme={"system"}
import { 
  addCoinbaseOnrampOrderEventListener,
  createCoinbaseOnrampOrder 
} from '@dynamic-labs-sdk/client'

const createOrderWithListener = async () => {
  const order = await createCoinbaseOnrampOrder({
    agreementAcceptedAt: new Date(),
    destinationAddress: '0x1234567890123456789012345678901234567890',
    destinationNetwork: 'base',
    paymentCurrency: 'USD',
    paymentMethod: 'GUEST_CHECKOUT_APPLE_PAY',
    purchaseCurrency: 'USDC',
    paymentAmount: '100.00',
  })

  // Set up event listener after order is created
  const removeListener = addCoinbaseOnrampOrderEventListener({
    listener: (event) => {
      if (event.eventName === 'onramp_api.cancel') {
        console.log('Order was canceled')
      }

      if (event.eventName === 'onramp_api.commit_success') {
        console.log('Payment authorized successfully')
      }

      if (event.eventName === 'onramp_api.commit_error') {
        console.log(`Payment failed: ${event.data.errorMessage}`)
      }

      if (event.eventName === 'onramp_api.polling_success') {
        console.log('Transaction completed successfully')
      }

      if (event.eventName === 'onramp_api.polling_failed') {
        console.log(`Transaction failed: ${event.data.errorMessage}`)
      }
    },
  })

  // Clean up the listener when done
  // removeListener()
}
```

#### Event types

| Event Name                   | Description                                                              |
| ---------------------------- | ------------------------------------------------------------------------ |
| `onramp_api.cancel`          | User canceled the order                                                  |
| `onramp_api.commit_success`  | Payment was authorized successfully, waiting for transaction to complete |
| `onramp_api.commit_error`    | Payment authorization failed                                             |
| `onramp_api.polling_success` | Transaction completed successfully                                       |
| `onramp_api.polling_failed`  | Transaction failed after authorization                                   |

#### Return value

The function returns a cleanup function that removes the event listener. Call this when you no longer need to listen for events (e.g., when the user closes the dialog or navigates away).

## Order status values

| Status                            | Description                  |
| --------------------------------- | ---------------------------- |
| `ONRAMP_ORDER_STATUS_CREATED`     | Order has been created       |
| `ONRAMP_ORDER_STATUS_IN_PROGRESS` | Order is being processed     |
| `ONRAMP_ORDER_STATUS_COMPLETED`   | Order completed successfully |
| `ONRAMP_ORDER_STATUS_FAILED`      | Order failed                 |
| `ONRAMP_ORDER_STATUS_CANCELLED`   | Order was cancelled          |

## Testing in sandbox

To test Coinbase onramp without real transactions:

1. Set `isSandbox: true` when creating orders
2. Or prefix your `partnerUserRef` with "sandbox-" (e.g., "sandbox-user-1234")

When using sandbox mode with Apple Pay, the payment link URL will automatically include `&useApplePaySandbox=true`.

## Requirements

For Apple Pay Guest Checkout, users must have:

* A verified email address
* A verified phone number (verified within the last 60 days)

Use `getMissingVerificationForCoinbaseOnrampOrder` to check these requirements before creating an order.

## Collecting and verifying user credentials

Dynamic sends the phone number and email associated with the Dynamic user when creating an onramp order. You can use the following functions to collect and verify user credentials.

### Collecting email and phone number

Use `updateUser` to store collected email or phone number in the user's verified credentials. This function returns OTP verification details if verification is required.

```javascript theme={"system"}
import { updateUser } from '@dynamic-labs-sdk/client'

// Update user email
const updateEmail = async () => {
  const otpVerification = await updateUser({
    userFields: {
      email: 'user@example.com',
    },
  })

  if (otpVerification) {
    // Email verification required - use verifyOTP with the code sent to user
    console.log('Verification UUID:', otpVerification.verificationUUID)
  }
}

// Update user phone number
const updatePhone = async () => {
  const otpVerification = await updateUser({
    userFields: {
      phoneNumber: '5551234567',
      isoCountryCode: 'US',
    },
  })

  if (otpVerification) {
    // Phone verification required - use verifyOTP with the code sent to user
    console.log('Verification UUID:', otpVerification.verificationUUID)
  }
}
```

### Verifying with OTP

After updating user credentials, use `verifyOTP` to complete the verification process with the code sent to the user.

```javascript theme={"system"}
import { verifyOTP } from '@dynamic-labs-sdk/client'

const completeVerification = async (otpVerification, userEnteredCode) => {
  const response = await verifyOTP({
    otpVerification,
    verificationToken: userEnteredCode,
  })

  return response
}
```

### Re-verifying expired phone numbers

Coinbase requires phone numbers to be verified within the last 60 days. If a user's phone verification has expired, use `sendSmsOTP` to trigger re-verification, then complete with `verifyOTP`.

```javascript theme={"system"}
import { sendSmsOTP, verifyOTP } from '@dynamic-labs-sdk/client'

const reverifyPhone = async () => {
  // Send new OTP to user's phone
  const otpVerification = await sendSmsOTP({
    isoCountryCode: 'US',
    phoneNumber: '5551234567',
  })

  // After user enters the code
  const userEnteredCode = '123456'
  await verifyOTP({
    otpVerification,
    verificationToken: userEnteredCode,
  })
}
```

## Supported countries and payment methods

Coinbase onramp supports various countries and payment methods. The United States has the most comprehensive support, including Apple Pay for Guest Checkout.

See the [Customizing the Onramp Experience](/react/money-and-funding/customizing-the-onramp-experience#coinbase-onramp-supported-countries-and-payment-methods) page for a complete list of supported countries and payment methods.

## Related

* [Default Onramps](/react/money-and-funding/default-onramps) - General onramp setup
* [Customizing the Onramp Experience](/react/money-and-funding/customizing-the-onramp-experience) - Customize onramp options
