Skip to main content

Refund a payment

You can refund all or part of a payment using the GOV.UK Pay API.

You can also refund a payment by signing into the GOV.UK Pay admin tool.

Your user will receive the refund in the same account they originally paid from. You cannot refund a payment to another card or bank account.

Check if you can refund a payment

Check if you can refund a payment by using the API to get information about the payment.

The API response includes a refund_summary object. For example, for a completed £50 payment with no previous refunds:

"refund_summary": {
  "status": "available",
  "amount_available": 5000,
  "amount_submitted": 0
}

For a completed £90 payment where £30 has already been refunded:

"refund_summary": {
  "status": "available",
  "amount_available": 6000,
  "amount_submitted": 3000
}

amount_available

amount_available is how much you can refund in pence. The amount includes any transaction fees and corporate card fees.

amount_submitted

amount_submitted is how much you’ve already refunded.

status

Status Meaning
pending You cannot refund the payment yet because your user has not completed the payment.
unavailable You cannot refund the payment, usually because the payment failed.
available You can refund the payment. Check how much you can refund in amount_available.
full You cannot refund the payment because you’ve already refunded the full amount.

Creating a refund

POST /v1/payments/{PAYMENT_ID}/refunds

Replace {PAYMENT_ID} with the ID of the payment you are refunding.

If the status in the refund_summary object is available, you can create a refund with the GOV.UK Pay API.

Example refund request:

{
  "amount": 2000,
  "refund_amount_available": 5000
}

amount

amount is how much to refund your user in pence. You can refund all or part of the payment.

refund_amount_available (optional)

refund_amount_available is the amount_available you received when you checked if you can refund the payment.

GOV.UK Pay will reject your refund request if refund_amount_available does not match the amount that’s available to refund. This stops you accidentally refunding your user twice.

Response

Example response:

{
  "amount": 2000,
  "created_date": "2019-09-19T16:53:03.213Z",
  "refund_id": "j6se0f2o427g28g8yg3u3i",
  "status": "submitted",
  ...
}

If GOV.UK Pay could not successfully create the refund, the JSON response will contain an API error code and a description of the error.

created_date

created_date is when you created the refund, in ISO 8601 format.

refund_id

refund_id is the unique ID that GOV.UK Pay generated for this refund.

status

Use the status field to check the status of a refund.

Checking the status of a refund

GET /v1/payments/{PAYMENT_ID}/refunds/{REFUND_ID}

Replace:

  • {PAYMENT_ID} with the ID of the payment you are checking
  • {REFUND_ID} with the ID of the refund you are checking

Example response:

{
  "amount": 2000,
  "created_date": "2019-09-19T16:53:03.213Z",
  "refund_id": "j6se0f2o427g28g8yg3u3i",
  "status": "success",
  "settlement_summary": {
    "settled_date": "2019-09-21"
  }
}

settlement_summary

If your payment service provider (PSP) is Stripe, you can use the settlement_summary object to check when Stripe took the refund.

status

It may take up to 30 minutes for the status field to change. Do not check the status more than once every 5 minutes.

status Meaning
submitted We’ve submitted your refund request to your PSP. Refunds do not have a submitted status if you’re using your test (‘sandbox’) account.
success Your PSP has successfully processed the refund.
error Your PSP could not process the refund, usually because your user’s payment card is cancelled or expired, or you do not have enough money in your account to refund your user.

Where your PSP takes the refund amount from

If your user’s payment did not reach your bank account yet, your PSP will:

  • cancel the payment, if your PSP is Stripe, ePDQ or SmartPay
  • take the refund amount after the payment has reached your bank account, if your PSP is Worldpay

If the payment has reached your bank account, your PSP will take the refund amount from:

  • the next payment or payments you receive from any of your users, if your PSP is Stripe or ePDQ
  • your bank account, if your PSP is SmartPay or Worldpay

If your PSP is Stripe, you can see when Stripe took the refund when you make an API call to check the status of a refund.

Example response:

"settlement_summary": {
  ...
  "settled_date": "2019-09-21",
}

settled_date will be either:

  • the date Stripe took the refund from the payments that Stripe sent to your bank account
  • missing if Stripe has not yet taken the refund

All dates are in Coordinated Universal Time (UTC).

Send email notifications about refunds

