Payment Initiation Service Specification

Note: For the use of Developer Assets, these Terms and Conditions apply. Please also read the Requirements Notation and Conventions.

The Credit Transfer (Überweisung) enables Relying Parties to help their end-users to initiate a SEPA credit transfer.

The Credit Transfer product is distinct from regulated payment initiation services where a party initiates a payment on behalf of the user. On a technical level, it is nonetheless described as a Payment Initiation Service, hence called PIS in this specification.

This specification is based on the Payment Inititation Service (PIS) specification of Berlin Group’s NextGenPSD2 XS2A Framework, adapted to the specifics of the ecosystem.

This specification deviates from NextGenPSD2 in these important points:

  • The service follows the Basic Service Protocol defined in the IDP Specification.

  • Payment authorization details are conveyed using the authorization_details parameter as defined in RAR. No dedicated payment resource is required to start the authorization process.

  • The debtor account of a particular payment is determined in the course of the authorization process, either automatically by the AS or by user-selection.

  • The relying party can optionally request that the debtor account must have a specific IBAN.

  • Optionally, the account holder’s identity can be matched against the authenticated user or a name provided by the relying party.

1. Architecture

The Relying Party is a website or app wanting to let its customers pay for services or goods or use a credit transfer in the context of an identification process. It utilizes the account chooser of the platform to find the AS of the bank the particular customer wants to use.

Within the authorization process at the bank’s authorization server, the PIS then gives the end-user the option to initiate a SEPA credit transfer. The respective data (creditor, reference, etc.) for this credit transfer is provided by the Relying Party and the bank (e.g., a selection of available debtor accounts). The Relying Party receives the information that the transfer has been initiated by the end-user and, optionally, the status of the credit transfer.

The platform manages the trust relationships among all participants. It provides all ASs with data needed to recognize and to authenticate Relying Parties.

The AS uses the platform to report back any service delivery in order to facilitate billing of the service usage.

2. Message Flow

The following sequence diagram shows the message flow in the course of a payment initiation.

pis_flow
Figure 1. PIS Flow Overview.
Details of the authentication and payment process can vary depending on the interface between the AS and PIS and other implementation constraints.

3. Service Parameters

The Basic Service Protocol parameters as defined in the IDP Specification.

Authorization Details Type

payment_initiation

Resource Endpoints

The status endpoint for a payment can be obtained from the authorization details returned from the token endpoint.

Combinations

This service can be combined all other services.

Example 1. Service Configuration for PIS
{
   "payment_initiation":{ }
}

4. Authorization Process

4.1. Payment Authorization Details

The RP uses a JSON structure to describe the details of the payment it wants to perform. This JSON structure contains the following elements:

  • type REQUIRED string. MUST be set to payment_initiation.

  • paymentProduct REQUIRED string. MUST be set to sepa-credit-transfers.

  • instructedAmount REQUIRED JSON Object. JSON Structure containing amount and currency to be transfered:

    • currency REQUIRED string. ISO 4217 Alpha 3 currency code. Currently, only EUR is supported.

    • amount REQUIRED string. The amount given with fractional digits, where fractions must be compliant to the currency definition. Up to 14 significant figures. Negative or zero amounts are not allowed. The decimal separator is a dot. Example: Valid representations for EUR with up to two decimals are: 1056, 5768.2, 1.50, 5877.78. The following regular expression matches allowed, and only allowed, strings: ^(?![0.]+$)[0-9]{1,14}(?:\.[0-9]{1,2})?$

  • remittanceInformationUnstructured OPTIONAL string, max. 140 characters. Additional information included in the transfer to allow the creditor to link the transfer to a certain transaction. If left empty, the remittance information will be empty.

  • creditorName REQUIRED string, max. 70 characters. The name of the creditor.

  • creditorAccount REQUIRED JSON object. Only one key:

    • iban REQUIRED string. Contains the creditor account IBAN.

  • debtorAccount OPTIONAL JSON Object.

    • MAY contain an account holder name constraint, expressed by either of the following two mutually exclusive options (see below for more background):

      • The keys holderFamilyName (string) and holderGivenName (string). The AS ensures that the name of an account holder of the debtor account matches the provided given name and family name. MUST NOT be used when PIS is used together with IDS or QES in the same flow. Both keys MUST be used together and contain a non-empty string, or omitted.

      • The key holderSameName with the value true. MAY only be used when PIS is used together with either IDS or QES. Same check as above, but the first name and given name are taken from the IDS or QES flow performed at the same time. MUST NOT be used in conjunction with an IDS flow unless the given_name and family_name are requested as verified claims within the IDS flow.

    • MAY (additionally or instead) contain the key iban. In this case, the AS ensures that the IBAN of the debtor account matches the provided IBAN.

