# Payment Sheet Events

Learn how to handle user interaction with payment sheet by listening to the following events and injecting callback handler

# Wallet Button Click

Triggered when wallet button is clicked. Event object is WalletButtonClickResponse

collect.on("wallet_button_click",  (e) => {
  ...
  console.log(e.source); //"apple_pay" or "google_pay"
});

# Payment Authorized required

Triggered when payment authorization is completed. Event object is PaymentAuthorizedResponse

Supported complete() options

  • error – WalletError (see InvalidBillingContact error for details)

The nonce you receive from event should be passed to your backend for processing payment. Once the charging is successful then e.complete() will close the payment sheet. If there are failure during this point, you can use e.complete(WalletError) to prompt user to try again.

collect.on("payment_authorized",  (e) => {
    ...
    Server.charge(e.nonce);
    e.complete();
 });

# PaymentAuthorizedResponse

interface PaymentAuthorizedResponse {
 nonce: string;
 source: PaymentMethod;        // "apple_pay" or "google_pay"
 shippingAddress?: Address;    // complete address
 billingAddress?: Address;
 complete: Function;       // only for handling error: invalid billing address
};

interface Address {
 emailAddress?: string;
 administrativeArea?: string;
 countryCode?: string;
 postalCode?: string;
 locality?: string;
 phoneNumber?: string;
 addressLines?: string[];
 name?: string;
};

# Shipping Address Change recommended

Pre-requisite

This event is only available when you enable shipping contact flag in WalletRequest.requireShippingAddress

const walletRequest = {
  ...
  requireShippingAddress: true,
};

Depending on the country, some shipping address fields can be missing or partially redacted due to privacy reason. Browser will return minimum information necessary for calculating tax or shipping cost. For US, event will return countryCode, postalCode, locality, and administrativeArea.

Triggered when the user selects an address for shipping. Event object is ShippingAddressChangeResponse. This event listens to Google event onPaymentDataChanged.

Supported updateWith options

  • total – LineItem
  • lineItems – list of LineItem
  • shippingMethods – list of ShippingMethod
  • error – WalletError (see Invalid Shipping Contact error for details)

# ShippingAddressResponse

interface ShippingAddressResponse {
  shippingAddress: Address;   // IMPORTANT: some fields can be redacted for security purposes
  updateWith: Function;
 };
 
interface Address {
  // some fields can be redacted
  administrativeArea?: string;
  countryCode?: string;
  postalCode?: string;
  locality?: string;
};

# Sample Code

collect.on("shipping_address_change", (e) => {
  const options = {
    lineItems: [
      {
        label: "Turkey Legs",
        amount: "10.00",
      },
      {
        label: "Ground Shipping",
        amount: "2.00",
      },
    ],
    shippingMethods: [
      {
        id: "ground_ship",
        label: "Ground Shipping",
        detail: "(3-business days) Ground shipping fulfilled by GoDaddy",
        amount: "2.00",
      },  
    ],
    total: {
      label: "TOTAL",
      amount: "12.00",  //GooglePay does NOT calculate total cost on-the-fly
    },
  };
 
  e.updateWith(options);
});

# Shipping Method Change

Pre-requisite

This event is only available when you enable shipping contact flag in WalletRequest.requireShippingAddress

const walletRequest = {
  ...
  requireShippingAddress: true,
};

Triggered when the user changes shipping method. Event object is ShippingMethodChangeResponse. This event listens to Google event onPaymentDataChanged.

Supported updateWith options

  • total – LineItem
  • lineItems – list of LineItem

# ShippingMethodResponse

interface ShippingMethodResponse {
  shippingMethod: ShippingMethod;
  updateWith: Function;
};
 
interface ShippingMethod {
  id: string;
  label: string;
  detail: string;
  amount: string;
}

# Sample Code

collect.on("shipping_method_change", (e) => {    
  const shippingMethod = e.shippingMethod
 
  const shippingAmount = shippingMethod.amount;
  const shippingLabel = shippingMethod.label;
 
  const lineItems = [
    {
      label: "Turkey Legs",
      amount: "10.00",
    },
    {
      label: shippingLabel,
      amount: shippingAmount,
    }
  ];
 
  const options = {
    lineItems: lineItems,
    total: {
      label: "TOTAL",
      amount: (10.0 + parseFloat(shippingAmount)).toString(),   //GooglePay does NOT calculate total cost on-the-fly
    },
  };
 
  e.updateWith(options);
});

