Supplier Payout Lifecycle

Introduction

In the DJUST PAY marketplace model, supplier payouts are the mechanism by which funds collected from buyer payments are transferred to individual suppliers. The payout lifecycle covers two main phases: calculation (grouping eligible orders into payout amounts per supplier) and execution (verifying funds and triggering actual bank transfers via the PSP).

This guide explains how supplier payouts work end-to-end, from order eligibility to final settlement.


Key Concepts

Balance Accounts

Each merchant in DJUST PAY has isolated balance accounts managed by the underlying payment provider:

  • MARKETPLACE — holds collected funds before distribution
  • SUPPLIER — holds funds allocated to a specific supplier, from which payouts are issued to their bank account

Payout Statuses

StatusMeaning
COMPUTEDPayout calculated from eligible orders, awaiting execution
SKIPPEDPayout amount is zero — no transfer needed
PENDINGPayout execution triggered, awaiting PSP confirmation
SETTLEDPSP confirmed successful transfer to supplier bank account
FAILEDPSP reported a transfer failure; orders remain eligible for a future payout
INSUFFICIENT_FUNDSSupplier balance account does not have enough funds; no PSP call made

Typical Workflow

Step 1 — Calculate Payouts

For a given period, DJUST PAY identifies all eligible orders and groups them by supplier to create one payout per supplier.

Eligibility criteria:

  • Payment status: PAID
  • Logistic status: included in the tenant's configured list (allowedLogisticStatuses, retrievable via GET /v1/settings/payouts)
  • The order is not already associated with a payout in SETTLED or PENDING status

Calculation rules:

  • The payout amount corresponds to the net amount credited to the supplier balance account (captured amount minus marketplace commission, DJUST fees, and IC++ fees)
  • If an order has been partially refunded, the payout amount is adjusted to account for the refund. The order remains eligible for payout with the reduced net amount.
  • One payout is created per supplier at status COMPUTED
  • If the net amount is zero, the payout is created at status SKIPPED
  • The calculation is idempotent: re-running on the same period does not duplicate existing payouts

Step 2 — Execute Payouts

When a payout is ready (COMPUTED), DJUST PAY checks the supplier balance account:

  • Sufficient funds — a PSP payout is triggered from the supplier balance account to the supplier's bank account. Status transitions to PENDING.
  • Insufficient funds (marketplace banking mode DISABLED) — status transitions to INSUFFICIENT_FUNDS. No PSP call is made. The payout can be retried later.
  • Insufficient funds (marketplace banking mode ENABLED) — the marketplace balance account is used to advance the missing funds to the supplier balance account, and the payout proceeds. Status transitions to PENDING.
📘

Marketplace Banking Mode

The marketplaceBankingMode setting controls whether the marketplace balance account can advance funds to cover supplier payouts when the supplier's balance is insufficient. See Supplier Payout Configuration for details on how to enable or disable this option.

Step 3 — PSP Confirmation (Webhook)

Final confirmation is handled asynchronously via PSP webhooks:

  • Success — payout transitions to SETTLED. All associated orders are marked as paid out.
  • Failure — payout transitions to FAILED. Associated orders remain eligible for a future payout cycle.

Full traceability is maintained: attempt date, confirmation date, PSP identifier, and failure reason (if applicable).


Payout Flow

