Migrate to return processing
In API version 2025-07, Shopify introduced returnProcess
to enhance the lifecycle management of returns. Processing a return means confirming the return items, exchange items, and return fees on the return, thereby updating a merchant's financial reports. This step will also result in exchange items being confirmed (if applicable).
This document outlines these updates in detail and offers migration best practices.
Anchor to What is changing?What is changing?
- Merchant reporting - Previously, a merchant's financial report would include a return when the return was created or approved. Moving forward, a return will only be recorded as a
Sale
when it has been processed. - Confirming exchange items - Previously, creating or approving a return would immediately confirm an
exchangeLineItem
on the return and create aFulfillmentOrder
. This will now only happen when the exchange line item has been processed. - Holding exchange fulfillment orders - Previously, all fulfillment orders created for an exchange would automatically be placed on hold. Moving forward only exchanges with a balance owed by the buyer will be automatically placed on hold. An even or refundable exchange will not be placed on hold.
Note:
In addition to new mutations, the way you obtain suggested refund and financial outcomes has changed. See Migrating from suggestedRefund
to suggestedFinancialOutcome
for details on updating your integration.
Anchor to Who needs to take action?Who needs to take action?
- Partners that create returns with an
exchangeLineItem
- Partners that create returns with a
ReturnShippingFee
orRestockingFee
- Partners that assume a merchant's financial report will include returns when the return is created
Although issuing refunds to the original payment method on a return will continue to work with returnRefund
or refundCreate
, returnRefund will be a legacy API, and using refundCreate for returns causes undesired effects for certain cases (example: risk of refunding the wrong item when there are multiple quantities of the same item on an order). The best practice is to integrate with returnProcess
for this use case as well.
Anchor to Key changes with return processingKey changes with return processing
The following table outlines the key differences introduced with return processing:
Action | Before return processing | After return processing |
---|---|---|
Return items are recorded as a Sale | returnCreate or returnApproveRequest | returnProcess or returnRefund or refundCreate |
Exchange items are confirmed and fulfillment orders are created | returnCreate or returnApproveRequest | returnProcess |
Return fees are recorded as a Sale | returnCreate or returnApproveRequest | returnProcess |
Anchor to Migration stepsMigration steps
Follow these steps to migrate your app from the legacy returns API to the return processing API:
- Update APIs for refunds on returns with and without return fees: Replace calls to the legacy refund mutations with the return processing mutation.
- Adapt your return workflow for exchanges: Call the return processing mutations on returns with exchange line items.
- Update webhook handlers: Subscribe to the new return/process webhooks (if applicable).
- Test your integration: Ensure your app works correctly with the new API.
Anchor to Step 1: Update APIs for refundsStep 1: Update APIs for refunds
Anchor to Migrating from the legacy ,[object Object], mutation to the new ,[object Object], mutationMigrating from the legacy returnRefund
mutation to the new returnProcess
mutation
returnRefund
mutation to the new returnProcess
mutationBefore: Using returnRefund
After: Using returnProcess
Key differences between returnRefund and returnProcess
-
Combined process:
returnProcess
handles both disposition decisions (restock/not restock) and financial processing in a single call, whilereturnRefund
only handled the financial aspect. -
Structure changes: Financial information is now under the
financialTransfer
object instead of being directly at the root level of the input.
Tip:
When preparing inputs for the new returnProcess
mutation, use the suggestedFinancialOutcome
field on the return
object to generate recommended values for refunds, exchanges, and fees. This replaces the legacy suggestedRefund
field.
Anchor to Migrating from the ,[object Object], mutation to the new ,[object Object], mutationMigrating from the refundCreate
mutation to the new returnProcess
mutation
refundCreate
mutation to the new returnProcess
mutationBefore: Using refundCreate
After: Using returnProcess
Key differences between refundCreate and returnProcess
-
Return-based vs Order-based:
returnProcess
works with return objects rather than directly with orders, providing better lifecycle management of returns. -
Line item precision: With
refundCreate
, which references orderLineItem
s directly, there's no guarantee that you are refunding the item you intended to refund when multiple quantities of the same product exist on an order.returnProcess
usesReturnLineItem
s that are specifically associated with the items being returned, ensuring the exact returned items are properly processed. -
Comprehensive return handling:
returnProcess
can handle all return types including exchanges, whereasrefundCreate
only works for net refundable returns. This meansreturnProcess
provides a complete solution for the entire returns lifecycle, including exchange fulfillment orders. -
Return fee support:
returnProcess
can record return fees (such as restocking or shipping fees) on the sales ledger, providing accurate financial reporting for merchants.refundCreate
lacks this capability, potentially leading to inconsistencies in financial reporting for return-related fees.
Anchor to Migrating from ,[object Object], to ,[object Object]Migrating from suggestedRefund
to suggestedFinancialOutcome
suggestedRefund
to suggestedFinancialOutcome
With the introduction of the new return processing API, Shopify has also modernized how apps can obtain suggested financial transactions for a return. Previously, the suggestedRefund
field on the return
object provided a recommended refund structure, typically used as input to the legacy refundCreate
mutation. Now, the suggestedFinancialOutcome
field provides a more comprehensive and flexible suggestion, designed to be used with the new returnProcess
mutation.
This section explains the differences between these two fields and how to migrate your integration.
Anchor to Key DifferencesKey Differences
Aspect | suggestedRefund (Legacy) | suggestedFinancialOutcome (New) |
---|---|---|
Purpose | Suggests refund amounts for a return, to be used with refundCreate or returnRefund | Suggests a complete financial outcome (refunds, exchanges, fees, allocations) for a return, to be used with returnProcess |
Inputs | - Return refund line items - Shipping refund - Duties - Additional fees - (Optionally) apply deductions | - Return line items - Exchange line items - Shipping refund - Duties - Additional fees - Refund method allocation (e.g., original payment method, store credit) |
Coverage | Focused on refunds only | Handles refunds, exchanges, fees, and supports allocation of refund methods |
Output Structure | Refund amounts and related fields | Detailed breakdown of all financial components, including refund methods, transactions, deductions, and more |
Mutation Usage | refundCreate or returnRefund | returnProcess |
Extensibility | Limited | Designed for future extensibility and more complex return scenarios |
Anchor to Example MigrationExample Migration
Before: Using suggestedRefund
The result would be used as input to the refundCreate
or returnRefund
mutation.
After: Using suggestedFinancialOutcome
The result is then used as input to the returnProcess
mutation, which can process refunds, exchanges, and fees in a single call.
Anchor to Migration StepsMigration Steps
- Update your query: Replace any usage of
suggestedRefund
withsuggestedFinancialOutcome
in your GraphQL queries. Adjust the input arguments to include both return and exchange line items, as well as any new fields relevant to your workflow (such asrefundMethodAllocation
). - Review the output: The structure of the response is more detailed. Update your code to extract the relevant suggested transactions, refund methods, and deductions as needed.
- Prepare the mutation input: Use the output from
suggestedFinancialOutcome
to construct the input for thereturnProcess
mutation. You may modify the suggested values as needed to fit your business logic. - Test thoroughly: Ensure that your integration correctly handles all return scenarios, including refunds, exchanges, and fees.
Anchor to Best PracticesBest Practices
- Use suggestions as a starting point: The values returned by
suggestedFinancialOutcome
are recommendations. You can modify them before passing toreturnProcess
if your workflow requires it. - Handle errors gracefully: Both fields may return user errors if the input is invalid (e.g., mismatched currencies, invalid IDs). Ensure your integration checks for and handles these errors.
- Support new features: The new API supports more complex scenarios, such as allocating refunds to store credit or handling multiple exchange line items. Take advantage of these features to provide a better merchant and buyer experience.
Anchor to Step 2: Adapt your return workflow for exchangesStep 2: Adapt your return workflow for exchanges
Another key change with return processing is the workflow for exchanges:
Before: Partners only needed to call returnCreate
or returnAppproveRequest
to create a return with exchange line items. This automatically confirmed exchange items and created fulfillment orders.
Now: Partners must follow a two-step process:
- Call
returnCreate
orreturnAppproveRequest
to create the return with exchange line items - Call
returnProcess
to confirm the return and exchange line items
The returnProcess
call is now required to:
- Commit those items to the sales ledger
- Create fulfillment orders for the exchange items
Additionally, whereas previously all fulfillment orders driven by exchanges would be placed on hold, now only fulfillment orders created for exchanges that have a net payable balance due by the buyer will be placed on automatic hold.
Anchor to Example: Processing a net even exchangeExample: Processing a net even exchange
In this example, the mutation processes both the return line items (with restock decisions) and the exchange line items. Since this is a net even exchange (no additional payment required from the buyer), the created fulfillment orders will not be placed on hold and can be fulfilled immediately.
Anchor to Step 3: Update webhook handlersStep 3: Update webhook handlers
Subscribe to the new returns/process
webhook. This webhook will be triggered when a return has been fully or partially processed. The return's status is CLOSED
when all items have been processed and a restock decision has been made.
Anchor to Step 4: Test your integrationStep 4: Test your integration
Before deploying to production, thoroughly test your updated integration:
- Create test orders and initiate returns
- Process returns using the
returnProcess
mutation - Verify webhook handling for all return events
- Confirm that exchanges are properly created and managed
- Validate that refunds are accurately issued
Anchor to TimelineTimeline
Return processing is available starting in API version 2025-07. Existing return apps that use returnRefund
or refundCreate
must migrate to returnProcess
to ensure consistent behavior and avoid disruptions.
Anchor to Next stepsNext steps
- Review the
returnProcess
mutation API reference - Learn more about returns apps
- Understand how to manage returns with the GraphQL Admin API
- Set up webhook handlers for return processing events
Anchor to Migration ChecklistMigration Checklist
- Update all refund and return processing flows to use
returnProcess
instead ofrefundCreate
/returnRefund
- Replace all queries to
suggestedRefund
withsuggestedFinancialOutcome
- Update your code to handle the new output structure from
suggestedFinancialOutcome
- Test all return, refund, and exchange scenarios end-to-end
- Update documentation and team knowledge to reflect these changes