feat: Edit Stripe payment settings

This commit is contained in:
Ahmed Bouhuolia
2024-09-22 14:55:48 +02:00
parent 3129c76c30
commit 3308133736
7 changed files with 120 additions and 4 deletions

View File

@@ -21,6 +21,7 @@ export class PaymentServicesController extends BaseController {
asyncMiddleware(this.getPaymentServicesSpecificInvoice.bind(this))
);
router.get('/state', this.getPaymentMethodsState.bind(this));
router.get('/:paymentServiceId', this.getPaymentService.bind(this));
router.post(
'/:paymentMethodId',
[
@@ -65,6 +66,33 @@ export class PaymentServicesController extends BaseController {
}
}
/**
* Retrieves a specific payment service.
* @param {Request} req - Request.
* @param {Response} res - Response.
* @param {NextFunction} next - Next function.
* @return {Promise<Response | void>}
*/
private async getPaymentService(
req: Request<{ paymentServiceId: number }>,
res: Response,
next: NextFunction
) {
const { tenantId } = req;
const { paymentServiceId } = req.params;
try {
const paymentService = await this.paymentServicesApp.getPaymentService(
tenantId,
paymentServiceId
);
return res.status(200).send({ data: paymentService });
} catch (error) {
next(error);
}
}
/**
* Edits the given payment method settings.
* @param {Request} req - Request.

View File

@@ -0,0 +1,27 @@
import { Inject, Service } from 'typedi';
import HasTenancyService from '../Tenancy/TenancyService';
import { GetPaymentMethodsPOJO } from './types';
@Service()
export class GetPaymentMethodService {
@Inject()
private tenancy: HasTenancyService;
/**
* Retrieves the payment state provising state.
* @param {number} tenantId
* @returns {Promise<GetPaymentMethodsPOJO>}
*/
public async getPaymentMethod(
tenantId: number,
paymentServiceId: number
): Promise<GetPaymentMethodsPOJO> {
const { PaymentIntegration } = this.tenancy.models(tenantId);
const stripePayment = await PaymentIntegration.query()
.findById(paymentServiceId)
.throwIfNotFound();
return stripePayment;
}
}

View File

@@ -4,6 +4,7 @@ import { DeletePaymentMethodService } from './DeletePaymentMethodService';
import { EditPaymentMethodService } from './EditPaymentMethodService';
import { EditPaymentMethodDTO, GetPaymentMethodsPOJO } from './types';
import { GetPaymentMethodsStateService } from './GetPaymentMethodsState';
import { GetPaymentMethodService } from './GetPaymentService';
@Service()
export class PaymentServicesApplication {
@@ -19,6 +20,9 @@ export class PaymentServicesApplication {
@Inject()
private getPaymentMethodsStateService: GetPaymentMethodsStateService;
@Inject()
private getPaymentMethodService: GetPaymentMethodService;
/**
* Retrieves the payment services for a specific invoice.
* @param {number} tenantId - The ID of the tenant.
@@ -31,6 +35,18 @@ export class PaymentServicesApplication {
);
}
/**
* Retrieves specific payment service details.
* @param {number} tenantId - Tennat id.
* @param {number} paymentServiceId - Payment service id.
*/
public async getPaymentService(tenantId: number, paymentServiceId: number) {
return this.getPaymentMethodService.getPaymentMethod(
tenantId,
paymentServiceId
);
}
/**
* Deletes the given payment method.
* @param {number} tenantId

View File

@@ -91,10 +91,12 @@ function StripePaymentMethod() {
});
};
// Handle edit button click.
const handleEditBtnClick = () => {
openDrawer(DRAWERS.STRIPE_PAYMENT_INTEGRATION_EDIT);
};
// Handle delete connection button click.
const handleDeleteConnectionClick = () => {
openAlert('delete-stripe-payment-method', {
paymentMethodId: stripePaymentMethodId,
@@ -133,7 +135,6 @@ function StripePaymentMethod() {
Complete Stripe Set Up
</Button>
)}
{isAccountCreated && (
<Popover
content={

View File

@@ -1,10 +1,14 @@
import React, { createContext, useContext } from 'react';
import { Spinner } from '@blueprintjs/core';
import { useAccounts } from '@/hooks/query';
import { useGetPaymentMethod } from '@/hooks/query/payment-services';
interface StripeIntegrationEditContextType {
accounts: any;
isAccountsLoading: boolean;
paymentMethod: any;
isPaymentMethodLoading: boolean;
}
const StripeIntegrationEditContext =
@@ -27,8 +31,19 @@ export const useStripeIntegrationEditBoot = () => {
export const StripeIntegrationEditBoot: React.FC = ({ children }) => {
const { data: accounts, isLoading: isAccountsLoading } = useAccounts({}, {});
const value = { accounts, isAccountsLoading };
const isLoading = isAccountsLoading;
const { data: paymentMethod, isLoading: isPaymentMethodLoading } =
useGetPaymentMethod(9);
const value = {
// Accounts.
accounts,
isAccountsLoading,
// Payment methods.
paymentMethod,
isPaymentMethodLoading,
};
const isLoading = isAccountsLoading || isPaymentMethodLoading;
if (isLoading) {
return <Spinner size={20} />;

View File

@@ -7,6 +7,8 @@ import { Intent } from '@blueprintjs/core';
import { usePaymentMethodsBoot } from '../PreferencesPaymentMethodsBoot';
import { useDrawerActions } from '@/hooks/state';
import { useDrawerContext } from '@/components/Drawer/DrawerProvider';
import { useStripeIntegrationEditBoot } from './StripeIntegrationEditBoot';
import { transformToForm } from '@/utils';
interface StripeIntegrationFormValues {
paymentAccountId: string;
@@ -34,9 +36,15 @@ export function StripeIntegrationEditForm({
const { name } = useDrawerContext();
const { mutateAsync: updatePaymentMethod } = useUpdatePaymentMethod();
const { paymentMethodsState } = usePaymentMethodsBoot();
const { paymentMethod } = useStripeIntegrationEditBoot();
const stripePaymentState = paymentMethodsState?.stripe;
const paymentMethodId = stripePaymentState?.stripePaymentMethodId;
const formInitialValues = {
...initialValues,
...transformToForm(paymentMethod?.options, initialValues),
};
const onSubmit = (
values: StripeIntegrationFormValues,
{ setSubmitting }: FormikHelpers<StripeIntegrationFormValues>,
@@ -62,7 +70,7 @@ export function StripeIntegrationEditForm({
return (
<Formik
initialValues={initialValues}
initialValues={formInitialValues}
validationSchema={validationSchema}
onSubmit={onSubmit}
>

View File

@@ -114,3 +114,24 @@ export const useUpdatePaymentMethod = (): UseMutationResult<
.then((response) => response.data),
);
};
interface GetPaymentMethodResponse {}
/**
* Retrieves a specific payment method.
* @param {number} paymentMethodId - The ID of the payment method.
* @returns {UseQueryResult<GetPaymentMethodResponse, Error>}
*/
export const useGetPaymentMethod = (
paymentMethodId: number,
): UseQueryResult<GetPaymentMethodResponse, Error> => {
const apiRequest = useApiRequest();
return useQuery<GetPaymentMethodResponse, Error>(
['paymentMethod', paymentMethodId],
() => apiRequest.get(`/payment-services/${paymentMethodId}`),
{
select: (data) =>
transformToCamelCase(data.data) as GetPaymentMethodResponse,
},
);
};