Contains functions for verifying fulfillment service requests. See the [fulfillment service documentation](https://shopify.dev/docs/apps/fulfillment/fulfillment-service-apps) for more information.
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();
};
Verifies requests coming from Shopify to fulfillment service apps
request: Request
export type AuthenticateFulfillmentService< Resources extends ShopifyRestResources = ShopifyRestResources, > = (request: Request) => Promise<FulfillmentServiceContext<Resources>>;
A session with an offline token for the shop. Returned only if there is a session for the shop.
An admin context for the fulfillment service request. Returned only if there is a session for the shop.
The payload from the fulfillment service request.
Stores App information from logged in merchants so they can make authenticated requests to the Admin API.
The unique identifier for the session.
The Shopify shop domain, such as `example.myshopify.com`.
The state of the session. Used for the OAuth authentication code flow.
Whether the access token in the session is online or offline.
The desired scopes for the access token, at the time the session was created.
The date the access token expires.
The access token for the session.
Information on the user for the session. Only present for online sessions.
Whether the session is active. Active sessions have an access token that is not expired, and has the given scopes.
Whether the access token has the given scopes.
Whether the access token is expired.
Converts an object with data into a Session.
Checks whether the given session is equal to this session.
Converts the session into an array of key-value pairs.
How long the access token is valid for, in seconds.
The effective set of scopes for the session.
The user associated with the access token.
The user's ID.
The user's first name.
The user's last name.
The user's email address.
Whether the user has verified their email address.
Whether the user is the account owner.
The user's locale.
Whether the user is a collaborator.
A class that represents a set of access token scopes.
Checks whether the current set of scopes includes the given one.
Checks whether the current set of scopes equals the given one.
Returns a comma-separated string with the current set of scopes.
Returns an array with the current set of scopes.
The unique identifier for the session.
The Shopify shop domain.
The state of the session. Used for the OAuth authentication code flow.
Whether the access token in the session is online or offline.
The scopes for the access token.
The date the access token expires.
The access token for the session.
Information on the user for the session. Only present for online sessions.
Omit<OnlineAccessInfo, 'associated_user'> & { associated_user: Partial<OnlineAccessUser>; }
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.
Methods for interacting with the Shopify Admin GraphQL API
RemixRestClient & {resources: Resources}
Performs a GET request on the given path.
Performs a POST request on the given path.
Performs a PUT request on the given path.
Performs a DELETE request on the given path.
The path to the resource, relative to the API version root.
The type of data expected in the response.
The request body.
Query parameters to be sent with the request.
Additional headers to be sent with the request.
The maximum number of times the request can be made if it fails with a throttling or server error.
Headers to be sent with the request.
Record<string, string | number | string[]>
GetRequestParams & { data: Record<string, any> | string; }
query: Operation extends keyof Operations
options: GraphQLQueryOptions<Operation, Operations>
export type GraphQLClient<Operations extends AllOperations> = < Operation extends keyof Operations, >( query: Operation, options?: GraphQLQueryOptions<Operation, Operations>, ) => Promise<GraphQLResponse<Operation, Operations>>;
The variables to pass to the operation.
The version of the API to use for the request.
Additional headers to include in the request.
The total number of times to try the request if it fails.
Contains functions for verifying fulfillment service requests. See the [fulfillment service documentation](https://shopify.dev/docs/apps/fulfillment/fulfillment-service-apps) for more information.
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();
};
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 });
}
/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();