Skip to main content

React Native SDK Payment Sheet UI

React Native SDK > Payment Sheet UI

Use the pre-built Payment Sheet UI and implement custom theming and payment methods.

Step 1: Initialise the WestpacProvider component

Add the WestpacProvider component to your app, and initialise it with:

  • apiConfig.gateway = quickstream
  • apiConfig.merchantIdentifier = A Supplier Business Code in your QuickStream facility.
  • apiConfig.publishableKey = Your Publishable API key.
  • paymentProviders.card{} (This example collects cards.)

EXAMPLE

import { type WestpacProvider } from "@westpac-developer/sdk";

export default function ExampleLayout() {
    return (
        <WestpacProvider
            apiConfig={{
                gateway: "quickstream",
                merchantIdentifier: "MYBUSINESS",
                publishableKey: "MY_PUBLISHABLE_API_KEY",
            }}
            paymentProviders={{
               card: {
                savePaymentDetails: {
                  hidden: true
                }
            }}
        >
        </WestpacProvider>
    );
}

Step 2: Initialise the PaymentSheet component

In your app, after your user selects the goods and services they are purchasing, display a button to open the Payment Sheet UI using the PaymentSheet component.

Implement the following:

EXAMPLE

import {
  type OnPaymentFailureError,
  PaymentSheet,
  usePaymentSheet,
} from "@westpac-developer/sdk";
import { Pressable, Text, View } from "react-native";

export default function PaymentSheetIndex() {
    const { togglePaymentSheet, isOpen } = usePaymentSheet();

    return (
        <>
            <View>
                <Pressable
                    accessibilityLabel="Pay now"
                    accessibilityRole="button"
                    onPress={togglePaymentSheet}
                    accessible={!isOpen}
                >
                    <Text>
                        Pay Now
                    </Text>
                </Pressable>
            </View>
            <PaymentSheet
                onPaymentSubmitted={async (payment: PaymentSubmission) => {
                    console.log(payment.token.singleUseTokenId);
                }}
                onPaymentFailure={async (error: OnPaymentFailureError) => {
                    console.log("code:", error.code);
                    console.log("type:", error.type);
                    console.log("message:", error.message);
                    console.log("additional details?:", error.details);
                    closePaymentSheet();
                }}
                lineItems={[
                {
                    label: "Purchase amount",
                    amount: purchaseAmount
                }
                ]}
            />
        </>
    );
}

Step 3: Take a payment

In the onPaymentSubmitted function, send the singleUseTokenId to your server.

  1. On your server read the single-use token from the parameter.
  2. Verify your customer.
  3. To take a one-off payment:
    1. Using your secret API key and the single-use token, send a request to take a one-time payment.
  4. Or, if you need to take more than one payment with the card details, you should register the card:
    1. Find a customer by your customer number or by the customerId.
    2. If your customer doesn't exist, create one.
    3. Using your secret API key and the single-use token, send a request to register the card.
    4. You will receive an account token. You should then take payments using the account token via this API or using batch payment file. If the customer already has an account token with the same card number, registering it again will update the expiry date and cardholder name and return the same account token.

EXAMPLE

async function onPaymentSubmitted(payment: PaymentSubmission) {
    router.navigate({
        pathname: "/purchase-complete",
        params: { token: payment.token.singleUseTokenId }
    });
}

Step 4: Present the result

Inform the customer that they have completed the payment and present the result.

Step 5: Improve your solution

You may now improve your solution by:

Step 6: Test your integration

Refer to the test card numbers, and see Testing for more.

(Optional) Direct Debit

Update your code to provide DirectDebitProviderConfig in paymentProvider to the WestpacProvider.

EXAMPLE

<WestpacProvider
    apiConfig={{
        gateway: "quickstream",
        merchantIdentifier: "MYBUSINESS",
        publishableKey: "MY_PUBLISHABLE_API_KEY",
    }}
    paymentProviders={{
        card: {
          savePaymentDetails: {
            hidden: true
          }
        },
        directDebit: {
          savePaymentDetails: {
            hidden: true
          }
        }
    }
>
</WestpacProvider>

If you are signing up customers for Direct Debit and will display your Direct Debit Request Service Agreement/Authority prior to opening the Payment Sheet UI:

  1. Configure Direct Debit without displaying it as an option in the Payment Sheet UI.
  2. Open the Payment Sheet to the Direct Debit payment method page directly.

EXAMPLE

In the PaymentProvidersObject, provide DirectDebitProviderConfig, and order and do not specify directDebit.

<WestpacProvider
    apiConfig={{
        gateway: "quickstream",
        merchantIdentifier: "MYBUSINESS",
        publishableKey: "MY_PUBLISHABLE_API_KEY",
    }}
    paymentProviders={{
        // Provide order, but not do provide directDebit.
        order: ["card"],
        card: {
          savePaymentDetails: {
            hidden: true
          }
        },
        // configure directDebit
        directDebit: {
          savePaymentDetails: {
            hidden: true
          }
        }
    }
>
</WestpacProvider>

Call openPaymentSheet() and provide DirectScreenType.DirectDebitScreen and set backButton to false.

openPaymentSheet(DirectScreenType.DirectDebitScreen, false);

(Optional) Apple Pay

Apple Merchant ID

Obtain an Apple Merchant ID from the Apple Developer website.

Payment Processing Certificate

Sign in to the QuickStream portal and Add an iOS Certificate. This process involves:

  1. Downloading a Certificate Signing Request from QuickStream.
  2. Exchanging the CSR with Apple for a Payment Processing Certificate.
  3. Uploading the Payment Processing Certificate to QuickStream.

Integrate your app

Update your code to provide ApplePayProviderConfig in paymentProvider to the WestpacProvider.

Refer to Apple Pay in an App with QuickStream REST API.

EXAMPLE

import { SupportedNetworkEnum } from "@rnw-community/react-native-payments";

...

<WestpacProvider
    apiConfig={{
        gateway: "quickstream",
        merchantIdentifier: "MYBUSINESS",
        publishableKey: "MY_PUBLISHABLE_API_KEY",
    }}
    paymentProviders={{
        card: {
          savePaymentDetails: {
            hidden: true
          }
        },
        applePay: {
            currencyCode: "AUD",
            countryCode: "AU",
            merchantIdentifier: "merchant.com.myappname",
            supportedNetworks: [
                SupportedNetworkEnum.Visa,
                SupportedNetworkEnum.Mastercard,
                SupportedNetworkEnum.Amex
          ]
        }
    }}
>
</WestpacProvider>

``

(Optional) Google Pay

Activate Google Pay

Sign in to the QuickStream portal and activate Google Pay.

Gateway Merchant ID

Take note of your QuickStream Community Code. This is the gatewayMerchantId in your integration.

Integrate your app

Update your code to provide GooglePayProviderConfig in paymentProvider to the WestpacProvider.

Refer to Google Pay in an App with QuickStream REST API.

EXAMPLE

<WestpacProvider
    apiConfig={{
        gateway: "quickstream",
        merchantIdentifier: "MYBUSINESS",
        publishableKey: "MY_PUBLISHABLE_API_KEY",
    }}
    paymentProviders={{
        card: {
          savePaymentDetails: {
            hidden: true
          }
        },
        googlePay: {
          countryCode: "AU",
          currencyCode: "AUD",
          cardParameters: {
            allowedAuthMethods: ["PAN_ONLY", "CRYPTOGRAM_3DS"],
            allowedCardNetworks: [
              "VISA",
              "MASTERCARD",
              "AMEX"
            ]
          },
          gatewayMerchantId: "COMMUNITYCODE",
          merchantInfo: {
            merchantName: "My Business"
          }
    }}
>
</WestpacProvider>

(Optional) PayTo

Server-side

Refer to the PayTo with QuickStream REST API guide to integrate PayTo with your back-end.

Send the singleUseTokenId to your server.

  1. on your server read the single-use token from the parameter.
  2. Verify your customer.
  3. To take a one-off payment
    1. Using your secret API key and the single-use token, send a request to eCommerce PayTo payment.
  4. Or, if you need to take more than one payment, you should create a PayTo agreement:
    1. Find a customer by your customer number or by the customerId.
    2. If your customer doesn't exist, create one.
    3. Using your secret API key and the single-use token, send a request to create a PayTo Agreement.
    4. You will receive an agreementToken. You should then take payments using the agreement token via this API or using batch payment file.

Integrate your app

Update your code to provide PayToProviderConfig in paymentProvider to the WestpacProvider.

Example

<WestpacProvider
    apiConfig={{
        gateway: "quickstream",
        merchantIdentifier: "MYBUSINESS",
        publishableKey: "MY_PUBLISHABLE_API_KEY",
    }}
    paymentProviders={{
        card: {
          savePaymentDetails: {
            hidden: true
          }
        },
        payto: {}
    }
>
</WestpacProvider>

(Optional) PayID

Server-side

Implement an endpoint to fetch a PayID for your customer.

Refer to the PayID with QuickStream REST API guide to integrate PayID with your back-end.

Integrate your app

Update your code to provide the PayIdProviderConfig to the WestpacProvider.

  • Provide helpUrl to tell customers how to pay by PayID.
  • Provide the PayID registered name in merchantName to match the name customers see in their banking app.

EXAMPLE

<WestpacProvider
    apiConfig={{
        gateway: "quickstream",
        merchantIdentifier: "MYBUSINESS",
        publishableKey: "MY_PUBLISHABLE_API_KEY",
    }}
    paymentProviders={{
        card: {
          savePaymentDetails: {
            hidden: true
          }
        },
        payId: {
          helpUrl: "https://www.westpac.com.au/personal-banking/online-banking/making-the-most/payid/",
          merchantName: "My Business"
        }
    }
>
</WestpacProvider>

Fetch a PayID

Implement the onPayIdInitiation() function for the PaymentSheet to fetch a PayID for the customer from your server.

EXAMPLE

<PaymentSheet
    onPaymentSubmitted={onPaymentSubmitted}
    onPaymentFailure={onPaymentFailure}
    onPayIdInitiation={async () => {
        const [email, referenceNumber] = await generatePayId();
        return { email, referenceNumber };
    }}
    lineItems={[
        {
            label: "Purchase amount",
            amount: purchaseAmount
        }
    ]}
    />
</>

(Optional) Custom Theming

Customise the visual theme of the Payment Sheet UI by providing styles to match the design of your app.

Provide a mode

Initialise ThemeConfig with a mode. You can choose light, dark or system (default.)

Override the theme

Customise the theme of the Payment Sheet UI by providing theme in ThemeConfig. You can customise the text, buttons, background and more.

EXAMPLE

<WestpacProvider
    themeConfig={
      mode: "light",
      theme: {
        darkColors: {
          primary: "#da1710"
        },
        components: {
          button: {
            primary: {
              view: {
                borderRadius: 10
              }
            }
          }
        }
      }
    }
    apiConfig={{...}}
    paymentProviders={{...}}
>
</WestpacProvider>

(Optional) Custom Payment Methods

Display other payment methods in the Payment Sheet UI by providing one or more CustomPaymentTypeConfig in paymentProvider to the WestpacProvider.

The id property is provided in the onCustomPaymentInitiation() callback function to identify which payment method was chosen by the user. You then handle the integration and payment processing in your app.

EXAMPLE

paymentProviders={{
  order: ["card", "paypal"],
  paypal: {
    id: "paypal",
    displayName: "PayPal",
    icon: <Text>PayPal</Text>,
  } as CustomPaymentTypeConfig,
  card: {}
}}

...

async function onCustomPaymentMethodSelected( id: string ) {
  // handle a custom payment method based on the id argument.
  console.log(id); // "paypal"
}

(Optional) Saved Payment Methods

Display your customers' saved card and bank accounts in the Payment Sheet UI. Do this when you want your customer to choose an existing payment method for a payment, or when updating an account.

Server-side

Implement an endpoint to retrieve a list of cards or bank accounts stored on for your customer. You can implement a request list the accounts for a customer using the Customers API.

For this simple example, return JSON objects matching PaymentMethodSource.

Tips:

  • default = true when there is many accounts will display at the top.
  • For bank accounts title=Bank Account, subtitle=paymentInfo.accountNumber, maskedNumber=paymentInfo.bsb

Set Payment Methods

In your app, retrieve one or more accounts from your server and then call setSavedPaymentMethods( methods: PaymentMethodSource[] ).

{
  const listMethods = async () => {
    try {
      // get the accounts for customer 123456
      const resp = await fetch(
        `https://myserver.com.au/accounts/list/123456`,
        {
          headers: {
            "Content-Type": "application/json",
          },
          method: "GET",
        }
      );

      if (resp.status !== 200) {
        console.error("Could not retrieve payment methods", resp);
      }

      // this example assumes the responses are in the
      // same format as PaymentMethodSource:
      // (CustomerPaymentCreditCardModel or CustomerPaymentBankAccountModel)
      const paymentMethods = await resp.json();
      setSavedPaymentMethods(paymentMethods.data);
    } catch (err) {
      console.error(err);
    }
  };
  listMethods();
}

Take a payment

In the onPaymentSubmitted function, handle retrieving the accountToken or a singleUseTokenId from the PaymentSubmission object.

You can then take payments using the account token via this API.

EXAMPLE

async function onPaymentSubmitted(payment: PaymentSubmission) {
  if(payment.type == "single-use") {
    console.log(payment.token.singleuseTokenId);
    // send the singleUseTokenId to your server to take a payment or save the account.
  } else if (payment.type == "saved") {
    console.log(payment.accountToken);
    // send the accountToken to your server to take a payment.
  }
}

(Optional) Save Payment Details Checkbox

Implement a checkbox in the Payment Sheet UI to allow your customer to choose if they want to save their card or bank account details.

Server-side

Implement an endpoint to take a payment, and then save the payment details for your customer.

  1. On your server read singleUseTokenId and customerId from the parameters.
  2. Verify your customer.
  3. Using your secret API key and the single-use token, send a request to take a one-time payment.
  4. Confirm that the transaction was successful.
  5. You will receive a receiptNumber to identify the transaction.

Register the card using the receiptNumber:

  1. Find a customer by your customer number or by the customerId.
  2. If your customer doesn't exist, create one.
  3. Using the receiptNumber, send a request to register the card.
  4. You will receive an account token.

You should then take further payments using the account token via this API or using batch payment file.

If the customer already has an account token with the same card number, registering it again will update the expiry date and cardholder name and return the same account token.

Client-side

Update your code to provide CardProviderConfig and/or the DirectDebitProviderConfig in paymentProvider to the WestpacProvider.

For each applicable config object, provide SavePaymentDetails and set hidden to false.

You can also change the label of the checkbox by providing text, and toggle the default selection of the checkbox using default.

EXAMPLE

<WestpacProvider
    apiConfig={{
        gateway: "quickstream",
        merchantIdentifier: "MYBUSINESS",
        publishableKey: "MY_PUBLISHABLE_API_KEY",
    }}
    paymentProviders={{
        card: {
          savePaymentDetails: {
            hidden: false
          }
        },
        directDebit: {
          savePaymentDetails: {
            hidden: false
          }
        }
    }
>
</WestpacProvider>

The customer will see a checkbox and select it to indicate they want to save their payment details.

In the onPaymentSubmitted function handle when the client has selected the checkbox by inspecting the savePaymentDetails property of SingleUseTokenResponse.

EXAMPLE

async function onPaymentSubmitted(payment: PaymentSubmission) {
  if (payment.type === "saved") {
    console.log(payment.accountToken);
    // handle the customer selecting an existing saved payment method
    // and taking a payment or updating an account using the accountToken.
  } else if (payment.type === "single-use") {
    if (payment.token.savePaymentDetails) {
      // handle taking a payment and saving the payment account details.
    } else {
      // handle taking a payment using the single-use token.
    }

    router.navigate({
      pathname: "/purchase-complete",
      params: { ... },
    });
  }
}
Westpac Privacy Statement

Privacy Statement (for individuals whose personal information may be collected - in this clause referred to as "you"). All personal information we collect about you is collected, used and disclosed by us in accordance with our Privacy Statement which is available at Privacy Statement or by calling us through your relationship manager or Westpac representative. Our Privacy Statement also provides information about how you can access and correct your personal information and make a complaint. You do not have to provide us with any personal information but, if you don't, we may not be able to process an application or a request for a product or service.