Files
Hotel-Booking/Frontend/src/services/api/paymentService.ts
Iliyan Angelov 44e11520c5 updates
2025-11-20 02:18:52 +02:00

407 lines
8.8 KiB
TypeScript

import apiClient from './apiClient';
// Types
export interface PaymentData {
booking_id: number;
amount: number;
payment_method: 'cash' | 'bank_transfer' | 'stripe' | 'paypal';
transaction_id?: string;
notes?: string;
}
export interface Payment {
id: number;
booking_id: number;
amount: number;
payment_method: 'cash' | 'bank_transfer' | 'credit_card' | 'debit_card' | 'e_wallet' | 'stripe' | 'paypal';
payment_type: 'full' | 'deposit' | 'remaining';
deposit_percentage?: number;
payment_status: 'pending' | 'completed' | 'failed' | 'refunded';
transaction_id?: string;
payment_date?: string;
notes?: string;
createdAt: string;
updatedAt: string;
booking?: {
id: number;
booking_number: string;
user?: {
name: string;
email?: string;
};
};
}
export interface BankInfo {
bank_name: string;
bank_code: string;
account_number: string;
account_name: string;
amount: number;
content: string;
qr_url: string;
}
export interface PaymentResponse {
success: boolean;
data: {
payment: Payment;
};
message?: string;
}
/**
* Create a new payment record
* POST /api/payments
*/
export const createPayment = async (
paymentData: PaymentData
): Promise<PaymentResponse> => {
const response = await apiClient.post<PaymentResponse>(
'/payments',
paymentData
);
return response.data;
};
/**
* Get payment details by booking ID
* GET /api/payments/:bookingId
*/
export const getPaymentByBookingId = async (
bookingId: number
): Promise<PaymentResponse> => {
const response = await apiClient.get<PaymentResponse>(
`/payments/${bookingId}`
);
return response.data;
};
/**
* Confirm bank transfer payment (with receipt)
* POST /api/payments/confirm
*/
export const confirmBankTransfer = async (
bookingId: number,
transactionId?: string,
receipt?: File
): Promise<{ success: boolean; message?: string }> => {
const formData = new FormData();
formData.append('booking_id', bookingId.toString());
if (transactionId) {
formData.append('transaction_id', transactionId);
}
if (receipt) {
formData.append('receipt', receipt);
}
const response = await apiClient.post(
'/payments/confirm',
formData,
{
headers: {
'Content-Type': 'multipart/form-data',
},
}
);
return response.data;
};
/**
* Get bank transfer info with QR code for deposit
* GET /api/payments/:paymentId/bank-info
*/
export const getBankTransferInfo = async (
paymentId: number
): Promise<{
success: boolean;
data: { payment: Payment; bank_info: BankInfo };
message?: string;
}> => {
const response = await apiClient.get(
`/payments/${paymentId}/bank-info`
);
return response.data;
};
/**
* Confirm deposit payment
* POST /api/payments/confirm-deposit
*/
export const confirmDepositPayment = async (
paymentId: number,
transactionId?: string
): Promise<{
success: boolean;
data: { payment: Payment; booking: any };
message?: string;
}> => {
const response = await apiClient.post(
'/payments/confirm-deposit',
{
payment_id: paymentId,
transaction_id: transactionId,
}
);
return response.data;
};
/**
* Notify payment completion (for admin verification)
* POST /api/payments/notify
*/
export const notifyPaymentCompletion = async (
paymentId: number,
notes?: string
): Promise<{ success: boolean; message?: string }> => {
const response = await apiClient.post(
'/payments/notify',
{
payment_id: paymentId,
notes,
}
);
return response.data;
};
/**
* Get all payments (with optional filters)
* GET /api/payments
*/
export const getPayments = async (params?: {
booking_id?: number;
status?: string;
page?: number;
limit?: number;
}): Promise<{
success: boolean;
data: {
payments: Payment[];
pagination?: {
total: number;
page: number;
limit: number;
totalPages: number;
};
};
message?: string;
}> => {
const response = await apiClient.get('/payments', { params });
// Map backend response format (status: "success") to frontend format (success: true)
const data = response.data;
return {
success: data.status === "success" || data.success === true,
data: data.data || { payments: [] },
message: data.message,
};
};
/**
* Get payments for a booking
* GET /api/payments/booking/:bookingId
*/
export const getPaymentsByBookingId = async (
bookingId: number
): Promise<{
success: boolean;
data: { payments: Payment[] };
message?: string;
}> => {
const response = await apiClient.get(
`/payments/booking/${bookingId}`
);
// Map backend response format (status: "success") to frontend format (success: true)
const data = response.data;
return {
success: data.status === "success" || data.success === true,
data: data.data || { payments: [] },
message: data.message,
};
};
/**
* Create Stripe payment intent
* POST /api/payments/stripe/create-intent
*/
export const createStripePaymentIntent = async (
bookingId: number,
amount: number,
currency: string = 'usd'
): Promise<{
success: boolean;
data: {
client_secret: string;
payment_intent_id: string;
publishable_key: string;
};
message?: string;
}> => {
const response = await apiClient.post(
'/payments/stripe/create-intent',
{
booking_id: bookingId,
amount,
currency,
}
);
// Map backend response format (status: "success") to frontend format (success: true)
const data = response.data;
return {
success: data.status === "success" || data.success === true,
data: data.data || {},
message: data.message,
};
};
/**
* Confirm Stripe payment
* POST /api/payments/stripe/confirm
*/
export const confirmStripePayment = async (
paymentIntentId: string,
bookingId: number
): Promise<{
success: boolean;
data: {
payment: Payment;
booking: {
id: number;
booking_number: string;
status: string;
};
};
message?: string;
}> => {
const response = await apiClient.post(
'/payments/stripe/confirm',
{
payment_intent_id: paymentIntentId,
booking_id: bookingId,
}
);
// Map backend response format (status: "success") to frontend format (success: true)
const data = response.data;
return {
success: data.status === "success" || data.success === true,
data: data.data || {},
message: data.message,
};
};
/**
* Create PayPal order
* POST /api/payments/paypal/create-order
*/
export const createPayPalOrder = async (
bookingId: number,
amount: number,
currency: string = 'USD',
returnUrl?: string,
cancelUrl?: string
): Promise<{
success: boolean;
data: {
order_id: string;
approval_url: string;
status: string;
};
message?: string;
}> => {
const response = await apiClient.post(
'/payments/paypal/create-order',
{
booking_id: bookingId,
amount,
currency,
return_url: returnUrl,
cancel_url: cancelUrl,
}
);
// Map backend response format (status: "success") to frontend format (success: true)
const data = response.data;
return {
success: data.status === "success" || data.success === true,
data: data.data || {},
message: data.message,
};
};
/**
* Capture PayPal payment
* POST /api/payments/paypal/capture
*/
export const capturePayPalPayment = async (
orderId: string,
bookingId: number
): Promise<{
success: boolean;
data: {
payment: Payment;
booking: {
id: number;
booking_number: string;
status: string;
};
};
message?: string;
}> => {
const response = await apiClient.post(
'/payments/paypal/capture',
{
order_id: orderId,
booking_id: bookingId,
}
);
// Map backend response format (status: "success") to frontend format (success: true)
const data = response.data;
return {
success: data.status === "success" || data.success === true,
data: data.data || {},
message: data.message,
};
};
/**
* Cancel PayPal payment (when user cancels on PayPal page)
* POST /api/payments/paypal/cancel
*/
export const cancelPayPalPayment = async (
bookingId: number
): Promise<{
success: boolean;
message?: string;
}> => {
const response = await apiClient.post(
'/payments/paypal/cancel',
{
booking_id: bookingId,
}
);
// Map backend response format (status: "success") to frontend format (success: true)
const data = response.data;
return {
success: data.status === "success" || data.success === true,
message: data.message,
};
};
export default {
createPayment,
getPayments,
getPaymentByBookingId,
confirmBankTransfer,
getBankTransferInfo,
confirmDepositPayment,
notifyPaymentCompletion,
getPaymentsByBookingId,
createStripePaymentIntent,
confirmStripePayment,
createPayPalOrder,
capturePayPalPayment,
cancelPayPalPayment,
};