Files
solutax_api/readme.md

13 KiB

SoluTax IFS WIT API - Bruno Collection

A Bruno API collection for testing and interacting with the SoluTax IFS WIT API developed by PT Sarana Prima Telematika. This collection provides integration capabilities with Indonesia's tax system (DJP - Direktorat Jenderal Pajak) for electronic withholding tax slips (Bukti Potong).

Overview

Item Details
API Base URL https://ifswit-solutax-ctas-dev.spt.co.id
Environment Development (CTAS-DEV)
Authentication JWT Token via Basic Auth
Tax Types PPh 21, PPh A0, PPh A1

Tax Slip Types Supported

  • PPh 21 - Employee income tax withholding (monthly/non-final)
  • PPh A0 - Permanent employee monthly withholding
  • PPh A1 - Permanent employee annual withholding

Prerequisites

  • Bruno API Client - Download and install
  • Valid credentials for SoluTax API (username/password)
  • NPWP (Tax ID) for testing transactions

Quick Start

1. Clone and Open in Bruno

# Clone this repository
git clone <repository-url>
cd solutax_api

# Open in Bruno
# File > Open Folder > Select solutax_api directory

2. Configure Environment

  1. Open Bruno
  2. Navigate to Environments > solutax
  3. Configure your credentials:
    • username - Your API username
    • password - Your API password
    • passphrase - Electronic signature passphrase
    • npwp - Your NPWP number
    • npwp_pemilik - Employer NPWP

3. Get Authentication Token

  1. Select token.bru in the collection
  2. Click Send Request (or press Ctrl+Enter)
  3. Verify response contains access_token
  4. Token is automatically stored in environment variable

4. Create Your First Tax Slip

  1. Select PPh A0 > PPh A0 - Pengesahan Baru.bru
  2. Click Send Request
  3. Note the nomorBupot and idBupot from response

5. Verify Status

  1. Select PPh A0 > ppha0-status.bru
  2. Click Send Request
  3. Confirm statusBupot is NORMAL-DONE

Project Structure

solutax_api/
├── bruno.json                    # Bruno collection configuration
├── readme.md                     # This file
├── agents.md                     # AI agent documentation
├── spesifikasi.md                # Full API specification (Indonesian)
├── token.bru                     # Authentication token request
├── package-lock.json             # Node.js lock file
│
├── environments/
│   ├── solutax.bru               # Environment variables template
│   ├── solutax.json              # Environment configuration
│   └── solutax copy.json         # Backup environment
│
├── PPh 21/                       # PPh 21 (Monthly/Non-Final)
│   ├── PPh 21 - Pengesahan Baru.bru
│   ├── pph21-edit.bru
│   ├── pph21-cancel.bru
│   ├── pph21-status.bru
│   └── pph21-pdf.bru
│
├── PPh A0/                       # PPh A0 (Permanent Employee Monthly)
│   ├── PPh A0 - Pengesahan Baru.bru
│   ├── ppha0-edit.bru
│   ├── ppha0-cancel.bru
│   ├── ppha0-status.bru
│   └── ppha0-pdf.bru
│
├── PPh A1/                       # PPh A1 (Permanent Employee Annual)
│   ├── PPh A1 - Pengesahan Baru.bru
│   ├── ppha1-edit.bru
│   ├── ppha1-cancel.bru
│   ├── ppha1-status.bru
│   └── ppha1-pdf.bru
│
└── sample result/                # Sample API responses
    ├── token_result_sample.json
    └── ppha0_new_result_sample.json

API Endpoints

Authentication

Endpoint Method Description
/auth/gettoken POST Get JWT access token using Basic Auth

PPh 21 (Monthly/Non-Final)

Endpoint Method Description
/ifs/api/wit/bulanan/new POST Create and approve new PPh 21 slip
/ifs/api/wit/bulanan/edit POST Replace/modify existing PPh 21 slip
/ifs/api/wit/cancel POST Cancel a PPh 21 slip
/ifs/api/wit/status POST Check status of PPh 21 slip
/ifs/api/wit/pdf POST Download PDF of PPh 21 slip

PPh A0 (Permanent Employee Monthly)

Endpoint Method Description
/ifs/api/wit/bulanan/new POST Create and approve new PPh A0 slip
/ifs/api/wit/bulanan/edit POST Replace/modify existing PPh A0 slip
/ifs/api/wit/cancel POST Cancel a PPh A0 slip
/ifs/api/wit/status POST Check status of PPh A0 slip
/ifs/api/wit/pdf POST Download PDF of PPh A0 slip

PPh A1 (Permanent Employee Annual)

Endpoint Method Description
/ifs/api/wit/tahunan/new POST Create and approve new PPh A1 slip
/ifs/api/wit/tahunan/edit POST Replace/modify existing PPh A1 slip
/ifs/api/wit/cancel POST Cancel a PPh A1 slip
/ifs/api/wit/status POST Check status of PPh A1 slip
/ifs/api/wit/pdf POST Download PDF of PPh A1 slip

