# Codes and Formats
source: https://developer.mastercard.com/ob-accept-payments/documentation/developer-support/code-and-formats/index.md

## Error handling {#error-handling}

Successful API responses return HTTP `200` or `201` if the response is immediate or HTTP `202` if the request has been accepted for asynchronous processing.

In case of errors, the API returns a JSON response containing the error code and details about the failure:

The following HTTP statuses will indicate that an API request failed to process successfully.

| **HTTP Status** |  **Description**  |
|-----------------|-------------------|
| 400             | Bad Request       |
| 401             | Unauthorized      |
| 403             | Forbidden         |
| 404             | Not Found         |
| 429             | Too Many Requests |

```json
{
  "Errors": {
    "Error": [
      {
        "Source": "Accept Payments API",
        "ReasonCode": "INVALID_INPUT",
        "Description": "Validation error occurred for the property: RedirectUrl",
        "Recoverable": false,
        "Details": "The RedirectUrl field is required."
      }
    ]
  }
}
```

The `ReasonCode` field in the body of the error response will indicate the type of error.

|   **Reason Code**    |                                                                     **Description**                                                                      |                                                     **How to handle**                                                     |
|----------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------|
| `RESOURCE_NOT_FOUND` | This may occur on the GET endpoints such as Get Payment and Get Mandate. If the provided resource ID does not exist, it will respond with 404 Not Found. | Ensure the resource IDs you are using for the Get requests refer to valid entities previously created with a POST request |

##### Example error code {#example-error-code}

```json
{
 "Errors": {
   "Error": [
     {
       "Source": "Accept Payments API",
       "ReasonCode": "RESOURCE_NOT_FOUND",
       "Description": "Resource not found",
       "Recoverable": false,
       "Details": "The requested entity was not found."
     }
   ]
 }
}
```

| **Reason Code** |                                                                                                                                            **Description**                                                                                                                                            |                **How to handle**                |
|-----------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------|
| `INVALID_INPUT` | This applies primarily to POST endpoints such as the Create Payment and Create Mandate endpoints that have bodies. A 400 Bad Request response will be returned for the request. The body of the response will contain details about what properties are not valid or which business rule was not met. | Fix the issue with the request before retrying. |

##### Example error code {#example-error-code}

```json
{
 "Errors": {
   "Error": [
     {
       "Source": "Accept Payments API",
       "ReasonCode": "INVALID_INPUT",
       "Description": "Validation error occurred for the property: Amount",
       "Recoverable": false,
       "Details": "Amount must be positive".
     },
     {
       "Source": "Accept Payments API",
       "ReasonCode": "INVALID_INPUT",
       "Description": "Validation error occurred for the property: Currency",
       "Recoverable": false,
       "Details": "Currency must be GBP"
     }
   ]
 }
} 
```

| **Reason Code**  |          **Description**          |                         **How to handle**                          |
|------------------|-----------------------------------|--------------------------------------------------------------------|
| `INTERNAL_ERROR` | An error occurred in the *xxxxx*. | Retry the request. If the issue persists contact Customer Support. |

##### Example error code {#example-error-code}

```json
{
    "Errors": {
        "Error": [
            {
                "Source": "Accept Payments API",
                "ReasonCode": "INTERNAL_ERROR",
                "Description": "An unexpected error has occurred with the service you have requested.",
                "Recoverable": false,
                "Details": null
            }
        ]
    }
}
```

| **Reason Code** |                                                                                  **Description**                                                                                  |                                           **How to handle**                                            |
|-----------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------|
| `RATE_LIMITED`  | This occurs when you have exceeded your rate limit for the endpoint. A 429 Too Many Requests response will be returned. See Advanced Topics \> Rate Limiting in the API Reference | Check the X-RateLimit-Reset to see when the window is reset and you can start making requests again.\* |

##### \*Sample of the header received in this scenario {#sample-of-the-header-received-in-this-scenario}

    HTTP/1.1 429 Too Many Requests
    Date: Mon, 08 Jul 2019 09:27:06 GMT
    Status: 429 Too Many Requests
    X-RateLimit-Limit: 60
    X-RateLimit-Remaining: 0
    X-RateLimit-Reset: 16

##### Example error code {#example-error-code}

```json
{
    "Errors": {
        "Error": [
            {
                "Source": "Accept Payments API",
                "ReasonCode": "RATE_LIMITED",
                "Description": "Too many requests",
                "Recoverable": true,
                "Details": null
            }
        ]
    }
}
```

| **Reason Code** |                **Description**                 |                     **How to handle**                     |
|-----------------|------------------------------------------------|-----------------------------------------------------------|
| `UNAUTHORIZED`  | The provided authorization token is not valid. | Check that the access token you have provided is correct. |

##### Example error code {#example-error-code}

