Skip to content

Takaful

The Takaful module handles Shariah-compliant mutual insurance: users contribute periodically to a pool, then may submit a claim when certain events occur (death, critical illness, disability, natural disaster). The TakafulController at /takaful combines two primary resources: contributions (CRUD + list) and claims (submit, list, admin review, payout, and pool stats). Review/payout are restricted to @Roles(UserType.MORIA).

PropertyValue
Base URL{HOST}/v1
AuthBearer JWT (header Authorization) or cookie access_token
Content-Typeapplication/json
Error envelope{ "message": string | string[], "statusCode": number, "error": string }
ValidationGlobal ValidationPipe · whitelist: true, forbidNonWhitelisted: true · unknown field → 400
Related modulespools, users, organizations, payments
Document versionv1 · 2026-05-20
AudienceInternal FE devs (mobile + web)

An INDIVIDUAL user creates a contribution via POST /takaful/contributions and can list / view detail of their own. When an incident occurs, the user submits a claim via POST /takaful/claims with a reason category. MORIA admin reviews (approve/reject) via PATCH /takaful/claims/:id/review; after approval, payout is disbursed via POST /takaful/claims/:id/payout. Pool stats are available to admins at GET /takaful/pools/:pool_id/stats.

MethodPathAuthSummary
GET/v1/takaful/contributionsbearerList contributions (own or by organization)
GET/v1/takaful/contributions/:idbearerContribution detail
POST/v1/takaful/contributionsbearerCreate new contribution
GET/v1/takaful/claimsbearerList claims (own or by org)
GET/v1/takaful/claims/:idbearerClaim detail
POST/v1/takaful/claimsbearerSubmit new claim
PATCH/v1/takaful/claims/:id/reviewbearerMORIA admin reviews claim (approve/reject)
POST/v1/takaful/claims/:id/payoutbearerMORIA admin processes payout
GET/v1/takaful/pools/:pool_id/statsbearerMORIA admin: pool statistics

GET /v1/takaful/contributions bearer

Section titled “GET /v1/takaful/contributions ”

List takaful contributions. INDIVIDUAL is automatically scoped to their own; ORGANIZATION/MORIA admins use the organization_id query to filter to a specific org.

bearer read-takaful RESOURCE_FETCHED
ParamTypeDefaultNotes
organization_idUUIDoptionalFilter by org (for admins); ignored if caller is INDIVIDUAL
{
"status": "success",
"statusCode": 200,
"message": "Takaful contributions retrieved successfully",
"data": {
"contributions": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"user_id": "770e8400-e29b-41d4-a716-446655440222",
"pool_id": "660e8400-e29b-41d4-a716-446655440111",
"amount": "500.0000",
"period_start": "2026-02-01",
"period_end": "2026-03-01",
"payment_ref": "PAY-20260201-001",
"status": "active",
"created_at": "2026-02-01T08:30:00.000Z"
}
]
}
}
StatusWhen it occurs
400 Bad RequestOrganization ID or query param invalid
401 UnauthorizedBearer/cookie token invalid
403 ForbiddenPermission insufficient

GET /v1/takaful/contributions/:id bearer

Section titled “GET /v1/takaful/contributions/:id ”

Detail of a single takaful contribution.

bearer read-takaful RESOURCE_FETCHED
ParamTypeNotes
idUUIDContribution ID — validated by ParseUUIDPipe
{
"status": "success",
"statusCode": 200,
"message": "Takaful contribution retrieved successfully",
"data": {
"contribution": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"user_id": "770e8400-e29b-41d4-a716-446655440222",
"pool_id": "660e8400-e29b-41d4-a716-446655440111",
"amount": "500.0000",
"period_start": "2026-02-01",
"period_end": "2026-03-01",
"payment_ref": "PAY-20260201-001",
"status": "active"
}
}
}
StatusWhen it occurs
400 Bad Requestid is not a UUID
401 UnauthorizedBearer/cookie token invalid
403 ForbiddenPermission insufficient
404 Not FoundContribution not found

POST /v1/takaful/contributions bearer

