Skip to main content

Integrating Coinbase Pay

This page explains how to trigger the Coinbase Pay experience by embedding a Coinbase Pay button with the Coinbase Pay SDK. When the user presses the Coinbase Pay button, the Coinbase Pay widget launches and is configured with the parameters passed.

A. Create a Coinbase Pay button

Download the Coinbase Pay button assets and add these buttons to your app. Here is a web integration example:

<a id="cbpay-button-container">
<img src="./buy-with-coinbase.png" />
</a>

Some things to be mindful of:

  • The selector must be unique on the DOM, but the name is not important.
  • The element must be accessible using the querySelector API.
  • The image source should reference one of the Coinbase approved buttons defined in button assets download.

B. Call the initOnRamp method

When the HTML container is ready and has been mounted to the DOM, call initOnRamp from the Coinbase Pay SDK to attach click listeners to the button.

info

Refer to the initOnRamp parameters.

initOnRamp Example

This is an example of how to implement in React with ready state listeners:

import { useEffect, useRef, useState } from 'react';
import { initOnRamp } from '@coinbase/cbpay-js';

type InitOnRampOptions = Parameters<initOnRamp>[0];

type CoinbaseButtonProps = {
destinationWalletAddress: string;
};

function CoinbaseButton({ destinationWalletAddress }: CoinbaseButtonProps) {
const [isReady, setIsReady] = useState(false);
const onrampInstance = useRef();

useEffect(() => {
//initOnRamp parameters
const options: InitOnRampOptions = {
appId: 'AppIdProvidedByCoinbase',
target: '#cbpay-container',
widgetParameters: {
destinationWallets: [{
address: destinationWalletAddress,
blockchains: ['ethereum', 'algorand'],
}],
},
onSuccess: () => {
// handle navigation when user successfully completes the flow
},
onExit: () => {
// handle navigation from dismiss / exit events due to errors
},
onEvent: (event) => {
// event stream
},
experienceLoggedIn: 'embedded',
experienceLoggedOut: 'popup',
};

// instance.destroy() should be called before initOnramp if there is already an instance.
if (onrampInstance.current) {
onrampInstance.current.destroy();
}

initOnRamp(options, (error, instance) => {
if (instance) {
onrampInstance.current = instance;
setIsReady(true);
}
});
}, [destinationWalletAddress])

const handleOnPress = () => {
onrampInstance.current.open();
}

// render with button from previous example
return (
<BuyWithCoinbaseButton onPress={handleOnPress} isLoading={!isReady} />
);
}

initOnRamp Parameters

The following table outlines the parameters supported in the initOnRamp function:

ParameterReq'dTypeDescription
widgetParametersYesWidgetParametersA WidgetParameters object
appIdYesStringUnique short-string ID provided to partners by the Coinbase Pay team
targetYesStringQuery selector string for the container into which to embed the Coinbase Pay button
onSuccessNoFunctionCallback that is triggered when the OnRamp purchase/send flow has finished
onExitNoFunctionCallback when the OnRamp experience exits
onEventNoFunctionCallback that emits events from the experience
onRequestedUrlNoFunctionSingle URL (String) that must be set outside of an iframe. In mobile webview, partners should display a close button for the URL.
closeOnExitNoBooleanAutomatically close the Coinbase Pay window when user exits the flow
closeOnSuccessNoBooleanAutomatically close the Coinbase Pay window on successful purchase
experienceLoggedInNoEnumEmbed Coinbase Pay into site/extension or run in popup window for logged in users (embedded,popup,new_tab)
experienceLoggedOutNoEnumEmbed Coinbase Pay into site/extension or run in popup window for logged out users (defaults to logged in option)
tip

Coinbase recommends using a mix of experienceLoggedIn: “embedded” and experienceLoggedOut: “popup” for a more seamless experience. Because for Chrome extensions, the logged out embedded experience opens a popup window (to login), and the extension popup may close, losing the window reference.

WidgetParameters Parameters

A WidgetParameters object accepts the following parameters:

ParameterReq'dTypeDescription
destinationWalletsYesDestinationWallet[]Array of DestinationWallet objects that define blockchain types (blockchains) and destination addresses (address)
presetCryptoAmountNoNumberPreset crypto amount value.
presetFiatAmountNoNumberPreset fiat amount value (for USD, CAD, GBP, EUR only). Ignored if presetCryptoAmount is also set.
defaultNetworkNoStringDefault network that should be selected when multiple networks are present
defaultExperienceNo'send', 'buy'Default visual experience: either (1) Transfer funds from Coinbase ('send') or (2) Buy assets ('buy')
handlingRequestedUrlsNoBooleanPrevents the widget from opening URLs directly & relies on onRequestedUrl entirely for opening links
partnerUserIdNoStringUnique ID representing the client app user. Must be less than 50 chars. Use with the Transaction Status API to retrieve transactions made during the session.
info

All transactions made during the session are linked to partnerUserId which can be used with the Transaction Status API to retrieve these transactions later.

DestinationWallet Parameters

A DestinationWallet object accepts the following parameters:

ParameterReq'dTypeDescription
addressYesStringDestination address where the purchased tokens will be sent.
blockchainsNoString[]List of blockchains enabled for the associated address. All tokens available per blockchain are displayed to the user.
assetsNoString[]List of assets enabled for the associated address. They are appended to the available list of tokens for the user to buy or send.
supportedNetworksNoString[]List of networks enabled for the associated assets.

C. Test and Verify

After the Coinbase Pay SDK has been configured and inserted into the application, submit test transactions, and then validate that the funds have been delivered to the destination wallet.

If the SDK call to initOnRamp is misconfigured, then either (1) Coinbase Pay does not render or (2) the Coinbase Pay experience redirects to the Coinbase landing page.

See Also:

Was this helpful?