```json
{
    "Errors": {
        "Error": [
            {
                "Source": "Accept Payments API",
                "ReasonCode": "UNAUTHORIZED",
                "Description": "Unauthorized - Access Not Granted",
                "Recoverable": false,
                "Details": null
            }
        ]
    }
}
```

| **Reason Code** |             **Description**             |                     **How to handle**                      |
|-----------------|-----------------------------------------|------------------------------------------------------------|
| `FORBIDDEN`     | You do not have access to the resource. | Contact customer support if you believe this is incorrect. |

##### Example error code {#example-error-code}

```json
	 {
    "Errors": {
        "Error": [
            {
                "Source": "Accept Payments API",
                "ReasonCode": "FORBIDDEN",
                "Description": "Access to the requested resource is forbidden",
                "Recoverable": false,
                "Details": null
            }
        ]
    }
}
```

|       **Reason Code**       |                                                                                         **Description**                                                                                          |                                              **How to handle**                                              |
|-----------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------|
| `RESOURCE_IN_INVALID_STATE` | You have attempted to take an action on a resource when it is not in a correct state for that action. This may occur on payment, mandate or refund endpoints. It will respond with 409 Conflict. | In the example shown, You could retry this payment as a Single Immediate Payment if the user is in session. |

##### Example error code {#example-error-code}

```json
{
    "Errors": {
        "Error": [
            {
                "Source": "Accept Payments API",
                "ReasonCode": "RESOURCE_IN_INVALID_STATE",
                "Description": "Conflict with the current state of the target resource",
                "Recoverable": false,
                "Details": "Requested payment exceeds limits: PerPaymentLimitExceeded"
            }
        ]
    }
}
```

|    **Reason Code**     |                                                **Description**                                                 |                                 **How to handle**                                 |
|------------------------|----------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------|
| `PAYMENT_LINK_EXPIRED` | This payment link has expired. The value set in expiryDate has elapsed. The It will respond with 409 Conflict. | If you want to try this payment again you will need to create a new Payment Link. |

##### Example error code {#example-error-code}

```json
{
    "Errors": {
        "Error": [
            {
                "Source": "Accept Payments API",
                "ReasonCode": "PAYMENT_LINK_EXPIRED",
                "Description": "Payment link expired",
                "Recoverable": false,
                "Details": null
            }
        ]
    }
}
```

|       **Reason Code**       |                                       **Description**                                       |                                                  **How to handle**                                                  |
|-----------------------------|---------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------|
| `PAYMENT_LINK_ALREADY_PAID` | A payment has already been made using this Payment Link. It will respond with 409 Conflict. | No further action should be taken. If you need to take another payment, you will need to create a new Payment Link. |

##### Example error code {#example-error-code}

```json
{
    "Errors": {
        "Error": [
            {
                "Source": "Accept Payments API",
                "ReasonCode": "PAYMENT_LINK_ALREADY_PAID",
                "Description": "Payment link already paid",
                "Recoverable": false,
                "Details": null
            }
        ]
    }
}
```

|      **Reason Code**       |                                   **Description**                                    |                                    **How to handle**                                    |
|----------------------------|--------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------|
| `PAYMENT_LINK_IN_PROGRESS` | A payment is in progress using this Payment Link. It will respond with 409 Conflict. | Query the Get payment link endpoint until you get a final status (SUCCEEDED or EXPIRED) |

##### Example error code {#example-error-code}

```json
{
    "Errors": {
        "Error": [
            {
                "Source": "Accept Payments API",
                "ReasonCode": "PAYMENT_LINK_IN_PROGRESS",
                "Description": "Payment link in progress",
                "Recoverable": false,
                "Details": null
            }
        ]
    }
}
```

|           **Reason Code**            |                                   **Description**                                    |                              **How to handle**                              |
|--------------------------------------|--------------------------------------------------------------------------------------|-----------------------------------------------------------------------------|
| `PAYMENT_LINK_IN_PROGRESS_RETRYABLE` | A payment is in progress using this Payment Link. It will respond with 409 Conflict. | It may still be possible to make a payment attempt using this payment link. |

##### Example error code {#example-error-code}

```json
{
    "Errors": {
        "Error": [
            {
                "Source": "Accept Payments API",
                "ReasonCode": "PAYMENT_LINK_IN_PROGRESS_RETRYABLE",
                "Description": "Payment link in progress (retryable)",
                "Recoverable": true,
                "Details": null
            }
        ]
    }
}
```

|     **Reason Code**      |                                    **Description**                                    |                                              **How to handle**                                               |
|--------------------------|---------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------|
| `PROVIDER_NOT_SUPPORTED` | This may occur if the specified provider has not been onboarded for your TPP License. | To handle this error, you will need to contact your dedicated representative at Mastercard Open Finance Pay. |

##### Example error code {#example-error-code}

