Refunds
Introduction
DJUST PAY supports refunding payments on orders — either fully or partially. This page explains how refunds work, how they are funded, their impact on commissions and supplier payouts, and how to retrieve the refund history of a logistic order.
Key Concepts
Full Refund
A full refund reimburses the entire order amount to the buyer. The payment status of the order transitions to REFUNDED.
Partial Refund
A partial refund reimburses a specific amount (less than the order total) to the buyer. Multiple partial refunds can be issued on the same order, up to the total order amount. The payment status of the order reflects the partial refund state until the full amount is refunded.
Refund Funding
Refunds are funded from the supplier balance account. If the supplier's balance is insufficient, the configured funding policy at the tenant level determines whether the marketplace balance account can cover the difference.
This mechanism is identical for both full and partial refunds.
Refund Reason
When initiating a refund, an optional reasonCode can be provided to record why the refund was requested (e.g. CUSTOMER_REQUEST, ORDER_ERROR). The reason is persisted for both full and partial refunds and is returned in the refund history.
Refund History
Every refund requested on a logistic order — whether it succeeded or failed — is recorded and can be retrieved through a dedicated endpoint, with its amount, reason, mode, status, dates and PSP reference. A failed refund does not prevent a new refund from being requested on the same logistic order.
Typical Workflow
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["📘 Operator triggers refund<br>POST /v1/logistic-orders/id/refunds"]:::create
B{{"💰 Amount specified?"}}:::decision
C["🔄 Partial refund<br>Specified amount"]:::update
D["🔄 Full refund<br>Total order amount"]:::update
E{{"💳 Supplier BA<br>sufficient?"}}:::decision
F["✅ Funded from<br>supplier BA"]:::place
G{{"🏦 Marketplace<br>funding policy?"}}:::decision
H["💰 Marketplace BA<br>covers difference"]:::add
I["⚠️ Refund blocked<br>Insufficient funds"]:::stop
J["✅ Refund processed<br>Commission recalculated"]:::place
A --> B
B -->|Yes| C
B -->|No| D
C --> E
D --> E
E -->|Yes| F --> J
E -->|No| G
G -->|Enabled| H --> J
G -->|Disabled| I
style A rx:8,ry:8
style C rx:8,ry:8
style D rx:8,ry:8
style F rx:8,ry:8
style H rx:8,ry:8
style I rx:8,ry:8
style J rx:8,ry:8
API Reference
Initiate a refund
Endpoint: POST /v1/logistic-orders/{logisticOrderId}/refunds — operationId: ADM-ORDER-100
| Header | Required | Description |
|---|---|---|
dj-client | Yes | OPERATOR |
dj-api-key | Yes | API key |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
amount | number | No | Gross amount to refund. If omitted, a full refund is performed. |
reasonCode | string | No | Reason for the refund (e.g. CUSTOMER_REQUEST). Persisted for both full and partial refunds, and returned in the refund history. |
Partial refund example
{
"amount": 25.50,
"reasonCode": "CUSTOMER_REQUEST"
}Full refund example
{}
Tip: ThereasonCodeis optional in every mode — a refund without a reason works exactly as before. Providing one makes the refund history much easier to exploit.
Response
200 OK— refund successfully initiated.
List the refunds of a logistic order
Endpoint: GET /v1/logistic-orders/{logisticOrderId}/refunds — operationId: ADM-ORDER-553
Returns the paginated refund history of a logistic order, with one entry per refund requested on it. An order refunded several times returns several entries; an order that has never been refunded returns an empty list.
| Header | Required | Description |
|---|---|---|
dj-client | Yes | OPERATOR |
dj-api-key | Yes | API key |
Query parameters
| Parameter | Required | Description |
|---|---|---|
idType | No | DJUST_ID (default): logisticOrderId is the DJUST business ID. EXTERNAL_ID: it is an external ID. |
page | No | Page number (0-based). Default: 0 |
size | No | Items per page. Default: 20, min 1, max 100 |
sort | No | Format property:(asc|desc). Sortable property: createdAt. Default: createdAt:desc |
Refund entry fields
| Field | Description |
|---|---|
refundId | Identifier of the refund |
createdAt | When the refund was requested |
executedAt | When the refund was processed |
amount / currency | Refunded amount and currency |
reasonCode | Reason supplied when the refund was requested (if any) |
refundMode | Refund mode (e.g. FREE_AMOUNT for a partial refund by amount) |
status | Current status of this individual refund (see below) |
pspReference | Reference of the refund at the payment provider |
failureReason | Reason of the failure, for refunds ending in FAILED or INSUFFICIENT_FUNDS |
Refund statuses
| Status | Meaning |
|---|---|
CREATED / PENDING | Transient — the refund is being processed by the payment provider. Overwritten by the final status once processing completes. |
REFUNDED | The refund was successfully processed. |
FAILED | The refund failed — see failureReason. |
INSUFFICIENT_FUNDS | The refund could not be funded — see failureReason. |
Note: A refund that ends inFAILEDorINSUFFICIENT_FUNDSdoes not prevent a new refund from being requested on the same logistic order.
Example response
{
"content": [
{
"refundId": "d1eebc99-9c0b-4ef8-bb6d-6bb9bd380a02",
"createdAt": "2026-04-02T10:00:00Z",
"executedAt": "2026-04-02T10:05:00Z",
"amount": 20.0,
"currency": "EUR",
"reasonCode": "ORDER_ERROR",
"refundMode": "FREE_AMOUNT",
"status": "FAILED",
"pspReference": "MT8G4LN6FBKGK6R3",
"failureReason": "Refund webhook returned success=false"
},
{
"refundId": "d1eebc99-9c0b-4ef8-bb6d-6bb9bd380a01",
"createdAt": "2026-04-01T10:00:00Z",
"executedAt": "2026-04-01T10:05:00Z",
"amount": 30.0,
"currency": "EUR",
"reasonCode": "CUSTOMER_REQUEST",
"refundMode": "FREE_AMOUNT",
"status": "REFUNDED",
"pspReference": "MT8G4LN6FBKGK6R2",
"failureReason": null
}
],
"empty": false,
"first": true,
"last": true,
"number": 0,
"numberOfElements": 2,
"size": 20,
"sort": ["createdAt:desc"]
}Errors
400— invalid pagination parameters (F-E-008ifsizeis less than 1,F-E-010ifsizeexceeds 100).404— the logistic order does not exist.
Business Rules
| Rule | Description |
|---|---|
| Partial refund | The amount field specifies the refund amount. Multiple partial refunds can be issued on the same order. |
| Cumulative limit | The total of all partial refunds cannot exceed the original order amount. |
| Commission adjustment | The marketplace commission is recalculated proportionally to the refunded amount. |
| Funding source | Refunds are funded from the supplier balance account. If insufficient, the marketplace balance account may cover the difference based on the tenant's funding policy. |
| Payout impact | A partially refunded order remains eligible for supplier payout, with the payout amount adjusted to account for the refund. |
| Reason persistence | The optional reasonCode supplied at initiation is persisted for both full and partial refunds, and returned in the refund history. |
| Failed refunds | A refund ending in FAILED or INSUFFICIENT_FUNDS is kept in the history with its failureReason, and does not prevent a new refund on the same logistic order. |
Sequence Diagram
sequenceDiagram
participant Operator
participant DJUST PAY
participant PSP
Operator->>DJUST PAY: POST /v1/logistic-orders/{logisticOrderId}/refunds (dj-client: OPERATOR)
DJUST PAY->>DJUST PAY: Validate refund amount against order total
DJUST PAY->>DJUST PAY: Check supplier BA balance
alt Sufficient funds in supplier BA
DJUST PAY->>PSP: Trigger refund from supplier BA
else Insufficient funds and marketplace funding enabled
DJUST PAY->>PSP: Transfer from marketplace BA to supplier BA
DJUST PAY->>PSP: Trigger refund from supplier BA
end
PSP-->>DJUST PAY: Webhook: refund confirmed
DJUST PAY->>DJUST PAY: Update payment status and recalculate commission
DJUST PAY-->>Operator: 200 OK
Best Practices
- Start with partial refunds — if the buyer only needs a partial reimbursement, use the
amountfield to avoid refunding the full order. - Check the order's refund history — before issuing a new partial refund, retrieve the refunds already requested with
GET /v1/logistic-orders/{logisticOrderId}/refunds(ADM-ORDER-553) and verify the cumulative amount already refunded to avoid exceeding the order total. - Monitor funding policy — if your marketplace funding policy is disabled, ensure supplier balance accounts are adequately funded before triggering refunds.
- Commission tracking — after a partial refund, the marketplace commission is proportionally reduced. Monitor your commission reports accordingly.
- Always provide a
reasonCode— the reason is persisted on both full and partial refunds and returned in the refund history, making audits and customer support much easier. - Do not treat
CREATED/PENDINGas final — these statuses are transient. Poll the refund history until the refund reachesREFUNDED,FAILEDorINSUFFICIENT_FUNDS.
Common Mistakes
| Mistake | Consequence | How to avoid |
|---|---|---|
Omitting amount when intending a partial refund | A full refund is performed instead | Always specify amount for partial refunds |
| Issuing partial refunds exceeding the order total | The API rejects the request | Track cumulative refunded amounts per order |
| Not checking supplier BA balance before refunding | Refund may fail if marketplace funding is disabled | Enable marketplace funding policy or ensure supplier BAs are funded |
Error Reference
For the complete list of DJUST error and warning codes, refer to the dedicated page:
Error / Warning codes
Related Documentation
- Introduction to Djust Pay
- Managing Card Payments
- Supplier Payout Lifecycle
- Supplier Payout Configuration
Updated 23 days ago