Environment Variables

Configure these in Environments > solutax:

Variable Description Required
accessToken JWT authentication token Yes (auto-generated)
idpel Customer ID Yes (from token response)
requestID Unique request GUID Yes (auto-generated)
username API username Yes
password API password Yes
passphrase Electronic signature passphrase Yes
npwp Employee NPWP Yes
npwp_pemilik Employer NPWP Yes
nomorBupot Tax slip number Yes (from create response)
idBupot Tax slip ID (UUID) Yes (from create response)

Request/Response Patterns

Request Structure

All requests follow a consistent pattern:

{
  "idPel": 12345,
  "requestID": "uuid-string",
  "dataBpA0": { ... }
}

Response Structure

{
  "kodestatus": 200,
  "keterangan": "Success",
  "data": { ... },
  "idPel": 12345
}

Common Status Codes

Code Meaning
200 Success
401 Unauthorized (invalid/expired token)
500 Server error (e.g., invalid User ID)

Slip Status Values

Status Meaning
NORMAL-DONE Original slip approved
AMENDED Slip was replaced/modified
CANCELLED-Done Slip was cancelled

Testing Workflow

Complete Workflow Example

1. Get Token
   └─> token.bru
       → accessToken set automatically

2. Create Slip
   └─> PPh A0/PPh A0 - Pengesahan Baru.bru
       → nomorBupot and idBupot returned

3. Verify Status
   └─> PPh A0/ppha0-status.bru
       → statusBupot = "NORMAL-DONE"

4. Download PDF (optional)
   └─> PPh A0/ppha0-pdf.bru
       → Base64 PDF in response

5. Modify Slip (if needed)
   └─> PPh A0/ppha0-edit.bru
       → New nomorBupot assigned

6. Cancel Slip (if needed)
   └─> PPh A0/ppha0-cancel.bru
       → statusBupot = "CANCELLED-Done"

Happy Flow Diagram

