Skip to content

Charitable Cause

The Charitable Cause module enables crowdfunding projects: organizations or individuals register a cause (funding target, regulations, benefit), assign managers, and receive donations. User-facing endpoints live in CharitableCauseController (/charitable-causes) for CRUD + assign manager. Admin endpoints live in CharitableCauseAdminController for summary, cause approval, and allocation of open donations (donations without a specific cause) to ACTIVE causes.

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 modulesaccounts, users, organizations, payments, transactions
Document versionv1 · 2026-05-20
AudienceInternal FE devs (mobile + web)

Typical flow: create cause → platform admin approves → donor contributes via the payments module (donation flow) → the creator may assign additional managers. Donations without a specific cause (type OPEN) are pooled and allocated by MORIA superadmin via the admin endpoint POST /donations/allocate.

MethodPathAuthSummary
GET/v1/charitable-causesbearerList causes (scoped by role)
GET/v1/charitable-causes/:idbearerDetail of a single cause
POST/v1/charitable-causesbearerCreate a new cause
PATCH/v1/charitable-causes/:idbearerUpdate a cause
DELETE/v1/charitable-causes/:idbearerDeactivate (soft-cancel)
POST/v1/charitable-causes/:id/assign-managerbearerAssign an additional manager
GET/v1/summary/charitable-causesbearerStatistics summary (admin)
GET/v1/donations/openbearerList open donations (MORIA only)
POST/v1/donations/allocatebearerAllocate a batch of open donations to a cause (MORIA only)
PATCH/v1/charitable-causes/:id/approvebearerApprove a cause (MORIA only)

GET /v1/charitable-causes bearer

Section titled “GET /v1/charitable-causes ”

Paginated list of causes. Scope depends on role: INDIVIDUAL sees causes tied to their account (or marketplace via organization_id); ORGANIZATION admin sees the org’s causes; MORIA sees all.

bearer read-charitable-cause
ParamTypeDefaultNotes
pagenumber1Page number
limitnumber10Records per page
statusenum CharitableCauseStatusoptionalStatus filter; all means no filter
order'asc' | 'desc'descSort by created_at
organization_idstring (UUID)optionalMarketplace lookup; INDIVIDUAL may only use their own organization
user_idstring (UUID)optionalUser filter; layered authorization
account_idstring (UUID)optionalAccount filter; layered authorization
{
"status": "success",
"statusCode": 200,
"message": "Causes fetched successfully",
"data": {
"limit": 10,
"count": 12,
"currentPage": 1,
"totalPages": 2,
"causes": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Bantu Korban Banjir",
"description": "...",
"target_amount": 10000000,
"current_amount": 2500000,
"currency": "IDR",
"status": "active",
"owner_type": "organization",
"organization_id": "660e8400-e29b-41d4-a716-446655440111",
"account_id": "be2cb7da-e217-401c-8d07-b01e64adfb34"
}
]
}
}
StatusWhen it occurs
401 UnauthorizedBearer/cookie token invalid
403 ForbiddenWrong scope (see auth notes)

GET /v1/charitable-causes/:id bearer

Section titled “GET /v1/charitable-causes/:id ”

Detail of a single cause. Response format differs between MOBILE (raw) and WEB (formatted with aggregation). Scope organization_id is passed from the user.

bearer read-charitable-cause
ParamTypeNotes
idUUIDCause ID
{
"status": "success",
"statusCode": 200,
"message": "Cause retrieved successfully",
"data": {
"cause": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Bantu Korban Banjir",
"description": "Bantuan untuk korban banjir Jakarta",
"target_amount": 10000000,
"current_amount": 2500000,
"currency": "IDR",
"regulations": "...",
"benefit": "...",
"location": "Jakarta, Indonesia",
"status": "active",
"owner_type": "organization",
"managers": [ { "user_id": "...", "role": "manager" } ]
}
}
}
StatusWhen it occurs
400 Bad Requestid is not a UUID
401 UnauthorizedBearer/cookie token invalid
403 ForbiddenNo access to the cause
404 Not FoundCause not found

POST /v1/charitable-causes bearer

Section titled “POST /v1/charitable-causes ”

Create a new cause. The initial status is pending until a MORIA admin approves it. The organization_id field is only for MORIA superadmins creating on behalf of an organization.

