Compare commits
80 Commits
trial-impl
...
develop
| Author | SHA1 | Date | |
|---|---|---|---|
| b6a490c979 | |||
|
|
1ac734de96 | ||
|
|
c692cd45ea | ||
|
|
0f2eaed9dd | ||
| 11ea8f5fea | |||
| e52fde1bb3 | |||
| 1761c662e7 | |||
|
|
6a0e5a5fba | ||
|
|
7953e035bb | ||
|
|
3c4ca6e00c | ||
|
|
f87baaca06 | ||
| 257f8f939b | |||
| c1bb52277e | |||
| e79ac51966 | |||
| c6b395a05b | |||
| 1d4fbf5004 | |||
|
|
8eed2a9dd6 | ||
|
|
5e255b7bac | ||
|
|
e2f70a78af | ||
|
|
ee0147b963 | ||
| 0a8a706675 | |||
| d42236dafc | |||
| 1aae9729b2 | |||
| f7975ed5a1 | |||
| f0c216be9b | |||
| 3db0d113a0 | |||
| f4e7bd9385 | |||
| c2a6b1c9c2 | |||
|
|
17f52cd914 | ||
| a493694021 | |||
| 96fd6341b0 | |||
| f1022c0d8d | |||
| 5b3264d9cd | |||
|
|
3d387e451b | ||
|
|
851f60d665 | ||
|
|
0987cedb4f | ||
| 23dd83fac9 | |||
| a637cfb4f2 | |||
| 42ff41baea | |||
| 699c633a4e | |||
| 95bc19d7ff | |||
| 8e77863480 | |||
| 07e1dc91e3 | |||
| 75531b4fdc | |||
| 00a98a6178 | |||
| 937a0323ed | |||
| ebee1178ef | |||
| 6e37b7c4fe | |||
| a0ebde6ae2 | |||
| 1f8e8f1381 | |||
| 1f0481119c | |||
| 3d2885f2b8 | |||
| 280d3b1fcd | |||
| f28a797b6b | |||
| 87d8f7df58 | |||
| 30e8860a39 | |||
| d18afcae8c | |||
| eb03aa04e6 | |||
| aca160f65c | |||
| 3f090c76b6 | |||
| 25788e0976 | |||
|
|
90bb7c11b5 | ||
|
|
0c23571085 | ||
|
|
f1a0850871 | ||
|
|
cc8881b9d5 | ||
|
|
d484acbc69 | ||
| e5a0b52d1b | |||
| 89833680db | |||
|
|
ff225ea00c | ||
|
|
bd870d0fa8 | ||
| 531eaa2ff6 | |||
|
|
7173bd3727 | ||
|
|
a09ad1ad08 | ||
|
|
f198c1633b | ||
| 5f7893b057 | |||
|
|
383d43122b | ||
|
|
f8010560cc | ||
|
|
69908f58b0 | ||
|
|
9fb20a491f | ||
|
|
2fca37628e |
0
src/AGO_Examples_20260904.curl
Normal file
0
src/AGO_Examples_20260904.curl
Normal file
Binary file not shown.
@ -215,8 +215,13 @@ public class ABTProductsPUTGenerator {
|
|||||||
}
|
}
|
||||||
case "paymentMoment" -> {
|
case "paymentMoment" -> {
|
||||||
LOGGER.info("Rewriting paymentMoment to paymentMomentId...");
|
LOGGER.info("Rewriting paymentMoment to paymentMomentId...");
|
||||||
Long paymentMomentId = jsonField.getValue().get("paymentMomentId").asLong();
|
if (jsonField.getValue().get("paymentMomentId").isNull()) {
|
||||||
((ObjectNode)newJsonNode).put("paymentMomentId", paymentMomentId);
|
LOGGER.info("Rewriting null paymentMomentId...");
|
||||||
|
((ObjectNode)newJsonNode).putRawValue("paymentMomentId", null);
|
||||||
|
} else {
|
||||||
|
Long paymentMomentId = jsonField.getValue().get("paymentMomentId").asLong();
|
||||||
|
((ObjectNode)newJsonNode).put("paymentMomentId", paymentMomentId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
case "requiredCustomerLevel" -> {
|
case "requiredCustomerLevel" -> {
|
||||||
LOGGER.info("Rewriting requiredCustomerLevel to requiredCustomerLevelId...");
|
LOGGER.info("Rewriting requiredCustomerLevel to requiredCustomerLevelId...");
|
||||||
|
|||||||
1845
src/openapi/container/abt-container-notifications.yaml
Normal file
1845
src/openapi/container/abt-container-notifications.yaml
Normal file
File diff suppressed because it is too large
Load Diff
417
src/openapi/container/abt-container-tokens.yaml
Normal file
417
src/openapi/container/abt-container-tokens.yaml
Normal file
@ -0,0 +1,417 @@
|
|||||||
|
openapi: 3.0.3
|
||||||
|
info:
|
||||||
|
title: Integration layer APIs for token storage for ABT
|
||||||
|
description: >-
|
||||||
|
APIs that give business processes access to the security and authorization state of a token within the scope of HTM. In the backend this is connected to a container which handles the accessToken en refreshToken management for an OVpas as given by GBO.
|
||||||
|
version: "1.0"
|
||||||
|
servers:
|
||||||
|
- url: https://services.acc.api.htm.nl/abt/containertokens/1.0
|
||||||
|
security:
|
||||||
|
- oAuthSample: [profile]
|
||||||
|
tags:
|
||||||
|
- name: securitytokens
|
||||||
|
paths:
|
||||||
|
/securitytokens:
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- securitytokens
|
||||||
|
summary: Create a new security token entry in the vault
|
||||||
|
description: Create a new security token entry in the vault, if the customerProfileId has been supplied create in the customerToken DB otherwise in the AnonymousToken DB
|
||||||
|
requestBody:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/CreateSecurityTokenBody"
|
||||||
|
examples:
|
||||||
|
token details:
|
||||||
|
value:
|
||||||
|
{
|
||||||
|
"xTat": "cf694905-7f76-4799-b0bc-490716921323",
|
||||||
|
"otpKey": "123456789123456789123456789abcde",
|
||||||
|
"customerProfileId": 12314
|
||||||
|
}
|
||||||
|
responses:
|
||||||
|
"201":
|
||||||
|
description: Created
|
||||||
|
"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 exists:
|
||||||
|
value:
|
||||||
|
status: 409
|
||||||
|
title: Conflict
|
||||||
|
detail: Security Token already exists
|
||||||
|
"500":
|
||||||
|
description: Internal server error
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/ErrorResponse"
|
||||||
|
examples:
|
||||||
|
Internal Server Error:
|
||||||
|
value:
|
||||||
|
status: 500
|
||||||
|
title: Internal Server Error
|
||||||
|
detail: An unknown error has occurred
|
||||||
|
/securitytokens/{xTat}/status:
|
||||||
|
parameters:
|
||||||
|
- name: xTat
|
||||||
|
in: path
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
example: 85dbeacc-b9aa-4d5b-bdec-9319010c597f
|
||||||
|
required: true
|
||||||
|
description: The xTat of the OVpastoken for which the status needs to be checked
|
||||||
|
- name: customerProfileId
|
||||||
|
in: query
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
example: 323
|
||||||
|
required: false
|
||||||
|
description: The id of the customer Profile for which the request is being done, if customer has identified themselves
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- securitytokens
|
||||||
|
summary: Request the security and authorization status of an OV pas token
|
||||||
|
description: Request the security and authorization status of an OV pas token, if the customerProfileId has been supplied look in the customerToken DB otherwise check the AnonymousToken DB.
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/SecurityTokenStatusResponse"
|
||||||
|
examples:
|
||||||
|
Not secured and not authorized :
|
||||||
|
summary: Not secured, not authorized
|
||||||
|
value:
|
||||||
|
{
|
||||||
|
"isAuthorized": false,
|
||||||
|
"isSecured": false
|
||||||
|
}
|
||||||
|
Secured and not authorized :
|
||||||
|
summary: Secured, not authorized
|
||||||
|
value:
|
||||||
|
{
|
||||||
|
"isAuthorized": false,
|
||||||
|
"isSecured": true
|
||||||
|
}
|
||||||
|
Secured and authorized :
|
||||||
|
summary: Secured and authorized
|
||||||
|
value:
|
||||||
|
{
|
||||||
|
"isAuthorized": true,
|
||||||
|
"isSecured": true
|
||||||
|
}
|
||||||
|
"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
|
||||||
|
"500":
|
||||||
|
description: Internal server error
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/ErrorResponse"
|
||||||
|
examples:
|
||||||
|
Internal Server Error:
|
||||||
|
value:
|
||||||
|
status: 500
|
||||||
|
title: Internal Server Error
|
||||||
|
detail: An unknown error has occurred
|
||||||
|
/securitytokens/{xTat}:
|
||||||
|
parameters:
|
||||||
|
- name: xTat
|
||||||
|
in: path
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
example: uuid
|
||||||
|
required: true
|
||||||
|
description: The xTat of the ovPastoken for which the status needs to be checked
|
||||||
|
- name: customerProfileId
|
||||||
|
in: query
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
example: 323
|
||||||
|
required: false
|
||||||
|
description: The id of the customer Profile for which the request is being done, if customer has identified themselves
|
||||||
|
patch:
|
||||||
|
tags:
|
||||||
|
- securitytokens
|
||||||
|
summary: Validate the supplied OTP and secure and/or authorize the token
|
||||||
|
description: Validate the supplied OTP and secure and/or authorize the token if the customerProfileId has been supplied look in the customerToken DB otherwise check the AnonymousToken DB.
|
||||||
|
requestBody:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/SecurityValidateTokenBody"
|
||||||
|
examples:
|
||||||
|
token:
|
||||||
|
value:
|
||||||
|
{
|
||||||
|
"otp": "123456"
|
||||||
|
}
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/SecurityTokenStatusResponse"
|
||||||
|
examples:
|
||||||
|
Not secured and not authorized :
|
||||||
|
summary: Not secured, not authorized
|
||||||
|
value:
|
||||||
|
{
|
||||||
|
"isAuthorized": false,
|
||||||
|
"isSecured": false
|
||||||
|
}
|
||||||
|
Secured and not authorized :
|
||||||
|
summary: Secured, not authorized
|
||||||
|
value:
|
||||||
|
{
|
||||||
|
"isAuthorized": false,
|
||||||
|
"isSecured": true
|
||||||
|
}
|
||||||
|
Secured and authorized :
|
||||||
|
summary: Secured and authorized
|
||||||
|
value:
|
||||||
|
{
|
||||||
|
"isAuthorized": true,
|
||||||
|
"isSecured": true
|
||||||
|
}
|
||||||
|
"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.
|
||||||
|
"422":
|
||||||
|
description: Unprocessable Entity
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/ErrorResponse"
|
||||||
|
examples:
|
||||||
|
Validation failed:
|
||||||
|
value:
|
||||||
|
status: 422
|
||||||
|
title: OTP validation failed
|
||||||
|
detail: The supplied OTP could not be validated
|
||||||
|
"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
|
||||||
|
"500":
|
||||||
|
description: Internal server error
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/ErrorResponse"
|
||||||
|
examples:
|
||||||
|
Internal Server Error:
|
||||||
|
value:
|
||||||
|
status: 500
|
||||||
|
title: Internal Server Error
|
||||||
|
detail: An unknown error has occurred
|
||||||
|
delete:
|
||||||
|
tags:
|
||||||
|
- securitytokens
|
||||||
|
summary: Delete the authorization for HTM for an ovpaytoken
|
||||||
|
description: Delete the authorization for HTM for an ovpaytoken if the customerProfileId has been supplied look in the customerToken DB otherwise check the AnonymousToken DB.
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/SecurityTokenStatusResponse"
|
||||||
|
example:
|
||||||
|
{}
|
||||||
|
components:
|
||||||
|
securitySchemes:
|
||||||
|
oAuthSample:
|
||||||
|
type: oauth2
|
||||||
|
description: This API uses OAuth 2 with the clientCredentials flow. [More info](https://api.example.com/docs/auth)
|
||||||
|
flows:
|
||||||
|
clientCredentials: # <---- OAuth flow( clientCredentials)
|
||||||
|
tokenUrl: https://identity.{env}.api.htm.nl/oauth2/token
|
||||||
|
scopes:
|
||||||
|
profile: "Access user profile"
|
||||||
|
schemas:
|
||||||
|
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.
|
||||||
|
CreateSecurityTokenBody:
|
||||||
|
description: Body for when the a new security token entry is created
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- xTat
|
||||||
|
- otpKey
|
||||||
|
properties:
|
||||||
|
xTat:
|
||||||
|
type : string
|
||||||
|
description: >-
|
||||||
|
Unique identifier for the GBO transit account
|
||||||
|
example: 03071794-482a-4168-b60f-84669a9e6a76
|
||||||
|
otpKey:
|
||||||
|
type : string
|
||||||
|
description: >-
|
||||||
|
Key used to validate the OTP at GBO
|
||||||
|
example: 123456789123456789123456789abcde
|
||||||
|
customerProfileId:
|
||||||
|
type : integer
|
||||||
|
description: >-
|
||||||
|
CustomerProfileId of the account requesting security or giving authorization
|
||||||
|
example: 123456
|
||||||
|
SecurityTokenStatusResponse:
|
||||||
|
description: Response for when the status of a token is requested
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
isSecured:
|
||||||
|
type: boolean
|
||||||
|
description: >-
|
||||||
|
Is the OVpas secured according to the GBO
|
||||||
|
example: false
|
||||||
|
isAuthorized:
|
||||||
|
type: boolean
|
||||||
|
description: >-
|
||||||
|
Does HTM have the authorization to access the secured the data of the OVpas
|
||||||
|
example: false
|
||||||
|
SecurityValidateTokenBody:
|
||||||
|
description: Body for when the a token entry is validated
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- otp
|
||||||
|
properties:
|
||||||
|
otp:
|
||||||
|
type : string
|
||||||
|
description: >-
|
||||||
|
OTP to be used to secure the token and retrieve the JWT at GBO
|
||||||
|
example: 123456
|
||||||
@ -45,12 +45,36 @@ paths:
|
|||||||
"contractStatus":
|
"contractStatus":
|
||||||
{ "contractStatusId": 2, "name": "active" },
|
{ "contractStatusId": 2, "name": "active" },
|
||||||
"productId": 1,
|
"productId": 1,
|
||||||
"productName": "HTM Maand 20% korting",
|
"productName": "HTM Maand 20% korting doorlopend",
|
||||||
"termDuration": "P0Y1M0D",
|
"termDuration": "P1M",
|
||||||
"billingDay": 15,
|
"billingDay": 15,
|
||||||
"highestInvoiceTerm": 1,
|
"highestInvoiceTerm": 1,
|
||||||
"created": "2024-08-01 15:01:00.000",
|
"created": "2024-08-01T15:01:00.000Z",
|
||||||
"ovPayTokenId": 1337,
|
"ovPayTokenId": 1337,
|
||||||
|
"contractVersions": [
|
||||||
|
{
|
||||||
|
"contractVersionId": 1,
|
||||||
|
"termsAndConditions": "https://www.htm.nl/reisproducten/productvoorwaarden/htm-maandkorting/",
|
||||||
|
"productId": 1,
|
||||||
|
"productName": "HTM Maand 20% korting doorlopend",
|
||||||
|
"taxCode": "V9",
|
||||||
|
"taxPercentage": 9,
|
||||||
|
"termAmountInclTax": 400,
|
||||||
|
"start": "2024-08-01T15:01:00.000Z",
|
||||||
|
"end": "2025-01-01T03:00:00.000Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"contractVersionId": 2,
|
||||||
|
"termsAndConditions": "https://www.htm.nl/reisproducten/productvoorwaarden/htm-maandkorting/",
|
||||||
|
"productId": 1,
|
||||||
|
"productName": "HTM Maand 20% korting doorlopend",
|
||||||
|
"taxCode": "V9",
|
||||||
|
"taxPercentage": 9,
|
||||||
|
"termAmountInclTax": 500,
|
||||||
|
"start": "2025-01-01T03:00:00.000Z",
|
||||||
|
"end": null
|
||||||
|
}
|
||||||
|
],
|
||||||
"_links":
|
"_links":
|
||||||
{
|
{
|
||||||
"get_token":
|
"get_token":
|
||||||
@ -68,14 +92,38 @@ paths:
|
|||||||
"orderLineId": "42f68042-908f-41f4-9d9b-4cab843ff0e8",
|
"orderLineId": "42f68042-908f-41f4-9d9b-4cab843ff0e8",
|
||||||
"touchpointId": 2,
|
"touchpointId": 2,
|
||||||
"contractStatus":
|
"contractStatus":
|
||||||
{ "contractStatusId": 1, "name": "new" },
|
{ "contractStatusId": 6, "name": "pending cancellation" },
|
||||||
"productId": 1,
|
"productId": 1,
|
||||||
"productName": "HTM Maand 20% korting",
|
"productName": "HTM 20% Korting doorlopend",
|
||||||
"termDuration": "P0Y1M0D",
|
"termDuration": "P1M",
|
||||||
"billingDay": 15,
|
"billingDay": 15,
|
||||||
"highestInvoiceTerm": 1,
|
"highestInvoiceTerm": 1,
|
||||||
"created": "2024-08-01 15:01:00.000",
|
"created": "2024-08-01T15:01:00.000Z",
|
||||||
"ovPayTokenId": 1338,
|
"ovPayTokenId": 1338,
|
||||||
|
"contractVersions": [
|
||||||
|
{
|
||||||
|
"contractVersionId": 1,
|
||||||
|
"termsAndConditions": "https://www.htm.nl/reisproducten/productvoorwaarden/htm-maandkorting/",
|
||||||
|
"productId": 1,
|
||||||
|
"productName": "HTM 20% Korting doorlopend",
|
||||||
|
"taxCode": "V9",
|
||||||
|
"taxPercentage": 9,
|
||||||
|
"termAmountInclTax": 400,
|
||||||
|
"start": "2024-08-01T15:01:00.000Z",
|
||||||
|
"end": "2025-01-01T03:00:00.000Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"contractVersionId": 2,
|
||||||
|
"termsAndConditions": "https://www.htm.nl/reisproducten/productvoorwaarden/htm-maandkorting/",
|
||||||
|
"productId": 1,
|
||||||
|
"productName": "HTM 20% Korting doorlopend",
|
||||||
|
"taxCode": "V9",
|
||||||
|
"taxPercentage": 9,
|
||||||
|
"termAmountInclTax": 500,
|
||||||
|
"start": "2025-01-01T03:00:00.000Z",
|
||||||
|
"end": "2025-02-01T03:00:00.000Z"
|
||||||
|
}
|
||||||
|
],
|
||||||
"_links":
|
"_links":
|
||||||
{
|
{
|
||||||
"get_token":
|
"get_token":
|
||||||
@ -154,8 +202,8 @@ paths:
|
|||||||
"contractStatus":
|
"contractStatus":
|
||||||
{ "contractStatusId": 2, "name": "active" },
|
{ "contractStatusId": 2, "name": "active" },
|
||||||
"productId": 1,
|
"productId": 1,
|
||||||
"productName": "HTM Maand 20% korting",
|
"productName": "HTM 20% Korting doorlopend",
|
||||||
"termDuration": "P0Y1M0D",
|
"termDuration": "P1M",
|
||||||
"billingDay": 15,
|
"billingDay": 15,
|
||||||
"highestInvoiceTerm": 1,
|
"highestInvoiceTerm": 1,
|
||||||
"ovPayTokenId": 1337,
|
"ovPayTokenId": 1337,
|
||||||
@ -165,22 +213,22 @@ paths:
|
|||||||
"contractVersionId": 1,
|
"contractVersionId": 1,
|
||||||
"termsAndConditions": "https://www.htm.nl/reisproducten/productvoorwaarden/htm-maandkorting/",
|
"termsAndConditions": "https://www.htm.nl/reisproducten/productvoorwaarden/htm-maandkorting/",
|
||||||
"productId": 1,
|
"productId": 1,
|
||||||
"productName": "HTM Maand 20% korting",
|
"productName": "HTM 20% Korting doorlopend",
|
||||||
"taxCode": "V9",
|
"taxCode": "V9",
|
||||||
"taxPercentage": 9.0,
|
"taxPercentage": 9.0,
|
||||||
"termAmountInclTax": 400,
|
"termAmountInclTax": 400,
|
||||||
"start": "2024-07-04 15:01:00.000",
|
"start": "2024-08-01T15:01:00.000Z",
|
||||||
"end": "2024-12-31 15:01:00.000",
|
"end": "2025-01-01T03:00:00.000Z",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"contractVersionId": 2,
|
"contractVersionId": 2,
|
||||||
"termsAndConditions": "https://www.htm.nl/reisproducten/productvoorwaarden/htm-maandkorting/",
|
"termsAndConditions": "https://www.htm.nl/reisproducten/productvoorwaarden/htm-maandkorting/",
|
||||||
"productId": 1,
|
"productId": 1,
|
||||||
"productName": "HTM Maand 20% korting",
|
"productName": "HTM 20% Korting doorlopend",
|
||||||
"taxCode": "V9",
|
"taxCode": "V9",
|
||||||
"taxPercentage": 9.0,
|
"taxPercentage": 9.0,
|
||||||
"termAmountInclTax": 400,
|
"termAmountInclTax": 400,
|
||||||
"start": "2025-01-01 15:01:00.000",
|
"start": "2025-01-01T03:00:00.000Z",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"contractActions":
|
"contractActions":
|
||||||
@ -190,7 +238,7 @@ paths:
|
|||||||
"actionType":
|
"actionType":
|
||||||
{ "actionTypeId": 1, "name": "create" },
|
{ "actionTypeId": 1, "name": "create" },
|
||||||
"user": "subid123456",
|
"user": "subid123456",
|
||||||
"timestamp": "2024-07-02 15:01:00.000",
|
"timestamp": "2024-07-02T15:01:00.000Z",
|
||||||
"details": "Contract created",
|
"details": "Contract created",
|
||||||
"correlationId": "976e7a4c-bf24-43d2-b444-55817556e7ee",
|
"correlationId": "976e7a4c-bf24-43d2-b444-55817556e7ee",
|
||||||
},
|
},
|
||||||
@ -199,7 +247,7 @@ paths:
|
|||||||
"actionType":
|
"actionType":
|
||||||
{ "actionTypeId": 2, "name": "change" },
|
{ "actionTypeId": 2, "name": "change" },
|
||||||
"user": "subid123456",
|
"user": "subid123456",
|
||||||
"timestamp": "2024-07-03 15:01:00.000",
|
"timestamp": "2024-07-03T15:01:00.000Z",
|
||||||
"details": "Contract changed",
|
"details": "Contract changed",
|
||||||
"correlationId": "e2462347-6749-4841-b42a-cf8de19ec727",
|
"correlationId": "e2462347-6749-4841-b42a-cf8de19ec727",
|
||||||
},
|
},
|
||||||
@ -211,8 +259,8 @@ paths:
|
|||||||
"externalReference": "F2024-0001",
|
"externalReference": "F2024-0001",
|
||||||
"term": 1,
|
"term": 1,
|
||||||
"invoiceDate": "2024-07-02",
|
"invoiceDate": "2024-07-02",
|
||||||
"created": "2024-07-02 15:01:00.000",
|
"created": "2024-07-02T15:01:00.000Z",
|
||||||
"updated": "2024-07-02 15:01:00.000",
|
"updated": "2024-07-02T15:01:00.000Z",
|
||||||
"state": "invoice_created",
|
"state": "invoice_created",
|
||||||
"data": "{json}",
|
"data": "{json}",
|
||||||
"isCredit": false,
|
"isCredit": false,
|
||||||
@ -270,8 +318,8 @@ paths:
|
|||||||
"externalReference": "F2024-0001",
|
"externalReference": "F2024-0001",
|
||||||
"term": 1,
|
"term": 1,
|
||||||
"invoiceDate": "2024-07-02",
|
"invoiceDate": "2024-07-02",
|
||||||
"created": "2024-07-02 15:01:34.000",
|
"created": "2024-07-02T15:01:34.000Z",
|
||||||
"updated": "2024-07-04 00:04:56.000",
|
"updated": "2024-07-04T00:04:56.000Z",
|
||||||
"state": "invoice_created",
|
"state": "invoice_created",
|
||||||
"public_link": "http://mijnfactuurinzien.nl/F2024-0001",
|
"public_link": "http://mijnfactuurinzien.nl/F2024-0001",
|
||||||
"isCredit": false,
|
"isCredit": false,
|
||||||
@ -282,8 +330,8 @@ paths:
|
|||||||
"externalReference": "F2024-0002",
|
"externalReference": "F2024-0002",
|
||||||
"term": 2,
|
"term": 2,
|
||||||
"invoiceDate": "2024-08-02",
|
"invoiceDate": "2024-08-02",
|
||||||
"created": "2024-08-02 15:01:34.000",
|
"created": "2024-08-02T15:01:34.000Z",
|
||||||
"updated": "2024-08-04 00:04:56.000",
|
"updated": "2024-08-04T00:04:56.000Z",
|
||||||
"state": "invoice_created",
|
"state": "invoice_created",
|
||||||
"public_link": "http://mijnfactuurinzien.nl/F2024-0002",
|
"public_link": "http://mijnfactuurinzien.nl/F2024-0002",
|
||||||
"isCredit": false,
|
"isCredit": false,
|
||||||
@ -328,8 +376,8 @@ paths:
|
|||||||
"cancellationMoment": "termBound",
|
"cancellationMoment": "termBound",
|
||||||
"termDuration": "P1M",
|
"termDuration": "P1M",
|
||||||
"billingDay": 18,
|
"billingDay": 18,
|
||||||
"cancellationFrom": "2024-08-10T00:00:00",
|
"cancellationFrom": "2024-08-10T00:00:00Z",
|
||||||
"cancellationUntil": "2026-08-10T00:00:00",
|
"cancellationUntil": "2026-08-10T00:00:00Z",
|
||||||
}
|
}
|
||||||
/contracts/{contractId}/cancellationvalidation:
|
/contracts/{contractId}/cancellationvalidation:
|
||||||
parameters:
|
parameters:
|
||||||
@ -382,7 +430,7 @@ paths:
|
|||||||
{
|
{
|
||||||
"validationResult": true,
|
"validationResult": true,
|
||||||
"validationMessage": "",
|
"validationMessage": "",
|
||||||
"end": "2024-08-10T03:59:59",
|
"end": "2024-08-10T03:59:59Z",
|
||||||
"refundAmount": 2489,
|
"refundAmount": 2489,
|
||||||
"refundMethods": ["creditInvoice", "iDeal"],
|
"refundMethods": ["creditInvoice", "iDeal"],
|
||||||
}
|
}
|
||||||
@ -451,7 +499,7 @@ paths:
|
|||||||
the refund amount and refund method.
|
the refund amount and refund method.
|
||||||
value:
|
value:
|
||||||
{
|
{
|
||||||
"end": "2024-08-10T03:59:59",
|
"end": "2024-08-10T03:59:59Z",
|
||||||
"refundAmount": 2489,
|
"refundAmount": 2489,
|
||||||
"refundMethod": "creditInvoice",
|
"refundMethod": "creditInvoice",
|
||||||
}
|
}
|
||||||
@ -516,8 +564,8 @@ paths:
|
|||||||
"taxCode": "V9",
|
"taxCode": "V9",
|
||||||
"taxPercentage": 9.0,
|
"taxPercentage": 9.0,
|
||||||
"termAmountInclTax": 400,
|
"termAmountInclTax": 400,
|
||||||
"start": "2024-07-04 15:01:00.000",
|
"start": "2024-07-04T15:01:00.000Z",
|
||||||
"end": "2024-12-31 15:01:00.000",
|
"end": "2024-12-31T15:01:00.000Z",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"contractVersionId": 2,
|
"contractVersionId": 2,
|
||||||
@ -527,7 +575,8 @@ paths:
|
|||||||
"taxCode": "V9",
|
"taxCode": "V9",
|
||||||
"taxPercentage": 9.0,
|
"taxPercentage": 9.0,
|
||||||
"termAmountInclTax": 400,
|
"termAmountInclTax": 400,
|
||||||
"start": "2025-01-01 15:01:00.000",
|
"start": "2025-01-01T15:01:00.000Z",
|
||||||
|
"end": null
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"contractActions":
|
"contractActions":
|
||||||
@ -537,7 +586,7 @@ paths:
|
|||||||
"actionType":
|
"actionType":
|
||||||
{ "actionTypeId": 1, "name": "create" },
|
{ "actionTypeId": 1, "name": "create" },
|
||||||
"user": "subid123456",
|
"user": "subid123456",
|
||||||
"timestamp": "2024-07-02 15:01:00.000",
|
"timestamp": "2024-07-02T15:01:00.000Z",
|
||||||
"details": "Contract created",
|
"details": "Contract created",
|
||||||
"correlationId": "976e7a4c-bf24-43d2-b444-55817556e7ee",
|
"correlationId": "976e7a4c-bf24-43d2-b444-55817556e7ee",
|
||||||
},
|
},
|
||||||
@ -546,7 +595,7 @@ paths:
|
|||||||
"actionType":
|
"actionType":
|
||||||
{ "actionTypeId": 2, "name": "change" },
|
{ "actionTypeId": 2, "name": "change" },
|
||||||
"user": "subid123456",
|
"user": "subid123456",
|
||||||
"timestamp": "2024-07-03 15:01:00.000",
|
"timestamp": "2024-07-03T15:01:00.000Z",
|
||||||
"details": "Contract changed",
|
"details": "Contract changed",
|
||||||
"correlationId": "e2462347-6749-4841-b42a-cf8de19ec727",
|
"correlationId": "e2462347-6749-4841-b42a-cf8de19ec727",
|
||||||
},
|
},
|
||||||
@ -558,8 +607,8 @@ paths:
|
|||||||
"externalReference": "F2024-0001",
|
"externalReference": "F2024-0001",
|
||||||
"term": 1,
|
"term": 1,
|
||||||
"invoiceDate": "2024-07-02",
|
"invoiceDate": "2024-07-02",
|
||||||
"created": "2024-07-02 15:01:00.000",
|
"created": "2024-07-02T15:01:00.000Z",
|
||||||
"updated": "2024-07-02 15:01:00.000",
|
"updated": "2024-07-02T15:01:00.000Z",
|
||||||
"state": "invoice_created",
|
"state": "invoice_created",
|
||||||
"data": "{json}",
|
"data": "{json}",
|
||||||
"isCredit": false,
|
"isCredit": false,
|
||||||
@ -682,7 +731,7 @@ paths:
|
|||||||
"termDuration": "P0Y1M0D",
|
"termDuration": "P0Y1M0D",
|
||||||
"billingDay": 15,
|
"billingDay": 15,
|
||||||
"highestInvoiceTerm": 1,
|
"highestInvoiceTerm": 1,
|
||||||
"created": "2024-08-01 15:01:00.000",
|
"created": "2024-08-01T15:01:00.000Z",
|
||||||
"ovPayTokenId": 1337,
|
"ovPayTokenId": 1337,
|
||||||
"contractVersions":
|
"contractVersions":
|
||||||
[
|
[
|
||||||
@ -781,7 +830,7 @@ paths:
|
|||||||
"termDuration": "P0Y1M0D",
|
"termDuration": "P0Y1M0D",
|
||||||
"billingDay": 15,
|
"billingDay": 15,
|
||||||
"highestInvoiceTerm": 1,
|
"highestInvoiceTerm": 1,
|
||||||
"created": "2024-08-01 15:01:00.000",
|
"created": "2024-08-01T15:01:00.000Z",
|
||||||
"ovPayTokenId": 1337,
|
"ovPayTokenId": 1337,
|
||||||
"contractVersions":
|
"contractVersions":
|
||||||
[
|
[
|
||||||
|
|||||||
@ -380,7 +380,7 @@ paths:
|
|||||||
type: string
|
type: string
|
||||||
example: Customer
|
example: Customer
|
||||||
required: false
|
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:
|
requestBody:
|
||||||
content:
|
content:
|
||||||
application/json:
|
application/json:
|
||||||
@ -415,7 +415,7 @@ paths:
|
|||||||
type: string
|
type: string
|
||||||
example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
|
example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
|
||||||
required: false
|
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
|
- name: X-HTM-CUSTOMER-PROFILE-ID-HEADER
|
||||||
in: header
|
in: header
|
||||||
schema:
|
schema:
|
||||||
@ -429,7 +429,7 @@ paths:
|
|||||||
type: string
|
type: string
|
||||||
example: Customer
|
example: Customer
|
||||||
required: false
|
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:
|
requestBody:
|
||||||
content:
|
content:
|
||||||
application/json:
|
application/json:
|
||||||
@ -464,7 +464,7 @@ paths:
|
|||||||
type: string
|
type: string
|
||||||
example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
|
example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
|
||||||
required: false
|
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
|
- name: X-HTM-CUSTOMER-PROFILE-ID-HEADER
|
||||||
in: header
|
in: header
|
||||||
schema:
|
schema:
|
||||||
@ -478,7 +478,7 @@ paths:
|
|||||||
type: string
|
type: string
|
||||||
example: Customer
|
example: Customer
|
||||||
required: false
|
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
|
- name: customerPreferenceId
|
||||||
in: path
|
in: path
|
||||||
required: true
|
required: true
|
||||||
@ -519,7 +519,7 @@ paths:
|
|||||||
type: string
|
type: string
|
||||||
example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
|
example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
|
||||||
required: false
|
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
|
- name: X-HTM-CUSTOMER-PROFILE-ID-HEADER
|
||||||
in: header
|
in: header
|
||||||
schema:
|
schema:
|
||||||
@ -533,8 +533,8 @@ paths:
|
|||||||
type: string
|
type: string
|
||||||
example: Customer
|
example: Customer
|
||||||
required: false
|
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:
|
requestBody:
|
||||||
content:
|
content:
|
||||||
application/json:
|
application/json:
|
||||||
@ -575,7 +575,7 @@ paths:
|
|||||||
type: string
|
type: string
|
||||||
example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
|
example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
|
||||||
required: false
|
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
|
- name: X-HTM-CUSTOMER-PROFILE-ID-HEADER
|
||||||
in: header
|
in: header
|
||||||
schema:
|
schema:
|
||||||
@ -589,7 +589,7 @@ paths:
|
|||||||
type: string
|
type: string
|
||||||
example: Customer
|
example: Customer
|
||||||
required: false
|
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
|
- name: addressId
|
||||||
in: path
|
in: path
|
||||||
required: true
|
required: true
|
||||||
@ -634,7 +634,7 @@ paths:
|
|||||||
type: string
|
type: string
|
||||||
example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
|
example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
|
||||||
required: false
|
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
|
- name: X-HTM-CUSTOMER-PROFILE-ID-HEADER
|
||||||
in: header
|
in: header
|
||||||
schema:
|
schema:
|
||||||
@ -648,7 +648,7 @@ paths:
|
|||||||
type: string
|
type: string
|
||||||
example: Customer
|
example: Customer
|
||||||
required: false
|
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
|
- name: addressId
|
||||||
in: path
|
in: path
|
||||||
required: true
|
required: true
|
||||||
@ -669,14 +669,14 @@ paths:
|
|||||||
summary: Add a customer phone
|
summary: Add a customer phone
|
||||||
description: >-
|
description: >-
|
||||||
|
|
||||||
parameters:
|
parameters:
|
||||||
- name: X-HTM-JWT-AUTH-HEADER
|
- name: X-HTM-JWT-AUTH-HEADER
|
||||||
in: header
|
in: header
|
||||||
schema:
|
schema:
|
||||||
type: string
|
type: string
|
||||||
example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
|
example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
|
||||||
required: false
|
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
|
- name: X-HTM-CUSTOMER-PROFILE-ID-HEADER
|
||||||
in: header
|
in: header
|
||||||
schema:
|
schema:
|
||||||
@ -690,7 +690,7 @@ paths:
|
|||||||
type: string
|
type: string
|
||||||
example: Customer
|
example: Customer
|
||||||
required: false
|
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:
|
requestBody:
|
||||||
content:
|
content:
|
||||||
application/json:
|
application/json:
|
||||||
@ -728,7 +728,7 @@ paths:
|
|||||||
type: string
|
type: string
|
||||||
example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
|
example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
|
||||||
required: false
|
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
|
- name: X-HTM-CUSTOMER-PROFILE-ID-HEADER
|
||||||
in: header
|
in: header
|
||||||
schema:
|
schema:
|
||||||
@ -742,7 +742,7 @@ paths:
|
|||||||
type: string
|
type: string
|
||||||
example: Customer
|
example: Customer
|
||||||
required: false
|
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
|
- name: phoneId
|
||||||
in: path
|
in: path
|
||||||
required: true
|
required: true
|
||||||
@ -754,7 +754,7 @@ paths:
|
|||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
$ref: "#/components/schemas/phoneEntity"
|
$ref: "#/components/schemas/phoneEntity"
|
||||||
examples:
|
examples:
|
||||||
updateFullPhoneEntity:
|
updateFullPhoneEntity:
|
||||||
value:
|
value:
|
||||||
phone:
|
phone:
|
||||||
@ -789,7 +789,7 @@ paths:
|
|||||||
type: string
|
type: string
|
||||||
example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
|
example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
|
||||||
required: false
|
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
|
- name: X-HTM-CUSTOMER-PROFILE-ID-HEADER
|
||||||
in: header
|
in: header
|
||||||
schema:
|
schema:
|
||||||
@ -803,7 +803,7 @@ paths:
|
|||||||
type: string
|
type: string
|
||||||
example: Customer
|
example: Customer
|
||||||
required: false
|
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
|
- name: phoneId
|
||||||
in: path
|
in: path
|
||||||
required: true
|
required: true
|
||||||
@ -816,7 +816,7 @@ paths:
|
|||||||
content:
|
content:
|
||||||
application/json: {}
|
application/json: {}
|
||||||
x-auth-type: Application & Application User
|
x-auth-type: Application & Application User
|
||||||
x-throttling-tier: Unlimited
|
x-throttling-tier: Unlimited
|
||||||
/customers/billinginformations:
|
/customers/billinginformations:
|
||||||
get:
|
get:
|
||||||
tags:
|
tags:
|
||||||
@ -831,7 +831,7 @@ paths:
|
|||||||
type: string
|
type: string
|
||||||
example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
|
example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
|
||||||
required: false
|
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
|
- name: X-HTM-CUSTOMER-PROFILE-ID-HEADER
|
||||||
in: header
|
in: header
|
||||||
schema:
|
schema:
|
||||||
@ -845,7 +845,7 @@ paths:
|
|||||||
type: string
|
type: string
|
||||||
example: Customer
|
example: Customer
|
||||||
required: false
|
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:
|
responses:
|
||||||
200:
|
200:
|
||||||
description: OK
|
description: OK
|
||||||
@ -866,7 +866,7 @@ paths:
|
|||||||
"billingInformationId": 1,
|
"billingInformationId": 1,
|
||||||
"iban": "NL••••••••••••1234",
|
"iban": "NL••••••••••••1234",
|
||||||
"ascription": "J. Doe",
|
"ascription": "J. Doe",
|
||||||
"alias": null,
|
"alias": null,
|
||||||
"created": "2024-10-20T17:05:52.000",
|
"created": "2024-10-20T17:05:52.000",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@ -875,7 +875,7 @@ paths:
|
|||||||
get:
|
get:
|
||||||
tags:
|
tags:
|
||||||
- Customers
|
- 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.
|
description: Find direct debit mandates for a customer.
|
||||||
parameters:
|
parameters:
|
||||||
- name: X-HTM-JWT-AUTH-HEADER
|
- name: X-HTM-JWT-AUTH-HEADER
|
||||||
@ -884,7 +884,7 @@ paths:
|
|||||||
type: string
|
type: string
|
||||||
example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
|
example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
|
||||||
required: false
|
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
|
- name: X-HTM-CUSTOMER-PROFILE-ID-HEADER
|
||||||
in: header
|
in: header
|
||||||
schema:
|
schema:
|
||||||
@ -898,7 +898,7 @@ paths:
|
|||||||
type: string
|
type: string
|
||||||
example: Customer
|
example: Customer
|
||||||
required: false
|
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:
|
responses:
|
||||||
200:
|
200:
|
||||||
description: OK
|
description: OK
|
||||||
@ -914,12 +914,12 @@ paths:
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"directDebitMandateId": 71,
|
"directDebitMandateId": 71,
|
||||||
"billingInformationId":
|
"billingInformationId":
|
||||||
{
|
{
|
||||||
"billingInformationId": 15,
|
"billingInformationId": 15,
|
||||||
"iban": "NL••••••••••••1234",
|
"iban": "NL••••••••••••1234",
|
||||||
"ascription": "J. Doe",
|
"ascription": "J. Doe",
|
||||||
"alias": null,
|
"alias": null,
|
||||||
"created": "2024-10-20T17:05:52.000",
|
"created": "2024-10-20T17:05:52.000",
|
||||||
},
|
},
|
||||||
"directDebitMandateType":
|
"directDebitMandateType":
|
||||||
@ -1081,6 +1081,10 @@ paths:
|
|||||||
"photo": null,
|
"photo": null,
|
||||||
},
|
},
|
||||||
"gboAgeProfile": null,
|
"gboAgeProfile": null,
|
||||||
|
"tatSecurity": {
|
||||||
|
"isSecured": true,
|
||||||
|
"isAuthorized": true,
|
||||||
|
},
|
||||||
"_links":
|
"_links":
|
||||||
{
|
{
|
||||||
"self":
|
"self":
|
||||||
@ -1130,9 +1134,9 @@ paths:
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
OV pas without PAD:
|
OV pas without PAD, without AGO:
|
||||||
summary: OV pas without PAD
|
summary: OV pas without PAD, without AGO
|
||||||
description: OV pas without PAD
|
description: OV pas without PAD, without AGO
|
||||||
value:
|
value:
|
||||||
{
|
{
|
||||||
"ovPayTokens":
|
"ovPayTokens":
|
||||||
@ -1142,7 +1146,7 @@ paths:
|
|||||||
"ovPayTokenId": 1,
|
"ovPayTokenId": 1,
|
||||||
"xTat": "32089cc8-d187-47ff-a3a9-5c2558def811",
|
"xTat": "32089cc8-d187-47ff-a3a9-5c2558def811",
|
||||||
"tokenType":
|
"tokenType":
|
||||||
{ "tokenTypeId": 2, "name": "OV-pas physical" },
|
{ "tokenTypeId": 2, "name": "OV-pas physical" },
|
||||||
"ovpasNumber": "OV34567",
|
"ovpasNumber": "OV34567",
|
||||||
"alias": "MyToken",
|
"alias": "MyToken",
|
||||||
"tokenStatus":
|
"tokenStatus":
|
||||||
@ -1164,6 +1168,10 @@ paths:
|
|||||||
"photo": null,
|
"photo": null,
|
||||||
},
|
},
|
||||||
"gboAgeProfile": null,
|
"gboAgeProfile": null,
|
||||||
|
"tatSecurity": {
|
||||||
|
"isSecured": false,
|
||||||
|
"isAuthorized": false,
|
||||||
|
},
|
||||||
"_links":
|
"_links":
|
||||||
{
|
{
|
||||||
"self":
|
"self":
|
||||||
@ -1201,6 +1209,10 @@ paths:
|
|||||||
"href": "https://api.integratielaag.nl/abt/touchpoint/1.0/customers/tokens/51compare",
|
"href": "https://api.integratielaag.nl/abt/touchpoint/1.0/customers/tokens/51compare",
|
||||||
"method": "POST",
|
"method": "POST",
|
||||||
},
|
},
|
||||||
|
"secure": {
|
||||||
|
"href": "/tokens/securetoken",
|
||||||
|
"method": "POST"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@ -1213,9 +1225,9 @@ paths:
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
OV pas with PAD and autoReload:
|
OV pas with PAD, with autoReload, with AGO:
|
||||||
summary: OV pas with PAD and autoReload
|
summary: OV pas with PAD, with autoReload, with AGO
|
||||||
description: OV pas with PAD and autoReload
|
description: OV pas with PAD, with autoReload, with AGO
|
||||||
value:
|
value:
|
||||||
{
|
{
|
||||||
"ovPayTokens":
|
"ovPayTokens":
|
||||||
@ -1225,7 +1237,7 @@ paths:
|
|||||||
"ovPayTokenId": 1,
|
"ovPayTokenId": 1,
|
||||||
"xTat": "32089cc8-d187-47ff-a3a9-5c2558def811",
|
"xTat": "32089cc8-d187-47ff-a3a9-5c2558def811",
|
||||||
"tokenType":
|
"tokenType":
|
||||||
{ "tokenTypeId": 2, "name": "OV-pas physical" },
|
{ "tokenTypeId": 2, "name": "OV-pas physical" },
|
||||||
"ovpasNumber": "OV34567",
|
"ovpasNumber": "OV34567",
|
||||||
"alias": "MyToken",
|
"alias": "MyToken",
|
||||||
"tokenStatus":
|
"tokenStatus":
|
||||||
@ -1287,6 +1299,10 @@ paths:
|
|||||||
"ageFromInclusive": 4,
|
"ageFromInclusive": 4,
|
||||||
"ageToInclusive": 11,
|
"ageToInclusive": 11,
|
||||||
},
|
},
|
||||||
|
"tatSecurity": {
|
||||||
|
"isSecured": true,
|
||||||
|
"isAuthorized": true,
|
||||||
|
},
|
||||||
"_links":
|
"_links":
|
||||||
{
|
{
|
||||||
"self":
|
"self":
|
||||||
@ -1348,8 +1364,8 @@ paths:
|
|||||||
"ovPayTokenId": 1,
|
"ovPayTokenId": 1,
|
||||||
"xTat": "32089cc8-d187-47ff-a3a9-5c2558def811",
|
"xTat": "32089cc8-d187-47ff-a3a9-5c2558def811",
|
||||||
"tokenType":
|
"tokenType":
|
||||||
{ "tokenTypeId": 2, "name": "OV-pas physical" },
|
{ "tokenTypeId": 2, "name": "OV-pas physical" },
|
||||||
"ovpasNumber": "OV34567",
|
"ovpasNumber": "OV34567",
|
||||||
"alias": "MyToken",
|
"alias": "MyToken",
|
||||||
"tokenStatus":
|
"tokenStatus":
|
||||||
{ "tokenStatusId": 2, "name": "Active" },
|
{ "tokenStatusId": 2, "name": "Active" },
|
||||||
@ -1385,6 +1401,10 @@ paths:
|
|||||||
"ageFromInclusive": 4,
|
"ageFromInclusive": 4,
|
||||||
"ageToInclusive": 11,
|
"ageToInclusive": 11,
|
||||||
},
|
},
|
||||||
|
"tatSecurity": {
|
||||||
|
"isSecured": true,
|
||||||
|
"isAuthorized": true,
|
||||||
|
},
|
||||||
"_links":
|
"_links":
|
||||||
{
|
{
|
||||||
"self":
|
"self":
|
||||||
@ -1446,7 +1466,7 @@ paths:
|
|||||||
"ovPayTokenId": 1,
|
"ovPayTokenId": 1,
|
||||||
"xTat": "32089cc8-d187-47ff-a3a9-5c2558def811",
|
"xTat": "32089cc8-d187-47ff-a3a9-5c2558def811",
|
||||||
"tokenType":
|
"tokenType":
|
||||||
{ "tokenTypeId": 2, "name": "OV-pas physical" },
|
{ "tokenTypeId": 2, "name": "OV-pas physical" },
|
||||||
"ovpasNumber": "OV34567",
|
"ovpasNumber": "OV34567",
|
||||||
"alias": "MyToken",
|
"alias": "MyToken",
|
||||||
"tokenStatus":
|
"tokenStatus":
|
||||||
@ -1501,6 +1521,10 @@ paths:
|
|||||||
"ageFromInclusive": 4,
|
"ageFromInclusive": 4,
|
||||||
"ageToInclusive": 11,
|
"ageToInclusive": 11,
|
||||||
},
|
},
|
||||||
|
"tatSecurity": {
|
||||||
|
"isSecured": true,
|
||||||
|
"isAuthorized": true,
|
||||||
|
},
|
||||||
"_links":
|
"_links":
|
||||||
{
|
{
|
||||||
"self":
|
"self":
|
||||||
@ -1562,7 +1586,7 @@ paths:
|
|||||||
"ovPayTokenId": 1,
|
"ovPayTokenId": 1,
|
||||||
"xTat": "e7fa3392-646b-40e2-95a6-c417dc0b0969",
|
"xTat": "e7fa3392-646b-40e2-95a6-c417dc0b0969",
|
||||||
"tokenType":
|
"tokenType":
|
||||||
{ "tokenTypeId": 2, "name": "OV-pas physical" },
|
{ "tokenTypeId": 2, "name": "OV-pas physical" },
|
||||||
"ovpasNumber": "OV34567",
|
"ovpasNumber": "OV34567",
|
||||||
"alias": "MyToken",
|
"alias": "MyToken",
|
||||||
"tokenStatus":
|
"tokenStatus":
|
||||||
@ -1577,13 +1601,29 @@ paths:
|
|||||||
"birthdate": null,
|
"birthdate": null,
|
||||||
"photo": null,
|
"photo": null,
|
||||||
},
|
},
|
||||||
|
"tatSecurity": {
|
||||||
|
"isSecured": true,
|
||||||
|
"isAuthorized": false,
|
||||||
|
},
|
||||||
|
"_links":{
|
||||||
|
"self":
|
||||||
|
{
|
||||||
|
"href": "https://api.integratielaag.nl/abt/touchpoint/1.0/customers/tokens?ovPaytokenId=1",
|
||||||
|
"method": "GET",
|
||||||
|
},
|
||||||
|
"authorize":
|
||||||
|
{
|
||||||
|
"href": "/tokens/authorizetoken",
|
||||||
|
"method": "POST"
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"customerProfileId": 1,
|
"customerProfileId": 1,
|
||||||
"ovPayTokenId": 6,
|
"ovPayTokenId": 6,
|
||||||
"xTat": "e7fa3392-646b-40e2-95a6-c417dc0b0969",
|
"xTat": "e7fa3392-646b-40e2-95a6-c417dc0b0969",
|
||||||
"tokenType":
|
"tokenType":
|
||||||
{ "tokenTypeId": 2, "name": "OV-pas physical" },
|
{ "tokenTypeId": 2, "name": "OV-pas physical" },
|
||||||
"ovpasNumber": "OV54567",
|
"ovpasNumber": "OV54567",
|
||||||
"alias": "MyToken",
|
"alias": "MyToken",
|
||||||
"tokenStatus":
|
"tokenStatus":
|
||||||
@ -1599,13 +1639,24 @@ paths:
|
|||||||
"photo": null,
|
"photo": null,
|
||||||
},
|
},
|
||||||
"gboAgeProfile": null,
|
"gboAgeProfile": null,
|
||||||
|
"tatSecurity": {
|
||||||
|
"isSecured": true,
|
||||||
|
"isAuthorized": true,
|
||||||
|
},
|
||||||
|
"_links":{
|
||||||
|
"self":
|
||||||
|
{
|
||||||
|
"href": "https://api.integratielaag.nl/abt/touchpoint/1.0/customers/tokens?ovPaytokenId=1",
|
||||||
|
"method": "GET",
|
||||||
|
},
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"customerProfileId": 18,
|
"customerProfileId": 18,
|
||||||
"ovPayTokenId": 13,
|
"ovPayTokenId": 13,
|
||||||
"xTat": "e7fa3392-646b-40e2-95a6-c417dc0b0969",
|
"xTat": "e7fa3392-646b-40e2-95a6-c417dc0b0969",
|
||||||
"tokenType":
|
"tokenType":
|
||||||
{ "tokenTypeId": 2, "name": "OV-pas physical" },
|
{ "tokenTypeId": 2, "name": "OV-pas physical" },
|
||||||
"ovpasNumber": "OV34547",
|
"ovpasNumber": "OV34547",
|
||||||
"alias": "MyToken",
|
"alias": "MyToken",
|
||||||
"tokenStatus":
|
"tokenStatus":
|
||||||
@ -1621,13 +1672,24 @@ paths:
|
|||||||
"photo": null,
|
"photo": null,
|
||||||
},
|
},
|
||||||
"gboAgeProfile": null,
|
"gboAgeProfile": null,
|
||||||
|
"tatSecurity": {
|
||||||
|
"isSecured": true,
|
||||||
|
"isAuthorized": true,
|
||||||
|
},
|
||||||
|
"_links":{
|
||||||
|
"self":
|
||||||
|
{
|
||||||
|
"href": "https://api.integratielaag.nl/abt/touchpoint/1.0/customers/tokens?ovPaytokenId=1",
|
||||||
|
"method": "GET",
|
||||||
|
},
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"customerProfileId": 132,
|
"customerProfileId": 132,
|
||||||
"ovPayTokenId": 21,
|
"ovPayTokenId": 21,
|
||||||
"xTat": "e7fa3392-646b-40e2-95a6-c417dc0b0969",
|
"xTat": "e7fa3392-646b-40e2-95a6-c417dc0b0969",
|
||||||
"tokenType":
|
"tokenType":
|
||||||
{ "tokenTypeId": 2, "name": "OV-pas physical" },
|
{ "tokenTypeId": 2, "name": "OV-pas physical" },
|
||||||
"ovpasNumber": "OV34831",
|
"ovpasNumber": "OV34831",
|
||||||
"alias": "Mijn OV Pas",
|
"alias": "Mijn OV Pas",
|
||||||
"tokenStatus":
|
"tokenStatus":
|
||||||
@ -1643,13 +1705,24 @@ paths:
|
|||||||
"photo": null,
|
"photo": null,
|
||||||
},
|
},
|
||||||
"gboAgeProfile": null,
|
"gboAgeProfile": null,
|
||||||
|
"tatSecurity": {
|
||||||
|
"isSecured": true,
|
||||||
|
"isAuthorized": true,
|
||||||
|
},
|
||||||
|
"_links":{
|
||||||
|
"self":
|
||||||
|
{
|
||||||
|
"href": "https://api.integratielaag.nl/abt/touchpoint/1.0/customers/tokens?ovPaytokenId=1",
|
||||||
|
"method": "GET",
|
||||||
|
},
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"customerProfileId": 166,
|
"customerProfileId": 166,
|
||||||
"ovPayTokenId": 28,
|
"ovPayTokenId": 28,
|
||||||
"xTat": "e7fa3392-646b-40e2-95a6-c417dc0b0969",
|
"xTat": "e7fa3392-646b-40e2-95a6-c417dc0b0969",
|
||||||
"tokenType":
|
"tokenType":
|
||||||
{ "tokenTypeId": 2, "name": "OV-pas physical" },
|
{ "tokenTypeId": 2, "name": "OV-pas physical" },
|
||||||
"ovpasNumber": "OV34984",
|
"ovpasNumber": "OV34984",
|
||||||
"alias": "Mijn OV Pas",
|
"alias": "Mijn OV Pas",
|
||||||
"tokenStatus":
|
"tokenStatus":
|
||||||
@ -1668,13 +1741,29 @@ paths:
|
|||||||
"photo": null,
|
"photo": null,
|
||||||
},
|
},
|
||||||
"gboAgeProfile": null,
|
"gboAgeProfile": null,
|
||||||
|
"tatSecurity": {
|
||||||
|
"isSecured": false,
|
||||||
|
"isAuthorized": false,
|
||||||
|
},
|
||||||
|
"_links":{
|
||||||
|
"self":
|
||||||
|
{
|
||||||
|
"href": "https://api.integratielaag.nl/abt/touchpoint/1.0/customers/tokens?ovPaytokenId=1",
|
||||||
|
"method": "GET",
|
||||||
|
},
|
||||||
|
"secure":
|
||||||
|
{
|
||||||
|
"href": "/tokens/securetoken",
|
||||||
|
"method": "POST"
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"customerProfileId": 166,
|
"customerProfileId": 166,
|
||||||
"ovPayTokenId": 115,
|
"ovPayTokenId": 115,
|
||||||
"xTat": "e7fa3392-646b-40e2-95a6-c417dc0b0969",
|
"xTat": "e7fa3392-646b-40e2-95a6-c417dc0b0969",
|
||||||
"tokenType":
|
"tokenType":
|
||||||
{ "tokenTypeId": 2, "name": "OV-pas physical" },
|
{ "tokenTypeId": 2, "name": "OV-pas physical" },
|
||||||
"ovpasNumber": "OV54368",
|
"ovpasNumber": "OV54368",
|
||||||
"alias": "My retired token",
|
"alias": "My retired token",
|
||||||
"tokenStatus":
|
"tokenStatus":
|
||||||
@ -1690,13 +1779,24 @@ paths:
|
|||||||
"photo": null,
|
"photo": null,
|
||||||
},
|
},
|
||||||
"gboAgeProfile": null,
|
"gboAgeProfile": null,
|
||||||
|
"tatSecurity": {
|
||||||
|
"isSecured": true,
|
||||||
|
"isAuthorized": true,
|
||||||
|
},
|
||||||
|
"_links":{
|
||||||
|
"self":
|
||||||
|
{
|
||||||
|
"href": "https://api.integratielaag.nl/abt/touchpoint/1.0/customers/tokens?ovPaytokenId=1",
|
||||||
|
"method": "GET",
|
||||||
|
},
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"customerProfileId": 1,
|
"customerProfileId": 1,
|
||||||
"ovPayTokenId": 118,
|
"ovPayTokenId": 118,
|
||||||
"xTat": "e7fa3392-646b-40e2-95a6-c417dc0b0969",
|
"xTat": "e7fa3392-646b-40e2-95a6-c417dc0b0969",
|
||||||
"tokenType":
|
"tokenType":
|
||||||
{ "tokenTypeId": 2, "name": "OV-pas physical" },
|
{ "tokenTypeId": 2, "name": "OV-pas physical" },
|
||||||
"ovpasNumber": "OV98263",
|
"ovpasNumber": "OV98263",
|
||||||
"alias": "My found token",
|
"alias": "My found token",
|
||||||
"tokenStatus":
|
"tokenStatus":
|
||||||
@ -1712,6 +1812,17 @@ paths:
|
|||||||
"photo": null,
|
"photo": null,
|
||||||
},
|
},
|
||||||
"gboAgeProfile": null,
|
"gboAgeProfile": null,
|
||||||
|
"tatSecurity": {
|
||||||
|
"isSecured": true,
|
||||||
|
"isAuthorized": true,
|
||||||
|
},
|
||||||
|
"_links":{
|
||||||
|
"self":
|
||||||
|
{
|
||||||
|
"href": "https://api.integratielaag.nl/abt/touchpoint/1.0/customers/tokens?ovPaytokenId=1",
|
||||||
|
"method": "GET",
|
||||||
|
},
|
||||||
|
}
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
_links:
|
_links:
|
||||||
@ -1812,6 +1923,10 @@ paths:
|
|||||||
"personalAccountData":
|
"personalAccountData":
|
||||||
{ "name": null, "birthdate": null, "photo": null },
|
{ "name": null, "birthdate": null, "photo": null },
|
||||||
"gboAgeProfile": null,
|
"gboAgeProfile": null,
|
||||||
|
"tatSecurity": {
|
||||||
|
"isSecured": true,
|
||||||
|
"isAuthorized": true,
|
||||||
|
},
|
||||||
"_links":
|
"_links":
|
||||||
{
|
{
|
||||||
"self":
|
"self":
|
||||||
@ -1890,6 +2005,10 @@ paths:
|
|||||||
"personalAccountData":
|
"personalAccountData":
|
||||||
{ "name": null, "birthdate": null, "photo": null },
|
{ "name": null, "birthdate": null, "photo": null },
|
||||||
"gboAgeProfile": null,
|
"gboAgeProfile": null,
|
||||||
|
"tatSecurity": {
|
||||||
|
"isSecured": true,
|
||||||
|
"isAuthorized": false,
|
||||||
|
},
|
||||||
"_links":
|
"_links":
|
||||||
{
|
{
|
||||||
"self":
|
"self":
|
||||||
@ -1927,6 +2046,12 @@ paths:
|
|||||||
"href": "https://api.integratielaag.nl/abt/touchpoint/1.0/customers/tokens/1/compare",
|
"href": "https://api.integratielaag.nl/abt/touchpoint/1.0/customers/tokens/1/compare",
|
||||||
"method": "POST",
|
"method": "POST",
|
||||||
},
|
},
|
||||||
|
"authorize":{
|
||||||
|
{
|
||||||
|
"href": "/tokens/authorizetoken",
|
||||||
|
"method": "POST"
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"_links":
|
"_links":
|
||||||
@ -2086,6 +2211,10 @@ paths:
|
|||||||
"personalAccountData":
|
"personalAccountData":
|
||||||
{ "name": null, "birthdate": null, "photo": null },
|
{ "name": null, "birthdate": null, "photo": null },
|
||||||
"gboAgeProfile": null,
|
"gboAgeProfile": null,
|
||||||
|
"tatSecurity": {
|
||||||
|
"isSecured": true,
|
||||||
|
"isAuthorized": true,
|
||||||
|
},
|
||||||
"_links":
|
"_links":
|
||||||
{
|
{
|
||||||
"self":
|
"self":
|
||||||
@ -2149,6 +2278,10 @@ paths:
|
|||||||
"personalAccountData":
|
"personalAccountData":
|
||||||
{ "name": null, "birthdate": null, "photo": null },
|
{ "name": null, "birthdate": null, "photo": null },
|
||||||
"gboAgeProfile": null,
|
"gboAgeProfile": null,
|
||||||
|
"tatSecurity": {
|
||||||
|
"isSecured": true,
|
||||||
|
"isAuthorized": true,
|
||||||
|
},
|
||||||
"_links":
|
"_links":
|
||||||
{
|
{
|
||||||
"self":
|
"self":
|
||||||
@ -2905,9 +3038,9 @@ paths:
|
|||||||
summary: "**INTEGRATIELAAG** Transfer old OVpay token to new OVpay token."
|
summary: "**INTEGRATIELAAG** Transfer old OVpay token to new OVpay token."
|
||||||
description: |-
|
description: |-
|
||||||
**Note that this directly calls the integratielaag and not the Service Engine!**
|
**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
|
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.
|
`/customers/tokens/transfer/responsestatus/*` endpoint.
|
||||||
tags:
|
tags:
|
||||||
- Token Replace v2
|
- Token Replace v2
|
||||||
@ -2920,9 +3053,9 @@ paths:
|
|||||||
Transfer from a token without PAD to a new token:
|
Transfer from a token without PAD to a new token:
|
||||||
summary: Transfer from a token without PAD to a new token
|
summary: Transfer from a token without PAD to a new token
|
||||||
description: |
|
description: |
|
||||||
Transfer of a token without PAD to a new OVpay token. Note the new token in the request is always
|
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
|
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,
|
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.
|
and it will be created in the customer profile.
|
||||||
value:
|
value:
|
||||||
{
|
{
|
||||||
@ -2936,11 +3069,11 @@ paths:
|
|||||||
Transfer from a token with PAD to a new token without existing PAD:
|
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
|
summary: Transfer from a token with PAD to a new token without existing PAD
|
||||||
description: |
|
description: |
|
||||||
Transfer of a token with PAD to a new token by xTAT without existing PAD. Note how this request is
|
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
|
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.
|
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
|
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
|
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.
|
user needs to provide an alias for the new token, and it will be created in the customer profile.
|
||||||
value:
|
value:
|
||||||
{
|
{
|
||||||
@ -2957,8 +3090,8 @@ paths:
|
|||||||
summary: Transfer from a token with PAD to a new token with existing PAD
|
summary: Transfer from a token with PAD to a new token with existing PAD
|
||||||
description: |
|
description: |
|
||||||
Transfer of a token with PAD to a new token by xTAT with existing PAD.
|
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
|
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
|
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.
|
user needs to provide an alias for the new token, and it will be created in the customer profile.
|
||||||
value:
|
value:
|
||||||
{
|
{
|
||||||
@ -2996,7 +3129,7 @@ paths:
|
|||||||
Transfer of token started:
|
Transfer of token started:
|
||||||
description: |
|
description: |
|
||||||
The transfer of the token was started successfully. The data of the token will be transferred
|
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.
|
processing status.
|
||||||
value:
|
value:
|
||||||
{
|
{
|
||||||
@ -3038,7 +3171,7 @@ paths:
|
|||||||
- Token Replace v2
|
- Token Replace v2
|
||||||
summary: "**INTEGRATIELAAG** Get the status of the initiated token transfer process."
|
summary: "**INTEGRATIELAAG** Get the status of the initiated token transfer process."
|
||||||
description: |
|
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.
|
asynchronous token transfer processing.
|
||||||
responses:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
@ -3166,7 +3299,7 @@ paths:
|
|||||||
examples:
|
examples:
|
||||||
Token transfer in progress:
|
Token transfer in progress:
|
||||||
description: |
|
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.
|
processing status.
|
||||||
value:
|
value:
|
||||||
{
|
{
|
||||||
@ -3347,7 +3480,7 @@ paths:
|
|||||||
in: query
|
in: query
|
||||||
description: External id of the device you want to get the purchased HTM products for.
|
description: External id of the device you want to get the purchased HTM products for.
|
||||||
schema:
|
schema:
|
||||||
type: string
|
type: string
|
||||||
- name: ovpayTokenId
|
- name: ovpayTokenId
|
||||||
in: query
|
in: query
|
||||||
description: Id of the OVpay-token you want to get the purchased HTM products for.
|
description: Id of the OVpay-token you want to get the purchased HTM products for.
|
||||||
@ -3380,9 +3513,9 @@ paths:
|
|||||||
}
|
}
|
||||||
getTwoBarcodePurchasedProductsForDevice:
|
getTwoBarcodePurchasedProductsForDevice:
|
||||||
summary: Two BarcodeTicket purchased products, one PendingActivation and one Active
|
summary: Two BarcodeTicket purchased products, one PendingActivation and one Active
|
||||||
description: |-
|
description: |-
|
||||||
The first ticket (PendingActivation) shows the 30-day range in which the ticket can be activated
|
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)
|
(using the PATCH endpoint) in the validityStart and validityEnd fields. The second ticket (Active)
|
||||||
shows the actual validity period of the ticket after activation.
|
shows the actual validity period of the ticket after activation.
|
||||||
value:
|
value:
|
||||||
{
|
{
|
||||||
@ -3401,14 +3534,14 @@ paths:
|
|||||||
"name": "Barcode",
|
"name": "Barcode",
|
||||||
},
|
},
|
||||||
"orderId": "501B17EF-36C4-4039-B92C-6517969B464E",
|
"orderId": "501B17EF-36C4-4039-B92C-6517969B464E",
|
||||||
"orderLineId": "38B17EF-36C4-4039-B92C-4817969B464E",
|
"orderLineId": "38B17EF-36C4-4039-B92C-4817969B464E",
|
||||||
"ticketReference": "KJj43nejhbTxhrfef287",
|
"ticketReference": "KJj43nejhbTxhrfef287",
|
||||||
"serviceId": "HTM-4321-7654-7659",
|
"serviceId": "HTM-4321-7654-7659",
|
||||||
"issuedAt": "2026-03-21T09:01:35+01:00",
|
"issuedAt": "2026-03-21T09:01:35+01:00",
|
||||||
"activatedAt": null,
|
"activatedAt": null,
|
||||||
"blocked": false,
|
"blocked": false,
|
||||||
"cancelledAt": null,
|
"cancelledAt": null,
|
||||||
"activateBefore": "2026-03-30",
|
"activateBefore": "2026-03-30",
|
||||||
"validityStart": null,
|
"validityStart": null,
|
||||||
"validityEnd": null,
|
"validityEnd": null,
|
||||||
"barcode": null,
|
"barcode": null,
|
||||||
@ -3436,14 +3569,14 @@ paths:
|
|||||||
"name": "Barcode",
|
"name": "Barcode",
|
||||||
},
|
},
|
||||||
"orderId": "501B17EF-36C4-4039-B92C-6517969B464E",
|
"orderId": "501B17EF-36C4-4039-B92C-6517969B464E",
|
||||||
"orderLineId": "38B17EF-36C4-4039-B92C-4817969B464E",
|
"orderLineId": "38B17EF-36C4-4039-B92C-4817969B464E",
|
||||||
"ticketReference": "KJj43nejhbTxhr897287",
|
"ticketReference": "KJj43nejhbTxhr897287",
|
||||||
"serviceId": "HTM-1234-7654-8945",
|
"serviceId": "HTM-1234-7654-8945",
|
||||||
"issuedAt": "2026-03-21T10:01:12+01:00",
|
"issuedAt": "2026-03-21T10:01:12+01:00",
|
||||||
"activatedAt": "2026-03-21T12:45:01+01:00",
|
"activatedAt": "2026-03-21T12:45:01+01:00",
|
||||||
"blocked": false,
|
"blocked": false,
|
||||||
"cancelledAt": null,
|
"cancelledAt": null,
|
||||||
"activateBefore": null,
|
"activateBefore": null,
|
||||||
"validityStart": "2026-03-21T12:45:01+01:00",
|
"validityStart": "2026-03-21T12:45:01+01:00",
|
||||||
"validityEnd": "2026-03-21T14: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=",
|
"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 +3632,7 @@ paths:
|
|||||||
"barcodeTickets":[],
|
"barcodeTickets":[],
|
||||||
"vouchers":[]
|
"vouchers":[]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
getSingleVoucherPurchasedProductForCustomer:
|
getSingleVoucherPurchasedProductForCustomer:
|
||||||
summary: One voucher purchased product
|
summary: One voucher purchased product
|
||||||
value:
|
value:
|
||||||
@ -3523,7 +3656,7 @@ paths:
|
|||||||
"voucherStatus": {
|
"voucherStatus": {
|
||||||
"voucherStatusId": 2,
|
"voucherStatusId": 2,
|
||||||
"name": "issued"
|
"name": "issued"
|
||||||
},
|
},
|
||||||
"mandatoryCustomerDataItems":
|
"mandatoryCustomerDataItems":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
@ -3538,7 +3671,7 @@ paths:
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/purchasedproducts/{purchasedProductId}:
|
/purchasedproducts/{purchasedProductId}:
|
||||||
parameters:
|
parameters:
|
||||||
- name: X-HTM-JWT-AUTH-HEADER
|
- name: X-HTM-JWT-AUTH-HEADER
|
||||||
@ -3586,7 +3719,7 @@ paths:
|
|||||||
value:
|
value:
|
||||||
{
|
{
|
||||||
"status": "Active"
|
"status": "Active"
|
||||||
}
|
}
|
||||||
responses:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
description: OK
|
description: OK
|
||||||
@ -3636,7 +3769,6 @@ paths:
|
|||||||
"vouchers": []
|
"vouchers": []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/customers/devices:
|
/customers/devices:
|
||||||
post:
|
post:
|
||||||
summary: Add a new device to a customer profile.
|
summary: Add a new device to a customer profile.
|
||||||
@ -3813,7 +3945,7 @@ components:
|
|||||||
customerProfileId:
|
customerProfileId:
|
||||||
type: integer
|
type: integer
|
||||||
example: 1
|
example: 1
|
||||||
customerPreference:
|
customerPreference:
|
||||||
$ref: "#/components/schemas/getCustomerPreference"
|
$ref: "#/components/schemas/getCustomerPreference"
|
||||||
customerNumber:
|
customerNumber:
|
||||||
type: integer
|
type: integer
|
||||||
@ -4014,12 +4146,12 @@ components:
|
|||||||
customerPreferenceId:
|
customerPreferenceId:
|
||||||
type: integer
|
type: integer
|
||||||
languageId:
|
languageId:
|
||||||
type: integer
|
type: integer
|
||||||
customerStatusEntity:
|
customerStatusEntity:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
customerStatusId:
|
customerStatusId:
|
||||||
type: integer
|
type: integer
|
||||||
OvPayTokensResponse:
|
OvPayTokensResponse:
|
||||||
type: object
|
type: object
|
||||||
required:
|
required:
|
||||||
@ -4298,7 +4430,7 @@ components:
|
|||||||
items:
|
items:
|
||||||
type: object
|
type: object
|
||||||
required:
|
required:
|
||||||
- purchasedProductId
|
- purchasedProductId
|
||||||
- productId
|
- productId
|
||||||
- name
|
- name
|
||||||
- status
|
- status
|
||||||
@ -4421,13 +4553,13 @@ components:
|
|||||||
type: string
|
type: string
|
||||||
example: HTM 2 uurskaart
|
example: HTM 2 uurskaart
|
||||||
description: |-
|
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.
|
Will be returned in the language as specified in the Accept-Language header or the customer profile. Otherwise defaults to NL.
|
||||||
description:
|
description:
|
||||||
type: string
|
type: string
|
||||||
example: "Met deze kaart reis je 2 uur lang onbeperkt met de bussen en trams van HTM. Overstappen is natuurlijk toegestaan!"
|
example: "Met deze kaart reis je 2 uur lang onbeperkt met de bussen en trams van HTM. Overstappen is natuurlijk toegestaan!"
|
||||||
description: |-
|
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.
|
Will be returned in the language as specified in the Accept-Language header or the customer profile. Otherwise defaults to NL.
|
||||||
status:
|
status:
|
||||||
type: string
|
type: string
|
||||||
@ -4486,15 +4618,15 @@ components:
|
|||||||
example: "2024-11-30"
|
example: "2024-11-30"
|
||||||
description: Only present for barcode tickets that are not yet activated. Tickets can only be activated BEFORE this date.
|
description: Only present for barcode tickets that are not yet activated. Tickets can only be activated BEFORE this date.
|
||||||
validityStart:
|
validityStart:
|
||||||
description: |-
|
description: |-
|
||||||
Only present for barcode tickets that have been activated. The date-time at which the ticket will become valid for traveling.
|
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.
|
The ticket will not be valid before this date/time.
|
||||||
type: string
|
type: string
|
||||||
format: date-time-offset
|
format: date-time-offset
|
||||||
example: "2024-11-25T13:25:00+01:00"
|
example: "2024-11-25T13:25:00+01:00"
|
||||||
validityEnd:
|
validityEnd:
|
||||||
description: |-
|
description: |-
|
||||||
Only present for barcode tickets that have been activated. The date-time at which the ticket will become invalid for traveling.
|
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.
|
The ticket will not be valid after this date/time.
|
||||||
type: string
|
type: string
|
||||||
format: date-time-offset
|
format: date-time-offset
|
||||||
@ -4603,4 +4735,3 @@ components:
|
|||||||
customerDataItem:
|
customerDataItem:
|
||||||
type: string
|
type: string
|
||||||
example: emailAddress
|
example: emailAddress
|
||||||
|
|
||||||
617
src/openapi/customers/SE-tat-security.yaml
Normal file
617
src/openapi/customers/SE-tat-security.yaml
Normal file
@ -0,0 +1,617 @@
|
|||||||
|
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/status:
|
||||||
|
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
|
||||||
|
- name: xTat
|
||||||
|
in: query
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
format : uuid
|
||||||
|
example: 5c4cba83-1ecd-46a4-b712-a8de0dcb7bbf
|
||||||
|
required: false
|
||||||
|
description: The xtat of the customerToken
|
||||||
|
- name: ovPayTokenId
|
||||||
|
in: query
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
example: 1
|
||||||
|
required: false
|
||||||
|
description: The ovpay token id of a specific customer token
|
||||||
|
- name: serviceReferenceId
|
||||||
|
in: query
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
example: NLOV1234567ABCDEFG
|
||||||
|
required: false
|
||||||
|
description: The serviceReferencId found on the bankstatement for a given trip with a bankcard, required for an unknown EMV card
|
||||||
|
- name: amount
|
||||||
|
in: query
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
example: 0
|
||||||
|
required: false
|
||||||
|
description: The amount of the value of the bankstatement in cents, required for an unknown EMV card
|
||||||
|
- name: ovpasNumber
|
||||||
|
in: query
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
example: OV34567
|
||||||
|
required: false
|
||||||
|
description: The number of the ovpas, required for an unknown Ovpas card
|
||||||
|
- name: verificationCode
|
||||||
|
in: query
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
example: HL78
|
||||||
|
required: false
|
||||||
|
description: The 4 digit verificationCode found on the backside of the Ovpas, required for an unknown Ovpas card
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- TAT Security
|
||||||
|
summary: Check the status of the security and authorization status of the given token
|
||||||
|
description: Check the status of the security and authorization status of the given token, check anonymous tokenDB if no customer headers are supplied otherwise check customer tokenDB
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/TokenStatusResponse"
|
||||||
|
examples:
|
||||||
|
isSecuredandnotAuthorized:
|
||||||
|
summary: Token is secured but HTM is not authorized
|
||||||
|
description: Token is secured but HTM is not authorized
|
||||||
|
value:
|
||||||
|
isSecured: true
|
||||||
|
isAuthorized: false
|
||||||
|
xTat: 12da8f2a-6390-408a-94eb-a6701b5daf27
|
||||||
|
_links: {
|
||||||
|
"authorize": {
|
||||||
|
"href": "/tokens/authorizetoken",
|
||||||
|
"method": "POST"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
notSecuredandnotAuthorized:
|
||||||
|
summary: Token is not secured but HTM is not authorized
|
||||||
|
description: Token is not secured but HTM is not authorized
|
||||||
|
value:
|
||||||
|
isSecured: false
|
||||||
|
isAuthorized: false
|
||||||
|
xTat: 12da8f2a-6390-408a-94eb-a6701b5daf27
|
||||||
|
_links: {
|
||||||
|
"secure": {
|
||||||
|
"href": "/tokens/securetoken",
|
||||||
|
"method": "POST"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"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.
|
||||||
|
"404":
|
||||||
|
description: Not found
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/ErrorResponse"
|
||||||
|
examples:
|
||||||
|
TAT not found:
|
||||||
|
value:
|
||||||
|
status: 404
|
||||||
|
title: Not Found
|
||||||
|
detail: XTAT Account Not Found
|
||||||
|
"500":
|
||||||
|
description: Internal server error
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/ErrorResponse"
|
||||||
|
example:
|
||||||
|
error: An unknown error has occurred
|
||||||
|
/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:
|
||||||
|
recipient: xxxxxx.user@gmail.com
|
||||||
|
description: OTP Sent
|
||||||
|
_links: {
|
||||||
|
"verifyotp": {
|
||||||
|
"href": "/tokens/verifyotp",
|
||||||
|
"method": "POST"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"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
|
||||||
|
/tokens/authorizetoken:
|
||||||
|
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 Authorization
|
||||||
|
summary: Request authorization for HTM to access the data secured by additional OV-pas security for a token either in profile or anonymous.
|
||||||
|
description: Request authorization for HTM to access the data secured by additional OV-pas security for a token either in profile or anonymous.
|
||||||
|
requestBody:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/AuthorizeTokenRequest"
|
||||||
|
examples:
|
||||||
|
With customer account:
|
||||||
|
value:
|
||||||
|
ovPayTokenId: 42
|
||||||
|
Without customer account:
|
||||||
|
value:
|
||||||
|
xTat: 62914b49-2c7f-437f-b4b0-2ad61a9f902d
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/EmailNotPreApprovedResponse"
|
||||||
|
example:
|
||||||
|
recipient: xxxxxx.user@gmail.com
|
||||||
|
description: OTP Sent
|
||||||
|
_links: {
|
||||||
|
"verifyotp": {
|
||||||
|
"href": "/tokens/verifyotp",
|
||||||
|
"method": "POST"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"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
|
||||||
|
"500":
|
||||||
|
description: Internal server error
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/ErrorResponse"
|
||||||
|
example:
|
||||||
|
error: An unknown error has occurred
|
||||||
|
/tokens/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 Verification
|
||||||
|
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:
|
||||||
|
recipient:
|
||||||
|
type: string
|
||||||
|
description: >-
|
||||||
|
A recipient IS A unique identifier THAT is associated with the TAT
|
||||||
|
owner.
|
||||||
|
example: xxxxxx.user@gmail.com
|
||||||
|
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:
|
||||||
|
- emailAddress
|
||||||
|
AuthorizeTokenRequest:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
ovPayTokenId:
|
||||||
|
type: integer
|
||||||
|
example: 42
|
||||||
|
xTat:
|
||||||
|
type: string
|
||||||
|
format: uuid
|
||||||
|
example: 6134db53-9ae5-41d1-a343-36656b60b510
|
||||||
|
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.
|
||||||
|
TokenStatusResponse:
|
||||||
|
type: object
|
||||||
|
description: >-
|
||||||
|
TokenStatusResponse IS AN object THAT represents the current state of the token in relation to the AGO security and authorization status of HTM.
|
||||||
|
required:
|
||||||
|
- isSecured
|
||||||
|
- isAuthorized
|
||||||
|
properties:
|
||||||
|
isSecured:
|
||||||
|
type: boolean
|
||||||
|
description: >-
|
||||||
|
Is the token secured in the national database (GBO)
|
||||||
|
example: false
|
||||||
|
isAuthorized:
|
||||||
|
type: boolean
|
||||||
|
description: >-
|
||||||
|
Does HTM have the authorization to access the secured data for this token, only applicable when isSecured equals True.
|
||||||
|
example: false
|
||||||
|
xTat:
|
||||||
|
type: string
|
||||||
|
format: uuid
|
||||||
|
description: >-
|
||||||
|
The xtat of the customerToken given when token is unknown for the customer
|
||||||
|
example: 883674e5-54c7-47d6-a3e3-8781f0d3ffea
|
||||||
|
|
||||||
@ -243,7 +243,7 @@ paths:
|
|||||||
suffix: PhD
|
suffix: PhD
|
||||||
dateOfBirth: "2002-10-29"
|
dateOfBirth: "2002-10-29"
|
||||||
emailAddresses: TEST@HTM.NL
|
emailAddresses: TEST@HTM.NL
|
||||||
isEmailVerified: True
|
isEmailVerified: false
|
||||||
addresses:
|
addresses:
|
||||||
- addressId: 1
|
- addressId: 1
|
||||||
street: mystreet
|
street: mystreet
|
||||||
@ -332,14 +332,6 @@ paths:
|
|||||||
user: user
|
user: user
|
||||||
timestamp: "2023-10-20T17:05:52.000+02:00"
|
timestamp: "2023-10-20T17:05:52.000+02:00"
|
||||||
correlationId: 01c6d8b4-1cd3-4f9b-85ea-c9adca53ce95
|
correlationId: 01c6d8b4-1cd3-4f9b-85ea-c9adca53ce95
|
||||||
_links:
|
|
||||||
{
|
|
||||||
"self":
|
|
||||||
{
|
|
||||||
"href": "https://api.integratielaag.nl/abt/abtcustomers/2.0/customers?customerProfileId=1",
|
|
||||||
"method": "GET",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
- customerProfileId: 12
|
- customerProfileId: 12
|
||||||
customerNumber: 1000002
|
customerNumber: 1000002
|
||||||
debtorNumber: DB100121
|
debtorNumber: DB100121
|
||||||
@ -377,7 +369,7 @@ paths:
|
|||||||
suffix: PhD
|
suffix: PhD
|
||||||
dateOfBirth: "2002-10-29"
|
dateOfBirth: "2002-10-29"
|
||||||
emailAddresses: TEST@HTM.NL
|
emailAddresses: TEST@HTM.NL
|
||||||
isEmailVerified: False
|
isEmailVerified: false
|
||||||
address:
|
address:
|
||||||
- addressId: 1
|
- addressId: 1
|
||||||
street: mystreet
|
street: mystreet
|
||||||
@ -467,32 +459,7 @@ paths:
|
|||||||
user: user
|
user: user
|
||||||
timestamp: "2023-10-20T17:05:52.000+02:00"
|
timestamp: "2023-10-20T17:05:52.000+02:00"
|
||||||
correlationId: 01c6d8b4-1cd3-4f9b-85ea-c9adca53ce95
|
correlationId: 01c6d8b4-1cd3-4f9b-85ea-c9adca53ce95
|
||||||
_links:
|
href: "https://api.integratielaag.nl/abt/abtcustomers/2.0/customers?offset=20&limit=20"
|
||||||
{
|
|
||||||
"self":
|
|
||||||
{
|
|
||||||
"href": "https://api.integratielaag.nl/abt/abtcustomers/2.0/customers?customerProfileId=12",
|
|
||||||
"method": "GET",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
_links:
|
|
||||||
{
|
|
||||||
"self":
|
|
||||||
{
|
|
||||||
"href": "https://api.integratielaag.nl/abt/abtcustomers/2.0/customers?offset=20",
|
|
||||||
"method": "GET",
|
|
||||||
},
|
|
||||||
"prev":
|
|
||||||
{
|
|
||||||
"href": "https://api.integratielaag.nl/abt/abtcustomers/2.0/customers",
|
|
||||||
"method": "GET",
|
|
||||||
},
|
|
||||||
"next":
|
|
||||||
{
|
|
||||||
"href": "https://api.integratielaag.nl/abt/abtcustomers/2.0/customers?offset=40",
|
|
||||||
"method": "GET",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
getCustomerActive:
|
getCustomerActive:
|
||||||
summary: getCustomerActive
|
summary: getCustomerActive
|
||||||
description: >-
|
description: >-
|
||||||
@ -526,7 +493,7 @@ paths:
|
|||||||
suffix: PhD
|
suffix: PhD
|
||||||
dateOfBirth: "2002-10-29"
|
dateOfBirth: "2002-10-29"
|
||||||
emailAddresses: TEST@HTM.NL
|
emailAddresses: TEST@HTM.NL
|
||||||
isEmailVerified: False
|
isEmailVerified: false
|
||||||
addresses:
|
addresses:
|
||||||
- addressId: 1
|
- addressId: 1
|
||||||
street: mystreet
|
street: mystreet
|
||||||
@ -615,22 +582,7 @@ paths:
|
|||||||
user: user
|
user: user
|
||||||
timestamp: "2023-10-20T17:05:52.000+02:00"
|
timestamp: "2023-10-20T17:05:52.000+02:00"
|
||||||
correlationId: 01c6d8b4-1cd3-4f9b-85ea-c9adca53ce95
|
correlationId: 01c6d8b4-1cd3-4f9b-85ea-c9adca53ce95
|
||||||
_links:
|
href: https://api.integratielaag.nl/abt/abtcustomers/2.0/customers?offset=20&limit=20
|
||||||
{
|
|
||||||
"self":
|
|
||||||
{
|
|
||||||
"href": "https://api.integratielaag.nl/abt/abtcustomers/2.0/customers?customerProfileId=1",
|
|
||||||
"method": "GET",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
_links:
|
|
||||||
{
|
|
||||||
"self":
|
|
||||||
{
|
|
||||||
"href": "https://api.integratielaag.nl/abt/abtcustomers/2.0/customers",
|
|
||||||
"method": "GET",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
getCustomerBlocked:
|
getCustomerBlocked:
|
||||||
summary: getCustomerBlocked
|
summary: getCustomerBlocked
|
||||||
description: >-
|
description: >-
|
||||||
@ -669,7 +621,7 @@ paths:
|
|||||||
suffix: PhD
|
suffix: PhD
|
||||||
dateOfBirth: "2002-10-29"
|
dateOfBirth: "2002-10-29"
|
||||||
emailAddresses: TEST@HTM.NL
|
emailAddresses: TEST@HTM.NL
|
||||||
isEmailVerified: True
|
isEmailVerified: false
|
||||||
addresses:
|
addresses:
|
||||||
- addressId: 1
|
- addressId: 1
|
||||||
street: mystreet
|
street: mystreet
|
||||||
@ -758,22 +710,7 @@ paths:
|
|||||||
user: user
|
user: user
|
||||||
timestamp: "2023-10-20T17:05:52.000+02:00"
|
timestamp: "2023-10-20T17:05:52.000+02:00"
|
||||||
correlationId: 01c6d8b4-1cd3-4f9b-85ea-c9adca53ce95
|
correlationId: 01c6d8b4-1cd3-4f9b-85ea-c9adca53ce95
|
||||||
_links:
|
href: https://api.integratielaag.nl/abt/abtcustomers/2.0/customers?offset=20&limit=20
|
||||||
{
|
|
||||||
"self":
|
|
||||||
{
|
|
||||||
"href": "https://api.integratielaag.nl/abt/abtcustomers/2.0/customers?customerProfileId=1",
|
|
||||||
"method": "GET",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
_links:
|
|
||||||
{
|
|
||||||
"self":
|
|
||||||
{
|
|
||||||
"href": "https://api.integratielaag.nl/abt/abtcustomers/2.0/customers",
|
|
||||||
"method": "GET",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
400:
|
400:
|
||||||
description: Bad Request
|
description: Bad Request
|
||||||
content:
|
content:
|
||||||
@ -835,7 +772,7 @@ paths:
|
|||||||
suffix: jr
|
suffix: jr
|
||||||
dateOfBirth: "1970-01-01"
|
dateOfBirth: "1970-01-01"
|
||||||
emailAddress: j.jansen@hatseflats.nl
|
emailAddress: j.jansen@hatseflats.nl
|
||||||
isEmailVerified: False
|
isEmailVerified: false
|
||||||
addresses:
|
addresses:
|
||||||
- street: Laan van Meerdervoort
|
- street: Laan van Meerdervoort
|
||||||
houseNumber: 5
|
houseNumber: 5
|
||||||
@ -934,7 +871,7 @@ paths:
|
|||||||
suffix: "jr",
|
suffix: "jr",
|
||||||
dateOfBirth: "1970-01-01",
|
dateOfBirth: "1970-01-01",
|
||||||
emailAddress: "TEST@TEST1.NL",
|
emailAddress: "TEST@TEST1.NL",
|
||||||
isEmailVerified: False
|
isEmailVerified: false
|
||||||
}
|
}
|
||||||
updateCompleteEntity:
|
updateCompleteEntity:
|
||||||
value:
|
value:
|
||||||
@ -946,7 +883,7 @@ paths:
|
|||||||
suffix: "jr",
|
suffix: "jr",
|
||||||
dateOfBirth: "1970-01-01",
|
dateOfBirth: "1970-01-01",
|
||||||
emailAddress: "TEST@TEST1.NL",
|
emailAddress: "TEST@TEST1.NL",
|
||||||
isEmailVerified: True
|
isEmailVerified: false
|
||||||
}
|
}
|
||||||
required: true
|
required: true
|
||||||
responses:
|
responses:
|
||||||
@ -1438,13 +1375,7 @@ paths:
|
|||||||
content:
|
content:
|
||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
$ref: "#/components/schemas/getDevices"
|
$ref: "#/components/schemas/patchDeviceResponse"
|
||||||
examples:
|
|
||||||
updateDeviceResponse:
|
|
||||||
value:
|
|
||||||
deviceId: "5bedce29-af0c-4f3c-b182-2caa8a1f9377"
|
|
||||||
externalDeviceId: "7122a988-a00a-417d-a5b4-da2d91354976"
|
|
||||||
alias: "iPhone zakelijk"
|
|
||||||
|
|
||||||
security:
|
security:
|
||||||
- default: []
|
- default: []
|
||||||
@ -1607,24 +1538,7 @@ paths:
|
|||||||
"replacedByTokenId": 12,
|
"replacedByTokenId": 12,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"_links":
|
"href": "https://api.integratielaag.nl/abt/abtcustomers/2.0/ovPayTokens?offset=20&limit=20"
|
||||||
{
|
|
||||||
"self":
|
|
||||||
{
|
|
||||||
"href": "https://api.integratielaag.nl/abt/abtcustomers/2.0/ovPayTokens?offset=20",
|
|
||||||
"method": "GET",
|
|
||||||
},
|
|
||||||
"prev":
|
|
||||||
{
|
|
||||||
"href": "https://api.integratielaag.nl/abt/abtcustomers/2.0/ovPayTokens",
|
|
||||||
"method": "GET",
|
|
||||||
},
|
|
||||||
"next":
|
|
||||||
{
|
|
||||||
"href": "https://api.integratielaag.nl/abt/abtcustomers/2.0/ovPayTokens?offset=40",
|
|
||||||
"method": "GET",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
/customers/{customerProfileId}/ovpaytokens:
|
/customers/{customerProfileId}/ovpaytokens:
|
||||||
post:
|
post:
|
||||||
@ -1943,9 +1857,10 @@ paths:
|
|||||||
"created": "2024-10-20T17:05:52.000",
|
"created": "2024-10-20T17:05:52.000",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
"href": "https://api.integratielaag.nl/abt/abtcustomers/2.0/billingInformations?offset=20&limit=20"
|
||||||
}
|
}
|
||||||
getBillingInformationSingleSpecificCustomer:
|
getBillingInformationSingleSpecificCustomer:
|
||||||
summary: Get singel billing information entity for a specific customers
|
summary: Get single billing information entity for a specific customers
|
||||||
description: >-
|
description: >-
|
||||||
Found one billing information matching the search parameters
|
Found one billing information matching the search parameters
|
||||||
value:
|
value:
|
||||||
@ -2135,59 +2050,7 @@ paths:
|
|||||||
"updateTimestamp": "2024-03-22T08:55:00",
|
"updateTimestamp": "2024-03-22T08:55:00",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"_links":
|
"href": "https://api.integratielaag.nl/abt/abtcustomers/2.0/directdebitmandates?offset=20&limit=20"
|
||||||
{
|
|
||||||
"self":
|
|
||||||
{
|
|
||||||
"href": "https://api.integratielaag.nl/abt/abtcustomers/2.0/directdebitmandates",
|
|
||||||
"method": "GET",
|
|
||||||
},
|
|
||||||
"next":
|
|
||||||
{
|
|
||||||
"href": "https://api.integratielaag.nl/abt/abtcustomers/2.0/directdebitmandates?offset=20",
|
|
||||||
"method": "GET",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
getDirectDebitMandateWithNextPageandPreviousPage:
|
|
||||||
value:
|
|
||||||
{
|
|
||||||
"directDebitMandates":
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"directDebitMandateId": 71,
|
|
||||||
"customerProfileId": 12,
|
|
||||||
"billingInformationId": 51,
|
|
||||||
"directDebitMandateType":
|
|
||||||
{
|
|
||||||
"directDebitMandateTypeId": 1,
|
|
||||||
"name": "import",
|
|
||||||
"description": "import",
|
|
||||||
},
|
|
||||||
"created": "2024-03-22T08:55:00",
|
|
||||||
"mandateReference": "CORE01",
|
|
||||||
"mandateState": "SIGNED",
|
|
||||||
"updateTimestamp": "2024-03-22T08:55:00",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"_links":
|
|
||||||
{
|
|
||||||
"self":
|
|
||||||
{
|
|
||||||
"href": "https://api.integratielaag.nl/abt/abtcustomers/2.0/directdebitmandates?offset=20",
|
|
||||||
"method": "GET",
|
|
||||||
},
|
|
||||||
"prev":
|
|
||||||
{
|
|
||||||
"href": "https://api.integratielaag.nl/abt/abtcustomers/2.0/directdebitmandates",
|
|
||||||
"method": "GET",
|
|
||||||
},
|
|
||||||
"next":
|
|
||||||
{
|
|
||||||
"href": "https://api.integratielaag.nl/abt/abtcustomers/2.0/directdebitmandates?offset=40",
|
|
||||||
"method": "GET",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
/billingInformation/{billingInformationId}/directdebitmandates:
|
/billingInformation/{billingInformationId}/directdebitmandates:
|
||||||
post:
|
post:
|
||||||
@ -2843,7 +2706,7 @@ components:
|
|||||||
emailAddress:
|
emailAddress:
|
||||||
type: string
|
type: string
|
||||||
isEmailVerified:
|
isEmailVerified:
|
||||||
type: string
|
type: boolean
|
||||||
postOvPayTokenResponse:
|
postOvPayTokenResponse:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
@ -2857,6 +2720,14 @@ components:
|
|||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
$ref: "#/components/schemas/getDeviceEntity"
|
$ref: "#/components/schemas/getDeviceEntity"
|
||||||
|
patchDeviceResponse:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
deviceId:
|
||||||
|
type: string
|
||||||
|
format: uuid
|
||||||
|
example: "b2c8a8c6-3d1c-4b6b-8f8d-3a6a1b6a1b6a"
|
||||||
|
|
||||||
getDeviceEntity:
|
getDeviceEntity:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
|
|||||||
@ -49,6 +49,8 @@ paths:
|
|||||||
- status
|
- status
|
||||||
- aggregationReference
|
- aggregationReference
|
||||||
- accountingSystemReference
|
- accountingSystemReference
|
||||||
|
- createdOn
|
||||||
|
- lastUpdatedOn
|
||||||
- name: $select
|
- name: $select
|
||||||
in: query
|
in: query
|
||||||
description: Select properties to be returned
|
description: Select properties to be returned
|
||||||
@ -79,6 +81,8 @@ paths:
|
|||||||
- status
|
- status
|
||||||
- aggregationReference
|
- aggregationReference
|
||||||
- accountingSystemReference
|
- accountingSystemReference
|
||||||
|
- createdOn
|
||||||
|
- lastUpdatedOn
|
||||||
responses:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
description: OK
|
description: OK
|
||||||
@ -117,7 +121,9 @@ paths:
|
|||||||
articleNumber: "4031"
|
articleNumber: "4031"
|
||||||
status: created
|
status: created
|
||||||
aggregationReference: null
|
aggregationReference: null
|
||||||
accountingSystemReference: null
|
accountingSystemReference: null
|
||||||
|
createdOn: 2024-11-04T00:00:00Z
|
||||||
|
lastUpdatedOn: 2024-11-04T04:00:00Z
|
||||||
- "@odata.etag": e671c8a1-b918-4867-bf12-5289822479c3
|
- "@odata.etag": e671c8a1-b918-4867-bf12-5289822479c3
|
||||||
transactionItemRowId: 3232
|
transactionItemRowId: 3232
|
||||||
transactionItemId: 1c1fc1c8-57f4-4336-9b43-a974eae5afbf
|
transactionItemId: 1c1fc1c8-57f4-4336-9b43-a974eae5afbf
|
||||||
@ -136,7 +142,9 @@ paths:
|
|||||||
articleNumber: "4051"
|
articleNumber: "4051"
|
||||||
status: failed
|
status: failed
|
||||||
aggregationReference: null
|
aggregationReference: null
|
||||||
accountingSystemReference: null
|
accountingSystemReference: null
|
||||||
|
createdOn: 2024-11-04T00:00:00Z
|
||||||
|
lastUpdatedOn: 2024-11-04T04:00:00Z
|
||||||
- "@odata.etag": be2715d4-4eff-4562-9bf3-5c43ad23e2c8
|
- "@odata.etag": be2715d4-4eff-4562-9bf3-5c43ad23e2c8
|
||||||
transactionItemRowId: 3233
|
transactionItemRowId: 3233
|
||||||
transactionItemId: 3f58441e-dc8f-4956-9bc5-c952312476db
|
transactionItemId: 3f58441e-dc8f-4956-9bc5-c952312476db
|
||||||
@ -155,7 +163,9 @@ paths:
|
|||||||
articleNumber: "4051"
|
articleNumber: "4051"
|
||||||
status: returned to src
|
status: returned to src
|
||||||
aggregationReference: FIKO-171f40609e
|
aggregationReference: FIKO-171f40609e
|
||||||
accountingSystemReference: null
|
accountingSystemReference: null
|
||||||
|
createdOn: 2024-11-04T00:00:00Z
|
||||||
|
lastUpdatedOn: 2024-11-04T04:00:00Z
|
||||||
- "@odata.etag": 52130c4d-e944-4454-a73e-8d55449a4bd1
|
- "@odata.etag": 52130c4d-e944-4454-a73e-8d55449a4bd1
|
||||||
transactionItemRowId: 3234
|
transactionItemRowId: 3234
|
||||||
transactionItemId: 4418825f-3f9b-45bc-b662-dc3cd4ce6599
|
transactionItemId: 4418825f-3f9b-45bc-b662-dc3cd4ce6599
|
||||||
@ -174,7 +184,9 @@ paths:
|
|||||||
articleNumber: "4051"
|
articleNumber: "4051"
|
||||||
status: returned to trx-db
|
status: returned to trx-db
|
||||||
aggregationReference: null
|
aggregationReference: null
|
||||||
accountingSystemReference: null
|
accountingSystemReference: null
|
||||||
|
createdOn: 2024-11-04T00:00:00Z
|
||||||
|
lastUpdatedOn: 2024-11-04T04:00:00Z
|
||||||
- "@odata.etag": 7da305e1-85cd-4250-ad77-8b54b2649cfb
|
- "@odata.etag": 7da305e1-85cd-4250-ad77-8b54b2649cfb
|
||||||
transactionItemRowId: 3235
|
transactionItemRowId: 3235
|
||||||
transactionItemId: 2ddc1831-cf7b-4a77-8aa1-11aaf8e98d9f
|
transactionItemId: 2ddc1831-cf7b-4a77-8aa1-11aaf8e98d9f
|
||||||
@ -193,7 +205,9 @@ paths:
|
|||||||
articleNumber: "4051"
|
articleNumber: "4051"
|
||||||
status: re-entered
|
status: re-entered
|
||||||
aggregationReference: null
|
aggregationReference: null
|
||||||
accountingSystemReference: null
|
accountingSystemReference: null
|
||||||
|
createdOn: 2024-11-04T00:00:00Z
|
||||||
|
lastUpdatedOn: 2024-11-04T04:00:00Z
|
||||||
- "@odata.etag": c3b17d21-0506-474d-b3d4-7ff654f368b9
|
- "@odata.etag": c3b17d21-0506-474d-b3d4-7ff654f368b9
|
||||||
transactionItemRowId: 3236
|
transactionItemRowId: 3236
|
||||||
transactionItemId: 5ab2513d-f334-4cf8-8895-4e7269374a4b
|
transactionItemId: 5ab2513d-f334-4cf8-8895-4e7269374a4b
|
||||||
@ -212,7 +226,9 @@ paths:
|
|||||||
articleNumber: "1737"
|
articleNumber: "1737"
|
||||||
status: succeeded
|
status: succeeded
|
||||||
aggregationReference: FIKO-6a4fca8cd6
|
aggregationReference: FIKO-6a4fca8cd6
|
||||||
accountingSystemReference: U4F-123456
|
accountingSystemReference: U4F-123456
|
||||||
|
createdOn: 2024-11-04T00:00:00Z
|
||||||
|
lastUpdatedOn: 2024-11-04T04:00:00Z
|
||||||
security:
|
security:
|
||||||
- default: []
|
- default: []
|
||||||
x-auth-type: Application & Application User
|
x-auth-type: Application & Application User
|
||||||
@ -434,7 +450,7 @@ paths:
|
|||||||
summary: Add a processing failure.
|
summary: Add a processing failure.
|
||||||
description: Add a processing failure.
|
description: Add a processing failure.
|
||||||
tags:
|
tags:
|
||||||
- Failures v2.2
|
- Failures v2.3
|
||||||
requestBody:
|
requestBody:
|
||||||
required: true
|
required: true
|
||||||
content:
|
content:
|
||||||
@ -455,6 +471,7 @@ paths:
|
|||||||
reasonCode: "012"
|
reasonCode: "012"
|
||||||
reasonDescription: Transaction date is in the future.
|
reasonDescription: Transaction date is in the future.
|
||||||
resolved: false
|
resolved: false
|
||||||
|
journalEntryId: 0e53b984-16b2-4ef7-b669-29bcdad2a3ce
|
||||||
responses:
|
responses:
|
||||||
"201":
|
"201":
|
||||||
description: Created
|
description: Created
|
||||||
@ -472,67 +489,6 @@ paths:
|
|||||||
- default: []
|
- default: []
|
||||||
x-auth-type: Application & Application User
|
x-auth-type: Application & Application User
|
||||||
x-throttling-tier: Unlimited
|
x-throttling-tier: Unlimited
|
||||||
/transactionitems/{transactionItemId}/transactionaudittrails:
|
|
||||||
parameters:
|
|
||||||
- in: path
|
|
||||||
name: transactionItemId
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
format: uuid
|
|
||||||
example: 9834b346-d68c-438d-9bd5-6716422c2657
|
|
||||||
required: true
|
|
||||||
description: The id of the transaction item to process.
|
|
||||||
post:
|
|
||||||
summary: Add an audit trail entry.
|
|
||||||
description: Add an audit trail entry.
|
|
||||||
tags:
|
|
||||||
- Audit Trail v2.2
|
|
||||||
requestBody:
|
|
||||||
required: true
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: "#/components/schemas/TransactionAuditTrailsPostRequestBody"
|
|
||||||
examples:
|
|
||||||
Add new transaction audit trail for created transaction item:
|
|
||||||
summary: Add new transaction audit trail for created transaction item
|
|
||||||
description: Add a new audit trail record for a newly created transaction item.
|
|
||||||
value:
|
|
||||||
user: fiko
|
|
||||||
timestamp: 2022-01-01 12:34:00
|
|
||||||
action: create
|
|
||||||
status: created
|
|
||||||
description: Transaction item created.
|
|
||||||
correlationId: null
|
|
||||||
Add new transaction audit trail for updated transaction item:
|
|
||||||
summary: Add new transaction audit trail for updated transaction item
|
|
||||||
description: Add a new audit trail record for an updated transaction item.
|
|
||||||
value:
|
|
||||||
user: ad.vogelaar
|
|
||||||
timestamp: 2022-01-02 12:34:00
|
|
||||||
action: update
|
|
||||||
status: return to src
|
|
||||||
description: Transaction item returned to source.
|
|
||||||
correlationId: 0dc216ea-58e7-4a5e-aa18-449f0304209c
|
|
||||||
responses:
|
|
||||||
"201":
|
|
||||||
description: Created
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: "#/components/schemas/TransactionAuditTrailsPostResponseBody"
|
|
||||||
examples:
|
|
||||||
Transaction audit trail record created:
|
|
||||||
summary: Transaction audit trail record created
|
|
||||||
description: |
|
|
||||||
A new audit trail record for this transaction item was successfully created.
|
|
||||||
The transactionAuditTrailId is returned as a reference for the consumer.
|
|
||||||
value:
|
|
||||||
transactionAuditTrailId: 37a8095b-19db-498f-9349-5f37d21c5bdf
|
|
||||||
security:
|
|
||||||
- default: []
|
|
||||||
x-auth-type: Application & Application User
|
|
||||||
x-throttling-tier: Unlimited
|
|
||||||
/Odata/TransactionAuditTrail:
|
/Odata/TransactionAuditTrail:
|
||||||
get:
|
get:
|
||||||
summary: Find audit trail entries.
|
summary: Find audit trail entries.
|
||||||
@ -564,6 +520,7 @@ paths:
|
|||||||
- action
|
- action
|
||||||
- status
|
- status
|
||||||
- correlationId
|
- correlationId
|
||||||
|
- journalEntryId
|
||||||
- name: $select
|
- name: $select
|
||||||
in: query
|
in: query
|
||||||
description: Select properties to be returned
|
description: Select properties to be returned
|
||||||
@ -584,6 +541,7 @@ paths:
|
|||||||
- action
|
- action
|
||||||
- status
|
- status
|
||||||
- correlationId
|
- correlationId
|
||||||
|
- journalEntryId
|
||||||
- name: $expand
|
- name: $expand
|
||||||
in: query
|
in: query
|
||||||
description: Expand related entities
|
description: Expand related entities
|
||||||
@ -597,6 +555,7 @@ paths:
|
|||||||
type: string
|
type: string
|
||||||
enum:
|
enum:
|
||||||
- TransactionItem
|
- TransactionItem
|
||||||
|
- JournalEntry
|
||||||
responses:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
description: OK
|
description: OK
|
||||||
@ -627,6 +586,7 @@ paths:
|
|||||||
status: created
|
status: created
|
||||||
description: Transaction created.
|
description: Transaction created.
|
||||||
correlationId: null
|
correlationId: null
|
||||||
|
journalEntryId: null
|
||||||
- "@odata.etag": 1ce407d3-4725-46b8-92b2-47282ccd38f5
|
- "@odata.etag": 1ce407d3-4725-46b8-92b2-47282ccd38f5
|
||||||
transactionAuditTrailRowId: 8219
|
transactionAuditTrailRowId: 8219
|
||||||
transactionAuditTrailId: 1d234fc1-eb16-41d3-b2e0-e400e17b017f
|
transactionAuditTrailId: 1d234fc1-eb16-41d3-b2e0-e400e17b017f
|
||||||
@ -637,6 +597,7 @@ paths:
|
|||||||
status: created
|
status: created
|
||||||
description: Transaction created.
|
description: Transaction created.
|
||||||
correlationId: null
|
correlationId: null
|
||||||
|
journalEntryId: null
|
||||||
- "@odata.etag": c8dec28b-bb85-4cb2-8a56-4a95fb2ed7bb
|
- "@odata.etag": c8dec28b-bb85-4cb2-8a56-4a95fb2ed7bb
|
||||||
transactionAuditTrailRowId: 8220
|
transactionAuditTrailRowId: 8220
|
||||||
transactionAuditTrailId: f4798a84-489d-4533-9dfe-42423c70f6b6
|
transactionAuditTrailId: f4798a84-489d-4533-9dfe-42423c70f6b6
|
||||||
@ -647,6 +608,7 @@ paths:
|
|||||||
status: return to src
|
status: return to src
|
||||||
description: Transaction retunred to source.
|
description: Transaction retunred to source.
|
||||||
correlationId: a3891560-3084-42cb-867c-f289e7cda47d
|
correlationId: a3891560-3084-42cb-867c-f289e7cda47d
|
||||||
|
journalEntryId: null
|
||||||
- "@odata.etag": 967ddfa0-835e-4954-a4af-2eb11de325dc
|
- "@odata.etag": 967ddfa0-835e-4954-a4af-2eb11de325dc
|
||||||
transactionAuditTrailRowId: 8221
|
transactionAuditTrailRowId: 8221
|
||||||
transactionAuditTrailId: cc80d58d-6ee7-409a-8c14-b1f807e67c10
|
transactionAuditTrailId: cc80d58d-6ee7-409a-8c14-b1f807e67c10
|
||||||
@ -657,6 +619,7 @@ paths:
|
|||||||
status: failed
|
status: failed
|
||||||
description: Validation XYZ failed.
|
description: Validation XYZ failed.
|
||||||
correlationId: null
|
correlationId: null
|
||||||
|
journalEntryId: a062f64f-f39e-48e7-9793-efbfa86d2827
|
||||||
List containing multiple transaction audit trails of one transaction item:
|
List containing multiple transaction audit trails of one transaction item:
|
||||||
summary: List containing multiple audit trails of one transaction item
|
summary: List containing multiple audit trails of one transaction item
|
||||||
description: List containing multiple audit trail records of one transaction item (with id `d667d293-aa82-4c9e-9b10-77cffc9058a1`).
|
description: List containing multiple audit trail records of one transaction item (with id `d667d293-aa82-4c9e-9b10-77cffc9058a1`).
|
||||||
@ -673,6 +636,7 @@ paths:
|
|||||||
status: re-entered
|
status: re-entered
|
||||||
description: Transaction re-entered.
|
description: Transaction re-entered.
|
||||||
correlationId: null
|
correlationId: null
|
||||||
|
journalEntryId: null
|
||||||
- "@odata.etag": 1ce407d3-4725-46b8-92b2-47282ccd38f5
|
- "@odata.etag": 1ce407d3-4725-46b8-92b2-47282ccd38f5
|
||||||
transactionAuditTrailRowId: 8219
|
transactionAuditTrailRowId: 8219
|
||||||
transactionAuditTrailId: b2192e6c-ab79-4000-a04d-d8f4d574a82f
|
transactionAuditTrailId: b2192e6c-ab79-4000-a04d-d8f4d574a82f
|
||||||
@ -683,6 +647,7 @@ paths:
|
|||||||
status: return to src
|
status: return to src
|
||||||
description: Transaction retunred to source.
|
description: Transaction retunred to source.
|
||||||
correlationId: a3891560-3084-42cb-867c-f289e7cda47d
|
correlationId: a3891560-3084-42cb-867c-f289e7cda47d
|
||||||
|
journalEntryId: null
|
||||||
- "@odata.etag": c8dec28b-bb85-4cb2-8a56-4a95fb2ed7bb
|
- "@odata.etag": c8dec28b-bb85-4cb2-8a56-4a95fb2ed7bb
|
||||||
transactionAuditTrailRowId: 8220
|
transactionAuditTrailRowId: 8220
|
||||||
transactionAuditTrailId: 1d759985-7f1a-48bd-8dd1-efa30ce26423
|
transactionAuditTrailId: 1d759985-7f1a-48bd-8dd1-efa30ce26423
|
||||||
@ -693,6 +658,7 @@ paths:
|
|||||||
status: failed
|
status: failed
|
||||||
description: Validation XYZ failed.
|
description: Validation XYZ failed.
|
||||||
correlationId: null
|
correlationId: null
|
||||||
|
journalEntryId: b479507a-a65d-48b5-8476-87c88ba3c560
|
||||||
- "@odata.etag": 967ddfa0-835e-4954-a4af-2eb11de325dc
|
- "@odata.etag": 967ddfa0-835e-4954-a4af-2eb11de325dc
|
||||||
transactionAuditTrailRowId: 8221
|
transactionAuditTrailRowId: 8221
|
||||||
transactionAuditTrailId: afce35b2-1dff-4ace-98d0-4b9ac405c87d
|
transactionAuditTrailId: afce35b2-1dff-4ace-98d0-4b9ac405c87d
|
||||||
@ -703,6 +669,7 @@ paths:
|
|||||||
status: created
|
status: created
|
||||||
description: Transaction created.
|
description: Transaction created.
|
||||||
correlationId: null
|
correlationId: null
|
||||||
|
journalEntryId: null
|
||||||
List containing multiple audit trails of different failed transactions:
|
List containing multiple audit trails of different failed transactions:
|
||||||
summary: List containing multiple audit trails of different failed transactions
|
summary: List containing multiple audit trails of different failed transactions
|
||||||
description: List containing multiple audit trails of different failed transactions (status = failed).
|
description: List containing multiple audit trails of different failed transactions (status = failed).
|
||||||
@ -719,6 +686,7 @@ paths:
|
|||||||
status: failed
|
status: failed
|
||||||
description: Validation XYZ failed.
|
description: Validation XYZ failed.
|
||||||
correlationId: null
|
correlationId: null
|
||||||
|
journalEntryId: null
|
||||||
- "@odata.etag": 1ce407d3-4725-46b8-92b2-47282ccd38f5
|
- "@odata.etag": 1ce407d3-4725-46b8-92b2-47282ccd38f5
|
||||||
transactionAuditTrailRowId: 8219
|
transactionAuditTrailRowId: 8219
|
||||||
transactionAuditTrailId: 1d234fc1-eb16-41d3-b2e0-e400e17b017f
|
transactionAuditTrailId: 1d234fc1-eb16-41d3-b2e0-e400e17b017f
|
||||||
@ -729,6 +697,7 @@ paths:
|
|||||||
status: failed
|
status: failed
|
||||||
description: Validation XYZ failed.
|
description: Validation XYZ failed.
|
||||||
correlationId: null
|
correlationId: null
|
||||||
|
journalEntryId: 43a98533-bb01-4aad-8d61-005051125969
|
||||||
- "@odata.etag": c8dec28b-bb85-4cb2-8a56-4a95fb2ed7bb
|
- "@odata.etag": c8dec28b-bb85-4cb2-8a56-4a95fb2ed7bb
|
||||||
transactionAuditTrailRowId: 8220
|
transactionAuditTrailRowId: 8220
|
||||||
transactionAuditTrailId: f4798a84-489d-4533-9dfe-42423c70f6b6
|
transactionAuditTrailId: f4798a84-489d-4533-9dfe-42423c70f6b6
|
||||||
@ -739,6 +708,7 @@ paths:
|
|||||||
status: failed
|
status: failed
|
||||||
description: Validation XYZ failed.
|
description: Validation XYZ failed.
|
||||||
correlationId: null
|
correlationId: null
|
||||||
|
journalEntryId: null
|
||||||
- "@odata.etag": 967ddfa0-835e-4954-a4af-2eb11de325dc
|
- "@odata.etag": 967ddfa0-835e-4954-a4af-2eb11de325dc
|
||||||
transactionAuditTrailRowId: 8221
|
transactionAuditTrailRowId: 8221
|
||||||
transactionAuditTrailId: cc80d58d-6ee7-409a-8c14-b1f807e67c10
|
transactionAuditTrailId: cc80d58d-6ee7-409a-8c14-b1f807e67c10
|
||||||
@ -749,6 +719,7 @@ paths:
|
|||||||
status: failed
|
status: failed
|
||||||
description: Validation XYZ failed.
|
description: Validation XYZ failed.
|
||||||
correlationId: null
|
correlationId: null
|
||||||
|
journalEntryId: null
|
||||||
security:
|
security:
|
||||||
- default: []
|
- default: []
|
||||||
x-auth-type: Application & Application User
|
x-auth-type: Application & Application User
|
||||||
@ -786,6 +757,7 @@ paths:
|
|||||||
- reasonDescription
|
- reasonDescription
|
||||||
- resolved
|
- resolved
|
||||||
- change
|
- change
|
||||||
|
- journalEntryId
|
||||||
- name: $select
|
- name: $select
|
||||||
in: query
|
in: query
|
||||||
description: Select properties to be returned
|
description: Select properties to be returned
|
||||||
@ -808,6 +780,7 @@ paths:
|
|||||||
- reasonDescription
|
- reasonDescription
|
||||||
- resolved
|
- resolved
|
||||||
- change
|
- change
|
||||||
|
- journalEntryId
|
||||||
- name: $expand
|
- name: $expand
|
||||||
in: query
|
in: query
|
||||||
description: Expand related entities
|
description: Expand related entities
|
||||||
@ -820,7 +793,8 @@ paths:
|
|||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
enum:
|
enum:
|
||||||
- TransactionItem
|
- TransactionItem
|
||||||
|
- JournalEntry
|
||||||
responses:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
description: OK
|
description: OK
|
||||||
@ -856,6 +830,7 @@ paths:
|
|||||||
reasonDescription: Cost type does not exist.
|
reasonDescription: Cost type does not exist.
|
||||||
resolved: false
|
resolved: false
|
||||||
change: null
|
change: null
|
||||||
|
journalEntryId: null
|
||||||
- "@odata.etag": ff49829d-a5de-4c1a-b331-15fd9c71dfe9
|
- "@odata.etag": ff49829d-a5de-4c1a-b331-15fd9c71dfe9
|
||||||
processingFailureRowId: 10
|
processingFailureRowId: 10
|
||||||
processingFailureId: ccc06dc9-956d-47d8-bde7-9644ddde2193
|
processingFailureId: ccc06dc9-956d-47d8-bde7-9644ddde2193
|
||||||
@ -866,7 +841,8 @@ paths:
|
|||||||
reasonCode: "002"
|
reasonCode: "002"
|
||||||
reasonDescription: Cost center does not exist.
|
reasonDescription: Cost center does not exist.
|
||||||
resolved: true
|
resolved: true
|
||||||
change: Adapt config
|
change: Adapt config
|
||||||
|
journalEntryId: null
|
||||||
- "@odata.etag": 5d5d3351-d3f1-49b2-905f-4dbbe1cc30e3
|
- "@odata.etag": 5d5d3351-d3f1-49b2-905f-4dbbe1cc30e3
|
||||||
processingFailureRowId: 11
|
processingFailureRowId: 11
|
||||||
processingFailureId: 96bf8d44-0030-4509-b24e-2d62299779c5
|
processingFailureId: 96bf8d44-0030-4509-b24e-2d62299779c5
|
||||||
@ -877,7 +853,8 @@ paths:
|
|||||||
reasonCode: "001"
|
reasonCode: "001"
|
||||||
reasonDescription: Department does not exist.
|
reasonDescription: Department does not exist.
|
||||||
resolved: true
|
resolved: true
|
||||||
change: Adapt config
|
change: Adapt config
|
||||||
|
journalEntryId: null
|
||||||
List of unfiltered processing failures:
|
List of unfiltered processing failures:
|
||||||
summary: List of unfiltered processing failures
|
summary: List of unfiltered processing failures
|
||||||
description: |
|
description: |
|
||||||
@ -896,7 +873,8 @@ paths:
|
|||||||
reasonCode: "009"
|
reasonCode: "009"
|
||||||
reasonDescription: Transaction date is in the future
|
reasonDescription: Transaction date is in the future
|
||||||
resolved: false
|
resolved: false
|
||||||
change: null
|
change: null
|
||||||
|
journalEntryId: null
|
||||||
- "@odata.etag": 584d3a8a-48bc-45f9-99be-8dd70399e6e4
|
- "@odata.etag": 584d3a8a-48bc-45f9-99be-8dd70399e6e4
|
||||||
processingFailureRowId: 10
|
processingFailureRowId: 10
|
||||||
processingFailureId: 76aa82e1-a10f-4664-a84f-1f30d60884b3
|
processingFailureId: 76aa82e1-a10f-4664-a84f-1f30d60884b3
|
||||||
@ -907,7 +885,8 @@ paths:
|
|||||||
reasonCode: "002"
|
reasonCode: "002"
|
||||||
reasonDescription: Cost center does not exist.
|
reasonDescription: Cost center does not exist.
|
||||||
resolved: false
|
resolved: false
|
||||||
change: null
|
change: null
|
||||||
|
journalEntryId: null
|
||||||
- "@odata.etag": df4ade9b-1bda-4d91-a5ba-4dbe067568a0
|
- "@odata.etag": df4ade9b-1bda-4d91-a5ba-4dbe067568a0
|
||||||
processingFailureRowId: 11
|
processingFailureRowId: 11
|
||||||
processingFailureId: 25d2dd6f-ae17-44a7-b7a5-43eaf6de78e1
|
processingFailureId: 25d2dd6f-ae17-44a7-b7a5-43eaf6de78e1
|
||||||
@ -918,7 +897,8 @@ paths:
|
|||||||
reasonCode: "001"
|
reasonCode: "001"
|
||||||
reasonDescription: Department does not exist.
|
reasonDescription: Department does not exist.
|
||||||
resolved: false
|
resolved: false
|
||||||
change: null
|
change: null
|
||||||
|
journalEntryId: null
|
||||||
security:
|
security:
|
||||||
- default: []
|
- default: []
|
||||||
x-auth-type: Application & Application User
|
x-auth-type: Application & Application User
|
||||||
@ -969,6 +949,415 @@ paths:
|
|||||||
- default: []
|
- default: []
|
||||||
x-auth-type: Application & Application User
|
x-auth-type: Application & Application User
|
||||||
x-throttling-tier: Unlimited
|
x-throttling-tier: Unlimited
|
||||||
|
/Odata/JournalEntries:
|
||||||
|
get:
|
||||||
|
summary: Find journalEntry.
|
||||||
|
description: Find journalEntry.
|
||||||
|
tags:
|
||||||
|
- Odata
|
||||||
|
parameters:
|
||||||
|
- $ref: "#/components/parameters/top"
|
||||||
|
- $ref: "#/components/parameters/skip"
|
||||||
|
- $ref: "#/components/parameters/filter"
|
||||||
|
- $ref: "#/components/parameters/count"
|
||||||
|
- name: $orderby
|
||||||
|
in: query
|
||||||
|
description: Order items by property values
|
||||||
|
required: false
|
||||||
|
style: form
|
||||||
|
explode: false
|
||||||
|
schema:
|
||||||
|
uniqueItems: true
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
enum:
|
||||||
|
- journalEntryId
|
||||||
|
- aggregationReference
|
||||||
|
- accountingSystemReference
|
||||||
|
- name: $select
|
||||||
|
in: query
|
||||||
|
description: Select properties to be returned
|
||||||
|
required: false
|
||||||
|
style: form
|
||||||
|
explode: false
|
||||||
|
schema:
|
||||||
|
uniqueItems: true
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
enum:
|
||||||
|
- journalEntryId
|
||||||
|
- aggregationReference
|
||||||
|
- accountingSystemReference
|
||||||
|
- data
|
||||||
|
- response
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/JournalEntryGetResponseBody"
|
||||||
|
examples:
|
||||||
|
List containing all journal entries:
|
||||||
|
summary: List containing all journal entries
|
||||||
|
description: Returns a list containing all journal entries (no filters applied).
|
||||||
|
value:
|
||||||
|
"@odata.context": "$metadata#JournalEntry"
|
||||||
|
value:
|
||||||
|
- "@odata.etag": 8f085711-eeae-44ed-bac1-06779bedb480
|
||||||
|
journalEntryId: e0af8c8f-d421-4567-a14e-48e2a1bb86fb
|
||||||
|
aggregationReference: FIKO-123456
|
||||||
|
accountingSystemReference: null
|
||||||
|
data: {
|
||||||
|
"transaction": {
|
||||||
|
"header": {
|
||||||
|
"key": {
|
||||||
|
"cmpCode": "1HTM",
|
||||||
|
"code": "OPBR-FIKO"
|
||||||
|
},
|
||||||
|
"timeStamp": 0,
|
||||||
|
"inputDate": "2026-07-20T00:00:00Z",
|
||||||
|
"period": "2026/6",
|
||||||
|
"curCode": "EUR",
|
||||||
|
"date": "2026-07-20T00:00:00Z",
|
||||||
|
"originalCompany": "1HTM",
|
||||||
|
"originalCode": "OPBR-FIKO",
|
||||||
|
"completionWorkflow": {
|
||||||
|
"completionStatus": "wfl_no_completion"
|
||||||
|
},
|
||||||
|
"salesInvoiceStatus": "salesinv_notyetinv"
|
||||||
|
},
|
||||||
|
"lines": {
|
||||||
|
"line": [
|
||||||
|
{
|
||||||
|
"number": 1,
|
||||||
|
"accountCode": "100.99999.D150000001",
|
||||||
|
"docValue": 100.00,
|
||||||
|
"lineType": "summary",
|
||||||
|
"lineSense": "debit",
|
||||||
|
"lineOrigin": "dl_orig_defined",
|
||||||
|
"description": "test",
|
||||||
|
"extRef1": "99999991",
|
||||||
|
"extRef2": "99999",
|
||||||
|
"sepaPaymentCategoryPurposeCode": "none",
|
||||||
|
"sepaPaymentPurposeCode": "none"
|
||||||
|
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"number": 2,
|
||||||
|
"accountCode": "642.41236.609311",
|
||||||
|
"docValue": 100.00,
|
||||||
|
"userStatus": "",
|
||||||
|
"lineType": "analysis",
|
||||||
|
"lineSense": "credit",
|
||||||
|
"lineOrigin": "dl_orig_defined",
|
||||||
|
"sepaPaymentCategoryPurposeCode": "none",
|
||||||
|
"sepaPaymentPurposeCode": "none"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
response: {
|
||||||
|
"status": "failed",
|
||||||
|
"message": [
|
||||||
|
{
|
||||||
|
"code": "352",
|
||||||
|
"reason": "Documentregel 1 kan niet geboekt worden."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "159",
|
||||||
|
"reason": "Element 99999 (niveau 2) is niet toegestaan in linkerlijst van element D150000001 (niveau 3)."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"hints": [],
|
||||||
|
"paths": [
|
||||||
|
"/InputRequest/PostToBooks/Request/Transaction/Lines/Line[1]/AccountCode"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
- "@odata.etag": 66c033af-fc67-4eb2-9d17-d74a0166470f
|
||||||
|
journalEntryId: 36a34bd8-2b84-4c89-87a4-22e809f6ed4a
|
||||||
|
aggregationReference: FIKO-123457
|
||||||
|
accountingSystemReference: "OPBR-FIKO10000090"
|
||||||
|
data: {
|
||||||
|
"transaction": {
|
||||||
|
"header": {
|
||||||
|
"key": {
|
||||||
|
"cmpCode": "1HTM",
|
||||||
|
"code": "OPBR-FIKO"
|
||||||
|
},
|
||||||
|
"timeStamp": 0,
|
||||||
|
"inputDate": "2026-07-20T00:00:00Z",
|
||||||
|
"period": "2026/6",
|
||||||
|
"curCode": "EUR",
|
||||||
|
"date": "2026-07-20T00:00:00Z",
|
||||||
|
"originalCompany": "1HTM",
|
||||||
|
"originalCode": "OPBR-FIKO",
|
||||||
|
"completionWorkflow": {
|
||||||
|
"completionStatus": "wfl_no_completion"
|
||||||
|
},
|
||||||
|
"salesInvoiceStatus": "salesinv_notyetinv"
|
||||||
|
},
|
||||||
|
"lines": {
|
||||||
|
"line": [
|
||||||
|
{
|
||||||
|
"number": 1,
|
||||||
|
"accountCode": "100.99999.D150000001",
|
||||||
|
"docValue": 100.00,
|
||||||
|
"lineType": "summary",
|
||||||
|
"lineSense": "debit",
|
||||||
|
"lineOrigin": "dl_orig_defined",
|
||||||
|
"description": "test",
|
||||||
|
"extRef1": "99999991",
|
||||||
|
"extRef2": "99999",
|
||||||
|
"sepaPaymentCategoryPurposeCode": "none",
|
||||||
|
"sepaPaymentPurposeCode": "none"
|
||||||
|
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"number": 2,
|
||||||
|
"accountCode": "642.41236.609311",
|
||||||
|
"docValue": 100.00,
|
||||||
|
"userStatus": "",
|
||||||
|
"lineType": "analysis",
|
||||||
|
"lineSense": "credit",
|
||||||
|
"lineOrigin": "dl_orig_defined",
|
||||||
|
"sepaPaymentCategoryPurposeCode": "none",
|
||||||
|
"sepaPaymentPurposeCode": "none"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
response: {
|
||||||
|
"key": {
|
||||||
|
"$type": "finance_transaction_txnKey",
|
||||||
|
"cmpCode": "1HTM",
|
||||||
|
"code": "OPBR-FIKO",
|
||||||
|
"number": " 10000090"
|
||||||
|
},
|
||||||
|
"suppliedNumber": ""
|
||||||
|
}
|
||||||
|
- "@odata.etag": 159f526c-3c88-48a1-93a0-e16430500bef
|
||||||
|
journalEntryId: 6097121f-f300-4c0b-ab8d-0a24685bda92
|
||||||
|
aggregationReference: FIKO-123458
|
||||||
|
accountingSystemReference: null
|
||||||
|
data: {
|
||||||
|
"transaction": {
|
||||||
|
"header": {
|
||||||
|
"key": {
|
||||||
|
"cmpCode": "1HTM",
|
||||||
|
"code": "OPBR-FIKO"
|
||||||
|
},
|
||||||
|
"timeStamp": 0,
|
||||||
|
"inputDate": "2026-07-20T00:00:00Z",
|
||||||
|
"period": "2026/6",
|
||||||
|
"curCode": "EUR",
|
||||||
|
"date": "2026-07-20T00:00:00Z",
|
||||||
|
"originalCompany": "1HTM",
|
||||||
|
"originalCode": "OPBR-FIKO",
|
||||||
|
"completionWorkflow": {
|
||||||
|
"completionStatus": "wfl_no_completion"
|
||||||
|
},
|
||||||
|
"salesInvoiceStatus": "salesinv_notyetinv"
|
||||||
|
},
|
||||||
|
"lines": {
|
||||||
|
"line": [
|
||||||
|
{
|
||||||
|
"number": 1,
|
||||||
|
"accountCode": "100.99999.D150000001",
|
||||||
|
"docValue": 100.00,
|
||||||
|
"lineType": "summary",
|
||||||
|
"lineSense": "debit",
|
||||||
|
"lineOrigin": "dl_orig_defined",
|
||||||
|
"description": "test",
|
||||||
|
"extRef1": "99999991",
|
||||||
|
"extRef2": "99999",
|
||||||
|
"sepaPaymentCategoryPurposeCode": "none",
|
||||||
|
"sepaPaymentPurposeCode": "none"
|
||||||
|
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"number": 2,
|
||||||
|
"accountCode": "642.41236.609311",
|
||||||
|
"docValue": 100.00,
|
||||||
|
"userStatus": "",
|
||||||
|
"lineType": "analysis",
|
||||||
|
"lineSense": "credit",
|
||||||
|
"lineOrigin": "dl_orig_defined",
|
||||||
|
"sepaPaymentCategoryPurposeCode": "none",
|
||||||
|
"sepaPaymentPurposeCode": "none"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
response: null
|
||||||
|
security:
|
||||||
|
- default: []
|
||||||
|
x-auth-type: Application & Application User
|
||||||
|
x-throttling-tier: Unlimited
|
||||||
|
/journalEntries:
|
||||||
|
post:
|
||||||
|
summary: Add a journalEntry.
|
||||||
|
description: Add a journalEntry.
|
||||||
|
tags:
|
||||||
|
- journalEntries v1.0
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/JournalEntryPostRequestBody"
|
||||||
|
examples:
|
||||||
|
Add a new journalEntry:
|
||||||
|
summary: Add a new journalEntry
|
||||||
|
description: In this example we add a new journalEntry.
|
||||||
|
value:
|
||||||
|
aggregationReference: FIKO-123456
|
||||||
|
data: {
|
||||||
|
"transaction": {
|
||||||
|
"header": {
|
||||||
|
"key": {
|
||||||
|
"cmpCode": "1HTM",
|
||||||
|
"code": "OPBR-FIKO"
|
||||||
|
},
|
||||||
|
"timeStamp": 0,
|
||||||
|
"inputDate": "2026-07-20T00:00:00Z",
|
||||||
|
"period": "2026/6",
|
||||||
|
"curCode": "EUR",
|
||||||
|
"date": "2026-07-20T00:00:00Z",
|
||||||
|
"originalCompany": "1HTM",
|
||||||
|
"originalCode": "OPBR-FIKO",
|
||||||
|
"completionWorkflow": {
|
||||||
|
"completionStatus": "wfl_no_completion"
|
||||||
|
},
|
||||||
|
"salesInvoiceStatus": "salesinv_notyetinv"
|
||||||
|
},
|
||||||
|
"lines": {
|
||||||
|
"line": [
|
||||||
|
{
|
||||||
|
"number": 1,
|
||||||
|
"accountCode": "100.99999.D150000001",
|
||||||
|
"docValue": 100.00,
|
||||||
|
"lineType": "summary",
|
||||||
|
"lineSense": "debit",
|
||||||
|
"lineOrigin": "dl_orig_defined",
|
||||||
|
"description": "test",
|
||||||
|
"extRef1": "99999991",
|
||||||
|
"extRef2": "99999",
|
||||||
|
"sepaPaymentCategoryPurposeCode": "none",
|
||||||
|
"sepaPaymentPurposeCode": "none"
|
||||||
|
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"number": 2,
|
||||||
|
"accountCode": "642.41236.609311",
|
||||||
|
"docValue": 100.00,
|
||||||
|
"userStatus": "",
|
||||||
|
"lineType": "analysis",
|
||||||
|
"lineSense": "credit",
|
||||||
|
"lineOrigin": "dl_orig_defined",
|
||||||
|
"sepaPaymentCategoryPurposeCode": "none",
|
||||||
|
"sepaPaymentPurposeCode": "none"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
responses:
|
||||||
|
"201":
|
||||||
|
description: Created
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/JournalEntryPostResponseBody"
|
||||||
|
examples:
|
||||||
|
Journalentry created successfully:
|
||||||
|
summary: Journalentry created successfully
|
||||||
|
description: TheJournalentry was successfully added to the database.
|
||||||
|
value:
|
||||||
|
journalEntryId: 6ce10520-9a73-4cb4-b8dd-39ee46ceb617
|
||||||
|
security:
|
||||||
|
- default: []
|
||||||
|
x-auth-type: Application & Application User
|
||||||
|
x-throttling-tier: Unlimited
|
||||||
|
/journalEntries/{journalEntryId}:
|
||||||
|
parameters:
|
||||||
|
- in: path
|
||||||
|
name: journalEntryId
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
format: uuid
|
||||||
|
example: 37a8095b-19db-498f-9349-5f37d21c5bdf
|
||||||
|
required: true
|
||||||
|
description: The id of the journalEntry.
|
||||||
|
patch:
|
||||||
|
summary: Update journalEntry.
|
||||||
|
description: Update journalEntry.
|
||||||
|
tags:
|
||||||
|
- journalEntries v1.0
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/JournalEntryPatchRequestBody"
|
||||||
|
examples:
|
||||||
|
Update an journalEntry after error:
|
||||||
|
summary: Update an journalEntry after error
|
||||||
|
description: Update an journalEntry after error by logging the response
|
||||||
|
value:
|
||||||
|
response: {
|
||||||
|
"status": "failed",
|
||||||
|
"message": [
|
||||||
|
{
|
||||||
|
"code": "352",
|
||||||
|
"reason": "Documentregel 1 kan niet geboekt worden."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "159",
|
||||||
|
"reason": "Element 99999 (niveau 2) is niet toegestaan in linkerlijst van element D150000001 (niveau 3)."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"hints": [],
|
||||||
|
"paths": [
|
||||||
|
"/InputRequest/PostToBooks/Request/Transaction/Lines/Line[1]/AccountCode"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
Update an journalEntry after success:
|
||||||
|
summary: Update an journalEntry after succesfull call
|
||||||
|
description: Update an journalEntry after uccesfull call bij logging the response and the accountingSystemReference.
|
||||||
|
value:
|
||||||
|
accountingSystemReference: "OPBR-FIKO10000090"
|
||||||
|
response: {
|
||||||
|
"key": {
|
||||||
|
"$type": "finance_transaction_txnKey",
|
||||||
|
"cmpCode": "1HTM",
|
||||||
|
"code": "OPBR-FIKO",
|
||||||
|
"number": " 10000090"
|
||||||
|
},
|
||||||
|
"suppliedNumber": ""
|
||||||
|
}
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/JournalEntryPatchResponseBody"
|
||||||
|
examples:
|
||||||
|
JournalEntry updated successfully:
|
||||||
|
summary: JournalEntry updated successfully
|
||||||
|
description: The journalEntry was successfully updated in the database.
|
||||||
|
value:
|
||||||
|
journalEntryId: 5bbf5abc-4da5-4bb4-894e-a7f553789a20
|
||||||
|
security:
|
||||||
|
- default: []
|
||||||
|
x-auth-type: Application & Application User
|
||||||
|
x-throttling-tier: Unlimited
|
||||||
/Odata/BookingProcess:
|
/Odata/BookingProcess:
|
||||||
get:
|
get:
|
||||||
summary: Find booking processes.
|
summary: Find booking processes.
|
||||||
@ -3316,6 +3705,16 @@ components:
|
|||||||
- occurredOn
|
- occurredOn
|
||||||
- type
|
- type
|
||||||
- status
|
- status
|
||||||
|
createdOn:
|
||||||
|
type: string
|
||||||
|
nullable: false
|
||||||
|
format: datetime
|
||||||
|
example: "2026-07-20T00:00:00Z"
|
||||||
|
updatedOn:
|
||||||
|
type: string
|
||||||
|
nullable: false
|
||||||
|
format: datetime
|
||||||
|
example: "2026-07-25T00:00:00Z"
|
||||||
TransactionItemsBulkRequestBody:
|
TransactionItemsBulkRequestBody:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
@ -3551,6 +3950,11 @@ components:
|
|||||||
type: string
|
type: string
|
||||||
nullable: true
|
nullable: true
|
||||||
example: Adapt config
|
example: Adapt config
|
||||||
|
journalEntryId:
|
||||||
|
type: string
|
||||||
|
format: uuid
|
||||||
|
nullable: true
|
||||||
|
example: b51b377d-6c82-4c4f-9ed3-1068ab6e30c9
|
||||||
required:
|
required:
|
||||||
- timestamp
|
- timestamp
|
||||||
- element
|
- element
|
||||||
@ -3617,6 +4021,11 @@ components:
|
|||||||
type: string
|
type: string
|
||||||
nullable: true
|
nullable: true
|
||||||
example: Adapt config
|
example: Adapt config
|
||||||
|
journalEntryId:
|
||||||
|
type: string
|
||||||
|
format: uuid
|
||||||
|
nullable: true
|
||||||
|
example: b51b377d-6c82-4c4f-9ed3-1068ab6e30c9
|
||||||
required:
|
required:
|
||||||
- processingFailureId
|
- processingFailureId
|
||||||
- transactionItemId
|
- transactionItemId
|
||||||
@ -3681,6 +4090,11 @@ components:
|
|||||||
format: uuid
|
format: uuid
|
||||||
nullable: true
|
nullable: true
|
||||||
example: 37a8095b-19db-498f-9349-5f37d21c5bdf
|
example: 37a8095b-19db-498f-9349-5f37d21c5bdf
|
||||||
|
journalEntryId:
|
||||||
|
type: string
|
||||||
|
format: uuid
|
||||||
|
nullable: true
|
||||||
|
example: b51b377d-6c82-4c4f-9ed3-1068ab6e30c9
|
||||||
required:
|
required:
|
||||||
- user
|
- user
|
||||||
- timestamp
|
- timestamp
|
||||||
@ -3754,6 +4168,11 @@ components:
|
|||||||
format: uuid
|
format: uuid
|
||||||
nullable: true
|
nullable: true
|
||||||
example: a3891560-3084-42cb-867c-f289e7cda47d
|
example: a3891560-3084-42cb-867c-f289e7cda47d
|
||||||
|
journalEntryId:
|
||||||
|
type: string
|
||||||
|
format: uuid
|
||||||
|
nullable: true
|
||||||
|
example: b51b377d-6c82-4c4f-9ed3-1068ab6e30c9
|
||||||
required:
|
required:
|
||||||
- transactionAuditTrailId
|
- transactionAuditTrailId
|
||||||
- transactionItemId
|
- transactionItemId
|
||||||
@ -3761,6 +4180,89 @@ components:
|
|||||||
- timestamp
|
- timestamp
|
||||||
- action
|
- action
|
||||||
- status
|
- status
|
||||||
|
JournalEntryGetResponseBody:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
"@odata.context":
|
||||||
|
type: string
|
||||||
|
example: $metadata#JournalEntry
|
||||||
|
value:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: "#/components/schemas/JournalEntry"
|
||||||
|
JournalEntry:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
"@odata.etag":
|
||||||
|
type: string
|
||||||
|
example: 333d6b7d-b709-3b89-89e0-bcb3d5fdddfc
|
||||||
|
journalEntryId:
|
||||||
|
type: string
|
||||||
|
format: uuid
|
||||||
|
example: 8871d779-512c-4d4d-9a8a-dee7c635179d
|
||||||
|
aggregationReference:
|
||||||
|
type: string
|
||||||
|
example: FIKO-123456
|
||||||
|
accountingSystemReference:
|
||||||
|
type: string
|
||||||
|
nullable: true
|
||||||
|
example: U4F-123456
|
||||||
|
data:
|
||||||
|
type: object
|
||||||
|
example: {}
|
||||||
|
responses:
|
||||||
|
type: object
|
||||||
|
nullable: true
|
||||||
|
example: {}
|
||||||
|
required:
|
||||||
|
- journalEntryId
|
||||||
|
- aggregationReference
|
||||||
|
- data
|
||||||
|
JournalEntryPostRequestBody:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
aggregationReference:
|
||||||
|
type: string
|
||||||
|
example: FIKO-123456
|
||||||
|
accountingSystemReference:
|
||||||
|
type: string
|
||||||
|
nullable: true
|
||||||
|
example: U4F-123456
|
||||||
|
data:
|
||||||
|
type: object
|
||||||
|
example: {}
|
||||||
|
responses:
|
||||||
|
type: object
|
||||||
|
nullable: true
|
||||||
|
example: {}
|
||||||
|
required:
|
||||||
|
- aggregationReference
|
||||||
|
- data
|
||||||
|
JournalEntryPostResponseBody:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
journalEntryId:
|
||||||
|
type: string
|
||||||
|
format: uuid
|
||||||
|
example: c97a8123-8d0e-41ea-9737-35843ebe2385
|
||||||
|
JournalEntryPatchRequestBody:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
accountingSystemReference:
|
||||||
|
type: string
|
||||||
|
nullable: true
|
||||||
|
example: U4F-123456
|
||||||
|
responses:
|
||||||
|
type: object
|
||||||
|
nullable: true
|
||||||
|
example: {}
|
||||||
|
JournalEntryPatchResponseBody:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
journalEntryId:
|
||||||
|
type: string
|
||||||
|
format: uuid
|
||||||
|
example: c97a8123-8d0e-41ea-9737-35843ebe2385
|
||||||
BookingProcessesGetResponseBody:
|
BookingProcessesGetResponseBody:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
|
|||||||
@ -111,14 +111,6 @@ paths:
|
|||||||
explode: false
|
explode: false
|
||||||
required: false
|
required: false
|
||||||
description: Filter on most recent order status. 1 = concept, 2 = awaitingPayment, 3 = pendingPayment, 4 = paid, 5 = delivered, 6 = cancelled.
|
description: Filter on most recent order status. 1 = concept, 2 = awaitingPayment, 3 = pendingPayment, 4 = paid, 5 = delivered, 6 = cancelled.
|
||||||
- in: query
|
|
||||||
name: issuedVoucherId
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
format: uuid
|
|
||||||
example: "b0a9f3c9-9b92-4f8c-b78d-6129be7218a6"
|
|
||||||
required: false
|
|
||||||
description: Filter on applied issuedVoucherId for the order.
|
|
||||||
responses:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
description: OK
|
description: OK
|
||||||
@ -777,6 +769,13 @@ paths:
|
|||||||
example: 9e3363c8-e776-4675-b108-99b8c2e38eb6
|
example: 9e3363c8-e776-4675-b108-99b8c2e38eb6
|
||||||
required: false
|
required: false
|
||||||
description: The id of the orderLine
|
description: The id of the orderLine
|
||||||
|
- in: query
|
||||||
|
name: issuedVoucherId
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
example: 9e3363c8-e776-4675-b108-99b8c2e38eb6
|
||||||
|
required: false
|
||||||
|
description: The id of the issuedVoucher
|
||||||
get:
|
get:
|
||||||
summary: Find vouchers on the order
|
summary: Find vouchers on the order
|
||||||
description: Find vouchers on the order
|
description: Find vouchers on the order
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -313,6 +313,7 @@ paths:
|
|||||||
{
|
{
|
||||||
"productId": 24,
|
"productId": 24,
|
||||||
"parentProductId": null,
|
"parentProductId": null,
|
||||||
|
"needsVoucher": false,
|
||||||
"layerInfo": null,
|
"layerInfo": null,
|
||||||
"fikoArticleNumber": "1234",
|
"fikoArticleNumber": "1234",
|
||||||
"gboPackageTemplateId": "30901",
|
"gboPackageTemplateId": "30901",
|
||||||
@ -429,6 +430,7 @@ paths:
|
|||||||
{
|
{
|
||||||
"productId": 126,
|
"productId": 126,
|
||||||
"parentProductId": null,
|
"parentProductId": null,
|
||||||
|
"needsVoucher": false,
|
||||||
"layerInfo": {
|
"layerInfo": {
|
||||||
"layerInfoId": 1,
|
"layerInfoId": 1,
|
||||||
"choiceKey": "isRenewable",
|
"choiceKey": "isRenewable",
|
||||||
@ -537,6 +539,7 @@ paths:
|
|||||||
{
|
{
|
||||||
"productId": 119,
|
"productId": 119,
|
||||||
"parentProductId": 126,
|
"parentProductId": 126,
|
||||||
|
"needsVoucher": false,
|
||||||
"layerInfo": null,
|
"layerInfo": null,
|
||||||
"fikoArticleNumber": "1234",
|
"fikoArticleNumber": "1234",
|
||||||
"gboPackageTemplateId": "30001",
|
"gboPackageTemplateId": "30001",
|
||||||
@ -652,6 +655,7 @@ paths:
|
|||||||
{
|
{
|
||||||
"productId": 120,
|
"productId": 120,
|
||||||
"parentProductId": 126,
|
"parentProductId": 126,
|
||||||
|
"needsVoucher": false,
|
||||||
"layerInfo": null,
|
"layerInfo": null,
|
||||||
"fikoArticleNumber": "1234",
|
"fikoArticleNumber": "1234",
|
||||||
"gboPackageTemplateId": "30001",
|
"gboPackageTemplateId": "30001",
|
||||||
@ -779,6 +783,7 @@ paths:
|
|||||||
{
|
{
|
||||||
"productId": 49,
|
"productId": 49,
|
||||||
"parentProductId": null,
|
"parentProductId": null,
|
||||||
|
"needsVoucher": false,
|
||||||
"layerInfo": {
|
"layerInfo": {
|
||||||
"layerInfoId": 2,
|
"layerInfoId": 2,
|
||||||
"choiceKey": "regio",
|
"choiceKey": "regio",
|
||||||
@ -926,6 +931,7 @@ paths:
|
|||||||
{
|
{
|
||||||
"productId": 109,
|
"productId": 109,
|
||||||
"parentProductId": 49,
|
"parentProductId": 49,
|
||||||
|
"needsVoucher": false,
|
||||||
"layerInfo": {
|
"layerInfo": {
|
||||||
"layerInfoId": 3,
|
"layerInfoId": 3,
|
||||||
"choiceKey": "allowedGboAgeProfiles",
|
"choiceKey": "allowedGboAgeProfiles",
|
||||||
@ -1076,6 +1082,7 @@ paths:
|
|||||||
{
|
{
|
||||||
"productId": 114,
|
"productId": 114,
|
||||||
"parentProductId": 109,
|
"parentProductId": 109,
|
||||||
|
"needsVoucher": false,
|
||||||
"layerInfo": {
|
"layerInfo": {
|
||||||
"layerInfoId": 1,
|
"layerInfoId": 1,
|
||||||
"choiceKey": "isRenewable",
|
"choiceKey": "isRenewable",
|
||||||
@ -1226,6 +1233,7 @@ paths:
|
|||||||
{
|
{
|
||||||
"productId": 115,
|
"productId": 115,
|
||||||
"parentProductId": 109,
|
"parentProductId": 109,
|
||||||
|
"needsVoucher": false,
|
||||||
"layerInfo": {
|
"layerInfo": {
|
||||||
"layerInfoId": 1,
|
"layerInfoId": 1,
|
||||||
"choiceKey": "isRenewable",
|
"choiceKey": "isRenewable",
|
||||||
@ -1377,6 +1385,7 @@ paths:
|
|||||||
{
|
{
|
||||||
"productId": 116,
|
"productId": 116,
|
||||||
"parentProductId": 115,
|
"parentProductId": 115,
|
||||||
|
"needsVoucher": false,
|
||||||
"layerInfo": null,
|
"layerInfo": null,
|
||||||
"fikoArticleNumber": "1234",
|
"fikoArticleNumber": "1234",
|
||||||
"gboPackageTemplateId": "33615",
|
"gboPackageTemplateId": "33615",
|
||||||
@ -1526,6 +1535,7 @@ paths:
|
|||||||
{
|
{
|
||||||
"productId": 117,
|
"productId": 117,
|
||||||
"parentProductId": 115,
|
"parentProductId": 115,
|
||||||
|
"needsVoucher": false,
|
||||||
"layerInfo": null,
|
"layerInfo": null,
|
||||||
"fikoArticleNumber": "1234",
|
"fikoArticleNumber": "1234",
|
||||||
"gboPackageTemplateId": "33615",
|
"gboPackageTemplateId": "33615",
|
||||||
@ -1679,6 +1689,7 @@ paths:
|
|||||||
{
|
{
|
||||||
"productId": 112,
|
"productId": 112,
|
||||||
"parentProductId": 49,
|
"parentProductId": 49,
|
||||||
|
"needsVoucher": false,
|
||||||
"layerInfo": {
|
"layerInfo": {
|
||||||
"layerInfoId": 3,
|
"layerInfoId": 3,
|
||||||
"choiceKey": "allowedGboAgeProfiles",
|
"choiceKey": "allowedGboAgeProfiles",
|
||||||
@ -2150,6 +2161,10 @@ components:
|
|||||||
parentProductId:
|
parentProductId:
|
||||||
type: integer
|
type: integer
|
||||||
example: 1
|
example: 1
|
||||||
|
needsVoucher:
|
||||||
|
type: boolean
|
||||||
|
description: Indicates if the product needs a voucher (with this productId as requiredProductId) to be bought - if false, this is optional, but still allowed
|
||||||
|
example: false
|
||||||
layerInfo:
|
layerInfo:
|
||||||
$ref: '#/components/schemas/LayerInfoResponse'
|
$ref: '#/components/schemas/LayerInfoResponse'
|
||||||
fikoArticleNumber:
|
fikoArticleNumber:
|
||||||
|
|||||||
@ -313,6 +313,7 @@ paths:
|
|||||||
{
|
{
|
||||||
"productId": 24,
|
"productId": 24,
|
||||||
"parentProductId": null,
|
"parentProductId": null,
|
||||||
|
"needsVoucher": false,
|
||||||
"layerInfo": null,
|
"layerInfo": null,
|
||||||
"fikoArticleNumber": "1234",
|
"fikoArticleNumber": "1234",
|
||||||
"gboPackageTemplateId": "30901",
|
"gboPackageTemplateId": "30901",
|
||||||
@ -429,6 +430,7 @@ paths:
|
|||||||
{
|
{
|
||||||
"productId": 126,
|
"productId": 126,
|
||||||
"parentProductId": null,
|
"parentProductId": null,
|
||||||
|
"needsVoucher": false,
|
||||||
"layerInfo": {
|
"layerInfo": {
|
||||||
"layerInfoId": 1,
|
"layerInfoId": 1,
|
||||||
"choiceKey": "isRenewable",
|
"choiceKey": "isRenewable",
|
||||||
@ -537,6 +539,7 @@ paths:
|
|||||||
{
|
{
|
||||||
"productId": 119,
|
"productId": 119,
|
||||||
"parentProductId": 126,
|
"parentProductId": 126,
|
||||||
|
"needsVoucher": false,
|
||||||
"layerInfo": null,
|
"layerInfo": null,
|
||||||
"fikoArticleNumber": "1234",
|
"fikoArticleNumber": "1234",
|
||||||
"gboPackageTemplateId": "30001",
|
"gboPackageTemplateId": "30001",
|
||||||
@ -652,6 +655,7 @@ paths:
|
|||||||
{
|
{
|
||||||
"productId": 120,
|
"productId": 120,
|
||||||
"parentProductId": 126,
|
"parentProductId": 126,
|
||||||
|
"needsVoucher": false,
|
||||||
"layerInfo": null,
|
"layerInfo": null,
|
||||||
"fikoArticleNumber": "1234",
|
"fikoArticleNumber": "1234",
|
||||||
"gboPackageTemplateId": "30001",
|
"gboPackageTemplateId": "30001",
|
||||||
@ -779,6 +783,7 @@ paths:
|
|||||||
{
|
{
|
||||||
"productId": 49,
|
"productId": 49,
|
||||||
"parentProductId": null,
|
"parentProductId": null,
|
||||||
|
"needsVoucher": false,
|
||||||
"layerInfo": {
|
"layerInfo": {
|
||||||
"layerInfoId": 2,
|
"layerInfoId": 2,
|
||||||
"choiceKey": "regio",
|
"choiceKey": "regio",
|
||||||
@ -926,6 +931,7 @@ paths:
|
|||||||
{
|
{
|
||||||
"productId": 109,
|
"productId": 109,
|
||||||
"parentProductId": 49,
|
"parentProductId": 49,
|
||||||
|
"needsVoucher": false,
|
||||||
"layerInfo": {
|
"layerInfo": {
|
||||||
"layerInfoId": 3,
|
"layerInfoId": 3,
|
||||||
"choiceKey": "allowedGboAgeProfiles",
|
"choiceKey": "allowedGboAgeProfiles",
|
||||||
@ -1076,6 +1082,7 @@ paths:
|
|||||||
{
|
{
|
||||||
"productId": 114,
|
"productId": 114,
|
||||||
"parentProductId": 109,
|
"parentProductId": 109,
|
||||||
|
"needsVoucher": false,
|
||||||
"layerInfo": {
|
"layerInfo": {
|
||||||
"layerInfoId": 1,
|
"layerInfoId": 1,
|
||||||
"choiceKey": "isRenewable",
|
"choiceKey": "isRenewable",
|
||||||
@ -1226,6 +1233,7 @@ paths:
|
|||||||
{
|
{
|
||||||
"productId": 115,
|
"productId": 115,
|
||||||
"parentProductId": 109,
|
"parentProductId": 109,
|
||||||
|
"needsVoucher": false,
|
||||||
"layerInfo": {
|
"layerInfo": {
|
||||||
"layerInfoId": 1,
|
"layerInfoId": 1,
|
||||||
"choiceKey": "isRenewable",
|
"choiceKey": "isRenewable",
|
||||||
@ -1377,6 +1385,7 @@ paths:
|
|||||||
{
|
{
|
||||||
"productId": 116,
|
"productId": 116,
|
||||||
"parentProductId": 115,
|
"parentProductId": 115,
|
||||||
|
"needsVoucher": false,
|
||||||
"layerInfo": null,
|
"layerInfo": null,
|
||||||
"fikoArticleNumber": "1234",
|
"fikoArticleNumber": "1234",
|
||||||
"gboPackageTemplateId": "33615",
|
"gboPackageTemplateId": "33615",
|
||||||
@ -1526,6 +1535,7 @@ paths:
|
|||||||
{
|
{
|
||||||
"productId": 117,
|
"productId": 117,
|
||||||
"parentProductId": 115,
|
"parentProductId": 115,
|
||||||
|
"needsVoucher": false,
|
||||||
"layerInfo": null,
|
"layerInfo": null,
|
||||||
"fikoArticleNumber": "1234",
|
"fikoArticleNumber": "1234",
|
||||||
"gboPackageTemplateId": "33615",
|
"gboPackageTemplateId": "33615",
|
||||||
@ -1679,6 +1689,7 @@ paths:
|
|||||||
{
|
{
|
||||||
"productId": 112,
|
"productId": 112,
|
||||||
"parentProductId": 49,
|
"parentProductId": 49,
|
||||||
|
"needsVoucher": false,
|
||||||
"layerInfo": {
|
"layerInfo": {
|
||||||
"layerInfoId": 3,
|
"layerInfoId": 3,
|
||||||
"choiceKey": "allowedGboAgeProfiles",
|
"choiceKey": "allowedGboAgeProfiles",
|
||||||
@ -2150,6 +2161,10 @@ components:
|
|||||||
parentProductId:
|
parentProductId:
|
||||||
type: integer
|
type: integer
|
||||||
example: 1
|
example: 1
|
||||||
|
needsVoucher:
|
||||||
|
type: boolean
|
||||||
|
description: Indicates if the product needs a voucher (with this productId as requiredProductId) to be bought - if false, this is optional, but still allowed
|
||||||
|
example: false
|
||||||
layerInfo:
|
layerInfo:
|
||||||
$ref: '#/components/schemas/LayerInfoResponse'
|
$ref: '#/components/schemas/LayerInfoResponse'
|
||||||
fikoArticleNumber:
|
fikoArticleNumber:
|
||||||
|
|||||||
@ -1,17 +1,17 @@
|
|||||||
openapi: 3.0.1
|
openapi: 3.0.1
|
||||||
info:
|
info:
|
||||||
title: Service Engine APIs for HTM voucher for sales Touchpint
|
title: Service Engine APIs for HTM voucher for sales Touchpoint
|
||||||
description: Service Engine APIs for HTM vouchers. These are NOT the CRUD APIs to the data hub. These ARE the api's for sales touchpoints.
|
description: Service Engine APIs for HTM vouchers. These are NOT the CRUD APIs to the data hub. These ARE the APIs for sales touchpoints.
|
||||||
version: "1.0"
|
version: "1.0"
|
||||||
servers:
|
servers:
|
||||||
- url: https://services.acc.api.htm.nl/abt/abtvouchersTouchpoint/1.0
|
- url: https://services.acc.api.htm.nl/abt/abtvouchersTouchpoint/1.0
|
||||||
paths:
|
paths:
|
||||||
/issuedvouchers/{voucherCode}:
|
/issuedvouchers/{voucherCode}:
|
||||||
get:
|
get:
|
||||||
summary: Get details of a voucher, that was issued for a specific touch point
|
summary: Get details of a voucher, that was issued for a specific touchpoint
|
||||||
description:
|
description:
|
||||||
Get details of an issued voucher for a specific touch point. This means that only products that the calling touch point is allowed to see or sell
|
Get details of an issued voucher for a specific touchpoint. This means that only products that the calling touchpoint is allowed to see or sell
|
||||||
(i.e. has active sellingPeriods for touchPointId of the calling touch point) are returned.
|
(i.e. has active sellingPeriods for touchPointId of the calling touchpoint) are returned.
|
||||||
parameters:
|
parameters:
|
||||||
- name: voucherCode
|
- name: voucherCode
|
||||||
in: path
|
in: path
|
||||||
@ -28,98 +28,132 @@ paths:
|
|||||||
content:
|
content:
|
||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
$ref: "#/components/schemas/unavailable"
|
$ref: "#/components/schemas/salesTouchpointIssuedVoucherResponse"
|
||||||
examples:
|
examples:
|
||||||
Voucher for a product with required attributes:
|
Voucher that grants a voucher-only product for free:
|
||||||
summary: Voucher for a single product with required attributes
|
summary: Voucher that grants a voucher-only product for free
|
||||||
|
description: |-
|
||||||
|
Voucher that grants a product (that can only be acquired via a voucher) for free.
|
||||||
|
In this case, the voucher has an amountInclTax of 0. If the requiredProduct has a
|
||||||
|
non-zero sellingPrice (amountInclTax), the difference between sellingPrice and
|
||||||
|
voucher amountInclTax represents the granted discount. If the requiredProduct has
|
||||||
|
a sellingPrice of 0, no "discount" is shown; just the voucher's amountInclTax.
|
||||||
value:
|
value:
|
||||||
{
|
{
|
||||||
"issuedVoucherId": "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90",
|
"issuedVoucherId": "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90",
|
||||||
"voucherCode": "VOUCHER123",
|
"voucherCode": "HTM-A7J-128-PYT",
|
||||||
"fromInclusive": "2024-10-04T00:00:00.000",
|
"fromInclusive": "2024-10-04T00:00:00.000",
|
||||||
"untilInclusive": "2024-11-04T00:00:00.000",
|
"untilInclusive": "2024-11-04T00:00:00.000",
|
||||||
"voucherStatus": { "voucherStatusId": 1, "name": "New" },
|
"voucherStatus": { "voucherStatusId": 2, "name": "issued" },
|
||||||
"product":
|
"product":
|
||||||
{
|
{
|
||||||
"productId": 263,
|
"productId": 263,
|
||||||
"productName": "HTM-80001",
|
"productName": "Voucher Ooievaarspas-product AOW",
|
||||||
"productDescription": "10 euro korting op Regiovrij maand.",
|
"productDescription": "Voucher voor AOW-ers in Den Haag met een Ooievaarspas, die ingewisseld kan worden voor het product \"Ooievaarspas voor AOW-ers in Den Haag\"",
|
||||||
"productCategory":
|
"amountInclTax": 0,
|
||||||
{
|
|
||||||
"productCategoryId": 9,
|
|
||||||
"isTravelProduct": false,
|
|
||||||
"name": "Voucher",
|
|
||||||
},
|
|
||||||
"amountInclTax": -1000,
|
|
||||||
"requiredProducts":
|
"requiredProducts":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"productId": 126,
|
"productId": 982,
|
||||||
"productName": "HTM-30001",
|
"productName": "Ooievaarspas voor AOW-ers in Den Haag",
|
||||||
"productDescription": "Regiovrij maand.",
|
"productDescription": "Vrij reizen bij HTM voor Haagse AOW-gerechtigden met een Ooievaarspas.",
|
||||||
|
"productCategory":
|
||||||
|
{
|
||||||
|
"productCategoryId": 2,
|
||||||
|
"isTravelProduct": true,
|
||||||
|
"name": "Afgekocht reisrecht",
|
||||||
|
},
|
||||||
|
"amountInclTax": 0,
|
||||||
"_links":
|
"_links":
|
||||||
{
|
{
|
||||||
"get_details":
|
"get_details":
|
||||||
{
|
{
|
||||||
"href": "https://api.integratielaag.nl/abt/touchpoint/1.0/products/126",
|
"href": "https://api.integratielaag.nl/abt/touchpoint/1.0/products/982",
|
||||||
"method": "GET",
|
"method": "GET",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
]
|
||||||
"_links":
|
|
||||||
{
|
|
||||||
"get_details":
|
|
||||||
{
|
|
||||||
"href": "https://api.integratielaag.nl/abt/touchpoint/1.0/products/263",
|
|
||||||
"method": "GET",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
"mandatoryCustomerDataItems":
|
"mandatoryCustomerDataItems":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"mandatoryCustomerDataItemId": 8,
|
"mandatoryCustomerDataItemId": 8,
|
||||||
"customerDataItem": "padBirthDate",
|
"customerDataItem": "padBirthDate"
|
||||||
},
|
}
|
||||||
{
|
]
|
||||||
"mandatoryCustomerDataItemId": 4,
|
|
||||||
"customerDataItem": "emailAddress",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}
|
}
|
||||||
Voucher for a whole order:
|
Voucher that grants a hybrid product for a reduced price:
|
||||||
summary: Voucher for a whole order
|
summary: Voucher that grants a hybrid product for a reduced price
|
||||||
|
description: |-
|
||||||
|
Voucher that grants a hybrid product (that can be acquired via voucher or via ordinary order flow)
|
||||||
|
for a reduced price. In this case, the voucher has an amountInclTax > 0, which dictates the (modified)
|
||||||
|
total amount that needs to be paid for said product. If the requiredProduct has a
|
||||||
|
non-zero sellingPrice (amountInclTax), the difference between sellingPrice and
|
||||||
|
voucher amountInclTax represents the granted discount. If the requiredProduct has
|
||||||
|
a sellingPrice of 0, no "discount" is shown; just the voucher's amountInclTax./
|
||||||
|
Specifically, in this example, the product "HTM 20% Korting" can be purchased for 1 euro instead of 5 euro.
|
||||||
value:
|
value:
|
||||||
{
|
{
|
||||||
"issuedVoucherId": "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90",
|
"issuedVoucherId": "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90",
|
||||||
"voucherCode": "VOUCHER123",
|
"voucherCode": "HTM-A7J-128-PYT",
|
||||||
"fromInclusive": "2024-10-04T00:00:00.000",
|
"fromInclusive": "2024-10-04T00:00:00.000",
|
||||||
"untilInclusive": "2024-11-04T00:00:00.000",
|
"untilInclusive": "2024-11-04T00:00:00.000",
|
||||||
"voucherStatus": { "voucherStatusId": 1, "name": "New" },
|
"voucherStatus": { "voucherStatusId": 2, "name": "issued" },
|
||||||
"product":
|
"product":
|
||||||
{
|
{
|
||||||
"productId": 263,
|
"productId": 264,
|
||||||
"productName": "HTM-80002",
|
"productName": "Kortingsvoucher HTM 20% Korting ",
|
||||||
"productDescription": "10 euro korting op je gehele winkelmand.",
|
"productDescription": "Voucher waarmee het product \"HTM 20% Korting\" voor een lagere prijs kan worden aangeschaft.",
|
||||||
"productCategory":
|
"amountInclTax": 100,
|
||||||
{
|
"requiredProducts":
|
||||||
"productCategoryId": 9,
|
[
|
||||||
"isTravelProduct": false,
|
{
|
||||||
"name": "Voucher",
|
"productId": 984,
|
||||||
},
|
"productName": "HTM 20% Korting",
|
||||||
"amountInclTax": -1000,
|
"productDescription": "Reis met 20% korting op je betaalpas bij HTM.",
|
||||||
"requiredProducts": [],
|
"productCategory":
|
||||||
"_links":
|
{
|
||||||
{
|
"productCategoryId": 1,
|
||||||
"get_details":
|
"isTravelProduct": true,
|
||||||
{
|
"name": "Kortingsabonnement",
|
||||||
"href": "https://api.integratielaag.nl/abt/touchpoint/1.0/products/263",
|
},
|
||||||
"method": "GET",
|
"amountInclTax": 500,
|
||||||
},
|
"_links":
|
||||||
},
|
{
|
||||||
|
"get_details":
|
||||||
|
{
|
||||||
|
"href": "https://api.integratielaag.nl/abt/touchpoint/1.0/products/984",
|
||||||
|
"method": "GET",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"mandatoryCustomerDataItems": [],
|
"mandatoryCustomerDataItems": []
|
||||||
|
}
|
||||||
|
Voucher that grants a discount for a whole order:
|
||||||
|
summary: Voucher that grants a discount for a whole order
|
||||||
|
description: |-
|
||||||
|
Voucher that grants a discount for a whole order. In this case, no requiredProduct is specified, and
|
||||||
|
the voucher has an amountInclTax < 0. The (negative) amountInclTax dictates the value of the voucher,
|
||||||
|
that is subtracted from the total order value as a discount (with a minimum order total of 0).
|
||||||
|
value:
|
||||||
|
{
|
||||||
|
"issuedVoucherId": "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90",
|
||||||
|
"voucherCode": "HTM-A7J-128-PYT",
|
||||||
|
"fromInclusive": "2024-10-04T00:00:00.000",
|
||||||
|
"untilInclusive": "2024-11-04T00:00:00.000",
|
||||||
|
"voucherStatus": { "voucherStatusId": 2, "name": "issued" },
|
||||||
|
"product":
|
||||||
|
{
|
||||||
|
"productId": 265,
|
||||||
|
"productName": "Voucher 10 euro korting",
|
||||||
|
"productDescription": "Voucher die 10 euro korting geeft op je gehele winkelmand.",
|
||||||
|
"amountInclTax": -1000,
|
||||||
|
"requiredProducts": []
|
||||||
|
},
|
||||||
|
"mandatoryCustomerDataItems": []
|
||||||
}
|
}
|
||||||
"403":
|
"403":
|
||||||
description: Forbidden
|
description: Forbidden
|
||||||
@ -137,20 +171,20 @@ paths:
|
|||||||
"detail": "You do not have permission to access this resource.",
|
"detail": "You do not have permission to access this resource.",
|
||||||
"instance": "/issuedvouchers",
|
"instance": "/issuedvouchers",
|
||||||
}
|
}
|
||||||
"404":
|
"400":
|
||||||
description: Not found
|
description: Bad request
|
||||||
content:
|
content:
|
||||||
application/problem+json:
|
application/problem+json:
|
||||||
schema:
|
schema:
|
||||||
$ref: "#/components/schemas/rfc9457"
|
$ref: "#/components/schemas/rfc9457"
|
||||||
examples:
|
examples:
|
||||||
Voucher not found:
|
Invalid voucher code:
|
||||||
summary: Voucher not found
|
summary: Invalid voucher code
|
||||||
value:
|
value:
|
||||||
{
|
{
|
||||||
"type": "https://example.com/probs/not-found",
|
"type": "https://example.com/probs/bad-request",
|
||||||
"title": "Voucher not found",
|
"title": "Invalid voucher code",
|
||||||
"detail": "The voucher with code VOUCHER123 does not exist.",
|
"detail": "No valid voucher found for code VOUCHER123.",
|
||||||
"instance": "/issuedvouchers",
|
"instance": "/issuedvouchers",
|
||||||
}
|
}
|
||||||
"500":
|
"500":
|
||||||
@ -176,6 +210,166 @@ components:
|
|||||||
scheme: bearer
|
scheme: bearer
|
||||||
bearerFormat: JWT
|
bearerFormat: JWT
|
||||||
schemas:
|
schemas:
|
||||||
|
salesTouchpointIssuedVoucherResponse:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- issuedVoucherId
|
||||||
|
- voucherCode
|
||||||
|
- fromInclusive
|
||||||
|
- untilInclusive
|
||||||
|
- voucherStatus
|
||||||
|
- product
|
||||||
|
- mandatoryCustomerDataItems
|
||||||
|
properties:
|
||||||
|
issuedVoucherId:
|
||||||
|
type: string
|
||||||
|
description: The unique (technical) identifier of the issued voucher instance.
|
||||||
|
example: "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90"
|
||||||
|
voucherCode:
|
||||||
|
type: string
|
||||||
|
description: The voucher code that is shared with the customer and uniquely identifies this voucher.
|
||||||
|
example: "HTM-A7J-128-PYT"
|
||||||
|
fromInclusive:
|
||||||
|
type: string
|
||||||
|
format: date-time-offset
|
||||||
|
description: |-
|
||||||
|
The date and time the voucher becomes valid for redemption. This has nothing to do with
|
||||||
|
the allowed start date of a requiredProduct (for this, the existing order flow logic is applied).
|
||||||
|
example: "2024-10-04T00:00:00.000+02:00"
|
||||||
|
untilInclusive:
|
||||||
|
type: string
|
||||||
|
format: date-time-offset
|
||||||
|
description: |-
|
||||||
|
The date and time the voucher becomes invalid for redemption. This has nothing to do with
|
||||||
|
the maximum allowed start date of a requiredProduct (for this, the existing order flow logic is applied).
|
||||||
|
example: "2024-11-04T00:00:00.000+01:00"
|
||||||
|
voucherStatus:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- voucherStatusId
|
||||||
|
- name
|
||||||
|
description: |-
|
||||||
|
The current status of the voucher. Can be any of the following:
|
||||||
|
- 1 = new
|
||||||
|
- 2 = issued
|
||||||
|
- 3 = redeemed
|
||||||
|
- 4 = revoked
|
||||||
|
- 5 = expired
|
||||||
|
- 6 = pendingRedemption
|
||||||
|
properties:
|
||||||
|
voucherStatusId:
|
||||||
|
type: integer
|
||||||
|
example: 2
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
example: "issued"
|
||||||
|
product:
|
||||||
|
type: object
|
||||||
|
description: The "product" referencing the voucher definition that this voucher instance is based on
|
||||||
|
required:
|
||||||
|
- productId
|
||||||
|
- productName
|
||||||
|
- productDescription
|
||||||
|
- amountInclTax
|
||||||
|
properties:
|
||||||
|
productId:
|
||||||
|
type: integer
|
||||||
|
example: 263
|
||||||
|
productName:
|
||||||
|
type: string
|
||||||
|
example: Voucher Ooievaarspas-product AOW
|
||||||
|
productDescription:
|
||||||
|
type: string
|
||||||
|
example: |-
|
||||||
|
Voucher voor AOW-ers in Den Haag met een Ooievaarspas, die ingewisseld kan worden
|
||||||
|
voor het product "Ooievaarspas voor AOW-ers in Den Haag".
|
||||||
|
amountInclTax:
|
||||||
|
type: integer
|
||||||
|
description: |-
|
||||||
|
When combined with a requiredProduct, the (positive or zero) amountInclTax dictates
|
||||||
|
the (modified) total amount that needs to be paid for said product. When the requiredProduct
|
||||||
|
has a sellingPrice > 0, the difference between sellingPrice and voucher amountInclTax
|
||||||
|
represents the granted discount.
|
||||||
|
When not combined with a required product, the (negative) amountInclTax dictates
|
||||||
|
the value of the voucher, that is subtracted from the total order value as a discount
|
||||||
|
(with a minimum order total of 0).
|
||||||
|
example: 0
|
||||||
|
requiredProducts:
|
||||||
|
type: array
|
||||||
|
description: |-
|
||||||
|
Currently, only one requiredProduct is supported and thus, this array can contain at
|
||||||
|
most one element.
|
||||||
|
items:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- productId
|
||||||
|
properties:
|
||||||
|
productId:
|
||||||
|
type: integer
|
||||||
|
example: 892
|
||||||
|
productName:
|
||||||
|
type: string
|
||||||
|
example: "Ooievaarspas voor AOW-ers in Den Haag"
|
||||||
|
productDescription:
|
||||||
|
type: string
|
||||||
|
example: "Vrij reizen bij HTM voor Haagse AOW-gerechtigden met een Ooievaarspas."
|
||||||
|
productCategory:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- productCategoryId
|
||||||
|
- isTravelProduct
|
||||||
|
- name
|
||||||
|
properties:
|
||||||
|
productCategoryId:
|
||||||
|
type: integer
|
||||||
|
example: 2
|
||||||
|
isTravelProduct:
|
||||||
|
type: boolean
|
||||||
|
example: true
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
example: "Afgekocht reisrecht"
|
||||||
|
amountInclTax:
|
||||||
|
type: integer
|
||||||
|
description: |-
|
||||||
|
Selling price of the product in cents (including tax, if applicable) that is
|
||||||
|
currently active for the calling touchpoint. When 0, the product is free of charge.
|
||||||
|
example: 0
|
||||||
|
imageReference:
|
||||||
|
type: string
|
||||||
|
description: Can be a URL or a base64 encoded image
|
||||||
|
example: https://www.htm.nl/nog-onbekende-productafbeelding
|
||||||
|
_links:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
get_details:
|
||||||
|
type: object
|
||||||
|
description: Link to get more details for the product that this voucher instance applies to
|
||||||
|
properties:
|
||||||
|
href:
|
||||||
|
type: string
|
||||||
|
example: https://api.integratielaag.nl/abt/touchpoint/1.0/products/982
|
||||||
|
method:
|
||||||
|
type: string
|
||||||
|
example: GET
|
||||||
|
mandatoryCustomerDataItems:
|
||||||
|
type: array
|
||||||
|
description: |-
|
||||||
|
List of mandatory customer data items that are required to redeem this voucher.\
|
||||||
|
The values provided for these data items may be checked against allowed values as provided by the voucher issuer.
|
||||||
|
items:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- mandatoryCustomerDataItemId
|
||||||
|
- customerDataItem
|
||||||
|
properties:
|
||||||
|
mandatoryCustomerDataItemId:
|
||||||
|
type: integer
|
||||||
|
example: 8
|
||||||
|
customerDataItem:
|
||||||
|
type: string
|
||||||
|
example: padBirthdate
|
||||||
|
|
||||||
unavailable:
|
unavailable:
|
||||||
type: object
|
type: object
|
||||||
rfc9457:
|
rfc9457:
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -1553,6 +1553,9 @@ components:
|
|||||||
- productCategoryId: 8
|
- productCategoryId: 8
|
||||||
name: Saldo
|
name: Saldo
|
||||||
isTravelProduct: true
|
isTravelProduct: true
|
||||||
|
- productCategoryId: 9
|
||||||
|
name: Voucher
|
||||||
|
isTravelProduct: false
|
||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
$ref: '#/components/schemas/productCategoryGetEntity'
|
$ref: '#/components/schemas/productCategoryGetEntity'
|
||||||
@ -1811,7 +1814,7 @@ components:
|
|||||||
- mandatoryCustomerDataItemId: 5
|
- mandatoryCustomerDataItemId: 5
|
||||||
customerDataItem: address
|
customerDataItem: address
|
||||||
- mandatoryCustomerDataItemId: 6
|
- mandatoryCustomerDataItemId: 6
|
||||||
customerDataItem: phone
|
customerDataItem: voucher
|
||||||
- mandatoryCustomerDataItemId: 7
|
- mandatoryCustomerDataItemId: 7
|
||||||
customerDataItem: ovPayToken
|
customerDataItem: ovPayToken
|
||||||
- mandatoryCustomerDataItemId: 8
|
- mandatoryCustomerDataItemId: 8
|
||||||
|
|||||||
@ -46,6 +46,13 @@ paths:
|
|||||||
when false, return only non-archived products (isArchived = false).
|
when false, return only non-archived products (isArchived = false).
|
||||||
schema:
|
schema:
|
||||||
type: boolean
|
type: boolean
|
||||||
|
- name: onlyVouchers
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
description: |-
|
||||||
|
When omitted, defaults to false (i.e. return all normal products that are NOT voucher definitions); when true, return only voucher definitions
|
||||||
|
schema:
|
||||||
|
type: boolean
|
||||||
responses:
|
responses:
|
||||||
'200':
|
'200':
|
||||||
description: OK
|
description: OK
|
||||||
@ -387,6 +394,7 @@ paths:
|
|||||||
"fikoArticleNumber": "1234",
|
"fikoArticleNumber": "1234",
|
||||||
"isValid": true,
|
"isValid": true,
|
||||||
"isArchived": false,
|
"isArchived": false,
|
||||||
|
"needsVoucher": false,
|
||||||
"gboPackageTemplateId": "30901",
|
"gboPackageTemplateId": "30901",
|
||||||
"productName": "HTM pilot 90% korting",
|
"productName": "HTM pilot 90% korting",
|
||||||
"productDescription": "Reis met 90% korting gedurende de eerste F&F pilot!",
|
"productDescription": "Reis met 90% korting gedurende de eerste F&F pilot!",
|
||||||
@ -474,6 +482,7 @@ paths:
|
|||||||
"fikoArticleNumber": "1234",
|
"fikoArticleNumber": "1234",
|
||||||
"isValid": true,
|
"isValid": true,
|
||||||
"isArchived": false,
|
"isArchived": false,
|
||||||
|
"needsVoucher": false,
|
||||||
"gboPackageTemplateId": "30901",
|
"gboPackageTemplateId": "30901",
|
||||||
"productName": "HTM pilot 90% korting",
|
"productName": "HTM pilot 90% korting",
|
||||||
"productDescription": "Reis met 90% korting gedurende de eerste F&F pilot!",
|
"productDescription": "Reis met 90% korting gedurende de eerste F&F pilot!",
|
||||||
@ -560,6 +569,7 @@ paths:
|
|||||||
"fikoArticleNumber": "1234",
|
"fikoArticleNumber": "1234",
|
||||||
"isValid": true,
|
"isValid": true,
|
||||||
"isArchived": false,
|
"isArchived": false,
|
||||||
|
"needsVoucher": false,
|
||||||
"gboPackageTemplateId": "30901",
|
"gboPackageTemplateId": "30901",
|
||||||
"productName": "HTM pilot 90% korting",
|
"productName": "HTM pilot 90% korting",
|
||||||
"productDescription": "Reis met 90% korting gedurende de eerste F&F pilot!",
|
"productDescription": "Reis met 90% korting gedurende de eerste F&F pilot!",
|
||||||
@ -680,6 +690,7 @@ paths:
|
|||||||
"fikoArticleNumber": "1234",
|
"fikoArticleNumber": "1234",
|
||||||
"isValid": true,
|
"isValid": true,
|
||||||
"isArchived": false,
|
"isArchived": false,
|
||||||
|
"needsVoucher": false,
|
||||||
"gboPackageTemplateId": "33610",
|
"gboPackageTemplateId": "33610",
|
||||||
"productName": "HTM Regio Vrij DH73",
|
"productName": "HTM Regio Vrij DH73",
|
||||||
"productDescription": "Voor een vast bedrag onbeperkt reizen met EBS, HTM en RET in het gekozen gebied in de regio Rotterdam Den Haag.",
|
"productDescription": "Voor een vast bedrag onbeperkt reizen met EBS, HTM en RET in het gekozen gebied in de regio Rotterdam Den Haag.",
|
||||||
@ -866,6 +877,7 @@ paths:
|
|||||||
"fikoArticleNumber": "1234",
|
"fikoArticleNumber": "1234",
|
||||||
"isValid": true,
|
"isValid": true,
|
||||||
"isArchived": false,
|
"isArchived": false,
|
||||||
|
"needsVoucher": false,
|
||||||
"gboPackageTemplateId": "30901",
|
"gboPackageTemplateId": "30901",
|
||||||
"tapConnectProductCode": null,
|
"tapConnectProductCode": null,
|
||||||
"productName": "HTM pilot 90% korting",
|
"productName": "HTM pilot 90% korting",
|
||||||
@ -1028,6 +1040,7 @@ paths:
|
|||||||
"fikoArticleNumber": "1234",
|
"fikoArticleNumber": "1234",
|
||||||
"isValid": true,
|
"isValid": true,
|
||||||
"isArchived": false,
|
"isArchived": false,
|
||||||
|
"needsVoucher": false,
|
||||||
"gboPackageTemplateId": "30901",
|
"gboPackageTemplateId": "30901",
|
||||||
"tapConnectProductCode": null,
|
"tapConnectProductCode": null,
|
||||||
"productName": "HTM pilot 90% korting",
|
"productName": "HTM pilot 90% korting",
|
||||||
@ -1270,6 +1283,7 @@ paths:
|
|||||||
"fikoArticleNumber": "1234",
|
"fikoArticleNumber": "1234",
|
||||||
"isValid": true,
|
"isValid": true,
|
||||||
"isArchived": false,
|
"isArchived": false,
|
||||||
|
"needsVoucher": false,
|
||||||
"gboPackageTemplateId": "33610",
|
"gboPackageTemplateId": "33610",
|
||||||
"tapConnectProductCode": null,
|
"tapConnectProductCode": null,
|
||||||
"productName": "HTM Regio Vrij DH73",
|
"productName": "HTM Regio Vrij DH73",
|
||||||
@ -1475,6 +1489,7 @@ paths:
|
|||||||
"fikoArticleNumber": "1234",
|
"fikoArticleNumber": "1234",
|
||||||
"isValid": true,
|
"isValid": true,
|
||||||
"isArchived": false,
|
"isArchived": false,
|
||||||
|
"needsVoucher": false,
|
||||||
"gboPackageTemplateId": null,
|
"gboPackageTemplateId": null,
|
||||||
"tapConnectProductCode": null,
|
"tapConnectProductCode": null,
|
||||||
"productName": "IBAN wijzigen functioneel product",
|
"productName": "IBAN wijzigen functioneel product",
|
||||||
@ -1672,6 +1687,7 @@ paths:
|
|||||||
"fikoArticleNumber": "1234",
|
"fikoArticleNumber": "1234",
|
||||||
"isValid": true,
|
"isValid": true,
|
||||||
"isArchived": false,
|
"isArchived": false,
|
||||||
|
"needsVoucher": false,
|
||||||
"gboPackageTemplateId": null,
|
"gboPackageTemplateId": null,
|
||||||
"tapConnectProductCode": null,
|
"tapConnectProductCode": null,
|
||||||
"productName": "OV-pas saldo (1 eurocent)",
|
"productName": "OV-pas saldo (1 eurocent)",
|
||||||
@ -2775,6 +2791,10 @@ components:
|
|||||||
type: boolean
|
type: boolean
|
||||||
description: Indicates if the product is archived - if true, the Service Engine will prevent touchpoints from seeing this product
|
description: Indicates if the product is archived - if true, the Service Engine will prevent touchpoints from seeing this product
|
||||||
example: false
|
example: false
|
||||||
|
needsVoucher:
|
||||||
|
type: boolean
|
||||||
|
description: Indicates if the product needs a voucher (with this productId as requiredProductId) to be bought - if false, this is optional, but still allowed
|
||||||
|
example: false
|
||||||
gboPackageTemplateId:
|
gboPackageTemplateId:
|
||||||
type: string
|
type: string
|
||||||
example: '30901'
|
example: '30901'
|
||||||
@ -3132,6 +3152,10 @@ components:
|
|||||||
type: boolean
|
type: boolean
|
||||||
description: Indicates if the product is archived - if true, the Service Engine will prevent touchpoints from seeing this product
|
description: Indicates if the product is archived - if true, the Service Engine will prevent touchpoints from seeing this product
|
||||||
example: false
|
example: false
|
||||||
|
needsVoucher:
|
||||||
|
type: boolean
|
||||||
|
description: Indicates if the product needs a voucher (with this productId as requiredProductId) to be bought - if false, this is optional, but still allowed
|
||||||
|
example: false
|
||||||
gboPackageTemplateId:
|
gboPackageTemplateId:
|
||||||
type: string
|
type: string
|
||||||
description: >-
|
description: >-
|
||||||
@ -3503,6 +3527,10 @@ components:
|
|||||||
type: boolean
|
type: boolean
|
||||||
description: Indicates if the product is archived - if true, the Service Engine will prevent touchpoints from seeing this product
|
description: Indicates if the product is archived - if true, the Service Engine will prevent touchpoints from seeing this product
|
||||||
example: false
|
example: false
|
||||||
|
needsVoucher:
|
||||||
|
type: boolean
|
||||||
|
description: Indicates if the product needs a voucher (with this productId as requiredProductId) to be bought - if false, this is optional, but still allowed
|
||||||
|
example: false
|
||||||
gboPackageTemplateId:
|
gboPackageTemplateId:
|
||||||
type: string
|
type: string
|
||||||
description: >-
|
description: >-
|
||||||
|
|||||||
@ -209,6 +209,12 @@ paths:
|
|||||||
{
|
{
|
||||||
"issuedVoucherId": "e1f2g3h4-i5j6-k7l8-m9n0-o1p2q3r4s5t6",
|
"issuedVoucherId": "e1f2g3h4-i5j6-k7l8-m9n0-o1p2q3r4s5t6",
|
||||||
"voucherCode": "VOUCHER12345",
|
"voucherCode": "VOUCHER12345",
|
||||||
|
"touchPointId": 23,
|
||||||
|
"metadata1": null,
|
||||||
|
"metadata2": null,
|
||||||
|
"metadata3": null,
|
||||||
|
"metadata4": null,
|
||||||
|
"metadata5": null,
|
||||||
"voucherStatusInstances":
|
"voucherStatusInstances":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
@ -219,6 +225,7 @@ paths:
|
|||||||
"name": "New",
|
"name": "New",
|
||||||
},
|
},
|
||||||
"createdOn": "2024-10-04T12:34:56.000",
|
"createdOn": "2024-10-04T12:34:56.000",
|
||||||
|
"reason": null,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"voucherStatusInstanceId": "b01412e6-70fb-4c05-9bef-e65bf2747ca1",
|
"voucherStatusInstanceId": "b01412e6-70fb-4c05-9bef-e65bf2747ca1",
|
||||||
@ -228,6 +235,7 @@ paths:
|
|||||||
"name": "Issued",
|
"name": "Issued",
|
||||||
},
|
},
|
||||||
"createdOn": "2024-10-04T12:37:14.000",
|
"createdOn": "2024-10-04T12:37:14.000",
|
||||||
|
"reason": "test reason"
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"voucherClaims":
|
"voucherClaims":
|
||||||
@ -248,6 +256,155 @@ paths:
|
|||||||
],
|
],
|
||||||
"href": null,
|
"href": null,
|
||||||
}
|
}
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- Purchased Product
|
||||||
|
summary: Create a new purchased product.
|
||||||
|
description: Create a new purchased product. Only one single instance of `purchasedGboProducts`, `purchasedTapconnectTickets` or `issuedVouchers` can be specified at once.
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/unavailable"
|
||||||
|
examples:
|
||||||
|
Create Purchased GBO Product:
|
||||||
|
value:
|
||||||
|
{
|
||||||
|
"productId": 11,
|
||||||
|
"createdOn": "2024-10-04T12:34:56.000",
|
||||||
|
"lastUpdatedOn": "2024-10-04T12:34:56.000",
|
||||||
|
"purchasedProductResources":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"resourceNameId": 1,
|
||||||
|
"resourceIdentifier": "408eefa9-b393-4bb3-8439-b2e51833abc7",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceNameId": 2,
|
||||||
|
"resourceIdentifier": "f809a6e1-1c8d-4f8e-8a6e-0d0b1e1e1e1e",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"purchasedGboProducts":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"salesTimestamp": "2024-10-04T12:34:56.000",
|
||||||
|
"refundTimestamp": "2024-10-04T12:34:56.000",
|
||||||
|
"fromInclusive": "2024-10-04T12:34:56.000",
|
||||||
|
"untilInclusive": "2024-10-04T12:34:56.000",
|
||||||
|
"packageTemplateId": "30003",
|
||||||
|
"xBot": "f15efe6f-7353-4968-b134-60ba6fc2da8b",
|
||||||
|
"xTat": "42efebf7-132e-4ee0-9cbb-4037a9a54ad8",
|
||||||
|
"xSpit": "d67b2f72-918a-4e6c-957d-a39ed9c9e16b",
|
||||||
|
"customerTokenId": "b6492322-c458-4857-9ac3-a109c1887b9f",
|
||||||
|
"ovPayTokenId": 13,
|
||||||
|
"createdOn": "2024-10-04T12:34:56.000",
|
||||||
|
"lastUpdatedOn": "2024-10-04T12:34:56.000",
|
||||||
|
"createdBy": "someuser",
|
||||||
|
"lastUpdatedBy": null
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"purchasedTapconnectTickets": [],
|
||||||
|
"issuedVouchers": [],
|
||||||
|
}
|
||||||
|
Create Purchased TapConnect Ticket:
|
||||||
|
value:
|
||||||
|
{
|
||||||
|
"productId": 11,
|
||||||
|
"createdOn": "2024-10-04T12:34:56.000",
|
||||||
|
"lastUpdatedOn": "2024-10-04T12:34:56.000",
|
||||||
|
"purchasedProductResources":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"resourceNameId": 1,
|
||||||
|
"resourceIdentifier": "408eefa9-b393-4bb3-8439-b2e51833abc7",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceNameId": 2,
|
||||||
|
"resourceIdentifier": "f809a6e1-1c8d-4f8e-8a6e-0d0b1e1e1e1e",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"purchasedGboProducts": [],
|
||||||
|
"purchasedTapconnectTickets":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"issuedAt": "2024-10-04T12:34:56.000",
|
||||||
|
"activatedAt": "2024-10-04T12:34:56.000",
|
||||||
|
"cancelledAt": "2024-10-04T12:34:56.000",
|
||||||
|
"ticketReference": "KJj43nejhbTxhr897287",
|
||||||
|
"createdOn": "2024-10-04T12:34:56.000",
|
||||||
|
"lastUpdatedOn": "2024-10-04T12:34:56.000",
|
||||||
|
"createdBy": "John Doe",
|
||||||
|
"lastUpdatedBy": "John Doe",
|
||||||
|
"externalDeviceId": "c5545584-04af-4c60-a955-d6a70baab848",
|
||||||
|
"serviceId": "HTM-1234-7654-8945",
|
||||||
|
"activateBefore": "2024-10-08",
|
||||||
|
"validityStart": "2024-10-05T12:34:56.000",
|
||||||
|
"validityEnd": "2024-10-06T12:34:56.000"
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"issuedVouchers": [],
|
||||||
|
}
|
||||||
|
Create Issued Voucher:
|
||||||
|
value:
|
||||||
|
{
|
||||||
|
"productId": 11,
|
||||||
|
"createdOn": "2024-10-04T12:34:56.000",
|
||||||
|
"lastUpdatedOn": "2024-10-04T12:34:56.000",
|
||||||
|
"purchasedProductResources":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"resourceNameId": 1,
|
||||||
|
"resourceIdentifier": "408eefa9-b393-4bb3-8439-b2e51833abc7",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceNameId": 2,
|
||||||
|
"resourceIdentifier": "f809a6e1-1c8d-4f8e-8a6e-0d0b1e1e1e1e",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"purchasedGboProducts": [],
|
||||||
|
"purchasedTapconnectTickets": [],
|
||||||
|
"issuedVouchers":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"voucherCode": "VOUCHER123",
|
||||||
|
"touchPointId": 23,
|
||||||
|
"metadata1": null,
|
||||||
|
"metadata2": null,
|
||||||
|
"metadata3": null,
|
||||||
|
"metadata4": null,
|
||||||
|
"metadata5": null,
|
||||||
|
"voucherStatusInstances": [
|
||||||
|
{
|
||||||
|
"voucherStatusId": 1,
|
||||||
|
"createdOn": "2024-10-04T12:34:56.000",
|
||||||
|
"reason": "test reason"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"voucherClaims": [
|
||||||
|
{
|
||||||
|
"mandatoryCustomerDataItemId": 8,
|
||||||
|
"value": "1999-12-31"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mandatoryCustomerDataItemId": 4,
|
||||||
|
"value": "john.doe@example.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"fromInclusive": "2024-10-04T12:34:56.000",
|
||||||
|
"untilInclusive": "2025-10-04T12:34:56.000"
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
responses:
|
||||||
|
"201":
|
||||||
|
description: Created
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/unavailable"
|
||||||
|
example:
|
||||||
|
{ "purchasedProductId": "a9b3dea5-fb8a-4b1e-9fe6-90cad31c0cfd" }
|
||||||
/purchasedproducts/{purchasedProductId}:
|
/purchasedproducts/{purchasedProductId}:
|
||||||
parameters:
|
parameters:
|
||||||
- in: path
|
- in: path
|
||||||
@ -382,6 +539,12 @@ paths:
|
|||||||
{
|
{
|
||||||
"issuedVoucherId": "e1f2g3h4-i5j6-k7l8-m9n0-o1p2q3r4s5t6",
|
"issuedVoucherId": "e1f2g3h4-i5j6-k7l8-m9n0-o1p2q3r4s5t6",
|
||||||
"voucherCode": "VOUCHER12345",
|
"voucherCode": "VOUCHER12345",
|
||||||
|
"touchPointId": 23,
|
||||||
|
"metadata1": null,
|
||||||
|
"metadata2": null,
|
||||||
|
"metadata3": null,
|
||||||
|
"metadata4": null,
|
||||||
|
"metadata5": null,
|
||||||
"voucherStatusInstances":
|
"voucherStatusInstances":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
@ -389,12 +552,14 @@ paths:
|
|||||||
"voucherStatus":
|
"voucherStatus":
|
||||||
{ "voucherStatusId": 1, "name": "New" },
|
{ "voucherStatusId": 1, "name": "New" },
|
||||||
"createdOn": "2024-10-04T12:34:56.000",
|
"createdOn": "2024-10-04T12:34:56.000",
|
||||||
|
"reason": null,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"voucherStatusInstanceId": "b01412e6-70fb-4c05-9bef-e65bf2747ca1",
|
"voucherStatusInstanceId": "b01412e6-70fb-4c05-9bef-e65bf2747ca1",
|
||||||
"voucherStatus":
|
"voucherStatus":
|
||||||
{ "voucherStatusId": 2, "name": "Issued" },
|
{ "voucherStatusId": 2, "name": "Issued" },
|
||||||
"createdOn": "2024-10-04T12:37:14.000",
|
"createdOn": "2024-10-04T12:37:14.000",
|
||||||
|
"reason": "test reason"
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"voucherClaims":
|
"voucherClaims":
|
||||||
@ -1054,11 +1219,18 @@ paths:
|
|||||||
example:
|
example:
|
||||||
{
|
{
|
||||||
"voucherCode": "VOUCHER123",
|
"voucherCode": "VOUCHER123",
|
||||||
|
"touchPointId": 23,
|
||||||
|
"metadata1": null,
|
||||||
|
"metadata2": null,
|
||||||
|
"metadata3": null,
|
||||||
|
"metadata4": null,
|
||||||
|
"metadata5": null,
|
||||||
"voucherStatusInstances":
|
"voucherStatusInstances":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"voucherStatusId": 1,
|
"voucherStatusId": 1,
|
||||||
"createdOn": "2024-10-04T12:34:56.000",
|
"createdOn": "2024-10-04T12:34:56.000",
|
||||||
|
"reason": "test reason"
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"voucherClaims":
|
"voucherClaims":
|
||||||
@ -1066,7 +1238,7 @@ paths:
|
|||||||
{ "mandatoryCustomerDataItemId": 8, "value": "1999-12-31" },
|
{ "mandatoryCustomerDataItemId": 8, "value": "1999-12-31" },
|
||||||
{
|
{
|
||||||
"mandatoryCustomerDataItemId": 4,
|
"mandatoryCustomerDataItemId": 4,
|
||||||
"value": "vlad.harkonnen@househarkonnen.net",
|
"value": "john.doe@example.com",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"fromInclusive": "2024-10-04T12:34:56.000",
|
"fromInclusive": "2024-10-04T12:34:56.000",
|
||||||
@ -1102,6 +1274,20 @@ paths:
|
|||||||
format: uuid
|
format: uuid
|
||||||
example: 058a1af7-897f-45d5-b691-9cc9161e387f
|
example: 058a1af7-897f-45d5-b691-9cc9161e387f
|
||||||
description: The id of the purchased product.
|
description: The id of the purchased product.
|
||||||
|
- in: query
|
||||||
|
name: statusChangedAfter
|
||||||
|
required: false
|
||||||
|
description: Return only issued vouchers that have had their status changed after the given date and time.
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
format: date-time-offset
|
||||||
|
example: "2024-10-04T00:00:00.000Z"
|
||||||
|
- in: query
|
||||||
|
name: productId
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
example: 1
|
||||||
|
description: The id of the product and the issuedVouchers related to it
|
||||||
- in: query
|
- in: query
|
||||||
name: voucherCode
|
name: voucherCode
|
||||||
schema:
|
schema:
|
||||||
@ -1117,6 +1303,14 @@ paths:
|
|||||||
explode: false
|
explode: false
|
||||||
required: false
|
required: false
|
||||||
description: The moest recent status id of the voucher.
|
description: The moest recent status id of the voucher.
|
||||||
|
- in: query
|
||||||
|
name: orderBy
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
enum: [PurchasedProductCreatedOn, PurchasedProductLastUpdatedOn]
|
||||||
|
explode: false
|
||||||
|
required: false
|
||||||
|
description: The ordering of the issuedVouchers in the list
|
||||||
responses:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
description: OK
|
description: OK
|
||||||
@ -1132,6 +1326,13 @@ paths:
|
|||||||
"issuedVoucherId": "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90",
|
"issuedVoucherId": "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90",
|
||||||
"purchasedProductId": "058a1af7-897f-45d5-b691-9cc9161e387f",
|
"purchasedProductId": "058a1af7-897f-45d5-b691-9cc9161e387f",
|
||||||
"voucherCode": "VOUCHER123",
|
"voucherCode": "VOUCHER123",
|
||||||
|
"productId": 888,
|
||||||
|
"touchPointId": 23,
|
||||||
|
"metadata1": null,
|
||||||
|
"metadata2": null,
|
||||||
|
"metadata3": null,
|
||||||
|
"metadata4": null,
|
||||||
|
"metadata5": null,
|
||||||
"voucherStatusInstances":
|
"voucherStatusInstances":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
@ -1139,12 +1340,14 @@ paths:
|
|||||||
"voucherStatus":
|
"voucherStatus":
|
||||||
{ "voucherStatusId": 1, "name": "New" },
|
{ "voucherStatusId": 1, "name": "New" },
|
||||||
"createdOn": "2024-10-04T12:34:56.000",
|
"createdOn": "2024-10-04T12:34:56.000",
|
||||||
|
"reason": null,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"voucherStatusInstanceId": "b01412e6-70fb-4c05-9bef-e65bf2747ca1",
|
"voucherStatusInstanceId": "b01412e6-70fb-4c05-9bef-e65bf2747ca1",
|
||||||
"voucherStatus":
|
"voucherStatus":
|
||||||
{ "voucherStatusId": 2, "name": "Issued" },
|
{ "voucherStatusId": 2, "name": "Issued" },
|
||||||
"createdOn": "2024-10-04T12:37:14.000",
|
"createdOn": "2024-10-04T12:37:14.000",
|
||||||
|
"reason": "test reason",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"voucherClaims":
|
"voucherClaims":
|
||||||
@ -1163,7 +1366,7 @@ paths:
|
|||||||
"mandatoryCustomerDataItemId": 4,
|
"mandatoryCustomerDataItemId": 4,
|
||||||
"customerDataItem": "emailAddress",
|
"customerDataItem": "emailAddress",
|
||||||
},
|
},
|
||||||
"value": "vlad.harkonnen@househarkonnen.net",
|
"value": "john.doe@example.com",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"fromInclusive": "2024-10-04T12:34:56.000",
|
"fromInclusive": "2024-10-04T12:34:56.000",
|
||||||
@ -1191,9 +1394,16 @@ paths:
|
|||||||
content:
|
content:
|
||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
$ref: "#/components/schemas/unavailable"
|
$ref: "#/components/schemas/PostIssuedVoucherStatusInstanceRequest"
|
||||||
example:
|
examples:
|
||||||
{ "voucherStatusId": 2, "createdOn": "2024-10-04T12:34:56.000" }
|
newToIssued:
|
||||||
|
summary: Mark a voucher as issued
|
||||||
|
value:
|
||||||
|
{ "voucherStatusId": 2, "createdOn": "2024-10-04T12:34:56.000" }
|
||||||
|
issuedToRevokedWithReason:
|
||||||
|
summary: Mark a voucher as revoked with reason
|
||||||
|
value:
|
||||||
|
{ "voucherStatusId": 4, "createdOn": "2024-10-04T12:34:56.000", "reason": "Voucher revoked because it was redeemed by an unauthorized user." }
|
||||||
responses:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
description: OK
|
description: OK
|
||||||
@ -1227,6 +1437,7 @@ paths:
|
|||||||
{ "voucherStatusId": 3, "name": "Redeemed" },
|
{ "voucherStatusId": 3, "name": "Redeemed" },
|
||||||
{ "voucherStatusId": 4, "name": "Revoked" },
|
{ "voucherStatusId": 4, "name": "Revoked" },
|
||||||
{ "voucherStatusId": 5, "name": "Expired" },
|
{ "voucherStatusId": 5, "name": "Expired" },
|
||||||
|
{ "voucherStatusId": 6, "name": "PendingRedemption" },
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
components:
|
components:
|
||||||
@ -1238,6 +1449,22 @@ components:
|
|||||||
schemas:
|
schemas:
|
||||||
unavailable:
|
unavailable:
|
||||||
type: object
|
type: object
|
||||||
|
PostIssuedVoucherStatusInstanceRequest:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- voucherStatusId
|
||||||
|
- createdOn
|
||||||
|
properties:
|
||||||
|
voucherStatusId:
|
||||||
|
type: integer
|
||||||
|
example: 4
|
||||||
|
createdOn:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
|
example: 2024-10-04T12:34:56.000
|
||||||
|
reason:
|
||||||
|
type: string
|
||||||
|
example: "Voucher revoked because it was redeemed by an unauthorized user."
|
||||||
PostPurchasedTapConnectTicketRequest:
|
PostPurchasedTapConnectTicketRequest:
|
||||||
type: object
|
type: object
|
||||||
required:
|
required:
|
||||||
@ -1299,56 +1526,6 @@ components:
|
|||||||
format: date-time
|
format: date-time
|
||||||
description: The date-time at which the ticket will become invalid for traveling. The ticket will not be valid after this date/time.
|
description: The date-time at which the ticket will become invalid for traveling. The ticket will not be valid after this date/time.
|
||||||
example: 2024-10-06T12:34:56.000
|
example: 2024-10-06T12:34:56.000
|
||||||
BulkResponseBody:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
startTime:
|
|
||||||
type: string
|
|
||||||
format: date-time
|
|
||||||
example: 2025-02-14T05:32:47.0672237Z
|
|
||||||
status:
|
|
||||||
type: string
|
|
||||||
example: Running
|
|
||||||
clientTrackingId:
|
|
||||||
type: string
|
|
||||||
example: 08584620957189579629541919368CU00
|
|
||||||
callbackurl:
|
|
||||||
type: string
|
|
||||||
format: uri
|
|
||||||
example: https://services.api.htm.nl/purchasedproducts/responsestatus/runtime/webhooks/workflow/scaleUnits/prod-00/workflows/6fd466916c
|
|
||||||
retryAfter:
|
|
||||||
type: integer
|
|
||||||
example: 10
|
|
||||||
summary:
|
|
||||||
$ref: "#/components/schemas/summaryBody"
|
|
||||||
required:
|
|
||||||
- startTime
|
|
||||||
- status
|
|
||||||
- clientTrackingId
|
|
||||||
- callbackurl
|
|
||||||
- retryAfter
|
|
||||||
- summary
|
|
||||||
summaryBody:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
summary:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
created:
|
|
||||||
type: integer
|
|
||||||
example: 15
|
|
||||||
updated:
|
|
||||||
type: integer
|
|
||||||
example: 2
|
|
||||||
total:
|
|
||||||
type: integer
|
|
||||||
example: 17
|
|
||||||
required:
|
|
||||||
- created
|
|
||||||
- total
|
|
||||||
- updated
|
|
||||||
required:
|
|
||||||
- summary
|
|
||||||
rfc9457:
|
rfc9457:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
|
|||||||
@ -1,121 +0,0 @@
|
|||||||
# Notification preferences transformation service - Python example
|
|
||||||
|
|
||||||
Reference implementation for the Service Engine `GET /customers/notificationpreferences` endpoint. It composes raw CRUD API data into the frontend-friendly response model from `SE-notifications.yaml`.
|
|
||||||
|
|
||||||
## Supplied contracts used
|
|
||||||
|
|
||||||
- `notifications-crud.yaml`
|
|
||||||
- `GET /notificationsubscriptions?customerProfileId={id}&expand=eventTypeChannel`
|
|
||||||
- `GET /notificationcategories?notificationCategoryId={id}&expand=eventTypeChannel`
|
|
||||||
- `customers-crud-v2.yaml`
|
|
||||||
- `GET /ovpaytokens?ovPayTokenId={id}`
|
|
||||||
- `GET /devices?customerProfileId={id}`
|
|
||||||
- `GET /customers?customerProfileId={id}` for person/email resource data
|
|
||||||
- `SE-notifications.yaml`
|
|
||||||
- `GET /customers/notificationpreferences`
|
|
||||||
|
|
||||||
## Runtime options
|
|
||||||
|
|
||||||
### Local FastAPI with real CRUD APIs
|
|
||||||
|
|
||||||
```powershell
|
|
||||||
.\.venv\Scripts\python.exe -m pip install -r requirements.txt
|
|
||||||
$env:NOTIFICATIONS_CRUD_BASE_URL="https://your-notifications-crud-api.example.nl"
|
|
||||||
$env:CUSTOMERS_CRUD_BASE_URL="https://your-customers-crud-api.example.nl"
|
|
||||||
.\.venv\Scripts\python.exe -m uvicorn app.entrypoints.fastapi_app:app --reload
|
|
||||||
```
|
|
||||||
|
|
||||||
Call:
|
|
||||||
|
|
||||||
```powershell
|
|
||||||
Invoke-RestMethod `
|
|
||||||
-Uri "http://127.0.0.1:8000/customers/notificationpreferences?deviceId=device-1" `
|
|
||||||
-Headers @{"X-HTM-CUSTOMER-PROFILE-ID-HEADER"="42"}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Local FastAPI with mock data
|
|
||||||
|
|
||||||
Use mock mode when you want to demo or test the transformation without live CRUD APIs.
|
|
||||||
|
|
||||||
```powershell
|
|
||||||
$env:USE_MOCK_DATA="true"
|
|
||||||
$env:MOCK_SCENARIO="mixed"
|
|
||||||
.\.venv\Scripts\python.exe -m uvicorn app.entrypoints.fastapi_app:app --reload
|
|
||||||
```
|
|
||||||
|
|
||||||
Open:
|
|
||||||
|
|
||||||
```text
|
|
||||||
http://127.0.0.1:8000/docs
|
|
||||||
```
|
|
||||||
|
|
||||||
Health check:
|
|
||||||
|
|
||||||
```text
|
|
||||||
http://127.0.0.1:8000/health
|
|
||||||
```
|
|
||||||
|
|
||||||
Available mock scenarios:
|
|
||||||
|
|
||||||
| Scenario | Purpose |
|
|
||||||
|---|---|
|
|
||||||
| `mixed` | Default-on push, default-off email, plus customer deviations |
|
|
||||||
| `defaults_only` | No customer preferences, so only defaults are applied |
|
|
||||||
| `global_override` | Preference with `resourceIdentifier = null` applies to all resources |
|
|
||||||
| `inactive_subscription` | Subscription is returned but marked inactive |
|
|
||||||
|
|
||||||
### Azure Function
|
|
||||||
|
|
||||||
Use `app/entrypoints/azure_function.py` as the HTTP-trigger body. Keep the `app/services` and `app/domain` modules unchanged.
|
|
||||||
|
|
||||||
## Running automated tests
|
|
||||||
|
|
||||||
```powershell
|
|
||||||
.\.venv\Scripts\python.exe -m pytest
|
|
||||||
```
|
|
||||||
|
|
||||||
The tests cover:
|
|
||||||
|
|
||||||
- default-on channel without preference -> active
|
|
||||||
- default-on channel with preference -> inactive deviation
|
|
||||||
- default-off channel without preference -> inactive
|
|
||||||
- default-off channel with preference -> active deviation
|
|
||||||
- global preference where `resourceIdentifier = null`
|
|
||||||
- device filtering via `deviceId`
|
|
||||||
- inactive subscription still returned as inactive
|
|
||||||
|
|
||||||
## Design choice
|
|
||||||
|
|
||||||
The implementation deliberately separates:
|
|
||||||
|
|
||||||
- HTTP entrypoints: request/response only
|
|
||||||
- CRUD client: raw REST calls only
|
|
||||||
- Mock CRUD client: deterministic local/demo data
|
|
||||||
- Service layer: composition and transformation logic
|
|
||||||
- Domain models: frontend/SE response shape
|
|
||||||
|
|
||||||
This makes the same transformation reusable in Azure Functions, Container Apps, and tests.
|
|
||||||
|
|
||||||
## Business rule interpretation
|
|
||||||
|
|
||||||
For each customer subscription:
|
|
||||||
|
|
||||||
1. Load customer `NotificationSubscriptions` with `NotificationPreferences` expanded to `EventTypeChannel`.
|
|
||||||
2. Load the default category definition with all `EventTypes` and `EventTypeChannels`.
|
|
||||||
3. Load customer resources for each channel resource type:
|
|
||||||
- `resourceNameId = 8` -> `GET /devices?customerProfileId={id}`
|
|
||||||
- `resourceNameId = 4` -> `GET /customers?customerProfileId={id}` and use the embedded `person` email data
|
|
||||||
4. For every default `EventTypeChannel`, write out resources explicitly.
|
|
||||||
5. If the channel is default-on and no preference exists, resource is active.
|
|
||||||
6. If the channel is default-off and no preference exists, resource is inactive.
|
|
||||||
7. A `NotificationPreference` row is interpreted as a deviation:
|
|
||||||
- default-on + preference -> inactive unless explicit `isActive` says otherwise
|
|
||||||
- default-off + preference -> active unless explicit `isActive` says otherwise
|
|
||||||
8. A null `resourceIdentifier` applies to all resources for that EventTypeChannel.
|
|
||||||
|
|
||||||
## Production hardening points
|
|
||||||
|
|
||||||
- Add authentication propagation from the SE API to both CRUD APIs.
|
|
||||||
- Decide whether category defaults should be cached across requests.
|
|
||||||
- Decide whether missing category defaults should become `502 Bad Gateway`, partial data, or an empty category.
|
|
||||||
- Confirm whether the real `NotificationPreference` has explicit `isActive`; this example supports it, but also works when preference existence alone means deviation.
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,89 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
from typing import Any, Optional
|
|
||||||
import httpx
|
|
||||||
|
|
||||||
|
|
||||||
class CrudApiClient:
|
|
||||||
"""Thin async client around the ABT CRUD APIs.
|
|
||||||
|
|
||||||
Keep business/transformation logic out of this class. The client only knows how
|
|
||||||
to call the source endpoints and unwrap the collection names from the CRUD
|
|
||||||
contracts.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
notifications_base_url: str,
|
|
||||||
customers_base_url: str,
|
|
||||||
timeout_seconds: float = 10.0,
|
|
||||||
):
|
|
||||||
self.notifications_base_url = notifications_base_url.rstrip("/")
|
|
||||||
self.customers_base_url = customers_base_url.rstrip("/")
|
|
||||||
self.timeout_seconds = timeout_seconds
|
|
||||||
|
|
||||||
async def _get(
|
|
||||||
self,
|
|
||||||
base_url: str,
|
|
||||||
path: str,
|
|
||||||
params: Optional[dict[str, Any]] = None,
|
|
||||||
) -> dict[str, Any]:
|
|
||||||
async with httpx.AsyncClient(base_url=base_url, timeout=self.timeout_seconds) as client:
|
|
||||||
response = await client.get(path, params=params)
|
|
||||||
response.raise_for_status()
|
|
||||||
return response.json()
|
|
||||||
|
|
||||||
# notifications-crud.yaml
|
|
||||||
async def get_notification_subscriptions(self, customer_profile_id: int) -> list[dict[str, Any]]:
|
|
||||||
payload = await self._get(
|
|
||||||
self.notifications_base_url,
|
|
||||||
"/notificationsubscriptions",
|
|
||||||
params={"customerProfileId": customer_profile_id, "expand": "eventTypeChannel"},
|
|
||||||
)
|
|
||||||
return payload.get("notificationSubscriptions", [])
|
|
||||||
|
|
||||||
async def get_notification_category_defaults(self, notification_category_id: int) -> Optional[dict[str, Any]]:
|
|
||||||
payload = await self._get(
|
|
||||||
self.notifications_base_url,
|
|
||||||
"/notificationcategories",
|
|
||||||
params={"notificationCategoryId": notification_category_id, "expand": "eventTypeChannel"},
|
|
||||||
)
|
|
||||||
categories = payload.get("notificationCategories", [])
|
|
||||||
return categories[0] if categories else None
|
|
||||||
|
|
||||||
# customers-crud-v2.yaml
|
|
||||||
async def get_ovpay_token(self, ovpay_token_id: Optional[int]) -> Optional[dict[str, Any]]:
|
|
||||||
if ovpay_token_id is None:
|
|
||||||
return None
|
|
||||||
payload = await self._get(
|
|
||||||
self.customers_base_url,
|
|
||||||
"/ovpaytokens",
|
|
||||||
params={"ovPayTokenId": ovpay_token_id},
|
|
||||||
)
|
|
||||||
tokens = payload.get("ovPayTokens", [])
|
|
||||||
return tokens[0] if tokens else None
|
|
||||||
|
|
||||||
async def get_devices(self, customer_profile_id: int) -> list[dict[str, Any]]:
|
|
||||||
payload = await self._get(
|
|
||||||
self.customers_base_url,
|
|
||||||
"/devices",
|
|
||||||
params={"customerProfileId": customer_profile_id},
|
|
||||||
)
|
|
||||||
return payload.get("devices", [])
|
|
||||||
|
|
||||||
async def get_persons(self, customer_profile_id: int) -> list[dict[str, Any]]:
|
|
||||||
"""Return customer/person resources used for email-like channels.
|
|
||||||
|
|
||||||
customers-crud-v2.yaml exposes person details through GET /customers,
|
|
||||||
filtered by customerProfileId. For the transformation service we normalize
|
|
||||||
the matching customer profile into one resource with the customer's email.
|
|
||||||
"""
|
|
||||||
payload = await self._get(
|
|
||||||
self.customers_base_url,
|
|
||||||
"/customers",
|
|
||||||
params={"customerProfileId": customer_profile_id},
|
|
||||||
)
|
|
||||||
return payload.get("customers", [])
|
|
||||||
|
|
||||||
|
|
||||||
# Backwards-compatible alias used by the service type hints.
|
|
||||||
NotificationsCrudClient = CrudApiClient
|
|
||||||
@ -1,162 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
from copy import deepcopy
|
|
||||||
from typing import Any, Optional
|
|
||||||
|
|
||||||
|
|
||||||
class MockCrudClient:
|
|
||||||
"""Deterministic in-memory CRUD client for local demos and tests.
|
|
||||||
|
|
||||||
It implements the same methods as CrudApiClient, so the service layer does
|
|
||||||
not know whether data comes from real CRUD APIs or from mock fixtures.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, scenario: str = "mixed"):
|
|
||||||
self.scenario = scenario
|
|
||||||
|
|
||||||
async def get_notification_subscriptions(self, customer_profile_id: int) -> list[dict[str, Any]]:
|
|
||||||
subscriptions = deepcopy(MOCK_SUBSCRIPTIONS.get(self.scenario, MOCK_SUBSCRIPTIONS["mixed"]))
|
|
||||||
for subscription in subscriptions:
|
|
||||||
subscription["customerProfileId"] = customer_profile_id
|
|
||||||
return subscriptions
|
|
||||||
|
|
||||||
async def get_notification_category_defaults(self, notification_category_id: int) -> Optional[dict[str, Any]]:
|
|
||||||
return deepcopy(MOCK_CATEGORIES.get(notification_category_id))
|
|
||||||
|
|
||||||
async def get_ovpay_token(self, ovpay_token_id: Optional[int]) -> Optional[dict[str, Any]]:
|
|
||||||
if ovpay_token_id is None:
|
|
||||||
return None
|
|
||||||
return deepcopy(MOCK_OVPAY_TOKENS.get(ovpay_token_id, {"ovPayTokenId": ovpay_token_id, "alias": None}))
|
|
||||||
|
|
||||||
async def get_devices(self, customer_profile_id: int) -> list[dict[str, Any]]:
|
|
||||||
return deepcopy(MOCK_DEVICES)
|
|
||||||
|
|
||||||
async def get_persons(self, customer_profile_id: int) -> list[dict[str, Any]]:
|
|
||||||
return deepcopy(MOCK_CUSTOMERS)
|
|
||||||
|
|
||||||
|
|
||||||
MOCK_CATEGORIES: dict[int, dict[str, Any]] = {
|
|
||||||
1: {
|
|
||||||
"notificationCategoryId": 1,
|
|
||||||
"name": "Reizen",
|
|
||||||
"groupName": "Mijn passen",
|
|
||||||
"eventTypes": [
|
|
||||||
{
|
|
||||||
"eventTypeId": 10,
|
|
||||||
"name": "OVPAY_CHECK_IN",
|
|
||||||
"subName": "Check-in",
|
|
||||||
"prettyName": "Check-in bevestiging",
|
|
||||||
"eventTypeChannels": [
|
|
||||||
{
|
|
||||||
"eventTypeChannelId": "etc-push-default-on",
|
|
||||||
"channel": {
|
|
||||||
"channelId": 1,
|
|
||||||
"name": "Push",
|
|
||||||
"resourceName": {"resourceNameId": 8, "name": "devices"},
|
|
||||||
},
|
|
||||||
"isDefault": True,
|
|
||||||
"isMandatory": False,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"eventTypeChannelId": "etc-email-default-off",
|
|
||||||
"channel": {
|
|
||||||
"channelId": 2,
|
|
||||||
"name": "E-mail",
|
|
||||||
"resourceName": {"resourceNameId": 4, "name": "customers"},
|
|
||||||
},
|
|
||||||
"isDefault": False,
|
|
||||||
"isMandatory": False,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"eventTypeId": 20,
|
|
||||||
"name": "SERVICE_MESSAGE",
|
|
||||||
"subName": "Service",
|
|
||||||
"prettyName": "Servicebericht",
|
|
||||||
"eventTypeChannels": [
|
|
||||||
{
|
|
||||||
"eventTypeChannelId": "etc-email-mandatory",
|
|
||||||
"channel": {
|
|
||||||
"channelId": 2,
|
|
||||||
"name": "E-mail",
|
|
||||||
"resourceName": {"resourceNameId": 4, "name": "customers"},
|
|
||||||
},
|
|
||||||
"isDefault": True,
|
|
||||||
"isMandatory": True,
|
|
||||||
}
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MOCK_SUBSCRIPTIONS: dict[str, list[dict[str, Any]]] = {
|
|
||||||
# Mixed scenario demonstrates both default behavior and customer deviations.
|
|
||||||
"mixed": [
|
|
||||||
{
|
|
||||||
"notificationSubscriptionId": "sub-mixed-1",
|
|
||||||
"notificationCategoryId": 1,
|
|
||||||
"notificationCategory": {"notificationCategoryId": 1, "name": "Reizen", "groupName": "Mijn passen"},
|
|
||||||
"customerProfileId": 42,
|
|
||||||
"ovPayTokenId": 112,
|
|
||||||
"subscriptionActivities": [{"timestamp": "2026-04-01T10:00:00Z", "isActive": True}],
|
|
||||||
"notificationPreferences": [
|
|
||||||
# Default push=true: this row opts out only device-2.
|
|
||||||
{"notificationPreferenceId": "pref-push-device-2-off", "eventTypeChannelId": "etc-push-default-on", "resourceIdentifier": "device-2"},
|
|
||||||
# Default email=false: this row opts in the customer's email resource.
|
|
||||||
{"notificationPreferenceId": "pref-email-on", "eventTypeChannelId": "etc-email-default-off", "resourceIdentifier": "42"},
|
|
||||||
],
|
|
||||||
}
|
|
||||||
],
|
|
||||||
# No preferences: output should be entirely based on category defaults.
|
|
||||||
"defaults_only": [
|
|
||||||
{
|
|
||||||
"notificationSubscriptionId": "sub-defaults-1",
|
|
||||||
"notificationCategoryId": 1,
|
|
||||||
"notificationCategory": {"notificationCategoryId": 1, "name": "Reizen", "groupName": "Mijn passen"},
|
|
||||||
"customerProfileId": 42,
|
|
||||||
"ovPayTokenId": 112,
|
|
||||||
"subscriptionActivities": [{"timestamp": "2026-04-01T10:00:00Z", "isActive": True}],
|
|
||||||
"notificationPreferences": [],
|
|
||||||
}
|
|
||||||
],
|
|
||||||
# Global preference: null resourceIdentifier applies the deviation to all resources.
|
|
||||||
"global_override": [
|
|
||||||
{
|
|
||||||
"notificationSubscriptionId": "sub-global-1",
|
|
||||||
"notificationCategoryId": 1,
|
|
||||||
"notificationCategory": {"notificationCategoryId": 1, "name": "Reizen", "groupName": "Mijn passen"},
|
|
||||||
"customerProfileId": 42,
|
|
||||||
"ovPayTokenId": 112,
|
|
||||||
"subscriptionActivities": [{"timestamp": "2026-04-01T10:00:00Z", "isActive": True}],
|
|
||||||
"notificationPreferences": [
|
|
||||||
{"notificationPreferenceId": "pref-all-push-off", "eventTypeChannelId": "etc-push-default-on", "resourceIdentifier": None}
|
|
||||||
],
|
|
||||||
}
|
|
||||||
],
|
|
||||||
# Subscription inactive while preferences are still written out for the frontend.
|
|
||||||
"inactive_subscription": [
|
|
||||||
{
|
|
||||||
"notificationSubscriptionId": "sub-inactive-1",
|
|
||||||
"notificationCategoryId": 1,
|
|
||||||
"notificationCategory": {"notificationCategoryId": 1, "name": "Reizen", "groupName": "Mijn passen"},
|
|
||||||
"customerProfileId": 42,
|
|
||||||
"ovPayTokenId": 112,
|
|
||||||
"subscriptionActivities": [{"timestamp": "2026-04-01T10:00:00Z", "isActive": False}],
|
|
||||||
"notificationPreferences": [],
|
|
||||||
}
|
|
||||||
],
|
|
||||||
}
|
|
||||||
|
|
||||||
MOCK_OVPAY_TOKENS = {
|
|
||||||
112: {"ovPayTokenId": 112, "alias": "Mijn betaalpas"},
|
|
||||||
}
|
|
||||||
|
|
||||||
MOCK_DEVICES = [
|
|
||||||
{"deviceId": "device-1", "alias": "Mijn iPhone"},
|
|
||||||
{"deviceId": "device-2", "alias": "Werktelefoon"},
|
|
||||||
]
|
|
||||||
|
|
||||||
MOCK_CUSTOMERS = [
|
|
||||||
{"customerProfileId": 42, "person": {"emailAddress": "klant@example.nl"}},
|
|
||||||
]
|
|
||||||
Binary file not shown.
Binary file not shown.
@ -1,60 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
from typing import Any, Optional
|
|
||||||
from pydantic import BaseModel, Field
|
|
||||||
|
|
||||||
|
|
||||||
class Resource(BaseModel):
|
|
||||||
resourceName: str
|
|
||||||
resourceIdentifier: str
|
|
||||||
alias: Optional[str] = None
|
|
||||||
isActive: bool
|
|
||||||
|
|
||||||
|
|
||||||
class EventTypeChannelPreference(BaseModel):
|
|
||||||
eventTypeChannelId: str
|
|
||||||
channelId: int
|
|
||||||
name: str
|
|
||||||
isMandatory: bool = False
|
|
||||||
resources: list[Resource] = Field(default_factory=list)
|
|
||||||
|
|
||||||
|
|
||||||
class EventTypePreference(BaseModel):
|
|
||||||
eventTypeId: int
|
|
||||||
name: str
|
|
||||||
subName: Optional[str] = None
|
|
||||||
prettyName: str
|
|
||||||
eventTypeChannels: list[EventTypeChannelPreference] = Field(default_factory=list)
|
|
||||||
|
|
||||||
|
|
||||||
class OvPayToken(BaseModel):
|
|
||||||
ovPayTokenId: int
|
|
||||||
alias: Optional[str] = None
|
|
||||||
|
|
||||||
|
|
||||||
class NotificationSubscriptionPreference(BaseModel):
|
|
||||||
notificationSubscriptionId: str
|
|
||||||
customerProfileId: int
|
|
||||||
ovPayToken: Optional[OvPayToken] = None
|
|
||||||
isActive: bool
|
|
||||||
eventTypes: list[EventTypePreference] = Field(default_factory=list)
|
|
||||||
|
|
||||||
|
|
||||||
class NotificationCategoryPreference(BaseModel):
|
|
||||||
notificationCategoryId: int
|
|
||||||
name: str
|
|
||||||
groupName: Optional[str] = None
|
|
||||||
notificationSubscriptions: list[NotificationSubscriptionPreference] = Field(default_factory=list)
|
|
||||||
|
|
||||||
|
|
||||||
class CustomerNotificationPreferencesResponse(BaseModel):
|
|
||||||
notificationCategories: list[NotificationCategoryPreference] = Field(default_factory=list)
|
|
||||||
|
|
||||||
|
|
||||||
def latest_activity_is_active(subscription: dict[str, Any]) -> bool:
|
|
||||||
"""CRUD returns subscriptionActivities; the most recent/current one determines active state."""
|
|
||||||
activities = subscription.get("subscriptionActivities") or []
|
|
||||||
if not activities:
|
|
||||||
return False
|
|
||||||
# CRUD activityLimit defaults to 1; when more are supplied, sort defensively on timestamp.
|
|
||||||
latest = sorted(activities, key=lambda a: a.get("timestamp", ""), reverse=True)[0]
|
|
||||||
return bool(latest.get("isActive"))
|
|
||||||
Binary file not shown.
@ -1,17 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
import azure.functions as func
|
|
||||||
|
|
||||||
from app.service_factory import create_notification_preferences_service
|
|
||||||
|
|
||||||
|
|
||||||
async def main(req: func.HttpRequest) -> func.HttpResponse:
|
|
||||||
customer_profile_id = req.headers.get("X-HTM-CUSTOMER-PROFILE-ID-HEADER")
|
|
||||||
if not customer_profile_id:
|
|
||||||
return func.HttpResponse("Missing X-HTM-CUSTOMER-PROFILE-ID-HEADER", status_code=400)
|
|
||||||
|
|
||||||
service = create_notification_preferences_service()
|
|
||||||
result = await service.get_customer_notification_preferences(
|
|
||||||
customer_profile_id=int(customer_profile_id),
|
|
||||||
device_id=req.params.get("deviceId"),
|
|
||||||
)
|
|
||||||
return func.HttpResponse(result.model_dump_json(exclude_none=True), mimetype="application/json", status_code=200)
|
|
||||||
@ -1,25 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
from fastapi import FastAPI, Header, Query
|
|
||||||
|
|
||||||
from app.domain.models import CustomerNotificationPreferencesResponse
|
|
||||||
from app.service_factory import create_notification_preferences_service
|
|
||||||
from app.settings import settings
|
|
||||||
|
|
||||||
app = FastAPI(title="SE Notifications example")
|
|
||||||
|
|
||||||
|
|
||||||
@app.get("/health")
|
|
||||||
async def health():
|
|
||||||
return {"status": "ok", "useMockData": settings.use_mock_data, "mockScenario": settings.mock_scenario}
|
|
||||||
|
|
||||||
|
|
||||||
@app.get("/customers/notificationpreferences", response_model=CustomerNotificationPreferencesResponse)
|
|
||||||
async def get_customer_notification_preferences(
|
|
||||||
x_htm_customer_profile_id_header: int = Header(..., alias="X-HTM-CUSTOMER-PROFILE-ID-HEADER"),
|
|
||||||
device_id: str | None = Query(default=None, alias="deviceId"),
|
|
||||||
):
|
|
||||||
service = create_notification_preferences_service()
|
|
||||||
return await service.get_customer_notification_preferences(
|
|
||||||
customer_profile_id=x_htm_customer_profile_id_header,
|
|
||||||
device_id=device_id,
|
|
||||||
)
|
|
||||||
@ -1,18 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from app.clients.crud_client import CrudApiClient
|
|
||||||
from app.clients.mock_crud_client import MockCrudClient
|
|
||||||
from app.services.notification_preferences_service import NotificationPreferencesService
|
|
||||||
from app.settings import settings
|
|
||||||
|
|
||||||
|
|
||||||
def create_notification_preferences_service() -> NotificationPreferencesService:
|
|
||||||
if settings.use_mock_data:
|
|
||||||
return NotificationPreferencesService(MockCrudClient(settings.mock_scenario))
|
|
||||||
|
|
||||||
return NotificationPreferencesService(
|
|
||||||
CrudApiClient(
|
|
||||||
notifications_base_url=settings.notifications_crud_base_url,
|
|
||||||
customers_base_url=settings.customers_crud_base_url,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
Binary file not shown.
Binary file not shown.
@ -1,228 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
from collections import defaultdict
|
|
||||||
from typing import Any, Optional
|
|
||||||
|
|
||||||
from app.clients.crud_client import NotificationsCrudClient
|
|
||||||
from app.domain.models import (
|
|
||||||
CustomerNotificationPreferencesResponse,
|
|
||||||
EventTypeChannelPreference,
|
|
||||||
EventTypePreference,
|
|
||||||
NotificationCategoryPreference,
|
|
||||||
NotificationSubscriptionPreference,
|
|
||||||
OvPayToken,
|
|
||||||
Resource,
|
|
||||||
latest_activity_is_active,
|
|
||||||
)
|
|
||||||
|
|
||||||
RESOURCE_DEVICES_ID = 8
|
|
||||||
RESOURCE_PERSONS_ID = 4
|
|
||||||
|
|
||||||
|
|
||||||
class NotificationPreferencesService:
|
|
||||||
def __init__(self, crud_client: NotificationsCrudClient):
|
|
||||||
self.crud_client = crud_client
|
|
||||||
|
|
||||||
async def get_customer_notification_preferences(
|
|
||||||
self,
|
|
||||||
customer_profile_id: int,
|
|
||||||
device_id: Optional[str] = None,
|
|
||||||
) -> CustomerNotificationPreferencesResponse:
|
|
||||||
subscriptions = await self.crud_client.get_notification_subscriptions(customer_profile_id)
|
|
||||||
categories_by_id: dict[int, NotificationCategoryPreference] = {}
|
|
||||||
|
|
||||||
# Small in-request caches avoid repeated calls for the same category/resources.
|
|
||||||
default_category_cache: dict[int, dict[str, Any]] = {}
|
|
||||||
resource_cache: dict[int, list[dict[str, Any]]] = {}
|
|
||||||
|
|
||||||
for subscription in subscriptions:
|
|
||||||
category_id = _extract_category_id(subscription)
|
|
||||||
default_category = default_category_cache.get(category_id)
|
|
||||||
if default_category is None:
|
|
||||||
default_category = await self.crud_client.get_notification_category_defaults(category_id)
|
|
||||||
if default_category is None:
|
|
||||||
# Defensive choice: skip orphaned subscriptions rather than returning incomplete UI data.
|
|
||||||
continue
|
|
||||||
default_category_cache[category_id] = default_category
|
|
||||||
|
|
||||||
category_response = categories_by_id.setdefault(
|
|
||||||
category_id,
|
|
||||||
NotificationCategoryPreference(
|
|
||||||
notificationCategoryId=category_id,
|
|
||||||
name=default_category.get("name") or subscription.get("notificationCategory", {}).get("name"),
|
|
||||||
groupName=default_category.get("groupName") or subscription.get("notificationCategory", {}).get("groupName"),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
token_payload = await self.crud_client.get_ovpay_token(subscription.get("ovPayTokenId"))
|
|
||||||
token = _to_ovpay_token(token_payload, subscription.get("ovPayTokenId"))
|
|
||||||
|
|
||||||
subscription_response = NotificationSubscriptionPreference(
|
|
||||||
notificationSubscriptionId=subscription["notificationSubscriptionId"],
|
|
||||||
customerProfileId=subscription["customerProfileId"],
|
|
||||||
ovPayToken=token,
|
|
||||||
isActive=latest_activity_is_active(subscription),
|
|
||||||
)
|
|
||||||
|
|
||||||
preferences_by_event_type_channel = _index_preferences(subscription)
|
|
||||||
|
|
||||||
for event_type in default_category.get("eventTypes", []):
|
|
||||||
event_type_response = EventTypePreference(
|
|
||||||
eventTypeId=event_type["eventTypeId"],
|
|
||||||
name=event_type["name"],
|
|
||||||
subName=event_type.get("subName"),
|
|
||||||
prettyName=event_type.get("prettyName") or event_type["name"],
|
|
||||||
)
|
|
||||||
|
|
||||||
for event_type_channel in event_type.get("eventTypeChannels", []):
|
|
||||||
channel = event_type_channel.get("channel", {})
|
|
||||||
resource_name = channel.get("resourceName", {})
|
|
||||||
resource_name_id = resource_name.get("resourceNameId")
|
|
||||||
resource_name_text = resource_name.get("name") or channel.get("name")
|
|
||||||
|
|
||||||
if resource_name_id not in resource_cache:
|
|
||||||
resource_cache[resource_name_id] = await self._load_resources(resource_name_id, customer_profile_id)
|
|
||||||
source_resources = resource_cache[resource_name_id]
|
|
||||||
|
|
||||||
if device_id and resource_name_id == RESOURCE_DEVICES_ID:
|
|
||||||
source_resources = [r for r in source_resources if str(_resource_identifier(r)) == str(device_id)]
|
|
||||||
if not source_resources:
|
|
||||||
# SE swagger states a deviceId filter returns only ETCs with resources for that device.
|
|
||||||
continue
|
|
||||||
|
|
||||||
matching_preferences = preferences_by_event_type_channel.get(
|
|
||||||
str(event_type_channel["eventTypeChannelId"]), []
|
|
||||||
)
|
|
||||||
|
|
||||||
resources = self._normalize_resources(
|
|
||||||
resource_name=resource_name_text,
|
|
||||||
event_type_channel=event_type_channel,
|
|
||||||
source_resources=source_resources,
|
|
||||||
preferences=matching_preferences,
|
|
||||||
)
|
|
||||||
|
|
||||||
event_type_response.eventTypeChannels.append(
|
|
||||||
EventTypeChannelPreference(
|
|
||||||
eventTypeChannelId=event_type_channel["eventTypeChannelId"],
|
|
||||||
channelId=channel["channelId"],
|
|
||||||
name=channel["name"],
|
|
||||||
isMandatory=bool(event_type_channel.get("isMandatory")),
|
|
||||||
resources=resources,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
if event_type_response.eventTypeChannels:
|
|
||||||
subscription_response.eventTypes.append(event_type_response)
|
|
||||||
|
|
||||||
category_response.notificationSubscriptions.append(subscription_response)
|
|
||||||
|
|
||||||
return CustomerNotificationPreferencesResponse(notificationCategories=list(categories_by_id.values()))
|
|
||||||
|
|
||||||
async def _load_resources(self, resource_name_id: int, customer_profile_id: int) -> list[dict[str, Any]]:
|
|
||||||
if resource_name_id == RESOURCE_DEVICES_ID:
|
|
||||||
return await self.crud_client.get_devices(customer_profile_id)
|
|
||||||
if resource_name_id == RESOURCE_PERSONS_ID:
|
|
||||||
return await self.crud_client.get_persons(customer_profile_id)
|
|
||||||
return []
|
|
||||||
|
|
||||||
def _normalize_resources(
|
|
||||||
self,
|
|
||||||
resource_name: str,
|
|
||||||
event_type_channel: dict[str, Any],
|
|
||||||
source_resources: list[dict[str, Any]],
|
|
||||||
preferences: list[dict[str, Any]],
|
|
||||||
) -> list[Resource]:
|
|
||||||
default_active = bool(event_type_channel.get("isDefault"))
|
|
||||||
|
|
||||||
if not preferences:
|
|
||||||
return [
|
|
||||||
Resource(
|
|
||||||
resourceName=resource_name,
|
|
||||||
resourceIdentifier=str(_resource_identifier(resource)),
|
|
||||||
alias=_resource_alias(resource),
|
|
||||||
isActive=default_active,
|
|
||||||
)
|
|
||||||
for resource in source_resources
|
|
||||||
]
|
|
||||||
|
|
||||||
# Preference rows are exceptions/deviations. A null resourceIdentifier means the exception applies to all resources.
|
|
||||||
preference_by_resource: dict[str, dict[str, Any]] = {}
|
|
||||||
global_preference: Optional[dict[str, Any]] = None
|
|
||||||
for preference in preferences:
|
|
||||||
pref_resource_id = preference.get("resourceIdentifier")
|
|
||||||
if pref_resource_id is None:
|
|
||||||
global_preference = preference
|
|
||||||
else:
|
|
||||||
preference_by_resource[str(pref_resource_id)] = preference
|
|
||||||
|
|
||||||
normalized: list[Resource] = []
|
|
||||||
for resource in source_resources:
|
|
||||||
resource_id = str(_resource_identifier(resource))
|
|
||||||
preference = preference_by_resource.get(resource_id) or global_preference
|
|
||||||
if preference is None:
|
|
||||||
is_active = default_active
|
|
||||||
else:
|
|
||||||
# The CRUD example only shows the existence of a preference row, no explicit isActive.
|
|
||||||
# Therefore: for default-on channels a row means opted out; for default-off a row means opted in.
|
|
||||||
is_active = bool(preference.get("isActive", not default_active))
|
|
||||||
|
|
||||||
normalized.append(
|
|
||||||
Resource(
|
|
||||||
resourceName=resource_name,
|
|
||||||
resourceIdentifier=resource_id,
|
|
||||||
alias=_resource_alias(resource),
|
|
||||||
isActive=is_active,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
return normalized
|
|
||||||
|
|
||||||
|
|
||||||
def _extract_category_id(subscription: dict[str, Any]) -> int:
|
|
||||||
if subscription.get("notificationCategoryId") is not None:
|
|
||||||
return int(subscription["notificationCategoryId"])
|
|
||||||
return int(subscription["notificationCategory"]["notificationCategoryId"])
|
|
||||||
|
|
||||||
|
|
||||||
def _index_preferences(subscription: dict[str, Any]) -> dict[str, list[dict[str, Any]]]:
|
|
||||||
result: dict[str, list[dict[str, Any]]] = defaultdict(list)
|
|
||||||
for preference in subscription.get("notificationPreferences", []) or []:
|
|
||||||
event_type_channel_id = preference.get("eventTypeChannelId")
|
|
||||||
if isinstance(event_type_channel_id, dict):
|
|
||||||
event_type_channel_id = event_type_channel_id.get("eventTypeChannelId")
|
|
||||||
if event_type_channel_id is None and isinstance(preference.get("eventTypeChannel"), dict):
|
|
||||||
event_type_channel_id = preference["eventTypeChannel"].get("eventTypeChannelId")
|
|
||||||
if event_type_channel_id is not None:
|
|
||||||
result[str(event_type_channel_id)].append(preference)
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
def _to_ovpay_token(payload: Optional[dict[str, Any]], fallback_id: Optional[int]) -> Optional[OvPayToken]:
|
|
||||||
if fallback_id is None:
|
|
||||||
return None
|
|
||||||
# Support both {ovPayToken: {...}} and direct {...} shapes.
|
|
||||||
token = (payload or {}).get("ovPayToken", payload or {})
|
|
||||||
return OvPayToken(ovPayTokenId=token.get("ovPayTokenId", fallback_id), alias=token.get("alias"))
|
|
||||||
|
|
||||||
|
|
||||||
def _resource_identifier(resource: dict[str, Any]) -> Any:
|
|
||||||
# Device resources use deviceId. Customer/person email resources are normalized
|
|
||||||
# to customerProfileId because customers-crud-v2 exposes person under /customers.
|
|
||||||
return (
|
|
||||||
resource.get("resourceIdentifier")
|
|
||||||
or resource.get("deviceId")
|
|
||||||
or resource.get("personId")
|
|
||||||
or resource.get("customerProfileId")
|
|
||||||
or resource.get("id")
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def _resource_alias(resource: dict[str, Any]) -> Optional[str]:
|
|
||||||
person = resource.get("person") or {}
|
|
||||||
return (
|
|
||||||
resource.get("alias")
|
|
||||||
or resource.get("emailAddress")
|
|
||||||
or resource.get("emailAddresses")
|
|
||||||
or resource.get("email")
|
|
||||||
or person.get("emailAddress")
|
|
||||||
or person.get("emailAddresses")
|
|
||||||
or resource.get("name")
|
|
||||||
)
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
from pydantic_settings import BaseSettings
|
|
||||||
|
|
||||||
|
|
||||||
class Settings(BaseSettings):
|
|
||||||
notifications_crud_base_url: str = "http://localhost:8001"
|
|
||||||
customers_crud_base_url: str = "http://localhost:8002"
|
|
||||||
|
|
||||||
# local development aid: set USE_MOCK_DATA=true to run without CRUD APIs
|
|
||||||
use_mock_data: bool = False
|
|
||||||
mock_scenario: str = "mixed"
|
|
||||||
|
|
||||||
|
|
||||||
settings = Settings()
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
fastapi==0.115.6
|
|
||||||
uvicorn[standard]==0.34.0
|
|
||||||
httpx==0.28.1
|
|
||||||
pydantic>=2.12.0
|
|
||||||
pydantic-settings>=2.7.1
|
|
||||||
azure-functions==1.21.3
|
|
||||||
pytest==8.3.4
|
|
||||||
pytest-asyncio==0.25.2
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,69 +0,0 @@
|
|||||||
import pytest
|
|
||||||
|
|
||||||
from app.clients.mock_crud_client import MockCrudClient
|
|
||||||
from app.services.notification_preferences_service import NotificationPreferencesService
|
|
||||||
|
|
||||||
|
|
||||||
def _channels(result):
|
|
||||||
subscription = result.notificationCategories[0].notificationSubscriptions[0]
|
|
||||||
return {
|
|
||||||
channel.eventTypeChannelId: channel
|
|
||||||
for event_type in subscription.eventTypes
|
|
||||||
for channel in event_type.eventTypeChannels
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
|
||||||
async def test_mixed_scenario_applies_default_on_and_default_off_deviations():
|
|
||||||
service = NotificationPreferencesService(MockCrudClient("mixed"))
|
|
||||||
result = await service.get_customer_notification_preferences(42)
|
|
||||||
channels = _channels(result)
|
|
||||||
|
|
||||||
push_resources = channels["etc-push-default-on"].resources
|
|
||||||
assert [(r.resourceIdentifier, r.isActive) for r in push_resources] == [
|
|
||||||
("device-1", True),
|
|
||||||
("device-2", False),
|
|
||||||
]
|
|
||||||
|
|
||||||
email_resources = channels["etc-email-default-off"].resources
|
|
||||||
assert [(r.resourceIdentifier, r.isActive) for r in email_resources] == [("42", True)]
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
|
||||||
async def test_defaults_only_scenario_writes_all_resources_from_defaults():
|
|
||||||
service = NotificationPreferencesService(MockCrudClient("defaults_only"))
|
|
||||||
result = await service.get_customer_notification_preferences(42)
|
|
||||||
channels = _channels(result)
|
|
||||||
|
|
||||||
assert [r.isActive for r in channels["etc-push-default-on"].resources] == [True, True]
|
|
||||||
assert [r.isActive for r in channels["etc-email-default-off"].resources] == [False]
|
|
||||||
assert channels["etc-email-mandatory"].isMandatory is True
|
|
||||||
assert [r.isActive for r in channels["etc-email-mandatory"].resources] == [True]
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
|
||||||
async def test_global_override_applies_to_all_resources_when_resource_identifier_is_null():
|
|
||||||
service = NotificationPreferencesService(MockCrudClient("global_override"))
|
|
||||||
result = await service.get_customer_notification_preferences(42)
|
|
||||||
channels = _channels(result)
|
|
||||||
|
|
||||||
assert [r.isActive for r in channels["etc-push-default-on"].resources] == [False, False]
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
|
||||||
async def test_device_filter_returns_only_requested_device_for_device_channels():
|
|
||||||
service = NotificationPreferencesService(MockCrudClient("mixed"))
|
|
||||||
result = await service.get_customer_notification_preferences(42, device_id="device-1")
|
|
||||||
channels = _channels(result)
|
|
||||||
|
|
||||||
assert [(r.resourceIdentifier, r.isActive) for r in channels["etc-push-default-on"].resources] == [("device-1", True)]
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
|
||||||
async def test_inactive_subscription_is_visible_but_marked_inactive():
|
|
||||||
service = NotificationPreferencesService(MockCrudClient("inactive_subscription"))
|
|
||||||
result = await service.get_customer_notification_preferences(42)
|
|
||||||
subscription = result.notificationCategories[0].notificationSubscriptions[0]
|
|
||||||
|
|
||||||
assert subscription.isActive is False
|
|
||||||
assert subscription.eventTypes
|
|
||||||
@ -1,83 +0,0 @@
|
|||||||
import pytest
|
|
||||||
|
|
||||||
from app.services.notification_preferences_service import NotificationPreferencesService
|
|
||||||
|
|
||||||
|
|
||||||
class FakeCrudClient:
|
|
||||||
async def get_notification_subscriptions(self, customer_profile_id: int):
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
"notificationSubscriptionId": "sub-1",
|
|
||||||
"notificationCategory": {"notificationCategoryId": 1, "name": "Reizen", "groupName": "Mijn passen"},
|
|
||||||
"customerProfileId": customer_profile_id,
|
|
||||||
"ovPayTokenId": 112,
|
|
||||||
"subscriptionActivities": [{"timestamp": "2026-01-01T00:00:00Z", "isActive": True}],
|
|
||||||
"notificationPreferences": [
|
|
||||||
# Default push=true, this row switches device-2 off only.
|
|
||||||
{"notificationPreferenceId": "pref-1", "eventTypeChannelId": "etc-push", "resourceIdentifier": "device-2"},
|
|
||||||
# Default email=false, this row switches customer email on.
|
|
||||||
{"notificationPreferenceId": "pref-2", "eventTypeChannelId": "etc-email", "resourceIdentifier": "42"},
|
|
||||||
],
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
async def get_notification_category_defaults(self, notification_category_id: int):
|
|
||||||
return {
|
|
||||||
"notificationCategoryId": 1,
|
|
||||||
"name": "Reizen",
|
|
||||||
"groupName": "Mijn passen",
|
|
||||||
"eventTypes": [
|
|
||||||
{
|
|
||||||
"eventTypeId": 2,
|
|
||||||
"name": "GBO",
|
|
||||||
"subName": "CI",
|
|
||||||
"prettyName": "Normal Check-in",
|
|
||||||
"eventTypeChannels": [
|
|
||||||
{
|
|
||||||
"eventTypeChannelId": "etc-push",
|
|
||||||
"channel": {"channelId": 1, "name": "push", "resourceName": {"resourceNameId": 8, "name": "devices"}},
|
|
||||||
"isDefault": True,
|
|
||||||
"isMandatory": False,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"eventTypeChannelId": "etc-email",
|
|
||||||
"channel": {"channelId": 2, "name": "email", "resourceName": {"resourceNameId": 4, "name": "customers"}},
|
|
||||||
"isDefault": False,
|
|
||||||
"isMandatory": False,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}
|
|
||||||
],
|
|
||||||
}
|
|
||||||
|
|
||||||
async def get_ovpay_token(self, ovpay_token_id):
|
|
||||||
return {"ovPayToken": {"ovPayTokenId": ovpay_token_id, "alias": "Mijn ING bankpas"}}
|
|
||||||
|
|
||||||
async def get_devices(self, customer_profile_id: int):
|
|
||||||
return [
|
|
||||||
{"deviceId": "device-1", "alias": "Mijn iPhone"},
|
|
||||||
{"deviceId": "device-2", "alias": "Mijn Pixel"},
|
|
||||||
]
|
|
||||||
|
|
||||||
async def get_persons(self, customer_profile_id: int):
|
|
||||||
return [{"customerProfileId": 42, "emailAddress": "customer@example.nl"}]
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
|
||||||
async def test_normalizes_defaults_and_customer_exceptions():
|
|
||||||
result = await NotificationPreferencesService(FakeCrudClient()).get_customer_notification_preferences(42)
|
|
||||||
event_type = result.notificationCategories[0].notificationSubscriptions[0].eventTypes[0]
|
|
||||||
|
|
||||||
push_resources = event_type.eventTypeChannels[0].resources
|
|
||||||
assert [r.isActive for r in push_resources] == [True, False]
|
|
||||||
|
|
||||||
email_resources = event_type.eventTypeChannels[1].resources
|
|
||||||
assert email_resources[0].isActive is True
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
|
||||||
async def test_device_filter_only_returns_that_device_resource():
|
|
||||||
result = await NotificationPreferencesService(FakeCrudClient()).get_customer_notification_preferences(42, device_id="device-1")
|
|
||||||
event_type = result.notificationCategories[0].notificationSubscriptions[0].eventTypes[0]
|
|
||||||
assert len(event_type.eventTypeChannels[0].resources) == 1
|
|
||||||
assert event_type.eventTypeChannels[0].resources[0].resourceIdentifier == "device-1"
|
|
||||||
0
src/trip.json
Normal file
0
src/trip.json
Normal file
151
trip2.json
Normal file
151
trip2.json
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
{ "tripId": 796727186, "tripVersion": 1, "tripStatus": "COMPLETE", "organisationIcon": "/icons/organisations/3.svg", "organisationId": "3", "organisationName": "HTM", "supersededByTripIds": [], "supersedesTripIds": [], "products": [ {
|
||||||
|
"productTemplateId": "30901", "productCommercialName": { "items": [ {
|
||||||
|
"key": "nl-NL", "value": "HTM 90% Korting" },
|
||||||
|
{
|
||||||
|
"key": "en-US", "value": "HTM 90% Discount" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"productIcon": "001.jpg", "purchaseDateTime": "2026-04-02T12:38:28+02:00", "organisationName": "ProductRetailer HTM", "appliedValue": -125, "organisationId": "3", "category": "SALES", "typesOfFareProduct": [ {
|
||||||
|
"privateCode": "discount" }
|
||||||
|
],
|
||||||
|
"xspit": "821ddb0d-4ea7-4a0d-84aa-bb7facce15d1" },
|
||||||
|
{
|
||||||
|
"productTemplateId": "N/A", "purchaseDateTime": "2025-07-09T12:39:27+02:00", "appliedValue": 139, "category": "SALES", "typesOfFareProduct": [ {
|
||||||
|
"privateCode": "payg" }
|
||||||
|
],
|
||||||
|
"xspit": "7618337f-c986-4bef-990d-f5a6b47292b8" },
|
||||||
|
{
|
||||||
|
"productTemplateId": "1:2000", "productCommercialName": { "items": [ {
|
||||||
|
"key": "nl-NL", "value": "Basis Bus Tram Metro" },
|
||||||
|
{
|
||||||
|
"key": "en-US", "value": "BTM full fare" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"validFrom": "2000-01-01T01:00:00+01:00", "validUntil": "2100-01-01T00:59:59+01:00", "weight": 116, "appliedMetric": "FARE", "appliedValue": 116, "category": "INTERNAL", "typesOfFareProduct": [ {
|
||||||
|
"privateCode": "payg" }
|
||||||
|
],
|
||||||
|
"xspit": "7618337f-c986-4bef-990d-f5a6b47292b8", "xpit": "f4256df6-b767-460f-9880-f7597bd7f3f2" },
|
||||||
|
{
|
||||||
|
"productTemplateId": "2:2000", "productCommercialName": { "items": [ {
|
||||||
|
"key": "nl-NL", "value": "Basis Bus Tram Metro" },
|
||||||
|
{
|
||||||
|
"key": "en-US", "value": "BTM full fare" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"validFrom": "2000-01-01T01:00:00+01:00", "validUntil": "2100-01-01T00:59:59+01:00", "weight": 23, "appliedMetric": "FARE", "appliedValue": 23, "category": "INTERNAL", "typesOfFareProduct": [ {
|
||||||
|
"privateCode": "payg" }
|
||||||
|
],
|
||||||
|
"xspit": "7618337f-c986-4bef-990d-f5a6b47292b8", "xpit": "f4256df6-b767-460f-9880-f7597bd7f3f2" },
|
||||||
|
{
|
||||||
|
"productTemplateId": "3:30901", "productCommercialName": { "items": [ {
|
||||||
|
"key": "nl-NL", "value": "HTM 90% Korting" },
|
||||||
|
{
|
||||||
|
"key": "en-US", "value": "HTM 90% Discount" },
|
||||||
|
{
|
||||||
|
"key": "nl-NL", "value": "Reis je regelmatig met HTM? Activeer dan HTM 90% Korting op je betaalpas of credit card en reis een week lang met korting!" },
|
||||||
|
{
|
||||||
|
"key": "en-US", "value": "Are you a regular traveler? Activate HTM 90% discount on your EMV card!" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"validFrom": "2026-04-03T04:00:00+02:00", "validUntil": "2031-04-03T04:00:00+02:00", "organisationName": "Product Owner HTM", "weight": -125, "appliedMetric": "DISCOUNT", "appliedValue": -125, "organisationId": "3", "category": "INTERNAL", "typesOfFareProduct": [ {
|
||||||
|
"privateCode": "discount" }
|
||||||
|
],
|
||||||
|
"productCatalogVersionId": "PC-HTM:70", "xspit": "821ddb0d-4ea7-4a0d-84aa-bb7facce15d1", "xpit": "1848597c-5ba9-4dab-8d9f-3948948706a1" }
|
||||||
|
],
|
||||||
|
"checkinTransactionTimestamp": "2026-04-20T16:59:48+02:00", "checkoutTransactionTimestamp": "2026-04-20T17:04:50+02:00", "checkinTransactionReference": "00310F92;29023;emvClt", "checkoutTransactionReference": "0030DBC1;30528;emvClt", "checkinLocation": { "stopId": 2721, "stopName": { "items": [ {
|
||||||
|
"key": "nl-NL", "value": "Station Hollands Spoor" },
|
||||||
|
{
|
||||||
|
"key": "en-US", "value": "Station Hollands Spoor" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"stopDesc": "Stop point2721", "stopUrl": "/icons/stops/stop.svg", "locationType": 0 },
|
||||||
|
"checkoutLocation": { "stopId": 2862, "stopName": { "items": [ {
|
||||||
|
"key": "nl-NL", "value": "Kalvermarkt-Stadhuis" },
|
||||||
|
{
|
||||||
|
"key": "en-US", "value": "Kalvermarkt-Stadhuis" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"stopDesc": "Stop point2862", "stopUrl": "/icons/stops/stop.svg", "locationType": 0 },
|
||||||
|
"tokenType": "EMV-CLT", "transportType": "TRAM", "lineId": "17", "lineName": "Tram17", "networkId": "1", "networkName": "HTM netwerk", "currency": "EUR", "transportIcon": "/icons/transportTypes/tram.svg", "legs": [ {
|
||||||
|
"legId": 1614950977, "checkinTransactionTimestamp": "2026-04-20T16:59:48+02:00", "checkoutTransactionTimestamp": "2026-04-20T17:04:50+02:00", "checkinLocation": { "stopId": 2721, "stopName": { "items": [ {
|
||||||
|
"key": "nl-NL", "value": "Station Hollands Spoor" },
|
||||||
|
{
|
||||||
|
"key": "en-US", "value": "Station Hollands Spoor" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"stopDesc": "Stop point2721", "stopUrl": "/icons/stops/stop.svg", "locationType": 0 },
|
||||||
|
"checkoutLocation": { "stopId": 2862, "stopName": { "items": [ {
|
||||||
|
"key": "nl-NL", "value": "Kalvermarkt-Stadhuis" },
|
||||||
|
{
|
||||||
|
"key": "en-US", "value": "Kalvermarkt-Stadhuis" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"stopDesc": "Stop point2862", "stopUrl": "/icons/stops/stop.svg", "locationType": 0 },
|
||||||
|
"baseRate": 139, "lineId": "17", "lineName": "Tram17", "networkId": "1", "networkName": "HTM netwerk", "fare": 14, "fareState": "CALCULATED", "currency": "EUR", "products": [ {
|
||||||
|
"productTemplateId": "30901", "productCommercialName": { "items": [ {
|
||||||
|
"key": "nl-NL", "value": "HTM 90% Korting" },
|
||||||
|
{
|
||||||
|
"key": "en-US", "value": "HTM 90% Discount" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"productIcon": "001.jpg", "purchaseDateTime": "2026-04-02T12:38:28+02:00", "organisationName": "ProductRetailer HTM", "appliedValue": -125, "organisationId": "3", "category": "SALES", "typesOfFareProduct": [ {
|
||||||
|
"privateCode": "discount" }
|
||||||
|
],
|
||||||
|
"xspit": "821ddb0d-4ea7-4a0d-84aa-bb7facce15d1" },
|
||||||
|
{
|
||||||
|
"productTemplateId": "N/A", "purchaseDateTime": "2025-07-09T12:39:27+02:00", "appliedValue": 139, "category": "SALES", "typesOfFareProduct": [ {
|
||||||
|
"privateCode": "payg" }
|
||||||
|
],
|
||||||
|
"xspit": "7618337f-c986-4bef-990d-f5a6b47292b8" },
|
||||||
|
{
|
||||||
|
"productTemplateId": "1:2000", "productCommercialName": { "items": [ {
|
||||||
|
"key": "nl-NL", "value": "Basis Bus Tram Metro" },
|
||||||
|
{
|
||||||
|
"key": "en-US", "value": "BTM full fare" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"validFrom": "2000-01-01T01:00:00+01:00", "validUntil": "2100-01-01T00:59:59+01:00", "weight": 116, "appliedMetric": "FARE", "appliedValue": 116, "category": "INTERNAL", "typesOfFareProduct": [ {
|
||||||
|
"privateCode": "payg" }
|
||||||
|
],
|
||||||
|
"xspit": "7618337f-c986-4bef-990d-f5a6b47292b8", "xpit": "f4256df6-b767-460f-9880-f7597bd7f3f2" },
|
||||||
|
{
|
||||||
|
"productTemplateId": "2:2000", "productCommercialName": { "items": [ {
|
||||||
|
"key": "nl-NL", "value": "Basis Bus Tram Metro" },
|
||||||
|
{
|
||||||
|
"key": "en-US", "value": "BTM full fare" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"validFrom": "2000-01-01T01:00:00+01:00", "validUntil": "2100-01-01T00:59:59+01:00", "weight": 23, "appliedMetric": "FARE", "appliedValue": 23, "category": "INTERNAL", "typesOfFareProduct": [ {
|
||||||
|
"privateCode": "payg" }
|
||||||
|
],
|
||||||
|
"xspit": "7618337f-c986-4bef-990d-f5a6b47292b8", "xpit": "f4256df6-b767-460f-9880-f7597bd7f3f2" },
|
||||||
|
{
|
||||||
|
"productTemplateId": "3:30901", "productCommercialName": { "items": [ {
|
||||||
|
"key": "nl-NL", "value": "HTM 90% Korting" },
|
||||||
|
{
|
||||||
|
"key": "en-US", "value": "HTM 90% Discount" },
|
||||||
|
{
|
||||||
|
"key": "nl-NL", "value": "Reis je regelmatig met HTM? Activeer dan HTM 90% Korting op je betaalpas of credit card en reis een week lang met korting!" },
|
||||||
|
{
|
||||||
|
"key": "en-US", "value": "Are you a regular traveler? Activate HTM 90% discount on your EMV card!" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"validFrom": "2026-04-03T04:00:00+02:00", "validUntil": "2031-04-03T04:00:00+02:00", "organisationName": "Product Owner HTM", "weight": -125, "appliedMetric": "DISCOUNT", "appliedValue": -125, "organisationId": "3", "category": "INTERNAL", "typesOfFareProduct": [ {
|
||||||
|
"privateCode": "discount" }
|
||||||
|
],
|
||||||
|
"discountPercentage": 90, "productCatalogVersionId": "PC-HTM:70", "xspit": "821ddb0d-4ea7-4a0d-84aa-bb7facce15d1", "xpit": "1848597c-5ba9-4dab-8d9f-3948948706a1" }
|
||||||
|
],
|
||||||
|
"appliedTimePeriods": [], "tariffJourneyStart": true, "topoDistance": 1161, "concessionId": "1", "appliedZones": [] }
|
||||||
|
],
|
||||||
|
"lastUpdatedTripDateTime": "2026-04-20T17:04:50+02:00", "fare": 14, "loyaltyOrDiscount": true, "supportCode": "pWM8Km6J8aHg5n", "tripVersionReason": "STRUCTURE", "checkinTransactionId": "00310F92-29023-emvClt-1776697188000", "checkoutTransactionId": "0030DBC1-30528-emvClt-1776697490000", "tariffVersionId": "HTM-CF1:278", "correlationId": "4bc7a040-71bf-4084-a61e-b2dd72092079", "createdAt": "2026-04-20T17:05:01.473+02:00", "entryTariffLocation": { "stopId": 2721, "stopName": { "items": [ {
|
||||||
|
"key": "nl-NL", "value": "Station Hollands Spoor" },
|
||||||
|
{
|
||||||
|
"key": "en-US", "value": "Station Hollands Spoor" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"stopDesc": "Stop point2721", "stopUrl": "/icons/stops/stop.svg", "locationType": 0 },
|
||||||
|
"traveledLines": [ {
|
||||||
|
"lineId": "17", "lineName": "Tram17" }
|
||||||
|
],
|
||||||
|
"tripFareNature": "FIXED", "paymentMethodId": "229a01ff-7bd9-4740-9b19-00637146a6ca", "paymentMethodMode": "PREPAID", "paymentMethodName": "EPURSE", "paymentProviderName": "TPURSE", "paymentProviderBusinessEntityId": "600027", "registryFragmentVersionId": "REG:27", "vehicleId": 5063, "xbot": "c85e34d6-f9c1-49c2-8574-59b37e0f3b8e" }
|
||||||
|
|
||||||
Loading…
Reference in New Issue
Block a user