Marketplaces / Tesco (on Marketplacer) / Tesco Technical Scope / Tesco Order Management / Tesco Claims Handle

Tesco Claims Handle

Version Date Created / Updated Notes
v1.0 Hristiyan Georgiev Initial version
v1.1 02/02/2025 Hristiyan Georgiev Added response and mapping for accepting the return

The seller initiated cancellations/returns will be handled via the claims functionality in Hemi. The purpose of the page is to give a good understanding on how that will work.

Seller or Operator initiated refunds will be handled via Claims in Hemi. This means when the customer or marketplace operator puts a request for refund/cancellation we will need to store a claim and then act on it (Reject or Accept).

Here is a diagram to get a better understanding on how it should work :

Per account we can set by default to Accept or Reject refund; In Account Tesco table we need to add additional options which will be Cancel Action Default and Return Action Default which will work as a default action if we would like to automatically accept or reject all claims for the specific account. If is “Accept“ , by default we accept the refund, if is “Reject“ , by default we reject the refund.

API Docs : https://api.marketplacer.com/docs/seller-api/examples/refunds/howto_sellerinitrefunds/#worked-example

All the validations, triggers etc. are as per our claims abstraction - Claims general management.

Please note that since the acceptance/rejection of claims is done on a line level, we want to store each line as a separate claim in Hemi.

Get Refund Requests

GraphQL Query :

query GetRefundRequestsUpdatedSince
($pageSize: Int $endCursor: String $updatedSince: ISO8601DateTime!)
{
  updatedRefundRequests
    (
        updatedSince: $updatedSince
        first: $pageSize
        after: $endCursor

    )

  {
    pageInfo{
            hasNextPage
            endCursor
        }
    edges{

     node{
        invoice{
            id
        }
        id        
        status        
        createdAt     
        initiatedBy
        invoice{
          id
        }
        lineItems{
           lineItem{
            id 
           } 
          id          
          dispatched
          reason 
        }
      }  
    }       
  }
}

Query Variables :

{
  "pageSize": 50,
  "endCursor": "",
  "updatedSince": "2025-01-30T08:36:56+00:00"
}

Variables Mapping :

Variable Value Note
pageSize 50 This will be our page size for this query
endCursor Should be null when doing the first query, and then if in the response we have hasNextPage = true, we need to use the string returned in the endCursor field.
updatedSince We want to overlap with 30 minutes. So it will be last_date_run - 30 minutes. The format is 2025-01-30T08:36:56+00:00

Example Response :

{
    "data": {
        "updatedRefundRequests": {
            "pageInfo": {
                "hasNextPage": false,
                "endCursor": "Mg"
            },
            "edges": [
                {
                    "node": {
                        "invoice": {                            
                            "id": "SW52b2ljZS0xMzkzOA=="
                        },
                        "id": "UmVmdW5kUmVxdWVzdC02OTk=",
                        "status": "AWAITING",
                        "createdAt": "2024-11-07T10:07:06+11:00",
                        "initiatedBy": "ADMIN",
                        "lineItems": [
                            {
                                "lineItem": {
                                    "id": "TGluZUl0ZW0tNDM0Mw=="
                                },
                                "id": "UmVmdW5kUmVxdWVzdExpbmVJdGVtLTk1Ng==",
                                "dispatched": true,                                
                                "reason": "Change of mind"
                            }
                        ]
                    }
                }
            ]
        }
    }
}

Response Mapping :

Integration Field Hemi Mapping Notes
data
updatedRefundRequests
pageInfo
hasNextPage N/A
endCursor N/A
edges
node
invoice
id We map this with Orders > Marketplace Order ID so we know for which order to create the claim.
id N/A
status
createdAt Order Claim > Marketplace Date It will be in a format 2024-11-07T10:04:39+11:00 we need to convert it to unix timestamp
initiatedBy Order Claim > Initiated By
lineItems
lineItem We might receive lineItem as null sometimes, and when we have it we cannot associate the claim with any product. In this case we want to skip and not save this claim.
id We need to map this with Product in Order > Item Order Line ID so we can understand which item is this for
id Order Claim > Marketplace ID This is the id that we need to send when accepting/rejecting the return/cancellation
dispatched We need to create a logic here.

If dispatched = false this means it is cancellation and we need to save the claim with Type = Cancel If dispatched = true then it is a return and we need to save the claim with Type = Return. Exchange process is not supported by API so we will not cover it. | | | | | | | reason | | Order Claim > Marketplace Reason | | | | | | | | status | | Order Claim > Marketplace Status AND Order Claim > Claim Status | Mapping for Claim Status as follows : -PENDING_APPROVAL we map with “Created” -AWAITING_RETURN we map with “Accepted” -REFUND_ACCEPTED we map with “Accepted & Refunded” -REFUNDED we map with “Accepted & Refunded” -REFUND_DENIED we map with “Rejected” |

After the claim has been received and successfully stored we can either approve or reject it. If we approve it, there is a 2 step approval : we first approve the return, and then, once the product is returned into the warehouse, we accept the refund.

For cancellations, there is only one step approval - it is the acceptance of the refund.

Accept Return

The validations are as per the claims abstraction. Claims general management

GrpahQL Query :

mutation RefundRequestLineItemReturn($input: RefundRequestLineItemReturnMutationInput!) {
    refundRequestLineItemReturn(
        input: $input
    ) {
        refundRequestLineItem {
            status
        }
        errors {
            field
            messages
        }
    }
}

Query variables :

{
  "input": {
    "refundRequestLineItemId": "UmVmdW5kUmVxdWVzdExpbmVJdGVtLTEwNDE=",
    "notes": [
      {
        "note": "This item does not need to be returned."
      }
    ]
  }
}

