TrustBill
Integration GuideOctober 2026
Oracle logoOracle NetSuite

Oracle NetSuite · Integration guide

Oracle NetSuite → UAE FTA E-Invoicing with TrustBill

Written for your NetSuite administrator, developer or implementation partner. It compares the three ways to connect NetSuite to the UAE e-invoicing network through TrustBill, shows exactly what to configure in NetSuite, and lists who owns each task, so nothing is left to discover in UAT.

0. Terms used in this guide

1. Overview: what TrustBill delivers for NetSuite

Oracle NetSuite is a cloud-only product. It calculates VAT and issues invoices, but it does not produce PINT-AE documents and cannot deliver them to the FTA through the Peppol network. TrustBill sits between NetSuite and the FTA: it takes your sales invoices and credit memos, validates them against the FTA business rules, converts them to PINT-AE, submits them through an FTA-accredited ASP, and returns the FTA UUID and status.

  • No SuiteApp is required for the CSV route, and none for the script route either: any scripts live in your own account.
  • Your invoice numbering, workflows and templates stay as they are.
  • Scope is accounts-receivable documents only: sales invoices and credit memos. Payables, general ledger, payroll and inventory are out of scope.
  • All three options use the same TrustBill validation and the same accredited ASP. Only the trigger and the status write-back differ, so you can start simple and move up later.
Availability today: Options A and B work now. Option C, a native TrustBill connector that pulls from NetSuite, is scoped per customer on request. We do not describe it as generally available.

2. The three connection options

Not sure which one fits? Answer the short NetSuite questionnaire and we reply with a recommendation, timeline and price. Pricing for all ERP integrations is published on the ERP integration pricing page.

3. Option A: Saved Search export and bulk upload

  1. Make sure every UAE customer has a 15-digit TRN stored in a customer field (see the field mapping section).
  2. Create a Saved Search of type Transaction. Criteria: Type is Invoice or Credit Memo, Posting is true, and a date range you control.
  3. Add the result columns listed below.
  4. Export to CSV or Excel, or schedule the search to be emailed to you.
  5. Upload the file in TrustBill bulk upload. Map the columns once; TrustBill remembers the mapping.
  6. Review the validation results. Fix any rejected row in NetSuite, never in the exported file, so the two stay in sync.
  • Document Number, Date, Due Date, Document Type (Invoice or Credit Memo).
  • Customer name and the field that holds the customer TRN.
  • Currency and Exchange Rate.
  • Item or line description, Quantity, Rate (excluding tax).
  • Tax Code, Tax Amount and Gross Amount per line.
  • Created From, for credit memos: the original invoice number.
A credit memo must reference its parent invoice. Create credit memos from the invoice (Actions, Credit) so Created From is populated, not as standalone records.

4. Option B: push from NetSuite to the TrustBill Partner API

NetSuite, or your integration platform, sends each approved invoice to TrustBill. TrustBill validates and submits it, then calls you back with the result.

NetSuite invoice approved
      |
      v
Script or iPaaS flow --- POST /v1/partner/invoices ---> TrustBill Partner API
      ^                                                      |
      |                                          validate, PINT-AE, ASP, FTA
      |                                                      |
      +------- signed webhook: invoice.status_changed <------+
              (FTA UUID + status written to the invoice)
  1. Create custom transaction body fields on the invoice and credit memo: FTA status, FTA UUID and reject reason (for example custbody_tb_fta_status, custbody_tb_fta_uuid, custbody_tb_reject_reason).
  2. Make sure the customer TRN field and each subsidiary's tax registration number are populated.
  3. TrustBill issues a sandbox key pair and a per-legal-entity secret. Store them in NetSuite API Secrets, not in script source or script parameters.
  4. Build the outbound flow: pick up approved invoices not yet sent, map them (see the mapping tables), POST with an Idempotency-Key.
  5. Build the inbound flow: receive the signed webhook, verify the signature, and write the UUID and status back to the invoice.
  6. Run UAT in the sandbox, then switch to live credentials.

