NetSuite SOAP Web Services with Postman

Web Services are Extensible Markup Language (XML) applications mapped to programs, objects, databases, or complex business functions.

They utilize standardized XML messaging to send and receive requests over the internet. The following protocols are used to publish, expose, and access Web Services:

  • Web Services Description Language (WSDL) – exposes an interface, interaction, and protocol mapping.
  • Simple Object Access Protocol (SOAP) – a messaging format that defines and envelope for communication via HTTP and HTTPS.

A SOAP message is an ordinary XML document that contains:

  • An Envelope element identifying the XML document as a SOAP message.
  • A header element.
  • A body element with call and response information.
  • A fault element with errors and status information.

An excellent reference document is the SuiteTalk (Web Services) Platform Guide, linked here.

Account Setup

The examples in this post assume that a SOAP integration record is already set up in your account. If this isn’t the case, refer to the Getting Started section of the SuiteTalk Platform Guide.

The API is versioned, with each version being specified by a WSDL file. In this post, we will use the 2021_2 version. If you use a different version, it may be necessary to modify the XML in these examples to match your API version. These resources fully describe the version used in this post:

The SOAP Schema Browser is used in conjunction with the SuiteTalk (Web Services) Records Guide available via help within your account.

Sending SOAP Messages

Many tools are available for interactively creating, sending, and analyzing SOAP requests. This post uses Postman – a cross-platform application that can be used to issue SOAP requests using OAuth1.0 for authentication.

The key to using Postman with NetSuite is to provide pre-request JavaScript code, run prior to invoking an operation. The pre-request code creates a nonce and timestamp, stores it, and makes it available for use by the request that follows.

Initial Setup

We have to do a little setup within Postman prior to issuing our first SOAP request to the API. First, we’ll create an environment in which to store values that can be used by any request.

Then we’ll create a collection that will keep the requests that we create, and their results, in a single place.

Create an Environment

Postman environments are collections of variables and values. To create the environment that will contain your account information and credentials:

  1. Click the gear icon in the top-right corner of the Postman UI.
  2. In the Manage Environments popup that appears, click Add.
  3. Provide an Environment Name, such as NetSuite Environment.
  4. Add the following Variables and Initial Values:
    • ACCOUNT — the account’s ACCOUNT ID
    • CONSUMER_KEY — the integration record’s CONSUMER KEY
    • CONSUMER_SECRET — the integration record’s CONSUMER SECRET
    • TOKEN_ID — the role’s TOKEN ID
    • TOKEN_SECRET — the role’s TOKEN SECRET
    • WEBSERVICES_URL — the NetSuite WebServices URL
  5. Click Add
  6. Once added, ensure that the environment is active. If it doesn’t appear in the top level of the pulldown to the left of the gear, use the pulldown to select it.

Your environment should be similar to the above, except that initial and current values will not be hidden.

Create a New Collection

Collections are used to organize associated groups of requests and responses. In Postman, create a collection, such as SOAP WS.

Javascript Pre-Request

/*
Taken from: https://gist.github.com/michoelchaikin/2a4916e0917aa0f79b8eb9d7fe275363

Usage:
1. Define a NetSuite environment in Postman
   (https://www.getpostman.com/docs/postman/environments_and_globals/manage_environments)
   with the following keys set: ACCOUNT, CONSUMER_KEY, CONSUMER_SECRET, TOKEN_ID, TOKEN_SECRET
   
2. Add this script to your "Pre Request Script" in Postman
   (https://www.getpostman.com/docs/postman/scripts/pre_request_scripts) 

3. Add the Token Passport in your request with variable placeholders

   <tokenPassport xmlns="urn: messages_2017_2.platform.webservices.netsuite.com"
                  xmlns:ns1="urn:core_2017_2.platform.webservices.netsuite.com">
       <ns1:account>{{ACCOUNT}}</ns1:account>
       <ns1:consumerKey>{{CONSUMER_KEY}}</ns1:consumerKey>
       <ns1:token>{{TOKEN_ID}}</ns1:token>
       <ns1:nonce>{{nonce}}</ns1:nonce>
       <ns1:timestamp>{{timestamp}}</ns1:timestamp>
       <ns1:signature algorithm="HMAC-SHA1">{{signature}}</ns1:signature>
   </tokenPassport>
*/

