How can I hide payment gateways based on current discounts?

kcarlton-spo
Shopify Partner
4 0 1

Prior to the checkout extensibility changes, we were using the Shopify scripts to modify our payment gateways if a particular discount was applied. We were working with that provider to fund the discount so we wanted to ensure that gateway was used. Here's the example from the Script Editor app:

discountCode = Input.cart.discount_code
isBlarneyCoup = false
if discountCode && discountCode.code == "BLARNEY10"
  isBlarneyCoup = true
end
Input.payment_gateways.delete_if {|pg| pg.name != "The Blarney System" && isBlarneyCoup}
Output.payment_gateways = Input.payment_gateways

As we transition to the Shopify Functions, we want to do something similar but the Cart provided by the Payment Customization API Input does not include the current discounts on the order. Any suggestions?

 

Thanks,

 

KC

Replies 6 (6)

Kalen_Jordan
Shopify Partner
436 14 61

Wonder if you could do this by comparing subtotalAmount (before discounts) to totalAmount (after discounts)?
https://shopify.dev/docs/api/functions/reference/payment-customization/graphql/common-objects/cartli...

Kalen Jordan
Platform Advocate
MESA - Shopify Automation You've Love
Stephen2020
Shopify Partner
19 2 6

Hm,

 

if you want to do that, then you must make available the discount code(s) for the input query of your payments function.

 

As cart attributes are available in the input query, that's a good place to do so. I.e.: Write a checkout ui extension which is setting a cart attribute for the discount code.

 

In the function query that attribute.

Kalen_Jordan
Shopify Partner
436 14 61

But discounts are not available in the input query for the payment customization function.

Kalen Jordan
Platform Advocate
MESA - Shopify Automation You've Love
kcarlton-spo
Shopify Partner
4 0 1

This might work... I'll consider it further. We already have several extensions: loyalty, address validation, return assurance, guaranteed delivery, additional footer disclaimer, etc. I might be able to shove this idea into another extension then have the function handle it.

kcarlton-spo
Shopify Partner
4 0 1

That won't work for my case... we only want to hide payment gateways when certain discount is used. For example, if we manage to get PayPal to fund a discount (I know, unlikely), we would want to disable all other payment methods so PayPal gets to process the payment.

Stephen2020
Shopify Partner
19 2 6

You can write a UI extension similar to following.

 

import {
  reactExtension,
  useDiscountCodes,
  useAttributes,
  useApplyAttributeChange,
} from '@shopify/ui-extensions-react/checkout';
import type { Attribute, CartDiscountCode } from '../../../app/lib/types'

export default reactExtension(
  'purchase.checkout.reductions.render-after',
  () => <Extension />,
);

function Extension() {
  const attributes = useAttributes();
  const discountCodes = useDiscountCodes();
  const applyAttributeChange = useApplyAttributeChange();

  const attrib = attributes && attributes.length ? attributes
  .filter((el: Attribute) => el.key === "disc_cds")
  .map((el: Attribute) => el.value).join("") : "";

  const codes = discountCodes
  .map((el: CartDiscountCode) => el.code) 
  .join(",");

  useEffect(() => {
    //console.log("Start useEffect", {inflCodes, codes, attrib});
    if (attrib !== codes) {
        updateDiscAttribute(codes);
    }

    async function updateDiscAttribute(codes: string) {
      try {
        const result = await applyAttributeChange({
          key: 'disc_cds',
          type: 'updateAttribute',
          value: codes,
        });
        console.log(
          'applyAttributeChange result',
          { result, codes, attrib, discountCodes }
        );
      } catch (error) {
        console.error(error);
      }
    }

  }, [codes]);

  return null;
}

 

This will write the discount code(s) as a comma separated list into a cart attribute named "disc_cds".

 

Then read that cart attribute in your input query.

 

    discAttribute: attribute(key: "disc_cds") {
      value
    }

 

Now you know in the function which discount code is set.