Parameters provided by the RP cannot be modified by the user later in the process.

This specification contains keys in snake_case notation, as usual in the ecosystem, and keys in camelCase notation which are aligned with NextGenPSD2 specifications.
Some characters within remittanceInformationUnstructured or creditorName might not be supported by the AS or payment product and MAY be removed at the discretion of the AS or payment backend.
The matching via holderFamilyName/holderGivenName cannot be used together with an IDS/QES flow, as this might introduce a new requirement for the IDS/QES flow, namely matching a certain name. This is currently not part of the IDS and QES specifications. Conversely, holderSameName requires a name to match against, so this information must come from a flow where it is already transferred to the RP - hence the dependency on a QES flow or a verified given_name and family_name from an IDS flow.
Example 2. Payment Authorization Details
{
  "type": "payment_initiation",
  "paymentProduct": "sepa-credit-transfers",
  "instructedAmount": {
    "currency": "EUR",
    "amount": "123.50"
  },
  "creditorName": "Merchant123",
  "creditorAccount": {
    "iban": "DE02100100109307118603"
  },
  "remittanceInformationUnstructured": "Ref Number Merchant",
  "debtorAccount": {
    "holderSameName": true,
    "iban": "DE30711860302100100109"
  }
}

The AS advertises its support for the Credit Transfer by including the following values into the authorization_data_types_supported claim of its OAuth configuration (.well-known/oauth-authorization-server):

  • payment_initiation

Example 3. OAuth Configuration
{
   ...
   "authorization_data_types_supported":[
      ...
      "payment_initiation"
   ],
   ...
}

Every RP wanting to ues the Credit Transfer must be authorized to request those authorization details type value in its RP configuration with the platform.

4.2. Preparation (Pushed Authorization Request)

The RP first sends the authorization request parameters to the AS in a HTTP POST request according to PAR and RAR.

This service can only be used when Pushed Authorization Requests are used. An AS MUST reject non-PAR requests with this authorization details with the error code invalid_authorization_details.
Example 4. Pushed Authorization Request
POST /as/par HTTP/1.1
Host: as.example.com
Content-Type: application/x-www-form-urlencoded
Authorization: Basic czZCaGRSa3F0Mzo3RmpmcDBaQnIxS3REUmJuZlZkbUl3

response_type=code&
client_id=s6BhdRkqt3
&state=af0ifjsldkj
&redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb
&code_challenge_method=S256
&code_challenge=K2-ltc83acc4h0c9w6ESC_rEMTJ3bww-uCHaoeK1t8U
&authorization_details=%5B%7B%22type%22%3A%22payment%5Finitiation%
22%2C%22payment%2Dproduct%22%3A%22sepa%2Dcredit%2Dtransfers%22%2C%22
instructedAmount%22%3A%7B%22currency%22%3A%22EUR%22%2C%22amount%22%3
A%22123%2E50%22%7D%2C%22creditorName%22%3A%22Merchant123%22%2C%22cre
ditorAccount%22%3A%7B%22iban%22%3A%22DE02100100109307118603%22%7D%2C
%22remittanceInformationUnstructured%22%3A%22Ref%20Number%20Merchant
%22%7D%5D

This request contains the payment authorization details in the authorization_details parameter.

The authorization_details MUST NOT contain multiple objects of type payment_initiation, otherwise the AS MUST respond with a status code 400 and the error value invalid_authorization_details.
When using debtorAccount/iban restriction, the RP SHOULD ensure that the provided IBAN belongs to the bank(s) the AS represents. Otherwise, the request will be rejected.

The client authenticates the request using mTLS.

