createCheckoutWithEth

CheckoutWithEth element is our embeddable iframe which allows you to enable your users to pay with ETH regardless of the token or coin that your NFT is priced in

526526

"Review your purchase" page

The native Javascript offers you three composable pieces to create the CheckoutWithEth element:

  1. createCheckoutWithEth
  2. createCheckoutWithEthLink
  3. createCheckoutWithEthMessageHandler

If you're looking to use the native JS SDK and get started as soon as possible, you'll start with the createCheckoutWithEth which uses both createCheckoutWithEthLink and createCheckoutWithEthMessageHandler under the hood to create the CheckoutWithEth element.

createCheckoutWithEth

This is the function that you'd be using most of the time to create the CheckoutWithEth element.

Code Snippet

import type {
  createCheckoutWithEthElement,
} from '@paperxyz/js-client-sdk';

// Assuming a container exists:
//      <div id="paper-checkout" />

const iframe = await createCheckoutWithEthElement({
  sdkClientSecret: '<from Checkout SDK Intent API>',
  elementOrId: 'paper-checkout',
  payingWalletSigner,
  setUpUserPayingWalletSigner,
  receivingWalletType,
  onError(error) {
    console.log('Error:', error);
  },
  onSuccess({ transactionId }) {
    console.log('Success! Transaction:', transactionId);
  },
});

// Alternatively, insert the iframe programmatically:
//      const iframe = createCheckoutWithEth(...)
//      document.getElementById('paper-checkout').appendChild(iframe);

Props

PropsTypeDescription
sdkClientSecretstringRequired

The client secret you get from create checkout SDK intent
payingWalletSignerethers.SignerRequired

The connected wallet who is going to be paying the ETH required for the checkout
setUpUserPayingWalletSigner(args: { chainId: number; }) => void | Promise<void>;Optional

If provided, the callback will be called before asking buyers to pay with the chainId that they are expected to be on.

Developers must make sure that users are on the right chain (Goerli for testnets, Eth for mainnets) or risk buyers sending funds into the void.
receivingWalletType"WalletConnect" | "MetaMask" | "Coinbase Wallet" | "Phantom" | string;Optional

If is one of the specified strings, the appropriate wallet icon will show. Otherwise a generic wallet icon will be displayed
onError(error: PaperSDKError) => voidOptional

If provided, the callback will be called when anything wrong happens during the checkout process
onSuccess(props : { transactionResponse: TransactionResponse; transactionId: string; }) => void)*Optional`

If provided, the callback will be called when the transaction is successfully sent to the blockchain
suppressErrorToastbooleanOptional

Defaults to true. If false, we will automatically display a toast in the iframe when something goes wrong.
optionsICustomizationOptionsOptional

See customizing checkout elements
onLoad() => voidOptional

This callback will be called when the iframe loads
elementOrIdstring | HTMLElementOptional

If provided, the iframe will be appended this element.

Note that you can either pass in a reference to the container element or the id associated with the container element

createCheckoutWithEthLink

This is the core building block that builds up the iframe link required to display the CheckoutWithEth element.

Once you generate the link, you can proceed to display it in an iframe but you'd still need to listen for the payWithEth event which will kickstart the process of getting the user to pay. We provide a handler which does most of the heavy lifting.

Code Snippet

const checkoutWithEthUrl = await createCheckoutWithEthLink({
    sdkClientSecret, 
    payingWalletSigner,
    receivingWalletType,
    options,
});

Props

PropsTypeDescription
sdkClientSecretstringRequired

The client secret you get from create checkout SDK intent
payingWalletSignerethers.SignerRequired

The connected wallet who is going to be paying the ETH required for the checkout
receivingWalletType"WalletConnect" | "MetaMask" | "Coinbase Wallet" | "Phantom" | string;Optional

If is one of the specified strings, the appropriate wallet icon will show. Otherwise a generic wallet icon will be displayed
optionsICustomizationOptionsOptional

See customizing checkout elements

createCheckoutWithEthMessageHandler

This is the message handler that is to be registered.

Essentially, this listens to two main events: payWithEth and sizing.

Code Snippet

const iframe = document.createElement("iframe");

window.addEventListener(
    "message",
    createCheckoutWithEthMessageHandler({
      iframe,
      setUpUserPayingWalletSigner,
      payingWalletSigner,
      onSuccess,
      onError,
      suppressErrorToast,
    })
);

Props

PropsTypeDescription
iframeHTMLIFrameElementRequired

The iframe that is displaying the link from createCheckoutWithEthLink
onError(error: PaperSDKError) => voidOptional

If provided, the callback will be called when anything wrong happens during the checkout process
onSuccess(props : { transactionResponse: TransactionResponse; transactionId: string; }) => void) | undefined*Optional`

If provided, the callback will be called when the transaction is successfully sent to the blockchain
suppressErrorToastbooleanOptional

Defaults to true. If false, we will automatically display a toast in the iframe when something goes wrong.
setUpUserPayingWalletSigner(args: { chainId: number; }) => void | Promise<void>;Optional

If provided, the callback will be called before asking buyers to pay with the chainId that they are expected to be on.

Developers must make sure that users are on the right chain (Goerli for testnets, Eth for mainnets) or risk buyers sending funds into the void.
payingWalletSignerethers.SignerRequired

The connected wallet who is going to be paying the ETH required for the checkout

Writing your own handler

You can write your own handler if you wish, Here's how:

The event object that is passed by default into the message event contains the data filed which has the following type

type event.data = {
    eventType: 'payWithEth',
  chainId: number,
  data: string,
  value: string,
  to: string,
  transactionId: string
}   | {
    eventType: 'sizing'
  height: string,
  width: string,
}

You simply create a function that handles or ignores either of the two events, exactly the way you want:

window.addEventListener('message', (event: MessageEvent) => {
        if (!event.origin.startsWith("https://paper.xyz")) {
      return;
    }
    const data = event.data;
    switch(data.eventType): {
        case "payWithEth": {
        break;
      }
      case "sizing": {
        break;
      }
    }
});