flowchart TD
    Start([Start]) --> Auth[Get Authentication Token]
    Auth -->|POST /auth/gettoken| TokenAPI[Token API]
    TokenAPI -->|Returns: access_token, idpel| TokenOK{Token Received?}
    
    TokenOK -->|Yes| Create[Create Tax Slip]
    TokenOK -->|No| Error1[Check Credentials]
    Error1 --> Auth
    
    Create --> CreateAPI{Choose Tax Slip Type}
    CreateAPI -->|PPh 21| P21[POST /ifs/api/wit/bulanan/new]
    CreateAPI -->|PPh A0| PA0[POST /ifs/api/wit/bulanan/new]
    CreateAPI -->|PPh A1| PA1[POST /ifs/api/wit/tahunan/new]
    
    P21 -->|Request: monthlyIncome, dataBp21| CreateSuccess{Success?}
    PA0 -->|Request: monthlyIncome, dataBpA0| CreateSuccess
    PA1 -->|Request: yearlyIncome, dataBpA1| CreateSuccess
    
    CreateSuccess -->|Yes: status=1| Return1[Returns: nomorBupot, idBupot]
    CreateSuccess -->|No: status=0| Error2[Handle Error]
    Error2 --> Create
    
    Return1 --> Status[Check Tax Slip Status]
    
    Status --> StatusAPI{Choose Tax Slip Type}
    StatusAPI -->|PPh 21| S21[POST /ifs/api/wit/status]
    StatusAPI -->|PPh A0| SA0[POST /ifs/api/wit/status]
    StatusAPI -->|PPh A1| SA1[POST /ifs/api/wit/status]
    
    S21 -->|Request: taxSlipVerification| StatusOK{Status Received?}
    SA0 -->|Request: taxSlipVerification| StatusOK
    SA1 -->|Request: taxSlipVerification| StatusOK
    
    StatusOK -->|statusBupot=NORMAL-DONE| Decision{What's Next?}
    StatusOK -->|statusBupot=AMENDED| Decision
    StatusOK -->|statusBupot=CANCELLED-Done| End1([End])
    StatusOK -->|Error| Error3[Handle Error]
    Error3 --> Status
    
    Decision -->|Download PDF| PDF[Download PDF]
    Decision -->|Modify Slip| Edit[Edit Tax Slip]
    Decision -->|Cancel Slip| Cancel[Cancel Tax Slip]
    Decision -->|Done| End2([End])
    
    PDF --> PDFAPI{Choose Tax Slip Type}
    PDFAPI -->|PPh 21| PF21[POST /ifs/api/wit/pdf]
    PDFAPI -->|PPh A0| PFA0[POST /ifs/api/wit/pdf]
    PDFAPI -->|PPh A1| PFA1[POST /ifs/api/wit/pdf]
    
    PF21 -->|Returns: Base64 PDF| PDFOK{Downloaded?}
    PFA0 -->|Returns: Base64 PDF| PDFOK
    PFA1 -->|Returns: Base64 PDF| PDFOK
    
    PDFOK -->|Yes| End3([End])
    PDFOK -->|No| Error4[Handle Error]
    Error4 --> PDF
    
    Edit --> EditAPI{Choose Tax Slip Type}
    EditAPI -->|PPh 21| E21[POST /ifs/api/wit/bulanan/edit]
    EditAPI -->|PPh A0| EA0[POST /ifs/api/wit/bulanan/edit]
    EditAPI -->|PPh A1| EA1[POST /ifs/api/wit/tahunan/edit]
    
    E21 -->|Request: monthlyIncome, nomorBupot, idBupot| EditSuccess{Success?}
    EA0 -->|Request: monthlyIncome, nomorBupot, idBupot| EditSuccess
    EA1 -->|Request: yearlyIncome, nomorBupot, idBupot| EditSuccess
    
    EditSuccess -->|Yes: status=1| Return2[Returns: new nomorBupot, new idBupot]
    EditSuccess -->|No: status=0| Error5[Handle Error]
    Error5 --> Edit
    
    Return2 --> Status2[Check Status Again]
    Status2 --> Status
    
    Cancel --> CancelAPI{Choose Tax Slip Type}
    CancelAPI -->|PPh 21| C21[POST /ifs/api/wit/cancel]
    CancelAPI -->|PPh A0| CA0[POST /ifs/api/wit/cancel]
    CancelAPI -->|PPh A1| CA1[POST /ifs/api/wit/cancel]
    
    C21 -->|Request: taxSlipCancel| CancelSuccess{Success?}
    CA0 -->|Request: taxSlipCancel| CancelSuccess
    CA1 -->|Request: taxSlipCancel| CancelSuccess
    
    CancelSuccess -->|Yes: status=1| Return3[Returns: status=1]
    CancelSuccess -->|No: status=0| Error6[Handle Error]
    Error6 --> Cancel
    
    Return3 --> Status3[Verify Cancellation]
    Status3 --> Status
    
    style Start fill:#e1f5fe
    style Auth fill:#e1f5fe
    style Create fill:#fff3e0
    style Status fill:#e8f5e9
    style PDF fill:#f3e5f5
    style Edit fill:#fff8e1
    style Cancel fill:#ffebee
    style End1 fill:#c8e6c9
    style End2 fill:#c8e6c9
    style End3 fill:#c8e6c9
    style Error1 fill:#ffcdd2
    style Error2 fill:#ffcdd2
    style Error3 fill:#ffcdd2
    style Error4 fill:#ffcdd2
    style Error5 fill:#ffcdd2
    style Error6 fill:#ffcdd2

Quick Reference: Happy Flow Steps

Step Action Endpoint Returns
1 Get Token POST /auth/gettoken access_token, idpel
2 Create Slip POST /ifs/api/wit/bulanan/new or /tahunan/new nomorBupot, idBupot
3 Check Status POST /ifs/api/wit/status statusBupot
4a Download PDF POST /ifs/api/wit/pdf Base64 PDF
4b Edit Slip POST /ifs/api/wit/bulanan/edit or /tahunan/edit New nomorBupot
4c Cancel Slip POST /ifs/api/wit/cancel Success confirmation

Status Flow

stateDiagram-v2
    [*] --> NORMAL_DONE: Pengesahan (New)
    NORMAL_DONE --> AMENDED: Penggantian (Edit)
    AMENDED --> AMENDED: Penggantian Lagi
    NORMAL_DONE --> CANCELLED_DONE: Pembatalan (Cancel)
    AMENDED --> CANCELLED_DONE: Pembatalan (Cancel)
    CANCELLED_DONE --> [*]

Important Notes

  1. Language: All API documentation and field names are in Indonesian (Bahasa Indonesia)

  2. Environment: This is a development/DEV environment (CTAS-DEV) - do not use for production

  3. Token Expiration: Monitor expires_in field; tokens expire and require renewal

  4. NPWP Validation: Tax ID numbers (NPWP) are validated on all endpoints

  5. Electronic Signature: Passphrase required for penandatangan (signatory) on create/edit/cancel operations

  6. Pre-request Scripts: Some files auto-generate UUIDs for requestID using JavaScript

  7. Post-response Scripts: Some files extract and store response values as environment variables

Documentation References

Troubleshooting

Token Issues

  • 401 Unauthorized: Token expired or invalid → Get new token via token.bru
  • 500 Server Error: Check username/password credentials

Slip Creation Issues

  • Missing Fields: Ensure all required fields are filled in the request body
  • NPWP Invalid: Verify NPWP format (15 digits with dots)
  • Signature Error: Check passphrase is correct

PDF Download Issues

  • Empty Response: Ensure slip status is NORMAL-DONE before downloading
  • Invalid Base64: Response data field contains Base64-encoded PDF

License

Copyright © 2026 PT Sarana Prima Telematika. All rights reserved.

Contact

Developer: PT Sarana Prima Telematika
Version: 1.0
Year: 2026