let account = pm.environment.get("ACCOUNT");
let consumerKey = pm.environment.get("CONSUMER_KEY");
let consumerSecret = pm.environment.get("CONSUMER_SECRET");
let tokenId = pm.environment.get("TOKEN_ID");
let tokenSecret = pm.environment.get("TOKEN_SECRET");
    
let timestamp = new Date().getTime().toString().substring(0, 10);
let nonce = CryptoJS.lib.WordArray.random(10).toString();
let baseString = `${account}&${consumerKey}&${tokenId}&${nonce}&${timestamp}`;
let key = `${consumerSecret}&${tokenSecret}`;
let signature = CryptoJS.HmacSHA1(baseString, key).toString(CryptoJS.enc.Base64);

pm.environment.set("signature", signature);
pm.environment.set("nonce", nonce);
pm.environment.set("timestamp", timestamp);

First SOAP Request

With the setup out of the way, it’s time to send a SOAP request. We’ll create a request that will return all List / records from the account specified in the environment.

The request will return the contents of all lists where record type is currency in the account.

  • Within the collection, create a new request named list.
  • Within the list request:
  • Near the top-left of the request UI, select a POST operation.
  • To the right of, enter {{webservices_url}} the URL. When the request is executed, {{webservices_url}} will be replaced by the value of webservices_url from the environment.
  • Under, click Pre-req. In the text area below Pre-req, add the Javascript code.The code will be executed prior to invoking the operation that we are currently defining. When executed, the code will add these variables/values to the Postman environment: signature, nonce, and timestamp.
  • Under, click Headers. Add the following Key / Value pairs:
  • NOTE: the value for SOAPAction must match the operation that is present in the body of the request. In this example, our request body performs a getAll SOAPAction is getAll.
  • Under POST, ensure that Auth -> Type is set to No Auth.
  • Under POST, nothing needs to be done to Params.
  • Under POST, click Body.Add the following XML which defines the entire request that will be sent:

Request

<soapenv:Envelope
    xmlns:xsd='http://www.w3.org/2001/XMLSchema'
    xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
    xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/'
    xmlns:platformCore='urn:core_2021_2.platform.webservices.netsuite.com'
    xmlns:listRel='urn:relationships_2021_2.lists.webservices.netsuite.com'
    xmlns:platformMsgs='urn:messages_2021_2.platform.webservices.netsuite.com'>
    <soapenv:Header>
     <tokenPassport xsi:type='platformCore:TokenPassport'>
            <account xsi:type='xsd:string'>{{accountId}}</account>
            <consumerKey xsi:type='xsd:string'>{{consumerKey}}</consumerKey>
            <token xsi:type='xsd:string'>{{tokenId}}</token>
            <nonce xsi:type='xsd:string'>{{nonce}}</nonce>
            <timestamp xsi:type='xsd:long'>{{timestamp}}</timestamp>
            <signature algorithm='HMAC_SHA256' xsi:type='platformCore:TokenPassportSignature'>{{signature}}</signature>
        </tokenPassport>   
    </soapenv:Header>
     <soapenv:Body>
        <getAll xsi:type='platformMsgs:GetAllRequest'>
            <record recordType='currency' xsi:type='platformCore:GetAllRecord'/>
        </getAll>
    </soapenv:Body>
</soapenv:Envelope>