Section titled “POST /v1/takaful/contributions ”

Create a new takaful contribution to an organization’s pool. The contribution period is set explicitly via period_start / period_end.

bearer create-takaful CONTRIBUTION_MADE

Request body — CreateTakafulContributionDto

Section titled “Request body — CreateTakafulContributionDto”
FieldTypeRequiredNotes
organization_idUUIDyesTarget pool organization
amountnumeric stringyesContribution amount (IsNumberString)
period_startstring (YYYY-MM-DD)yesPeriod start date
period_endstring (YYYY-MM-DD)yesPeriod end date
payment_refstringoptionalPayment reference
{
"organization_id": "be2cb7da-e217-401c-8d07-b01e64adfb34",
"amount": "500.00",
"period_start": "2025-02-01",
"period_end": "2025-03-01",
"payment_ref": "PAY-20250201-001"
}
{
"status": "success",
"statusCode": 201,
"message": "Takaful contribution created successfully",
"data": { "contribution": { "...": "TakafulContributions shape" } }
}
StatusWhen it occurs
400 Bad RequestValidation failed (UUID/format)
401 UnauthorizedBearer/cookie token invalid
403 ForbiddenPermission insufficient
  • Emits BusinessEvent CONTRIBUTION_MADE (impact MEDIUM).
  • Balance is moved to the organization’s takaful pool.

List takaful claims. INDIVIDUAL is automatically scoped to their own claims; ORGANIZATION/MORIA admins use the orgId query (note: param name here is camelCase, differing from the contributions endpoint).

bearer read-takaful-claims RESOURCE_FETCHED
ParamTypeDefaultNotes
orgIdUUIDoptionalFilter by org (for admins); ignored if caller is INDIVIDUAL
{
"status": "success",
"statusCode": 200,
"message": "Takaful claims retrieved successfully",
"data": {
"claims": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"contribution_id": "660e8400-e29b-41d4-a716-446655440111",
"user_id": "770e8400-e29b-41d4-a716-446655440222",
"pool_id": "880e8400-e29b-41d4-a716-446655440333",
"claim_amount": "5000.0000",
"approved_amount": null,
"reason": "Medical emergency requiring treatment",
"claim_reason": "critical_illness",
"status": "submitted",
"reviewed_by": null,
"reviewed_at": null,
"created_at": "2026-02-15T10:00:00.000Z"
}
]
}
}
StatusWhen it occurs
400 Bad RequestorgId invalid
401 UnauthorizedBearer/cookie token invalid
403 ForbiddenPermission insufficient

GET /v1/takaful/claims/:id bearer

Section titled “GET /v1/takaful/claims/:id ”

Detail of a single takaful claim.

bearer read-takaful-claims RESOURCE_FETCHED
ParamTypeNotes
idUUIDClaim ID
{
"status": "success",
"statusCode": 200,
"message": "Takaful claim retrieved successfully",
"data": {
"claim": { "...": "TakafulClaims shape" }
}
}
StatusWhen it occurs
400 Bad Requestid is not a UUID
401 UnauthorizedBearer/cookie token invalid
403 ForbiddenPermission insufficient
404 Not FoundClaim not found

POST /v1/takaful/claims bearer

Section titled “POST /v1/takaful/claims ”

Submit a takaful claim against a contribution. Valid values for claim_reason: death, critical_illness, disability, natural_disaster.

bearer create-takaful-claims RESOURCE_CREATED
FieldTypeRequiredNotes
contribution_idUUIDyesContribution that the claim is based on
claim_amountnumeric stringyesRequested amount
reasonstringyesFree-text reason detail
claim_reasonenum TakafulClaimReasonyesdeath, critical_illness, disability, natural_disaster
{
"contribution_id": "be2cb7da-e217-401c-8d07-b01e64adfb34",
"claim_amount": "5000.00",
"reason": "Medical emergency requiring treatment",
"claim_reason": "critical_illness"
}
{
"status": "success",
"statusCode": 201,
"message": "Takaful claim submitted successfully",
"data": {
"claim": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"contribution_id": "be2cb7da-e217-401c-8d07-b01e64adfb34",
"claim_amount": "5000.0000",
"claim_reason": "critical_illness",
"status": "submitted"
}
}
}
StatusWhen it occurs
400 Bad RequestValidation failed (UUID/format/enum)
401 UnauthorizedBearer/cookie token invalid
403 ForbiddenPermission insufficient

