Mapping d'intégration Netsuite
Connexion & authentification
- API utilisée : SuiteQL (langage de requête SQL de NetSuite), exposé via un unique endpoint REST :
POST https://{account_id}.suitetalk.api.netsuite.com/services/rest/query/v1/suiteql
- Authentification : OAuth 2.0 Machine-to-Machine (M2M), via une assertion JWT signée en ES256 (grant_type=client_credentials). Il n'y a pas de flux OAuth interactif côté utilisateur.
- Endpoint de jeton :
https://{account_id}.suitetalk.api.netsuite.com/services/rest/auth/oauth2/v1/token - En-têtes des requêtes :
Authorization: Bearer <token>etPrefer: transient. - Sur une réponse
401, le jeton est régénéré automatiquement et la requête est rejouée une fois ; en cas d'échec, une erreurInvalidCredentialsest levée. - Prérequis côté NetSuite :
- Activer les fonctionnalités REST Web Services et OAuth 2.0.
- Un rôle disposant des droits de lecture sur
customer,item,transaction,transactionLine,currency,classificationet les enregistrements personnalisés éventuels, ainsi que l'accès aux REST Web Services / SuiteQL.
Mise en place de la connexion
La connexion est machine-to-machine : vous enregistrez Fincome comme application de confiance dans votre compte NetSuite, puis vous reportez trois identifiants dans Fincome. La clé privée de signature ne quitte jamais Fincome — vous n'importez que le certificat public Fincome.
- Créer l'enregistrement d'intégration.
Setup ▸ Integration ▸ Manage Integrations ▸ New. Cochez toutes les cases Token-Based Authentication, OAuth 2.0 et Client Credentials (Machine to Machine) Grant, enregistrez, puis notez le Client ID (Consumer Key).
- Téléverser le certificat Fincome.
Téléchargez le certificat public Fincome : <https://fincome-public-assets.s3.eu-west-3.amazonaws.com/netsuite/fincome-netsuite.pem>
Puis allez dans Setup ▸ Integration ▸ OAuth 2.0 Client Credentials (M2M) Setup ▸ New : sélectionnez l'intégration de l'étape 1, importez le certificat et rattachez-le à une entité et un rôle disposant des droits REST Web Services / SuiteQL (cf. prérequis). Notez le Certificate ID renvoyé.
- Renseigner Fincome.
Dans Fincome, ouvrez le connecteur NetSuite et saisissez votre Account ID (Setup ▸ Company ▸ Company Information), votre Client ID (étape 1) et votre Certificate ID (étape 2). Optionnellement, indiquez les IDs de vos champs personnalisés de reconnaissance du revenu et votre/vos catégorie(s) de revenu récurrent.
Objets synchronisés
Le connecteur traite cinq flux, dans cet ordre :
Flux | Source NetSuite | Objets Fincome créés | Condition de filtrage |
|---|---|---|---|
customer | table | Customer | aucune (sync complète) |
product | table | Product + Price | aucune |
subscription | transactions | Subscription | |
invoice | transactions | Invoice + InvoiceLineItem | |
credit_note | transactions | Invoice + InvoiceLineItem | |
Mapping des champs
Clients (customer)
Champ NetSuite | Champ Fincome | Remarque |
|---|---|---|
id | original_id |
|
entitytitle | name |
|
| ||
toplevelparent | root_parent_id | Renseigné uniquement si |
Produits & tarifs (product)
À partir de la table item, le connecteur crée un Product et un Price :
Champ NetSuite | Champ Fincome (Product) |
|---|---|
id | original_id |
itemid | name |
Champ NetSuite | Champ Fincome (Price) |
|---|---|
id | original_id |
id | product_id (clé étrangère vers Product) |
itemid | name |
itemrevenuecategory | type → |
Factures (invoice)
En-tête (Invoice) :
Champ NetSuite | Champ Fincome | Remarque |
|---|---|---|
id | original_id |
|
tranId | invoice_number |
|
entity | customer_id | clé étrangère vers Customer |
tranDate | date | format JJ/MM/AAAA ; si absente, la facture est ignorée |
status | status | mappé via la table |
Lignes (InvoiceLineItem) :
Champ NetSuite | Champ Fincome | Remarque |
|---|---|---|
original_id (combiné à l'id facture) |
| |
— | invoice_id | clé étrangère vers Invoice (ligne ignorée si la facture est absente) |
itemrevenuecategory + dates de période | type | |
creditforeignamount / debitforeignamount | amount_excluding_tax_after_discount | voir § Montants |
— | tax_amount | toujours 0 (lignes de taxe exclues) |
quantity | quantity | transformé en |
currency.symbol | currency_code |
|
transactionLine.memo | description |
|
custcol_iw_rr_start_date | period_start | date de début de reconnaissance du revenu |
custcol_iw_rr_end_date | period_end | 1 jour (NetSuite borne la fin de façon inclusive) |
item | price_id | clé étrangère vers Price |
Axes personnalisés (custom_axis_field) :
Enregistrement NetSuite | Champ Fincome |
|---|---|
CUSTOMLIST_IW_CONTRACT_TYPE.name | contract_type |
CUSTOMRECORD_CSEG_IW_CA_COUNTRY.name | country_name |
class |
Abonnements (subscription)
Champ NetSuite | Champ Fincome | Remarque |
|---|---|---|
id (+ id de ligne) | original_id | identifiant combiné |
id (transaction) | subscription_set_id | regroupe les lignes d'un même |
entity | customer_id | clé étrangère vers Customer |
custcol_iw_rr_start_date | subscription_start_date |
|
montant de la ligne ÷ nombre de mois de la période | monthly_value | les mois partiels sont calculés au prorata |
— | monthly_value_main | |
Avoirs (credit_note)
Structure identique aux factures, à trois différences près :
- source = transactions
creditmemo(et nonsalesorder) ; - status mappé via la table
creditmemo(voir § Mapping des statuts) ; original_id= l'id de l'avoir lui-même (ce n'est pas un lien vers une facture d'origine).
Mapping des statuts
Les statuts dépendent du type d'enregistrement source.
Bons de commande (salesorder) → utilisés pour les factures
Code NetSuite | Libellé NetSuite | Statut Fincome |
|---|---|---|
A | Pending Approval | pending |
B | Pending Fulfillment | open |
C | Cancelled | ignoré |
D | Partially Fulfilled | open |
E | Pending Billing/Part. Fulf. | open |
F | Pending Billing | open |
G | Billed | open |
H | Closed | ignoré |
Y | Undefined | ignoré |
Avoirs (creditmemo)
Code NetSuite | Libellé NetSuite | Statut Fincome |
|---|---|---|
A | Open | open |
B | Fully Applied | paid |
C | Undefined | ignoré |
D | Voided | ignoré |
Un enregistrement passé à un statut ignoré (commande annulée/clôturée, avoir annulé…) est marqué comme supprimé côté Fincome lors du sync suivant.
Montants, quantités, dates & devises
- Montants. NetSuite scinde chaque ligne en deux pieds comptables. Le connecteur lit les montants en devise étrangère :
creditforeignamount→ montant positif ;- sinon
debitforeignamount→ montant négatif (-1 ×). - Le champ
netamountn'est pas utilisé. - Quantités. Inversées et arrondies au supérieur :
-1 × ceil(quantity). - Dates. Format attendu JJ/MM/AAAA. Les dates de fin de période (
period_end) sont décalées de +1 jour. - Devises. Les montants sont exprimés dans la devise de la transaction (
*foreignamount). Ils sont convertis dans la devise de base de l'entreprise au taux de la date de la transaction (champs*_main). À noter : pour les abonnements, cette date est dans le futur (tranDate > aujourd'hui), la conversion utilise donc le taux de change associé à cette date future.
Synchronisation incrémentale & pagination
- Pagination : par
limit(1000) etoffsetsur SuiteQL. - Curseur :
{ offset, last_modified_date }. Une fois un flux épuisé (hasMore = false),offsetrepasse à 0 etlast_modified_dateavance à la date de début du dernier sync. - Champ de dernière modification :
- customer →
lastmodifieddate; - subscription / invoice / credit_note →
t.lastmodifieddate. - Suppressions. Les suppressions définitives côté NetSuite ne sont pas propagées : un enregistrement supprimé cesse simplement d'apparaître, sans être retiré de Fincome. En revanche, un enregistrement passé à un statut ignoré (voir § Mapping des statuts) est marqué comme supprimé.
Champs & enregistrements personnalisés requis
Ces éléments doivent exister dans l'instance NetSuite pour un mapping complet :
Élément | Usage Fincome |
|---|---|
custcol_iw_rr_start_date | début de période (period_start, subscription_start_date) |
custcol_iw_rr_end_date | fin de période (period_end) |
CUSTOMLIST_IW_CONTRACT_TYPE | axe personnalisé contract_type |
CUSTOMRECORD_CSEG_IW_CA_COUNTRY | axe personnalisé country_name |
Mis à jour le : 23/06/2026
Merci !