Response

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <soapenv:Header>
        <platformMsgs:documentInfo xmlns:platformMsgs="urn:messages_2021_2.platform.webservices.netsuite.com">
            <platformMsgs:nsId>WEBSERVICES_TSTDRV2747395_071720231671669349390849022_78a41c</platformMsgs:nsId>
        </platformMsgs:documentInfo>
    </soapenv:Header>
    <soapenv:Body>
        <getAllResponse xmlns="">
            <platformCore:getAllResult xmlns:platformCore="urn:core_2021_2.platform.webservices.netsuite.com">
                <platformCore:status isSuccess="true"/>
                <platformCore:totalRecords>4</platformCore:totalRecords>
                <platformCore:recordList>
                    <platformCore:record internalId="1" xsi:type="listAcct:Currency" xmlns:listAcct="urn:accounting_2021_2.lists.webservices.netsuite.com">
                        <listAcct:name>USA</listAcct:name>
                        <listAcct:symbol>USD</listAcct:symbol>
                        <listAcct:isBaseCurrency>true</listAcct:isBaseCurrency>
                        <listAcct:isInactive>false</listAcct:isInactive>
                        <listAcct:overrideCurrencyFormat>false</listAcct:overrideCurrencyFormat>
                        <listAcct:displaySymbol>$</listAcct:displaySymbol>
                        <listAcct:symbolPlacement>_beforeNumber</listAcct:symbolPlacement>
                        <listAcct:locale>_unitedStatesEnglish</listAcct:locale>
                        <listAcct:formatSample>$1,234.56</listAcct:formatSample>
                        <listAcct:exchangeRate>1.0</listAcct:exchangeRate>
                        <listAcct:currencyPrecision>_two</listAcct:currencyPrecision>
                    </platformCore:record>
                    <platformCore:record internalId="2" xsi:type="listAcct:Currency" xmlns:listAcct="urn:accounting_2021_2.lists.webservices.netsuite.com">
                        <listAcct:name>British pound</listAcct:name>
                        <listAcct:symbol>GBP</listAcct:symbol>
                        <listAcct:isBaseCurrency>false</listAcct:isBaseCurrency>
                        <listAcct:isInactive>false</listAcct:isInactive>
                        <listAcct:overrideCurrencyFormat>false</listAcct:overrideCurrencyFormat>
                        <listAcct:displaySymbol>£</listAcct:displaySymbol>
                        <listAcct:symbolPlacement>_beforeNumber</listAcct:symbolPlacement>
                        <listAcct:locale>_unitedKingdomEnglish</listAcct:locale>
                        <listAcct:formatSample>£1,234.56</listAcct:formatSample>
                        <listAcct:exchangeRate>2.365</listAcct:exchangeRate>
                        <listAcct:currencyPrecision>_two</listAcct:currencyPrecision>
                    </platformCore:record>
                    <platformCore:record internalId="3" xsi:type="listAcct:Currency" xmlns:listAcct="urn:accounting_2021_2.lists.webservices.netsuite.com">
                        <listAcct:name>Canadian Dollar</listAcct:name>
                        <listAcct:symbol>CAD</listAcct:symbol>
                        <listAcct:isBaseCurrency>false</listAcct:isBaseCurrency>
                        <listAcct:isInactive>false</listAcct:isInactive>
                        <listAcct:overrideCurrencyFormat>false</listAcct:overrideCurrencyFormat>
                        <listAcct:displaySymbol>$</listAcct:displaySymbol>
                        <listAcct:symbolPlacement>_beforeNumber</listAcct:symbolPlacement>
                        <listAcct:locale>_canadaEnglish</listAcct:locale>
                        <listAcct:formatSample>$1,234.56</listAcct:formatSample>
                        <listAcct:exchangeRate>1.559</listAcct:exchangeRate>
                        <listAcct:currencyPrecision>_two</listAcct:currencyPrecision>
                    </platformCore:record>
                    <platformCore:record internalId="4" xsi:type="listAcct:Currency" xmlns:listAcct="urn:accounting_2021_2.lists.webservices.netsuite.com">
                        <listAcct:name>Euro</listAcct:name>
                        <listAcct:symbol>EUR</listAcct:symbol>
                        <listAcct:isBaseCurrency>false</listAcct:isBaseCurrency>
                        <listAcct:isInactive>false</listAcct:isInactive>
                        <listAcct:overrideCurrencyFormat>false</listAcct:overrideCurrencyFormat>
                        <listAcct:displaySymbol>€</listAcct:displaySymbol>
                        <listAcct:symbolPlacement>_beforeNumber</listAcct:symbolPlacement>
                        <listAcct:locale>_franceFrenchEuro</listAcct:locale>
                        <listAcct:formatSample>€1 234,56</listAcct:formatSample>
                        <listAcct:exchangeRate>1.509</listAcct:exchangeRate>
                        <listAcct:currencyPrecision>_two</listAcct:currencyPrecision>
                    </platformCore:record>
                </platformCore:recordList>
            </platformCore:getAllResult>
        </getAllResponse>
    </soapenv:Body>
</soapenv:Envelope>

Leave a comment

Your email address will not be published. Required fields are marked *