> ## Documentation Index
> Fetch the complete documentation index at: https://docs.yapily.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Tutorial: Make a bulk payment

> Step-by-step tutorial for completing a UK domestic bulk payment with Yapily's Open Banking API. Covers payment file structure, user consent, and status tracking.

<Note>
  Bulk Payments are currently available as a BETA version.
</Note>

## Introduction

This tutorial explains how to create a UK domestic bulk payment with the Modelo Sandbox.

**Note:** All requests made to the Yapily API require [basic authentication](/getting-started/integration-setup/api-authentication).

***

<Steps>
  <Step title="Select bank">
    To find which banks support bulk payments use [GET institutions](/api-reference/institutions/get-institutions) to retrieve the list of your supported institutions.

    <CodeGroup>
      ```bash Request theme={null}
      curl -L -X GET 'https://api.yapily.com/institutions' \
        -u 'APPLICATION_KEY:APPLICATION_SECRET'
      ```

      ```json Response theme={null}
      {
        "meta": {
          "tracingId": "acbb76db4ab8f4ac7f039d000456c13f",
          "count": 1
        },
        "data": [
          {
            "id": "modelo-sandbox",
            "name": "Modelo Sandbox",
            "fullName": "Modelo Sandbox",
            "countries": [
              {
                "displayName": "United Kingdom",
                "countryCode2": "GB"
              }
            ],
            "environmentType": "SANDBOX",
            "credentialsType": "OPEN_BANKING_UK_AUTO",
            "media": [
              {
                "source": "https://images.yapily.com/image/ce2bfdbf-1ae2-4919-ab7b-e8b3d5e93b36?size=0",
                "type": "icon"
              },
              {
                "source": "https://images.yapily.com/image/ca502f24-d6df-4785-b4b8-1034b100af77?size=0",
                "type": "logo"
              }
            ],
            "features": [
              "INITIATE_ACCOUNT_REQUEST",
              "ACCOUNT_REQUEST_DETAILS",
              "EXISTING_PAYMENTS_DETAILS",
              "ACCOUNT_BALANCES",
              "CREATE_BULK_PAYMENT",
              "ACCOUNT_PERIODIC_PAYMENTS",
              "ACCOUNT_STATEMENTS",
              "INITIATE_BULK_PAYMENT",
              "ACCOUNT_STATEMENT",
              "ACCOUNT",
              "INITIATE_DOMESTIC_PERIODIC_PAYMENT",
              "INITIATE_SINGLE_PAYMENT_SORTCODE",
              "ACCOUNT_DIRECT_DEBITS",
              "ACCOUNTS",
              "ACCOUNT_TRANSACTIONS",
              "EXISTING_PAYMENT_INITIATION_DETAILS",
              "CREATE_DOMESTIC_SINGLE_PAYMENT",
              "INITIATE_DOMESTIC_SINGLE_PAYMENT",
              "ACCOUNT_STATEMENT_FILE",
              "CREATE_INTERNATIONAL_SINGLE_PAYMENT",
              "IDENTITY",
              "CREATE_DOMESTIC_SCHEDULED_PAYMENT",
              "INITIATE_DOMESTIC_SCHEDULED_PAYMENT",
              "CREATE_SINGLE_PAYMENT_SORTCODE",
              "ACCOUNT_TRANSACTIONS_WITH_MERCHANT",
              "INITIATE_INTERNATIONAL_SINGLE_PAYMENT",
              "PERIODIC_PAYMENT_FREQUENCY_EXTENDED",
              "ACCOUNT_SCHEDULED_PAYMENTS",
              "CREATE_DOMESTIC_PERIODIC_PAYMENT"
            ]
          }
        ]
      }
      ```
    </CodeGroup>

    Filter the list for all institutions that support the feature `CREATE_BULK_PAYMENT`. Then display these institutions in your application so the user can select which bank to make the payment from.

    Once the user selects a bank, store the `id` of the institution to use in step 2.
  </Step>

  <Step title="Authorise">
    <Info>
      This example uses a single redirect flow using a callback URL.
    </Info>

    Execute [create payment authorisation](/api-reference/authorisations/create-bulk-payment-authorisation) including the institution ID, your callback URL and the `paymentRequest` object.

    <CodeGroup>
      ```bash Request theme={null}
      curl -L -X POST 'https://api.yapily.com/bulk-payment-auth-requests' \
        -H 'Content-Type: application/json' \
        -u 'APPLICATION_KEY:APPLICATION_SECRET' \
        -d '{
            "applicationUserId": "bulk-payment-tutorial",
            "institutionId": "modelo-sandbox",
            "callback": "https://display-parameters.com/",
            "paymentRequest": {
                "payments": [
                    {
                        "type": "DOMESTIC_PAYMENT",
                        "reference": "Payment 1",
                        "paymentIdempotencyId": "{uniqueValue}",
                        "amount": {
                            "amount": 8.70,
                            "currency": "GBP"
                        },
                        "payee": {
                            "name": "BILLS COFFEE LTD",
                            "accountIdentifications": [
                                {
                                    "type": "ACCOUNT_NUMBER",
                                    "identification": "{accountNumber}"
                                },
                                {
                                    "type": "SORT_CODE",
                                    "identification": "{sortCode}"
                                }
                            ],
                            "address": {
                                "country": "GB"
                            }
                        }
                    },
                    {
                        "type": "DOMESTIC_PAYMENT",
                        "reference": "Payment 2",
                        "paymentIdempotencyId": "{uniqueValue}",
                        "amount": {
                            "amount": 8.70,
                            "currency": "GBP"
                        },
                        "payee": {
                            "name": "BILLS COFFEE LTD",
                            "accountIdentifications": [
                                {
                                    "type": "ACCOUNT_NUMBER",
                                    "identification": "{accountNumber}"
                                },
                                {
                                    "type": "SORT_CODE",
                                    "identification": "{sortCode}"
                                }
                            ],
                            "address": {
                                "country": "GB"
                            }
                        }
                    }
                ]
            }
        }'
      ```

      ```json Response theme={null}
      {
        "meta": {
          "tracingId": "611f74cb4f3205d983ebb2fca59d0847"
        },
        "data": {
          "id": "af563bac-e50a-42bd-91bc-581813e13733",
          "userUuid": "f3be3c23-bd0e-475e-b389-62dd1f5aa6c1",
          "applicationUserId": "bulk-payment-tutorial",
          "institutionId": "modelo-sandbox",
          "status": "AWAITING_AUTHORIZATION",
          "createdAt": "2021-03-03T09:23:45.841Z",
          "featureScope": [
            "EXISTING_PAYMENTS_DETAILS",
            "EXISTING_PAYMENT_INITIATION_DETAILS",
            "CREATE_BULK_PAYMENT"
          ],
          "state": "6b07bddf9e7746ae8ecb7cbecc00f19a",
          "institutionConsentId": "sdp-1-469c63ef-e6b6-4dd2-88b7-3aea0bff4136",
          "authorisationUrl": "{authorisationUrl}",
          "qrCodeUrl": "https://images.yapily.com/image/55b6b6bc-daa8-490c-89e1-243156868e00/1614763426?size=0"
        }
      }
      ```
    </CodeGroup>

    Redirect the user to the `authorisationUrl` returned in the response.

    The user is then asked to login and authorise the payment with their bank. The Modelo sandbox credentials are: `mits` / `mits`.

    Upon completion, the user is redirected back to the callback URL supplied in the request. In this example, the callback is `https://display-parameters.com/` which displays the parameters returned with the redirect.

    Store the `consentToken` to use when creating the payment in step 3.
  </Step>

  <Step title="Create payment">
    [Create the bulk payment](/api-reference/payments/create-bulk-payment) specifying the `consentToken` in the header and the contents of the `paymentRequest` object in step 2 as the body.

    <CodeGroup>
      ```bash Request theme={null}
      curl -L -X POST 'https://api.yapily.com/bulk-payments' \
        -H 'Content-Type: application/json' \
        -H 'Consent: {consentToken}' \
        -u 'APPLICATION_KEY:APPLICATION_SECRET' \
        -d '{
            "payments": [
                {
                    "type": "DOMESTIC_PAYMENT",
                    "reference": "Payment 1",
                    "paymentIdempotencyId": "{uniqueValue}",
                    "amount": {
                        "amount": 8.70,
                        "currency": "GBP"
                    },
                    "payee": {
                        "name": "BILLS COFFEE LTD",
                        "accountIdentifications": [
                            {
                                "type": "ACCOUNT_NUMBER",
                                "identification": "{accountNumber}"
                            },
                            {
                                "type": "SORT_CODE",
                                "identification": "{sortCode}"
                            }
                        ],
                        "address": {
                            "country": "GB"
                        }
                    }
                },
                {
                    "type": "DOMESTIC_PAYMENT",
                    "reference": "Payment 2",
                    "paymentIdempotencyId": "{uniqueValue}",
                    "amount": {
                        "amount": 8.70,
                        "currency": "GBP"
                    },
                    "payee": {
                        "name": "BILLS COFFEE LTD",
                        "accountIdentifications": [
                            {
                                "type": "ACCOUNT_NUMBER",
                                "identification": "{accountNumber}"
                            },
                            {
                                "type": "SORT_CODE",
                                "identification": "{sortCode}"
                            }
                        ],
                        "address": {
                            "country": "GB"
                        }
                    }
                }
            ]
        }'
      ```

      ```json Response theme={null}
      {
        "meta": {
          "tracingId": "0cda48c70f3941148bbee775a65fa3d0"
        },
        "data": {
          "id": "pv3-a1e2ecb0-270c-42e2-8ba5-005261b629d2",
          "institutionConsentId": "sdp-6-b06f9a82-c641-4aba-b76d-43e6bc052f75",
          "status": "PENDING",
          "statusDetails": {
            "status": "PENDING",
            "statusUpdateDate": "2021-06-09T13:53:28.67Z"
          },
          "createdAt": "2021-06-09T13:53:28.67Z",
          "bulkAmountSum": 7
        }
      }
      ```
    </CodeGroup>

    The payment `status`, which describes the state of the payment, is returned in the response.

    If the status is `PENDING`, you can use the payment `id` to poll the payment status until it transitions to `COMPLETED` or `FAILED` as in step 4.

    For more information see [payment status](/payments/payment-resources/payment-status).
  </Step>

  <Step title="Confirm payment">
    <Info>
      This is an optional step, however we recommend monitoring the status of the payment when its `PENDING` to confirm if the institution accepts the payment initiation request.
    </Info>

    You can confirm the status of the file payment by polling the status using the bulk payment `Id` from step 3.

    Execute get payment details (`GET /bulk-payments/{bulkPaymentId}`), specifying the bulk payment file `Id` in the path.

    <CodeGroup>
      ```bash Request theme={null}
      curl -L -X GET 'https://api.yapily.com/bulk-payments/{bulkPaymentId}' \
        -H 'Content-Type: application/json' \
        -H 'Consent: {consentToken}' \
        -u 'APPLICATION_KEY:APPLICATION_SECRET'
      ```

      ```json Response theme={null}
      {
        "meta": {
          "tracingId": "0cda48c70f3941148bbee775a65fa3d0"
        },
        "data": {
          "id": "pv3-a1e2ecb0-270c-42e2-8ba5-005261b629d2",
          "ConsentId": "sdp-6-b06f9a82-c641-4aba-b76d-43e6bc052f75",
          "statusDetails": {
            "status": "COMPLETED",
            "updatedAt": "2021-06-09T13:53:28.67Z"
          },
          "createdAt": "2021-06-09T13:53:28.67Z"
        }
      }
      ```
    </CodeGroup>
  </Step>
</Steps>
