feat(dimentorin): wire appointment payment flow to payments API

- PaymentStep: selectable VA/QRIS method, rate from mentor.mentoring_rate (fallback 50000), onMethodChange
- AppointmentModal: book session -> create payment -> route to VA/QRIS step with real payment data; then success
- QrisPaymentStep/VAPaymentStep: show real total + external_ref (VA number/QR ref) + expiry
- service lib: TPayment/TCreatePaymentRequest types + postCreatePayment/getMyPayments/getPaymentById/postConfirmPayment + hooks
- build verified, payments flow bundled
This commit is contained in:
asepharyana
2026-08-05 09:28:56 +07:00
parent a74fabe5f5
commit 893f7ba03c
7 changed files with 209 additions and 30 deletions
+41 -1
View File
@@ -3,14 +3,16 @@ import {
TArticleDetail,
TArticleListItem,
TArticleListParams,
TBookSessionRequest,
TCreatePaymentRequest,
TMentorAvailability,
TMentorDetail,
TMentorListParams,
TMentorRegisterRequest,
TMentorStats,
TPayment,
TSessionFeedbackRequest,
TSessionListResponse,
TBookSessionRequest,
} from '../../types/dimentorin';
import { TResponseMessage } from '../../types/common';
@@ -154,3 +156,41 @@ export const postRegisterMentor = async (
});
return data;
};
export const postCreatePayment = async (
sessionId: string,
payload: TCreatePaymentRequest
): Promise<TPayment> => {
const { data } = await api({
method: 'POST',
url: `/dimentorin/payments/sessions/${sessionId}/create`,
data: payload,
});
return data.data;
};
export const getMyPayments = async (): Promise<TPayment[]> => {
const { data } = await api({
method: 'GET',
url: '/dimentorin/payments/me',
});
return data.data;
};
export const getPaymentById = async (id: string): Promise<TPayment> => {
const { data } = await api({
method: 'GET',
url: `/dimentorin/payments/${id}`,
});
return data.data;
};
export const postConfirmPayment = async (
id: string
): Promise<TResponseMessage> => {
const { data } = await api({
method: 'POST',
url: `/dimentorin/payments/${id}/confirm`,
});
return data;
};
@@ -11,8 +11,12 @@ import {
getMentorSessions,
getMentorStats,
getMentors,
getMyPayments,
getMySessions,
getPaymentById,
postBookSession,
postConfirmPayment,
postCreatePayment,
postRegisterMentor,
postSessionFeedback,
} from '../../api/dimentorin';
@@ -21,11 +25,13 @@ import {
TArticleListItem,
TArticleListParams,
TBookSessionRequest,
TCreatePaymentRequest,
TMentorAvailability,
TMentorDetail,
TMentorListParams,
TMentorRegisterRequest,
TMentorStats,
TPayment,
TSessionFeedbackRequest,
TSessionListResponse,
} from '../../types/dimentorin';
@@ -134,6 +140,41 @@ export const usePostRegisterMentor = () => {
});
};
export const usePostCreatePayment = (sessionId: string) => {
return useMutation({
mutationKey: ['post-create-payment', sessionId],
mutationFn: async (payload: TCreatePaymentRequest) =>
await postCreatePayment(sessionId, payload),
});
};
export const useGetMyPayments = (): UseQueryResult<
TPayment[],
TResponseError
> => {
return useQuery({
queryKey: ['get-my-payments'],
queryFn: async () => await getMyPayments(),
});
};
export const useGetPaymentById = (
id: string
): UseQueryResult<TPayment, TResponseError> => {
return useQuery({
queryKey: ['get-payment-by-id', id],
queryFn: async () => await getPaymentById(id),
enabled: !!id,
});
};
export const usePostConfirmPayment = () => {
return useMutation({
mutationKey: ['post-confirm-payment'],
mutationFn: async (id: string) => await postConfirmPayment(id),
});
};
export const useGetArticles = (
params?: TArticleListParams
): UseQueryResult<TArticleListItem[], TResponseError> => {
@@ -162,3 +162,22 @@ export type TMentorRegisterRequest = {
mentoring_rate_amount: number;
};
};
export type TPayment = {
id: string;
session_id: string;
mentor_id: string;
amount: number;
service_fee: number;
total: number;
method: string;
provider: string;
status: string;
external_ref?: string | null;
expires_at: string;
created_at: string;
};
export type TCreatePaymentRequest = {
method: string; // 'va' | 'qris' | 'manual'
};