Appearance
Invoices
This guide covers creating and managing invoices with the InvoisX API.
Setup
Before using the examples below, set up your HTTP client:
javascript
const API_URL = 'https://invoisx.com/api/v1';
const API_TOKEN = 'your-api-token';
async function api(method, endpoint, data = null) {
const response = await fetch(`${API_URL}${endpoint}`, {
method,
headers: {
'Authorization': `Bearer ${API_TOKEN}`,
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: data ? JSON.stringify(data) : null,
});
return response.json();
}python
import requests
API_URL = 'https://invoisx.com/api/v1'
API_TOKEN = 'your-api-token'
def api(method, endpoint, data=None):
response = requests.request(
method,
f'{API_URL}{endpoint}',
headers={
'Authorization': f'Bearer {API_TOKEN}',
'Accept': 'application/json',
},
json=data
)
return response.json()php
use Illuminate\Support\Facades\Http;
$api = Http::withToken('your-api-token')
->accept('application/json')
->baseUrl('https://invoisx.com/api/v1');php
use GuzzleHttp\Client;
$client = new Client([
'base_uri' => 'https://invoisx.com/api/v1/',
'headers' => [
'Authorization' => 'Bearer your-api-token',
'Accept' => 'application/json',
'Content-Type' => 'application/json',
]
]);java
import java.net.http.*;
import java.net.URI;
var client = HttpClient.newHttpClient();
var API_URL = "https://invoisx.com/api/v1";
var API_TOKEN = "your-api-token";
HttpResponse<String> api(String method, String endpoint, String jsonBody) throws Exception {
var builder = HttpRequest.newBuilder()
.uri(URI.create(API_URL + endpoint))
.header("Authorization", "Bearer " + API_TOKEN)
.header("Accept", "application/json")
.header("Content-Type", "application/json");
if (jsonBody != null) {
builder.method(method, HttpRequest.BodyPublishers.ofString(jsonBody));
} else {
builder.method(method, HttpRequest.BodyPublishers.noBody());
}
return client.send(builder.build(), HttpResponse.BodyHandlers.ofString());
}csharp
using System.Net.Http;
using System.Text;
using System.Text.Json;
var client = new HttpClient {
BaseAddress = new Uri("https://invoisx.com/api/v1")
};
client.DefaultRequestHeaders.Add("Authorization", "Bearer your-api-token");
client.DefaultRequestHeaders.Add("Accept", "application/json");Overview
Invoices are the core document type in InvoisX. They represent sales transactions that need to be submitted to LHDN for e-invoicing compliance.
Creating an Invoice
Minimal Invoice
The only required field is buyerId:
javascript
const invoice = await api('POST', '/invoices', {
buyerId: 'buyer-uuid-here'
});python
invoice = api('POST', '/invoices', {
'buyerId': 'buyer-uuid-here'
})php
$invoice = $api->post('/invoices', [
'buyerId' => 'buyer-uuid-here'
]);php
$response = $client->post('invoices', ['json' => [
'buyerId' => 'buyer-uuid-here'
]]);
$invoice = json_decode($response->getBody(), true);java
var json = """
{"buyerId": "buyer-uuid-here"}""";
var response = api("POST", "/invoices", json);csharp
var invoice = new { buyerId = "buyer-uuid-here" };
var response = await client.PostAsJsonAsync("/invoices", invoice);Invoice with Line Items
A complete invoice with line items, taxes, and payment information:
javascript
const invoice = await api('POST', '/invoices', {
buyerId: 'buyer-uuid',
invoiceSerialNumber: 'INV-2024-001',
currencyCode: 'MYR',
autoCalculate: true,
invoiceLines: [
{
classifications: ['001'],
productDescription: 'Web Development Services',
quantity: 1,
unitCode: 'H87',
unitPrice: 5000.00,
invoiceLineTaxes: [
{ taxType: '01', taxRate: 8 }
]
},
{
classifications: ['001'],
productDescription: 'Monthly Hosting',
quantity: 12,
unitCode: 'MON',
unitPrice: 150.00,
discountRate: 10,
discountDescription: 'Annual discount',
invoiceLineTaxes: [
{ taxType: '01', taxRate: 8 }
]
}
],
payment: {
paymentMode: '03', // Bank Transfer
paymentTerms: 'Net 30 days',
supplierBankAccountNumber: '1234567890'
},
invoicePeriod: {
frequencyOfBilling: 'Monthly',
billingPeriodStartDate: '2024-01-01',
billingPeriodEndDate: '2024-01-31'
}
});python
invoice = api('POST', '/invoices', {
'buyerId': 'buyer-uuid',
'invoiceSerialNumber': 'INV-2024-001',
'currencyCode': 'MYR',
'autoCalculate': True,
'invoiceLines': [
{
'classifications': ['001'],
'productDescription': 'Web Development Services',
'quantity': 1,
'unitCode': 'H87',
'unitPrice': 5000.00,
'invoiceLineTaxes': [
{'taxType': '01', 'taxRate': 8}
]
},
{
'classifications': ['001'],
'productDescription': 'Monthly Hosting',
'quantity': 12,
'unitCode': 'MON',
'unitPrice': 150.00,
'discountRate': 10,
'discountDescription': 'Annual discount',
'invoiceLineTaxes': [
{'taxType': '01', 'taxRate': 8}
]
}
],
'payment': {
'paymentMode': '03',
'paymentTerms': 'Net 30 days',
'supplierBankAccountNumber': '1234567890'
},
'invoicePeriod': {
'frequencyOfBilling': 'Monthly',
'billingPeriodStartDate': '2024-01-01',
'billingPeriodEndDate': '2024-01-31'
}
})php
$invoice = $api->post('/invoices', [
'buyerId' => 'buyer-uuid',
'invoiceSerialNumber' => 'INV-2024-001',
'currencyCode' => 'MYR',
'autoCalculate' => true,
'invoiceLines' => [
[
'classifications' => ['001'],
'productDescription' => 'Web Development Services',
'quantity' => 1,
'unitCode' => 'H87',
'unitPrice' => 5000.00,
'invoiceLineTaxes' => [
['taxType' => '01', 'taxRate' => 8]
]
],
[
'classifications' => ['001'],
'productDescription' => 'Monthly Hosting',
'quantity' => 12,
'unitCode' => 'MON',
'unitPrice' => 150.00,
'discountRate' => 10,
'discountDescription' => 'Annual discount',
'invoiceLineTaxes' => [
['taxType' => '01', 'taxRate' => 8]
]
]
],
'payment' => [
'paymentMode' => '03',
'paymentTerms' => 'Net 30 days',
'supplierBankAccountNumber' => '1234567890'
],
'invoicePeriod' => [
'frequencyOfBilling' => 'Monthly',
'billingPeriodStartDate' => '2024-01-01',
'billingPeriodEndDate' => '2024-01-31'
]
]);php
$response = $client->post('invoices', ['json' => [
'buyerId' => 'buyer-uuid',
'invoiceSerialNumber' => 'INV-2024-001',
'currencyCode' => 'MYR',
'autoCalculate' => true,
'invoiceLines' => [
[
'classifications' => ['001'],
'productDescription' => 'Web Development Services',
'quantity' => 1,
'unitCode' => 'H87',
'unitPrice' => 5000.00,
'invoiceLineTaxes' => [
['taxType' => '01', 'taxRate' => 8]
]
],
[
'classifications' => ['001'],
'productDescription' => 'Monthly Hosting',
'quantity' => 12,
'unitCode' => 'MON',
'unitPrice' => 150.00,
'discountRate' => 10,
'discountDescription' => 'Annual discount',
'invoiceLineTaxes' => [
['taxType' => '01', 'taxRate' => 8]
]
]
],
'payment' => [
'paymentMode' => '03',
'paymentTerms' => 'Net 30 days',
'supplierBankAccountNumber' => '1234567890'
],
'invoicePeriod' => [
'frequencyOfBilling' => 'Monthly',
'billingPeriodStartDate' => '2024-01-01',
'billingPeriodEndDate' => '2024-01-31'
]
]]);
$invoice = json_decode($response->getBody(), true);java
var json = """
{
"buyerId": "buyer-uuid",
"invoiceSerialNumber": "INV-2024-001",
"currencyCode": "MYR",
"autoCalculate": true,
"invoiceLines": [
{
"classifications": ["001"],
"productDescription": "Web Development Services",
"quantity": 1,
"unitCode": "H87",
"unitPrice": 5000.00,
"invoiceLineTaxes": [
{"taxType": "01", "taxRate": 8}
]
},
{
"classifications": ["001"],
"productDescription": "Monthly Hosting",
"quantity": 12,
"unitCode": "MON",
"unitPrice": 150.00,
"discountRate": 10,
"discountDescription": "Annual discount",
"invoiceLineTaxes": [
{"taxType": "01", "taxRate": 8}
]
}
],
"payment": {
"paymentMode": "03",
"paymentTerms": "Net 30 days",
"supplierBankAccountNumber": "1234567890"
},
"invoicePeriod": {
"frequencyOfBilling": "Monthly",
"billingPeriodStartDate": "2024-01-01",
"billingPeriodEndDate": "2024-01-31"
}
}""";
var response = api("POST", "/invoices", json);csharp
var invoice = new {
buyerId = "buyer-uuid",
invoiceSerialNumber = "INV-2024-001",
currencyCode = "MYR",
autoCalculate = true,
invoiceLines = new[] {
new {
classifications = new[] { "001" },
productDescription = "Web Development Services",
quantity = 1,
unitCode = "H87",
unitPrice = 5000.00,
invoiceLineTaxes = new[] {
new { taxType = "01", taxRate = 8 }
}
},
new {
classifications = new[] { "001" },
productDescription = "Monthly Hosting",
quantity = 12,
unitCode = "MON",
unitPrice = 150.00,
discountRate = 10,
discountDescription = "Annual discount",
invoiceLineTaxes = new[] {
new { taxType = "01", taxRate = 8 }
}
}
},
payment = new {
paymentMode = "03",
paymentTerms = "Net 30 days",
supplierBankAccountNumber = "1234567890"
},
invoicePeriod = new {
frequencyOfBilling = "Monthly",
billingPeriodStartDate = "2024-01-01",
billingPeriodEndDate = "2024-01-31"
}
};
var response = await client.PostAsJsonAsync("/invoices", invoice);Calculation Modes
Auto-Calculate (Recommended)
When autoCalculate: true, you only provide:
- Line inputs:
quantity,unitPrice,discountRate,feeOrChargeRate - Tax inputs:
taxType,taxRate
The system automatically calculates all totals:
json
{
"autoCalculate": true,
"invoiceLines": [
{
"quantity": 10,
"unitPrice": 100.00,
"discountRate": 5,
"invoiceLineTaxes": [
{ "taxType": "01", "taxRate": 8 }
]
}
]
}Calculated fields:
- Line:
totalAmount,taxableAmount,totalExcludingTaxAmount,totalTaxAmount - Tax:
taxAmount,taxableAmount - Invoice:
totalNetAmount,totalTaxAmount,payableAmount
Manual Mode
When autoCalculate: false, you must provide ALL calculated fields:
json
{
"autoCalculate": false,
"totalNetAmount": 1000.00,
"totalTaxAmount": 80.00,
"payableAmount": 1080.00,
"invoiceLines": [
{
"quantity": 2,
"unitPrice": 500.00,
"totalAmount": 1000.00,
"taxableAmount": 1000.00,
"totalExcludingTaxAmount": 1000.00,
"totalTaxAmount": 80.00,
"invoiceLineTaxes": [
{
"taxType": "01",
"taxRate": 8,
"taxAmount": 80.00,
"taxableAmount": 1000.00
}
]
}
]
}Invoice-Level Discounts and Fees
Apply discounts or fees to the entire invoice:
javascript
const invoice = await api('POST', '/invoices', {
buyerId: 'buyer-uuid',
autoCalculate: true,
invoiceDiscountAmount: 100.00,
invoiceDiscountDescription: 'Loyalty discount',
invoiceFeeAmount: 25.00,
invoiceFeeDescription: 'Processing fee',
invoiceLines: [/* ... */]
});python
invoice = api('POST', '/invoices', {
'buyerId': 'buyer-uuid',
'autoCalculate': True,
'invoiceDiscountAmount': 100.00,
'invoiceDiscountDescription': 'Loyalty discount',
'invoiceFeeAmount': 25.00,
'invoiceFeeDescription': 'Processing fee',
'invoiceLines': [# ...]
})php
$invoice = $api->post('/invoices', [
'buyerId' => 'buyer-uuid',
'autoCalculate' => true,
'invoiceDiscountAmount' => 100.00,
'invoiceDiscountDescription' => 'Loyalty discount',
'invoiceFeeAmount' => 25.00,
'invoiceFeeDescription' => 'Processing fee',
'invoiceLines' => [/* ... */]
]);php
$response = $client->post('invoices', ['json' => [
'buyerId' => 'buyer-uuid',
'autoCalculate' => true,
'invoiceDiscountAmount' => 100.00,
'invoiceDiscountDescription' => 'Loyalty discount',
'invoiceFeeAmount' => 25.00,
'invoiceFeeDescription' => 'Processing fee',
'invoiceLines' => [/* ... */]
]]);
$invoice = json_decode($response->getBody(), true);java
var json = """
{
"buyerId": "buyer-uuid",
"autoCalculate": true,
"invoiceDiscountAmount": 100.00,
"invoiceDiscountDescription": "Loyalty discount",
"invoiceFeeAmount": 25.00,
"invoiceFeeDescription": "Processing fee",
"invoiceLines": []
}""";
var response = api("POST", "/invoices", json);csharp
var invoice = new {
buyerId = "buyer-uuid",
autoCalculate = true,
invoiceDiscountAmount = 100.00,
invoiceDiscountDescription = "Loyalty discount",
invoiceFeeAmount = 25.00,
invoiceFeeDescription = "Processing fee",
invoiceLines = new object[] { /* ... */ }
};
var response = await client.PostAsJsonAsync("/invoices", invoice);Calculation Sequence
1. Sum line totals = Total Net Amount
2. Total Net - Invoice Discount + Invoice Fee = Total Excluding Tax
3. Total Excluding Tax + Tax = Total Including Tax
4. Total Including Tax + Rounding = Total PayableListing Invoices
javascript
// List all invoices
const invoices = await api('GET', '/invoices');
// With filters
const filtered = await api('GET', '/invoices?status=draft&per_page=10');python
# List all invoices
invoices = api('GET', '/invoices')
# With filters
filtered = api('GET', '/invoices?status=draft&per_page=10')php
// List all invoices
$invoices = $api->get('/invoices');
// With filters
$filtered = $api->get('/invoices', [
'status' => 'draft',
'per_page' => 10
]);php
// List all invoices
$response = $client->get('invoices');
$invoices = json_decode($response->getBody(), true);
// With filters
$response = $client->get('invoices', ['query' => [
'status' => 'draft',
'per_page' => 10
]]);
$filtered = json_decode($response->getBody(), true);java
// List all invoices
var response = api("GET", "/invoices", null);
// With filters
var filtered = api("GET", "/invoices?status=draft&per_page=10", null);csharp
// List all invoices
var response = await client.GetAsync("/invoices");
var invoices = await response.Content.ReadFromJsonAsync<JsonElement>();
// With filters
var filtered = await client.GetAsync("/invoices?status=draft&per_page=10");Available Filters
| Parameter | Type | Description |
|---|---|---|
status | string | Filter by status: draft, ready, Submitted, Valid, Invalid |
search | string | Search by invoice number |
per_page | integer | Results per page (default: 15) |
page | integer | Page number |
Updating an Invoice
WARNING
Only invoices in draft status can be updated. Once submitted, invoices become read-only.
javascript
const updated = await api('PUT', `/invoices/${invoiceId}`, {
invoiceSerialNumber: 'INV-2024-001-UPDATED',
invoiceLines: [
{
classifications: ['001'],
productDescription: 'Updated Service',
quantity: 2,
unitCode: 'H87',
unitPrice: 2500.00,
invoiceLineTaxes: [
{ taxType: '01', taxRate: 8 }
]
}
]
});python
updated = api('PUT', f'/invoices/{invoice_id}', {
'invoiceSerialNumber': 'INV-2024-001-UPDATED',
'invoiceLines': [
{
'classifications': ['001'],
'productDescription': 'Updated Service',
'quantity': 2,
'unitCode': 'H87',
'unitPrice': 2500.00,
'invoiceLineTaxes': [
{'taxType': '01', 'taxRate': 8}
]
}
]
})php
$updated = $api->put("/invoices/$invoiceId", [
'invoiceSerialNumber' => 'INV-2024-001-UPDATED',
'invoiceLines' => [
[
'classifications' => ['001'],
'productDescription' => 'Updated Service',
'quantity' => 2,
'unitCode' => 'H87',
'unitPrice' => 2500.00,
'invoiceLineTaxes' => [
['taxType' => '01', 'taxRate' => 8]
]
]
]
]);php
$response = $client->put("invoices/$invoiceId", ['json' => [
'invoiceSerialNumber' => 'INV-2024-001-UPDATED',
'invoiceLines' => [
[
'classifications' => ['001'],
'productDescription' => 'Updated Service',
'quantity' => 2,
'unitCode' => 'H87',
'unitPrice' => 2500.00,
'invoiceLineTaxes' => [
['taxType' => '01', 'taxRate' => 8]
]
]
]
]]);
$updated = json_decode($response->getBody(), true);java
var json = """
{
"invoiceSerialNumber": "INV-2024-001-UPDATED",
"invoiceLines": [
{
"classifications": ["001"],
"productDescription": "Updated Service",
"quantity": 2,
"unitCode": "H87",
"unitPrice": 2500.00,
"invoiceLineTaxes": [
{"taxType": "01", "taxRate": 8}
]
}
]
}""";
var response = api("PUT", "/invoices/" + invoiceId, json);csharp
var update = new {
invoiceSerialNumber = "INV-2024-001-UPDATED",
invoiceLines = new[] {
new {
classifications = new[] { "001" },
productDescription = "Updated Service",
quantity = 2,
unitCode = "H87",
unitPrice = 2500.00,
invoiceLineTaxes = new[] {
new { taxType = "01", taxRate = 8 }
}
}
}
};
var response = await client.PutAsJsonAsync($"/invoices/{invoiceId}", update);Deleting an Invoice
WARNING
Only invoices in draft status can be deleted.
javascript
await api('DELETE', `/invoices/${invoiceId}`);python
api('DELETE', f'/invoices/{invoice_id}')php
$api->delete("/invoices/$invoiceId");php
$client->delete("invoices/$invoiceId");java
api("DELETE", "/invoices/" + invoiceId, null);csharp
await client.DeleteAsync($"/invoices/{invoiceId}");Invoice Fields Reference
Invoice-Level Fields
| Field | Type | Required | Description |
|---|---|---|---|
buyerId | string (UUID) | Yes | UUID of the buyer |
invoiceSerialNumber | string | No | Custom invoice number (max 50 chars) |
currencyCode | string | No | Currency code (default: MYR) |
exchangeRate | number | No | Exchange rate for foreign currencies |
autoCalculate | boolean | No | Auto-calculate totals (default: true) |
erpIssuedAt | datetime | No | Original issue date from ERP |
invoiceLines | array | No | Array of line items |
payment | object | No | Payment information |
delivery | object | No | Delivery information |
invoicePeriod | object | No | Billing period |
Invoice Line Fields
| Field | Type | Required | Description |
|---|---|---|---|
classifications | array | Yes | Product classification codes |
productDescription | string | Yes | Item description |
quantity | number | Yes | Quantity |
unitCode | string | Yes | Unit of measurement code |
unitPrice | number | Yes | Price per unit |
invoiceLineTaxes | array | Yes | Tax information (min 1) |
discountRate | number | No | Discount percentage (0-100) |
discountAmount | number | No | Fixed discount amount |
discountDescription | string | No | Discount description |
feeOrChargeRate | number | No | Fee percentage (0-100) |
feeOrChargeAmount | number | No | Fixed fee amount |
feeOrChargeDescription | string | No | Fee description |
Tax Fields
| Field | Type | Required | Description |
|---|---|---|---|
taxType | string | Yes | Tax type code (01, 02, E, etc.) |
taxRate | number | No | Tax rate percentage |
taxAmount | number | No | Tax amount (auto-calculated) |
Payment Fields
| Field | Type | Description |
|---|---|---|
paymentMode | string | 01=Cash, 02=Cheque, 03=Bank Transfer |
supplierBankAccountNumber | string | Bank account number |
paymentTerms | string | Payment terms description |
prepaymentAmount | number | Prepayment amount |
prepaymentDate | date | Prepayment date |
prepaymentReferenceNumber | string | Prepayment reference |
Invoice Statuses
| Status | Description |
|---|---|
draft | Initial state, can be edited |
ready | Validated, ready for submission |
Submitted | Sent to LHDN, awaiting validation |
Valid | Accepted by LHDN |
Invalid | Rejected by LHDN |
Next Steps
- Validation - Validate invoices before submission
- Submission - Submit to LHDN
- Document Types - Credit notes, debit notes, etc.
