---
schema_version: "1"
id: ab49ff0aed78cbb6006f4f7ce442d8488d8fb3d6a1f1644da77e4160a85fdafa
title: Agent Order on Behalf
collection: developer
version: current
locale: en-us
portal_url: https://docs.salesforce.com/developer/current/en-us/commerce-cloud/pwa-kit-managed-runtime/guides/taob-in-composable.md
canonical_url: https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/taob-in-composable.html
source_site: developer.salesforce.com
content_type: documentation
content_hash: 961ce7bab2eca19fae85796b55047ea9390e86990f4221c8d103622486b3a647
products:
  - Composable Storefront
  - Salesforce APIs
---
# Agent Order on Behalf

Use [SLAS Trusted Agent on Behalf](https://developer.salesforce.com/docs/commerce/commerce-api/guide/slas-trusted-agent.html) (TAOB) functionality in your PWA Kit application to allow agents to place orders on behalf of customers. PWA Kit comes with TAOB authentication hooks. Learn how to use these and check out sample code for implementing order-on-behalf UI components.

## Prerequisites

- Familiarize yourself with the [SLAS Trusted Agent on Behalf documentation](https://developer.salesforce.com/docs/commerce/commerce-api/guide/slas-trusted-agent.html#configure-trusted-agent-authorization) to understand the auth flows, client requirements, and requirements for Business Manager users to login and place orders on behalf of customers.
- Ensure the private SLAS client used by PWA Kit is configured with the `sfcc.ta_ext_on_behalf_of` scope.

## PWA Kit Hooks

The `@salesforce/commerce-sdk-react` package in PWA Kit contains a `useTrustedAgent` React hook. This hook allows inspection of the agent state as well as actions to log in and log out agents via Account Manager (AM).

```javascript
import {useTrustedAgent} from '@salesforce/commerce-sdk-react'

// Inside a React component
const {isAgent, agentId, loginId, login, logout} = useTrustedAgent()
```

The `login(loginId?: string, usid?: string, refresh = false)` action handles the complete agent login flow within the agent's browser:

1. The hook invokes the [`getTrustedAgentAuthorizationToken`](https://developer.salesforce.com/docs/commerce/commerce-api/references/auth?meta=getTrustedAgentAuthorizationToken) SLAS API. This API returns a login URL at Salesforce B2C Commerce Account Manager (AM) for the agent to authenticate. If provided, the `loginId` and `usid` parameters are included in the request. A `loginId` value of `guest` can be used to login as a guest user.
2. The hook opens this URL in a browser "popup" window and the agent authenticates with AM.
3. Upon successful authentication, AM redirects to a URL (the `/callback` redirectURI used by PWA Kit and configured on your SLAS client) that includes an authorization code.
4. The popup handling code reads this authorization code and uses it to invoke the [`getTrustedAgentAccessToken`](https://developer.salesforce.com/docs/commerce/commerce-api/references/auth?meta=getTrustedAgentAccessToken) SLAS API to exchange the code for an access token. This access token replaces the normal access token used by the PWA Kit application to make authenticated requests to SLAS APIs.
5. The hook updates its internal state to reflect that an agent is now logged in (`isAgent` is `true` and `agentId` and `loginId` are populated).

From this point onward, all SCAPI API requests made by the PWA Kit application will be made on behalf of the customer represented by the trusted agent access token. The agent can now place orders on behalf of customers.

To log out the agent and revert to normal customer authentication, simply call the `logout()` action provided by the hook. This will clear the trusted agent access token and revert to the normal customer access token.

### Agent Access Token Expiration

TAOB access tokens have a limited lifetime (default is 15 minutes). If the agent is still active after the token expires, the PWA Kit application can call the `login` action again with the `refresh` parameter set to `true` to obtain a new access token. Agent access tokens don't support refresh tokens. This `refresh` parameter is instead used to re-initiate the full login flow described above but keeps the popup from being focused. Since the agent would have recently been authenticated with AM, they don't need to re-enter their credentials and the authentication can complete seamlessly.

The normal refresh handling flow in PWA Kit automatically invokes the `login` action in this manner when an agent access token is present.

## Sample UI Implementation

This sample code implements a new component, a `TrustedAgentBanner`. We place this component in our PWA Kit applications `app/components` directory.

```javascript
import React, {useState} from 'react'
import {useLocation} from 'react-router-dom'

import {
  Box,
  Button,
  Center,
  Flex,
  Input,
  Text
} from '@salesforce/retail-react-app/app/components/shared/ui'

import {useTrustedAgent} from '@salesforce/commerce-sdk-react'

const TrustedAgentBanner = () => {
  const {isAgent, agentId, loginId, login, logout} = useTrustedAgent()
  const [inputValue, setInputValue] = useState(loginId === 'Guest' ? 'guest' : loginId)
  const location = useLocation()
  const searchParams = new URLSearchParams(location.search)
  const showAgentBanner = searchParams.has('showAgentBanner')

  // Only show banner if isAgent is true OR showAgentBanner query param is present
  if (!isAgent && !showAgentBanner) {
    return null
  }

  return (
    <Box px={8} py={2} bg="gray.100">
      <Flex>
        <Center>
          <Text as="h2" color={'black'} fontWeight={700} fontSize={20} pr={8}>
            Trusted Agent
          </Text>
        </Center>
        <Center>
          {agentId && (
            <>
              <Text as="div" fontWeight={700} fontSize={16} px={4}>
                Agent ID
              </Text>
              <Text as="div">{agentId}</Text>
            </>
          )}
          {isAgent && loginId && (
            <>
              <Text as="div" fontWeight={700} fontSize={16} px={4}>
                Login ID
              </Text>
              <Text as="div">{loginId}</Text>
            </>
          )}
        </Center>
        <Box flex={1} />
        <Center>
          {!isAgent ? (
            <form onSubmit={(e) => (e.preventDefault(), login(inputValue))}>
              <Flex>
                <Input
                  mr={4}
                  bg="white.100"
                  value={inputValue && inputValue !== 'guest' ? inputValue : ''}
                  placeholder="Login ID"
                  onChange={(e) => setInputValue(e.target.value)}
                />
                <Button type="submit">Login</Button>
              </Flex>
            </form>
          ) : (
            <Button onClick={() => logout()}>Logout</Button>
          )}
        </Center>
      </Flex>
    </Box>
  )
}

export default TrustedAgentBanner
```

This component displays a banner at the top of the page when an agent is logged in or when the `showAgentBanner` query parameter is present in the URL. It shows the agent ID and login ID when available, and provides a form for logging in as an agent or a button to logout.

Let's add this component to our PWA Kit application's main layout so that it appears on all pages. Open the `app/_app/index.jsx` file and import the `TrustedAgentBanner` component at the top:

```javascript
// imports...
import TrustedAgentBanner from '@salesforce/retail-react-app/app/components/TrustedAgentBanner'

// inside <App/> component
<>
    <AboveHeader />
    <TrustedAgentBanner />
    <Header
        onMenuClick={onOpen}
// ...
```

This places the `TrustedAgentBanner` above the main `Header` component. Remember this will only display when an agent is logged in or when the `showAgentBanner` query parameter is present.

Finally we need to make a small change to our apps `ssr.js` file in the Express handler for the `/callback` route. This route is used by PWA Kit to handle OAuth redirects. We need to ensure it returns a proper content type to be loaded in our popup window. Open the `ssr.js` file and locate the `/callback` route handler. Update it as follows, adding the `Content-Type` header:

```javascript
app.get('/callback', (req, res) => {
  // This endpoint does nothing and is not expected to change
  // Thus we cache it for a year to maximize performance
  res.set('Cache-Control', `max-age=31536000`)
  // Add this line
  res.set('Content-Type', 'text/plain')
  res.send()
})
```

Now when we test our application, the trusted agent banner should appear by adding a `showAgentBanner` query parameter to the URL. For example: `http://localhost:3000/?showAgentBanner`.

![Custom TAOB Banner Logged Out](https://developer.salesforce.com/docs/media/pwa-kit-managed-runtime/taob-pwa-kit.png)

We can enter a customer login ID or simply click `Login` to login as a guest user. This action opens the Account Manager login page in a popup window. After authenticating, the banner updates to show the agent is logged in:

![Custom TAOB Banner Logged Out](https://developer.salesforce.com/docs/media/pwa-kit-managed-runtime/taob-pwa-kit-logged-in.png)

### Logging In from External Applications

The previous solution uses a banner to allow agents to log in from within the PWA Kit application. In some cases, you may want to allow agents to log in from an external application or portal. This portal could have already initiated the Account Manager login process and therefore an active AM session already exists. In this case, we can adjust the `TrustedAgentBanner` component to accept a query parameter with the target customer ID and automatically trigger the login flow. Update the `TrustedAgentBanner` component as follows:

```javascript
import React, {useState, useEffect} from 'react'

// ...

const TrustedAgentBanner = () => {
    const {isAgent, agentId, loginId, login, logout} = useTrustedAgent()
    const [inputValue, setInputValue] = useState(loginId === 'Guest' ? 'guest' : loginId)
    const location = useLocation()
    const searchParams = new URLSearchParams(location.search)
    const showAgentBanner = searchParams.has('showAgentBanner')
    const trustedAgentCustomerID = searchParams.get('trustedAgentCustomerID')

    useEffect(() => {
        if (!isAgent && trustedAgentCustomerID) {
            // set refresh = true to login in the background
            login(trustedAgentCustomerID, undefined, true)
        }
    }, [isAgent, trustedAgentCustomerID, login])
```

In this example, we read a new `trustedAgentCustomerID` query parameter. If this parameter is present and no agent is currently logged in, we automatically call the `login` action with this customer ID (this can be set to `guest` as well) and set the `refresh` parameter to `true` (because an Account Manager Session already exists). The `login` action triggers the login flow in the background without focusing the popup window.

**note:** In order for the popup window to open in this scenario, you must ensure that your browser allows popups always. In Chrome, this can be done under the site settings for your PWA Kit application domain by setting the "Pop-ups and redirects" setting to "Allow".
