{
  "info": {
    "_postman_id": "8f8c6c20-3a8d-4c42-9d6d-f1f8c801a9d4",
    "name": "LoanMetric API",
    "description": "LoanMetric backend endpoint collection. Run Public auth requests first; customer_token and admin_token are saved automatically.",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "variable": [
    { "key": "base_url", "value": "http://127.0.0.1:8000/api/v1" },
    { "key": "customer_phone", "value": "60123456789" },
    { "key": "customer_otp", "value": "123456" },
    { "key": "customer_token", "value": "" },
    { "key": "admin_email", "value": "admin@loanmetric.test" },
    { "key": "admin_password", "value": "password" },
    { "key": "admin_token", "value": "" },
    { "key": "loan_id", "value": "1" },
    { "key": "payment_id", "value": "1" },
    { "key": "fee_id", "value": "1" },
    { "key": "staff_user_id", "value": "2" },
    { "key": "receipt_file", "value": "C:\\\\path\\\\to\\\\receipt.pdf" }
  ],
  "item": [
    {
      "name": "Public Auth",
      "item": [
        {
          "name": "GET Config",
          "request": {
            "method": "GET",
            "header": [{ "key": "Accept", "value": "application/json" }],
            "url": "{{base_url}}/config"
          }
        },
        {
          "name": "POST Customer Request OTP",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const json = pm.response.json();",
                  "if (json.data?.demo_tac) pm.collectionVariables.set('customer_otp', json.data.demo_tac);",
                  "if (json.data?.phone) pm.collectionVariables.set('customer_phone', json.data.phone);"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              { "key": "Accept", "value": "application/json" },
              { "key": "Content-Type", "value": "application/json" }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"phone\": \"{{customer_phone}}\"\n}"
            },
            "url": "{{base_url}}/auth/customer/request-otp"
          }
        },
        {
          "name": "POST Customer Verify OTP",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const json = pm.response.json();",
                  "if (json.data?.token) pm.collectionVariables.set('customer_token', json.data.token);"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              { "key": "Accept", "value": "application/json" },
              { "key": "Content-Type", "value": "application/json" }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"phone\": \"{{customer_phone}}\",\n  \"otp\": \"{{customer_otp}}\"\n}"
            },
            "url": "{{base_url}}/auth/customer/verify-otp"
          }
        },
        {
          "name": "POST Admin Login",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const json = pm.response.json();",
                  "if (json.data?.token) pm.collectionVariables.set('admin_token', json.data.token);"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              { "key": "Accept", "value": "application/json" },
              { "key": "Content-Type", "value": "application/json" }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"email\": \"{{admin_email}}\",\n  \"password\": \"{{admin_password}}\"\n}"
            },
            "url": "{{base_url}}/auth/admin/login"
          }
        }
      ]
    },
    {
      "name": "Customer",
      "auth": {
        "type": "bearer",
        "bearer": [{ "key": "token", "value": "{{customer_token}}", "type": "string" }]
      },
      "item": [
        {
          "name": "GET Auth Me",
          "request": { "method": "GET", "header": [{ "key": "Accept", "value": "application/json" }], "url": "{{base_url}}/auth/me" }
        },
        {
          "name": "POST Logout",
          "request": { "method": "POST", "header": [{ "key": "Accept", "value": "application/json" }], "url": "{{base_url}}/auth/logout" }
        },
        {
          "name": "GET Dashboard",
          "request": { "method": "GET", "header": [{ "key": "Accept", "value": "application/json" }], "url": "{{base_url}}/customer/dashboard" }
        },
        {
          "name": "GET Application",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const json = pm.response.json();",
                  "if (json.data?.application?.id) pm.collectionVariables.set('loan_id', json.data.application.id);"
                ]
              }
            }
          ],
          "request": { "method": "GET", "header": [{ "key": "Accept", "value": "application/json" }], "url": "{{base_url}}/customer/application" }
        },
        {
          "name": "POST Basic Info",
          "request": {
            "method": "POST",
            "header": [{ "key": "Accept", "value": "application/json" }, { "key": "Content-Type", "value": "application/json" }],
            "body": { "mode": "raw", "raw": "{\n  \"full_name\": \"Afiq Rahman\",\n  \"email\": \"afiq@example.com\",\n  \"gender\": \"male\",\n  \"date_of_birth\": \"1990-01-15\",\n  \"id_type\": \"NRIC\",\n  \"id_number\": \"900115-10-1234\"\n}" },
            "url": "{{base_url}}/customer/basic-info"
          }
        },
        {
          "name": "POST Employment Info",
          "request": {
            "method": "POST",
            "header": [{ "key": "Accept", "value": "application/json" }, { "key": "Content-Type", "value": "application/json" }],
            "body": { "mode": "raw", "raw": "{\n  \"employment_type\": \"Full Time\",\n  \"position\": \"Manager\",\n  \"monthly_gross_income\": 6500,\n  \"monthly_net_income\": 5200\n}" },
            "url": "{{base_url}}/customer/employment-info"
          }
        },
        {
          "name": "POST Bank Info",
          "request": {
            "method": "POST",
            "header": [{ "key": "Accept", "value": "application/json" }, { "key": "Content-Type", "value": "application/json" }],
            "body": { "mode": "raw", "raw": "{\n  \"bank_name\": \"Maybank\",\n  \"account_holder_name\": \"Afiq Rahman\",\n  \"account_number\": \"1234567890\",\n  \"branch_name\": \"KL Main\"\n}" },
            "url": "{{base_url}}/customer/bank-info"
          }
        },
        {
          "name": "POST Review Start",
          "request": { "method": "POST", "header": [{ "key": "Accept", "value": "application/json" }], "url": "{{base_url}}/customer/review/start" }
        },
        {
          "name": "POST Review Complete",
          "request": { "method": "POST", "header": [{ "key": "Accept", "value": "application/json" }], "url": "{{base_url}}/customer/review/complete" }
        },
        {
          "name": "POST Application Received Confirm",
          "request": { "method": "POST", "header": [{ "key": "Accept", "value": "application/json" }], "url": "{{base_url}}/customer/application-received/confirm" }
        },
        {
          "name": "POST Loan Term Calculate",
          "request": {
            "method": "POST",
            "header": [{ "key": "Accept", "value": "application/json" }, { "key": "Content-Type", "value": "application/json" }],
            "body": { "mode": "raw", "raw": "{\n  \"loan_amount\": 50000,\n  \"term_months\": 12\n}" },
            "url": "{{base_url}}/customer/loan-term/calculate"
          }
        },
        {
          "name": "POST Loan Term Save",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const json = pm.response.json();",
                  "if (json.data?.current_fee?.payment_id) pm.collectionVariables.set('payment_id', json.data.current_fee.payment_id);"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [{ "key": "Accept", "value": "application/json" }, { "key": "Content-Type", "value": "application/json" }],
            "body": { "mode": "raw", "raw": "{\n  \"loan_amount\": 50000,\n  \"term_months\": 12\n}" },
            "url": "{{base_url}}/customer/loan-term"
          }
        },
        {
          "name": "GET Current Fee",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const json = pm.response.json();",
                  "if (json.data?.current_fee?.payment_id) pm.collectionVariables.set('payment_id', json.data.current_fee.payment_id);",
                  "if (json.data?.current_fee?.id) pm.collectionVariables.set('fee_id', json.data.current_fee.id);"
                ]
              }
            }
          ],
          "request": { "method": "GET", "header": [{ "key": "Accept", "value": "application/json" }], "url": "{{base_url}}/customer/current-fee" }
        },
        {
          "name": "GET Payments",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const json = pm.response.json();",
                  "if (json.data?.payments?.length) pm.collectionVariables.set('payment_id', json.data.payments[0].payment_id || json.data.payments[0].id);"
                ]
              }
            }
          ],
          "request": { "method": "GET", "header": [{ "key": "Accept", "value": "application/json" }], "url": "{{base_url}}/customer/payments" }
        },
        {
          "name": "POST Upload Receipt",
          "request": {
            "method": "POST",
            "header": [{ "key": "Accept", "value": "application/json" }],
            "body": {
              "mode": "formdata",
              "formdata": [
                { "key": "receipt", "type": "file", "src": "{{receipt_file}}" },
                { "key": "customer_note", "type": "text", "value": "Uploaded via Postman." }
              ]
            },
            "url": "{{base_url}}/customer/payments/{{payment_id}}/receipt"
          }
        },
        {
          "name": "GET Loan Status",
          "request": { "method": "GET", "header": [{ "key": "Accept", "value": "application/json" }], "url": "{{base_url}}/customer/loan-status" }
        },
        {
          "name": "GET Loan Approved",
          "request": { "method": "GET", "header": [{ "key": "Accept", "value": "application/json" }], "url": "{{base_url}}/customer/loan-approved" }
        }
      ]
    },
    {
      "name": "Admin",
      "auth": {
        "type": "bearer",
        "bearer": [{ "key": "token", "value": "{{admin_token}}", "type": "string" }]
      },
      "item": [
        {
          "name": "GET Auth Me",
          "request": { "method": "GET", "header": [{ "key": "Accept", "value": "application/json" }], "url": "{{base_url}}/auth/me" }
        },
        {
          "name": "POST Logout",
          "request": { "method": "POST", "header": [{ "key": "Accept", "value": "application/json" }], "url": "{{base_url}}/auth/logout" }
        },
        {
          "name": "GET Dashboard Stats",
          "request": { "method": "GET", "header": [{ "key": "Accept", "value": "application/json" }], "url": "{{base_url}}/admin/dashboard/stats" }
        },
        {
          "name": "GET Loans",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const json = pm.response.json();",
                  "if (json.data?.length) pm.collectionVariables.set('loan_id', json.data[0].id);"
                ]
              }
            }
          ],
          "request": { "method": "GET", "header": [{ "key": "Accept", "value": "application/json" }], "url": "{{base_url}}/admin/loans" }
        },
        {
          "name": "GET Loan Detail",
          "request": { "method": "GET", "header": [{ "key": "Accept", "value": "application/json" }], "url": "{{base_url}}/admin/loans/{{loan_id}}" }
        },
        {
          "name": "POST Approve Loan",
          "request": {
            "method": "POST",
            "header": [{ "key": "Accept", "value": "application/json" }, { "key": "Content-Type", "value": "application/json" }],
            "body": { "mode": "raw", "raw": "{\n  \"approved_amount\": 50000,\n  \"admin_note\": \"Approved based on submitted documents.\"\n}" },
            "url": "{{base_url}}/admin/loans/{{loan_id}}/approve-loan"
          }
        },
        {
          "name": "POST Reject Loan",
          "request": {
            "method": "POST",
            "header": [{ "key": "Accept", "value": "application/json" }, { "key": "Content-Type", "value": "application/json" }],
            "body": { "mode": "raw", "raw": "{\n  \"reason\": \"Customer information could not be verified.\"\n}" },
            "url": "{{base_url}}/admin/loans/{{loan_id}}/reject"
          }
        },
        {
          "name": "GET Payments",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const json = pm.response.json();",
                  "if (json.data?.length) pm.collectionVariables.set('payment_id', json.data[0].id);"
                ]
              }
            }
          ],
          "request": { "method": "GET", "header": [{ "key": "Accept", "value": "application/json" }], "url": "{{base_url}}/admin/payments" }
        },
        {
          "name": "POST Approve Payment",
          "request": {
            "method": "POST",
            "header": [{ "key": "Accept", "value": "application/json" }, { "key": "Content-Type", "value": "application/json" }],
            "body": { "mode": "raw", "raw": "{\n  \"admin_note\": \"Receipt verified.\"\n}" },
            "url": "{{base_url}}/admin/payments/{{payment_id}}/approve"
          }
        },
        {
          "name": "POST Reject Payment",
          "request": {
            "method": "POST",
            "header": [{ "key": "Accept", "value": "application/json" }, { "key": "Content-Type", "value": "application/json" }],
            "body": { "mode": "raw", "raw": "{\n  \"rejection_reason\": \"Receipt image is unclear.\",\n  \"admin_note\": \"Please upload clear bank transfer slip.\"\n}" },
            "url": "{{base_url}}/admin/payments/{{payment_id}}/reject"
          }
        },
        {
          "name": "GET Settings",
          "request": { "method": "GET", "header": [{ "key": "Accept", "value": "application/json" }], "url": "{{base_url}}/admin/settings" }
        },
        {
          "name": "PUT Settings Bank",
          "request": {
            "method": "PUT",
            "header": [{ "key": "Accept", "value": "application/json" }, { "key": "Content-Type", "value": "application/json" }],
            "body": { "mode": "raw", "raw": "{\n  \"bank_name\": \"Demo Bank\",\n  \"account_name\": \"LoanMetric Sdn Bhd\",\n  \"account_number\": \"0000000000\",\n  \"notes\": \"Use phone number as reference.\"\n}" },
            "url": "{{base_url}}/admin/settings/bank"
          }
        },
        {
          "name": "PUT Settings Maintenance",
          "request": {
            "method": "PUT",
            "header": [{ "key": "Accept", "value": "application/json" }, { "key": "Content-Type", "value": "application/json" }],
            "body": { "mode": "raw", "raw": "{\n  \"enabled\": false,\n  \"message\": \"Maintenance in progress.\"\n}" },
            "url": "{{base_url}}/admin/settings/maintenance"
          }
        },
        {
          "name": "PUT Settings Loan Config",
          "request": {
            "method": "PUT",
            "header": [{ "key": "Accept", "value": "application/json" }, { "key": "Content-Type", "value": "application/json" }],
            "body": { "mode": "raw", "raw": "{\n  \"min_amount\": 5000,\n  \"max_amount\": 100000,\n  \"terms\": [6, 12, 18, 24, 36],\n  \"original_interest_rate\": 0.05,\n  \"discounted_interest_rate\": 0.025,\n  \"handling_fee_rate\": 0.008\n}" },
            "url": "{{base_url}}/admin/settings/loan-config"
          }
        },
        {
          "name": "GET Fees",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const json = pm.response.json();",
                  "if (json.data?.length) pm.collectionVariables.set('fee_id', json.data[0].id);"
                ]
              }
            }
          ],
          "request": { "method": "GET", "header": [{ "key": "Accept", "value": "application/json" }], "url": "{{base_url}}/admin/fees" }
        },
        {
          "name": "POST Create Fee",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const json = pm.response.json();",
                  "if (json.data?.id) pm.collectionVariables.set('fee_id', json.data.id);"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [{ "key": "Accept", "value": "application/json" }, { "key": "Content-Type", "value": "application/json" }],
            "body": { "mode": "raw", "raw": "{\n  \"title\": \"Legal Review Fee\",\n  \"description\": \"Refundable upon loan disbursement.\",\n  \"amount_type\": \"fixed\",\n  \"amount\": 300,\n  \"sort_order\": 7,\n  \"is_active\": true,\n  \"bank_name\": \"Demo Bank\",\n  \"bank_account_name\": \"LoanMetric Sdn Bhd\",\n  \"bank_account_number\": \"0000000000\"\n}" },
            "url": "{{base_url}}/admin/fees"
          }
        },
        {
          "name": "GET Fee Detail",
          "request": { "method": "GET", "header": [{ "key": "Accept", "value": "application/json" }], "url": "{{base_url}}/admin/fees/{{fee_id}}" }
        },
        {
          "name": "PUT Update Fee",
          "request": {
            "method": "PUT",
            "header": [{ "key": "Accept", "value": "application/json" }, { "key": "Content-Type", "value": "application/json" }],
            "body": { "mode": "raw", "raw": "{\n  \"title\": \"Processing Fee\",\n  \"description\": \"Refundable upon disbursement.\",\n  \"amount_type\": \"fixed\",\n  \"amount\": 500,\n  \"is_active\": true,\n  \"bank_name\": \"Demo Bank\",\n  \"bank_account_name\": \"LoanMetric Sdn Bhd\",\n  \"bank_account_number\": \"0000000000\"\n}" },
            "url": "{{base_url}}/admin/fees/{{fee_id}}"
          }
        },
        {
          "name": "DELETE Fee",
          "request": { "method": "DELETE", "header": [{ "key": "Accept", "value": "application/json" }], "url": "{{base_url}}/admin/fees/{{fee_id}}" }
        },
        {
          "name": "POST Reorder Fees",
          "request": {
            "method": "POST",
            "header": [{ "key": "Accept", "value": "application/json" }, { "key": "Content-Type", "value": "application/json" }],
            "body": { "mode": "raw", "raw": "{\n  \"items\": [\n    { \"id\": 1, \"sort_order\": 1 },\n    { \"id\": 2, \"sort_order\": 2 },\n    { \"id\": 3, \"sort_order\": 3 }\n  ]\n}" },
            "url": "{{base_url}}/admin/fees/reorder"
          }
        },
        {
          "name": "PATCH Toggle Fee",
          "request": {
            "method": "PATCH",
            "header": [{ "key": "Accept", "value": "application/json" }, { "key": "Content-Type", "value": "application/json" }],
            "body": { "mode": "raw", "raw": "{\n  \"is_active\": false\n}" },
            "url": "{{base_url}}/admin/fees/{{fee_id}}/toggle"
          }
        },
        {
          "name": "GET Activity Logs",
          "request": { "method": "GET", "header": [{ "key": "Accept", "value": "application/json" }], "url": "{{base_url}}/admin/activity-logs" }
        },
        {
          "name": "GET Staff",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const json = pm.response.json();",
                  "if (json.data?.length) pm.collectionVariables.set('staff_user_id', json.data[0].id);"
                ]
              }
            }
          ],
          "request": { "method": "GET", "header": [{ "key": "Accept", "value": "application/json" }], "url": "{{base_url}}/admin/staff" }
        },
        {
          "name": "POST Create Staff",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const json = pm.response.json();",
                  "if (json.data?.id) pm.collectionVariables.set('staff_user_id', json.data.id);"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [{ "key": "Accept", "value": "application/json" }, { "key": "Content-Type", "value": "application/json" }],
            "body": { "mode": "raw", "raw": "{\n  \"name\": \"New Staff\",\n  \"email\": \"newstaff@example.com\",\n  \"password\": \"StrongPassword123\",\n  \"status\": \"active\"\n}" },
            "url": "{{base_url}}/admin/staff"
          }
        },
        {
          "name": "PUT Update Staff",
          "request": {
            "method": "PUT",
            "header": [{ "key": "Accept", "value": "application/json" }, { "key": "Content-Type", "value": "application/json" }],
            "body": { "mode": "raw", "raw": "{\n  \"name\": \"Review Staff\",\n  \"status\": \"inactive\",\n  \"password\": \"NewPassword123\"\n}" },
            "url": "{{base_url}}/admin/staff/{{staff_user_id}}"
          }
        }
      ]
    }
  ]
}
