# Malaysia v2: Create Receipt API

Create receipts for high-volume B2C sales and consolidate them into one e-invoice later, in the Malaysia LHDN API v2 (legacy): endpoint, headers, request fields, responses and code examples.

> **Legacy API v2**
>
> This page documents API v2 for Malaysia, which is no longer developed. Start new integrations on the current API: see the [Unify API reference](https://docs.complyance.io/api-reference/unify/) and the [Malaysia guide](https://docs.complyance.io/countries/my/).

The Create Receipt API is for cases where issuing an e-invoice for every transaction is not practical, such as **B2C (business-to-consumer)** sales in supermarkets, retail stores and other high-volume businesses.

In a B2C flow, individual consumers make frequent, small purchases and usually do not need an e-invoice at the point of sale. A supermarket may serve thousands of customers a day, and an e-invoice for each sale would be impractical.

Instead, you issue **receipts** to customers during the day. A receipt is the customer’s proof of purchase, and you do not send each one to the tax authority straight away.

At the end of the day, or another period, the receipts are consolidated into a **single e-invoice** that summarizes all the transactions in that period. That e-invoice goes to the tax authority to meet the compliance requirements.

This approach:

1. **Saves work**: you do not generate and submit an e-invoice for every B2C sale. Receipts are created at once, and the e-invoice is generated in bulk later.
2. **Keeps you compliant**: a consolidated e-invoice at the end of each day, or another interval, meets the legal requirements.
3. **Keeps checkout fast**: customers get their receipt at checkout.

It suits businesses with a **high volume of low-value transactions**.

You create a receipt by sending its data as JSON in a `POST` request.

## Document types

| Code | Document | Value to send |
| - | - | - |
| 01 | Invoice | `INV` |
| 02 | Credit Note | `CRD` |

## Endpoint

| Environment | Host |
| - | - |
| Sandbox | `https://malaysia-sandbox.complyance.io` |
| Production | `https://malaysia-prod.complyance.io` |

```http title="Create a receipt"
POST https://malaysia-sandbox.complyance.io/createReciept
POST https://malaysia-prod.complyance.io/createReciept
```

The path is spelled `createReciept`.

## Headers

| Header | Value | Description | Conditionality |
| - | - | - | - |
| `x-api-key` | `your-api-key` | API key that authorizes the request | Mandatory |
| `Content-Type` | `application/json` | Says the request body is JSON | Optional |

## Code examples

These examples show the endpoint and headers. Send the [request body](https://docs.complyance.io/legacy/v2/malaysia/api-create-receipt/#request-body) as JSON.

**Shell**

```bash
curl --location 'https://malaysia-prod.complyance.io/createReciept' \
--header 'x-api-key: your-api-key' \
--header 'Content-Type: application/json'
```

**JavaScript**

```javascript
const headers = {
  'x-api-key': 'your-api-key',
  'Content-Type': 'application/json'
};

fetch('https://malaysia-prod.complyance.io/createReciept', {
  method: 'POST',
  headers: headers
})
.then(function(response) {
    return response.json();
}).then(function(body) {
    console.log(body);
});
```

**Ruby**

```ruby
require 'rest-client'

headers = {
  'x-api-key' => 'your-api-key',
  'Content-Type' => 'application/json'
}

response = RestClient.post 'https://malaysia-sandbox.complyance.io/createReciept', {}, headers

puts response.body
```

**Python**

```python
import requests

headers = {
  'x-api-key': 'your-api-key',
  'Content-Type': 'application/json'
}

response = requests.post('https://malaysia-prod.complyance.io/createReciept', headers=headers)
print(response.json())
```

**PHP**

```php
<?php

$headers = [
    'x-api-key' => 'your-api-key',
    'Content-Type' => 'application/json'
];

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://malaysia-prod.complyance.io/createReciept', [
    'headers' => $headers
]);

echo $response->getBody()->getContents();
?>
```

**Java**

```java
URL url = new URL("https://malaysia-prod.complyance.io/createReciept");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("x-api-key", "your-api-key");
con.setRequestProperty("Content-Type", "application/json");

int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();

while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());
```

**Go**

```go
package main

import (
	"net/http"
)

func main() {
	headers := map[string][]string{
		"x-api-key":    []string{"your-api-key"},
		"Content-Type": []string{"application/json"},
	}

	req, err := http.NewRequest("POST", "https://malaysia-prod.complyance.io/createReciept", nil)
	if err != nil {
		// Handle error
	}

	for key, values := range headers {
		for _, value := range values {
			req.Header.Add(key, value)
		}
	}

	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		// Handle error
	}
	defer resp.Body.Close()
}
```

## Request body

Send the receipts as a JSON array in `receiptDataList`. Each receipt number must be unique.

```json title="Request body"
{
    "receiptDataList": [
        {
            "documentType": "INV",
            "recieptNumber": "RCPT-2025-0001",
            "mobileNumber": "60123456789",
            "originalEInvoiceReferenceNumber": "",
            "recieptIssueDate": "2025-01-07",
            "documentIssueTime": "22:30:00Z",
            "typeOfBuyer": "BUSINESS",
            "currency": "MYR",
            "currencyExchangeRate": "",
            "supplierId": "",
            "sellerTinNumber": "C20000000000",
            "sellerRegistrationIdType": "BRN",
            "sellerRegistrationId": "202001234567",
            "supplierSstRegistrationNumber": "",
            "supplierTourismTaxRegistrationNumber": "",
            "buyerId": "",
            "buyerTinNumber": "",
            "buyerRegistrationIdType": "",
            "buyerRegistrationId": "",
            "buyerSstRegistrationNumber": "",
            "isShippingAndBuyerAddressSame": true,
            "shippingRecipientName": "",
            "shippingRecipientTin": "",
            "shippingRecipientRegistrationType": "",
            "shippingRecipientRegistrationNumber": "",
            "totalExcludingTax": "700",
            "taxTotal": "0",
            "documentTotal": "700",
            "invoiceAmountExemptedFromTax": "0",
            "invoiceTaxExemptionReason": "Goods acquired with SST exemption under Sales Tax Act 2018. Reference No: (C01-2345-67890123)",
            "invoiceAdditionalDiscountAmount": "0",
            "invoiceAdditionalChargeAmount": "00",
            "totalPayableAmount": "700",
            "paymentMeans": "07",
            "sellerAddress": {
                "addressLine1": "Lot 66",
                "addressLine2": "Bangunan Merdeka",
                "addressLine3": "Persiaran Jaya",
                "postalCode": "",
                "city": "Kuala Lumpur",
                "state": "08",
                "country": "MYS"
            },
            "buyerAddress": {
                "addressLine1": "",
                "addressLine2": "",
                "addressLine3": "",
                "postalCode": "",
                "city": "",
                "state": "",
                "country": ""
            },
            "shippingRecipientAddress": {
                "addressLine1": "",
                "addressLine2": " ",
                "addressLine3": " ",
                "postalCode": "",
                "city": "",
                "state": "",
                "country": ""
            },
            "supplierDetails": {
                "organizationName": "Acme Trading Sdn Bhd",
                "email": "finance@acme.example",
                "industryCode": "01111",
                "industryDescription": "Growing of maize",
                "phoneNumber": "60123456789"
            },
            "buyerDetails": {
                "organizationName": "",
                "email": "",
                "phoneNumber": ""
            },
            "documentLineItems": [
                {
                    "lineItemId": "1",
                    "commodityClassificationCode": "10",
                    "description": "Laptop peripherals",
                    "unitPrice": "100",
                    "quantity": "7",
                    "lineItemSubtotal": "700",
                    "discountPercent": "0",
                    "discountAmount": "0",
                    "chargePercent": "0",
                    "chargeAmount": "0",
                    "lineTotalExcludingTax": "700",
                    "taxType": "06",
                    "taxPercentage": "0",
                    "totalTax": "0",
                    "taxExemptionReason": "Goods acquired with SST exemption under Sales Tax Act 2018. Reference No: (C01-2345-67890123)",
                    "amountExemptedFromTax": "0",
                    "lineItemTotal": "700"
                }
            ]
        }
    ]
}
```

## Request fields

### Receipt details

Each field below belongs to an object in `receiptDataList`.

| Field name | Conditionality | Description | Max length |
| - | - | - | - |
| `documentType` | Mandatory | The document type (for example `INV`, `CRD`, `DBT`, `RFD`, `SLF_INV`, `SLF_CRD`, `SLF_DBT`, `SLF_REF`). | 3 to 7 |
| `recieptNumber` | Mandatory | Receipt reference number for internal tracking. Example: `test6`. | 50 |
| `recieptIssuedate` | Mandatory | Date the receipt is issued. Must be the current date. Format: yyyy-mm-dd. | 10 |
| `mobileNumber` | Optional | Mobile number used to convert the receipt to an e-invoice. Example: `+60123456789`. | 15 |
| `originalEInvoiceReferenceNumber` | Mandatory where applicable | LHDNM unique identifier number of the original invoice or document being adjusted. | 26 |
| `documentIssueDate` | Mandatory | Date the e-invoice is issued. Must be the current date. | 10 (format: yyyy-mm-dd) |
| `typeOfBuyer` | Mandatory | The type of buyer: `BUSINESS` for business entities or `INDIVIDUAL` for personal customers. | |
| `documentIssueTime` | Mandatory | Time the e-invoice is issued. Must be UTC time. | 15 (format: hh:mm:ss) |
| `currency` | Mandatory | The currency of the monetary values in the e-invoice. | 3 |
| `sellerTinNumber` | Mandatory | Supplier’s TIN, assigned by LHDNM. | 14 |
| `sellerRegistrationIdType` | Mandatory | Supplier’s registration, identification or passport number type. | |
| `sellerRegistrationId` | Mandatory | For businesses: business registration number. For Malaysian individuals: MyKad or MyTentera identification number. For non-Malaysian individuals: passport number, MyPR or MyKAS identification number. MyPR and MyKAS use the NRIC scheme. | |
| `supplierSstRegistrationNumber` | Mandatory where applicable | Supplier’s SST registration number. Not applicable to suppliers that are not SST-registered. Only the special characters dash (-) and semicolon (;) are allowed. Up to 2 SST numbers, separated by a semicolon. Enter “NA” if not SST-registered. | 35 |
| `supplierTourismTaxRegistrationNumber` | Mandatory where applicable | Supplier’s tourism tax registration number. Only applies to registrants such as hotel operators. Only the special character dash (-) is allowed. Enter “NA” if not registered. | 17 |
| `totalExcludingTax` | Mandatory | Sum of the amount payable, excluding taxes. Attach the currencyID attribute to the XML element. | |
| `taxTotal` | Mandatory | Total amount of tax payable. | |
| `documentTotal` | Mandatory | Invoice total amount including tax. | |
| `totalPayableAmount` | Mandatory | Sum of the amount payable, including taxes and adjustments, excluding advance payments. Attach the currencyID attribute to the XML element. | |
| `paymentMeans` | Optional | How funds are transferred (for example cash, cheque, bank transfer, credit card, e-wallet). | 2 |

## Response fields

| Parameter name | Type | Length | Description |
| - | - | - | - |
| `submissionUid` | string | NA | The number LHDN generates as the official identifier for a submission. |
| `documentUlid` | string | | The number Complyance generates for the document, for tracking. |
| `uuid` | string | | Government acknowledgement number for the invoice sent to LHDN. |
| `invoiceCodeNumber` | string | | Document reference number the supplier uses for internal tracking. |

## Response

### Success response

When the receipt is created, the API returns a success message.

```json title="Response"
{
    "message": "Receipt saved successfully",
    "data": null
}
```

### Error response

When something goes wrong, the API returns an error message. This example is for a receipt number that was already used.

```json title="Error response"
{
    "errorMessages": null,
    "errorsList": null,
    "batchId": null,
    "errorCode": "409",
    "success": true,
    "valid": true,
    "errors": [
        {
            "code": "E-RCPT-409",
            "message": "RecieptNumber Random number -02 is already available with the status CREATED",
            "location": "receiptDataList[0].recieptNumber",
            "suggestion": "Use a different receipt number that hasn't been used before",
            "affectedFields": [
                "recieptNumber"
            ]
        }
    ],
    "metadata": {
        "validationTime": "2025-06-03T09:43:25.569727Z[UTC]",
        "totalErrors": 1
    }
}
```

### Status codes

| Status code | Description |
| - | - |
| `200` | Success: the request was processed. |
| `202` | Accepted: the request was accepted and is still processing. |

## Notes

- The `x-api-key` must be valid, or the request fails with an authentication error.
- Check that all required fields are formatted correctly, especially dates and tax information.

Source: https://docs.complyance.io/legacy/v2/malaysia/api-create-receipt/