A starting skeleton for the outbound script (SuiteScript 2.1). It is a sketch to show the shape, not production code:

/**
 * @NApiVersion 2.1
 * @NScriptType ScheduledScript
 */
define(['N/https', 'N/search'], (https, search) => {
  const execute = () => {
    // 1. Find approved invoices where custbody_tb_fta_status is empty.
    // 2. For each one, build the payload (see the field mapping table).
    // 3. POST it. Use the invoice internal ID as the Idempotency-Key.
    const response = https.post({
      url: 'https://api.trustbill.ae/v1/partner/invoices',
      headers: {
        'Content-Type': 'application/json',
        'X-API-Key': '<from NetSuite API Secrets>',
        'X-API-Secret': '<from NetSuite API Secrets>',
        'x-erp-partner-secret': '<per legal entity>',
        'Idempotency-Key': 'netsuite-inv-' + invoiceInternalId
      },
      body: JSON.stringify(payload)
    });
    // 4. 202 = queued. Keep the invoice marked "sent" so it is not re-sent.
  };
  return { execute };
});
Prefer a Scheduled or Map/Reduce script over an inline callout from a User Event script. An outage or slow response on the other side must never block someone from saving an invoice in NetSuite.

5. Authentication

The Partner API uses two layers. The partner credential proves the caller is a known integrator; the per-entity secret proves this push belongs to the legal entity named on the invoice. All writes need both.

The seller TRN in the body is checked against the entity resolved from x-erp-partner-secret. A mismatch is rejected with 403 trn_mismatch before anything is processed. In OneWorld accounts this protects you from a script that picks the wrong subsidiary.

For the native connector (Option C) the direction reverses: you create a least-privilege integration role in NetSuite and an OAuth 2.0 or token-based credential, and we ask you to share it during a secure remote session. Never send passwords or tokens by email or through a web form.

6. Payload: what NetSuite sends

A minimal sales invoice. The full schema, including credit notes and debit notes, is published at https://api.trustbill.ae/v1/partner/openapi.json.

POST /v1/partner/invoices HTTP/1.1
Host: api.trustbill.ae
Content-Type: application/json
X-API-Key: tbp_live_...
X-API-Secret: tbs_live_...
x-erp-partner-secret: ers_live_...
Idempotency-Key: netsuite-inv-48213

{
  "documentType": "tax_invoice",
  "externalRef": "INV-2026-00042",
  "issueDate": "2026-10-31",
  "dueDate": "2026-11-30",
  "currency": "AED",
  "seller": { "trn": "100123456700003", "legalName": "Acme Trading L.L.C" },
  "buyer":  { "trn": "100987654300003", "legalName": "Beta Distribution F.Z.E" },
  "lines": [
    { "description": "Industrial pump, model X9", "quantity": 2,
      "unitPrice": 1500.00, "taxCategory": "S", "taxRate": 5 }
  ],
  "totals": { "netAmount": 3000.00, "taxAmount": 150.00, "grossAmount": 3150.00 },
  "indicators": { "freeZone": false, "reverseCharge": false, "export": false }
}

A successful call returns 202 Accepted with the TrustBill invoice ID and status: "queued". The webhook is the authoritative channel for the final FTA result.

7. NetSuite field mapping

Use this table as the acceptance criterion for the mapping. Field IDs shown are standard NetSuite fields; fields starting custentity_ or custbody_ are examples, because every account names its custom fields differently.

8. Tax code mapping

Whether you use SuiteTax or classic tax codes, each code you apply to a UAE sales line must map to one PINT-AE VAT category. Code names differ per account; the logic does not.

An unmapped tax code is the most common reason a first invoice fails. Settle the mapping with your tax adviser before UAT, and set it once in TrustBill Settings, Tax Mapping.

