> ## Documentation Index
> Fetch the complete documentation index at: https://docs.chift.eu/llms.txt
> Use this file to discover all available pages before exploring further.

# Netsuite

export const OverviewLegend = ({showTitle = true}) => <blockquote>
    {showTitle && <p>
        <strong>Overview legend 🧭</strong>
      </p>}
    <table>
      <thead>
        <tr>
          <th>Column</th>
          <th>Value</th>
          <th>Meaning</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>Geography</td>
          <td>🇫🇷 FR · 🇧🇪 BE · …</td>
          <td>Countries where the connector is officially supported.</td>
        </tr>
        <tr>
          <td rowSpan={3}>Software type</td>
          <td>SaaS</td>
          <td>Through API.</td>
        </tr>
        <tr>
          <td>On-premise (local agent)</td>
          <td>
            Software running locally — installation of a local agent is
            required.
          </td>
        </tr>
        <tr>
          <td>On-premise (API)</td>
          <td>Software running locally — API available.</td>
        </tr>
        <tr>
          <td rowSpan={2}>Status</td>
          <td>🔵 Live</td>
          <td>Connector is generally available and production-ready.</td>
        </tr>
        <tr>
          <td>🟣 Beta</td>
          <td>
            Connector is in beta — usable in production but may still evolve.
          </td>
        </tr>
        <tr>
          <td>Multi folder</td>
          <td>✅ Yes / ❌ No</td>
          <td>
            Connection to multiple accounting folders at the same time (see{' '}
            <a href="/developer-guides/api-guides/accounting/folders">
              accounting folders guide
            </a>
            ).
          </td>
        </tr>
        <tr>
          <td>Rate limits</td>
          <td>✅ No / ❌ Yes</td>
          <td>Whether the target software sets rate limits on API calls.</td>
        </tr>
        <tr>
          <td rowSpan={3}>API keys</td>
          <td>❎ No</td>
          <td>
            No API keys required (OAuth2 client secret and client ID). No
            requirements to activate the connector — you can create a
            connection.
          </td>
        </tr>
        <tr>
          <td>🔑</td>
          <td>
            Keys are required to activate the connector. Chift cannot act as
            intermediary to obtain them; we can still assist with steps to get
            keys directly from the software provider.
          </td>
        </tr>
        <tr>
          <td>🔑 ☑️ via Chift</td>
          <td>
            Keys are required to activate the connector. You can go through
            Chift to get the keys (intermediary or partnership keys). An
            approval process may still apply, but you do not need to request
            keys from the vendor on your own.
          </td>
        </tr>
        <tr>
          <td rowSpan={3}>Approval / certification process</td>
          <td>⚡ Instant</td>
          <td>
            No keys required, or Chift can encode their keys for you when
            requested. Activation is instantaneous.
          </td>
        </tr>
        <tr>
          <td>🟢 Approval — [Duration]</td>
          <td>
            Approval will be granted. The vendor may require information or app
            configuration in a developer portal before issuing keys.
          </td>
        </tr>
        <tr>
          <td>🟠 Approval — [Duration]</td>
          <td>
            Approval is not guaranteed — often due to integration strategy; the
            vendor may do a deeper assessment (competitors, partnership
            requirements, and similar).
          </td>
        </tr>
        <tr>
          <td rowSpan={2}>Activation time</td>
          <td>⚡ Instant</td>
          <td>
            If no keys are required, or Chift has keys ready to share with you.
          </td>
        </tr>
        <tr>
          <td>Time</td>
          <td>
            Estimated time to get the connector activated in production as a
            result of the approval or certification process (e.g. ⏱️ 2 days, 1
            week).
          </td>
        </tr>
        <tr>
          <td rowSpan={3}>Extra fees — software editor</td>
          <td>❎ No</td>
          <td>No fees charged by the software editor.</td>
        </tr>
        <tr>
          <td>💰 🕹️</td>
          <td>Fees associated with obtaining a testing account.</td>
        </tr>
        <tr>
          <td>💰 🔑</td>
          <td>Fees charged to get API keys.</td>
        </tr>
        <tr>
          <td rowSpan={2}>Extra fees — end user</td>
          <td>❎ No</td>
          <td>The end user does not pay extra to get integrated.</td>
        </tr>
        <tr>
          <td>💰 Yes</td>
          <td>The end user must pay extra to get integrated.</td>
        </tr>
        <tr>
          <td>Comments on costs</td>
          <td>—</td>
          <td>Additional notes on fees or pricing when relevant.</td>
        </tr>
        <tr>
          <td rowSpan={4}>Sandbox account</td>
          <td>✅ via Chift</td>
          <td>Chift can provide you with a sandbox.</td>
        </tr>
        <tr>
          <td>🟠 Only through integrator</td>
          <td>Only the software's integrator can provide a sandbox.</td>
        </tr>
        <tr>
          <td>✅ Self-service</td>
          <td>You can create your own sandbox.</td>
        </tr>
        <tr>
          <td>✅ Trial account</td>
          <td>It is possible to create a trial account.</td>
        </tr>
      </tbody>
    </table>
  </blockquote>;

