WP Service Quote Manager
WordPress service quote workflow plugin with admin states, CSV export, scheduled retries, and HMAC webhooks
by szzhoujiarui · github.com/szzhoujiarui/wp-service-quote-manager · website
★ 0stars
0forks
Install
No release zip yet. The repository archive installs, but the folder name will carry the branch suffix and updates will not flow:
wp plugin install https://github.com/szzhoujiarui/wp-service-quote-manager/archive/refs/heads/master.zipReadme
WP Service Quote Manager
A WordPress plugin for managing service quote requests with secure form submission, admin workflow, and webhook delivery.

Features
- Public Quote Form: Shortcode-based form with validation and rate limiting
- Admin Workflow: Request management with status transitions (new → contacted → qualified → closed)
- CSV Export: Filtered export with formula injection prevention
- Webhook Delivery: Signed webhooks with exponential backoff retries
- Security: Nonce verification, input sanitization, and capability checks
Installation
Prerequisites
- PHP 8.2 or higher
- WordPress 6.8 or higher
- Composer
Install via Composer
composer install
Manual Installation
- Download or clone this repository
- Copy to
wp-content/plugins/wp-service-quote-manager/ - Run
composer installin the plugin directory - Activate the plugin in WordPress admin
Screenshots
Header

Features

Architecture

Interactive Demo

Quick Start
1. Activate Plugin
The plugin automatically:
- Creates the
sqm_requestcustom post type - Creates database tables for submission tokens and webhook jobs
- Grants
manage_service_quotescapability to administrators - Schedules the webhook delivery worker (every minute)
2. Configure Services
Go to Quote Manager → Settings and configure available services:
- Consultation
- Web Development
- Automation Integration
3. Add Quote Form
Add the shortcode to any page or post:
[service_quote_form]
4. Configure Webhooks (Optional)
In settings, enable webhooks and provide:
- Webhook URL (HTTPS only)
- Webhook secret (auto-generated if empty)
Architecture
┌─────────────────────────────────────────────────────────────┐
│ WordPress Hooks │
└─────────────────────┬───────────────────────────────────────┘
│
┌─────────────────────▼───────────────────────────────────────┐
│ Plugin Container │
├─────────────────────────────────────────────────────────────┤
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Form │ │ Admin │ │ CSV │ │
│ │ Controller │ │ Controller │ │ Controller │ │
│ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │
│ │ │ │ │
│ ┌──────▼─────────────────▼─────────────────▼───────┐ │
│ │ Request Service │ │
│ │ - Validation - Transitions - Webhook Trigger │ │
│ └──────────────────────┬───────────────────────────┘ │
│ │ │
│ ┌──────────────────────▼───────────────────────────┐ │
│ │ Domain Models │ │
│ │ - Request - SubmissionToken - DeliveryJob │ │
│ │ - WebhookPayload - RequestValidator │ │
│ └──────────────────────┬───────────────────────────┘ │
│ │ │
│ ┌──────────────────────▼───────────────────────────┐ │
│ │ Persistence Layer │ │
│ │ - RequestRepository │ │
│ │ - SubmissionTokenRepository │ │
│ │ - DeliveryRepository │ │
│ └──────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
│
┌─────────────────────▼───────────────────────────────────────┐
│ Webhook Delivery │
│ - WebhookSigner (HMAC-SHA256) │
│ - DeliveryWorker (Cron-based) │
│ - Retry Logic (1, 5, 30 minutes) │
└─────────────────────────────────────────────────────────────┘
Verification Commands
Run Unit Tests
composer test
Run Specific Test Suite
composer test:unit
Check PHP Syntax
find src -name "*.php" -exec php -l {} \;
Run PHPCS (Coding Standards)
./vendor/bin/phpcs --standard=WordPress src/
File Structure
wp-service-quote-manager/
├── src/
│ ├── Admin/
│ │ └── AdminController.php
│ ├── CSV/
│ │ └── CSVExportController.php
│ ├── Domain/
│ │ ├── DeliveryJob.php
│ │ ├── Request.php
│ │ ├── RequestService.php
│ │ ├── RequestValidator.php
│ │ ├── SubmissionToken.php
│ │ └── WebhookPayload.php
│ ├── Form/
│ │ └── QuoteFormController.php
│ ├── Persistence/
│ │ ├── DeliveryRepository.php
│ │ ├── RequestRepository.php
│ │ └── SubmissionTokenRepository.php
│ ├── Webhook/
│ │ ├── DeliveryWorker.php
│ │ └── WebhookSigner.php
│ ├── Container.php
│ └── Plugin.php
├── tests/
│ ├── Unit/
│ │ ├── CSV/
│ │ ├── Domain/
│ │ └── Webhook/
│ └── Integration/
├── docker-compose.yml
├── composer.json
├── phpunit.xml.dist
└── wp-service-quote-manager.php
Status Transitions
new ──────► contacted ──────► qualified
│ │ │
└──────────────┴─────────────────┴──► closed
Webhook Events
quote_request.created
Triggered when a new quote request is submitted.
Headers:
Content-Type: application/jsonX-SQM-Event: quote_request.createdX-SQM-Delivery: <uuid>X-SQM-Timestamp: <unix_timestamp>X-SQM-Signature: sha256=<hmac_hex>
Payload:
{
"schema_version": "1.0",
"event": "quote_request.created",
"delivery_id": "uuid",
"occurred_at": "ISO8601",
"request": {
"reference": "SQM-12345678",
"name": "John Doe",
"email": "john@example.com",
"company": "Example Corp",
"service_type": "consultation",
"budget_range": "under-1000",
"desired_start_date": "2026-08-01",
"message": "Project description...",
"status": "new"
}
}
Security
- All form submissions use nonce verification
- Input is sanitized using WordPress functions
- Output is escaped for the appropriate context
- Webhook URLs are validated (HTTPS, no private IPs)
- Rate limiting prevents abuse (5 submissions per 10 minutes)
- CSV export prevents formula injection
License
GPL-2.0 (see LICENSE file)
Author
szzhoujiarui