A Go-based API for wallet balance disbursements designed for the Indonesian market. This project implements a simple, yet robust system that allows users to withdraw funds from their wallet to bank accounts or e-wallets.
- IDR (Indonesian Rupiah) currency support
- Multiple disbursement methods:
- Bank transfers (BCA, Mandiri, BNI, BRI, etc.)
- E-wallets (GoPay, OVO, DANA, LinkAja, ShopeePay)
- Transaction fee calculation based on disbursement method
- Comprehensive validation including:
- Minimum withdrawal amount (Rp 10,000)
- Maximum withdrawal amount (Rp 50,000,000)
- Sufficient balance checks
- Transaction reference ID generation
- PostgreSQL database for data persistence
- Language: Go (Golang)
- Database: PostgreSQL
- External packages:
- github.com/google/uuid - For generating unique reference IDs
- github.com/lib/pq - PostgreSQL driver
- Go 1.16 or higher
- PostgreSQL 12 or higher
- Docker (optional, for containerized database)
-
Clone the repository:
git clone https://github.com/yourusername/wallet-disbursement-api.git cd wallet-disbursement-api -
Initialize Go module (if starting from scratch):
go mod init wallet-disbursement-api
-
Install dependencies:
go get github.com/lib/pq go get github.com/google/uuid
-
Start PostgreSQL container:
docker run --name postgres -e POSTGRES_PASSWORD=postgres -e POSTGRES_USER=postgres -e POSTGRES_DB=wallet_db -p 5432:5432 -d postgres:14
-
Run migrations:
# Copy migrations to container docker cp internal/database/migrations/001_initial_schema.sql postgres:/tmp/ # Execute migrations docker exec postgres psql -U postgres -d wallet_db -f /tmp/001_initial_schema.sql
-
Create database:
psql -U postgres -c "CREATE DATABASE wallet_db;" -
Run migrations:
psql -U postgres -d wallet_db -f internal/database/migrations/001_initial_schema.sql
-
Build and run:
go build -o wallet-api ./cmd/api ./wallet-api
Or use
go run:go run cmd/api/main.go
-
The API will be available at: http://localhost:8080
Endpoint: POST /api/disbursements
Request Body:
{
"user_id": 1,
"amount": 1000000.00,
"disbursement_method_id": 1,
"description": "Penarikan ke rekening BCA"
}Parameters:
user_id(required): ID of the user requesting disbursementamount(required): Amount to withdraw in IDRdisbursement_method_id(optional): ID of the disbursement method to usedescription(optional): Transaction description
Success Response (200 OK):
{
"success": true,
"reference_id": "fb8e642c-6a9d-4b5c-8749-e7dda4f76326",
"amount": 1000000.00,
"currency": "IDR",
"status": "processing",
"fee": 6500.00,
"remaining_balance": 8993500.00,
"method": "bank_transfer",
"provider": "BCA",
"account_number": "1234567890",
"created_at": "2023-07-21T15:30:45Z"
}Error Response (400 Bad Request):
{
"success": false,
"error": {
"code": "insufficient_balance",
"message": "Saldo dompet tidak mencukupi"
}
}Possible Error Codes:
invalid_user_id: User ID is not a positive integerinvalid_amount: Amount is not a positive numberuser_not_found: User does not existwallet_not_found: Wallet does not exist for this usermethod_not_found: Disbursement method not foundinsufficient_balance: Wallet has insufficient balanceminimum_amount: Amount is below minimum (Rp 10,000)maximum_amount: Amount exceeds maximum (Rp 50,000,000)daily_limit_exceeded: Daily withdrawal limit exceededinternal_error: An internal server error occurred
The database consists of the following tables:
id: User identifiername: User's full nameemail: User's email addressnik: National ID number (KTP)phone: Phone numbercreated_at: Record creation timestampupdated_at: Record update timestamp
id: Wallet identifieruser_id: Reference to users.idbalance: Current wallet balancecurrency: Currency code (IDR)created_at: Record creation timestampupdated_at: Record update timestamp
id: Method identifieruser_id: Reference to users.idtype: Method type (bank_transfer or e_wallet)provider: Bank name or e-wallet provideraccount_number: Account number or identifieraccount_holder_name: Name of account holderbank_code: Bank code (for bank transfers)is_default: Whether this is the default methodcreated_at: Record creation timestampupdated_at: Record update timestamp
id: Disbursement identifierreference_id: Unique reference ID for the transactionuser_id: Reference to users.idwallet_id: Reference to wallets.iddisbursement_method_id: Reference to disbursement_methods.idamount: Disbursement amountcurrency: Currency code (IDR)status: Transaction status (pending, processing, completed, failed)description: Transaction descriptionfee: Transaction fee amountcreated_at: Record creation timestampupdated_at: Record update timestamp