Oracle NetSuiteOracle 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
| Term | Meaning |
|---|---|
| SuiteScript | NetSuite's JavaScript scripting layer (we assume version 2.1) for custom logic that runs inside your account. |
| User Event / Scheduled / Map-Reduce | Script types that run when a record is saved, on a timer, or over large batches of records. |
| Suitelet / RESTlet | Custom HTTP endpoints hosted inside NetSuite. A Suitelet can be made externally available; a RESTlet always requires authentication. |
| SuiteQL | SQL-like query language exposed through NetSuite's REST web services. |
| TBA / OAuth 2.0 | The two authentication methods NetSuite supports for integrations: token-based authentication and OAuth 2.0. |
| OneWorld | The NetSuite edition with multiple subsidiaries. In the UAE, one subsidiary normally equals one TRN. |
| SuiteTax | NetSuite's tax engine. Accounts without it use classic tax codes. |
| Saved Search | NetSuite's query and reporting tool. Results can be exported to CSV or Excel. |
| TRN | UAE Tax Registration Number: 15 digits. |
| PINT-AE | The UAE e-invoicing format, based on Peppol. TrustBill converts your invoices into it. |
| ASP | FTA-accredited Service Provider. TrustBill submits through Microvista Technologies LLC, an FTA-accredited ASP. |
| Partner API | TrustBill's REST surface at https://api.trustbill.ae/v1/partner/*. |
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.
2. The three connection options
Pick the option that matches your volume and how much change your NetSuite team can take on
| A. Export and upload | B. Push from NetSuite | C. Native pull connector | |
|---|---|---|---|
| How it works | Export posted invoices from a Saved Search to CSV or Excel and upload them in TrustBill bulk upload. | A script in your account, or your integration platform (Celigo, Boomi, Workato and similar), sends each invoice to the TrustBill Partner API. A signed webhook returns the FTA UUID. | TrustBill reads invoices from NetSuite through REST web services and SuiteQL using OAuth 2.0 or TBA, and writes status back. |
| Status | Available today | Available today (Partner API is live) | Scoped per customer, on request |
| Your effort | A few hours once, then a daily or weekly export. | Typically one to two weeks of NetSuite developer or partner time. | Integration role and credentials, plus a field-mapping workshop. |
| TrustBill effort | None. | Issue credentials, provide a sandbox, support UAT. | Build and test the connector for your account. |
| FTA UUID back in NetSuite | Manual: copy from the TrustBill dashboard or export. | Automatic through the signed webhook. | Automatic. |
| Best for | Pilots and low volume. | Most mid-size NetSuite accounts. | Customers who want no scripts in NetSuite. |
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
- Make sure every UAE customer has a 15-digit TRN stored in a customer field (see the field mapping section).
- Create a Saved Search of type Transaction. Criteria: Type is Invoice or Credit Memo, Posting is true, and a date range you control.
- Add the result columns listed below.
- Export to CSV or Excel, or schedule the search to be emailed to you.
- Upload the file in TrustBill bulk upload. Map the columns once; TrustBill remembers the mapping.
- 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.
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)- 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). - Make sure the customer TRN field and each subsidiary's tax registration number are populated.
- 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.
- Build the outbound flow: pick up approved invoices not yet sent, map them (see the mapping tables), POST with an
Idempotency-Key. - Build the inbound flow: receive the signed webhook, verify the signature, and write the UUID and status back to the invoice.
- 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 };
});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.
| Header | Purpose | Rotation |
|---|---|---|
| X-API-Key | Identifies your organisation as a TrustBill partner. | On demand, with a dual-key window. |
| X-API-Secret | Secret paired with the key. Treat as a credential and never log it. | On demand, with a 24-hour dual-secret window. |
| x-erp-partner-secret | Bound to one legal entity (one TRN). Issued when the entity connects in TrustBill. | On demand per entity. |
| Idempotency-Key | Any string of 1 to 128 characters, unique per logical write within 24 hours. Required on all POSTs. | Chosen by you. |
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.
| TrustBill field | NetSuite source | Notes |
|---|---|---|
| externalRef | Invoice tranid (Document Number) | Must be unique per TRN. |
| issueDate | trandate | Date only, UAE time zone. |
| dueDate | duedate | Falls back to the issue date when empty. |
| currency | Transaction currency (ISO code) | AED for domestic invoices. |
| exchangeRate | exchangerate | Required when the currency is not AED. |
| seller.trn | Subsidiary tax registration number (OneWorld) or company information | 15 digits. One per TRN. |
| seller.legalName | Subsidiary legal name | |
| buyer.trn | Customer tax registration field, or a custom field such as custentity_trn | Required for B2B UAE invoices. 15 digits. |
| buyer.legalName | Customer company name | Use the registered legal name, not a trading name. |
| lines[*].description | Line description or item display name | |
| lines[*].quantity | Line quantity | |
| lines[*].unitPrice | Line rate | Excluding tax. |
| lines[*].taxCategory | Line tax code, translated to a UAE category | See the tax code table. |
| lines[*].taxRate | Rate of the tax code | 5, 0, or empty for exempt. |
| totals.* | total, taxtotal, subtotal | TrustBill re-checks totals within 0.01 AED. |
| parent invoice (credit memos) | Credit memo createdfrom | Required for credit notes. |
| indicators.freeZone | Customer custom field | Set once on the customer; flows to every invoice. |
| indicators.reverseCharge | Derived from the tax code |
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.
| Your NetSuite tax code | PINT-AE category | Rate | Typical use |
|---|---|---|---|
| Standard-rated 5% | S | 5% | Most domestic supplies. |
| Zero-rated | Z | 0% | Exports, qualifying international transport, certain supplies. |
| Exempt | E | none | Certain financial services, residential property. |
| Out of scope | O | none | Supplies outside the scope of UAE VAT. |
| Reverse charge | RC | per rule | Where the buyer accounts for the VAT. |
9. OneWorld, subsidiaries and multiple TRNs
| Your setup | What to do |
|---|---|
| Single company, one TRN | One TrustBill legal entity and one x-erp-partner-secret. |
| OneWorld, several UAE subsidiaries, each with its own TRN | One TrustBill legal entity per subsidiary. The script or flow selects the secret by the invoice's subsidiary. |
| UAE VAT group | The group TRN is the seller TRN on member invoices. Confirm the treatment with your tax adviser. |
| Non-UAE subsidiaries | Out of scope. They are not connected. |
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"
}
}- Read
X-Webhook-Timestampand extractv1fromX-Webhook-Signature. - Reject the request if the timestamp is more than 300 seconds from now.
- Compute HMAC-SHA256 of
timestamp.raw_bodywith your webhook secret and compare in constant time. - Only then parse the body and write
ftaUuidandstatusto 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
| Test case | Expected result |
|---|---|
| Standard 5% domestic invoice | Delivered, FTA UUID written back. |
| Zero-rated export | Delivered with category Z. |
| Exempt supply | Delivered with category E. |
| Reverse charge | Delivered with the reverse-charge indicator. |
| Free-zone customer | Delivered with the free-zone indicator. |
| Foreign-currency invoice | Delivered with the exchange rate. |
| Credit memo created from an invoice | Delivered, linked to the parent invoice. |
| Invoice with a deliberate error (missing buyer TRN) | Rejected with a clear reason, written to the reject-reason field. |
- In the sandbox, the reserved test TRN
100000000000000always accepts and fires a real webhook;100000000000666always 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
| Task | Your NetSuite team | TrustBill |
|---|---|---|
| Customer and subsidiary TRNs populated | Yes | Validates format and the FTA registry. |
| Custom fields on invoices | Yes (Option B) | Provides field names and meanings. |
| Script or integration flow | Yes (Option B) | Provides the API, a sample and support. |
| Tax code mapping | Decides the mapping | Applies it and checks it in UAT. |
| Credentials and sandbox | Stores them securely | Issues them. |
| PINT-AE conversion, validation, ASP submission | Yes | |
| FTA UUID, signed XML and PDF/A-3 copy | Yes |
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 integrationFrequently 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
Oracle NetSuite E-Invoicing UAE
Overview, supported approaches and the request form.
ERP Partner API
Full REST reference: auth, invoices, credit notes, webhooks.
Oracle Fusion Cloud ERP guide
For Fusion customers using Oracle Integration Cloud.
ERP integration pricing
Published pricing and lead times for every ERP.
