From aca160f65c4efd6b8cf64f618c1b4291fe75f61d Mon Sep 17 00:00:00 2001 From: "b.boterman@htm.nl" Date: Wed, 17 Jun 2026 16:08:06 +0200 Subject: [PATCH 1/9] OVPAY-2485 - Added SE endpoint for AGO activation. --- src/openapi/customers/SE-customers-v2.yaml | 211 ++++++++++++++++++++- 1 file changed, 209 insertions(+), 2 deletions(-) diff --git a/src/openapi/customers/SE-customers-v2.yaml b/src/openapi/customers/SE-customers-v2.yaml index 0ea36a6..5036601 100644 --- a/src/openapi/customers/SE-customers-v2.yaml +++ b/src/openapi/customers/SE-customers-v2.yaml @@ -3636,7 +3636,6 @@ paths: "vouchers": [] } } - /customers/devices: post: summary: Add a new device to a customer profile. @@ -3717,6 +3716,135 @@ paths: responses: "200": description: OK + /customers/tokens/{ovPayTokenId}/activateAgo: + parameters: + - name: ovPayTokenId + in: path + required: true + style: simple + description: Id of the OvPayToken to get product-instances for. + schema: + type: integer + example: 1 + - name: X-HTM-JWT-AUTH-HEADER + in: header + schema: + type: string + example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c + required: false + description: The JWT of a customer in case of touchpoint were customer logs in themselves + - name: X-HTM-CUSTOMER-PROFILE-ID-HEADER + in: header + schema: + type: integer + example: 323 + required: false + description: The id of the customer Profile + - name: X-HTM-ROLE-HEADER + in: header + schema: + type: string + example: Customer + required: false + description: The role of the HTM employee in the case of the SMP + post: + tags: + - AGO + summary: Request additional OV-pas security for a token in profile. + description: Request additional OV-pas security for a token in profile. + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/unavailable" + examples: + For self: + value: + emailAddress: null + For other: + value: + emailAddress: stasjo@htm.nl + responses: + "200": + description: OK + content: + application/json: + schema: + oneOf: + - $ref: "#/components/schemas/EmailPreApprovedResponse" + - $ref: "#/components/schemas/EmailNotPreApprovedResponse" + examples: + Email preapproved: + value: + status: Success + description: TAT Secured + Email not preapproved: + value: + uid: 7594f3ee-cd3d-40a3-8e82-73b90d16c481 + recipient: xxxxxx.user@gmail.com + key: 123456789123456789123456789abcde + description: OTP Sent + "400": + description: OK + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + examples: + Missing Parameters: + value: + status: 400 + title: Missing Mandatory Parameter + detail: Required parameter {0} is missing. + Invalid Parameters: + value: + status: 400 + title: Invalid Parameter + detail: Required parameter {0} is invalid. + "401": + description: OK + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + examples: + Unauthorized: + value: + status: 401 + title: Unauthorized + detail: Invalid Access Token + "404": + description: OK + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + examples: + TAT not found: + value: + status: 404 + title: Not Found + detail: TAT Account Not Found + "409": + description: 409 Conflict + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + examples: + TAT Already Secured: + value: + status: 409 + title: Conflict + detail: TAT Already Secured + "500": + description: OK + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + example: + error: An unknown error has occurred components: schemas: unavailable: @@ -4603,4 +4731,83 @@ components: customerDataItem: type: string example: emailAddress - \ No newline at end of file + GenerateTatOutput: + type: object + properties: + uid: + type: string + description: >- + An uid IS A unique identifier THAT is associated with the + user. + recipient: + type: string + description: >- + A recipient IS A unique identifier THAT is associated with the + TAT owner. + key: + type: string + description: >- + A key IS a 32 character string THAT uniquely identifies the + OTP session. + EmailPreApprovedResponse: + type: object + description: >- + AN EmailPreApprovedResponse IS AN object THAT represents the response of + email pre-approval check. + properties: + status: + type: string + description: >- + A status IS A boolean THAT indicates that the provided email address + is pre-approved by the calling client app/web. + example: Success + description: + type: string + description: >- + A description IS A string THAT provides additional information + relating to the aprroval result + example: TAT Secured + EmailNotPreApprovedResponse: + type: object + description: >- + EmailNotPreApprovedResponse IS AN object THAT represents the response of + email pre-approval check. + properties: + uid: + type: string + description: A uid IS A unique identifier THAT is associated with the user. + example: 7594f3ee-cd3d-40a3-8e82-73b90d16c481 + recipient: + type: string + description: >- + A recipient IS A unique identifier THAT is associated with the TAT + owner. + example: xxxxxx.user@gmail.com + key: + type: string + description: >- + A key IS a 32 character string THAT uniquely identifies the OTP + session. + example: 123456789123456789123456789abcde + description: + type: string + description: >- + A description IS A string THAT describes the reason why the email is + not pre-approved. + example: OTP Sent + ErrorResponse: + description: Default response when an invalid request has been sent + type: object + properties: + status: + type: integer + description: >- + A status IS An integer that represents the HTTP status code of the + response. + example: 400 + title: + type: string + description: A title IS A string that provides a brief summary of the error. + detail: + type: string + description: A detail IS A string that provides more details about the error. \ No newline at end of file From eb03aa04e69e5bb70c7d3e19f7023bdf69435323 Mon Sep 17 00:00:00 2001 From: "b.boterman@htm.nl" Date: Wed, 17 Jun 2026 16:22:38 +0200 Subject: [PATCH 2/9] OVPAY-2485 - Added SE endpoint for AGO OTP verification. --- src/openapi/customers/SE-customers-v2.yaml | 147 ++++++++++++++++++++- 1 file changed, 141 insertions(+), 6 deletions(-) diff --git a/src/openapi/customers/SE-customers-v2.yaml b/src/openapi/customers/SE-customers-v2.yaml index 5036601..951e68e 100644 --- a/src/openapi/customers/SE-customers-v2.yaml +++ b/src/openapi/customers/SE-customers-v2.yaml @@ -3716,13 +3716,13 @@ paths: responses: "200": description: OK - /customers/tokens/{ovPayTokenId}/activateAgo: + /customers/tokens/{ovPayTokenId}/activateago: parameters: - name: ovPayTokenId in: path required: true style: simple - description: Id of the OvPayToken to get product-instances for. + description: Id of the OvPayToken to activate AGO for. schema: type: integer example: 1 @@ -3785,7 +3785,7 @@ paths: key: 123456789123456789123456789abcde description: OTP Sent "400": - description: OK + description: Bad Request content: application/json: schema: @@ -3802,7 +3802,7 @@ paths: title: Invalid Parameter detail: Required parameter {0} is invalid. "401": - description: OK + description: Unauthorized content: application/json: schema: @@ -3814,7 +3814,7 @@ paths: title: Unauthorized detail: Invalid Access Token "404": - description: OK + description: Not found content: application/json: schema: @@ -3826,7 +3826,7 @@ paths: title: Not Found detail: TAT Account Not Found "409": - description: 409 Conflict + description: Conflict content: application/json: schema: @@ -3838,7 +3838,105 @@ paths: title: Conflict detail: TAT Already Secured "500": + description: Internal server error + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + example: + error: An unknown error has occurred + /customers/tokens/{ovPayTokenId}/validateotp: + parameters: + - name: ovPayTokenId + in: path + required: true + style: simple + description: Id of the OvPayToken to verify OTP for. + schema: + type: integer + example: 1 + - name: X-HTM-JWT-AUTH-HEADER + in: header + schema: + type: string + example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c + required: false + description: The JWT of a customer in case of touchpoint were customer logs in themselves + - name: X-HTM-CUSTOMER-PROFILE-ID-HEADER + in: header + schema: + type: integer + example: 323 + required: false + description: The id of the customer Profile + - name: X-HTM-ROLE-HEADER + in: header + schema: + type: string + example: Customer + required: false + description: The role of the HTM employee in the case of the SMP + post: + tags: + - AGO + summary: Request additional OV-pas security for a token in profile. + description: Request additional OV-pas security for a token in profile. + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/unavailable" + example: + otp: 123456 + responses: + "200": description: OK + content: + application/json: + schema: + type: object + oneOf: + - $ref: '#/components/schemas/AuthCodeResponse' + - $ref: '#/components/schemas/ValidateTatOutputDescription' + - $ref: '#/components/schemas/TatUnsecured' + examples: + AuthCodeResponse: + value: + ValidateTatOutputDescription: + value: + TatUnsecured: + value: + "400": + description: Bad request + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + examples: + Missing Parameters: + value: + status: 400 + title: Missing Mandatory Parameter + detail: Required parameter {0} is missing. + Invalid Parameters: + value: + status: 400 + title: Invalid Parameter + detail: Required parameter {0} is invalid. + "401": + description: Unauthorized + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + examples: + Unauthorized: + value: + status: 401 + title: Unauthorized + detail: Invalid Access Token + "500": + description: Internal server error content: application/json: schema: @@ -4795,6 +4893,43 @@ components: A description IS A string THAT describes the reason why the email is not pre-approved. example: OTP Sent + AuthCodeResponse: + type: object + properties: + authCode: + type: string + description: >- + An AuthCodeResponse IS A string that represents the authorization + code that can be exchanged for a user access token. + example: 4f3a9c8b-xxxx + ValidateTatOutputDescription: + type: string + properties: + authCode: + type: string + description: >- + An AuthCodeResponse IS A string that represents the authorization + code that can be exchanged for a user access token. + example: 4f3a9c8b-xxxx + status: + type: string + example: Success + description: + type: string + description: >- + A ValidateTatOutputDescription IS A string that provides more + details about the OTP validation result. + example: TAT Secured + TatUnsecured: + type: object + description: A TatUnsecured IS AN object THAT represents the response of TAT security + properties: + status: + type: string + example: Success + description: + type: string + example: TAT Unsecured ErrorResponse: description: Default response when an invalid request has been sent type: object From d18afcae8c3e477381dd58c1da26335496aeac5b Mon Sep 17 00:00:00 2001 From: "b.boterman@htm.nl" Date: Wed, 17 Jun 2026 16:23:11 +0200 Subject: [PATCH 3/9] OVPAY-2485 - Minor additions. --- src/openapi/customers/SE-customers-v2.yaml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/openapi/customers/SE-customers-v2.yaml b/src/openapi/customers/SE-customers-v2.yaml index 951e68e..e09b067 100644 --- a/src/openapi/customers/SE-customers-v2.yaml +++ b/src/openapi/customers/SE-customers-v2.yaml @@ -3902,10 +3902,19 @@ paths: examples: AuthCodeResponse: value: + authCode: 4f3a9c8b-xxxx ValidateTatOutputDescription: value: + 0: s + 1: t + 2: r + 3: i + 4: n + 5: g TatUnsecured: value: + status: Success + description: TAT Unsecured "400": description: Bad request content: From 30e8860a391f03bf817afe9edfa9b7e04949516f Mon Sep 17 00:00:00 2001 From: "b.boterman@htm.nl" Date: Wed, 17 Jun 2026 16:26:39 +0200 Subject: [PATCH 4/9] OVPAY-2485 - Added schemas. --- src/openapi/customers/SE-customers-v2.yaml | 187 +++++++++++---------- 1 file changed, 100 insertions(+), 87 deletions(-) diff --git a/src/openapi/customers/SE-customers-v2.yaml b/src/openapi/customers/SE-customers-v2.yaml index e09b067..0543f84 100644 --- a/src/openapi/customers/SE-customers-v2.yaml +++ b/src/openapi/customers/SE-customers-v2.yaml @@ -380,7 +380,7 @@ paths: type: string example: Customer required: false - description: The role of the HTM employee in the case of the SMP + description: The role of the HTM employee in the case of the SMP requestBody: content: application/json: @@ -415,7 +415,7 @@ paths: type: string example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c required: false - description: The JWT of a customer in case of touchpoint were customer logs in themselves + description: The JWT of a customer in case of touchpoint were customer logs in themselves - name: X-HTM-CUSTOMER-PROFILE-ID-HEADER in: header schema: @@ -429,7 +429,7 @@ paths: type: string example: Customer required: false - description: The role of the HTM employee in the case of the SMP + description: The role of the HTM employee in the case of the SMP requestBody: content: application/json: @@ -464,7 +464,7 @@ paths: type: string example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c required: false - description: The JWT of a customer in case of touchpoint were customer logs in themselves + description: The JWT of a customer in case of touchpoint were customer logs in themselves - name: X-HTM-CUSTOMER-PROFILE-ID-HEADER in: header schema: @@ -478,7 +478,7 @@ paths: type: string example: Customer required: false - description: The role of the HTM employee in the case of the SMP + description: The role of the HTM employee in the case of the SMP - name: customerPreferenceId in: path required: true @@ -519,7 +519,7 @@ paths: type: string example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c required: false - description: The JWT of a customer in case of touchpoint were customer logs in themselves + description: The JWT of a customer in case of touchpoint were customer logs in themselves - name: X-HTM-CUSTOMER-PROFILE-ID-HEADER in: header schema: @@ -533,8 +533,8 @@ paths: type: string example: Customer required: false - description: The role of the HTM employee in the case of the SMP - + description: The role of the HTM employee in the case of the SMP + requestBody: content: application/json: @@ -575,7 +575,7 @@ paths: type: string example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c required: false - description: The JWT of a customer in case of touchpoint were customer logs in themselves + description: The JWT of a customer in case of touchpoint were customer logs in themselves - name: X-HTM-CUSTOMER-PROFILE-ID-HEADER in: header schema: @@ -589,7 +589,7 @@ paths: type: string example: Customer required: false - description: The role of the HTM employee in the case of the SMP + description: The role of the HTM employee in the case of the SMP - name: addressId in: path required: true @@ -634,7 +634,7 @@ paths: type: string example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c required: false - description: The JWT of a customer in case of touchpoint were customer logs in themselves + description: The JWT of a customer in case of touchpoint were customer logs in themselves - name: X-HTM-CUSTOMER-PROFILE-ID-HEADER in: header schema: @@ -648,7 +648,7 @@ paths: type: string example: Customer required: false - description: The role of the HTM employee in the case of the SMP + description: The role of the HTM employee in the case of the SMP - name: addressId in: path required: true @@ -669,14 +669,14 @@ paths: summary: Add a customer phone description: >- - parameters: + parameters: - name: X-HTM-JWT-AUTH-HEADER in: header schema: type: string example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c required: false - description: The JWT of a customer in case of touchpoint were customer logs in themselves + description: The JWT of a customer in case of touchpoint were customer logs in themselves - name: X-HTM-CUSTOMER-PROFILE-ID-HEADER in: header schema: @@ -690,7 +690,7 @@ paths: type: string example: Customer required: false - description: The role of the HTM employee in the case of the SMP + description: The role of the HTM employee in the case of the SMP requestBody: content: application/json: @@ -728,7 +728,7 @@ paths: type: string example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c required: false - description: The JWT of a customer in case of touchpoint were customer logs in themselves + description: The JWT of a customer in case of touchpoint were customer logs in themselves - name: X-HTM-CUSTOMER-PROFILE-ID-HEADER in: header schema: @@ -742,7 +742,7 @@ paths: type: string example: Customer required: false - description: The role of the HTM employee in the case of the SMP + description: The role of the HTM employee in the case of the SMP - name: phoneId in: path required: true @@ -754,7 +754,7 @@ paths: application/json: schema: $ref: "#/components/schemas/phoneEntity" - examples: + examples: updateFullPhoneEntity: value: phone: @@ -789,7 +789,7 @@ paths: type: string example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c required: false - description: The JWT of a customer in case of touchpoint were customer logs in themselves + description: The JWT of a customer in case of touchpoint were customer logs in themselves - name: X-HTM-CUSTOMER-PROFILE-ID-HEADER in: header schema: @@ -803,7 +803,7 @@ paths: type: string example: Customer required: false - description: The role of the HTM employee in the case of the SMP + description: The role of the HTM employee in the case of the SMP - name: phoneId in: path required: true @@ -816,7 +816,7 @@ paths: content: application/json: {} x-auth-type: Application & Application User - x-throttling-tier: Unlimited + x-throttling-tier: Unlimited /customers/billinginformations: get: tags: @@ -831,7 +831,7 @@ paths: type: string example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c required: false - description: The JWT of a customer in case of touchpoint were customer logs in themselves + description: The JWT of a customer in case of touchpoint were customer logs in themselves - name: X-HTM-CUSTOMER-PROFILE-ID-HEADER in: header schema: @@ -845,7 +845,7 @@ paths: type: string example: Customer required: false - description: The role of the HTM employee in the case of the SMP + description: The role of the HTM employee in the case of the SMP responses: 200: description: OK @@ -866,7 +866,7 @@ paths: "billingInformationId": 1, "iban": "NL••••••••••••1234", "ascription": "J. Doe", - "alias": null, + "alias": null, "created": "2024-10-20T17:05:52.000", }, ], @@ -875,7 +875,7 @@ paths: get: tags: - Customers - summary: Find direct debit mandates for a customer. + summary: Find direct debit mandates for a customer. description: Find direct debit mandates for a customer. parameters: - name: X-HTM-JWT-AUTH-HEADER @@ -884,7 +884,7 @@ paths: type: string example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c required: false - description: The JWT of a customer in case of touchpoint were customer logs in themselves + description: The JWT of a customer in case of touchpoint were customer logs in themselves - name: X-HTM-CUSTOMER-PROFILE-ID-HEADER in: header schema: @@ -898,7 +898,7 @@ paths: type: string example: Customer required: false - description: The role of the HTM employee in the case of the SMP + description: The role of the HTM employee in the case of the SMP responses: 200: description: OK @@ -914,12 +914,12 @@ paths: [ { "directDebitMandateId": 71, - "billingInformationId": + "billingInformationId": { "billingInformationId": 15, "iban": "NL••••••••••••1234", "ascription": "J. Doe", - "alias": null, + "alias": null, "created": "2024-10-20T17:05:52.000", }, "directDebitMandateType": @@ -1142,7 +1142,7 @@ paths: "ovPayTokenId": 1, "xTat": "32089cc8-d187-47ff-a3a9-5c2558def811", "tokenType": - { "tokenTypeId": 2, "name": "OV-pas physical" }, + { "tokenTypeId": 2, "name": "OV-pas physical" }, "ovpasNumber": "OV34567", "alias": "MyToken", "tokenStatus": @@ -1225,7 +1225,7 @@ paths: "ovPayTokenId": 1, "xTat": "32089cc8-d187-47ff-a3a9-5c2558def811", "tokenType": - { "tokenTypeId": 2, "name": "OV-pas physical" }, + { "tokenTypeId": 2, "name": "OV-pas physical" }, "ovpasNumber": "OV34567", "alias": "MyToken", "tokenStatus": @@ -1348,8 +1348,8 @@ paths: "ovPayTokenId": 1, "xTat": "32089cc8-d187-47ff-a3a9-5c2558def811", "tokenType": - { "tokenTypeId": 2, "name": "OV-pas physical" }, - "ovpasNumber": "OV34567", + { "tokenTypeId": 2, "name": "OV-pas physical" }, + "ovpasNumber": "OV34567", "alias": "MyToken", "tokenStatus": { "tokenStatusId": 2, "name": "Active" }, @@ -1446,7 +1446,7 @@ paths: "ovPayTokenId": 1, "xTat": "32089cc8-d187-47ff-a3a9-5c2558def811", "tokenType": - { "tokenTypeId": 2, "name": "OV-pas physical" }, + { "tokenTypeId": 2, "name": "OV-pas physical" }, "ovpasNumber": "OV34567", "alias": "MyToken", "tokenStatus": @@ -1562,7 +1562,7 @@ paths: "ovPayTokenId": 1, "xTat": "e7fa3392-646b-40e2-95a6-c417dc0b0969", "tokenType": - { "tokenTypeId": 2, "name": "OV-pas physical" }, + { "tokenTypeId": 2, "name": "OV-pas physical" }, "ovpasNumber": "OV34567", "alias": "MyToken", "tokenStatus": @@ -1583,7 +1583,7 @@ paths: "ovPayTokenId": 6, "xTat": "e7fa3392-646b-40e2-95a6-c417dc0b0969", "tokenType": - { "tokenTypeId": 2, "name": "OV-pas physical" }, + { "tokenTypeId": 2, "name": "OV-pas physical" }, "ovpasNumber": "OV54567", "alias": "MyToken", "tokenStatus": @@ -1605,7 +1605,7 @@ paths: "ovPayTokenId": 13, "xTat": "e7fa3392-646b-40e2-95a6-c417dc0b0969", "tokenType": - { "tokenTypeId": 2, "name": "OV-pas physical" }, + { "tokenTypeId": 2, "name": "OV-pas physical" }, "ovpasNumber": "OV34547", "alias": "MyToken", "tokenStatus": @@ -1627,7 +1627,7 @@ paths: "ovPayTokenId": 21, "xTat": "e7fa3392-646b-40e2-95a6-c417dc0b0969", "tokenType": - { "tokenTypeId": 2, "name": "OV-pas physical" }, + { "tokenTypeId": 2, "name": "OV-pas physical" }, "ovpasNumber": "OV34831", "alias": "Mijn OV Pas", "tokenStatus": @@ -1649,7 +1649,7 @@ paths: "ovPayTokenId": 28, "xTat": "e7fa3392-646b-40e2-95a6-c417dc0b0969", "tokenType": - { "tokenTypeId": 2, "name": "OV-pas physical" }, + { "tokenTypeId": 2, "name": "OV-pas physical" }, "ovpasNumber": "OV34984", "alias": "Mijn OV Pas", "tokenStatus": @@ -1674,7 +1674,7 @@ paths: "ovPayTokenId": 115, "xTat": "e7fa3392-646b-40e2-95a6-c417dc0b0969", "tokenType": - { "tokenTypeId": 2, "name": "OV-pas physical" }, + { "tokenTypeId": 2, "name": "OV-pas physical" }, "ovpasNumber": "OV54368", "alias": "My retired token", "tokenStatus": @@ -1696,7 +1696,7 @@ paths: "ovPayTokenId": 118, "xTat": "e7fa3392-646b-40e2-95a6-c417dc0b0969", "tokenType": - { "tokenTypeId": 2, "name": "OV-pas physical" }, + { "tokenTypeId": 2, "name": "OV-pas physical" }, "ovpasNumber": "OV98263", "alias": "My found token", "tokenStatus": @@ -2905,9 +2905,9 @@ paths: summary: "**INTEGRATIELAAG** Transfer old OVpay token to new OVpay token." description: |- **Note that this directly calls the integratielaag and not the Service Engine!** - First transfers all personal account data (if present), then all products, of an existing OVpay token + First transfers all personal account data (if present), then all products, of an existing OVpay token to a new OVpay token. The new token will also be persisted in the profile as a replacement - of the old token. This call is asynchronous, and progress can be monitored using the + of the old token. This call is asynchronous, and progress can be monitored using the `/customers/tokens/transfer/responsestatus/*` endpoint. tags: - Token Replace v2 @@ -2920,9 +2920,9 @@ paths: Transfer from a token without PAD to a new token: summary: Transfer from a token without PAD to a new token description: | - Transfer of a token without PAD to a new OVpay token. Note the new token in the request is always - identified by xTAT, regardless if the new token already exists in the customer profile. If the new - token does not exist in the customer profile, the user needs to provide an alias for the new token, + Transfer of a token without PAD to a new OVpay token. Note the new token in the request is always + identified by xTAT, regardless if the new token already exists in the customer profile. If the new + token does not exist in the customer profile, the user needs to provide an alias for the new token, and it will be created in the customer profile. value: { @@ -2936,11 +2936,11 @@ paths: Transfer from a token with PAD to a new token without existing PAD: summary: Transfer from a token with PAD to a new token without existing PAD description: | - Transfer of a token with PAD to a new token by xTAT without existing PAD. Note how this request is - different, since it has an e-mail address on which the new PAD should be created. This request may + Transfer of a token with PAD to a new token by xTAT without existing PAD. Note how this request is + different, since it has an e-mail address on which the new PAD should be created. This request may optionally provide an OTP for verification of th provided email address. - Also note the new token in the request is always identified by xTAT, regardless if the new token - already exists in the customer profile. If the new token does not exist in the customer profile, the + Also note the new token in the request is always identified by xTAT, regardless if the new token + already exists in the customer profile. If the new token does not exist in the customer profile, the user needs to provide an alias for the new token, and it will be created in the customer profile. value: { @@ -2957,8 +2957,8 @@ paths: summary: Transfer from a token with PAD to a new token with existing PAD description: | Transfer of a token with PAD to a new token by xTAT with existing PAD. - Note that the new token in the request is always identified by xTAT, regardless if the new token - already exists in the customer profile. If the new token does not exist in the customer profile, the + Note that the new token in the request is always identified by xTAT, regardless if the new token + already exists in the customer profile. If the new token does not exist in the customer profile, the user needs to provide an alias for the new token, and it will be created in the customer profile. value: { @@ -2996,7 +2996,7 @@ paths: Transfer of token started: description: | The transfer of the token was started successfully. The data of the token will be transferred - asynchronously. In the response body the consumer will find information on how to retrieve the + asynchronously. In the response body the consumer will find information on how to retrieve the processing status. value: { @@ -3038,7 +3038,7 @@ paths: - Token Replace v2 summary: "**INTEGRATIELAAG** Get the status of the initiated token transfer process." description: | - **Note that this directly calls the integratielaag and not the Service Engine!** Get the status of the + **Note that this directly calls the integratielaag and not the Service Engine!** Get the status of the asynchronous token transfer processing. responses: "200": @@ -3166,7 +3166,7 @@ paths: examples: Token transfer in progress: description: | - The transfer of the token is still in progress. The response body shows the details of the + The transfer of the token is still in progress. The response body shows the details of the processing status. value: { @@ -3347,7 +3347,7 @@ paths: in: query description: External id of the device you want to get the purchased HTM products for. schema: - type: string + type: string - name: ovpayTokenId in: query description: Id of the OVpay-token you want to get the purchased HTM products for. @@ -3380,9 +3380,9 @@ paths: } getTwoBarcodePurchasedProductsForDevice: summary: Two BarcodeTicket purchased products, one PendingActivation and one Active - description: |- - The first ticket (PendingActivation) shows the 30-day range in which the ticket can be activated - (using the PATCH endpoint) in the validityStart and validityEnd fields. The second ticket (Active) + description: |- + The first ticket (PendingActivation) shows the 30-day range in which the ticket can be activated + (using the PATCH endpoint) in the validityStart and validityEnd fields. The second ticket (Active) shows the actual validity period of the ticket after activation. value: { @@ -3401,14 +3401,14 @@ paths: "name": "Barcode", }, "orderId": "501B17EF-36C4-4039-B92C-6517969B464E", - "orderLineId": "38B17EF-36C4-4039-B92C-4817969B464E", + "orderLineId": "38B17EF-36C4-4039-B92C-4817969B464E", "ticketReference": "KJj43nejhbTxhrfef287", "serviceId": "HTM-4321-7654-7659", "issuedAt": "2026-03-21T09:01:35+01:00", "activatedAt": null, "blocked": false, - "cancelledAt": null, - "activateBefore": "2026-03-30", + "cancelledAt": null, + "activateBefore": "2026-03-30", "validityStart": null, "validityEnd": null, "barcode": null, @@ -3436,14 +3436,14 @@ paths: "name": "Barcode", }, "orderId": "501B17EF-36C4-4039-B92C-6517969B464E", - "orderLineId": "38B17EF-36C4-4039-B92C-4817969B464E", + "orderLineId": "38B17EF-36C4-4039-B92C-4817969B464E", "ticketReference": "KJj43nejhbTxhr897287", "serviceId": "HTM-1234-7654-8945", "issuedAt": "2026-03-21T10:01:12+01:00", "activatedAt": "2026-03-21T12:45:01+01:00", "blocked": false, - "cancelledAt": null, - "activateBefore": null, + "cancelledAt": null, + "activateBefore": null, "validityStart": "2026-03-21T12:45:01+01:00", "validityEnd": "2026-03-21T14:45:01+01:00", "barcode": "iVBORw0KGgoAAAANSUhEUgAAAVwAAAFcAQAAAACsbTuBAAAFDElEQVR4Xu2bQa6rOhBEGzHwMEtgKewMyM5YCkvIkAGif50yyc/Tl770piZW9HSNywzqVlW3nXcjc83cusxnvsbMjBieuelf/bzGYz1jWCKmeGS+4g5grSwlz/IaI+JgEfzcvzQZo2yhxQgW7wDutLJrvVLzEInbVHLpM/tK5T7kHmNdbxssgqSipQj/0KLA24yqNvEWWRclpJKpefNgE7YZr/lj1eZ55wMYIWkUbZb7Xj/wH+BezvPkFJhQetmD+7AI2VuSEQMevANYESzqZh49VlEXIKOT7SDtseqnpz0Iyc2DJZezkEB5aaVKSvuF5FMwaIdB7wCGOgb5fFgus2wlKhPDpUiTlogr1tsHG7lfzcqYLlVnDHq6ylYn1OE54qd5cNC6aQxL0UQRy2YJJxCS8N4m273Gm4BJFAhzlytb5T4A0QrCYmUTrxd1bYNVgGqqPndH7vHwYqHLHf9cpO1pHJxU3Nq6vUbAVhXaocnTKO5cpK+4AViLitRwf8IQdYFwBkkKW7FzZxNh/AN/g5NHqXyed5MOz45kjkvKofpLYNwBrNBR/Dz9SKpTDkGd8CApZYonT24B7un56XKnoMeXkOBNHqTDk/NOmrrwyfIWYHe51O4kn4FBnfYbnHjqKuw3AGMreKOvC07DCAebHS5lAXWq5eKVA0HjYA2xM0MYCSMnqTqpx48ZVSmPTd15tT03AF+LVBuOgJoMqc2HL6Gy8nr1/K2DU+YpmKerd45fQ2ypzSFyq8coUM2D1yBksNWqOTWnjqvLpVYPvrt17f6BP+AaQk85zR4MarfHbAlSu/XhgGCJNg6mQNmASXnGhpZY+tKp93lywaY+SjcPhroCWx1BHFAnVemR81mdjEikWlllzYNrCM27bKVt7nInLplEnef6SfPFhb19MDmCbewcjtL/d7FwAzCqmShYzMd/qaPnp0AxV+SOpq5xMCnLZJOhZCNCZuIR4BWwL6un4luF5sE9N7CKXIJ2Zecncnt3vZ0it+hN7wNC6+DU/Ene1gj+lOOr4BDGilyT3D74NZ4OlYm2Xmx9t2rJN+kb7P3A/wUzV6lSQaonIoR3DUdy7vR1WQt782CrzrbbvTOdxwu2ZKy4MZXXflPzYJoVLg6GpbIVtLSb2JxduzEg+6Mm+R3AXECaHYRjG4nH2UIak7jSm9zXNQ9OLha2yhbUCT/vOA1VHUAGXpVuhpsHE7H7O0d6d2+i7rxeI2EVVMTm4wZg5vZUV2/nBUmoG5befZ0XERKkNg9O8zR9Rexls+WgldPRmTYHp90BrAIkqqYYnkmNGfvEY1E2Ijeu/3SQLKar1Q/8AX88eDqCRe3wZKJ89sVCRdaTZfvg/u8uFhoH14J0apHvil2rFwrUNtuDcXLOruNdvRoGB9ezgJXP2OrwN+mz8jl9lPab3Ob0NwDbVteFpEuX+7ylbHGdo5Oeny8y4vJgy2DniHhzQQp3c4yCkLwZvPbXk+INwKeqj6grVB/ha+dC88LVfec3zR/q2gYnlyO5GD+Kvfp03unruKCUygJb1e8HmwdbPp2pg8fgr3XYnE6YQGUWUp20Dz6hSgReznmXY3hLJ5A2ozJT9wN/gfVIEbzBsxvdYSneL571OV279S+/jubBiuCzAL5qt5xHPNHMcHgciSuD15rXbYMtJFbE1piEkEi0fPp6AoLX5Lvjt+paBvOIRQjSEEHaCX5BSP4DBSalHh4bB/8DVeIFt2RfPhQAAAAASUVORK5CYII=", @@ -3499,7 +3499,7 @@ paths: "barcodeTickets":[], "vouchers":[] } - } + } getSingleVoucherPurchasedProductForCustomer: summary: One voucher purchased product value: @@ -3523,7 +3523,7 @@ paths: "voucherStatus": { "voucherStatusId": 2, "name": "issued" - }, + }, "mandatoryCustomerDataItems": [ { @@ -3538,7 +3538,7 @@ paths: } ] } - } + } /purchasedproducts/{purchasedProductId}: parameters: - name: X-HTM-JWT-AUTH-HEADER @@ -3586,7 +3586,7 @@ paths: value: { "status": "Active" - } + } responses: "200": description: OK @@ -3732,7 +3732,7 @@ paths: type: string example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c required: false - description: The JWT of a customer in case of touchpoint were customer logs in themselves + description: The JWT of a customer in case of touchpoint were customer logs in themselves - name: X-HTM-CUSTOMER-PROFILE-ID-HEADER in: header schema: @@ -3746,7 +3746,7 @@ paths: type: string example: Customer required: false - description: The role of the HTM employee in the case of the SMP + description: The role of the HTM employee in the case of the SMP post: tags: - AGO @@ -3756,7 +3756,7 @@ paths: content: application/json: schema: - $ref: "#/components/schemas/unavailable" + $ref: "#/components/schemas/ActivateAgoRequest" examples: For self: value: @@ -3861,7 +3861,7 @@ paths: type: string example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c required: false - description: The JWT of a customer in case of touchpoint were customer logs in themselves + description: The JWT of a customer in case of touchpoint were customer logs in themselves - name: X-HTM-CUSTOMER-PROFILE-ID-HEADER in: header schema: @@ -3875,7 +3875,7 @@ paths: type: string example: Customer required: false - description: The role of the HTM employee in the case of the SMP + description: The role of the HTM employee in the case of the SMP post: tags: - AGO @@ -3885,7 +3885,7 @@ paths: content: application/json: schema: - $ref: "#/components/schemas/unavailable" + $ref: "#/components/schemas/VerifyOtpRequest" example: otp: 123456 responses: @@ -4048,7 +4048,7 @@ components: customerProfileId: type: integer example: 1 - customerPreference: + customerPreference: $ref: "#/components/schemas/getCustomerPreference" customerNumber: type: integer @@ -4249,12 +4249,12 @@ components: customerPreferenceId: type: integer languageId: - type: integer + type: integer customerStatusEntity: type: object properties: customerStatusId: - type: integer + type: integer OvPayTokensResponse: type: object required: @@ -4533,7 +4533,7 @@ components: items: type: object required: - - purchasedProductId + - purchasedProductId - productId - name - status @@ -4656,13 +4656,13 @@ components: type: string example: HTM 2 uurskaart description: |- - The name of the originating HTM product definition. + The name of the originating HTM product definition. Will be returned in the language as specified in the Accept-Language header or the customer profile. Otherwise defaults to NL. description: type: string example: "Met deze kaart reis je 2 uur lang onbeperkt met de bussen en trams van HTM. Overstappen is natuurlijk toegestaan!" description: |- - The description of the originating HTM product definition. + The description of the originating HTM product definition. Will be returned in the language as specified in the Accept-Language header or the customer profile. Otherwise defaults to NL. status: type: string @@ -4721,15 +4721,15 @@ components: example: "2024-11-30" description: Only present for barcode tickets that are not yet activated. Tickets can only be activated BEFORE this date. validityStart: - description: |- - Only present for barcode tickets that have been activated. The date-time at which the ticket will become valid for traveling. + description: |- + Only present for barcode tickets that have been activated. The date-time at which the ticket will become valid for traveling. The ticket will not be valid before this date/time. type: string format: date-time-offset example: "2024-11-25T13:25:00+01:00" validityEnd: - description: |- - Only present for barcode tickets that have been activated. The date-time at which the ticket will become invalid for traveling. + description: |- + Only present for barcode tickets that have been activated. The date-time at which the ticket will become invalid for traveling. The ticket will not be valid after this date/time. type: string format: date-time-offset @@ -4928,7 +4928,7 @@ components: description: >- A ValidateTatOutputDescription IS A string that provides more details about the OTP validation result. - example: TAT Secured + example: TAT Secured TatUnsecured: type: object description: A TatUnsecured IS AN object THAT represents the response of TAT security @@ -4938,7 +4938,20 @@ components: example: Success description: type: string - example: TAT Unsecured + example: TAT Unsecured + ActivateAgoRequest: + type: object + properties: + emailAddress: + type: string + format: email + example: stasjo@htm.nl + VerifyOtpRequest: + type: object + properties: + emailAddress: + type: string + example: 123456 ErrorResponse: description: Default response when an invalid request has been sent type: object From 87d8f7df589c8075bf9966ce934e1b351c305f25 Mon Sep 17 00:00:00 2001 From: "b.boterman@htm.nl" Date: Thu, 18 Jun 2026 10:25:06 +0200 Subject: [PATCH 5/9] OVPAY-2485 - Updated OTP response body for TP. --- src/openapi/customers/SE-customers-v2.yaml | 71 ++++++---------------- 1 file changed, 18 insertions(+), 53 deletions(-) diff --git a/src/openapi/customers/SE-customers-v2.yaml b/src/openapi/customers/SE-customers-v2.yaml index 0543f84..a3882c6 100644 --- a/src/openapi/customers/SE-customers-v2.yaml +++ b/src/openapi/customers/SE-customers-v2.yaml @@ -3894,27 +3894,20 @@ paths: content: application/json: schema: - type: object - oneOf: - - $ref: '#/components/schemas/AuthCodeResponse' - - $ref: '#/components/schemas/ValidateTatOutputDescription' - - $ref: '#/components/schemas/TatUnsecured' + $ref: '#/components/schemas/VerifyOtpResponse' examples: - AuthCodeResponse: + Tat Secured: value: - authCode: 4f3a9c8b-xxxx - ValidateTatOutputDescription: - value: - 0: s - 1: t - 2: r - 3: i - 4: n - 5: g - TatUnsecured: + status: Success + description: TAT Secured + Tat Unsecured: value: status: Success description: TAT Unsecured + Tat Authorized: + value: + status: Success + description: TAT Authorized "400": description: Bad request content: @@ -4902,43 +4895,6 @@ components: A description IS A string THAT describes the reason why the email is not pre-approved. example: OTP Sent - AuthCodeResponse: - type: object - properties: - authCode: - type: string - description: >- - An AuthCodeResponse IS A string that represents the authorization - code that can be exchanged for a user access token. - example: 4f3a9c8b-xxxx - ValidateTatOutputDescription: - type: string - properties: - authCode: - type: string - description: >- - An AuthCodeResponse IS A string that represents the authorization - code that can be exchanged for a user access token. - example: 4f3a9c8b-xxxx - status: - type: string - example: Success - description: - type: string - description: >- - A ValidateTatOutputDescription IS A string that provides more - details about the OTP validation result. - example: TAT Secured - TatUnsecured: - type: object - description: A TatUnsecured IS AN object THAT represents the response of TAT security - properties: - status: - type: string - example: Success - description: - type: string - example: TAT Unsecured ActivateAgoRequest: type: object properties: @@ -4952,6 +4908,15 @@ components: emailAddress: type: string example: 123456 + VerifyOtpResponse: + type: object + properties: + status: + type: string + example: Success + description: + type: string + example: TAT Secured ErrorResponse: description: Default response when an invalid request has been sent type: object From f28a797b6bd4220e0c4ccde0c66f66c3ee5eeaa7 Mon Sep 17 00:00:00 2001 From: "b.boterman@htm.nl" Date: Thu, 18 Jun 2026 11:17:04 +0200 Subject: [PATCH 6/9] OVPAY-2485 - Improved TP requests. --- src/openapi/customers/SE-customers-v2.yaml | 30 ++++++++++++++-------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/src/openapi/customers/SE-customers-v2.yaml b/src/openapi/customers/SE-customers-v2.yaml index a3882c6..1b59ae6 100644 --- a/src/openapi/customers/SE-customers-v2.yaml +++ b/src/openapi/customers/SE-customers-v2.yaml @@ -3757,13 +3757,8 @@ paths: application/json: schema: $ref: "#/components/schemas/ActivateAgoRequest" - examples: - For self: - value: - emailAddress: null - For other: - value: - emailAddress: stasjo@htm.nl + example: + emailAddress: stasjo@htm.nl responses: "200": description: OK @@ -3879,15 +3874,25 @@ paths: post: tags: - AGO - summary: Request additional OV-pas security for a token in profile. - description: Request additional OV-pas security for a token in profile. + summary: Submit an OTP for a triggered OTP flow. + description: | + Submit an OTP for a triggered OTP flow. This can either be result of an AGO activation, or + result of an AGO authorization flow. Since the backoffice behaves slightly different depending + on which use case is executed, the calling TP needs to provide an `action` in the request body. requestBody: content: application/json: schema: $ref: "#/components/schemas/VerifyOtpRequest" - example: - otp: 123456 + examples: + OTP verification for TAT security activation: + value: + otp: 123456 + action: secure + OTP verification for TAT security authorization: + value: + otp: 123456 + action: authorize responses: "200": description: OK @@ -4908,6 +4913,9 @@ components: emailAddress: type: string example: 123456 + action: + type: string + example: secure VerifyOtpResponse: type: object properties: From 280d3b1fcd8895d1fd4bc7613048ddca16b1e6cc Mon Sep 17 00:00:00 2001 From: "b.boterman@htm.nl" Date: Thu, 18 Jun 2026 11:58:34 +0200 Subject: [PATCH 7/9] OVPAY-2485 - Extended token details response bodies with security. --- src/openapi/customers/SE-customers-v2.yaml | 72 ++++++++++++++++++++-- 1 file changed, 66 insertions(+), 6 deletions(-) diff --git a/src/openapi/customers/SE-customers-v2.yaml b/src/openapi/customers/SE-customers-v2.yaml index 1b59ae6..8710a1e 100644 --- a/src/openapi/customers/SE-customers-v2.yaml +++ b/src/openapi/customers/SE-customers-v2.yaml @@ -1081,6 +1081,10 @@ paths: "photo": null, }, "gboAgeProfile": null, + "tatSecurity": { + "isSecured": true, + "isAuthorized": true, + }, "_links": { "self": @@ -1130,9 +1134,9 @@ paths: }, }, } - OV pas without PAD: - summary: OV pas without PAD - description: OV pas without PAD + OV pas without PAD, without AGO: + summary: OV pas without PAD, without AGO + description: OV pas without PAD, without AGO value: { "ovPayTokens": @@ -1164,6 +1168,10 @@ paths: "photo": null, }, "gboAgeProfile": null, + "tatSecurity": { + "isSecured": false, + "isAuthorized": null, + }, "_links": { "self": @@ -1213,9 +1221,9 @@ paths: }, }, } - OV pas with PAD and autoReload: - summary: OV pas with PAD and autoReload - description: OV pas with PAD and autoReload + OV pas with PAD, with autoReload, with AGO: + summary: OV pas with PAD, with autoReload, with AGO + description: OV pas with PAD, with autoReload, with AGO value: { "ovPayTokens": @@ -1287,6 +1295,10 @@ paths: "ageFromInclusive": 4, "ageToInclusive": 11, }, + "tatSecurity": { + "isSecured": true, + "isAuthorized": true, + }, "_links": { "self": @@ -1385,6 +1397,10 @@ paths: "ageFromInclusive": 4, "ageToInclusive": 11, }, + "tatSecurity": { + "isSecured": true, + "isAuthorized": true, + }, "_links": { "self": @@ -1501,6 +1517,10 @@ paths: "ageFromInclusive": 4, "ageToInclusive": 11, }, + "tatSecurity": { + "isSecured": true, + "isAuthorized": true, + }, "_links": { "self": @@ -1599,6 +1619,10 @@ paths: "photo": null, }, "gboAgeProfile": null, + "tatSecurity": { + "isSecured": true, + "isAuthorized": true, + }, }, { "customerProfileId": 18, @@ -1621,6 +1645,10 @@ paths: "photo": null, }, "gboAgeProfile": null, + "tatSecurity": { + "isSecured": true, + "isAuthorized": true, + }, }, { "customerProfileId": 132, @@ -1643,6 +1671,10 @@ paths: "photo": null, }, "gboAgeProfile": null, + "tatSecurity": { + "isSecured": true, + "isAuthorized": true, + }, }, { "customerProfileId": 166, @@ -1668,6 +1700,10 @@ paths: "photo": null, }, "gboAgeProfile": null, + "tatSecurity": { + "isSecured": true, + "isAuthorized": true, + }, }, { "customerProfileId": 166, @@ -1690,6 +1726,10 @@ paths: "photo": null, }, "gboAgeProfile": null, + "tatSecurity": { + "isSecured": true, + "isAuthorized": true, + }, }, { "customerProfileId": 1, @@ -1712,6 +1752,10 @@ paths: "photo": null, }, "gboAgeProfile": null, + "tatSecurity": { + "isSecured": true, + "isAuthorized": true, + }, }, ], _links: @@ -1812,6 +1856,10 @@ paths: "personalAccountData": { "name": null, "birthdate": null, "photo": null }, "gboAgeProfile": null, + "tatSecurity": { + "isSecured": true, + "isAuthorized": true, + }, "_links": { "self": @@ -1890,6 +1938,10 @@ paths: "personalAccountData": { "name": null, "birthdate": null, "photo": null }, "gboAgeProfile": null, + "tatSecurity": { + "isSecured": true, + "isAuthorized": true, + }, "_links": { "self": @@ -2086,6 +2138,10 @@ paths: "personalAccountData": { "name": null, "birthdate": null, "photo": null }, "gboAgeProfile": null, + "tatSecurity": { + "isSecured": true, + "isAuthorized": true, + }, "_links": { "self": @@ -2149,6 +2205,10 @@ paths: "personalAccountData": { "name": null, "birthdate": null, "photo": null }, "gboAgeProfile": null, + "tatSecurity": { + "isSecured": true, + "isAuthorized": true, + }, "_links": { "self": From 3d2885f2b8f1bd45c43111db8062d9afdd4d17df Mon Sep 17 00:00:00 2001 From: "b.boterman@htm.nl" Date: Thu, 18 Jun 2026 14:43:08 +0200 Subject: [PATCH 8/9] OVPAY-2485 - Added support for anonymous TAT security. --- src/openapi/customers/SE-customers-v2.yaml | 339 -------------------- src/openapi/customers/SE-tat-security.yaml | 341 +++++++++++++++++++++ 2 files changed, 341 insertions(+), 339 deletions(-) create mode 100644 src/openapi/customers/SE-tat-security.yaml diff --git a/src/openapi/customers/SE-customers-v2.yaml b/src/openapi/customers/SE-customers-v2.yaml index 8710a1e..29fd300 100644 --- a/src/openapi/customers/SE-customers-v2.yaml +++ b/src/openapi/customers/SE-customers-v2.yaml @@ -3776,240 +3776,6 @@ paths: responses: "200": description: OK - /customers/tokens/{ovPayTokenId}/activateago: - parameters: - - name: ovPayTokenId - in: path - required: true - style: simple - description: Id of the OvPayToken to activate AGO for. - schema: - type: integer - example: 1 - - name: X-HTM-JWT-AUTH-HEADER - in: header - schema: - type: string - example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c - required: false - description: The JWT of a customer in case of touchpoint were customer logs in themselves - - name: X-HTM-CUSTOMER-PROFILE-ID-HEADER - in: header - schema: - type: integer - example: 323 - required: false - description: The id of the customer Profile - - name: X-HTM-ROLE-HEADER - in: header - schema: - type: string - example: Customer - required: false - description: The role of the HTM employee in the case of the SMP - post: - tags: - - AGO - summary: Request additional OV-pas security for a token in profile. - description: Request additional OV-pas security for a token in profile. - requestBody: - content: - application/json: - schema: - $ref: "#/components/schemas/ActivateAgoRequest" - example: - emailAddress: stasjo@htm.nl - responses: - "200": - description: OK - content: - application/json: - schema: - oneOf: - - $ref: "#/components/schemas/EmailPreApprovedResponse" - - $ref: "#/components/schemas/EmailNotPreApprovedResponse" - examples: - Email preapproved: - value: - status: Success - description: TAT Secured - Email not preapproved: - value: - uid: 7594f3ee-cd3d-40a3-8e82-73b90d16c481 - recipient: xxxxxx.user@gmail.com - key: 123456789123456789123456789abcde - description: OTP Sent - "400": - description: Bad Request - content: - application/json: - schema: - $ref: "#/components/schemas/ErrorResponse" - examples: - Missing Parameters: - value: - status: 400 - title: Missing Mandatory Parameter - detail: Required parameter {0} is missing. - Invalid Parameters: - value: - status: 400 - title: Invalid Parameter - detail: Required parameter {0} is invalid. - "401": - description: Unauthorized - content: - application/json: - schema: - $ref: "#/components/schemas/ErrorResponse" - examples: - Unauthorized: - value: - status: 401 - title: Unauthorized - detail: Invalid Access Token - "404": - description: Not found - content: - application/json: - schema: - $ref: "#/components/schemas/ErrorResponse" - examples: - TAT not found: - value: - status: 404 - title: Not Found - detail: TAT Account Not Found - "409": - description: Conflict - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - examples: - TAT Already Secured: - value: - status: 409 - title: Conflict - detail: TAT Already Secured - "500": - description: Internal server error - content: - application/json: - schema: - $ref: "#/components/schemas/ErrorResponse" - example: - error: An unknown error has occurred - /customers/tokens/{ovPayTokenId}/validateotp: - parameters: - - name: ovPayTokenId - in: path - required: true - style: simple - description: Id of the OvPayToken to verify OTP for. - schema: - type: integer - example: 1 - - name: X-HTM-JWT-AUTH-HEADER - in: header - schema: - type: string - example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c - required: false - description: The JWT of a customer in case of touchpoint were customer logs in themselves - - name: X-HTM-CUSTOMER-PROFILE-ID-HEADER - in: header - schema: - type: integer - example: 323 - required: false - description: The id of the customer Profile - - name: X-HTM-ROLE-HEADER - in: header - schema: - type: string - example: Customer - required: false - description: The role of the HTM employee in the case of the SMP - post: - tags: - - AGO - summary: Submit an OTP for a triggered OTP flow. - description: | - Submit an OTP for a triggered OTP flow. This can either be result of an AGO activation, or - result of an AGO authorization flow. Since the backoffice behaves slightly different depending - on which use case is executed, the calling TP needs to provide an `action` in the request body. - requestBody: - content: - application/json: - schema: - $ref: "#/components/schemas/VerifyOtpRequest" - examples: - OTP verification for TAT security activation: - value: - otp: 123456 - action: secure - OTP verification for TAT security authorization: - value: - otp: 123456 - action: authorize - responses: - "200": - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/VerifyOtpResponse' - examples: - Tat Secured: - value: - status: Success - description: TAT Secured - Tat Unsecured: - value: - status: Success - description: TAT Unsecured - Tat Authorized: - value: - status: Success - description: TAT Authorized - "400": - description: Bad request - content: - application/json: - schema: - $ref: "#/components/schemas/ErrorResponse" - examples: - Missing Parameters: - value: - status: 400 - title: Missing Mandatory Parameter - detail: Required parameter {0} is missing. - Invalid Parameters: - value: - status: 400 - title: Invalid Parameter - detail: Required parameter {0} is invalid. - "401": - description: Unauthorized - content: - application/json: - schema: - $ref: "#/components/schemas/ErrorResponse" - examples: - Unauthorized: - value: - status: 401 - title: Unauthorized - detail: Invalid Access Token - "500": - description: Internal server error - content: - application/json: - schema: - $ref: "#/components/schemas/ErrorResponse" - example: - error: An unknown error has occurred components: schemas: unavailable: @@ -4896,108 +4662,3 @@ components: customerDataItem: type: string example: emailAddress - GenerateTatOutput: - type: object - properties: - uid: - type: string - description: >- - An uid IS A unique identifier THAT is associated with the - user. - recipient: - type: string - description: >- - A recipient IS A unique identifier THAT is associated with the - TAT owner. - key: - type: string - description: >- - A key IS a 32 character string THAT uniquely identifies the - OTP session. - EmailPreApprovedResponse: - type: object - description: >- - AN EmailPreApprovedResponse IS AN object THAT represents the response of - email pre-approval check. - properties: - status: - type: string - description: >- - A status IS A boolean THAT indicates that the provided email address - is pre-approved by the calling client app/web. - example: Success - description: - type: string - description: >- - A description IS A string THAT provides additional information - relating to the aprroval result - example: TAT Secured - EmailNotPreApprovedResponse: - type: object - description: >- - EmailNotPreApprovedResponse IS AN object THAT represents the response of - email pre-approval check. - properties: - uid: - type: string - description: A uid IS A unique identifier THAT is associated with the user. - example: 7594f3ee-cd3d-40a3-8e82-73b90d16c481 - recipient: - type: string - description: >- - A recipient IS A unique identifier THAT is associated with the TAT - owner. - example: xxxxxx.user@gmail.com - key: - type: string - description: >- - A key IS a 32 character string THAT uniquely identifies the OTP - session. - example: 123456789123456789123456789abcde - description: - type: string - description: >- - A description IS A string THAT describes the reason why the email is - not pre-approved. - example: OTP Sent - ActivateAgoRequest: - type: object - properties: - emailAddress: - type: string - format: email - example: stasjo@htm.nl - VerifyOtpRequest: - type: object - properties: - emailAddress: - type: string - example: 123456 - action: - type: string - example: secure - VerifyOtpResponse: - type: object - properties: - status: - type: string - example: Success - description: - type: string - example: TAT Secured - ErrorResponse: - description: Default response when an invalid request has been sent - type: object - properties: - status: - type: integer - description: >- - A status IS An integer that represents the HTTP status code of the - response. - example: 400 - title: - type: string - description: A title IS A string that provides a brief summary of the error. - detail: - type: string - description: A detail IS A string that provides more details about the error. \ No newline at end of file diff --git a/src/openapi/customers/SE-tat-security.yaml b/src/openapi/customers/SE-tat-security.yaml new file mode 100644 index 0000000..1cb6920 --- /dev/null +++ b/src/openapi/customers/SE-tat-security.yaml @@ -0,0 +1,341 @@ +openapi: 3.0.1 +info: + title: Service Engine APIs for TAT security + description: >- + Service Engine APIs for TAT security. These are NOT the raw GBO APIs to access TAT security at GBO directly. + To be used by touch points to get secure a TAT. + version: "2.0" +servers: + - url: https://services.acc.api.htm.nl/abt/touchpoint/2.0 +tags: + - name: TAT Security +paths: + /tokens/securetoken: + parameters: + - name: X-HTM-JWT-AUTH-HEADER + in: header + schema: + type: string + example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c + required: false + description: The JWT of a customer in case of touchpoint were customer logs in themselves + - name: X-HTM-CUSTOMER-PROFILE-ID-HEADER + in: header + schema: + type: integer + example: 323 + required: false + description: The id of the customer Profile + - name: X-HTM-ROLE-HEADER + in: header + schema: + type: string + example: Customer + required: false + description: The role of the HTM employee in the case of the SMP + post: + tags: + - TAT Security + summary: Request additional OV-pas security for a token either in profile or anonymous. + description: Request additional OV-pas security for a token either in profile or anonymous + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/SecureTokenRequest" + examples: + With customer account: + value: + ovPayTokenId: 42 + emailAddress: stasjo@htm.nl + Without customer account: + value: + xtat: 62914b49-2c7f-437f-b4b0-2ad61a9f902d + emailAddress: stasjo@htm.nl + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: "#/components/schemas/EmailNotPreApprovedResponse" + example: + uid: 7594f3ee-cd3d-40a3-8e82-73b90d16c481 + recipient: xxxxxx.user@gmail.com + key: 123456789123456789123456789abcde + description: OTP Sent + "400": + description: Bad Request + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + examples: + Missing Parameters: + value: + status: 400 + title: Missing Mandatory Parameter + detail: Required parameter {0} is missing. + Invalid Parameters: + value: + status: 400 + title: Invalid Parameter + detail: Required parameter {0} is invalid. + "401": + description: Unauthorized + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + examples: + Unauthorized: + value: + status: 401 + title: Unauthorized + detail: Invalid Access Token + "404": + description: Not found + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + examples: + TAT not found: + value: + status: 404 + title: Not Found + detail: TAT Account Not Found + "409": + description: Conflict + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + examples: + TAT Already Secured: + value: + status: 409 + title: Conflict + detail: TAT Already Secured + "500": + description: Internal server error + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + example: + error: An unknown error has occurred + /customers/verifyotp: + parameters: + - name: X-HTM-JWT-AUTH-HEADER + in: header + schema: + type: string + example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c + required: false + description: The JWT of a customer in case of touchpoint were customer logs in themselves + - name: X-HTM-CUSTOMER-PROFILE-ID-HEADER + in: header + schema: + type: integer + example: 323 + required: false + description: The id of the customer Profile + - name: X-HTM-ROLE-HEADER + in: header + schema: + type: string + example: Customer + required: false + description: The role of the HTM employee in the case of the SMP + post: + tags: + - TAT Security + summary: Submit an OTP for a triggered OTP flow. + description: | + Submit an OTP for a triggered OTP flow. This can either be result of an AGO activation, or + result of an AGO authorization flow. Since the backoffice behaves slightly different depending + on which use case is executed, the calling TP needs to provide an `action` in the request body. + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/VerifyOtpRequest" + examples: + OTP verification for TAT security activation for token in customer account: + value: + ovPayTokenId: 42 + otp: 123456 + action: secure + OTP verification for TAT security authorization for anonymous token: + value: + xtat: 0f0defe8-828c-48e5-97e5-26d1d0179ef0 + otp: 123456 + action: authorize + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/VerifyOtpResponse' + examples: + Tat Secured: + value: + status: Success + description: TAT Secured + Tat Unsecured: + value: + status: Success + description: TAT Unsecured + Tat Authorized: + value: + status: Success + description: TAT Authorized + "400": + description: Bad request + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + examples: + Missing Parameters: + value: + status: 400 + title: Missing Mandatory Parameter + detail: Required parameter {0} is missing. + Invalid Parameters: + value: + status: 400 + title: Invalid Parameter + detail: Required parameter {0} is invalid. + "401": + description: Unauthorized + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + examples: + Unauthorized: + value: + status: 401 + title: Unauthorized + detail: Invalid Access Token + "500": + description: Internal server error + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + example: + error: An unknown error has occurred +components: + schemas: + unavailable: + type: object + GenerateTatOutput: + type: object + properties: + uid: + type: string + description: >- + An uid IS A unique identifier THAT is associated with the + user. + recipient: + type: string + description: >- + A recipient IS A unique identifier THAT is associated with the + TAT owner. + key: + type: string + description: >- + A key IS a 32 character string THAT uniquely identifies the + OTP session. + EmailNotPreApprovedResponse: + type: object + description: >- + EmailNotPreApprovedResponse IS AN object THAT represents the response of + email pre-approval check. + properties: + uid: + type: string + description: A uid IS A unique identifier THAT is associated with the user. + example: 7594f3ee-cd3d-40a3-8e82-73b90d16c481 + recipient: + type: string + description: >- + A recipient IS A unique identifier THAT is associated with the TAT + owner. + example: xxxxxx.user@gmail.com + key: + type: string + description: >- + A key IS a 32 character string THAT uniquely identifies the OTP + session. + example: 123456789123456789123456789abcde + description: + type: string + description: >- + A description IS A string THAT describes the reason why the email is + not pre-approved. + example: OTP Sent + SecureTokenRequest: + type: object + properties: + ovPayTokenId: + type: integer + example: 42 + xtat: + type: string + format: uuid + example: 6134db53-9ae5-41d1-a343-36656b60b510 + emailAddress: + type: string + format: email + example: stasjo@htm.nl + required: + - ovPayTokenId + VerifyOtpRequest: + type: object + properties: + ovPayTokenId: + type: integer + example: 42 + xtat: + type: string + format: uuid + example: f3474452-e1d4-428c-b366-e5ad5965eb8c + otp: + type: string + example: 123456 + action: + type: string + example: secure + required: + - otp + - action + VerifyOtpResponse: + type: object + properties: + status: + type: string + example: Success + description: + type: string + example: TAT Secured + ErrorResponse: + description: Default response when an invalid request has been sent + type: object + properties: + status: + type: integer + description: >- + A status IS An integer that represents the HTTP status code of the + response. + example: 400 + title: + type: string + description: A title IS A string that provides a brief summary of the error. + detail: + type: string + description: A detail IS A string that provides more details about the error. \ No newline at end of file From 1f0481119c38bb42848ca243c5472b78082a2d19 Mon Sep 17 00:00:00 2001 From: "b.boterman@htm.nl" Date: Thu, 18 Jun 2026 16:04:41 +0200 Subject: [PATCH 9/9] OVPAY-2485 - Typo in url. --- src/openapi/customers/SE-tat-security.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openapi/customers/SE-tat-security.yaml b/src/openapi/customers/SE-tat-security.yaml index 1cb6920..3c635f0 100644 --- a/src/openapi/customers/SE-tat-security.yaml +++ b/src/openapi/customers/SE-tat-security.yaml @@ -125,7 +125,7 @@ paths: $ref: "#/components/schemas/ErrorResponse" example: error: An unknown error has occurred - /customers/verifyotp: + /tokens/verifyotp: parameters: - name: X-HTM-JWT-AUTH-HEADER in: header