# Coupon Code Change

Pre-requisite

This event is only available when you enable support coupon code flag in WalletRequest.supportCouponCode

const walletRequest = {
  ...
  supportCouponCode: true,
};

Triggered when the user applies or removes coupon code. Event object is CouponCodeChangeResponse. This event listens to Google event onPaymentDataChanged.

IMPORTANT: Event will be triggered on every attempt to add or delete coupon code. You need to validate coupon and pass a couponCode object to the updateWith method. couponCode can contain object with coupon data that was successfully applied to the order to display it on the payment sheet or an object with empty data to remove coupon from the payment sheet:

Supported updateWith options

  • total – LineItem
  • lineItems – list of LineItem
  • shippingMethods – list of ShippingMethod
  • couponCode - CouponCode (required if no error is passed)
  • error – WalletError (see Invalid Coupon Code error for details)
collect.on("coupon_code_change", (e) => {
  const couponCode = e.couponCode;
  ...                                 //process coupon codes
  e.updateWith(options);
});

# CouponCodeResponse

interface CouponCodeResponse {
  couponCode: string;
  updateWith: Function;
};

# Sample Code

Initialize order details and available coupon codes before user interacts with wallet button

const order = {
  total: {
    label: "TOTAL",
    amount: "10.00",
  },
  lineItems: [
    {
      label: "Blanket",
      amount: "10.00",
    }
  ],
  coupon: {
    code: "",
    label: "",
    amount: "0.00",
  },
};
 
//Define available coupon codes to apply
const availableCouponCodes = [
  {
    code: "free",
    label: "Free Shipping",
    amount: "0.00",
  },
  {
    code: "discount10",
    label: "10$ discount",
    amount: "-10.00",
  }
];

Setup coupon_code_change event handler and update line items, shipping method, coupon codes details and total

collect.on("coupon_code_change", (e) => {
  //IMPORTANT
  //e.couponCode can be an empty string when user removes code from a payment sheet
  if (!e.couponCode) {
    //Pass an object with empty data in "updateWith" to remove coupon code from payment sheet
   order.coupon = {
      code: "",
      label: "",
      amount: "0.00",
    }
  } else {
    //You can validate coupon code here and attach an error object to options if it's needed
    if (e.couponCode === "error") {
      const options = {
        error: {
          code: "invalid_coupon_code",
          message: "Coupon code " + e.couponCode + " does not exists", 
        }
      };
     }
    order.coupon = couponCode;
  }   
  
  const shippingMethods = order.coupon === "free" ? [
    {
      id: "next_day",
      label: "Free Next-Day Shipping (coupon)",
      detail: "Free next-day shipping fulfilled by GoDaddy",
      amount: "0.00",
    },
    {
      id: "standard",
      label: "(2-business days) Free Standard Shipping (coupon)",
      detail: "Free standard shipping fulfilled by GoDaddy",
      amount: "0.00",
    }
  ] : [
    {
      id: "next_day",
      label: "Free Next-Day Shipping",
      detail: "Free next-day shipping fulfilled by GoDaddy",
      amount: "0.00",
    },
    {
      id: "standard",
      label: "(2-business days) Free Standard Shipping",
      detail: "Free standard shipping fulfilled by GoDaddy",
      amount: "5.00",
    }
  ];
 
  //IMPORTANT
  //Wallet defaults to first shipping method if coupon changed
  const shippingMethod = shippingMethods[0];
 
  const shippingCost = parseFloat(shippingMethod.amount);
 
  const totalAmount = parseFloat(order.total.amount) + shippingCost;
 
  const lineItems = order.lineItems.concat([
    {
      label: shippingMethod.label,
      amount: shippingMethod.amount,
    },
  ]);
   
  //Add coupon code to line items and total amount
  if (order.coupon.code) {
    lineItems.push({ ...order.coupon });
    totalAmount += parseFloat(order.coupon.amount || "0.00");
  }
 
  const options = {
    lineItems: lineItems,
    shippingMethods: shippingMethods,
    couponCode: { ...order.coupon }, //this field is required in "coupon_code_change" event if no error is passed,
    total: {
      label: "TOTAL",
      amount: totalAmount.toString(),
    },
  };
 
  e.updateWith(options);
});

# Close Wallet

Triggered when user exits payment sheet.

collect.on("close_wallet",  () => {
  ...
});
Last Updated: 11/30/2022, 12:22:10 AM