```json
{
     "Errors": {
        "Error": [
            {
                "Source": "Accept Payments API",
                "ReasonCode": "PROVIDER_NOT_SUPPORTED",
                "Description": "Validation error occurred for the property: providerId,",
                "Recoverable": false,
                "Details": "Your client setup doesn't support the requested provider. Please contact support."
             }
        ]
    }
}
```

|            **Reason Code**             |                                                     **Description**                                                     |                                                                          **How to handle**                                                                           |
|----------------------------------------|-------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `PRESELECTEDSOURCE_ACCOUNT_UNRESOLVED` | This error can occur when you send in a preselectedSource account and we are unable to resolve it to a single provider. | You can retry the payment. However, when you retry do not pass in a preselectedSource account. When you do this, the user will select a bank from the Bank Selector. |

##### Example error code {#example-error-code}

```json
{
   "Errors":{
      "Error":[
         {
            "Source":"Accept Payments API",
            "ReasonCode":"PRESELECTEDSOURCE_ACCOUNT_UNRESOLVED",
            "Description":"Validation error occurred for the property: preselectedSource",
            "Recoverable":false,
            "Details":"Unable to resolve the preselectedSource account to a provider."
         }
      ]
   }
}
```

## Failures in the Mandate Flow {#failures-in-the-mandate-flow}