export const ConnectorCardIframe = ({api = 'accounting', connectors}) => {
  const [theme, setTheme] = React.useState('light');
  React.useEffect(() => {
    const checkTheme = () => {
      const isDark = document.documentElement.classList.contains('dark');
      setTheme(isDark ? 'dark' : 'light');
    };
    checkTheme();
    const observer = new MutationObserver(checkTheme);
    observer.observe(document.documentElement, {
      attributes: true,
      attributeFilter: ['class']
    });
    return () => observer.disconnect();
  }, []);
  const queryParams = new URLSearchParams({
    api,
    theme,
    ...connectors ? {
      connectors
    } : {}
  });
  const iframeUrl = `https://chift-coverage-matrix.s3.eu-west-3.amazonaws.com/connector-card.html?${queryParams.toString()}`;
  return <iframe src={iframeUrl} title={`Chift connector information - ${api}`} style={{
    display: 'block',
    width: '100%',
    height: '480px',
    margin: 0,
    padding: 0,
    border: 'none'
  }} />;
};

export const CoverageIframe = ({api = 'accounting', connectors}) => {
  const [theme, setTheme] = React.useState('light');
  const [isFullscreen, setIsFullscreen] = React.useState(false);
  const [currentIframeUrl, setCurrentIframeUrl] = React.useState(null);
  const iframeRef = React.useRef(null);
  React.useEffect(() => {
    const checkTheme = () => {
      const isDark = document.documentElement.classList.contains('dark');
      setTheme(isDark ? 'dark' : 'light');
    };
    checkTheme();
    const observer = new MutationObserver(checkTheme);
    observer.observe(document.documentElement, {
      attributes: true,
      attributeFilter: ['class']
    });
    return () => observer.disconnect();
  }, []);
  React.useEffect(() => {
    const handleFullscreenChange = () => {
      setIsFullscreen(!!document.fullscreenElement);
    };
    document.addEventListener('fullscreenchange', handleFullscreenChange);
    return () => document.removeEventListener('fullscreenchange', handleFullscreenChange);
  }, []);
  React.useEffect(() => {
    const handleMessage = event => {
      if (!event.origin.includes('chift-coverage-matrix.s3.eu-west-3.amazonaws.com')) return;
      if (event.data?.type === 'urlChange' && event.data?.url) {
        setCurrentIframeUrl(event.data.url);
      }
    };
    window.addEventListener('message', handleMessage);
    return () => window.removeEventListener('message', handleMessage);
  }, []);
  const queryParams = new URLSearchParams({
    api,
    theme,
    ...connectors ? {
      connectors
    } : {}
  });
  const iframeUrl = `https://chift-coverage-matrix.s3.eu-west-3.amazonaws.com/coverage.html?${queryParams.toString()}`;
  const openUrl = currentIframeUrl || iframeUrl;
  const toggleFullscreen = () => {
    if (!document.fullscreenElement) {
      iframeRef.current?.requestFullscreen();
    } else {
      document.exitFullscreen();
    }
  };
  const isDark = theme === 'dark';
  const buttonStyle = {
    display: 'inline-flex',
    alignItems: 'center',
    gap: '8px',
    padding: '4px 12px',
    fontSize: '14px',
    fontWeight: '500',
    color: isDark ? '#d4d4d4' : '#374151',
    backgroundColor: 'transparent',
    border: `1px solid ${isDark ? '#404040' : '#e5e7eb'}`,
    borderRadius: '12px',
    cursor: 'pointer',
    textDecoration: 'none',
    transition: 'all 0.15s ease'
  };
  const hoverBg = isDark ? 'rgba(255,255,255,0.05)' : 'rgba(0,0,0,0.03)';
  const hoverBorder = isDark ? '#525252' : '#d1d5db';
  const defaultBg = 'transparent';
  const defaultBorder = isDark ? '#404040' : '#e5e7eb';
  return <>
  <div style={{
    display: 'flex',
    justifyContent: 'flex-end',
    gap: '12px',
    marginBottom: '8px'
  }}>
    <button onClick={toggleFullscreen} style={buttonStyle} onMouseEnter={e => {
    e.target.style.backgroundColor = hoverBg;
    e.target.style.borderColor = hoverBorder;
  }} onMouseLeave={e => {
    e.target.style.backgroundColor = defaultBg;
    e.target.style.borderColor = defaultBorder;
  }}>
      <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
        {isFullscreen ? <>
            <polyline points="4 14 10 14 10 20"></polyline>
            <polyline points="20 10 14 10 14 4"></polyline>
            <line x1="14" y1="10" x2="21" y2="3"></line>
            <line x1="3" y1="21" x2="10" y2="14"></line>
          </> : <>
            <polyline points="15 3 21 3 21 9"></polyline>
            <polyline points="9 21 3 21 3 15"></polyline>
            <line x1="21" y1="3" x2="14" y2="10"></line>
            <line x1="3" y1="21" x2="10" y2="14"></line>
          </>}
      </svg>
      {isFullscreen ? 'Exit Fullscreen' : 'Fullscreen'}
    </button>
    <a href={iframeUrl} target="_blank" rel="noopener noreferrer" style={buttonStyle} onMouseEnter={e => {
    e.target.style.backgroundColor = hoverBg;
    e.target.style.borderColor = hoverBorder;
  }} onMouseLeave={e => {
    e.target.style.backgroundColor = defaultBg;
    e.target.style.borderColor = defaultBorder;
  }}>
      <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
        <path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path>
        <polyline points="15 3 21 3 21 9"></polyline>
        <line x1="10" y1="14" x2="21" y2="3"></line>
      </svg>
      Open in new tab
    </a>
  </div>
  <iframe ref={iframeRef} src={iframeUrl} title={`Chift Coverage Matrix - ${api}`} style={{
    height: 'max(500px, 80vh)'
  }} className="w-full" allowFullScreen />
  <blockquote>
    <p>
      <strong>Matrix Legend 🧭</strong>
    </p>
    <table>
      <thead>
        <tr>
          <th>Status</th>
          <th>Meaning</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>✅ Implemented</td>
          <td>Endpoint is implemented and available.</td>
        </tr>
        <tr>
          <td>❌ Not supported</td>
          <td>
            Endpoint is not supported by the target software (connector
            limitation). Cannot be implemented.
          </td>
        </tr>
        <tr>
          <td>💬 On request</td>
          <td>
            Endpoint is not implemented but feasibility is validated. Can be
            implemented on request — contact your Chift point of contact to
            discuss scope and timing.
          </td>
        </tr>
        <tr>
          <td>🔎 To be analyzed</td>
          <td>
            Endpoint is not implemented and feasibility has not yet been fully
            assessed. Analysis is pending.
          </td>
        </tr>
      </tbody>
    </table>
  </blockquote>
</>;
};

