--- title: Fulfillment Service description: >- Contains functions for verifying fulfillment service requests. See the [fulfillment service documentation](https://shopify.dev/docs/apps/fulfillment/fulfillment-service-apps) for more information. api_version: v2 api_name: shopify-app-remix source_url: html: >- https://shopify.dev/docs/api/shopify-app-remix/v2/authenticate/fulfillment-service md: >- https://shopify.dev/docs/api/shopify-app-remix/v2/authenticate/fulfillment-service.md --- # Fulfillment Service Contains functions for verifying fulfillment service requests. See the [fulfillment service documentation](https://shopify.dev/docs/apps/fulfillment/fulfillment-service-apps) for more information. ## authenticate.​fulfillment​Service(**[request](#authenticatefulfillmentservice-propertydetail-request)**​) Verifies requests coming from Shopify to fulfillment service apps ### Parameters * **request** **Request** **required** ### Returns * **Promise\>** ### FulfillmentServiceContext * session A session with an offline token for the shop. Returned only if there is a session for the shop. ```ts Session ``` * admin An admin context for the fulfillment service request. Returned only if there is a session for the shop. ```ts AdminApiContext ``` * payload The payload from the fulfillment service request. ```ts Record & { kind: string; } ``` ### Session Stores App information from logged in merchants so they can make authenticated requests to the Admin API. * id The unique identifier for the session. ```ts string ``` * shop The Shopify shop domain, such as \`example.myshopify.com\`. ```ts string ``` * state The state of the session. Used for the OAuth authentication code flow. ```ts string ``` * isOnline Whether the access token in the session is online or offline. ```ts boolean ``` * scope The desired scopes for the access token, at the time the session was created. ```ts string ``` * expires The date the access token expires. ```ts Date ``` * accessToken The access token for the session. ```ts string ``` * onlineAccessInfo Information on the user for the session. Only present for online sessions. ```ts OnlineAccessInfo ``` * isActive Whether the session is active. Active sessions have an access token that is not expired, and has the given scopes. ```ts (scopes: string | string[] | AuthScopes) => boolean ``` * isScopeChanged Whether the access token has the given scopes. ```ts (scopes: string | string[] | AuthScopes) => boolean ``` * isExpired Whether the access token is expired. ```ts (withinMillisecondsOfExpiry?: number) => boolean ``` * toObject Converts an object with data into a Session. ```ts () => SessionParams ``` * equals Checks whether the given session is equal to this session. ```ts (other: Session) => boolean ``` * toPropertyArray Converts the session into an array of key-value pairs. ```ts (returnUserData?: boolean) => [string, string | number | boolean][] ``` ### OnlineAccessInfo * expires\_in How long the access token is valid for, in seconds. ```ts number ``` * associated\_user\_scope The effective set of scopes for the session. ```ts string ``` * associated\_user The user associated with the access token. ```ts OnlineAccessUser ``` ### OnlineAccessUser * id The user's ID. ```ts number ``` * first\_name The user's first name. ```ts string ``` * last\_name The user's last name. ```ts string ``` * email The user's email address. ```ts string ``` * email\_verified Whether the user has verified their email address. ```ts boolean ``` * account\_owner Whether the user is the account owner. ```ts boolean ``` * locale The user's locale. ```ts string ``` * collaborator Whether the user is a collaborator. ```ts boolean ``` ### AuthScopes A class that represents a set of access token scopes. * has Checks whether the current set of scopes includes the given one. ```ts (scope: string | string[] | AuthScopes) => boolean ``` * equals Checks whether the current set of scopes equals the given one. ```ts (otherScopes: string | string[] | AuthScopes) => boolean ``` * toString Returns a comma-separated string with the current set of scopes. ```ts () => string ``` * toArray Returns an array with the current set of scopes. ```ts () => any[] ``` ### SessionParams * \[key: string] ```ts any ``` * id The unique identifier for the session. ```ts string ``` * shop The Shopify shop domain. ```ts string ``` * state The state of the session. Used for the OAuth authentication code flow. ```ts string ``` * isOnline Whether the access token in the session is online or offline. ```ts boolean ``` * scope The scopes for the access token. ```ts string ``` * expires The date the access token expires. ```ts Date ``` * accessToken The access token for the session. ```ts string ``` * onlineAccessInfo Information on the user for the session. Only present for online sessions. ```ts OnlineAccessInfo | StoredOnlineAccessInfo ``` ### StoredOnlineAccessInfo ```ts Omit & { associated_user: Partial; } ``` ### AdminApiContext * rest Methods for interacting with the Shopify Admin REST API There are methods for interacting with individual REST resources. You can also make \`GET\`, \`POST\`, \`PUT\` and \`DELETE\` requests should the REST resources not meet your needs. ```ts RestClientWithResources ``` * graphql Methods for interacting with the Shopify Admin GraphQL API ```ts GraphQLClient ``` ### RestClientWithResources ```ts RemixRestClient & {resources: Resources} ``` ### RemixRestClient * session ```ts Session ``` * get Performs a GET request on the given path. ```ts (params: GetRequestParams) => Promise ``` * post Performs a POST request on the given path. ```ts (params: PostRequestParams) => Promise ``` * put Performs a PUT request on the given path. ```ts (params: PostRequestParams) => Promise ``` * delete Performs a DELETE request on the given path. ```ts (params: GetRequestParams) => Promise ``` ### GetRequestParams * path The path to the resource, relative to the API version root. ```ts string ``` * type The type of data expected in the response. ```ts DataType ``` * data The request body. ```ts string | Record ``` * query Query parameters to be sent with the request. ```ts SearchParams ``` * extraHeaders Additional headers to be sent with the request. ```ts HeaderParams ``` * tries The maximum number of times the request can be made if it fails with a throttling or server error. ```ts number ``` ### DataType * JSON ```ts application/json ``` * GraphQL ```ts application/graphql ``` * URLEncoded ```ts application/x-www-form-urlencoded ``` ### HeaderParams Headers to be sent with the request. ### PostRequestParams ```ts GetRequestParams & { data: Record | string; } ``` ### GraphQLClient * query ```ts Operation extends keyof Operations ``` * options ```ts GraphQLQueryOptions ``` interface Promise\ { /\*\* \* Attaches callbacks for the resolution and/or rejection of the Promise. \* @param onfulfilled The callback to execute when the Promise is resolved. \* @param onrejected The callback to execute when the Promise is rejected. \* @returns A Promise for the completion of which ever callback is executed. \*/ then\(onfulfilled?: ((value: T) => TResult1 | PromiseLike\) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike\) | undefined | null): Promise\; /\*\* \* Attaches a callback for only the rejection of the Promise. \* @param onrejected The callback to execute when the Promise is rejected. \* @returns A Promise for the completion of the callback. \*/ catch\(onrejected?: ((reason: any) => TResult | PromiseLike\) | undefined | null): Promise\; }, interface Promise\ {}, Promise: PromiseConstructor, interface Promise\ { readonly \[Symbol.toStringTag]: string; }, interface Promise\ { /\*\* \* Attaches a callback that is invoked when the Promise is settled (fulfilled or rejected). The \* resolved value cannot be modified from the callback. \* @param onfinally The callback to execute when the Promise is settled (fulfilled or rejected). \* @returns A Promise for the completion of the callback. \*/ finally(onfinally?: (() => void) | undefined | null): Promise\; } ```ts interface Promise { /** * Attaches callbacks for the resolution and/or rejection of the Promise. * @param onfulfilled The callback to execute when the Promise is resolved. * @param onrejected The callback to execute when the Promise is rejected. * @returns A Promise for the completion of which ever callback is executed. */ then(onfulfilled?: ((value: T) => TResult1 | PromiseLike) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike) | undefined | null): Promise; /** * Attaches a callback for only the rejection of the Promise. * @param onrejected The callback to execute when the Promise is rejected. * @returns A Promise for the completion of the callback. */ catch(onrejected?: ((reason: any) => TResult | PromiseLike) | undefined | null): Promise; }, interface Promise {}, Promise: PromiseConstructor, interface Promise { readonly [Symbol.toStringTag]: string; }, interface Promise { /** * Attaches a callback that is invoked when the Promise is settled (fulfilled or rejected). The * resolved value cannot be modified from the callback. * @param onfinally The callback to execute when the Promise is settled (fulfilled or rejected). * @returns A Promise for the completion of the callback. */ finally(onfinally?: (() => void) | undefined | null): Promise; } ``` ### GraphQLQueryOptions * variables The variables to pass to the operation. ```ts ApiClientRequestOptions["variables"] ``` * apiVersion The version of the API to use for the request. ```ts ApiVersion ``` * headers Additional headers to include in the request. ```ts Record ``` * tries The total number of times to try the request if it fails. ```ts number ``` ### ApiVersion * October22 ```ts 2022-10 ``` * January23 ```ts 2023-01 ``` * April23 ```ts 2023-04 ``` * July23 ```ts 2023-07 ``` * October23 ```ts 2023-10 ``` * January24 ```ts 2024-01 ``` * April24 ```ts 2024-04 ``` * Unstable ```ts unstable ``` Examples ### Examples * #### Consume a fulfillment service notification request ##### Description Handle a fulfillment service notification call ##### /app/routes/\*\*.ts ```typescript import {type ActionFunctionArgs} from '@remix-run/node'; import {authenticate} from '../shopify.server'; export const action = async ({request}: ActionFunctionArgs) => { const {admin, payload} = await authenticate.flow(request); const kind = payload.kind; if(kind === 'FULFILLMENT_REQUEST') { const response = await admin?.graphql( `#graphql query { shop { assignedFulfillmentOrders(first: 10, assignmentStatus: FULFILLMENT_REQUESTED) { edges { node { id destination { firstName lastName } lineItems(first: 10) { edges { node { id productTitle sku remainingQuantity } } } merchantRequests(first: 10, kind: FULFILLMENT_REQUEST) { edges { node { message } } } } } } } }`); const fulfillments = await response.json(); console.log(fulfillments); } return new Response(); }; ``` * #### Shopify session for the fulfillment service notification request ##### Description Use the session associated with this request to use REST resources. ##### /app/routes/fulfillment\_service\_notification.tsx ```typescript import { ActionFunctionArgs } from "@remix-run/node"; import { authenticate } from "../shopify.server"; export const action = async ({ request }: ActionFunctionArgs) => { const { session, admin } = await authenticate.fulfillmentService(request); const products = await admin?.rest.resources.Product.all({ session }); // Use products return new Response(); }; ``` * #### Shopify session for the fulfillment service request ##### Description Use the session associated with this request to use the Admin GraphQL API ##### /app/routes/fulfillment\_order\_notification.ts ```typescript import { ActionFunctionArgs } from "@remix-run/node"; import { authenticate } from "../shopify.server"; export async function action({ request }: ActionFunctionArgs) { const { admin } = await authenticate.fulfillmentService(request); const response = await admin?.graphql( `#graphql query { shop { assignedFulfillmentOrders(first: 10, assignmentStatus: FULFILLMENT_REQUESTED) { edges { node { id destination { firstName lastName } lineItems(first: 10) { edges { node { id productTitle sku remainingQuantity } } } merchantRequests(first: 10, kind: FULFILLMENT_REQUEST) { edges { node { message } } } } } } } }`); const fulfillments = await response.json(); return json({ data: fulfillments.data }); } ``` * #### Fulfillment service request payload ##### Description Get the request's POST payload. ##### Example ```typescript /app/routes/fulfillment_order_notification.ts import { ActionFunction } from "@remix-run/node"; import { authenticate } from "../shopify.server"; export const action: ActionFunction = async ({ request }) => { const { payload } = await authenticate.fulfillmentService(request); if(payload.kind === 'FULFILLMENT_REQUEST') { // handle fulfillment request } else if (payload.kind === 'CANCELLATION_REQUEST') { // handle cancellation request }; return new Response(); ``` ## Related [Interact with the Admin API. - Admin API context](https://shopify.dev/docs/api/shopify-app-remix/apis/admin-api) [Receive fulfillment requests and cancellations. - Manage Fulfillments](https://shopify.dev/docs/apps/fulfillment/fulfillment-service-apps/manage-fulfillments)