9. OneWorld, subsidiaries and multiple TRNs

10. Status webhooks back to NetSuite

When an invoice reaches a final state, TrustBill sends one invoice.status_changed event to the URL you registered. Deliveries are signed and retried.

POST /your-endpoint HTTP/1.1
Content-Type: application/json
X-Webhook-Timestamp: 1761900000
X-Webhook-Signature: t=1761900000,v1=4e9c3d...hex...

{
  "event": "invoice.status_changed",
  "payload": {
    "invoiceId": "inv_01HZ...",
    "externalRef": "INV-2026-00042",
    "status": "delivered",
    "ftaUuid": "f1b8c7e2-9d4a-4b11-9c38-7c7a3a9c0e8b"
  }
}
  1. Read X-Webhook-Timestamp and extract v1 from X-Webhook-Signature.
  2. Reject the request if the timestamp is more than 300 seconds from now.
  3. Compute HMAC-SHA256 of timestamp.raw_body with your webhook secret and compare in constant time.
  4. Only then parse the body and write ftaUuid and status to the invoice custom fields.

In NetSuite you can receive the webhook in an externally available Suitelet (verify the HMAC with the N/crypto module), or let your integration platform receive it and update the invoice through REST. Retries follow 30 seconds, 2 minutes, 10 minutes, 30 minutes, 1 hour and 3 hours. Errors are RFC 7807 problem documents: branch on the stable type value, not the HTTP status alone.

11. UAT and go-live checklist

  • In the sandbox, the reserved test TRN 100000000000000 always accepts and fires a real webhook; 100000000000666 always rejects.
  • Confirm the webhook signature check works before going live.
  • Switch to live credentials, then ramp traffic over the first two days.

12. Who owns what

Need Oracle NetSuite connected to FTA e-invoicing?

Answer a short questionnaire (about 5 minutes). We review your setup and reply by email with the integration plan, timeline and price.

Request Oracle NetSuite integration

Frequently asked questions

Is Oracle NetSuite cloud or on-premise?

NetSuite is cloud-only (SaaS). The on-premise Oracle products are E-Business Suite and JD Edwards, which are integrated differently. Oracle Fusion Cloud ERP is also cloud but is a separate, larger product with its own guide.

Does TrustBill have a native NetSuite connector?

Not as a generally available product today. You can connect now with Option A (export and upload) or Option B (push through a script or integration platform). A native connector that pulls from NetSuite is scoped per customer on request.

Do I need to install a SuiteApp?

No. Option A needs nothing installed. Option B uses scripts or flows that run in your own account and are deployed by your administrator or NetSuite partner.

Where is the customer TRN stored in NetSuite?

Either in the customer's tax registration field or in a custom field your team created. It must be 15 digits. The questionnaire asks where you keep it so we can map it.

We use OneWorld with several subsidiaries. Is that a problem?

No. Each subsidiary that holds a UAE TRN becomes its own TrustBill legal entity with its own secret. Your flow picks the right one by subsidiary.

Does NetSuite already support UAE e-invoicing?

NetSuite calculates VAT and issues invoices. Delivering PINT-AE invoices to the FTA network through an accredited ASP is a separate step, which is what TrustBill does. Oracle may release localisation updates, so ask your NetSuite partner what is installed in your account.

What happens when an invoice is rejected?

The webhook returns status rejected with a reason, which you can write to a field on the invoice. Fix the cause in NetSuite and resubmit, or issue a credit memo where the rules require one.

How long does it take and what does it cost?

Option A can start the same day. Option B typically takes one to two weeks of NetSuite developer time. Option C is scoped after the questionnaire. Prices are on the ERP integration pricing page.

Is it secure?

Calls use HTTPS with a key pair plus a per-entity secret. Webhooks are HMAC-signed with a replay window. In NetSuite we ask only for a least-privilege integration role. We never ask for passwords through the form.

Related guides