The AS validates the authorization request, including the following checks:

  • The AS MUST check whether the provided authorization_details object contains the keys listed above with valid values and that the constraints expressed in debtorAccount are compatible with the requested flows. If this check fails, the AS terminates processing and sends an error response to the RP with the error code invalid_authorization_details.

  • The AS SHOULD check whether the account referred to in debtorAccount/iban is an account of the bank represented by the AS. If not, the AS terminates processing and sends an error response to the RP with the error code unable_to_enforce_debtor_account.

  • The AS MUST check whether the RP is allowed to use the type value payment_initiation by checking the allowed_authorization_data_types field of the respective RP record obtained from the platform. If this check fails, the AS terminates processing and sends an error response to the RP with the error code access_denied.

If all checks succeed, the AS returns a request URI in case of success as shown in the following example.

Example 5. Pushed Authorization Response
HTTP/1.1 201 Created
Cache-Control: no-cache, no-store
Content-Type: application/json

{
  "request_uri": "urn:example:bwc4JK-ESC0w8acc191e-Y1LTC2",
  "expires_in": 90
}

4.3. Authentication and Authorization (OAuth Frontend Part)

The client uses the request URI to start the authorization process with the AS by sending an authorization request through the user agent.

Example 6. Authorization Request
GET /authorize?request_uri=
    urn%3Aexample%3Abwc4JK-ESC0w8acc191e-Y1LTC2&client_id=s6BhdRkqt3 HTTP/1.1

The AS ensures that a credit transfer can only be executed by authenticated users that have given their consent to the transaction. The user’s strong customer authentication (SCA) factor is used as required.

Details of the authentication and payment process can vary depending on the interface between the AS and PIS and other implementation constraints.

The AS responds to the RP with an OAuth authorization response.

If the AS is unable to fulfill the request by the RP for a specific account IBAN or holder name (expressed through debtorAccount), the AS MUST return an error code unable_to_enforce_debtor_account, to the RP and MUST NOT allow the end-user to initiate the payment.

If the AS can determine already in the authorization process that the payment cannot be initiated (e.g., when the daily transfer limit would be exceeded), the AS SHOULD return the error code unable_to_initiate_payment to the RP. The error code access_denied SHOULD be used when the user has no valid account or cannot provide a second factor.

4.4. Authentication and Authorization (OAuth Backend Part)

The RP will redeem the authorization code provided in the authorization response for an access token.

The access token lifetime should be chosen sufficiently long, such that for typical payments, the RP can track all relevant payment status changes through the payment status URL described below.

The AS enriches the authorization_details element in the token response with the object payment_information. This object contains the following keys:

  • status_href (OPTIONAL): provides the RP with the URL at which it can retrieve information about the payment status. The URL MUST be an https URL, relative URLs are not allowed. The URL does not need to be on the same host as the AS. A missing key indicates that the bank does not provide payment status information.

  • txn: a unique identifier for the transaction.

The AS MAY use the same identifier or different identifiers for the payment in the URL for status_href and txn.
Example 7. Token Response
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-cache, no-store

{
  "access_token": "2YotnFZFEjr...1zCsicMWpAA",
  "token_type": "example",
  "expires_in": 3600,
  "authorization_details": [
    {
      "type": "payment_initiation",
      "paymentProduct": "sepa-credit-transfers",
      "instructedAmount": {
        "currency": "EUR",
        "amount": "123.50"
      },
      "creditorName": "Merchant123",
      "creditorAccount": {
        "iban": "DE02100100109307118603"
      },
      "remittanceInformationUnstructured": "Ref Number Merchant",
      "debtorAccount": {
        "holderSameName": true,
        "iban": "DE30711860302100100109"
      },
      "payment_information": {
        "status_href": "https://pis.example.com/payments/36fc67776/status",
        "txn": "9fe0d04d-7094-4f28-8c1b-6776d13814a4"
      }
    }
  ],
}

5. Resource Access: Query Payment Status

If the bank provides payment status information, the client can query the status of the payment by sending a GET request to the URL provided in the status_href element. The request needs to be authenticated using normal OAuth resource access with mTLS, i.e., by sending the OAuth access token in the Authorization header and using the client’s TLS certificate.

