Automatic order transfer to dropshipping supplier

Our company is engaged in the development, support and maintenance of sites of any complexity. From simple one-page sites to large-scale cluster systems built on micro services. Experience of developers is confirmed by certificates from vendors.
Development and maintenance of all types of websites:
Informational websites or web applications
Business card websites, landing pages, corporate websites, online catalogs, quizzes, promo websites, blogs, news resources, informational portals, forums, aggregators
E-commerce websites or web applications
Online stores, B2B portals, marketplaces, online exchanges, cashback websites, exchanges, dropshipping platforms, product parsers
Business process management web applications
CRM systems, ERP systems, corporate portals, production management systems, information parsers
Electronic service websites or web applications
Classified ads platforms, online schools, online cinemas, website builders, portals for electronic services, video hosting platforms, thematic portals

These are just some of the technical types of websites we work with, and each of them can have its own specific features and functionality, as well as be customized to meet the specific needs and goals of the client.

Showing 1 of 1 servicesAll 2065 services
Automatic order transfer to dropshipping supplier
Medium
~3-5 business days
FAQ
Our competencies:
Development stages
Latest works
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1161
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1041
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    822
  • image_crm_chasseurs_493_0.webp
    CRM development for Chasseurs
    847
  • image_website-sbh_0.png
    Website development for SBH Partners
    999
  • image_website-_0.png
    Website development for Red Pear
    451

Implementation of Automatic Order Transfer to Dropshipping Supplier

Manual order sending to suppliers by email is a source of errors and delays. Automating transfer reduces order processing time from hours to seconds and eliminates human error. Task: after payment confirmation, order must go to supplier without manager involvement.

Transfer Trigger

Order is sent to supplier strictly after payment confirmation — not after order placement. This is critical: placing without payment creates false requests from the supplier.

// Listener on payment event
class DispatchOrderToSupplierListener
{
    public function __construct(
        private readonly DropshippingKernel $kernel,
    ) {}

    public function handle(PaymentConfirmedEvent $event): void
    {
        $order = $event->order;

        // Only dropshipping items
        $dropshipItems = $order->items->filter(
            fn($item) => $item->product->dropshipProduct !== null
        );

        if ($dropshipItems->isEmpty()) {
            return;
        }

        // Group by supplier and dispatch separate tasks
        $dropshipItems
            ->groupBy(fn($item) => $item->product->dropshipProduct->supplier_id)
            ->each(function ($items, $supplierId) use ($order) {
                DispatchOrderToSupplierJob::dispatch($order, $supplierId, $items)
                    ->onQueue('supplier-orders');
            });
    }
}

Order Transfer Job

class DispatchOrderToSupplierJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public $tries = 5;
    public $backoff = [30, 60, 120, 300, 600];
    public $timeout = 60;

    public function __construct(
        private readonly Order $order,
        private readonly int $supplierId,
        private readonly Collection $items,
    ) {}

    public function handle(SupplierConnectorFactory $factory): void
    {
        $supplier  = Supplier::findOrFail($this->supplierId);
        $connector = $factory->make($supplier);

        $dto = new SupplierOrderDTO(
            orderId:        $this->order->id,
            externalRef:    $this->order->number, // order number in store
            recipientName:  $this->order->delivery_name,
            phone:          $this->order->delivery_phone,
            deliveryAddress: $this->order->deliveryAddress->formatted(),
            deliveryMethod: $this->order->delivery_method,
            comment:        $this->order->comment,
            items: $this->items->map(fn($item) => new SupplierOrderItemDTO(
                supplierSku: $item->product->dropshipProduct->supplier_sku,
                quantity:    $item->quantity,
            )),
        );

        $result = $connector->placeOrder($dto);

        // Save supplier order ID
        SupplierOrder::create([
            'order_id'          => $this->order->id,
            'supplier_id'       => $this->supplierId,
            'supplier_order_id' => $result->supplierOrderId,
            'status'            => $result->status,
            'placed_at'         => now(),
        ]);

        // Update item status
        $this->items->each(fn($item) => $item->update([
            'supplier_status' => 'dispatched',
            'dispatched_at'   => now(),
        ]));

        Log::info('Order dispatched to supplier', [
            'order_id'    => $this->order->id,
            'supplier_id' => $this->supplierId,
            'supplier_order_id' => $result->supplierOrderId,
        ]);
    }

    public function failed(Throwable $e): void
    {
        // After exhausting attempts — notify manager for manual processing
        $this->order->update(['requires_manual_dispatch' => true]);

        Notification::route('mail', config('dropshipping.manager_email'))
            ->notify(new SupplierDispatchFailedNotification(
                $this->order,
                $this->supplierId,
                $e->getMessage()
            ));
    }
}

Order Transfer Formats

REST API — preferred format. POST request with JSON body.

Email with fixed format — supplier accepts orders via email in a specific template. Sent via Laravel Mailable.

Telegram bot — some small suppliers accept orders through Telegram. Integration via Telegram Bot API.

Supplier portal — form on supplier's website. As a last resort automated through Playwright/Puppeteer (headless browser automation).

// Example: sending order via email template
class SupplierOrderEmailConnector implements SupplierConnectorInterface
{
    public function placeOrder(SupplierOrderDTO $dto): SupplierOrderResult
    {
        Mail::to($this->supplier->credentials['order_email'])
            ->send(new SupplierOrderMail($dto));

        // Email integration doesn't return ID — generate internal
        return new SupplierOrderResult(
            supplierOrderId: 'email-' . $dto->orderId . '-' . time(),
            status: 'sent',
        );
    }
}

Order Receipt Confirmation

After sending order, supplier must confirm receipt. Options:

  1. Webhook from supplier — supplier calls store endpoint when status changes
  2. Polling — store periodically queries supplier API for order status
  3. Email parsing — supplier's reply email is parsed via IMAP
// Polling statuses (runs every 30 minutes)
class PollSupplierOrderStatusJob implements ShouldQueue
{
    public function handle(): void
    {
        SupplierOrder::where('status', 'dispatched')
            ->where('placed_at', '>', now()->subDays(14))
            ->with('supplier')
            ->chunk(50, function ($supplierOrders) {
                foreach ($supplierOrders as $so) {
                    $connector = SupplierConnectorFactory::make($so->supplier);
                    $result    = $connector->getOrderStatus($so->supplier_order_id);

                    if ($result->status !== $so->status) {
                        $so->update(['status' => $result->status, 'tracking_number' => $result->tracking]);
                        event(new SupplierOrderStatusChangedEvent($so, $result));
                    }
                }
            });
    }
}

Supplier Error Handling

Supplier may reject order (out of stock, address error, temporary unavailability). Processing logic:

  • Product out of stock at supplier → automatically find alternative supplier (if configured) or notify manager
  • Authorization error → alert in Slack/Telegram, pause further sends
  • Network error → retry with backoff

Timeline

Automatic order transfer via REST API — 3–4 business days. Email integration — 1–2 business days. Polling statuses + customer notifications — another 2 days.