【Shopify.dev和訳】Apps/Fulfillments/Fulfillment service apps
この記事について
この記事は、Apps/Fulfillment/Fulfillment service appsの記事を和訳したものです。
記事内で使用する画像は、公式ドキュメント内の画像を引用して使用させていただいております。
Shopify アプリのご紹介
Shopify アプリである、「商品ページ発売予告アプリ | リテリア Coming Soon」は、商品ページを買えない状態のまま、発売日時の予告をすることができるアプリです。Shopify で Coming Soon 機能を実現することができます。
Shopify アプリである、「らくらく日本語フォント設定|リテリア Font Picker」は、ノーコードで日本語フォントを使用できるアプリです。日本語フォントを導入することでブランドを演出することができます。
フルフィルメントサービスアプリとしてフルフィルメントを管理
このガイドでは、フルフィルメントサービスアプリが Shopify でフルフィルメントを管理するために Admin API を使用する方法について説明します。
あなたのアプリが FulfillmentService の場所を管理する場合(ストアオーナーに代わって注文を準備して出荷するサードパーティの倉庫など)、このガイドに従ってください。
お使いのアプリが FulfillmentService ロケーションを管理しておらず、マーチャントまたはサードパーティのロケーションで処理される注文を割り当てている場合は、注文管理アプリとしてフルフィルメントを管理するためのガイドに従うことができます。
概要
フルフィルメントサービスとは、店舗オーナーに代わって注文の準備や発送を行う、サードパーティのウェアハウジング、プリントオンデマンド、フルフィルメントサービスのことです。
Shopify では、各フルフィルメントサービスは専用の場所を持っています。フルフィルメントサービスを作成すると、Shopify は自動的にそのための新しいロケーションを作成します。
フルフィルメントサービスは、GraphQL Admin API では FulfillmentService オブジェクトとして表されます。
フルフィルメントサービスは、マーチャントからフルフィルメントサービスに送信された特定のリクエストを表す FulfillmentOrderMerchantRequest をリッスンすることで、何をいつ処理するかを知ることができます。
例えば、マーチャントがフルフィルメントサービスに所定のフルフィルメントオーダーを満たすためのリクエストを提出したとします。マーチャントが提供したメモを含むリクエストデータは、FulfillmentOrder
の一部として利用可能なFulfillmentOrderMerchantRequest
を通じて API アクセスが可能になります。
FulfillmentService アプリの機能
フルフィルメントサービスとして登録されているアプリは、フルフィルメントオーダーを使って以下のことができます。
- フルフィルメントリクエストとキャンセルリクエストを、Webhooks に頼らず、登録されたコールバック URL(
callback_url/fulfillment_order_notification
)で受け取る。これは、Shopify からのリクエストを受け取るための要件です。この仕組みの詳細については、Receiving FULFILLMENT_REQUEST and CANCELLATION_REQUEST notificationsをご覧ください。 - フルフィルメント要求を明示的に受け入れるか拒否することで、アプリがフルフィルメントを実行する意図があるかどうかをマーチャントに示す。
- マーチャントから送られてきたフルフィルメントのキャンセル要求を受理または拒否する。
- フルフィルメントを受理、拒否、または作成する際に、マーチャントとフルフィルメント リクエスト ノートを交換し、コミュニケーションを促進する。
- 複数のパッケージを表現するために、所定のフルフィルメントオーダーに対して複数のフルフィルメントを作成する。
- 自分に割り当てられた仕事に対してのみフルフィルメントを実行する
- アプリがフルフィルメント要求を受け入れた後、いつでもフルフィルメントを作成し、それをフルフィルメントとしてマークする。
- 一部の作業のみを実行した後、フルフィルメントオーダーを閉じる。
はじめに
フルフィルメントリクエストを受信する前に、まずテストストアにいくつかの未達成の注文がある必要があります。テスト注文を作成する方法については、チュートリアルManage test orders with the REST Admin APIを参照してください。
また、このカテゴリに該当するアプリは、OAuthを使用して以下のパーミッションを要求する必要があります。
- 自分のロケーションに割り当てられたフルフィルメント注文を管理するための
write_assigned_fulfillment_orders
の読み取りおよび書き込み権限
登録
最初のステップは、フルフィルメントリクエストを受け付けるコールバック URL を持つフルフィルメントサービスを Shopify に作成することです。
新しいフルフィルメントサービスを作成する手順は、GraphQLとRESTのリファレンスドキュメントに記載されています。
フルフィルメントサービスは、注文ベースのフルフィルメントではなく FulfillmentOrder ベースのフルフィルメントを実行する準備ができていることを Shopify に知らせることで、注文のフルフィルメントを選択する必要があります。これは 1 つのリクエストで行われ、私たちの移行ガイドで詳しく説明されています。
FULFILLMENT_REQUEST および CANCELLATION_REQUEST 通知の受信
アプリは、Shopify がフルフィルメントリクエストの通知を送信するコールバック URL のエンドポイントを設定する必要があります。このエンドポイントは以下の形式で構成する必要があります。<callback_url>/fulfillment_order_notification
.
このエンドポイントが受け取るペイロードには、FULFILLMENT_REQUEST
または CANCELLATION_REQUEST
のいずれかである kind
というフィールドが含まれています。マーチャントが Shopify 管理者からフルフィルメントを要求した場合、Shopify はフルフィルメントサービスに種類がFULFILLMENT_REQUEST
に設定された通知を送ります。この場合、コールバック URL に送信されるリクエストのボディには、{"kind": "FULFILLMENT_REQUEST"}
が含まれています。マーチャントがキャンセルリクエストを送信した場合、ボディには{"kind": "CANCELLATION_REQUEST"}
が含まれます。
以下に、各タイプのリクエストに対するペイロードの例を示します。
FULFILLMENT_REQUEST
{
"kind": "FULFILLMENT_REQUEST"
}
CANCELLATION_REQUEST
{
"kind": "CANCELLATION_REQUEST"
}
FULFILLMENT_REQUEST の通知を受けての行動
FULFILLMENT_REQUEST
のフルフィルメントオーダー通知は、サービスに割り当てられた新しいフルフィルメントオーダーがあり、それが(マーチャントがフルフィルメントを要求したので)行動する準備ができていることを示します。
フルフィルメント・サービスは、shop
オブジェクトの下で公開されている assignedFulfillmentOrders
コネクションを照会し、オプションとして、FULFILLMENT_REQUESTED
に設定された assignmentStatus
を渡すことが期待されます。
フルフィルメントサービスは、指定されたフルフィルメントリクエストを受け入れるか拒否するかを決定するために必要なフィールドを指定することができます。
次の例では、クエリはフルフィルメントオーダーの宛先、ラインアイテム、ラインアイテムの SKU を要求し、マーチャントのリクエストには、マーチャントがリクエストを送信した際に提供したメモが含まれています。
GraphQL
POST https://{shop}.myshopify.com/admin/api/2021-07/graphql.json
Request
query {
shop {
assignedFulfillmentOrders(first: 10, assignmentStatus: FULFILLMENT_REQUESTED) {
edges {
node {
id
destination {
firstName
lastName
address1
city
province
zip
countryCode
phone
}
lineItems(first: 10) {
edges {
node {
id
lineItem {
name
sku
}
remainingQuantity
}
}
}
merchantRequests(first: 10, kind: FULFILLMENT_REQUEST) {
edges {
node {
message
}
}
}
}
}
}
}
}
Response
{
"data": {
"shop": {
"assignedFulfillmentOrders": {
"edges": [
{
"node": {
"id": "gid://shopify/FulfillmentOrder/5018595819542",
"destination": {
"firstName": "Benedict",
"lastName": "Ankunding",
"address1": "1318 Bloor St.",
"city": "Innisfree",
"province": "Alberta",
"zip": "T0B2G0",
"countryCode": "CA",
"phone": null
},
"lineItems": {
"edges": [
{
"node": {
"id": "gid://shopify/FulfillmentOrderLineItem/10926793228310",
"lineItem": {
"name": "Billowing Brook Cap",
"sku": "BBC-1"
},
"remainingQuantity": 3
}
}
]
},
"merchantRequests": {
"edges": [
{
"node": {
"message": "Please fulfill ASAP"
}
}
]
}
}
}
]
}
}
}
}
REST API
GET https://{shop}.myshopify.com/admin/api/2021-07/assigned_fulfillment_orders.json?assignment_status=fulfillment_requested
Response
{
"fulfillment_orders": [
{
"id": 5018595819542,
"shop_id": 6587023382,
"order_id": 4063714836502,
"assigned_location_id": 61208625174,
"request_status": "submitted",
"status": "open",
"supported_actions": ["cancel_fulfillment_order"],
"destination": {
"id": 4793449578518,
"address1": "1318 Bloor St.",
"address2": "",
"city": "Innisfree",
"company": "",
"country": "Canada",
"email": "benedict.ankunding@testemail.com",
"first_name": "Benedict",
"last_name": "Ankunding",
"phone": null,
"province": "Alberta",
"zip": "T0B2G0"
},
"line_items": [
{
"id": 10926793228310,
"shop_id": 6587023382,
"fulfillment_order_id": 5018595819542,
"quantity": 3,
"line_item_id": 10840452497430,
"inventory_item_id": 19848968437782,
"fulfillable_quantity": 3,
"variant_id": 19523142352918
}
],
"outgoing_requests": [
{
"message": "Please fulfill ASAP",
"request_options": {
"notify_customer": false
},
"sent_at": "2021-06-24T15:02:03-04:00",
"kind": "fulfillment_request"
}
],
"fulfill_at": null,
"international_duties": null,
"delivery_method": null,
"assigned_location": {
"address1": null,
"address2": null,
"city": null,
"country_code": "CA",
"location_id": 61208625174,
"name": "Very Good Fulfillment Company",
"phone": null,
"province": null,
"zip": null
}
}
]
}
フルフィルメントサービスは、上記で要求された各フルフィルメントオーダーを検討し、それが履行可能かどうかを決定することができる。与えられたフルフィルメントオーダーを受諾するために、フルフィルメントサービスは、fillupmentOrderAcceptFulfillmentRequestミューテーションを使用して、accept
要求を送信しなければならない。また、オプションのメッセージを送信することもできる。
GraphQL
POST https://{shop}.myshopify.com/admin/api/2021-07/graphql.json
Request
mutation acceptFulfillmentRequest($id: ID!, $message: String) {
fulfillmentOrderAcceptFulfillmentRequest(id: $id, message: $message) {
fulfillmentOrder {
status
requestStatus
}
}
}
Variables
{
"id": "gid://shopify/FulfillmentOrder/5014440902678",
"message": "Reminder that tomorrow is a holiday, we won't be able to ship this until Monday"
}
Response
{
"data": {
"fulfillmentOrderAcceptFulfillmentRequest": {
"fulfillmentOrder": {
"status": "IN_PROGRESS",
"requestStatus": "ACCEPTED"
},
"userErrors": []
}
}
}
REST API
POST https://{shop}.myshopify.com/admin/api/2021-07/fulfillment_orders/{fulfillment_order_id}/fulfillment_request/accept.json
{
"fulfillment_request": {
"message": "Reminder that tomorrow is a holiday, we won't be able to ship this until Monday"
}
}
Response
{
"fulfillment_order": {
"id": 5019418001430,
"shop_id": 6587023382,
"order_id": 4064536756246,
"assigned_location_id": 61208625174,
"request_status": "accepted",
"status": "in_progress",
"supported_actions": ["request_cancellation", "create_fulfillment"],
"destination": {
"id": 4794270547990,
"address1": "1318 Bloor St.",
"address2": "",
"city": "Innisfree",
"company": "",
"country": "Canada",
"email": "benedict.ankunding@testemail.com",
"first_name": "Benedict",
"last_name": "Ankunding",
"phone": null,
"province": "Alberta",
"zip": "T0B2G0"
},
"origin": {
"address1": null,
"address2": null,
"city": null,
"country_code": "CA",
"location_id": 61208625174,
"name": "Very Good Fulfillment Company",
"phone": null,
"province": null,
"zip": null
},
"line_items": [
{
"id": 10927617310742,
"shop_id": 6587023382,
"fulfillment_order_id": 5019418001430,
"quantity": 3,
"line_item_id": 10841276022806,
"inventory_item_id": 19848968437782,
"fulfillable_quantity": 3,
"variant_id": 19523142352918
}
],
"outgoing_requests": [
{
"message": "",
"request_options": {
"notify_customer": false
},
"sent_at": "2021-06-24T15:38:21-04:00",
"kind": "fulfillment_request"
}
],
"fulfillment_service_handle": "very-good-fulfillment-company",
"fulfill_at": null,
"delivery_method": null
}
}
フルフィルメントサービスがアクセプトリクエストを送信した後、Shopify 管理画面のフルフィルメントオーダーカードには、リクエストがaccept
されたことがマーチャントに表示されます。
フルフィルメントサービスが注文を満たすことができないと判断した場合、フルフィルメントOrderRejectFulfillmentRequestミューテーションを使用してフルフィルメントリクエストを拒否する。
GraphQL
POST https://{shop}.myshopify.com/admin/api/2021-07/graphql.json
Request
mutation rejectFulfillmentRequest($id: ID!, $message: String) {
fulfillmentOrderRejectFulfillmentRequest(id: $id, message: $message) {
fulfillmentOrder {
status
requestStatus
}
}
}
Variables
{
"id": "gid://shopify/FulfillmentOrder/5014440902678",
"message": "We weren't able to find this product in the warehouse, sorry!"
}
Response
{
"data": {
"fulfillmentOrderRejectFulfillmentRequest": {
"fulfillmentOrder": {
"status": "OPEN",
"requestStatus": "REJECTED"
},
"userErrors": []
}
}
}
REST API
POST https://{shop}.myshopify.com/admin/api/2021-07/fulfillment_orders/{fulfillment_order_id}/fulfillment_request/reject.json
{
"fulfillment_request": {
"message": "We weren't able to find this product in the warehouse, sorry!"
}
}
Response
{
"fulfillment_order": {
"id": 5019418263574,
"shop_id": 6587023382,
"order_id": 4064537018390,
"assigned_location_id": 61208625174,
"request_status": "rejected",
"status": "open",
"supported_actions": ["request_fulfillment", "create_fulfillment"],
"destination": {
"id": 4794270679062,
"address1": "1318 Bloor St.",
"address2": "",
"city": "Innisfree",
"company": "",
"country": "Canada",
"email": "benedict.ankunding@testemail.com",
"first_name": "Benedict",
"last_name": "Ankunding",
"phone": null,
"province": "Alberta",
"zip": "T0B2G0"
},
"origin": {
"address1": null,
"address2": null,
"city": null,
"country_code": "CA",
"location_id": 61208625174,
"name": "Very Good Fulfillment Company",
"phone": null,
"province": null,
"zip": null
},
"line_items": [
{
"id": 10927617769494,
"shop_id": 6587023382,
"fulfillment_order_id": 5019418263574,
"quantity": 3,
"line_item_id": 10841276481558,
"inventory_item_id": 19848968437782,
"fulfillable_quantity": 3,
"variant_id": 19523142352918
}
],
"outgoing_requests": [
{
"message": "",
"request_options": {
"notify_customer": false
},
"sent_at": "2021-06-24T15:41:44-04:00",
"kind": "fulfillment_request"
},
{
"message": "",
"request_options": {
"notify_customer": false
},
"sent_at": "2021-06-24T15:45:10-04:00",
"kind": "fulfillment_request"
}
],
"fulfillment_service_handle": "very-good-fulfillment-company",
"fulfill_at": null,
"delivery_method": null
}
}
この場合、Shopify 管理画面のフルフィルメントオーダーカードには、リクエストが拒否されたことがマーチャントに表示されます。
フルフィルメントの作成
フルフィルメントリクエストを受理した後、フルフィルメントサービスはフルフィルメントの作成を開始することができます。
フルフィルメントサービスがフルフィルメント要求を受諾する前に、フルフィルメントをフルフィルメント注文に対して作成することはできないことに留意されたい。
フルフィルメントサービスは、必要に応じて、出荷される複数のパッケージを表すために、特定のフルフィルメントオーダーに対して複数のフルフィルメントを作成することができる。
アプリがフルフィルメント要求を受け入れると、フルフィルメントオーダーのステータスはIN_PROGRESS
に遷移します。
フルフィルメントオーダー上のすべてのラインアイテムが完全に満たされた後、フルフィルメントオーダーステータスはCLOSED
状態に移行します。
個々の lineItemsByFulfillmentOrder.fulfillmentOrderLineItems
が提供されていない場合、アプリは残りのすべてのラインアイテムに対してフルフィルメントを作成します。
GraphQL
POST https://{shop}.myshopify.com/admin/api/2021-07/graphql.json
Request
mutation fulfillmentCreateV2($fulfillment: FulfillmentV2Input!) {
fulfillmentCreateV2(fulfillment: $fulfillment) {
fulfillment {
id
status
trackingInfo {
company
number
url
}
}
userErrors {
field
message
}
}
}
Varibales
{
"fulfillment": {
"notifyCustomer": false,
"trackingInfo": {
"company": "my-shipping-company",
"number": "1562678",
"url": "https://www.my-shipping-company.com"
},
"lineItemsByFulfillmentOrder": [
{
"fulfillmentOrderId": "gid://shopify/FulfillmentOrder/5018595819542",
"fulfillmentOrderLineItems": {
"id": "gid://shopify/FulfillmentOrderLineItem/10926793228310",
"quantity": 3
}
}
]
}
}
Response
{
"data": {
"fulfillmentCreateV2": {
"fulfillment": {
"id": "gid://shopify/Fulfillment/3286469410838",
"status": "SUCCESS",
"trackingInfo": [
{
"company": "my-shipping-company",
"number": "1562678",
"url": "https://www.my-shipping-company.com"
}
]
},
"userErrors": []
}
}
}
REST API
POST https://{shop}.myshopify.com/admin/api/2021-07/fulfillments.json
{
"fulfillment": {
"message": "The package was shipped this morning.",
"notify_customer": false,
"tracking_info": {
"number": 1562678,
"url": "https://www.my-shipping-company.com",
"company": "my-shipping-company"
},
"line_items_by_fulfillment_order": [
{
"fulfillment_order_id": 5019418001430,
"fulfillment_order_line_items": [
{
"id": 10927617310742,
"quantity": 3
}
]
}
]
}
}
Response
{
"fulfillment": {
"id": 3286471016470,
"order_id": 4064536756246,
"status": "success",
"created_at": "2021-06-24T16:24:15-04:00",
"service": "very-good-fulfillment-company",
"updated_at": "2021-06-24T16:24:15-04:00",
"tracking_company": "my-shipping-company",
"shipment_status": null,
"location_id": 61208625174,
"line_items": [
{
"id": 10841276022806,
"variant_id": 19523142352918,
"title": "Billowing Brook Cap",
"quantity": 3,
"sku": "BBC-1",
"variant_title": "",
"vendor": "graphql-admin",
"fulfillment_service": "very-good-fulfillment-company",
"product_id": 1974227435542,
"requires_shipping": true,
"taxable": true,
"gift_card": false,
"name": "Billowing Brook Cap",
"variant_inventory_management": "shopify",
"properties": [],
"product_exists": true,
"fulfillable_quantity": 0,
"grams": 500,
"price": "120.00",
"total_discount": "0.00",
"fulfillment_status": "fulfilled",
"price_set": {
"shop_money": {
"amount": "120.00",
"currency_code": "CAD"
},
"presentment_money": {
"amount": "120.00",
"currency_code": "CAD"
}
},
"total_discount_set": {
"shop_money": {
"amount": "0.00",
"currency_code": "CAD"
},
"presentment_money": {
"amount": "0.00",
"currency_code": "CAD"
}
},
"discount_allocations": [],
"duties": [],
"admin_graphql_api_id": "gid://shopify/LineItem/10841276022806",
"tax_lines": [],
"origin_location": {
"id": 2849710276630,
"country_code": "CA",
"province_code": "ON",
"name": "graphql-admin",
"address1": "151 O'Connor Street",
"address2": "1st Floor",
"city": "Ottawa",
"zip": "K2P 2L8"
},
"destination_location": {
"id": 2849710309398,
"country_code": "CA",
"province_code": "AB",
"name": "Benedict Ankunding",
"address1": "1318 Bloor St.",
"address2": "",
"city": "Innisfree",
"zip": "T0B2G0"
}
}
],
"tracking_number": "1562678",
"tracking_numbers": ["1562678"],
"tracking_url": "https://www.my-shipping-company.com",
"tracking_urls": ["https://www.my-shipping-company.com"],
"receipt": {},
"name": "#1015.1",
"admin_graphql_api_id": "gid://shopify/Fulfillment/3286471016470"
}
}
CANCEL_REQUEST 通知の受信
キャンセルのリクエストは、<callback_url>/fulfillment_order_notification
の通知エンドポイント URL にも送信できます。リクエストのペイロードには、CANCELLATION_REQUEST
という値を持つ種類が含まれています。マーチャントは Shopify の管理画面で、以下のメニューを使ってキャンセルを要求することができます。
これにより、キャンセル要求を送信するためのモーダルが表示され、マーチャントはフルフィルメントサービスにこのキャンセル要求に関する具体的なメモを追加することができます。
モーダルが送信された後、フルフィルメントオーダーカードは、この仕事が現在キャンセル待ちであることを示します。
マーチャントが発行する CANCEL_REQUEST 通知への対応
CANCELLATION_REQUEST
タイプのフルフィルメントオーダー通知を受信すると、マーチャントがフルフィルメントオーダーのキャンセルを要求したことを示します。フルフィルメント要求に対処するのと同様に、フルフィルメントサービスは assignedFulfillmentOrders
を照会し、引数assignmentStatus
を渡すべきですが、代わりに CANCELLATION_REQUESTED
を設定してください。
GraphQL
POST https://{shop}.myshopify.com/admin/api/2021-07/graphql.json
Request
query {
shop {
assignedFulfillmentOrders(first: 10, assignmentStatus: CANCELLATION_REQUESTED) {
edges {
node {
id
destination {
firstName
lastName
address1
city
province
zip
countryCode
phone
}
lineItems(first: 10) {
edges {
node {
id
lineItem {
name
sku
}
remainingQuantity
}
}
}
merchantRequests(first: 10, kind: CANCELLATION_REQUEST) {
edges {
node {
message
}
}
}
}
}
}
}
}
Response
{
"data": {
"shop": {
"assignedFulfillmentOrders": {
"edges": [
{
"node": {
"id": "gid://shopify/FulfillmentOrder/5018595819542",
"destination": {
"firstName": "Benedict",
"lastName": "Ankunding",
"address1": "1318 Bloor St.",
"city": "Innisfree",
"province": "Alberta",
"zip": "T0B2G0",
"countryCode": "CA",
"phone": null
},
"lineItems": {
"edges": [
{
"node": {
"id": "gid://shopify/FulfillmentOrderLineItem/10926793228310",
"lineItem": {
"name": "Billowing Brook Cap",
"sku": "BBC-1"
},
"remainingQuantity": 3
}
}
]
},
"merchantRequests": {
"edges": [
{
"node": {
"message": "Please cancel, the customer changed their mind!"
}
}
]
}
}
}
]
}
}
}
}
REST API
GET https://{shop}.myshopify.com/admin/api/2021-07/assigned_fulfillment_orders.json?assignment_status=cancellation_requested
Response
{
"fulfillment_orders": [
{
"id": 5019418263574,
"shop_id": 6587023382,
"order_id": 4064537018390,
"assigned_location_id": 61208625174,
"request_status": "cancellation_requested",
"status": "in_progress",
"supported_actions": ["cancel_fulfillment_order", "create_fulfillment"],
"destination": {
"id": 4793449578518,
"address1": "1318 Bloor St.",
"address2": "",
"city": "Innisfree",
"company": "",
"country": "Canada",
"email": "benedict.ankunding@testemail.com",
"first_name": "Benedict",
"last_name": "Ankunding",
"phone": null,
"province": "Alberta",
"zip": "T0B2G0"
},
"line_items": [
{
"id": 10926793228310,
"shop_id": 6587023382,
"fulfillment_order_id": 5018595819542,
"quantity": 3,
"line_item_id": 10840452497430,
"inventory_item_id": 19848968437782,
"fulfillable_quantity": 3,
"variant_id": 19523142352918
}
],
"outgoing_requests": [
{
"message": "Please fulfill ASAP",
"request_options": {
"notify_customer": false
},
"sent_at": "2021-06-24T15:02:03-04:00",
"kind": "fulfillment_request"
},
{
"message": "Please cancel, the customer changed their mind!",
"request_options": {},
"sent_at": "2021-06-24T16:36:56-04:00",
"kind": "cancellation_request"
}
],
"fulfill_at": null,
"international_duties": null,
"delivery_method": null,
"assigned_location": {
"address1": null,
"address2": null,
"city": null,
"country_code": "CA",
"location_id": 61208625174,
"name": "Very Good Fulfillment Company",
"phone": null,
"province": null,
"zip": null
}
}
]
}
フルフィルメントサービスは、キャンセル要求を受け入れるか拒否するまで、このリストに返されたフルフィルメントオーダーに対してフルフィルメントを作成することはできません。フルフィルメントサービスは、各フルフィルメントオーダーを確認し、それらがキャンセルできるかどうかを判断することができる。もし可能であれば、フルフィルメントサービスは、オプションのメッセージとともにフルフィルメントオーダーのキャンセルを受け入れるために、fruffmentOrderAcceptCancellationRequestミューテーションを使用してリクエストを提出することができる。これはrequestStatus
が CANCELLATION_ACCEPTED
であるフルフィルメントオーダーの結果です。
GraphQL
POST https://{shop}.myshopify.com/admin/api/2021-07/graphql.json
Request
mutation acceptCancellationRequest($id: ID!, $message: String) {
fulfillmentOrderAcceptCancellationRequest(id: $id, message: $message) {
fulfillmentOrder {
status
requestStatus
}
}
}
Varibales
{
"id": "gid://shopify/FulfillmentOrder/5019418263574",
"message": "Item was not picked and packed yet, cancelling as requested"
}
Response
{
"data": {
"fulfillmentOrderAcceptCancellationRequest": {
"fulfillmentOrder": {
"status": "CANCELLED",
"requestStatus": "CANCELLATION_ACCEPTED"
}
}
}
}
REST API
POST https://{shop}.myshopify.com/admin/api/2021-07/fulfillment_orders/{fulfillment_order_id}/fulfillment_request/accept.json
{
"fulfillment_request": {
"message": "Item was not picked and packed yet, cancelling as requested"
}
}
Response
{
"fulfillment_order": {
"id": 5020241428502,
"shop_id": 6587023382,
"order_id": 4064537018390,
"assigned_location_id": 61208625174,
"request_status": "cancellation_accepted",
"status": "cancelled",
"supported_actions": ["request_fulfillment", "create_fulfillment"],
"destination": {
"id": 4795091025942,
"address1": "1318 Bloor St.",
"address2": "",
"city": "Innisfree",
"company": "",
"country": "Canada",
"email": "benedict.ankunding@testemail.com",
"first_name": "Benedict",
"last_name": "Ankunding",
"phone": null,
"province": "Alberta",
"zip": "T0B2G0"
},
"origin": {
"address1": null,
"address2": null,
"city": null,
"country_code": "CA",
"location_id": 61208625174,
"name": "Very Good Fulfillment Company",
"phone": null,
"province": null,
"zip": null
},
"line_items": [
{
"id": 10928446242838,
"shop_id": 6587023382,
"fulfillment_order_id": 5020241428502,
"quantity": 3,
"line_item_id": 10841276481558,
"inventory_item_id": 19848968437782,
"fulfillable_quantity": 3,
"variant_id": 19523142352918
}
],
"outgoing_requests": [
{
"message": "",
"request_options": {
"notify_customer": false
},
"sent_at": "2021-06-24T16:45:53-04:00",
"kind": "fulfillment_request"
},
{
"message": "Customer changed their mind!",
"request_options": {},
"sent_at": "2021-06-24T16:46:38-04:00",
"kind": "cancellation_request"
}
],
"fulfillment_service_handle": "very-good-fulfillment-company",
"fulfill_at": null,
"delivery_method": null
}
}
フルフィルメントサービスがキャンセル依頼を受理した後、Shopify 管理画面のフルフィルメントオーダーカードに、キャンセル依頼が受理されたことがマーチャントに表示されます。
フルフィルメントサービスが、フルフィルメントオーダーのキャンセルを受け入れることができないと判断した場合、fulfillmentOrderRejectCancellationRequestミューテーションを使用してキャンセル要求を拒否する。これは requestStatus
が CANCELLATION_REJECTED
であるフルフィルメントオーダーの結果である。フルフィルメントサービスは、キャンセルを拒否した後もフルフィルメントの作成を続けることができる。
GraphQL
POST https://{shop}.myshopify.com/admin/api/2021-07/graphql.json
Request
mutation rejectCancellationRequest($id: ID!, $message: String) {
fulfillmentOrderRejectCancellationRequest(id: $id, message: $message) {
fulfillmentOrder {
status
requestStatus
}
}
}
Variables
{
"id": "gid://shopify/FulfillmentOrder/5020276391958",
"message": "This was already picked up by the courier"
}
Response
{
"data": {
"fulfillmentOrderRejectCancellationRequest": {
"fulfillmentOrder": {
"status": "IN_PROGRESS",
"requestStatus": "CANCELLATION_REJECTED"
}
}
}
REST API
POST https://{shop}.myshopify.com/admin/api/2021-07/fulfillment_orders/{fulfillment_order_id}/fulfillment_request/reject.json
{
"fulfillment_request": {
"message": "This was already picked up by the courier"
}
}
Response
{
"fulfillment_order": {
"id": 5020795797526,
"shop_id": 6587023382,
"order_id": 4064537018390,
"assigned_location_id": 61208625174,
"request_status": "cancellation_rejected",
"status": "in_progress",
"supported_actions": ["create_fulfillment"],
"destination": {
"id": 4795644182550,
"address1": "1318 Bloor St.",
"address2": "",
"city": "Innisfree",
"company": "",
"country": "Canada",
"email": "benedict.ankunding@testemail.com",
"first_name": "Benedict",
"last_name": "Ankunding",
"phone": null,
"province": "Alberta",
"zip": "T0B2G0"
},
"origin": {
"address1": null,
"address2": null,
"city": null,
"country_code": "CA",
"location_id": 61208625174,
"name": "Very Good Fulfillment Company",
"phone": null,
"province": null,
"zip": null
},
"line_items": [
{
"id": 10931208618006,
"shop_id": 6587023382,
"fulfillment_order_id": 5020795797526,
"quantity": 3,
"line_item_id": 10841276481558,
"inventory_item_id": 19848968437782,
"fulfillable_quantity": 3,
"variant_id": 19523142352918
}
],
"outgoing_requests": [
{
"message": "Please fulfill ASAP!",
"request_options": {
"notify_customer": false
},
"sent_at": "2021-06-24T17:18:23-04:00",
"kind": "fulfillment_request"
},
{
"message": "Customer changed their mind!",
"request_options": {},
"sent_at": "2021-06-24T17:19:10-04:00",
"kind": "cancellation_request"
}
],
"fulfillment_service_handle": "very-good-fulfillment-company",
"fulfill_at": null,
"delivery_method": null
}
}
この場合、Shopify 管理画面のフルフィルメントオーダーカードには、マーチャントにキャンセル要求が拒否されたことが表示されます。
フルフィルメントオーダーを強制的にキャンセルするマーチャント
マーチャントは、フルフィルメントサービスがキャンセル要求に応答する前にフルフィルメント注文をキャンセルすることができます。
このオプションは、キャンセルを要求した直後に提供されます。
また、フルフィルメントオーダーを強制的にキャンセルしても、フルフィルメントサービスが商品を出荷しないことを保証するものではないことを示す警告メッセージがマーチャントに表示されます。
フルフィルメントサービスがキャンセル要求を拒否または受け入れることによって応答すると、オプションはもはやマーチャントに提供されません。フルフィルメントサービスは、マーチャントによってキャンセルされたフルフィルメントオーダーに対してフルフィルメントを作成することはできません。
フルフィルメントサービスによるフルフィルメントオーダーの閉鎖
いくつかのケースでは、フルフィルメントサービスは、それがすでにフルフィルメント注文の要求を受け入れた後にのみ、要求された項目を満たすことができないことを実現しています。
フルフィルメントサービスは、フルフィルメントオーダーをクローズするコールを行い、フルフィルメントを行わないことをマーチャントに示すことができます。これは、status
がINCOMPLETE
で、requestStatus
がCLOSED
であるフルフィルメントオーダーの結果です。
GraphQL
POST https://{shop}.myshopify.com/admin/api/2021-07/graphql.json
Request
mutation closeFulfillmentOrder($id: ID!, $message: String) {
fulfillmentOrderClose(id: $id, message: $message) {
fulfillmentOrder {
status
requestStatus
}
}
}
Variables
{
"id": "gid://shopify/FulfillmentOrder/5020795797526",
"message": "Apologies but it appears we are out of stock."
}
Response
{
"data": {
"fulfillmentOrderClose": {
"fulfillmentOrder": {
"status": "INCOMPLETE",
"requestStatus": "CLOSED"
}
}
}
}
REST API
POST https://{shop}.myshopify.com/admin/api/2021-04/fulfillment_orders//close.json
{
"message": "Unfortunately we are out of stock"
}
Response
{
"fulfillment_order": {
"id": 5021063905302,
"shop_id": 6587023382,
"order_id": 4064537018390,
"assigned_location_id": 61208625174,
"request_status": "closed",
"status": "incomplete",
"supported_actions": ["request_fulfillment", "create_fulfillment"],
"destination": {
"id": 4795912224790,
"address1": "1318 Bloor St.",
"address2": "",
"city": "Innisfree",
"company": "",
"country": "Canada",
"email": "benedict.ankunding@testemail.com",
"first_name": "Benedict",
"last_name": "Ankunding",
"phone": null,
"province": "Alberta",
"zip": "T0B2G0"
},
"line_items": [
{
"id": 10932546633750,
"shop_id": 6587023382,
"fulfillment_order_id": 5021063905302,
"quantity": 3,
"line_item_id": 10841276481558,
"inventory_item_id": 19848968437782,
"fulfillable_quantity": 3,
"variant_id": 19523142352918
}
],
"fulfillment_service_handle": "very-good-fulfillment-company",
"fulfill_at": null,
"delivery_method": null,
"assigned_location": {
"address1": null,
"address2": null,
"city": null,
"country_code": "CA",
"location_id": 61208625174,
"name": "Very Good Fulfillment Company",
"phone": null,
"province": null,
"zip": null
},
"merchant_requests": [
{
"message": "Please fulfill ASAP!",
"request_options": {
"notify_customer": false
},
"sent_at": "2021-06-24T17:27:24-04:00",
"kind": "fulfillment_request"
}
]
}
}
フルフィルメントサービスがフルフィルメントをキャンセルすると、Shopify 管理画面のフルフィルメントオーダーカードは、フルフィルメントリクエストがキャンセルされたことをマーチャントに通知します。
フルフィルメントのキャンセル
フルフィルメントは fulfillmentCancel ミューテーションを使用して API を通してキャンセルすることができます。ただし、フルフィルメントが作成されたすべてのフルフィルメント注文が影響を受けます。
- 基礎となるフルフィルメント注文が完全に満たされていた場合、その注文は自動的に
CLOSED
されます。 - 関連するフルフィルメントがキャンセルされると、キャンセルされたフルフィルメントのラインアイテムで構成される新しいフルフィルメントオーダーが作成されます。この新規受注は、元の受注と同じ場所に在庫がある場合は、そこに割り当てられます。
- キャンセルされたフルフィルメントのすべてのアイテムが同じ場所から調達できない場合、新しいフルフィルメントオーダーは、ショップのフルフィルメントの優先順位設定を考慮して、アイテムがストックされている場所に割り当てられます。これにより、異なるロケーションに対して複数の新規フルフィルメントオーダーが発生する場合があります。
- フルフィルメントオーダーが部分的に履行されていた場合、fulfillmentOrderLineItem remainingQuantity は、キャンセルされたフルフィルメントのラインアイテムに基づいて調整されます。
GraphQL
POST https://{shop}.myshopify.com/admin/api/2021-07/graphql.json
Request
mutation cancelFulfillment($id: ID!) {
fulfillmentCancel(id: $id) {
fulfillment {
id
status
fulfillmentOrders(first: 10) {
edges {
node {
id
status
}
}
}
}
}
}
Variables
{
"id": "gid://shopify/Fulfillment/3286482681878"
}
Response
{
"data": {
"fulfillmentCancel": {
"fulfillment": {
"id": "gid://shopify/Fulfillment/3286482681878",
"status": "CANCELLED",
"fulfillmentOrders": {
"edges": [
{
"node": {
"id": "gid://shopify/FulfillmentOrder/5021075374102",
"status": "CLOSED"
}
}
]
}
}
}
}
}
REST API
POST https://{shop}.myshopify.com/admin/api/2021-04/fulfillments/{ fulfillment_id }/cancel.json
{}
Response
{
"fulfillment": {
"order_id": 4064537018390,
"status": "cancelled",
"location_id": 61208625174,
"id": 3286482747414,
"created_at": "2021-06-24T21:20:17-04:00",
"service": "very-good-fulfillment-company",
"updated_at": "2021-06-24T21:25:15-04:00",
"tracking_company": "my-shipping-company",
"shipment_status": null,
"line_items": [
{
"id": 10841276481558,
"variant_id": 19523142352918,
"title": "Billowing Brook Cap",
"quantity": 3,
"sku": "BBC-1",
"variant_title": "",
"vendor": "graphql-admin",
"fulfillment_service": "very-good-fulfillment-company",
"product_id": 1974227435542,
"requires_shipping": true,
"taxable": true,
"gift_card": false,
"name": "Billowing Brook Cap",
"variant_inventory_management": "shopify",
"properties": [],
"product_exists": true,
"fulfillable_quantity": 0,
"grams": 500,
"price": "120.00",
"total_discount": "0.00",
"fulfillment_status": "fulfilled",
"price_set": {
"shop_money": {
"amount": "120.00",
"currency_code": "CAD"
},
"presentment_money": {
"amount": "120.00",
"currency_code": "CAD"
}
},
"total_discount_set": {
"shop_money": {
"amount": "0.00",
"currency_code": "CAD"
},
"presentment_money": {
"amount": "0.00",
"currency_code": "CAD"
}
},
"discount_allocations": [],
"duties": [],
"admin_graphql_api_id": "gid://shopify/LineItem/10841276481558",
"tax_lines": [],
"origin_location": {
"id": 2849710276630,
"country_code": "CA",
"province_code": "ON",
"name": "graphql-admin",
"address1": "151 O'Connor Street",
"address2": "1st Floor",
"city": "Ottawa",
"zip": "K2P 2L8"
},
"destination_location": {
"id": 2849710309398,
"country_code": "CA",
"province_code": "AB",
"name": "Benedict Ankunding",
"address1": "1318 Bloor St.",
"address2": "",
"city": "Innisfree",
"zip": "T0B2G0"
}
}
],
"tracking_number": "1562678",
"tracking_numbers": ["1562678"],
"tracking_url": "https://www.my-shipping-company.com",
"tracking_urls": ["https://www.my-shipping-company.com"],
"receipt": {},
"name": "#1016.3",
"admin_graphql_api_id": "gid://shopify/Fulfillment/3286482747414"
}
}
在庫の管理
API による在庫管理の詳細については、在庫の更新のガイドをご覧ください。
API リファレンス
- GraphQL Admin API: FulfillmentOrder オブジェクト
- REST Admin API: 配送およびフルフィルメントリソース
Shopify アプリのご紹介
Shopify アプリである、「商品ページ発売予告アプリ | リテリア Coming Soon」は、商品ページを買えない状態のまま、発売日時の予告をすることができるアプリです。Shopify で Coming Soon 機能を実現することができます。
Shopify アプリである、「らくらく日本語フォント設定|リテリア Font Picker」は、ノーコードで日本語フォントを使用できるアプリです。日本語フォントを導入することでブランドを演出することができます。
Discussion