Appearance
Background Jobs
Upvendo uses Laravel's queue system to offload time-consuming operations from the HTTP request cycle. Jobs handle email sending, payment capture, integration syncing, image processing, and order processing.
Key Files
All jobs live in app/Jobs/:
app/Jobs/
CapturePaymentJob.php
CompressImageJob.php
ExportUpvendoMenuToShopifyJob.php
GenerateQrCodesConsolidation.php
GenerateQrCodesConsolidationBatch.php
GenerateQrCodesFinalConsolidation.php
GenerateQrCodesForSection.php
GenerateQrCodesForSectionBatch.php
GetKassanetBillJob.php
ImportKassanetCategoriesJob.php
ImportKassanetDisplayGroupsJob.php
ImportKassanetMenuJob.php
ImportKassanetProductsJob.php
ImportShopifyMenuJob.php
PayKassanetBillJob.php
ProcessOrderJob.php
RetranslatePublishedLanguagesJob.php
SendBackofficeOTPMail.php
SendDeviceActivationCodeMail.php
SendGridMail.php
SendLocalOrderDeliveredMail.php
SendLocalOrderMissedDeliveryMail.php
SendLocalOrderOutForDeliveryMail.php
SendLocalOrderPickupCompletedMail.php
SendLocalOrderReadyDeliveryMail.php
SendLocalOrderReadyForPickupMail.php
SendLocalOrderReceiptMail.php
SendLoyaltyProgramAlertMail.php
SendMerchantInvitationMail.php
SendPasswordResetMail.php
SendSMS.php
SendVerificationCodeMail.php
SyncLocationToDeliverooJob.php
SyncSquareIntegrationJob.php
SyncSquareInventoryJob.php
SyncSquareJob.php
SyncSquareLocationJob.php
SyncSquareMenuJob.php
UpdateD1StocksAfterPayment.php
UpdateUserUberLocationsJob.php
UberEats/
ProcessUberEatsCancelNotificationJob.php
ProcessUberEatsOrderNotificationJob.php
ProcessUberEatsScheduledNotificationJob.phpJob Categories
Payment Jobs
| Job | Purpose | Dispatched By |
|---|---|---|
CapturePaymentJob | Capture payment after terminal confirmation | KioskOrchestrator |
ProcessOrderJob | Post-payment order processing (KDS, notifications) | PaymentCaptureService |
UpdateD1StocksAfterPayment | Sync stock changes to Cloudflare D1 edge database | PaymentCaptureService |
ProcessOrderJob
The most important job in the payment flow. Dispatched after successful payment capture.
php
ProcessOrderJob::dispatch($transactionId, $locationId);Dispatch timing (from PaymentCaptureService::processOrderJob()):
- Kiosk orders: Dispatched immediately
- Online ordering (dine-in): Dispatched immediately
- Online ordering (delivery/pickup): May be delayed based on
sent_attime - Local development: Executed synchronously via
->handle()
Delayed dispatch for scheduled orders:
php
$delayInSeconds = $processTime->diffInSeconds($now, true);
ProcessOrderJob::dispatch($transactionId, $locationId)->delay($delayInSeconds);Email Jobs
| Job | Purpose | Trigger |
|---|---|---|
SendBackofficeOTPMail | Send OTP code for 2FA login | AuthService::requestBackofficeOTP() |
SendDeviceActivationCodeMail | Send device activation code | Device management |
SendGridMail | Generic email via SendGrid | Various |
SendLocalOrderReceiptMail | Send order receipt to customer | After payment capture |
SendLocalOrderReadyForPickupMail | Notify customer order is ready | KDS marks order ready |
SendLocalOrderOutForDeliveryMail | Notify customer order is out for delivery | Order status change |
SendLocalOrderDeliveredMail | Confirm delivery to customer | Order status change |
SendLocalOrderReadyDeliveryMail | Notify order ready for delivery | KDS marks order ready |
SendLocalOrderPickupCompletedMail | Confirm pickup complete | Order status change |
SendLocalOrderMissedDeliveryMail | Notify missed delivery | Delivery status |
SendLoyaltyProgramAlertMail | Loyalty program notifications | Loyalty threshold reached |
SendMerchantInvitationMail | Invite user to merchant team | Team management |
SendPasswordResetMail | Password reset link | AuthService::forgetPassword() |
SendVerificationCodeMail | Customer verification code | AuthCustomerService::sendOTP() |
SMS Jobs
| Job | Purpose |
|---|---|
SendSMS | Send SMS via configured provider (customer OTP, notifications) |
Integration Sync Jobs
| Job | Purpose | Trigger |
|---|---|---|
SyncSquareJob | Full Square integration sync | Manual or scheduled |
SyncSquareMenuJob | Sync menu catalog to Square | Menu publish |
SyncSquareInventoryJob | Sync inventory to Square | Inventory changes |
SyncSquareLocationJob | Sync location data to Square | Location update |
SyncSquareIntegrationJob | Initialize Square integration | OAuth completion |
SyncLocationToDeliverooJob | Sync location data to Deliveroo | Location update |
ExportUpvendoMenuToShopifyJob | Export menu to Shopify | Manual trigger |
ImportShopifyMenuJob | Import menu from Shopify | Manual trigger |
UpdateUserUberLocationsJob | Update Uber Eats store locations | OAuth/config change |
Kassanet (POS Integration) Jobs
| Job | Purpose |
|---|---|
ImportKassanetMenuJob | Import full menu from Kassanet POS |
ImportKassanetCategoriesJob | Import categories from Kassanet |
ImportKassanetDisplayGroupsJob | Import display groups from Kassanet |
ImportKassanetProductsJob | Import products from Kassanet |
GetKassanetBillJob | Retrieve bill from Kassanet POS |
PayKassanetBillJob | Submit payment to Kassanet POS |
Uber Eats Jobs
Located in app/Jobs/UberEats/:
| Job | Purpose |
|---|---|
ProcessUberEatsOrderNotificationJob | Process incoming Uber Eats order |
ProcessUberEatsCancelNotificationJob | Handle Uber Eats order cancellation |
ProcessUberEatsScheduledNotificationJob | Handle scheduled order updates |
Image Processing Jobs
| Job | Purpose |
|---|---|
CompressImageJob | Compress uploaded images for storage optimization |
QR Code Generation Jobs
| Job | Purpose |
|---|---|
GenerateQrCodesForSection | Generate QR codes for a table section |
GenerateQrCodesForSectionBatch | Batch generate QR codes for section |
GenerateQrCodesConsolidation | Consolidate generated QR codes |
GenerateQrCodesConsolidationBatch | Batch consolidation of QR codes |
GenerateQrCodesFinalConsolidation | Final consolidation step |
Translation Jobs
| Job | Purpose |
|---|---|
RetranslatePublishedLanguagesJob | Re-translate all published language content |
Dispatch Patterns
Immediate Dispatch
Most jobs are dispatched immediately to the queue:
php
SendBackofficeOTPMail::dispatch($user, $otpCode);Delayed Dispatch
Used for scheduled orders:
php
ProcessOrderJob::dispatch($transactionId, $locationId)->delay($delayInSeconds);Synchronous Execution (Local Dev)
In local environment, some jobs execute synchronously for easier debugging:
php
if (app()->isLocal()) {
(new ProcessOrderJob($transactionId, $locationId))->handle();
return;
}Deferred Execution
Some operations use defer() to execute after the HTTP response is sent:
php
defer(function () use ($transaction) {
$this->publishPaymentStatus(...);
$this->processOrderJob($transaction);
});Queue Configuration
The queue driver and connection are configured via environment variables:
| Variable | Purpose |
|---|---|
QUEUE_CONNECTION | Queue driver (redis, database, sqs, sync) |
QUEUE_DEFAULT | Default queue name |
Queue Names
Jobs may be dispatched to specific queues for priority management. Check individual job classes for $queue property or onQueue() calls.
Job Structure Pattern
All jobs follow Laravel's standard structure:
php
class ExampleJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function __construct(
private string $someId,
private string $tenantDatabase
) {}
public function handle(): void
{
// Set tenant database if multi-tenant
config()->set('database.connections.tenant.database', $this->tenantDatabase);
// Execute job logic
// ...
}
}Multi-Tenant Considerations
Jobs that access tenant data must set the tenant database at the start of handle():
php
config()->set('database.connections.tenant.database', $this->tenantDatabase);The tenant database name is typically passed as a constructor parameter when dispatching:
php
UpdateD1StocksAfterPayment::dispatch(
$transaction,
config('database.connections.tenant.database')
);Error Handling and Retries
Default Behavior
Laravel's queue system provides automatic retry behavior. Failed jobs are stored in the failed_jobs table.
Manual Retry
bash
php artisan queue:retry {job_id}
php artisan queue:retry allMonitoring Failed Jobs
bash
php artisan queue:failedDebugging Jobs
Common Issues
- Job not executing: Check queue worker is running (
php artisan queue:work) - Tenant database error: Verify tenant database name is passed to job constructor
- Serialization error: Ensure job constructor parameters are serializable (use IDs, not models)
- Job timing: For delayed jobs, check
sent_atcalculation inPaymentCaptureService::processOrderJob()
Logging
Jobs typically log their execution. Search for job class name in logs:
grep "ProcessOrderJob" storage/logs/laravel.logRunning Jobs Synchronously
For debugging, set QUEUE_CONNECTION=sync in .env to execute all jobs synchronously.