bearer create-charitable-cause RESOURCE_CREATED
FieldTypeRequiredNotes
account_idstring (UUID)Account that will receive donations
descriptionstringCause description
currencystringoptionalCurrency (default IDR)
target_amountnumberFunding target (number, not string)
regulationsstringCause regulations & terms
benefitstringCause benefit & impact
namestringCause name
locationstringoptionalCause location (e.g. Jakarta, Indonesia)
organization_idstringoptionalOnly MORIA may send this — create on behalf of someone else
{
"account_id": "be2cb7da-e217-401c-8d07-b01e64adfb34",
"name": "Bantu Korban Banjir",
"description": "Bantuan untuk korban banjir Jakarta",
"currency": "IDR",
"target_amount": 10000000,
"regulations": "Dana digunakan untuk kebutuhan pokok korban",
"benefit": "Membantu 500 keluarga terdampak",
"location": "Jakarta, Indonesia"
}
{
"status": "success",
"statusCode": 201,
"message": "Cause created successfully",
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Bantu Korban Banjir",
"target_amount": 10000000,
"current_amount": 0,
"currency": "IDR",
"status": "pending"
}
}
StatusWhen it occurs
400 Bad RequestValidation failed (non-numeric target_amount, required field empty)
401 UnauthorizedBearer/cookie token invalid
403 ForbiddenMissing create-charitable-cause permission

PATCH /v1/charitable-causes/:id bearer

Section titled “PATCH /v1/charitable-causes/:id ”

Update a cause. Only the creator or a manager may perform this. All fields are optional.

bearer update-charitable-cause RESOURCE_UPDATED
ParamTypeNotes
idUUIDCause ID
FieldTypeNotes
descriptionstringNew description
currencystringCurrency
target_amountnumberNew funding target
regulationsstringNew regulations
benefitstringNew benefit
namestringNew name
statusenum CharitableCauseStatusNew status
{ "name": "Bantu Korban Banjir 2026", "target_amount": 15000000 }
{
"status": "success",
"statusCode": 200,
"message": "Cause updated successfully",
"data": { "...": "CauseDto shape" }
}
StatusWhen it occurs
400 Bad RequestValidation failed
401 UnauthorizedBearer/cookie token invalid
403 ForbiddenNot the creator/manager
404 Not FoundCause not found

DELETE /v1/charitable-causes/:id bearer

Section titled “DELETE /v1/charitable-causes/:id ”

Deactivate a cause (soft-cancel). Status changes to deactivated; the row is not removed and donations already received are not refunded.

bearer delete-charitable-cause RESOURCE_DELETED
ParamTypeNotes
idUUIDCause ID
{
"status": "success",
"statusCode": 200,
"message": "Cause cancelled successfully",
"data": { "...": "CauseDto shape, status='deactivated'" }
}
StatusWhen it occurs
401 UnauthorizedBearer/cookie token invalid
403 ForbiddenNot the creator
404 Not FoundCause not found

POST /v1/charitable-causes/:id/assign-manager bearer

Section titled “POST /v1/charitable-causes/:id/assign-manager ”

Designate another user as a manager of the cause. Only the creator is allowed — additional managers may update the cause but may not assign further managers.

bearer update-charitable-cause
ParamTypeNotes
idUUIDCause ID
FieldTypeRequiredNotes
user_idstring (UUID)ID of the user to become a manager
{ "user_id": "be2cb7da-e217-401c-8d07-b01e64adfb34" }
{
"status": "success",
"statusCode": 201,
"message": "Manager assigned successfully",
"data": { "manager": { "user_id": "...", "cause_id": "..." } }
}
StatusWhen it occurs
400 Bad RequestUser is already a manager of this cause
401 UnauthorizedBearer/cookie token invalid
403 ForbiddenNot the creator (only the creator may assign)
404 Not FoundCause or user not found

GET /v1/summary/charitable-causes bearer

Section titled “GET /v1/summary/charitable-causes ”

Cause statistics summary for the caller’s organization. Admin endpoint (MORIA / ORGANIZATION). MORIA can also view summaries across organizations.

