Skip to main content

Refunds & After-Sales Service (SAV)

What It Does

This workflow manages the full lifecycle of customer returns, refunds, and after-sales complaints. It coordinates between Logidav, payment providers (Stripe, Hipay, Payline), and the stock system to ensure that refunds are issued correctly, stock is re-credited when products are physically returned, and every action is audit-logged.

How It Connects

Trigger

SourceTypePurpose
Refund commandsCron-scheduledAutomated refund processing
Customer SAV Status APIAPI endpointProgrammatic access to return statuses
Manual actionAdmin back-officeAgent-initiated refund or SAV case

Components

ComponentFile PathRole
Refund entitysrc/AppBundle/Entity/Refund record linked to a sale
RefundLog entitysrc/AppBundle/Entity/Audit log for every refund action
SaleSav entitysrc/AppBundle/Entity/SAV case record tracking the return lifecycle
SaleSavComplaint entitysrc/AppBundle/Entity/Customer complaint linked to a sale
PaylineServicesrc/CoreBundle/Services/PaylineService.phpPayline payment reversals
StripeApisrc/CoreBundle/Api/StripeApi.phpStripe refund API integration
HipayApisrc/CoreBundle/Api/HipayApi.phpHipay refund API integration

Refund Lifecycle

Payment Provider Flows

:::info Stripe refunds Stripe refunds are issued via StripeApi using the original charge ID. The API supports both full and partial refunds. The refund is processed immediately and Stripe handles the settlement timeline with the customer's bank. :::

:::info Hipay refunds Hipay refunds use HipayApi to perform a transaction reversal on the original payment. The API requires the original transaction reference. Hipay settlement timelines vary by the customer's payment method. :::

:::info Payline refunds Payline refunds go through PaylineService, which also logs every transaction via PaylineTransactionLogService. Payline supports partial and full reversals. Transaction logs are critical for reconciliation with Payline statements. :::

SAV Complaint Flow

Side Effects

Database

  • Creates Refund record linked to the sale
  • Writes RefundLog entry for every refund action (amount, provider, timestamp, status)
  • Updates SaleSav status through its lifecycle
  • Creates SaleSavComplaint for customer complaints

Stock

  • Increments product quantity via ProductQtyLogService::productChangeLog(..., 'return') when a product is physically returned
  • Stock increment only happens for physical returns, not for refund-only scenarios

External Systems

  • Issues refund via the appropriate payment provider API (Stripe, Hipay, or Payline)
  • Updated stock propagates to marketplaces on the next sync cycle

Customer

  • Sends notification to the customer about refund status

Failure Modes

:::danger Partial refund failure If the payment provider API times out or returns an error during a partial refund, the refund may be recorded in Logidav but not actually processed by the provider. This creates a mismatch between Logidav's refund records and the payment provider's transaction history.

Recovery: Check RefundLog entries against the payment provider's dashboard. If the refund was not processed, either retry via the provider's API or issue a manual refund through the provider's back-office. :::

:::danger Double refund If the refund command processes the same sale concurrently (e.g., overlapping cron executions or simultaneous manual + automated processing), two refunds can be issued for the same order.

Mitigation: Check RefundLog for existing refund entries before processing. However, concurrent execution can bypass this check.

Recovery: Contact the payment provider to reverse the duplicate refund, or debit the customer's next order. :::

:::warning Payment amount mismatch If the refund amount does not match the original payment (due to currency conversion, partial refunds that exceed the original, or data corruption), the payment provider will reject the refund.

Recovery: Verify the original payment amount in the provider's dashboard, correct the refund amount in Logidav, and retry. :::

:::warning Stock not re-credited If a physical return is processed but the stock increment fails (e.g., EntityManager error), the product quantity will be lower than actual inventory. Check ProductQtyLogService logs to verify the return mutation was recorded. :::

Debugging Path

  1. Check Refund and RefundLog entries -- query the Refund entity for the sale and inspect all RefundLog entries to see what actions were taken and their outcomes.
  2. Verify payment provider transaction -- log into the provider dashboard (Stripe, Hipay, or Payline) and confirm whether the refund was actually processed.
  3. Check SaleSav status -- verify the SAV case lifecycle stage. A stuck case may indicate a failed refund or missing approval.
  4. Verify stock increment on return -- if the customer returned a product, check ProductQtyLogService for a return type mutation on the relevant product.
  5. Check PaylineTransactionLogService -- for Payline refunds, inspect the transaction log for detailed API responses and error codes.
  6. Compare amounts -- verify that the refund amount in Logidav matches the original payment amount in the provider's system.
CommandPurpose
Refund processing commandsAutomated refund batch processing
SAV status commandsSAV case status management
menzzo:v2:sales:updateMay trigger status changes that interact with SAV