[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)
|
- 1 Potential Solutions
- 2 Proposed Solution
- 2.1 Enhance the WL-App to retrieve the allowed payment methods more efficiently
- 2.2 Clean up non-existent payments on Sanity Restaurant
- 2.3 Create a schedule to enable/disable the payment methods states
- 2.3.1 Create a Feature Flag
- 2.3.2 Create a Date component
- 2.3.3 Create a Dropbox Component
- 2.3.4 Create a component Quick Fill
- 2.3.5 Add component and Logic on Payment Method Screen on Allow Payments
- 2.3.6 Remove the flag of Cash Limitation of control of Payment method screen
- 2.3.7 Create logic to change payment status according to schedule
- 2.3.8 Save the schedule information on Sanity
- 2.3.9 Show the Schedule information on Sanity
- 2.3.10 Get schedule on WL-App to display or not the Payment
- 3 Figma file
- 4 Cost
- 5 Configuration
- 6 Metrics
- 7 Delivery Plan
- 8 QA Plan
- 9 Call-outs
- 10 FAQ
Potential Solutions
This document intends to present the solution to these problems:
Improvements in the first solution of Allow Payment Methods:
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;
New feature in Allow Payment Methods:
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 |
---|---|
All payments are in DOP and these payments have been stored in Sanity. Payments: |
|
Now we remove the SODEXO VOUCHER from the DOP, update the payment status and save it to replace in Sanity. | |
The changes impact Sanity, but the SODEXO VOUCHER still exists in the document of restaurant. |
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 theupdateRestaurantPaymentsResolver
,formatSanityPaymentUpdate
andupdateSingleRestaurantPaymentsList
functions.In the
updateExistingPayments
onworkspaces/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)
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
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).
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.
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.”
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 datefrom
.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
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
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
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