<ConnectorCardIframe api="accounting" connectors="NetSuite" />

<Accordion title="Overview Legend 🧭">
  <OverviewLegend showTitle={false} />
</Accordion>

## Introduction

NetSuite is the leading integrated cloud business software suite, including business accounting, ERP, CRM and ecommerce software. An AI-powered business management suite, encompassing ERP/Financials, CRM, and ecommerce for more than 41,000 customers.

## Configure NetSuite

**Prerequisite(s)** There's no prerequisite to activate the connector on your Chift App.

**Activation Process** Activate the connector in one click on the connector section in your Chift account.

## Test NetSuite

A sandbox environment is available from NetSuite, but only for customers with an active NetSuite subscription. It is typically priced at **\~10–20% of the annual subscription cost**.

In practice, the recommended approach is to partner with **beta clients or partners who already have NetSuite access** and can provide a test environment for integration testing.

## Connect NetSuite

For detailed connection steps, check out the documentation:

* [Connect NetSuite – English](https://help.chift.app/articles/4463201464-netsuite?lang=en)
* [Connecter NetSuite – Français](https://help.chift.app/articles/4463201464-netsuite?lang=fr)

## Limitations

### `POST invoices/payments `**([Create an invoice payment](https://docs.chift.eu/api-reference/endpoints/accounting/create-an-invoice-payment)) :** Payment method must be linked to a ledger account

A payment method must be linked to a ledger account in NetSuite to be used in an invoice payment. This configuration is done at the payment method level in NetSuite — you will have to make sure each payment method you intend to use for invoice payments has a ledger account assigned. An error will be thrown if this is not the case.

## Coverage

<CoverageIframe api="accounting" connectors="NetSuite" />

## Troubleshooting

### Specific errors for NetSuite:

| Error Code                                     | Error description                                                                                | Resolution                                                                                                           |
| ---------------------------------------------- | ------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------- |
| ERROR\_ACCOUNT\_TYPE\_NOT\_ALLOWED             | Only general accounts can be used when creating journal entries in NetSuite.                     | Use general accounts for journal entries.                                                                            |
| ERROR\_CUSTOMER\_INVOICE\_TYPE\_NOT\_SUPPORTED | Customer invoices are not supported in this NetSuite connection.                                 | Use supplier invoice types instead.                                                                                  |
| ERROR\_INVALID\_TRANSACTION\_DATE              | Transaction dates may be at most 30 years in the past and 10 years in the future.                | Use a transaction date within the allowed range.                                                                     |
| ERROR\_JOURNAL\_ID\_NOT\_AUTHORIZED            | Only journal\_id 3 and 4 are authorized for this connection to create sales or purchase entries. | Use the correct journal\_id for sales/purchase entries, or use the create journal entry endpoint for other journals. |