Variables mapping :

Integration Field Hemi Mapping Notes
input
refundRequestLineItemId Order Claim > Marketplace ID
notes
note Order Claim > Action Reason We need to also have a logic and if the Action Reason is empty, we want to have a default reason of “Refund Accepted”

<v1.1> Example success response :

{
    "data": {
        "refundRequestLineItemReturn": {
            "refundRequestLineItem": {
                "status": "AWAITING_RETURN"
            },
            "errors": null
        }
    }
}

Example error response :

{
    "data": {
        "refundRequestLineItemReturn": {
            "refundRequestLineItem": null,
            "errors": [
                {
                    "field": "status",
                    "messages": [
                        "The refund request line item status should be pending_approval."
                    ]
                }
            ]
        }
    }
}

Response Mapping :

Integration Field Hemi Mapping Notes
data
refundRequestLineItemReturn
refundRequestLineItem
status Order Claim > Marketplace Status
AND Order Claim > Claim Status With same mapping for the Claim Status as in the above table. errors field Order Error > Message with Type = Claim Accept We need to concatenate field and messages and store them together messages Order Error > Message with Type = Claim Accept We need to concatenate field and messages and store them together

</v1.1>

After receiving the package we need to approve(push) or reject the refund to the customer. In order to approve it, we need to obviously push a refund and this is done by making similar call as above, just with a different mutation.

When rejecting the refund, there is a separate call for that explained below.

Accept Refund

This call serves either as the first (and only) step for accepting Cancellation or the second step in accepting a Return. So we need to have a logic and if we are accepting a cancellation, we need to skip the first step (Accept Return) and go straight to this step.

Triggers, validations etc are as per Refunds send general logic

The refund record needs to be associated with the claim and with Refund Type = Return. Once we have created a refund associated with the claim, we need to make sure we are not making a standard refund call, but rather the below call.

GraphQL Query :

mutation RefundRequestLineItemAccept(
    $input: RefundRequestLineItemAcceptMutationInput!
) {
    refundRequestLineItemAccept(input: $input) {
        refundRequestLineItem {
            status
        }
        errors {
            field
            messages
        }
    }
}

Query Variables :

{
  "input": {
    "refundRequestLineItemId": "UmVmdW5kUmVxdWVzdExpbmVJdGVtLTk1NQ==",
    "notes": [
      {
        "note": "This item does not need to be returned."
      }
    ]
  }
}

Variables Mapping :

Integration Field Hemi Mapping Notes
input
refundRequestLineItemId Order Claim > Marketplace ID
notes
note Order Claim > Action Reason We need to also have a logic and if the Action Reason is empty, we want to have a default reason of “Refund Accepted”

Example success response :

{
    "data": {
        "refundRequestLineItemAccept": {
            "refundRequestLineItem": {
                "status": "REFUND_ACCEPTED"
            },
            "errors": null
        }
    }
}

Example error response :

{
    "data": {
        "refundRequestLineItemAccept": {
            "refundRequestLineItem": null,
            "errors": [
                {
                    "field": "status",
                    "messages": [
                        "The refund request line item status should be pending_approval or awaiting_return."
                    ]
                }
            ]
        }
    }
}

Response Mapping :

Integration Field Hemi Mapping Notes
data
refundRequestLineItemAccept
refundRequestLineItem
status Order Claim > Marketplace Status

AND Order Claim > Claim Status | With same mapping for the Claim Status as in the first table. | | | | errors | | | | | | | | field | Order Error > Message with Type = Claim Accept | We need to concatenate field and messages and store them together | | | | | messages | Order Error > Message with Type = Claim Accept | We need to concatenate field and messages and store them together |

Reject Return/Refund

Please note that we can perform a reject action either on the first step (reject the return) or the second step (reject the refund after the return has been approved and item(s) received in the warehouse) or reject a cancellation request. All three are using the same call.

The validations are as per the claims abstraction. Claims general management

GraphQL Query :

mutation RefundRequestLineItemDeny(
    $input: RefundRequestLineItemDenyMutationInput!
) {
    refundRequestLineItemDeny(input: $input) {
         refundRequestLineItem {
            status
        }
        errors {
            field
            messages
        }
    }
}

Query Variables :

{
  "input": {
    "refundRequestLineItemId": "UmVmdW5kUmVxdWVzdExpbmVJdGVtLTk1Ng==",
    "denyRefundReason": "Return time exceeded",
    "notes": [
      {
        "note": "Refund request not accepted"
      }
    ]
  }
}

Variables Mapping :

Integration Field Hemi Mapping Notes
input
refundRequestLineItemId Order Claim > Marketplace ID
denyRefundReason Order Claim > Action Reason We need to also have a logic and if the Action Reason is empty, we want to have a default reason of “Refund request not accepted”
notes
note Hardcoded as “Request not accepted”

Example Success Response :

{
    "data": {
        "refundRequestLineItemDeny": {
            "refundRequestLineItem": {
                "status": "REFUND_DENIED"
            },
            "errors": null
        }
    }
}

Example Error Response :

{
    "data": {
        "refundRequestLineItemDeny": {
            "refundRequestLineItem": null,
            "errors": [
                {
                    "field": "status",
                    "messages": [
                        "The refund request line item status should be pending_approval or awaiting_return."
                    ]
                }
            ]
        }
    }
}

Response Mapping :

Integration Field Hemi Mapping Notes
data
refundRequestLineItemDeny
refundRequestLineItem
status Order Claim > Marketplace Status
errors
field Order Error > Message with Type = Claim Reject We need to concatenate field and messages and store them together
messages Order Error > Message with Type = Claim Reject We need to concatenate field and messages and store them together
Is this article helpful?
0 0 0