Example 8. Payment Status Request
GET /payments/36fc67776/status
Host: pis.example.com
Accept: application/json
Authorization: Bearer 2YotnFZFEjr1zCsicMWpAA
Example 9. Payment Status Response
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8

{
   "transactionStatus":"ACSC"
}

The payment status endpoint responds with the following parameters:

Response Parameter Type Description

transactionStatus

String

transaction status according to ISO 20022, see table below

The following table lists the possible transaction status values. The contents of this table have been obtained from the NextGenPSD2 XS2A specification.

Code Name ISO 20022 Definition

ACCP

AcceptedCustomerProfile

Preceding check of technical validation was successful. Customer profile check was also successful.

ACSC

AcceptedSettlementCompleted

Settlement on the debtor’s account has been completed.

Usage: this can be used by the first agent to report to the debtor that the transaction has been completed.

ACSP

AcceptedSettlementInProcess

All preceding checks such as technical validation and customer profile were successful and therefore the payment initiation has been accepted for execution.

ACTC

AcceptedTechnicalValidation

Authentication and syntactical and semantical validation are successful

ACWC

AcceptedWithChange

Instruction is accepted but a change will be made, such as date or remittance not sent.

ACWP

AcceptedWithoutPosting

Payment instruction included in the credit transfer is accepted without being posted to the creditor customer’s account.

RCVD

Received

Payment initiation has been received by the receiving agent.

PDNG

Pending

Payment initiation or individual transaction included in the payment initiation is pending. Further checks and status update will be performed.

RJCT

Rejected

Payment initiation or individual transaction included in the payment initiation has been rejected.

For detailed information about the states and state changes in a payment process see NextGenPSD2 XS2A Framework, section 4.9.

6. Billing Mediation

The AS MUST report any successful payment initiation to the Mediation Service.

The mediation record SHOULD be posted to the mediation service after the payment was initiated.

The mediation record MUST contain the following data:

  • type: MUST be payment_initiation

  • issuer: set to the Issuer URL of the IDP

  • client_id: set to the client_id of the RP

  • paymentProduct: set to the value sepa-credit-transfers

  • currency: set to the value of currency in the request

  • amount: set to the value of amount in the request

  • debtorAccount: an array containing up to two strings depending on the checks requested by the RP using debtorAccount in the request:

    • the string holderName if any of the keys holderSameName, holderFamilyName, or holderGivenName were used.

    • the string iban if the key iban was used.

  • transaction_id: set to the transaction identifier at the AS, same value as the txn claim returned in the token response

  • delivery_time: the time when the data was delivered to the RP

  • owner_id: the respective owner_id (see Platform API Documentation for details)

  • reference_id: OPTIONAL. String (1 to 100 characters restricted to a-z, A-Z, 0-9 and dashes ("-"), e.g., a uuid) generated by the AS as unique mediation record id to prevent multiple mediation records for the same event. Uniqueness is considered per AS (issuer element). If the field is provided in the mediation record, the mediation service checks whether a mediation record with the same reference_id for the the same issuer already exists and will refuse processing in that case.

7. Changes

  • Version 1.7

    • Payment status endpoint is now optional

  • Version 1.6

    • Aligned with the Credit Transfer product

    • Clarify that IBAN provided in debtorAccount/iban should belong to the bank the AS represents

    • Add that holderFamilyName and holderGivenName must be both empty or set

    • Added explanation where the requirements on the restrictions come from

    • Add regular expression for amount

    • Provided guidance on the length of remittanceInformationUnstructured and creditorName and added a warning that some characters might not be supported.

    • In the PAR request, the AS SHOULD check whether the account referred to in debtorAccount/iban is an account of the bank represented by the AS

  • Version 1.5

    • Adopted PIS to rich/pushed authorization requests mechanics

    • Introduced account holder name check

    • Introduced account holder IBAN check

    • Removed creditor account check against platform-registered accounts

  • Version 1.4 (2019-09-27)

    • Added clarification on error response for /initiate endpoint

  • Version 1.3 (2019-09-17)

    • Added billing mediation

  • Version 1.2 (2019-08-28)

    • changed "execution" to "initiation"

    • Added sequence and architecture charts

    • Allow for non-instant transfer of funds.