Suite Utils
Back to Blog
SuiteScriptJul 26, 2026 • 5 min read

Automate NetSuite Invoice Entry from WhatsApp PDF Files

Receiving invoices via WhatsApp presents a unique logistical challenge. While it may seem like an unconventional communication channel for accounts payable, the technical hurdle lies in bridging a mes…

Arav SharmaArav SharmaCore SuiteScript & Integration Engineer
Automate NetSuite Invoice Entry from WhatsApp PDF Files
Photo by Microsoft 365 on Unsplash

Receiving invoices via WhatsApp presents a unique logistical challenge. While it may seem like an unconventional communication channel for accounts payable, the technical hurdle lies in bridging a messaging platform, which lacks native file-handling structures for ERPs, with NetSuite’s structured data requirements.

The core problem is not just "getting the file," but extracting the data from that file and ensuring it correctly populates NetSuite records. To automate this, you must bridge the gap between a messaging API (WhatsApp Business Platform), a file storage/parsing layer, and NetSuite’s SuiteScripting engine.

The Architecture of the Solution

To automate this workflow, you cannot rely on a single "out-of-the-box" NetSuite feature. Instead, you must build or configure a pipeline that handles three distinct stages: Ingestion, Extraction, and Persistence.

1. Ingestion: The WhatsApp Business API

Because WhatsApp does not provide a standard "email-style" inbox, you must use the WhatsApp Business Platform (API). This allows you to receive messages and media (PDFs) programmatically. Unlike a standard message, a PDF sent via WhatsApp is received as a media object. You must first request the media content URL, then download the binary data. This is a critical step because the message body itself does not contain the file content; it only contains a pointer to the media.

2. Extraction: Parsing the PDF

Once the file is downloaded, you need to extract data points like vendor, amount, item_description, and due_date. Since these are PDFs, simple string scraping is often insufficient. You typically need an OCR (Optical Character Recognition) or a Document AI service to extract these fields into a JSON object.

3. Persistence: NetSuite Record Creation

Once you have the data in a structured JSON format, you can use SuiteScript to create the vendorbill or invoice records. This is where you map the extracted JSON keys to the specific NetSuite internal IDs.

Technical Implementation via SuiteScript 2.1

To handle the data entry, you will interact with the N/record module. When creating a vendor bill from an invoice, you need to ensure that the correct fields are populated accurately.

Here is a technical example of how to programmatically create a vendorbill record using the data extracted from your PDF. Note that we use the correct module methods and ensure the syntax follows SuiteScript 2.1 standards.

/**
 * @NApiVersion 2.1
 * @NScriptType Suitelet
 */
define(['N/record', 'N/log', 'N/error'], (record, log, error) => {
    /**
     * Example function to create a Vendor Bill from extracted PDF data.
     * This would be triggered by an external API call (e.g., from a 
     * middleware or a Webhook receiving the parsed JSON).
     */
    const createVendorBill = (data) => {
        try {
            // Create the Vendor Bill record
            // Note: isLookup is not a valid parameter for record.create()
            const billRec = record.create({
                type: record.Type.VENDOR_BILL
            });

            // Set Header Fields
            // 'entity' is the standard field for Vendor/Customer
            billRec.setValue({ fieldId: 'entity', value: data.vendor_id });
            billRec.setValue({ fieldId: 'trandate', value: data.invoice_date });
            billRec.setValue({ fieldId: 'amount', value: data.total_amount });
            billRec.setValue({ fieldId: 'memo', value: `Invoice: ${data.invoice_number}` });

            // Set Line Item Details
            // Note: 'item' is the sublist ID for line items
            billRec.setSublistValue({
                sublistId: 'item',
                fieldId: 'item',
                line: 0,
                value: data.item_id
            });

            billRec.setSublistValue({
                sublistId: 'item',
                fieldId: 'quantity',
                line: 0,
                value: data.quantity
            });

            billRec.setSublistValue({
                sublistId: 'item',
                fieldId: 'rate',
                line: 0,
                value: data.unit_price
            });

            // Save the record
            // record.save() returns the internal ID of the newly created record
            const billId = record.save();
            log.audit({ title: 'Success', details: `Created Vendor Bill ID: ${billId}` });
            return billId;

        } catch (e) {
            log.error({ title: 'Error Creating Bill', details: e.toString() });
            throw e;
        }
    };

    // Example data object mimicking a parsed PDF result
    const mockData = {
        vendor_id: '12345', // Internal ID of the Vendor record
        invoice_date: '2023-10-01',
        total_amount: 500.00,
        item_id: '67890', // Internal ID of the Item record
        quantity: 1,
        unit_price: 500.00
    };

    // In a real scenario, this would be triggered by a Request/Response cycle
    // For demonstration, we call the function directly.
    // createVendorBill(mockData);

    return {
        onRequest: (requestContext) => {
            // Logic to handle incoming request would go here
        }
    };
});

Step-by-Step Workflow Configuration

If you are looking for a "no-code" or "low-code" approach to handle the flow, follow this architectural path:

Step 1: The Webhook Receiver

Set up a listener (using a service like Make.com, Zapier, or a custom Node.js server). This listener receives the WhatsApp Webhook.

  • Action: Capture the media_id from the WhatsApp message.
  • Action: Call the WhatsApp API to download the file content.

Step 2: The Document Processing Layer

Pass the binary PDF data to a document processing API. This step is critical because it converts "unstructured" visual data into "structured" JSON.

  • Input: PDF File.

Step 3: The NetSuite Integration

Use a SuiteScript Restlet to receive the JSON from your processing layer. A Restlet is ideal here because it provides a clean endpoint for external systems to "push" data into NetSuite. You can refer to the SuiteScript Developer Guide for detailed information on handling request bodies and response types.

| Component | Responsibility | Tool/Method | |:--- | | | | WhatsApp Business API | Receives the PDF file from the user. | Webhook / Media Download | | Document AI | Extracts text and fields from the PDF. | OCR / Machine Learning API | | Restlet | Receives JSON and creates the record. | N/record Module | | NetSuite | Stores the final Vendor Bill. | vendorbill Record Type |

Handling Edge Cases and Validation

When automating invoice entry, you must account for data integrity. A common issue is receiving a PDF that contains multiple line items or requires specific tax calculations.

  1. Validation: Before calling record.save(), ensure the entity (Vendor) and item IDs exist in your NetSuite account. If a vendor is not found, the script will throw an error.
  2. Duplicate Checking: You should check if a line item or invoice number already exists to prevent duplicate payments.
  3. Permissions: Ensure the Integration Role assigned to the Restlet has "Create" permissions for vendorbill and "Full" permissions for the relevant items.

When building these integrations, it is vital to understand how NetSuite handles record creation via external requests. For more information on interacting with records, refer to the SuiteTalk REST Web Services API Guide.

Automating the flow from WhatsApp to NetSuite comes down to treating it as a multi-stage pipeline: the WhatsApp Business API handles ingestion, an OCR or Document AI service extracts the data, and a SuiteScript Restlet creates the vendorbill record. Get those three stages talking to each other cleanly and you cut out manual entry errors and speed up the accounts payable cycle.

About the author

Put these ideas to work.

Suite Utils builds small NetSuite tools that fix the specific thing breaking your day. Each one runs as a native SuiteScript SuiteApp inside your account. No sales call, no onboarding.

Browse the Tools

Enjoyed this one?

Get NetSuite tips like this in your inbox. No spam. Practical guides only.

Keep reading