Here’s the combined workflow integrating the Booking State Transitions with Auto-Cancellation and the Payment Screenshot Submission and Vendor Confirmation process. This unified flow ensures seamless booking, payment handling, and state transitions with notifications for renters and vendors.
Unified Booking Workflow
Booking States
State | Description |
---|---|
Pending | Booking created but awaiting Partner confirmation. |
Auto-Cancelled | Booking automatically cancelled due to Partner’s inaction within 1 hour. |
Confirmed | Partner has confirmed the booking but awaiting payment verification. |
Awaiting Payment | Renter has uploaded payment screenshot but awaiting Vendor confirmation. |
Paid | Vendor has verified payment and confirmed it as paid. |
Vehicle Ready | Partner has prepared the vehicle for pick-up/delivery. |
In Progress | Vehicle has been handed over to the Renter. |
Completed | Booking successfully completed, and the vehicle is returned. |
Cancelled | Booking cancelled manually by Renter or Partner. |
Refunded | Booking refunded after cancellation (if applicable). |
Issue Reported | An issue (damage, delay, etc.) has been flagged for resolution. |
Workflow Steps
Step 1: Booking Creation
- State:
Pending
- Trigger: Renter creates a booking.
- Time Constraint: If Partner does not confirm within 1 hour, the booking transitions to
Auto-Cancelled
.
Step 2: Partner Confirmation
- State:
Confirmed
- Trigger: Partner confirms the booking.
- Time Constraint: If Renter does not pay or upload a payment screenshot within 1 hour, the booking transitions to
Auto-Cancelled
.
Step 3: Payment Proof Submission
- State:
Awaiting Payment
- Trigger: Renter uploads payment screenshot.
- Action: Booking transitions to
Awaiting Payment
, and the Vendor is notified.
Step 4: Payment Verification by Vendor
- State:
Paid
- Trigger: Vendor confirms payment screenshot.
- Next State:
- Approved: Booking transitions to
Paid
. - Rejected: Booking transitions to
Cancelled
.
- Approved: Booking transitions to
Step 5: Vehicle Preparation
- State:
Vehicle Ready
- Trigger: Vendor prepares the vehicle for delivery/pick-up.
- Next State: Booking progresses to
Vehicle Ready
.
Step 6: Vehicle Handover
- State:
In Progress
- Trigger: Renter picks up the vehicle.
- Action: Booking transitions to
In Progress
.
Step 7: Booking Completion
- State:
Completed
- Trigger: Renter returns the vehicle.
- Action: Booking transitions to
Completed
.
Auto-Cancellation Logic
Current State | Trigger/Action | Next State | Time Constraint | Description |
---|---|---|---|---|
Pending | System checks timeout | Auto-Cancelled | Exceeds 1 hour | Booking is auto-cancelled if not confirmed. |
Confirmed | System checks timeout | Auto-Cancelled | Exceeds 1 hour | Booking is auto-cancelled if payment isn’t made or proof isn’t uploaded. |
Notifications
Renter Notifications
- UI, Email, SMS, WhatsApp:
- Pending → Auto-Cancelled: “Your booking was cancelled because the Partner did not confirm within 1 hour.”
- Confirmed → Auto-Cancelled: “Your booking was cancelled because payment was not completed on time.”
- Awaiting Payment → Paid: “Your payment has been confirmed. The booking is now active.”
Vendor Notifications
- UI, Email, SMS, WhatsApp:
- Payment Proof Submitted: “A payment proof has been uploaded for your confirmation.”
- Pending → Auto-Cancelled: “The booking request was cancelled as you did not confirm within 1 hour.”
- Payment Verified: “You have successfully confirmed the payment.”
Database Structure
Additions to the bookings
Table:
Schema::table('bookings', function (Blueprint $table) {
$table->enum('status', ['Pending', 'Auto-Cancelled', 'Confirmed', 'Awaiting Payment', 'Paid', 'Vehicle Ready', 'In Progress', 'Completed', 'Cancelled', 'Refunded', 'Issue Reported'])->default('Pending');
$table->timestamp('auto_cancel_at')->nullable();
});
Create payment_screenshots
Table:
Schema::create('payment_screenshots', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('booking_id');
$table->unsignedBigInteger('user_id');
$table->string('screenshot_path');
$table->timestamps();
});
Backend Implementation
Payment Proof Submission
public function storePaymentProof(Request $request)
{
$request->validate([
'booking_id' => 'required|exists:bookings,id',
'screenshot' => 'required|image|max:2048',
]);
$screenshotPath = $request->file('screenshot')->store('payment_screenshots', 'public');
PaymentScreenshot::create([
'booking_id' => $request->booking_id,
'user_id' => Auth::id(),
'screenshot_path' => $screenshotPath,
]);
$booking = Booking::find($request->booking_id);
$booking->update(['status' => 'Awaiting Payment']);
$booking->vendor->notify(new PaymentScreenshotSubmittedNotification($booking));
return redirect()->back()->with('success', 'Payment proof submitted successfully.');
}
Auto-Cancellation Job
namespace App\Jobs;
use App\Models\Booking;
class AutoCancelBookings extends Job
{
public function handle()
{
$now = now();
$bookings = Booking::whereIn('status', ['Pending', 'Confirmed'])
->where('auto_cancel_at', '<=', $now)
->get();
foreach ($bookings as $booking) {
if ($booking->status === 'Pending') {
$booking->update(['status' => 'Auto-Cancelled']);
$booking->renter->notify(new BookingAutoCancelledNotification($booking));
$booking->vendor->notify(new BookingAutoCancelledNotification($booking));
} elseif ($booking->status === 'Confirmed' && $booking->payment_status !== 'Paid') {
$booking->update(['status' => 'Auto-Cancelled']);
$booking->renter->notify(new BookingAutoCancelledNotification($booking));
$booking->vendor->notify(new BookingAutoCancelledNotification($booking));
}
}
}
}
Vendor Payment Verification
public function verifyPayment(Request $request, Booking $booking)
{
$request->validate(['action' => 'required|in:approve,reject']);
if ($request->action === 'approve') {
$booking->update(['status' => 'Paid']);
$booking->renter->notify(new PaymentApprovedNotification($booking));
} elseif ($request->action === 'reject') {
$booking->update(['status' => 'Cancelled']);
$booking->renter->notify(new PaymentRejectedNotification($booking));
}
return redirect()->back()->with('success', 'Payment verification processed.');
}
Frontend Implementation
Renter Payment Proof Submission
<form method="POST" action="{{ route('payment.screenshot.store') }}" enctype="multipart/form-data">
@csrf
<input type="hidden" name="booking_id" value="{{ $booking->id }}">
<input type="file" name="screenshot" required>
<button type="submit">Submit Payment Proof</button>
</form>
Vendor Payment Review
<table>
<thead>
<tr>
<th>Booking ID</th>
<th>Screenshot</th>
<th>Action</th>
</tr>
</thead>
<tbody>
@foreach($bookings as $booking)
<tr>
<td>{{ $booking->id }}</td>
<td><a href="{{ asset('storage/' . $booking->paymentScreenshot->screenshot_path) }}" target="_blank">View Screenshot</a></td>
<td>
<form method="POST" action="{{ route('payment.verify', $booking->id) }}">
@csrf
@method('PUT')
<button name="action" value="approve">Approve</button>
<button name="action" value="reject">Reject</button>
</form>
</td>
</tr>
@endforeach
</tbody>
</table>
This workflow provides a robust system for managing bookings, handling payments, and ensuring automated and manual transitions. Notifications across UI, email, SMS, and WhatsApp keep all parties informed.