Process a refund
To process a refund, Shopify makes an HTTP call to your app, and your app completes the refund by replying with a GraphQL mutation. This interaction is illustrated in the following diagram:
- Merchant requests refund.
- Shopify sends a backend request to the payments app, specifying the refund.
- The app replies with a
201
and an empty response body. - The app finalizes the refund using the
refundSessionResolve
orrefundSessionReject
mutation. - Shopify updates the refund status.
Initiate the flow
Anchor link to section titled "Initiate the flow"The refund flow begins with an HTTP POST request sent from Shopify to the payments app's refund session URL provided during app extension configuration:
Shopify must receive an HTTP 201
(Created) response for the refund session creation to be successful.
If the request fails, then it's retried several times. If the request still fails, then the user needs to manually retry the refund in the Shopify admin.
Request headers
Anchor link to section titled "Request headers"Header | Description |
---|---|
Shopify-Shop-Domain Required |
The permanent domain of the shop. Can be used to identify which shop is initiating the request. |
Shopify-Request-Id Required |
The unique request ID used to track specific requests for troubleshooting purposes. |
Shopify-Api-Version Required |
The API version selected in the payments app configuration. The version selected defines the response expected by the payments app. |
Request body
Anchor link to section titled "Request body"Attribute | Description | Type |
---|---|---|
id Required |
Unique identifier for the refund attempt. Used as the idempotency key. It can be assumed that requests with a given ID are identical to any previously-received requests with the same ID. | String |
gid Required |
Identifies the refund when communicating with Shopify (in GraphQL mutations, for example). | String |
payment_id Required |
ID of the original payment that is to be refunded. For captured payments, this ID corresponds to the original authorization ID rather than the capture ID. | String |
amount Required |
The amount to be refunded. The amount is always sent using a decimal point as a separator, regardless of locale. | Numeric |
currency Required |
Three-letter ISO 4217 currency code. | String |
test Required |
Indicates whether the refund is in test or live mode. The test field is only sent if you select API version 2022-01 or higher in the payments app extension configuration in the Partner Dashboard. For more information, refer to Test a payments app.
| Boolean |
merchant_locale Required |
IETF BCP 47 language tag representing the language used by the merchant. | String |
proposed_at Required |
Timestamp representing when the refund request was proposed. | String (ISO-8601) |
Resolve a refund session
Anchor link to section titled "Resolve a refund session"After you've successfully processed the refund request, you can resolve it by using the refundSessionResolve
mutation:
The id
argument corresponds to the gid
of the refund.
Reject a refund session
Anchor link to section titled "Reject a refund session"If you cannot process a refund, then you should reject it. You should only reject a refund in the case of final and irrecoverable errors. Otherwise, you can re-attempt to process the refund.
You can reject a refund using the refundSessionReject
mutation:
As part of the rejection, you need to include a reason why the refund was rejected as part of RefundSessionRejectionReasonInput
.
The RefundSessionRejectionReasonInput.code
is a RefundSessionStatusReasonRejectionCode
, which is an enum of standardized error codes.
The RefundSessionRejectionReasonInput.merchantMessage
argument is a localized error message presented to the merchant explaining why the refund was rejected.