Update CBS Mobile App codebase
This commit is contained in:
@@ -1,14 +1,34 @@
|
||||
import type { Beneficiary } from '../../../types/app';
|
||||
import { demoBeneficiaries } from '../../../constants/mockData';
|
||||
import { endpoints } from '../../../services/api/endpoints';
|
||||
import { apiClient } from '../../../services/api/apiClient';
|
||||
import { baseApi } from '../../../services/api/baseApi';
|
||||
import { resolveWithMock } from '../../../services/api/serviceHelpers';
|
||||
import { endpoints } from '../../../services/api/endpoints';
|
||||
import { resolveLive, resolveWithMock } from '../../../services/api/serviceHelpers';
|
||||
import type { Beneficiary } from '../../../types/app';
|
||||
import type {
|
||||
BeneficiarySaveRequest,
|
||||
BeneficiaryValidateRequest,
|
||||
BeneficiaryValidateResult,
|
||||
CbsBeneficiary,
|
||||
} from '../../../types/cbs';
|
||||
import { favoriteStore, toBeneficiary } from '../utils/beneficiaryMapper';
|
||||
|
||||
/**
|
||||
* TEMPORARY — fixed payer account for payee validation.
|
||||
*
|
||||
* Every validate call goes out with this as the payer, overriding whichever
|
||||
* account the customer selected on screen. The development CBS only recognises
|
||||
* this account as a payer; the profile's own accounts come back
|
||||
* `ACCOUNT_NOT_FOUND`, which reads on screen as the *payee* being unverifiable.
|
||||
*
|
||||
* Delete this and pass `request` through untouched once the backend accepts
|
||||
* the profile's accounts. It must not ship: in production it would validate
|
||||
* every payee against an account that is not the customer's.
|
||||
*/
|
||||
const HARDCODED_PAYER_ACCOUNT = '002002000100019';
|
||||
|
||||
export interface BankTransferRequest {
|
||||
beneficiaryId: string;
|
||||
amount: number;
|
||||
transferType: 'IMPS' | 'NEFT' | 'RTGS';
|
||||
transferType: 'IMPS' | 'NEFT' | 'RTGS' | 'Internal';
|
||||
remarks?: string;
|
||||
sourceAccountId: string;
|
||||
}
|
||||
@@ -20,37 +40,66 @@ export interface BankTransferResponse {
|
||||
|
||||
export const paymentsApi = baseApi.injectEndpoints({
|
||||
endpoints: (builder) => ({
|
||||
/** The customer's saved payees, newest first. */
|
||||
getBeneficiaries: builder.query<Beneficiary[], void>({
|
||||
queryFn: () =>
|
||||
resolveWithMock({
|
||||
mockData: demoBeneficiaries,
|
||||
request: async () => {
|
||||
// Real API implementation
|
||||
// const response = await apiClient.get<Beneficiary[]>('/beneficiaries');
|
||||
// return response.data;
|
||||
return [] as Beneficiary[];
|
||||
},
|
||||
resolveLive(async () => {
|
||||
const [response, favorites] = await Promise.all([
|
||||
apiClient.get<CbsBeneficiary[]>(endpoints.beneficiaries.list),
|
||||
favoriteStore.read(),
|
||||
]);
|
||||
|
||||
const favoriteSet = new Set(favorites);
|
||||
|
||||
return (response.data ?? []).map((payee) => toBeneficiary(payee, favoriteSet));
|
||||
}),
|
||||
providesTags: ['Payments'],
|
||||
providesTags: ['Beneficiaries'],
|
||||
}),
|
||||
addBeneficiary: builder.mutation<Beneficiary, Partial<Beneficiary>>({
|
||||
queryFn: (newBen) =>
|
||||
resolveWithMock({
|
||||
mockData: {
|
||||
id: `ben_${Date.now()}`,
|
||||
name: newBen.name || 'Unknown',
|
||||
bankName: newBen.bankName || 'Unknown Bank',
|
||||
accountMasked: newBen.accountMasked || 'xxxx0000',
|
||||
favorite: false,
|
||||
} as Beneficiary,
|
||||
request: async () => {
|
||||
// const response = await apiClient.post('/beneficiaries/add', newBen);
|
||||
// return response.data;
|
||||
return {} as Beneficiary;
|
||||
}
|
||||
}),
|
||||
invalidatesTags: ['Payments'],
|
||||
|
||||
/**
|
||||
* Asks IMPS whether this payee exists, and who they are. Saves nothing.
|
||||
*
|
||||
* This is what the confirmation step shows, because a mistyped account
|
||||
* number is the most common way money reaches the wrong person. Read
|
||||
* `result` rather than the status code: the switch answers 200 whether or
|
||||
* not it recognised the payee.
|
||||
*/
|
||||
validateBeneficiary: builder.mutation<BeneficiaryValidateResult, BeneficiaryValidateRequest>({
|
||||
queryFn: (request) =>
|
||||
resolveLive(async () => {
|
||||
const response = await apiClient.post<BeneficiaryValidateResult>(
|
||||
endpoints.beneficiaries.validate,
|
||||
// See HARDCODED_PAYER_ACCOUNT — the caller's payer is discarded.
|
||||
{ ...request, payer: { accountNumber: HARDCODED_PAYER_ACCOUNT } },
|
||||
);
|
||||
|
||||
return response.data;
|
||||
}),
|
||||
}),
|
||||
|
||||
/**
|
||||
* Saves the payee, resolved through the bank's CBS lookup.
|
||||
*
|
||||
* A different body and a different lookup from validate, which goes to
|
||||
* IMPS — so the two can disagree, and this one's answer is what gets
|
||||
* stored. Validate first regardless: the server does not enforce the
|
||||
* order, which means nothing but the app stops a customer saving a payee
|
||||
* nobody has confirmed.
|
||||
*/
|
||||
saveBeneficiary: builder.mutation<Beneficiary, BeneficiarySaveRequest>({
|
||||
queryFn: (request) =>
|
||||
resolveLive(async () => {
|
||||
const response = await apiClient.post<CbsBeneficiary>(
|
||||
endpoints.beneficiaries.save,
|
||||
request,
|
||||
);
|
||||
|
||||
return toBeneficiary(response.data);
|
||||
}),
|
||||
invalidatesTags: ['Beneficiaries'],
|
||||
}),
|
||||
|
||||
/** No transfer endpoint exists yet, so this stays on fixtures. */
|
||||
submitBankTransfer: builder.mutation<BankTransferResponse, BankTransferRequest>({
|
||||
queryFn: (req) =>
|
||||
resolveWithMock({
|
||||
@@ -59,9 +108,7 @@ export const paymentsApi = baseApi.injectEndpoints({
|
||||
status: req.transferType === 'NEFT' ? 'Process_Pending' : 'Process_Success',
|
||||
}),
|
||||
request: async () => {
|
||||
// const response = await apiClient.post<BankTransferResponse>('/transactions/transfer', req);
|
||||
// return response.data;
|
||||
return { referenceId: '', status: 'Process_Success' };
|
||||
throw new Error('Transfer submission is not implemented by the CBS API yet');
|
||||
},
|
||||
}),
|
||||
invalidatesTags: ['Payments', 'Transactions'],
|
||||
@@ -69,4 +116,9 @@ export const paymentsApi = baseApi.injectEndpoints({
|
||||
}),
|
||||
});
|
||||
|
||||
export const { useGetBeneficiariesQuery, useAddBeneficiaryMutation, useSubmitBankTransferMutation } = paymentsApi;
|
||||
export const {
|
||||
useGetBeneficiariesQuery,
|
||||
useValidateBeneficiaryMutation,
|
||||
useSaveBeneficiaryMutation,
|
||||
useSubmitBankTransferMutation,
|
||||
} = paymentsApi;
|
||||
|
||||
Reference in New Issue
Block a user