bearer MORIA, ORGANIZATION read-charitable-cause
{
"status": "success",
"statusCode": 200,
"message": "charitable cause summary fetched successfully",
"data": {
"organization_id": "660e8400-e29b-41d4-a716-446655440111",
"organization_name": "Moria Fund",
"total_causes": "12",
"active_causes": "5",
"completed_causes": "3",
"pending_causes": "2",
"total_target_amount": "100000000.00",
"total_collected_amount": "65000000.00"
}
}
StatusWhen it occurs
401 UnauthorizedToken invalid / querying another org (mismatch)
403 ForbiddenRole is not MORIA/ORGANIZATION

List OPEN donations not yet allocated to a specific cause. MORIA superadmin only — typically used to allocate donations to causes in need.

bearer MORIA allocate-open-donation RESOURCE_UPDATED
ParamTypeDefaultNotes
pagenumber1Page number
limitnumber20Records per page
{
"status": "success",
"statusCode": 200,
"message": "Unallocated open donations fetched",
"data": {
"limit": 20,
"count": 8,
"currentPage": 1,
"totalPages": 1,
"donations": [
{
"id": "be2cb7da-e217-401c-8d07-b01e64adfb34",
"donor_user_id": "...",
"amount": "100000.00",
"donation_type": "open",
"status": "open",
"created_at": "2026-05-20T08:30:00.000Z"
}
]
}
}
StatusWhen it occurs
401 UnauthorizedBearer/cookie token invalid
403 ForbiddenNot MORIA superadmin

POST /v1/donations/allocate bearer

Section titled “POST /v1/donations/allocate ”

Allocate a batch of OPEN donations to a single active cause. Atomic — if any donation is invalid (already allocated / cause not active), the entire batch is rolled back.

bearer MORIA allocate-open-donation RESOURCE_UPDATED

Request body — AllocateDonationsBatchDto

Section titled “Request body — AllocateDonationsBatchDto”
FieldTypeRequiredNotes
donation_idsstring[] (UUID)List of donations to allocate — all must be OPEN, not yet allocated, and exist
cause_idstring (UUID)Target cause; must be in status ACTIVE
{
"donation_ids": [
"be2cb7da-e217-401c-8d07-b01e64adfb34",
"a1f2c3d4-5678-90ab-cdef-1234567890ab"
],
"cause_id": "550e8400-e29b-41d4-a716-446655440000"
}
{
"status": "success",
"statusCode": 200,
"message": "Donations allocated",
"data": { "allocated_count": 2, "cause_id": "550e8400-e29b-41d4-a716-446655440000" }
}
StatusWhen it occurs
400 Bad RequestSome donations are non-OPEN / already allocated / cause not active
401 UnauthorizedBearer/cookie token invalid
403 ForbiddenNot MORIA superadmin
404 Not FoundDonation or cause not found

PATCH /v1/charitable-causes/:id/approve bearer

Section titled “PATCH /v1/charitable-causes/:id/approve ”

Approve a cause currently in pending. MORIA superadmin only. After approval, the status moves to approved / active per the service logic.

bearer MORIA approve-charitable-cause RESOURCE_UPDATED
ParamTypeNotes
idUUIDCause ID
{
"status": "success",
"statusCode": 200,
"message": "Cause approved successfully",
"data": { "...": "CauseDto shape, status='active'" }
}
StatusWhen it occurs
400 Bad RequestCause was already approved
401 UnauthorizedBearer/cookie token invalid
403 ForbiddenNot MORIA superadmin
404 Not FoundCause not found

  • pending — awaiting MORIA approval
  • new — newly created (internal variant)
  • active — accepting donations
  • approved — approved by admin
  • in_progress — disbursement in progress
  • completed — target reached / finished
  • cancelled — cancelled
  • rejected — approval rejected
  • deactivated — soft-cancelled
  • all — filter sentinel (no filter)
  • specific — donor picks the cause
  • open — no cause, allocated by admin
  • subscription — recurring
  • organization · individual · moria
{
"message": "target_amount must be a number",
"statusCode": 400,
"error": "Bad Request"
}
  • 400 validation · donation already allocated · cause already approved
  • 401 token expired / missing
  • 403 not creator/manager · not MORIA
  • 404 cause/donation not found
  • 500 internal — show a generic toast