Getting started with Refunds
The Refunds feature enables businesses to automate and simplify the process of issuing customer refunds. Built on Lean’s existing payout infrastructure, it allows clients to initiate refunds seamlessly. The feature automatically identifies the connected Payout account and processes a reverse transaction, refunding the payment directly to its original source
Getting access to Refunds
To use the refunds feature, you need to have access to the following services:
- Payments: Refunds reverse customer payments processed through Lean Payments. The refunds are hence processed directly to the bank account connected with Lean while making the payment.
- Reconciliation: Refunds are only allowed for payments that have been successfully reconciled, ensuring funds that are received in your bank account are only refunded.
- Payouts:This enables Lean to process the refund by transferring the amount back to the customer's original payment source from the connected business account.
Ensure these features are enabled to streamline the refund process efficiently.
How does Refunds work ?
Lean's Refunds API allows you to initiate and manage refunds for payments processed through the Lean platform. The system supports:
- Full and partial refunds for reconciled payments
- Refunds to the source bank account
- Status tracking through the complete refund lifecycle
- Reason code management for refund categorization
Creating Refunds from the Lean Application Dashboard
- Navigate to the Payments tab and locate the payment you wish to refund.
- Ensure the payment is reconciled, as refunds cannot be initiated for unreconciled payments. Click the three-dot menu and select "Refund".
Refunds are only available for transactions that have been reconciled. This ensures users cannot initiate refunds for payments that have not yet settled in the bank.

- Enter the required details, such as the refund reason, transaction reference, and refund amount, then click "Initiate Refund".
- Click "Refund" to process the refund, triggering a payout back to the original payment source.

- Once the refund is confirmed , you can track the status of the refund transaction on the same screen. For more details on status please refer to Refunds lifecycle

The status of the queued refund can be tracked real-time on the same pageDetails of payment status can be found in Refunds Lifecycle
Creating Refunds via Lean APIs
Lean provides an API-driven solution that enables clients to process refunds programmatically. This automated workflow allows clients to seamlessly integrate their refund process with Lean, ensuring efficient and streamlined refund management.
1. Create a Refund
Initiate a new refund via API : POST /payouts/refunds
Request Body:
[
{
"payment_id": "uuid",
"amount": 100.00,
"currency": "AED",
"reason_code": "CUSTOMER_REQUEST",
"description": "Customer requested refund",
"external_reference": "REF123",
"beneficiary": {
"name": "John Doe",
"iban": "AE123456789",
"city": "Dubai"
}
}
]
The “payment_id” in the refund request corresponds to the payment against which the refund is being initiated
For more , details please refer to the API reference doc
Reason code is a mandatory field in this request .This can be fetched from the Get Refund Reasons API as explained below.
To enter the reason code in the Create Refund Request, retrieve the reason codes from GET refunds reason endpoint
Get Refund Reasons
Retrieve available reason codes for refunds: GET /payouts/refunds/reasons
Example Response:
[
{
"code": "CUSTOMER_REQUEST",
"description": "Requested by the client"
},
{
"code": "DUPLICATED_PAYMENT",
"description": "Duplicated Payment"
},
{
"code": "ORDER_CANCELLED",
"description": "Service/Order Cancellation"
},
{
"code": "FRAUDULENT_PAYMENT",
"description": "Fraudulent Payment"
}
]
2. Update Refund Status
Once the refund is created, update the status of a refund to "CONFIRMED" or "REJECTED"
PUT /payouts/refunds
Request Body:
[
{
"refund_id": "uuid",
"status": "CONFIRMED"
}
]
After the Authorization you will receive web-hooks of type payment.updated showing the status of the payment along with the payment information.
This webhook is triggered when there is an update to the status of a payment
{
"payload": {
"id": "e4e672fb-7f3c-43ea-be31-84195a65d0d7",
"amount": 670,
"status": "ACCEPTED_BY_BANK",
"currency": "AED",
"intent_id": "17e030df-91a9-4463-964c-6656605d5bcf",
"customer_id": "8ad2437d-2815-4b5c-82fd-543d85567668",
"end_user_id": "85fb7de7-3e67-4e97-a2c1-13de419d003e",
"post_initiation_status": "REJECTED",
"bank_transaction_reference": "44778733"
},
"type": "payment.updated",
"message": "A payment object has been updated.",
"timestamp": "2022-10-07T10:32:39.691593783Z",
"event_id": "cce42859-055b-4271-b4c0-b94d54a3b894"
}
Please note that thestatus
field in the payload refers to the payment initiation status which may not be the final status of the payment.To determine the final status of the payment, you should refer to
post_initiation_status
field. This field reflects whether it was successfully processed or rejected after initiation.
Refund Lifecycle
- CREATED – The refund request has been initiated. At this stage, it is pending approval and has not been sent to the bank.
- APPROVED – The refund has been approved by the designated approver.
- REJECTED – The refund has been rejected by the approver.
- ACCEPTED_BY_BANK – The bank has acknowledged receipt of the refund request and is accepted for processing
- PENDING_WITH_BANK – The refund is currently being processed by the bank.
- FAILED – The refund processing failed at the bank’s end.
Best Practices
- Include meaningful descriptions and external references for better tracking
- Store the refund_id returned from the creation API for future reference
- Handle all possible status codes in your integration
Updated 24 days ago