Appearance
Maker-Checker Approval Workflow
The Maker-Checker system (also called the 4-eyes principle) requires that certain operations are submitted by one user (the maker) and approved by a different user (the checker) before they take effect. This is a standard internal control requirement for regulated financial institutions.
How It Works
- A maker initiates an action - for example, approving a loan
- Instead of executing immediately, the action is placed in a pending queue
- A checker (a different user with the appropriate permission) reviews the pending action
- The checker approves or rejects it
- On approval, the action executes; on rejection, it is discarded and the maker is notified
The maker and checker must be different users. A user cannot approve their own submissions.
Enabling Maker-Checker Globally
Maker-Checker must first be enabled at the system level via the Global Configuration API:
bash
PUT /fineract-provider/api/v1/configurations/{configId}
Authorization: Basic <base64>
Fineract-Platform-TenantId: default
Content-Type: application/jsonjson
{
"enabled": true
}Find the Maker-Checker configuration ID first:
bash
GET /fineract-provider/api/v1/configurationsLook for the entry with "name": "maker-checker" and use its id.
Disabled by default
Maker-Checker is disabled on a fresh Fineract installation. Enabling it immediately affects all task types that have been configured to require approval.
Configuring Which Tasks Require Approval
Not all operations need to go through maker-checker. Configure it per task type:
bash
GET /fineract-provider/api/v1/makercheckersThis returns all auditable task types with their current makerCheckerTask flag. To require approval for a specific task:
bash
PUT /fineract-provider/api/v1/makercheckers/{taskId}json
{
"makerCheckerTask": true
}Commonly configured task types
| Task | Recommended for maker-checker |
|---|---|
| Loan application submission | Optional |
| Loan approval | Yes - regulated environments |
| Loan disbursement | Yes - high value |
| Loan write-off | Yes - irreversible |
| Savings withdrawal | Yes - above threshold |
| Journal entry posting | Yes - accounting integrity |
| User creation | Optional |
| Role/permission changes | Yes |
| Client creation | Optional |
| Charge waiver | Yes |
Roles and Permissions
Two distinct permissions control maker-checker participation:
| Permission | Code | Who needs it |
|---|---|---|
| Submit (maker) | Standard operation permission (e.g. APPROVE_LOAN) | Anyone submitting actions for approval |
| Approve/reject (checker) | CHECKER_SUPER_USER or task-specific checker permission | Checkers only |
A user with APPROVE_LOAN but without checker permission can submit loan approvals for review. A user with checker permission can approve or reject them.
Typically:
- Loan officers have maker permissions - they submit actions
- Branch managers or supervisors have checker permissions - they approve
- Super users have both (but should not approve their own actions)
The Checker Inbox
Pending maker-checker items accumulate in the Checker Inbox. Query it via:
bash
GET /fineract-provider/api/v1/audits?processingResult=2processingResult=2 returns items in awaiting approval state.
Each item includes:
json
{
"id": 1234,
"actionName": "APPROVE",
"entityName": "LOAN",
"resourceId": 567,
"maker": "loan.officer",
"madeOnDate": "2025-03-01T10:30:00Z",
"processingResult": "Awaiting Approval"
}Approving a Pending Action
bash
POST /fineract-provider/api/v1/audits/{auditId}?command=approveNo request body required. The original action executes immediately upon approval.
Rejecting a Pending Action
bash
POST /fineract-provider/api/v1/audits/{auditId}?command=rejectThe pending action is discarded. The maker will see the rejection when they query their submission history.
Bulk Approval
For high-volume environments, checkers can approve multiple items at once. Retrieve all pending items, filter for the desired subset, and approve each:
bash
# Get all pending loan approvals
GET /fineract-provider/api/v1/audits?processingResult=2&entityName=LOAN&actionName=APPROVE
# Approve each
POST /fineract-provider/api/v1/audits/{auditId1}?command=approve
POST /fineract-provider/api/v1/audits/{auditId2}?command=approveViewing the Audit Trail
All maker-checker submissions - approved, rejected, and pending - are retained in the audit log:
bash
# All audit entries for a specific loan
GET /fineract-provider/api/v1/audits?entityName=LOAN&resourceId={loanId}
# All actions by a specific user
GET /fineract-provider/api/v1/audits?makerId={userId}
# All actions approved by a checker
GET /fineract-provider/api/v1/audits?checkerId={userId}The audit log is permanent - entries cannot be deleted - which is important for regulatory compliance.
Processing Result Codes
| Code | Meaning |
|---|---|
1 | Approved |
2 | Awaiting approval |
3 | Rejected |
4 | Error during execution |
Maker-Checker and API Integrations
When maker-checker is enabled for a task type, API calls that trigger that task will return a 200 OK with a response indicating the action is pending rather than executed:
json
{
"officeId": 1,
"clientId": 45,
"loanId": 123,
"resourceId": 1234,
"subResourceId": null
}The resourceId here is the audit entry ID, not the loan ID. Your integration must detect this and either:
- Poll
GET /fineract-provider/api/v1/audits/{resourceId}untilprocessingResultchanges from2 - Or notify a human checker to review the inbox
Integration impact
Enabling maker-checker on operations that your integration calls synchronously will break the synchronous flow - the operation will not have executed when the API returns. Always test integrations against a maker-checker enabled environment before production.
Disabling Maker-Checker for Specific Environments
For development or testing environments where the approval loop is not needed:
bash
PUT /fineract-provider/api/v1/configurations/{makercheckerConfigId}json
{
"enabled": false
}Or disable it per task type to leave global maker-checker on but skip it for low-risk operations.