The Vendor Management admin page was migrated to a React SPA in v4.40.0. VendorManagementRestController registers 7 REST routes under /wp-json/mhm-rentiva/v1/vendor-management/*. Components: VendorManagementPage, ApplicationTable, VendorTable, VendorDetailPanel, ActionBar. Data is fetched client-side β no full PHP page render.
Rentiva can transform from a centralized vehicle rental system into a Multi-Vendor marketplace. This document explains the vendor lifecycle in technical detail.
π€ Vendor Management
The stages a user must pass through to become a Vendor in the system, and the technical structures behind that process, are summarized below.
ποΈ 1. Vendor Role & Authorizationβ
rentiva_vendor Roleβ
Every approved vendor is assigned this role, which comes with the following capabilities:
edit_posts: Can add their own vehicles.upload_files: Can upload vehicle images.read: Can access the vendor dashboard.
π‘οΈ Ownership Enforcement (VendorOwnershipEnforcer)β
The user_has_cap filter is used to prevent vendors from accessing each other's vehicles or bookings:
- A vendor can only edit
vehiclerecords where thepost_authorvalue matches their ownuser_id. - The "All Vehicles" list in the admin portal is filtered to show only the vendor's own records.
π 2. Application Management (mhm_vendor_app)β
Vendor applicant data is stored within the mhm_vendor_app Custom Post Type (CPT):
- Onboarding Flow:
PendingβApproved/Rejected. - Data Security: IBAN data collected during application is encrypted using
VendorApplicationManager::encrypt_iban()with the AES-256-CBC method. - Document Tracking: Identity, driver's license, and proof of address documents are associated with the WordPress Media Library under
_vendor_doc_*meta keys.
βοΈ 3. Operational Controlsβ
Approval & Meta Synchronization (VendorOnboardingController)β
When an admin approves an application:
- Phone, city, and IBAN data from the
mhm_vendor_apprecord are copied to the user's (WP_User) meta tables. - The user's role is upgraded from
customertorentiva_vendor. - The
mhm_rentiva_vendor_approvedhook is triggered and a welcome email is sent.
Profile Management (VendorProfileExtension)β
The WordPress profile page (wp-admin/profile.php) is extended with vendor-specific fields:
- Store Information: Bio, tax number, and service areas.
- Financial Information: Masked IBAN display (e.g., TR***5678).
Vendor Settings Page (v4.23.1)β
The settings page in the vendor dashboard (vendor-settings.php) was completely redesigned in v4.23.1:
- CSS Architecture: All inline styles removed and moved to
vendor-forms.cssusing the.mhm-vendor-form__*CSS class structure. - New Fields: Account Holder and Tax Office fields added.
- City Selection: Uses the SelectWoo component (
CityHelper::render_select()) instead of a text input. - Notification System: Success/error notifications standardized using the
mhm-vendor-noticeclass structure.
All form fields on the vendor settings page are styled using BEM-like classes such as .mhm-vendor-form__group, .mhm-vendor-form__label, .mhm-vendor-form__input. Follow the same class structure when adding new fields.
Lifecycle Summaryβ
π 5. Vendor Transfer Location & Route Management (v4.23.0)β
With v4.23.0, vendors can select locations and routes for transfer services:
City-Based Filteringβ
On the vendor vehicle submission form ([rentiva_vehicle_submit]), only locations and routes within the city specified in the vendor's application are listed. This is part of the City β Point hierarchy.
Per-Route Pricingβ
- The vendor selects the routes they want to serve.
- For each route, they enter their own price within the
min_priceβmax_pricerange set by the admin. - Capacity details (passengers, luggage) are defined at the vehicle level.
Meta Structureβ
_mhm_rentiva_transfer_locations: Locations the vendor serves (array)_mhm_rentiva_transfer_routes: Routes the vendor serves (array)_mhm_rentiva_transfer_route_prices: Per-route vendor prices (JSON)
Admin Viewβ
On the vehicle edit screen (VehicleTransferMetaBox), the vendor's city and their selected locations/routes are displayed.
π Vehicle Lifecycle Management (v4.24.0)β
A comprehensive vehicle lifecycle system was implemented in v4.24.0:
| Feature | Detail |
|---|---|
| Statuses | Active / Paused / Withdrawn / Expired / Pending Review |
| Listing period | 90 days (admin-configurable), renewable by vendor |
| Cancellation penalty system | Graduated penalty points (2nd withdrawal 10%, 3rd+ 25%) |
| Reliability score | 0β100 performance rating |
| Cooldown period | 7-day waiting period after withdrawal |
| Anti-gaming | Cancelled booking dates blocked for 30 days |
Remaining Time Display on Vendor Vehicle Cards (v4.24.1)β
Each vehicle card in the vendor dashboard shows the remaining listing time:
| Status | Display | Color |
|---|---|---|
| > 50% time remaining | "Remaining: X days" | π’ Green |
| 20%β50% time remaining | "Remaining: X days" | π‘ Yellow |
| < 20% time remaining | "Remaining: X days" | π΄ Red |
| Expired | "Expired" badge | β |
CSS classes: .mhm-vendor-listing-card__remaining with .is-green, .is-yellow, .is-red variants.
π° Paid Listing System (v4.24.1)β
Vendors may be required to pay via WooCommerce to publish a vehicle listing. This feature can be toggled by the admin.
Admin Settings (Settings β Vendor Marketplace β Listing Fee)β
| Setting | Type | Default | Description |
|---|---|---|---|
| Enable Listing Fee | Checkbox | Off | Enable/disable the paid listing system |
| Fee Model | Select | One-Time | one_time or per_period (every 90-day period) |
| Listing Fee Amount | Number | 0 | Fee amount in store currency |
Payment Flowβ
Trigger Pointsβ
| Action | Free Flow | Paid Flow |
|---|---|---|
| New Vehicle | Form β Pending Review | Form β Draft β WC Payment β Pending Review |
| Renewal (expired) | AJAX β Lifecycle renewal | AJAX β WC Payment β Lifecycle renewal |
| Relist (withdrawn) | AJAX β Lifecycle relist | AJAX β WC Payment β Lifecycle relist |
WooCommerce Productβ
- Type:
WC_Product_Simple(virtual, hidden) - SKU:
mhm-rentiva-listing-fee - Visibility: Hidden in the store (not shown in shop/search results)
- Price: Dynamically read from admin settings
- Cart meta:
_mhm_listing_vehicle_id,_mhm_listing_action(new/renew/relist) - Auto-creation: Automatically created when the feature is first enabled
Grandfather Ruleβ
- Existing active vehicles are not affected when the feature is enabled
- Renewal payment is required when the 90-day listing period expires
- No retroactive fees applied
Commission Relationshipβ
The listing fee and commission are independent of each other:
- Vendor pays the listing fee (upfront, per listing)
- Vendor pays commission (percentage, per booking)
- There is no discount or offset between the two
Technical Classβ
ListingFeeManager (src/Admin/Vehicle/ListingFeeManager.php):
is_enabled()β Checks whether the feature is activerequires_payment(string $action)β Determines if payment is required for the given actionget_or_create_product()β Creates or returns the existing WC productadd_to_cart(int $vehicle_id, string $action)β Adds to cart and returns the payment URLon_order_completed()β Publishes the vehicle when the order is completed
π WooCommerce My Account β Vendor Dashboard Menu Link (v4.24.1)β
Users with the vendor role see a "Vendor Dashboard" menu link in the sidebar on the WooCommerce My Account page. This link redirects to /panel/.
| User Role | Menu Item | URL |
|---|---|---|
rentiva_vendor | Vendor Dashboard | /panel/ |
| Other roles (customer, etc.) | Become a Vendor | /hesabim/vendor-apply/ |
Technical Details:
WooCommerceIntegration::add_menu_items()β Menu item is switched based on vendor role checkWooCommerceIntegration::vendor_panel_endpoint_url()β Redirects thevendor-panelendpoint to the/panel/page- The vendor application URL slug is translatable via the
_x()function (SEO-compatible)
π Unsuspend Action (v4.43.0)β
Admins can now unsuspend a vendor directly from the Vendor Management admin page without navigating to the user profile. The unsuspend action:
- Restores the vendor's
rentiva_vendorrole (from suspended state). - Re-publishes any vehicles that were unpublished at suspension time.
- Sends a reactivation email to the vendor.
- Logs the action in the commission audit log.
REST endpoint: POST /wp-json/mhm-rentiva/v1/vendor-management/unsuspend (requires manage_options).
π Commission Audit Log (v4.43.0)β
Every commission transaction is now written to a persistent audit log, accessible from the Vendor Management detail panel. Each entry records:
| Field | Description |
|---|---|
event_type | commission_applied, commission_reversed, vendor_suspended, vendor_unsuspended, penalty_applied, penalty_deferred |
vendor_id | Vendor user ID |
booking_id | Associated booking (where applicable) |
amount | Commission or penalty amount (signed float) |
note | Admin or system-generated note |
created_at | Timestamp |
admin_user_id | Admin who triggered the event (NULL for system events) |
The audit log is append-only β entries are never deleted or modified. Use it to trace disputes, verify payouts, and audit automated penalty events.
REST endpoint: GET /wp-json/mhm-rentiva/v1/vendor-management/{vendor_id}/audit-log
React Components (v4.40.0+)β
| Component | Purpose |
|---|---|
VendorManagementPage | Root β tab navigation (Applications / Vendors / Audit) |
ApplicationTable | Paginated pending application list with approve/reject actions |
VendorTable | Active vendor list with search and status filter |
VendorDetailPanel | Slide-in panel: IBAN (masked), documents, audit log, actions |
ActionBar | Suspend / Unsuspend / Edit quick-action row |
REST Namespace: GET/POST /wp-json/mhm-rentiva/v1/vendor-management/*
Known Issues (Discovered in v4.23.1)β
| Issue | Detail | Status |
|---|---|---|
| Vehicle status filter | _mhm_vehicle_status is not checked in search queries β vehicles in maintenance are visible. | Discovered |
| Vendor suspension | VendorOnboardingController::suspend() does not unpublish vendor vehicles. | Discovered |
Section Summaryβ
- Data isolation is guaranteed by
VendorOwnershipEnforcer. - All critical application data is stored encrypted.
rentiva_vendorcapabilities apply only to posts owned by the vendor.- Vendors can only access locations and routes in their own city. (v4.23.0)
- The vendor settings page was redesigned with a BEM-like CSS class structure. (v4.23.1)
- City selection uses the SelectWoo component across all forms. (v4.23.1)
- Vehicle lifecycle system (90-day listing, pausing, renewal, withdrawal) implemented. (v4.24.0)
- Paid listing system: WooCommerce checkout-based payment gate, admin-configurable. (v4.24.1)
- Remaining time display on vendor vehicle cards (color-coded). (v4.24.1)
- "Vendor Dashboard" link added for vendors in the WC My Account menu. (v4.24.1)
Changelogβ
| Date | Version | Note |
|---|---|---|
| 07.05.2026 | 4.43.0 | Unsuspend action (role restore + vehicle re-publish + email). Commission audit log (append-only, 6 event types). |
| 06.05.2026 | 4.40.0 | Full React SPA migration. VendorManagementRestController (7 REST routes). VendorManagementPage, ApplicationTable, VendorTable, VendorDetailPanel, ActionBar components. |
| 23.04.2026 | 4.27.2 | English translation added. |
| 01.04.2026 | 4.24.1 | Paid listing system (ListingFeeManager), remaining time display, WC My Account "Vendor Dashboard" menu link, 18 new tests. |
| 29.03.2026 | 4.24.0 | Vehicle lifecycle system implemented (Phases 0-4, 6-7). Pause, renewal, withdrawal, reliability score. |
| 28.03.2026 | 4.23.1 | Vendor settings page redesign, Account Holder and Tax Office fields, city SelectWoo migration. |
| 26.03.2026 | 4.23.0 | Vendor Transfer Location/Route management, CityβPoint hierarchy, and per-route pricing added. |
| 19.03.2026 | 4.21.2 | CPT, Enforcer, and Onboarding details added. |