flowchart LR
  %% Styles (Readme)
  classDef create   fill:#e8f1ff,stroke:#2f6feb,stroke-width:2px,color:#0b3d91;
  classDef read     fill:#ede9fe,stroke:#7c3aed,stroke-width:2px,color:#1e1b4b;
  classDef update   fill:#e0f7fa,stroke:#06b6d4,stroke-width:2px,color:#0c4a6e;
  classDef add      fill:#ecfdf5,stroke:#10b981,stroke-width:2px,color:#064e3b;
  classDef remove   fill:#fee2e2,stroke:#ef4444,stroke-width:2px,color:#7f1d1d;
  classDef decision fill:#fff4e5,stroke:#f59e0b,stroke-width:2px,color:#7a3e00;
  classDef place    fill:#dcfce7,stroke:#16a34a,stroke-width:2px,color:#14532d;
  classDef sys      fill:#f2f4f7,stroke:#475569,stroke-width:2px,color:#111827;
  classDef ok       fill:#ecfdf5,stroke:#10b981,stroke-width:2px,color:#064e3b;
  classDef stop     fill:#fee2e2,stroke:#ef4444,stroke-width:2px,color:#7f1d1d;

  A["📘 Calculate payouts"]:::create
  B{{"💰 Amount > 0?"}}:::decision
  C["⏭️ SKIPPED"]:::sys
  D["✅ COMPUTED"]:::place
  E["🔄 Execute payout"]:::update
  F{{"💳 Funds sufficient?"}}:::decision
  G{{"🏦 Banking mode?"}}:::decision
  H["⚠️ INSUFFICIENT_FUNDS"]:::stop
  L["💰 Marketplace BA<br>advances funds"]:::add
  I["⏳ PENDING<br>PSP payout triggered"]:::update
  J{{"📩 Webhook result"}}:::decision
  K["✅ SETTLED<br>Orders marked paid out"]:::place
  M["❌ FAILED<br>Orders remain eligible"]:::stop

  A --> B
  B -->|No| C
  B -->|Yes| D --> E --> F
  F -->|Yes| I
  F -->|No| G
  G -->|DISABLED| H
  G -->|ENABLED| L --> I
  I --> J
  J -->|Success| K
  J -->|Failure| M

  style A rx:8,ry:8
  style C rx:8,ry:8
  style D rx:8,ry:8
  style E rx:8,ry:8
  style H rx:8,ry:8
  style L rx:8,ry:8
  style I rx:8,ry:8
  style K rx:8,ry:8
  style M rx:8,ry:8

Sequence Diagram

sequenceDiagram
    participant Operator
    participant DJUST PAY
    participant PSP

    Note over Operator,PSP: Step 1 - Calculate payouts
    Operator->>DJUST PAY: Trigger payout calculation
    DJUST PAY->>DJUST PAY: Identify eligible orders per supplier
    DJUST PAY->>DJUST PAY: Compute net amounts (captured - commissions - fees)
    DJUST PAY-->>Operator: Payouts created (COMPUTED / SKIPPED)

    Note over Operator,PSP: Step 2 - Execute payouts
    Operator->>DJUST PAY: Trigger payout execution
    DJUST PAY->>DJUST PAY: Check supplier BA balance
    alt Sufficient funds
        DJUST PAY->>PSP: Trigger payout from supplier BA
        DJUST PAY-->>Operator: Payout status = PENDING
        PSP-->>DJUST PAY: Webhook: payout confirmed
        DJUST PAY->>DJUST PAY: Status = SETTLED, orders marked as paid out
    else Insufficient funds & banking mode ENABLED
        DJUST PAY->>PSP: Advance funds from marketplace BA
        DJUST PAY->>PSP: Trigger payout from supplier BA
        DJUST PAY-->>Operator: Payout status = PENDING
        PSP-->>DJUST PAY: Webhook: payout confirmed
        DJUST PAY->>DJUST PAY: Status = SETTLED
    else Insufficient funds & banking mode DISABLED
        DJUST PAY-->>Operator: Payout status = INSUFFICIENT_FUNDS
    end

Configuration

Eligible logistic statuses for payout calculation are configurable at tenant level:

GET /v1/settings/payouts
dj-client: OPERATOR
dj-api-key: {{apiKey}}

This returns the list of allowedLogisticStatuses that qualify orders for supplier payouts.


Best Practices

  1. Configure eligible statuses carefully — only include logistic statuses that indicate the order has been fulfilled (e.g., SHIPPED, DELIVERED). Including early statuses may trigger payouts before goods are dispatched.
  2. Run calculations before execution — always compute payouts first, review the results, then execute.
  3. Monitor INSUFFICIENT_FUNDS — this status means the supplier balance account needs to be funded (e.g., via marketplace-to-supplier funding transfer) before the payout can succeed.
  4. Leverage idempotency — re-running payout calculation on the same period is safe and will not create duplicate payouts.
  5. Track via PSP identifiers — each executed payout carries a PSP reference for reconciliation with your payment provider's dashboard.

Common Mistakes

MistakeConsequenceHow to avoid
Executing payouts without prior calculationNo COMPUTED payouts exist to executeAlways run the calculation step before the execution step
Not checking INSUFFICIENT_FUNDS payoutsSupplier payouts remain stuck, never reaching the bankMonitor payout statuses and fund supplier BAs as needed, or enable marketplaceBankingMode to allow the marketplace BA to advance funds
Including too-early logistic statuses in configPayouts triggered before fulfillmentOnly include post-fulfillment statuses in allowedLogisticStatuses
Expecting instant settlementPayout stays PENDING until PSP confirmsSettlement is asynchronous — monitor via webhooks or status polling

Error Reference

For the complete list of DJUST error and warning codes, refer to the dedicated page: Error / Warning codes


Related Documentation