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
Salewhen it has been processed. - Confirming exchange items - Previously, creating or approving a return would immediately confirm an
exchangeLineItemon 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
ReturnShippingFeeorRestockingFee - 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:
returnProcesshandles both disposition decisions (restock/not restock) and financial processing in a single call, whilereturnRefundonly handled the financial aspect. -
Structure changes: Financial information is now under the
financialTransferobject 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:
returnProcessworks with return objects rather than directly with orders, providing better lifecycle management of returns. -
Line item precision: With
refundCreate, which references orderLineItems 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.returnProcessusesReturnLineItems that are specifically associated with the items being returned, ensuring the exact returned items are properly processed. -
Comprehensive return handling:
returnProcesscan handle all return types including exchanges, whereasrefundCreateonly works for net refundable returns. This meansreturnProcessprovides a complete solution for the entire returns lifecycle, including exchange fulfillment orders. -
Return fee support:
returnProcesscan record return fees (such as restocking or shipping fees) on the sales ledger, providing accurate financial reporting for merchants.refundCreatelacks 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 suggestedFinancialOutcomeWith 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 |
| Extensions | Limited | Designed for future extensions 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
suggestedRefundwithsuggestedFinancialOutcomein 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
suggestedFinancialOutcometo construct the input for thereturnProcessmutation. 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
suggestedFinancialOutcomeare recommendations. You can modify them before passing toreturnProcessif 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
returnCreateorreturnAppproveRequestto create the return with exchange line items - Call
returnProcessto 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
returnProcessmutation - 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
returnProcessmutation 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
returnProcessinstead ofrefundCreate/returnRefund - Replace all queries to
suggestedRefundwithsuggestedFinancialOutcome - 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