[Solution] Allow Payment Methods v2

Document Status

ReVIEWed

Document Owner(s)

@Goncalves, Felipe (Deactivated)

Reviewers

@Caes, Guilherme (Deactivated)
@Ferreira Gomes, Raphael (Deactivated)
@Augusto Romao, Vinicius (Deactivated)
@Franca, Helio (Deactivated)

 

Potential Solutions

This document intends to present the solution to these problems:

Improvements in the first solution of Allow Payment Methods:

  1. Enhance the WL-App to retrieve the allowed payment methods more efficiently. Currently, the app only gathers this information when the user searches for a restaurant, which can lead to a delay in accessing updated data, such as when a user has already saved a restaurant;

  2. Clean up non-existent payments on Sanity Restaurant;

New feature in Allow Payment Methods:

  1. Create a schedule to enable/disable the payment methods states.

 

This documentation serves as an extension of the documentation available at the following link: Allow Payment methods by DOP - iteration v1 .

Proposed Solution

Enhance the WL-App to retrieve the allowed payment methods more efficiently

Currently, for users to access updated information on allowed payments, they must search for the restaurant. However, if there are any changes to the allowed payments while they are in the menu or cart, they will not be able to see this information and will need to search for the restaurant again.

As a solution, we will implement a new query when the user navigates to the payment screen. This query will use the restaurant ID to perform a search in Sanity and retrieve the allowed payment data. This way, every time the user enters the payment screen, the app will query this information, ensuring that the data is always up-to-date.

This solution is already done and delivered.

Create a new query and fragment on restaurant.graphql

File: src/queries/sanity/restaurant.graphql

Code:

fragment PaymentMethodsFragment on PaymentMethodConfiguration { name paymentMethodBrand state isOnlinePayment } query GetPaymentMethodsControl($storeId: ID!) { Restaurant(id: $storeId) { paymentMethods { ...PaymentMethodsFragment } } }

Run: apollo:generate to create a new query on sanity.graphql file.

Into payment method control hook put a new query to get the information of Sanity.

File: src/pages/cart/payment/order-payment/use-payment-method-control.ts

This query should avoid using cache to ensure we always access the most recent data. However, sanity CDN can take up to 15 minutes to be updated, and not using the CDN is not an option, since it would impact the entire application performance.
There’s the possibility to create a logic with the introduction of a new logic involving the CDN FF. So that it impacts only this query. But this should be aligned core-fe and it’s not part of this scope right now.

Query:

const { data } = useGetPaymentMethodsControlQuery({ fetchPolicy: 'network-only', skip: !enableStorePaymentMethodControl || !storeId, variables: { storeId, }, });

Now, the payment methods are updated, as every time the user accesses the payment screen, the WL-App will fetch the payment information from Sanity.

Clean up non-existent payments on Sanity Restaurant

Currently, if we remove a payment method from the DOP, it will not be removed from Sanity in the restaurant document and this cause a problem of consistency. To address this issue, we need to adjust the updateExistingPayments function on DOP, so that it also removes non-existent payment methods of Sanity.

The table below details the scenario where this issue could happen.

Scenario

Evidence

Scenario

Evidence

All payments are in DOP and these payments have been stored in Sanity.

Payments:
Cash
Cheque Gourmet Voucher
Payment on Delivery Card
Ticket Restaurant Voucher
Sodexo Voucher

 

image-20241213-125336.png

 

Now we remove the SODEXO VOUCHER from the DOP, update the payment status and save it to replace in Sanity.

image-20241213-125528.png

The changes impact Sanity, but the SODEXO VOUCHER still exists in the document of restaurant.
The SODEXO no longer exists in the DOP, so we need to remove it from Sanity as well.

image-20241213-125746.png

Solution

To resolve this, we also need to validate the payment methods in the market. Therefore, it is necessary to send all market payments for this validation in the function updateExistingPayments.

With this new attribute that will include all payment methods in the market, we will be able to validate the restaurant's payment methods against those available in the market. If the restaurant has any methods that do not exist in the market, we can simply remove them, ensuring that the data remains consistent.

Add new atribute on updateRestaurantPayments mutation

File: workspaces/graphql/src/schema/mutations/updateRestaurantPayments.ts