A webhook notification is returned when a mandate status changes. Refer to the [Recurring Payments with Mandate](https://developer.mastercard.com/ob-accept-payments/documentation/use-cases/ecommerce-payments/#cvrp---commercial-variable-recurring-payments) use case for a Mandate Status Flow diagram and a description of possible statuses.

Some recommendations on how to handle Failure or Undefined states of the payment are shown below.

|       **Payment status**        |                                                                                **Handling recommendations**                                                                                 |
|---------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `CANCELLED`                     | The user cancelled the authorization flow. You may offer the user option to try again.                                                                                                      |
| `FAILED`                        | The payment failed. This can occur for a number of reasons including the bank rejecting the consent. For more information about the failure, refer to the details section of the response.​ |
| `EXPIRED`                       | The mandate is expired. You need to ask the PSU to create a new mandate.                                                                                                                    |
| `REVOKED`                       | The mandate has been revoked. You need to ask the PSU to create a new mandate.                                                                                                              |
| `AUTHORIZATION_FLOW_INCOMPLETE` | ​The mandate authorization URL expired, or the PSU left the mandate authorization page. ​The mandate authorization has not been completed. You may offer the PSU the option to try again.   |

## Failures in the Payment Flow {#failures-in-the-payment-flow}

A webhook notification is returned when a payment status changes. Refer to the [Single Immediate Payments](https://developer.mastercard.com/ob-accept-payments/documentation/use-cases/ecommerce-payments/#single-immediate-payments) use case for a Payment Status Flow diagram and a description of possible statuses.

Below you can find some recommendations on how to handle Failure or Undefined states of the payment.

|       **Payment status**        |                                                                                 **Handling recommendations**                                                                                 |
|---------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `CANCELLED`                     | The user cancelled the authorization flow. You may offer the user option to try again.                                                                                                       |
| `FAILED`                        | The payment failed. This can occur for a number of reasons including the bank rejecting the payment. For more information about the failure, refer to the details section of the response.​  |
| `UNKNOWN`                       | For confirmation of the payment execution, perform reconciliation against transactions in the destination account.                                                                           |
| `AUTHORIZATION_FLOW_INCOMPLETE` | The payment authorization URL expired, or the Payer left the payment authorization page. ​The payment authorization has not been completed. You may offer the payer the option to try again. |

#### Additional Information on Payment Failures: {#additional-information-on-payment-failures}

Beyond our standard payment statuses and API errors, we provide supplemental details to help you understand why a payment failed and what follow-up actions you may need to take.
These insights are included in the Get Payment response.

Within the status object, you will find a detail object that surfaces failure-specific information. This allows you to better diagnose issues and guide your users accordingly.

Here is an example excerpt from a Get payment response illustrating the structure and content you can expect:

```json
        "details": {
			"code": "InsufficientFunds",
			"reason": "Transaction failed due to insufficient funds.",
			"provider": {
				"code": null
			}
		}
```

Here is a list of these codes along with guidance on how to handle each one.
Note: Due to the breadth of Open Finance integrations and the number of markets and providers we support, this information may not be available for every payment failure. The list below is not exhaustive, and we will continue to expand it over time.

|               **Code**                |                                    **Reason**                                     |                                                                                                             **Handling recommendations**                                                                                                              |
|---------------------------------------|-----------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `AisLoginFailed`                      | AIS authorisation failed                                                          | Ask the user to retry and advise them to and advise them to ensure they complete all Strong Customer Authentication (SCA) steps.                                                                                                                      |
| `AisLoginFailedAfterThreeAttempts`    | AIS login failed after three attempts                                             | Notify the user that multiple failed login attempts have occurred. Ask the user to verify their credentials and try again later. If they continue to have issues they can contact their bank for more information.                                    |
| `PisLoginFailed`                      | PIS authorisation failed                                                          | Ask the user to retry and advise them to ensure they complete all Strong Customer Authentication (SCA) steps.                                                                                                                                         |
| `KycPaymentServiceUserStatusRejected` | This payment falls outside of our risk appetite                                   | There are no further actions the user can take. You can contact your Mastercard representative for more information if required. However, they may not be able to advise further based on the context of the failure.                                 |
| `InsufficientFunds`                   | Transaction failed due to insufficient funds                                      | Advise the user that their chosen account does not have enough funds to complete the payment. You could advise them to try again with another account or advise them to make sure they top up the account before retrying.                            |
| `DailyLimitExceeded`                  | Daily limit exceeded                                                              | Advise the user that their banks daily limit has been reached. You could advise the user to try the payment again tomorrow when the daily limit has reset. They can also contact their bank to get a better understanding of their daily limits.      |
| `ProviderDidNotReturnValidResponse`   | Provider did not return a valid response                                          | The provider did not return a valid response. The user can try again as it may be a temporary issue. If the issue persists, you can contact your Mastercard representative for more information.                                                      |
| `AccountGettingFailure`               | Failure getting accounts                                                          | We were unable to fetch the users account. The user can try again as it may be a temporary issue. If the issue persists, you can contact your Mastercard representative for more information.                                                         |
| `AccountNotFound`                     | Selected account was not found                                                    | We were unable to fetch the users account. The user can try again as it may be a temporary issue. If the issue persists, you can contact your Mastercard representative for more information.                                                         |
| `AuthorisationFailed`                 | The transaction authorisation failed                                              | This is a generic authorization failure. The user can retry the payment or try again using a different bank or account.                                                                                                                               |
| `AuthorizationFailed`                 | Invalid code in query or fragment                                                 | The user can retry the payment or try again using a different bank or account.                                                                                                                                                                        |
| `NoUsableScaMethods`                  | No available authentication methods for this transaction                          | Advise the user that their bank does not currently provide an authentication method that can be used for this type of transaction. They can try again but this time use a different bank.                                                             |
| `RejectedByBank`                      | Transaction rejected by bank                                                      | This is a generic payment rejection. The user can retry the payment or try again using a different bank or account. If the user feels they payment should not have been rejected, they can contact their bank to understand why it has been rejected. |
| `ProviderCouldNotAuthoriseRequest`    | Provider could not authorise the request                                          | This is a generic authorization failure. The user can retry the payment or try again using a different bank or account.                                                                                                                               |
| `PreparingLoginFailed`                | Preparing login failed                                                            | We have encountered an issue while preparing the login. If the issue persists, you can contact your Mastercard representative for more information.                                                                                                   |
| `BankServiceUnavailable`              | Bank service is unavailable                                                       | These are usually related to downtime or maintenance at the Bank side. The user can retry the payment later or they can try again using a different bank.                                                                                             |
| `InvalidBankId`                       | Bank/ID is invalid                                                                | An invalid Bank Id was used. If you are passing in a providerId, verify that it is correct. If you continue to see this error, you can contact your Mastercard representative for more information.                                                   |
| `ClientConfigurationMissing`          | Client configuration missing from source                                          | Technical configuration issue, it is best to contact your Mastercard representative for more information.                                                                                                                                             |
| `PaymentNotCreatedAtProvider`         | Payment not created at provider                                                   | This is a generic payment rejection. The user can retry the payment or try again using a different bank or account.                                                                                                                                   |
| `InvalidPsuCredentialsBlocked`        | Customer needs to login to Open Finance first before proceeding with this service | When we receive these from the bank, it usually means that there is a block on the users account. When you see this, you can advise the user to contact their bank to get the block removed. After this, the user can retry the payment.              |

## Failures in the Refund Flow {#failures-in-the-refund-flow}

A webhook notification is returned when a refund status changes. Refer to the [Refunds](https://developer.mastercard.com/ob-accept-payments/documentation/use-cases/refunds/index.md) use case for Refund Flow diagrams and descriptions of possible statuses.

Below you can find some recommendations on how to handle Failure or Undefined states of the refund.

|     **Payment status**      |                                                                                                             **Handling recommendations**                                                                                                              |
|-----------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `PAYMENT_RAILS_UNAVAILABLE` | The refund cannot be executed and the source account cannot be obtained. The `/refunds/{refund_id}/payment-rails` endpoint can be used to enable the PSU to connect one of their accounts to obtain the account details needed to perform the refund. |
| `FAILED`                    | The refund failed. This can occur for a number of reasons. For more info about the failure refer to the details section of the response.​​                                                                                                            |

