# Create a file payment

This tutorial presents how to create a [file payment](/docs/api/open-banking), which allows you to initiate a transaction batch with a single consent.

:::note
File payments are available only for Revolut Business users.
:::

The procedure is similar to [the procedure for other payment endpoints](/docs/guides/build-banking-apps/tutorials/initiate-your-first-payment), but it includes additional steps and considerations required to upload the batch files.

## Prerequisites

Before you begin, ensure that you have:

- Registered your application with the `payments` scope in the Developer Portal
- Obtained a sandbox/production `client_id` from the Developer Portal
- Obtained sandbox/production `transport.pem` and `signing.pem` certificates, from the Developer Portal or QTSP issuing body
- Uploaded the [`jwks_url`](/docs/guides/build-banking-apps/register-your-application-using-dcr/get-the-jwks-url) in the Developer Portal that is specific to your `signing.pem` certificate. Ensure that the `x5c` claim is specified.

:::tip
If unsure, head to [Get Started](/docs/guides/build-banking-apps/get-started/register-your-application-in-the-developer-portal) and review the setup process.
:::

:::warning
If you get certificate errors when using `curl` with Sandbox, it usually means your system [doesn't trust our certificate issuer](/docs/guides/build-banking-apps/get-started/get-access-token#certificates). The recommended approach is to add the certificate to your trusted store.

As a quick workaround, you can use the `-k` (or `--insecure`) option to skip certificate checks. **Be aware this disables all SSL verification, which can hide issues like expired or mismatched certificates and leaves you vulnerable to man-in-the-middle attacks**. For these reasons, avoid using `-k` in production or as a permanent solution.
:::

## 1. Create a file payment CSV

:::details [A file payment CSV contains all the payments that you want to initiate in a batch. It consists of the following fields, separated by a comma (`,`):]

| Field                    | Required                                 | Description                                                                                                                                  |
| ------------------------ | ---------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| `Name`                   | Yes                                      | Can contain up to 80 characters. If `recipient type` is `INDIVIDUAL`, this field must contain a first and a last name, separated by a space. |
| `Recipient type`         | Yes                                      | Can be either `INDIVIDUAL` or `COMPANY`.                                                                                                     |
| `Account number`         | For non-IBAN countries                   | Must contain valid account number if provided.                                                                                               |
| `Sort code`              | For UK local transfers                   | Must contain valid sort code if provided.                                                                                                    |
| `Routing number`         | For US local transfers                   | Must contain valid routing number if provided.                                                                                               |
| `IBAN`                   | For IBAN countries                       | Must contain valid IBAN if provided.                                                                                                         |
| `BIC`                    | All the countries except for UK/US local | Must contain valid BIC if provided.                                                                                                          |
| `Recipient bank country` | Yes                                      | Must contain a valid [ISO 3166-1](https://en.wikipedia.org/wiki/ISO_3166-1) country code.                                                    |
| `Currency`               | Yes                                      | Must contain valid [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) currency code.                                                         |
| `Amount`                 | Yes                                      | Must match the following pattern `[0-9]*(\.[0-9]*)?`.                                                                                        |
| `Payment reference`      | Yes                                      | Can contain up to 100 characters.                                                                                                            |
| `Recipient country`      | For international transfers <br /> (Note: SEPA EUR transfers are treated as local transfers) | Must contain a valid [ISO 3166-1](https://en.wikipedia.org/wiki/ISO_3166-1) country code if provided.                                        |
| `State or province`      | For transfers to US, AU, CA, or MX       | Can contain up to 50 characters.                                                                                                             |
| `Address line 1`         | For international transfers <br /> (Note: SEPA EUR transfers are treated as local transfers) | Can contain up to 50 characters.                                                                                                             |
| `Address line 2`         | No                                       | Can contain up to 50 characters.                                                                                                             |
| `City`                   | For international transfers <br /> (Note: SEPA EUR transfers are treated as local transfers) | Can contain up to 50 characters.                                                                                                             |
| `Postal code`            | For international transfers <br /> (Note: SEPA EUR transfers are treated as local transfers) | Can contain up to 50 characters.                                                                                                             |

:::

For the purpose of this tutorial, we will use the following sample file contents and save it as `file.csv`:

- ![UK local transfer]

  ```csv
  Name,Recipient type,Account number,Sort code,Recipient bank country,Currency,Amount,Payment reference
  John Smith,INDIVIDUAL,40513598,207409,GB,GBP,10,First comment
  John Doe,INDIVIDUAL,90352556,600001,GB,GBP,10,Second comment
  ```

- ![US local transfer]

  ```csv
  Name,Recipient type,Account number,Routing number,Recipient bank country,Currency,Amount,Payment reference,Recipient country,State or province,Address line 1,Address line 2,City,Postal code
  John Smith,INDIVIDUAL,531782059505,024600402,US,USD,10,First comment,US,California,Revolutest LTD,2340 Marietta Street,Oakland,94612
  John Doe,INDIVIDUAL,356972945639,118677794,US,USD,10,Second comment,US,Arkansas,Revolutest LTD,3243 Midway Road,Portland,71654
  ```

- ![IBAN transfer]

  ```csv
  Name,Recipient type,IBAN,BIC,Recipient bank country,Currency,Amount,Payment reference,Recipient country,State or province,Address line 1,Address line 2,City,Postal code
  Jaques Martin,INDIVIDUAL,FR0514508000305251415643Y69,SOGEFRPP,FR,EUR,10,First comment,FR,Bretagne,Revolutest LTD,82 rue Lenotre,RENNES,35000
  Sophie Martin,INDIVIDUAL,FR1420041010050500013M02606,LBPAFRPP,FR,EUR,10,Second comment,FR,Aquitaine,Revolutest LTD,52 rue Jean Vilar,BERGERAC,24100
  ```

:::note
If you use your own CSV file, remember to replace the file name later when you [compute the hash](#2-compute-the-hash-of-the-csv-file).
:::

## 2. Compute the hash of the CSV file

Compute the `SHA256` hash of the CSV file. To do it from a Command Line Interface (CLI), follow these steps:

1. Open the CLI, for example, Terminal in macOS.
2. In your CLI, navigate to the directory in which you saved the CSV file.
3. Compute the `SHA256` hash of your [CSV file](#1-create-a-file-payment-csv).
 If you're using your own CSV file, replace `file.csv` with your file's name.

   ```
   cat file.csv | shasum -a 256 | xxd -r -p | base64
   ```

:::tip [Expected result]
The above command returns the `SHA256` hash of the CSV file. For our sample `file.csv`, this would be:

```text
2nDGfxr0OI5+ts/iz9/+mk3VYTxhamlWA3P65a5LuKs=
```

Save the resulting hash for further steps.
:::

:::info
The resulting hash will be different with any minor modification to the file, so it uniquely identifies the contents of the file.
:::

## 3. Generate a client credentials token

Request an access token for client credentials using the `/token` endpoint and the `client_credentials` grant type with the scope `payments`:

- ![Production]

  ```shell
  curl --cert transport.pem --key private.key \
  --location --request POST 'https://oba-auth.revolut.com/token' \
  --header 'Content-Type: application/x-www-form-urlencoded' \
  --data-urlencode 'grant_type=client_credentials' \
  --data-urlencode 'scope=payments' \
  --data-urlencode 'client_id=<your client_id>'
  ```

- ![Sandbox]

  ```shell
  curl --cert transport.pem --key private.key \
  --location --request POST 'https://sandbox-oba-auth.revolut.com/token' \
  --header 'Content-Type: application/x-www-form-urlencoded' \
  --data-urlencode 'grant_type=client_credentials' \
  --data-urlencode 'scope=payments' \
  --data-urlencode 'client_id=<your client_id>'
  ```

Response:

```json
{
  "access_token": "<JWT client credentials>",
  "token_type": "Bearer",
  "expires_in": 2399
}
```

You can use this token to:

- [Create a file payment consent](#2-create-a-file-payment-consent)
- [Upload a file for a file payment](/docs/api/open-banking#upload-a-payment-file)
- [Check the status of a previously created payment consent](/docs/api/open-banking#retrieve-a-file-payment-consent)
- [Check the status of a previously completed payment](/docs/api/open-banking#retrieve-a-file-payment)

:::note
When your token expires and you need a new one, repeat this procedure to generate a new token.
:::

## 4. Create a file payment consent

Create a consent to initiate a file payment on behalf of a Revolut customer.

### Consent prerequisites

When you create the consent, ensure that you:

- Use your access token that you [obtained with `grant_type=client_credentials`](#3-generate-a-client-credentials-token) as the Bearer token.
- Specify the `x-idempotency-key` header so that when there is a network failure and you do not receive the ID from the response, you can safely retry the request.
- Provide the `x-jws-signature` header in the API request.

  It must contain a valid JSON Web Signature (JWS) of the request payload body.
  When generating the signature, use the following JSON header:

  ```json
  {
    "alg": "PS256",
    "kid": "<kid parameter of your signing certificate>",
    "crit": ["http://openbanking.org.uk/tan"],
    "http://openbanking.org.uk/tan": "<root domain of your JWKS URL>"
  }
  ```
  
  The result is a string consisting of the above header in base64 encoding, followed by two dots and the cryptographic signature.
:::warning
  The signature in the JWS validates the header and payload as text, so make sure the payload used when generating the signature is exactly the same as the payload sent in the request payload, including JSON formatting, line breaks and spacing.
  :::
  
  You can read more about JSON Web Signatures [here](/docs/guides/build-banking-apps/tutorials/work-with-json-web-signatures).

### Create a consent

Make a file payment consent request. An example request looks like this:

- ![Production]

  ```shell
  curl --location --request POST 'https://oba-auth.revolut.com/file-payment-consents' \
  --header 'x-fapi-financial-id: 001580000103UAvAAM' \
  --header 'Content-Type: application/json' \
  --header 'x-idempotency-key: 123' \
  --header 'Authorization: Bearer <insert JWT client credentials from step 3.>' \
  --header 'x-jws-signature: <insert JWS>' \
  --data '{
      "Data": {
          "Initiation": {
              "FileType": "text/csv",
              "FileHash": "2nDGfxr0OI5+ts/iz9/+mk3VYTxhamlWA3P65a5LuKs=",
              "FileReference": "reference1234"
          }
      }
  }'
  ```

  Response:

  ```json
  {
      "Data": {
          "Status": "AwaitingUpload",
          "StatusUpdateDateTime": "2023-11-08T16:23:57.491851Z",
          "CreationDateTime": "2023-11-08T16:23:57.491851Z",
          "ConsentId": "f3e5d778-a0b6-48c5-bae2-886f0097d51f",
          "Initiation": {
              "FileType": "text/csv",
              "FileHash": "2nDGfxr0OI5+ts/iz9/+mk3VYTxhamlWA3P65a5LuKs=",
              "FileReference": "reference1234"
          }
      },
      "Links": {
          "Self": "https://oba-auth.revolut.com/file-payment-consents/f3e5d778-a0b6-48c5-bae2-886f0097d51f"
      },
      "Meta": {
          "TotalPages": 1
      }
  }
  ```

- ![Sandbox]

  ```shell
  curl --location --request POST 'https://sandbox-oba-auth.revolut.com/file-payment-consents' \
  --header 'x-fapi-financial-id: 001580000103UAvAAM' \
  --header 'Content-Type: application/json' \
  --header 'x-idempotency-key: 123' \
  --header 'Authorization: Bearer <insert JWT client credentials from step 3.>' \
  --header 'x-jws-signature: <insert JWS>' \
  --data '{
      "Data": {
          "Initiation": {
              "FileType": "text/csv",
              "FileHash": "2nDGfxr0OI5+ts/iz9/+mk3VYTxhamlWA3P65a5LuKs=",
              "FileReference": "reference1234"
          }
      }
  }'
  ```

  Response:

  ```json
  {
      "Data": {
          "Status": "AwaitingUpload",
          "StatusUpdateDateTime": "2023-11-08T16:23:57.491851Z",
          "CreationDateTime": "2023-11-08T16:23:57.491851Z",
          "ConsentId": "f3e5d778-a0b6-48c5-bae2-886f0097d51f",
          "Initiation": {
              "FileType": "text/csv",
              "FileHash": "2nDGfxr0OI5+ts/iz9/+mk3VYTxhamlWA3P65a5LuKs=",
              "FileReference": "reference1234"
          }
      },
      "Links": {
          "Self": "https://sandbox-oba-auth.revolut.com/file-payment-consents/f3e5d778-a0b6-48c5-bae2-886f0097d51f"
      },
      "Meta": {
          "TotalPages": 1
      }
  }
  ```

For the full list of available parameters and other details:

[See the API reference: Create a file payment consent](/docs/api/open-banking#create-a-file-payment-consent)

:::tip [Expected result]
The consent has been created, and the CSV file has been loaded.

The ID of the created consent (`Data.ConsentId`) is returned in the response. 
Copy this value, as you will need it for further steps. In our example, the obtained consent ID is `f3e5d778-a0b6-48c5-bae2-886f0097d51f`.
:::

## 5. Upload the CSV file

After the consent has been successfully created, you must upload the CSV file in a separate request.

:::note
- Use the same access token that you [obtained with `grant_type=client_credentials`](#3-generate-a-client-credentials-token) as the Bearer token.
- Use the `ConsentId` [obtained after creating the consent](#4-create-a-file-payment-consent).
- To calculate the `x-jws-signature` header parameter, use the same process as described in [the previous step](#consent-prerequisites) and provide the content of the CSV file as the payload.
- In the request body, provide the local path to where the CSV file that you're uploading is located on your machine. For example: `--data '@/Users/john.doe/Desktop/file.csv'`.
:::

- ![Production]

  ```shell
  curl --location 'https://oba-auth.revolut.com/file-payment-consents/<insert ConsentId from step 4.>/file' \
  --header 'x-fapi-financial-id: 001580000103UAvAAM' \
  --header 'Content-Type: text/csv' \
  --header 'x-idempotency-key: 123' \
  --header 'Authorization: Bearer <insert JWT client credentials from step 3.>' \
  --header 'x-jws-signature: <insert JWS>' \
  --data '@<insert full path to your CSV file>'
  ```

- ![Sandbox]

  ```shell
  curl --location 'https://sandbox-oba-auth.revolut.com/file-payment-consents/<insert ConsentId from step 4.>/file' \
  --header 'x-fapi-financial-id: 001580000103UAvAAM' \
  --header 'Content-Type: text/csv' \
  --header 'x-idempotency-key: 123' \
  --header 'Authorization: Bearer <insert JWT client credentials from step 3.>' \
  --header 'x-jws-signature: <insert JWS>' \
  --data '@<insert full path to your CSV file>'
  ```

For the full list of available parameters and other details:

[See the API reference: Upload a payment file](/docs/api/open-banking#upload-a-payment-file)

:::tip [Expected result]
On successful upload, you receive an empty JSON object as a response:

```json
{}
```
:::

## 6. Create a JWT URL parameter

After you create a consent, you need the user to authorise the consent so that you can initiate a payment on their behalf.

Create a JWT request parameter with the following header and payload.
Use the private key corresponding to your signing certificate.
This signature will be validated using the JWKs endpoint that you specified when you registered your application.

:::note [Header and payload parameters]
- The values of `client_id`, `redirect_uri`, `kid`, and `scope` should correspond to those for your specific application and consent request.
- The value of `openbanking_intent_id` is the value of the `ConsentId` field returned in the [consent creation response](#4-create-a-file-payment-consent).
- `state` is an OAuth parameter that lets you restore the state of the application after redirection.
  If provided, this value is returned in the redirect URI.
- `nbf` and `exp` should contain the Unix timestamps before and after which the JWT is not valid.

For more details on these parameters, see the guide: [Work with JSON Web Tokens](/docs/guides/build-banking-apps/tutorials/work-with-json-web-tokens).
:::

Header:

```json
{
  "alg": "PS256",
  "kid": "<insert kid>"
}
```

Body:

```json
{
  "response_type": "code id_token",
  "client_id": "<insert client_id>",
  "redirect_uri": "<insert redirect_uri>",
  "aud": "https://oba-auth.revolut.com",
  "scope": "payments",
  "state": "<insert state>",
  "nbf": <insert nbf>,
  "exp": <insert exp>,
  "claims": {
    "id_token": {
      "openbanking_intent_id": {
        "value": "<insert ConsentId>"
      }
    }
  }
}
```

## 7. Get consent from the user

Create an authorisation URL with the following parameters. Make sure they are URL-encoded.

| Parameter       | Description                                                                                                                                                                                                                                                                                                          | Required |
| --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
| `response_type` | Always set to `code id_token`.                                                                                                                                                                                                                                                                                       | yes      |
| `client_id`     | The client ID for your application.                                                                                                                                                                                                                                                                                  | yes      |
| `redirect_uri`  | One of the redirect URIs that you defined when you created the application. Keep it static without variable parameters (`https://example.com`) and pass any return information or additional parameter via the `state` parameter in the [JWT payload](#6-create-a-jwt-url-parameter), not inside the `redirect_uri`. | yes      |
| `scope`         | The scope that you are requesting, for example, `accounts` or `payments`. For file payments, you need the scope `payments`.                                                                                                                                                                                          | yes      |
| `request`       | The encoded JWT generated in the [previous step](#6-create-a-jwt-url-parameter).                                                                                                                                                                                                                                     | yes      |
| `response_mode` | If set to `fragment`, parameters are passed in the fragment section of the redirect URI. Otherwise, they are passed in the URI query. Passing parameters in fragment is considered to be more secure.                                                                                                                | no       |

A sample authorisation URL looks like this:

- ![Production]

  ```shell
  https://oba.revolut.com/ui/index.html?response_type=code%20id_token&scope=payments&redirect_uri=<insert redirect URL>&client_id=<insert client_id>&request=<insert JWT from step 3.>
  ```

- ![Sandbox]

  ```shell
  https://sandbox-oba.revolut.com/ui/index.html?response_type=code%20id_token&scope=payments&redirect_uri=<insert redirect URL>&client_id=<insert client_id>&request=<insert JWT from step 3.>
  ```

:::tip [Expected result]
Once you have redirected the user to the authorisation URL, they will need to provide their Revolut credentials and complete the payment authorisation.

After authorising the payment, the user will be redirected back to the redirect URL (`redirect_uri`) containing the authorisation code (`code`) as a URL parameter, as in the below example:

```text
https://example.com/?code=oa_sand_sPoyVs-oMhyR36j5N-ZEVLfK9rQWPNssgIQqsOFZQ-c&id_token=<JWT id_token>&state=example_state
```

Use this authorisation code in the [next step](#8-exchange-the-authorisation-code-for-an-access-token).
:::

:::warning
The `code` is valid only for two minutes.
:::

## 8. Exchange the authorisation code for an access token

Exchange the `code` parameter obtained when [getting the consent](#7-get-consent-from-the-user) for a new access token:

- ![Production]

  ```shell
  curl  --key private.key --cert transport.pem \
  --location --request POST 'https://oba-auth.revolut.com/token' \
  --header 'Content-Type:application/x-www-form-urlencoded' \
  --data-urlencode 'grant_type=authorization_code' \
  --data-urlencode 'client_id=<your client_id>' \
  --data-urlencode 'code=<insert code>'
  ```

  Response:

  ```json
  {
    "access_token":"oa_prod_tP1Nofi1ixsRfBmVBtVPdIVN0J5x91imqmheQIWTS5s",
    "token_type":"Bearer",
    "expires_in":86376,
    "id_token":"<JWT id_token>"
  }
  ```

- ![Sandbox]

  ```shell
  curl --key private.key --cert transport.pem \
  --location --request POST 'https://sandbox-oba-auth.revolut.com/token' \
  --header 'Content-Type:application/x-www-form-urlencoded' \
  --data-urlencode 'grant_type=authorization_code' \
  --data-urlencode 'client_id=<your client_id>' \
  --data-urlencode 'code=<insert code>'
  ```

  Response:

  ```json
  {
    "access_token":"oa_sand_N0J5x91imqmVBtVPdIVmhtP1Nofi1ixsRfBeQIWTS5s",
    "token_type":"Bearer",
    "expires_in":86376,
    "id_token":"<JWT id_token>"
  }
  ```

:::tip [Expected result]
The access token (`access_token`) returned in this response will allow you to execute the batch payment.
:::

:::note
This access token is valid only for 24 hours.
:::

## 9. Initiate the file payment

Now you can initiate the file payment on the user's behalf. Make a call to the `/file-payments` endpoint to initiate the payments.

In the request body, use the same JSON content which was used previously in the [consent request](#4-create-a-file-payment-consent), and add the `Data.ConsentId` key with the `ConsentId` value which you received when creating the consent.

:::note
For this request, you must also use:
- The [`x-jws-signature` header](#consent-prerequisites), which you must calculate again with the new payload.
- The access token which was [obtained with the authorisation code](#8-exchange-the-authorisation-code-for-an-access-token).
:::

- ![Production]

  ```shell
  curl --cert transport.pem --key private.key \
  --location --request POST 'https://oba-auth.revolut.com/file-payments' \
  --header 'x-fapi-financial-id: 001580000103UAvAAM' \
  --header 'Content-Type: application/json' \
  --header 'x-idempotency-key: 123' \
  --header 'Authorization: Bearer <insert access_token from step 8.>' \
  --header 'x-jws-signature: <insert JWS>' \
  --data '{
      "Data": {
          "ConsentId": "f3e5d778-a0b6-48c5-bae2-886f0097d51f",
          "Initiation": {
              "FileType": "text/csv",
              "FileHash": "2nDGfxr0OI5+ts/iz9/+mk3VYTxhamlWA3P65a5LuKs=",
              "FileReference": "reference1234"
          }
      }
  }'
  ```

  Response:

  ```json
  {
      "Data": {
          "ConsentId": "f3e5d778-a0b6-48c5-bae2-886f0097d51f",
          "CreationDateTime": "2023-11-13T13:46:47.678627Z",
          "FilePaymentId": "e82cced4-8277-4220-bb0a-72775876f2ea",
          "Initiation": {
              "DebtorAccount": {
                  "SchemeName": "UK.OBIE.IBAN",
                  "Identification": "GB95REVO00997053872360",
                  "Name": "John Doe"
              },
              "FileHash": "2nDGfxr0OI5+ts/iz9/+mk3VYTxhamlWA3P65a5LuKs=",
              "FileReference": "reference1234",
              "FileType": "text/csv"
          },
          "Status": "InitiationCompleted",
          "StatusUpdateDateTime": "2023-11-13T13:46:47.678627Z"
      },
      "Links": {
          "Self": "https://oba-auth.revolut.com/file-payments/e82cced4-8277-4220-bb0a-72775876f2ea"
      },
      "Meta": {
          "TotalPages": 1
      }
  }
  ```

- ![Sandbox]

  ```shell
  curl --cert transport.pem --key private.key \
  --location --request POST 'https://sandbox-oba-auth.revolut.com/file-payments' \
  --header 'x-fapi-financial-id: 001580000103UAvAAM' \
  --header 'Content-Type: application/json' \
  --header 'x-idempotency-key: 123' \
  --header 'Authorization: Bearer <insert access_token from step 8.>' \
  --header 'x-jws-signature: <insert JWS>' \
  --data '{
      "Data": {
          "ConsentId": "f3e5d778-a0b6-48c5-bae2-886f0097d51f",
          "Initiation": {
              "FileType": "text/csv",
              "FileHash": "2nDGfxr0OI5+ts/iz9/+mk3VYTxhamlWA3P65a5LuKs=",
              "FileReference": "reference1234"
          }
      }
  }'
  ```

  Response:

  ```json
  {
      "Data": {
          "Status": "InitiationCompleted",
          "StatusUpdateDateTime": "2023-11-13T13:46:47.678627Z",
          "CreationDateTime": "2023-11-13T13:46:47.678627Z",
          "FilePaymentId": "e82cced4-8277-4220-bb0a-72775876f2ea",
          "ConsentId": "f3e5d778-a0b6-48c5-bae2-886f0097d51f",
          "Initiation": {
              "DebtorAccount": {
                  "SchemeName": "UK.OBIE.IBAN",
                  "Identification": "GB95REVO00997053872360",
                  "Name": "John Doe"
              },
              "FileType": "text/csv",
              "FileHash": "2nDGfxr0OI5+ts/iz9/+mk3VYTxhamlWA3P65a5LuKs=",
              "FileReference": "reference1234"
          }
      },
      "Links": {
          "Self": "https://sandbox-oba-auth.revolut.com/file-payments/e82cced4-8277-4220-bb0a-72775876f2ea"
      },
      "Meta": {
          "TotalPages": 1
      }
  }
  ```

For more details about this call:

[See the API reference: Create a file payment](/docs/api/open-banking#create-a-file-payment)

:::tip [Congratulations!]
You have successfully initiated your first file payment.

Save the `FilePaymentId` value from the response so that you can later check the status of the payments execution.
:::

## 10. Check the file payment status

After you execute a file payment, it will typically go into the `InitiationInProcess` status.

To check the status of the batch payment, make a request and provide the file payment ID.

:::note
- You can use the [previously generated access token](#3-generate-a-client-credentials-token) with the grant type `client_credentials` and scope `payments` while it's still valid.
After the token has expired, generate a new one in the same way.
- Use the `FilePaymentId` value obtained when [initiating the payment](#9-initiate-the-file-payment).
:::

- ![Production]

  Request:

  ```shell
  curl --cert transport.pem --key private.key \
  --location 'https://oba-auth.revolut.com/file-payments/<FilePaymentId>' \
  --header 'x-fapi-financial-id: 001580000103UAvAAM' \
  --header 'Authorization: Bearer <access_token>'
  ```

  Response:

  ```json
  {
      "Data": {
          "Status": "InitiationCompleted",
          "StatusUpdateDateTime": "2023-11-13T13:46:49.116202Z",
          "CreationDateTime": "2023-11-13T13:46:47.678627Z",
          "FilePaymentId": "e82cced4-8277-4220-bb0a-72775876f2ea",
          "ConsentId": "f3e5d778-a0b6-48c5-bae2-886f0097d51f",
          "Initiation": {
              "DebtorAccount": {
                  "SchemeName": "UK.OBIE.IBAN",
                  "Identification": "GB95REVO00997053872360",
                  "Name": "John Doe"
              },
              "FileType": "text/csv",
              "FileHash": "2nDGfxr0OI5+ts/iz9/+mk3VYTxhamlWA3P65a5LuKs=",
              "FileReference": "reference1234"
          }
      },
      "Links": {
          "Self": "https://oba-auth.revolut.com/file-payments/e82cced4-8277-4220-bb0a-72775876f2ea"
      },
      "Meta": {
          "TotalPages": 1
      }
  }
  ```

- ![Sandbox]

  Request:

  ```shell
  curl --cert transport.pem --key private.key \
  --location 'https://sandbox-oba-auth.revolut.com/file-payments/<FilePaymentId>' \
  --header 'x-fapi-financial-id: 001580000103UAvAAM' \
  --header 'Authorization: Bearer <access_token>'
  ```

  Response:

  ```json
  {
      "Data": {
          "Status": "InitiationCompleted",
          "StatusUpdateDateTime": "2023-11-13T13:46:49.116202Z",
          "CreationDateTime": "2023-11-13T13:46:47.678627Z",
          "FilePaymentId": "e82cced4-8277-4220-bb0a-72775876f2ea",
          "ConsentId": "f3e5d778-a0b6-48c5-bae2-886f0097d51f",
          "Initiation": {
              "DebtorAccount": {
                  "SchemeName": "UK.OBIE.IBAN",
                  "Identification": "GB95REVO00997053872360",
                  "Name": "John Doe"
              },
              "FileType": "text/csv",
              "FileHash": "2nDGfxr0OI5+ts/iz9/+mk3VYTxhamlWA3P65a5LuKs=",
              "FileReference": "reference1234"
          }
      },
      "Links": {
          "Self": "https://sandbox-oba-auth.revolut.com/file-payments/e82cced4-8277-4220-bb0a-72775876f2ea"
      },
      "Meta": {
          "TotalPages": 1
      }
  }
  ```

For more details about this call:

[See the API reference: Retrieve a file payment](/docs/api/open-banking#retrieve-a-file-payment)

## 11. Check the status of all payments

You can also check the status of all the payments included in the file payment.

:::note
- You can use the [previously generated access token](#3-generate-a-client-credentials-token) with the grant type `client_credentials` and scope `payments` while it's still valid.
    After the token has expired, generate a new one in the same way.
- Use the `FilePaymentId` value obtained when [initiating the payment](#9-initiate-the-file-payment).
:::

- ![Production]

  ```shell
  curl --cert transport.pem --key private.key \
  --location 'https://oba-auth.revolut.com/file-payments/<FilePaymentId>/report-file' \
  --header 'x-fapi-financial-id: 001580000103UAvAAM' \
  --header 'Authorization: Bearer <access_token>'
  ```

- ![Sandbox]

  ```shell
  curl --cert transport.pem --key private.key \
  --location 'https://sandbox-oba-auth.revolut.com/file-payments/<FilePaymentId>/report-file' \
  --header 'x-fapi-financial-id: 001580000103UAvAAM' \
  --header 'Authorization: Bearer <access_token>'
  ```

Response:

```json
{
    "Payments": [
        {
            "Amount": {
                "Amount": "10.00",
                "Currency": "GBP"
            },
            "Reference": "First comment",
            "Status": "Created"
        },
        {
            "Amount": {
                "Amount": "10.00",
                "Currency": "GBP"
            },
            "Reference": "Second comment",
            "Status": "Created"
        }
    ]
}
```

For more details about this call:

[See the API reference: Retrieve all payments of a file payment](/docs/api/open-banking#retrieve-all-payments-of-a-file-payment)

## What's next

- See [Open Banking API: File payment](/docs/api/open-banking) for full details on the file payments API.
- Test the above in [Postman](/docs/guides/build-banking-apps/tutorials/test-with-postman/get-a-payment-consent) without having to write any code.