extend type Mutation { """ Update restaurant payment methods """ updateRestaurantPayments( documentIds: [String!]! paymentMethodBrandMarket: [String!]! // new atribute with all payments paymentsUpdate: [PaymentMethodInput!]! ): [Restaurant!] }

Run: yarn build:graphql

  • In the same file get the new attribute paymentMethodBrandMarket and add in the updateRestaurantPaymentsResolver, formatSanityPaymentUpdate and updateSingleRestaurantPaymentsList functions.

  • In the updateExistingPayments on workspaces/graphql/src/schema/mutations/utils/formatPaymentMethodUpdate.ts
    Change this function to validate the payments of market

Like this:

const updateExistingPayments = ( currentList: RestaurantPaymentMethod[], updates: PaymentMethodInput[], paymentMethodBrandMarket: String[] ) => { const updateMap = new Map( updates.map(update => [update.paymentMethodBrand, update]) ); return currentList.reduce((updatedPayments, currentPayment) => { const currentPaymentMethodBrand = currentPayment.paymentMethodBrand as string const updatedPayment = updateMap.get(currentPaymentMethodBrand); // If the payment no longer exists, it will be removed from the restaurant document of Sanity const isValidPayment = paymentMethodBrandMarket.includes(currentPaymentMethodBrand); // Add the payment only if it has been updated or if it already exists. if (updatedPayment || isValidPayment) { updatedPayments.push({ ...currentPayment, ...updatedPayment }); } return updatedPayments; }, [] as RestaurantPaymentMethod[]); }
  • Adjust the unit tests.

Add new atribute paymentMethodBrandMarket on front-end Mutation

File: workspaces/frontend/src/graphql/mutations.graphql

mutation UpdateAllowPayments( $documentIds: [String!]! $paymentMethodBrandMarket: [String!]! //new atribute $updatePayload: [PaymentMethodInput!]! ) { updateRestaurantPayments( documentIds: $documentIds paymentMethodBrandMarket: $paymentMethodBrandMarket //new atribute paymentsUpdate: $updatePayload ) { id paymentMethods { paymentMethodBrand state } } }

Run: yarn build:graphql

After this send the new attribute on updateAllowPayments in saveCashLimitation function.
File workspaces/frontend/src/hooks/usePaymentMethods.tsx

Adjust the unit tests.

POC

https://github.com/rbilabs/ctg-fz-portal/pull/3253

Create a schedule to enable/disable the payment methods states

Some restaurants need to enable or disable certain payment methods daily or twice a week. To address this, we will implement a scheduling feature for each payment method.

 

Create a Feature Flag

Create a new feature flag on DOP to control the exhibitions of schedule fields like:

  • Label and Toggle Quick Fill

  • Schedule Dropbox

Name of new flag: enable-schedule-payment-method-control

 

Create a Date component

This date component already exists on DOP, but it's used in delivery location. So we need to change the place more generic.

Name Component: <DateFilter/>

Location: src/pages/delivery/history/filters/OrderHistoryFilters.styled.ts

 

Create a Dropbox Component

Create a new Dropbox with:

  • Title

  • Description Label

  • Two Radio box (Custom Deactivation Period / Permanent Deactivation)

image-20241205-113151.png

DOD:

  • When collapsing the Dropbox, it needs to adjust its position below the payment title and next to the status.

  • When expanding the Dropbox, it should expand below the payment title and status.

  • When the Dropbox is opened and there are no saved configurations, the “Custom Deactivation Period” option must be selected.

 

Create a component Quick Fill

  • Create a new flag called “Quick fill“;

  • Create a new option among the payment methods called “Quick Fill,” with the default value set to undetermined.

When the "Quick Fill" component is activated, a new item called "Quick Fill" will appear in the payment list. When we make changes to this payment method, those changes will be replicated across all other payments. This provides an easier way for users to modify multiple payments at the same time.

In this PR have a example of quick fill https://github.com/rbilabs/ctg-fz-portal/pull/3252

 

image-20241204-161139.png

DOD

  • Default value of flag is false

  • Default value of state is undetermined

  • The “Quick Fill” option in payments is enabled only when the quick fill flag is set to true.

  • The “Quick Fill” option, when edited, will update all payment methods.

 

Add component and Logic on Payment Method Screen on Allow Payments

  • Add these components on payment methods component

  • Verify all scenarios possibles on Figma

User Flows

Flow 1:

  • When the user selects “Quick Fill,” all methods share the same behavior.

  • Clicking “Deactivate” expands the deactivation settings with today’s date and reactivation set for the next day at 11:00. The user can adjust the dates and open or close the settings using the dropdown arrow.

  • If “Quick Fill” is deselected, methods keep their settings but behave independently.

  • The user can also switch to “Activated” and later selects again Deactivate, then the deactivation settings will reopen again (with today’s date and reactivation set for 24 hours later at 11:00).

  • Figma

Flow1.mov

Flow 2:

  • When the user deactivates a method and selects a future date, the state automatically changes to “Enabled.” The reactivation date is set for 11:00 on the day after the chosen date (though it can be adjusted).

  • If the user clicks “Deactivate” again, the deactivation settings reset to the current date and time by default.

  • Figma

Flow2.mov

Flow 3:

  • If the user sets the dates to the current moment instead of a future date, the method will be deactivated, and the button will change to “Disabled.”

  • Figma

flow3.mov

DOD:

  • If the user selects deactivation by period, it is mandatory to choose two dates: from and to.

  • If the user selects deactivation by period, the start date from must be the moment the user chooses this option, but the user can change this date just to at moment or future date.

  • If the user selects deactivation by period, the start date to must be the next day at 11 am, but the user can change this date to a future date, after the date from.

  • If the user selects permanent deactivation, the dates need to be null.

 

Remove the flag of Cash Limitation of control of Payment method screen

Remove the cash limitation flag from the Editor Bar component, because this flag prevents the Allow Payment option from being displayed.

File: workspaces/frontend/src/pages/editor/editor-bar/EditorBar.tsx

image-20241206-164718.png
This dropdown that need to remove Cash Limitation flag

Add the cash limitation flag on Payment Methods Page to control the display of DeliveryAmountCard and PreventRepeatedFailureCard.

File: workspaces/frontend/src/pages/payment-methods/PaymentMethodsPage.tsx

DOD

  • If the cash limitation flag is disabled, the user will be able to access the Payment Method Page.

 

Create logic to change payment status according to schedule

When the user is on the payment methods screen and there is a scheduled payment method, the DOP should check the statuses that have future changes. If there are any, the system must perform periodic checks (pulling or timeout) to determine when the scheduled date is reached, so that it can automatically change the status of the payment method.

Scenario: The status of the cash payment is currently active, but it has a scheduled deactivation.

  • The current date is 04/18/2024 at 18:55:00.

  • The deactivation date is 04/18/2024 at 19:00:00.

  • In this case, the payment method remains active, but in 5 minutes, it should switch to deactivated.

This change must occur automatically, which is why we need to implement validation to ensure this happens.

DOD

  • If the status is deactivated and there is a scheduled reactivation, the status must change to active at the correct time of reactivation.

  • If the status is activated and there is a scheduled deactivation, the status must change to deactive at the correct time of deactivation.

  • If there is no scheduled date, the status should not change.

 

Save the schedule information on Sanity

We need to save the information about the schedule on Sanity.

So we need to add two new fields in PaymentConfig to the DOP to send this to Sanity.

File: workspaces/frontend/src/hooks/usePaymentMethods.tsx

export type PaymentConfig = { ... deactivationFrom: String | null deactivationTo: String | null };

We need to add these dates on updateRestaurantPaymentsMutation

input PaymentMethodInput { ... deactivationFrom: String deactivationTo: String }

File: workspaces/graphql/src/schema/mutations/updateRestaurantPayments.ts

 

Show the Schedule information on Sanity

Display the schedule information on each payment.
For this, we need to change the custom component.

File: components/restaurant-payment-methods-list.tsx

image-20241204-161615.png

DOD:

  • Display the Deactivate date, if it exists.

  • Display the Reactivate date, if it exists.

 

Get schedule on WL-App to display or not the Payment

Get this information with GetPaymentMethodsControlQuery
We need to do:

  • Add the Deactivate date on PaymentMethodsFragment

  • Add the Reactivate date on PaymentMethodsFragment

  • Use this information to determine whether the payment is enabled or not.

DOD

  • If a payment falls between the deactivate and reactivate dates, it will not be displayed.

  • If a payment doesn't have any date, it should maintain its normal behavior.

 

Figma file

DOP - FZ Portal

https://www.figma.com/design/CeYjZSYqevJwE9Lp2emj5P/branch/axJnmgvzdxnAM5TpeI4czb/Digital-Ops-Portal?node-id=7444-9558&node-type=canvas&t=Sqj2NNwbWLFeONXk-0

Sanity:
https://www.figma.com/design/oLr5rewpNjJ5VWgoCh27i1/branch/OaeRqnr1zqNYTuRMDmGSms/RBI-Sanity-Studio?node-id=7759-75338&node-type=frame&t=eVNSzHS2TSG7ICB5-0

Potential Challenges

List here potential challenges that have come across the opportunity definition or from the potential solutions so far.

Cost

Describe any additional cost this solution may imply.

Configuration

Include here any configuration required (Sanity, LaunchDarkly flags, etc.) required to enable the solution.

  • A new feature flag enable-schedule-payment-method-control on DOP

Metrics

Describe the metrics that will be used to measure the solution’s success, as well as how to measure those KPIs.

  • Reduce canceled orders associated with offline payment methods

  • Payment conversion rate (to avoid reduced conversion due to payment methods disablement)

  • Feedback positive of operation team about flexibility to change payment methods

  • Start using new payment methods like “Terminal at home” payment method in BK PT

  • There is a possibility to create an amplitude chart that monitors the payment types, and check the number of payments by type, specificially, at the times of offline deactivation. The expectation is that the online payment at these times will increase compared to previous periods when we didn’t have this feature.

Delivery Plan

Link to the task or list of all the tasks required to deliver the solution, along with its progress.

https://rbictg.atlassian.net/browse/IBFEC-1943
https://rbictg.atlassian.net/browse/IBFEC-3213

QA Plan

Testing scenarios. See example here.

Call-outs

Tip: Document here any improvement or discussion regarding the feature

 

FAQ

Doubts and questions

 

 

Related content