PATCH /v1/takaful/claims/:id/review bearer

Section titled “PATCH /v1/takaful/claims/:id/review ”

MORIA admin reviews a claim: approve (with approved_amount) or reject. After approval, payout can be triggered via a separate endpoint.

bearer MORIA update-takaful-claims RESOURCE_UPDATED
ParamTypeNotes
idUUIDClaim ID
FieldTypeRequiredNotes
action'approve' | 'reject'yesReview action
approved_amountnumeric stringoptionalApproved amount (required when action=approve)
{
"action": "approve",
"approved_amount": "5000.00"
}
{
"status": "success",
"statusCode": 200,
"message": "Takaful claim reviewed successfully",
"data": {
"claim": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"status": "approved",
"approved_amount": "5000.0000",
"reviewed_by": "880e8400-e29b-41d4-a716-446655440444",
"reviewed_at": "2026-02-20T10:00:00.000Z"
}
}
}
StatusWhen it occurs
400 Bad RequestValidation failed · approved_amount missing on approve
401 UnauthorizedBearer/cookie token invalid
403 ForbiddenRole not MORIA
404 Not FoundClaim not found

POST /v1/takaful/claims/:id/payout bearer

Section titled “POST /v1/takaful/claims/:id/payout ”

MORIA admin processes payout for an approved claim. Funds are moved from the takaful pool to the recipient account and the claim status changes to paid.

bearer MORIA payout-takaful-claims WITHDRAWAL_PROCESSED
ParamTypeNotes
idUUIDClaim ID
{
"status": "success",
"statusCode": 200,
"message": "Takaful payout processed successfully",
"data": {
"payout": { "amount": "500.00", "reference": "PAYOUT-20250201-001" }
}
}
StatusWhen it occurs
400 Bad RequestInvalid payout (claim not approved, etc.)
401 UnauthorizedBearer/cookie token invalid
403 ForbiddenRole not MORIA
404 Not FoundClaim not found
  • Claim status → paid.
  • Takaful pool balance is reduced by approved_amount.
  • Emits BusinessEvent WITHDRAWAL_PROCESSED (impact CRITICAL).

GET /v1/takaful/pools/:pool_id/stats bearer

Section titled “GET /v1/takaful/pools/:pool_id/stats ”

MORIA admin: takaful pool statistics — total contributions, total claims, total payouts, and other metrics.

bearer MORIA read-takaful-claims RESOURCE_FETCHED
ParamTypeNotes
pool_idUUIDTakaful pool ID
{
"status": "success",
"statusCode": 200,
"message": "Takaful pool statistics retrieved successfully",
"data": {
"stats": {
"total_contributions": "10000.00",
"total_claims": 5,
"total_payouts": "2500.00"
}
}
}
StatusWhen it occurs
400 Bad Requestpool_id is not a UUID
401 UnauthorizedBearer/cookie token invalid
403 ForbiddenRole not MORIA
404 Not FoundPool not found

  • active — contribution active within the period
  • expired — period has elapsed
  • cancelled — cancelled
  • submitted — claim newly submitted
  • under_review — admin is reviewing
  • approved — claim approved, awaiting payout
  • rejected — claim rejected
  • paid — payout executed
  • death — participant death
  • critical_illness — critical illness
  • disability — disability
  • natural_disaster — natural disaster
{
"message": "Claim not found",
"statusCode": 404,
"error": "Not Found"
}

message may be a string or array of strings (multi-field validation errors).

  • 400 body/query/param validation
  • 401 token expired / missing
  • 403 permission insufficient · role not MORIA
  • 404 contribution/claim/pool not found
  • 500 internal — show a generic toast
  • List contributions: ?organization_id=<uuid>
  • List claims: ?orgId=<uuid> (camelCase, different)