Handle the payment response [Payments V2]

Learn how to handle the response to the payment initiation request to let the user authorise their payment.

You need to handle the response to let the user authorise the payment. You can either:

Redirect flow

To authorise a payment using the redirect auth flow, you have to redirect your user to their bank's app or website.

Redirect the user to the bank URI specified in the API response value auth_flow.uri.
* To initiate the payment from a mobile app, you can run the bank's website as a webview. Don't embed the bank’s website as a frame within a larger frameset as most banks will block your user from continuing.

If the provider uses a redirect authorisation flow, the auth_flow object on the response will have the following fields:

FieldTypeDescription
typestringValue indicating this is a redirect authorisation flow: redirect
uristringThe URI for the end user to authorise the payment in the bank's UI.
expiry
(optional)
stringAn expiry time, if one is known, after which the URI to authorise the payment will become invalid. In UTC, formatted as an ISO 8601 string (YYYY-MM-DDThh:mm:ss.sssZ).
{
  "type": "redirect",
  "uri": "https://example.com",
  "expiry": "2020-11-03T23:00:00.000Z"
}

Embedded flow

To authorise a payment using the embedded auth flow, you have to collect the payment details from the user in your application and then pass those details on to TrueLayer.

  1. Display the inputs specified in the API response to the user.
  2. Submit the values they enter to our submission API.
  3. Repeat if the submission response specifies more inputs.

If the provider uses an embedded authorisation flow, the auth_flow object on the response will have the following fields:

FieldTypeDescription
typestringValue indicating this is a embedded authorisation flow: embedded
stepEmbeddedAuthStepAn object describing the next step in the authorisation flow.

EmbeddedAuthStep

The step object can have a different structure depending on the type field.

If the type is additional_inputs, then more inputs need to be collected from the end user in order to authorise the payment, and the step object will have the following fields:

FieldTypeDescription
typestringValue indicating further inputs required: additional_inputs
step_idstringThe step id, needed to submit additional inputs.
additional_inputsAdditionalInputsThe additional required inputs in the structure defined in the AdditionalInputs section in the providers endpoint description above.

You should use the additional_inputs description to build a UI to collect the inputs from your user, and submit them to our Embedded Auth Step Submission API, detailed below, in order to authorise the payment.

If the type is completed, then there is no more input required from the end user, and the step object will have the following fields:

FieldTypeDescription
typestringValue indicating no more steps: completed
outcomestringThe result of the authorisation.
Values: psu_cancelled, provider_rejected, authorised

In the completed case, no further inputs are required from the user, and you should begin polling for status changes, or wait for updates from webhooks.

{
  "type": "embedded",
  "step": {
    "type": "additional_inputs",
    "step_id": "STEP_1",
    "additional_inputs": {
      "some-additional-input": {
        "type": "select",
        "display_text": "Choose an option",
        "mandatory": true,
        "options": [
          {
            "id": "option-a",
            "display_text": "First Option"
          },
          {
            "id": "option-b",
            "display_text": "Second Option"
          }
        ]
      }
    }
  }
}

Submit embedded authorisation steps

📘

This feature is in private beta and is currently available to a limited number of clients. To join our private beta, contact Client Care.

After presenting the additional inputs to the end user in your UI, you need to submit what they enter to the embedded_auth_steps/<step_id>/submission API, as an additional_inputs dictionary, using the same structure as the payment initiation request.

Use this request to submit the embedded auth request:

curl -X PUT \
     -H "Authorization: Bearer ${access_token}" \
     --data '{
  "type": "additional_inputs",
  "additional_inputs": {
    "some-additional-input": "option-a"
  }
}' \
https://pay-api.truelayer.com/v2/single-immediate-payments/44708581-1967-4120-8f6a-1e532f1bf52a/embedded-auth-steps/STEP_1/submission

Use this request to cancel the embedded auth request:

curl -X PUT \
     -H "Authorization: Bearer ${access_token}" \
     --data '{
  "type": "cancel"
}' \
https://pay-api.truelayer.com/v2/single-immediate-payments/44708581-1967-4120-8f6a-1e532f1bf52a/embedded-auth-steps/STEP_1/submission

The response returns the same step structure as the payment initiation response auth_flow.step object, with either additional_inputs or completed step types.

{
  "result": {
    "step": {
      "type": "additional_inputs",
      "step_id": "STEP_2",
      "additional_inputs": {
        "otp": {
          "type": "text",
          "mandatory": true,
          "sensitive": true,
          "min_length": 6,
          "max_length": 6,
          "regex": "^\\d{6}$",
          "format": "numerical"
        }
      }
    }
  }
}

You should keep submitting the end user's additional inputs, whilst more are returned, until you receive a completed step type.

{
  "result": {
    "step": {
      "type": "completed",
      "outcome": "authorised"
    }
  }
}

Handle errors

Our API may return 4xx/5xx status codes to indicate an error handling the request. We may return the following status codes:

Http StatusDescription
400The request is not valid and will not succeed without modification. The error_details property in the response should assist in diagnosing the reason(s) for the failure.
403Your client id is not allowed to access the resource. The most likely reason for this is because your client id is not enlisted in the private beta for these endpoints. Please contact customer support if you are interested in participating in the private beta.
404The requested resource is not found or not accessible to your client id.
500An issue occurred inside TrueLayer in handling the request. The request may succeed on retry. Please contact customer support if the issue persists.
502The provider associated with the request was unavailable at the time of the request. The request may succeed on retry. Please contact customer support if the issue persists.
{
  "error": "parameter_error",
  "error_description": "Invalid parameters",
  "error_details": {
    "parameters": {
      "single_immediate_payment.single_immediate_payment_id": [
        "Value is required"
      ],
      "single_immediate_payment.beneficiary.account.type": [
        "Unknown value. Valid values are 'sort_code_account_number', 'iban', 'bban', 'nrb'"
      ]
    }
  }
}
{
  "error_description": "An error occurred. Please contact customer support."
}
{
  "error_description": "An error occurred while trying to contact the provider. Please try again later or contact customer support."
}

{
  "error": "parameter_error",
  "error_description": "Invalid parameters",
  "error_details": {
    "parameters": {
      "single_immediate_payment.single_immediate_payment_id": [
        "Value is required"
      ],
      "single_immediate_payment.beneficiary.account.type": [
        "Unknown value. Valid values are 'sort_code_account_number', 'iban', 'bban', 'nrb'"
      ]
    }
  }
}
{
  "error_description": "An error occurred. Please contact customer support."
}
{
  "error_description": "An error occurred while trying to contact the provider. Please try again later or contact customer support."
}