You can use the GOV.UK Pay admin tool to turn on sending refund email notifications to your users. Select the account in the GOV.UK admin tool, then select Settings.

Getting a list of refunds

You can use the GOV.UK API to:

  • get all refunds for a single payment
  • search refunds

Get all refunds for a single payment

GET /v1/payments/{PAYMENT_ID}/refunds

Replace {PAYMENT_ID} with the ID of the payment you are getting the refunds for.

Example response:

{
  "payment_id": "hu20sqlact5260q2nanm0q8u93",
  ...
  "_embedded": {
    "refunds": [
      {
        "refund_id": "act4c33g40j3edfmi8jknab84x",
        "created_date": "2019-09-19T16:52:07.855Z",
        "amount": 120,
        "status": "success"
        "settlement_summary": {
          "settled_date": "2019-09-21"
        }
      },
      {
        "refund_id": "9rwjbdcpjd54ol1btog2a8zowh",
        "created_date": "2019-09-20T20:46:01.121Z",
        "amount": 60,
        "status": "success"
        "settlement_summary": {
          "settled_date": "2019-09-21"
        }
      }
    ]
  }
}

Searching refunds

GET /v1/refunds?{QUERY_PARAMETERS}

An example search request:

GET /v1/refunds?from_date=2019-09-20T13:30:00Z&to_date=2019-09-22T15:00:00Z

Example search response:

{
  "total": 100,
  "count": 20,
  "page": 2,
  "results": [
    {
      "refund_id": "act4c33g40j3edfmi8jknab84x",
      "created_date": "2017-01-10T16:52:07.855Z",
      "amount": 120,
      "status": "success",
      "settlement_summary": {
        "settled_date": "2017-01-11"
      }
      "_links": {
        "payment": {
            "href": "https://publicapi.payments.service.gov.uk/v1/payments/5chu1yzxglqajfv97ous23s22i",
            "method": "GET"
        }
      ...
      }
    },
    {
      "refund_id": "efj6834secviyyxe8vs861pg3j",
      ...
    }
  ],
  "_links": {
    "prev_page": {
      "href": "https://publicapi.payments.service.gov.uk/v1/refunds?display_size=20&page=1",
      "method": "GET"
    },
    "next_page": {
      "href": "https://publicapi.payments.service.gov.uk/v1/refunds?display_size=20&page=3",
      "method": "GET"
    }
    ...
  }
  ...
}

The _links object includes a payment URL and method that you can use to get information about the payment the refund is for.

Filtering by date

You can use the following query parameters to filter refunds by date:

  • from_date, which is the start date to search, inclusive
  • to_date, which is the end date to search, exclusive

All dates are in Coordinated Universal Time (UTC).

Dates must be in ISO 8601 format and include a:

  • date
  • time in hours and minutes - seconds are optional
  • time zone designation

For example, 2019-09-20T13:30Z.

Filter refunds by when your PSP took refunds

If your payment service provider (PSP) is Stripe, you can use the following query parameters to filter by when your PSP took refunds:

  • from_settled_date - the start date for payments to be searched, inclusive
  • to_settled_date - the end date for payments to be searched, inclusive

All dates are in Coordinated Universal Time (UTC).

For example, to list all the refunds your PSP took on 16 June 2020:

GET /v1/refunds?from_settled_date=2020-06-16&to_settled_date=2020-06-16

Dates must be in ISO 8601 format and include a date value only. For example, 2015-08-13.

Splitting results into pages

You can use the following query parameters to split results into pages:

  • display_size, which has a default of 500, and must be between 1 and 500
  • page, which has a default of 1

These must be positive integers.

For example, you run the following search and get 1500 refunds in the response:

GET /v1/refunds?from_date=2019-09-20T13:30:00Z&to_date=2019-09-22T15:00:00Z

You could then get a single page of these refunds by running:

GET /v1/refunds?from_date=2019-09-20T13:30:00Z&to_date=2019-09-22T15:00:00Z&display_size=500&page=2

This would return refunds 501 to 1000.

The API response includes a _links object, which includes href and method fields you can use to move between pages. Use the fields in:

  • self to run the same search again
  • first_page to get the first page of results
  • last_page to get the last page
  • prev_page to get the previous page
  • next_page to get the next page