> This page is for Afterpay Button Documentation.

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://developers.afterpay.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://developers.afterpay.com/_mcp/server.

# Advanced Rendering Control

By default, we provide a fully managed and branded UI. You may want advanced controls in certain situations such as validating information a customer has provided during checkout before continuing. When `afterpayButton.renderCashAppPayButton` is called, a begin method is returned through the `onBegin` callback for you to call when you are ready.

## 1. Create your custom button

Either with JavaScript

```javascript
function createCustomButton() {
  // Create custom button
  const cashAppPayCustomButton = document.createElement('button');
  cashAppPayCustomButton.classList.add('btn', 'cash-app-pay-custom-button');
  cashAppPayCustomButton.textContent = "Continue with";

  // Attach cash app pay logo to button
  const cashAppPayLogo = document.createElement('cash-app-pay-logo');
  cashAppPayCustomButton.appendChild(cashAppPayLogo);
  document.getElementById('cash-app-pay').after(cashAppPayCustomButton);
}
```

or directly in HTML

```html
<button class="btn cash-app-pay-custom-button">
  Continue with<cash-app-pay-logo></cash-app-pay-logo>
</button>
```

The `<cash-app-pay-logo>` element renders a Cash App Pay logo which can be used when choosing a payment method or to enhance your checkout button.

## 2. Initialize the authorization flow when ready

Your checkout experience may want to use its own button for consistency across payment methods. When the manage option is false, you can also set the button option to false to prevent a Cash App Pay button from being rendered. You can now provide your own button and manage the authorization flow.

```javascript
function renderCashAppPayButton(afterpayButton) {
  const cashAppPayButtonOptions = {
    button: false,
    manage: false,
    onBegin: function({ begin }) {
      addEventListenerToCashAppPayButton(async (event) => {
        event.preventDefault();        
        // TODO: validate customer information
        bindAttributesToButton(afterpayButton); // bind attributes if you haven't already
        afterpayButton.initializeForCashAppPay({
          redirectConfirmUrl,
          onError,
          onComplete,
          eventListeners: {
            CUSTOMER_INTERACTION: ({ isMobile }) => {
              if (isMobile) {
                console.log(`Customer is on mobile`);
              } else {
                console.log(`Customer is not on mobile`);
              }
            },
            CUSTOMER_REQUEST_DECLINED: () => {
              console.log(`CUSTOMER_REQUEST_DECLINED`);
            },
            CUSTOMER_REQUEST_APPROVED: () => {
              console.log(`CUSTOMER_REQUEST_APPROVED`);
            },
            CUSTOMER_REQUEST_FAILED: () => {
              console.log(`CUSTOMER_REQUEST_FAILED`);
            },
            CUSTOMER_DISMISSED: () => {
              console.log(`CUSTOMER_REQUEST_FAILED`);
            }
          }
        });
        begin();
      });
    },
  }
  afterpayButton.renderCashAppPayButton({
    countryCode: "US",
    cashAppPayButtonOptions
  });
}
```