# Obtain PSU Source Account for Refund
source: https://developer.mastercard.com/ob-accept-payments/documentation/tutorials-and-guides/obtain-psu-source-account-tutorial/index.md

This guide walks you through obtaining the PSU source account related to a payment you previously received through Mastercard Open Finance Pay. Refer [Refunds](https://developer.mastercard.com/ob-accept-payments/documentation/use-cases/refunds/index.md) for general specifications about integrating refunds.

We will not execute the refund when you have not signed up for a Mastercard Settlement Account. We will only help you obtain the PSU account so that you can perform the refund outside of this solution.

If you have a Mastercard Settlement Account, refer to the [Make a Refund (Mastercard Settlement Accounts only)](https://developer.mastercard.com/ob-accept-payments/documentation/tutorials-and-guides/make-a-refund-tutorial/index.md) guidance.

## Prerequisites {#prerequisites}

* You have been onboarded to Mastercard Open Finance Pay and have been set up with access to the Refunds endpoint.
* You have previously processed through us a payment for one of your Merchants.
* The `refundSupport` flag was set to TRUE as part of the respective Merchant's onboarding details.
* A decision has been made to refund the original payment either in full or partially.
* The refund amount for each specific refund request and the cumulative amount of all refunds made for a specific payment cannot exceed a threshold (percentage of the original payment) based on your agreed terms and conditions.
* You have successfully authenticated with the API (refer to the [Authentication](https://developer.mastercard.com/ob-accept-payments/documentation/api-basics/index.md) guide).

## Step 1 - Prepare the Necessary Refund Details {#step-1---prepare-the-necessary-refund-details}

To create a refund, you need to prepare the following:

* The `paymentId` for a previous payment made to one of your (Merchants) destination accounts and the payment is in at least an **INITIATED** or subsequent payment status.
* A clear **reason** for the refund. Refer to the list of supported refund reasons explained in the Refunds specification (Pre-conditions section).
* The **amount** of the refund. The amount for each specific refund request and the cumulative amount of all refunds made for a specific payment cannot exceed a threshold (percentage of the original payment) based on your agreed terms and conditions.

## Step 2 - Call the Create Payment Refund Endpoint {#step-2---call-the-create-payment-refund-endpoint}

Call the following endpoint and provide all required parameters.

API Reference: `POST /payments/{payment_id}/refunds`

### Request {#request}

* Use the `paymentId` of the original payment as `{payment_id}` path parameter.
* Use the **amount** prepared in the previous step.
* Ensure that the currency of the refund matches the currency of the original payment.
* Use the **reason** prepared in the previous step.

### Response {#response}

If the request is successful, the response will look like:

```json
{
"refundId": "79e86ce2-db6f-4ca1-a2bb-5986f32a6073"
}
```

Record the `refundId` for next steps.

In the background we will:

* Verify if the Payment Rail, including the PSU Source Account, is available for the original payment.
* Enable you to retrieve the Payment Rail and PSU Source Account information. (See the steps below)

## Step 3 - Refund Status Webhook Notification {#step-3---refund-status-webhook-notification}

When the Refund status changes you will receive a webhook notification of `type="RefundStatusUpdated"`.

The content of the webhook will look like this:

```json
{
  "type": "RefundStatusUpdated",
  "data": {
    "refundId": "acb29db6-70df-4c99-888c-d8485cd40c3d",
    "executionTime": "2024-01-01T12:34:56.123456+00:00",
    "status": {
      "code": "PAYMENT_EXECUTED_DEBITED",
      "lastUpdated": "2025-05-12T15:23:39.969894+00:00"
    }
  },
  "retryCount": 0
}
```

Record the `refundId` for the next step.

## Step 4 - Refund Result {#step-4---refund-result}

Retrieve the status of the refund using the Get Payment Refund endpoint.

API Reference: `GET /refunds/{refund_id}`

### Request {#request-1}

Use the `refundId` retrieved from the second step as the refund_id path parameter to get the refund status.

### Response {#response-1}

If the request is successful, the response will look like this:

```json
{
  "refundId": "472e651e-5a1e-424d-8098-23858bf03ad7",
  "paymentId": "472e651e-5a1e-424d-8098-23858bf03ad7",
  "createdDate": "2023-11-28T00:00:00.0000000+00:00",
  "amount": 0.1,
  "currency": "GBP",
  "reason": "string",
  "status": {
    "code": "string",
    "events": [],
    "lastUpdated": "2023-11-28T00:00:00.0000000+00:00",
    "details": {}
  },
  "clientAssignedReference": "reference",
  "forwardSettlementReference": "string"
}
```

Handle different refund outcomes based on the returned refund status code and reason code (see step 3 in the Refunds specification for description of status codes).

The statuses relevant for this step are:

|        **Status**         |  **Scope**   |                                                                                                    **Description**                                                                                                     |
|---------------------------|--------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| PREPARING                 | All requests | The refund request details have been captured and it is ready to be processed.                                                                                                                                         |
| PAYMENT_RAILS_AVAILABLE   | All requests | The refund cannot be executed, but the source account is available. The source account details are provided as a set of payment rails so that the client can execute the refund themselves. You can proceed to step 5. |
| PAYMENT_RAILS_UNAVAILABLE | All requests | The refund cannot be executed and the source account cannot be obtained. Consider starting a low for collecting the source account of the payment (see step 6 below).                                                  |

## Step 5 - Get Refund Payment Rails​ {#step-5---get-refund-payment-rails}

Retrieve the payment rails including the PSU account information using the Get Refund Payment Rails endpoint.

API Reference: `GET /refunds/{refund_id}/payment-rails`

### Request {#request-2}

Use the `refundId` retrieved from the second step as the `refund_id` path parameter to get the refund status.

### Response {#response-2}

If the request is successful, the response will look like:
Note: **Polymorphic models**   
The response models are polymorphic, with a different response for each payment rail. For example, the UkFasterPayments rail will return the sort code, accountNumber and accountName, while GermanSepaCreditTransfer will return the IBAN.

```json
{
  "paymentRail": "UkFasterPayments",
  "sortCode": "608371",
  "accountNumber": "31510604",
  "accountName": "John Doe"
}
```

## Step 6 - Call the Collect Refund Source Account Endpoint {#step-6---call-the-collect-refund-source-account-endpoint}

Engage the PSU in an AIS flow to capture their account. Note: This flow is currently not supported for payments made with the UKFasterPayments rail.

You can only call this if the refund has the status `PAYMENT_RAILS_UNAVAILABLE`. This happens when we cannot identify the PSU's original payment's PSU Source Account.

Call the following endpoint. Note that this will change the status of the Refund to `COLLECTING_SOURCE_ACCOUNT`.

API Reference: `POST /refunds/{refund_id}/payment-rails`

### Request {#request-3}

* Use the `refundId` retrieved from the second step as the `refund_id` path parameter to get the refund status.
* Specify a **redirectURL** where the user will be redirected after finishing the AIS flow. Please make sure this URL was allowlisted during onboarding.
* Optionally specify an **expiryDate**. The default will be 48 hours. The maximum is a week from the moment that the endpoint is called. Different maximum expiry can be configured during onboarding if needed.

### Response {#response-3}

If the request is successful, the response will look like:

```json
{
  "flowUrl": "https://mtf.connect.openbanking.mastercard.eu/accept-payments/payment-rails/start/472e651e-5a1e-424d-8098-23858bf03ad7"
}
```

Redirect the user to the **flowUrl** to start the AIS request authorization flow. This will require the PSU to go through an SCA with the ASPSP, select their account and authorize the account information request so that we can obtain the account details.

Once the flow is completed, we will redirect the PSU back to you on the **redirectUrl** specified in the request.

After that, you can go back and re-iterate from step 4 to obtain the PSU account.
