Compare commits

...

10 Commits

Author SHA1 Message Date
e5a0b52d1b Merge pull request 'Updated OpenAPI spec for voucher supplier, with examples more relevant to the first usecase (ooievaarspas AOW) - this YAML is also shared with PASS devs' (#60) from feature/OVPAY-2545-vouchers into develop
Reviewed-on: #60
2026-06-08 08:45:46 +00:00
89833680db Merge branch 'develop' into feature/OVPAY-2545-vouchers 2026-06-08 08:44:17 +00:00
Max Martens
ff225ea00c Merge branch 'feature/OVPAY-2545-vouchers' of https://git.integratielaag.nl/HTM/ovpay into feature/OVPAY-2545-vouchers 2026-06-03 19:06:25 +02:00
Max Martens
bd870d0fa8 Added JSON schema and updated examples and error specs for supplier - tweaked OAS for TP 2026-06-03 19:06:17 +02:00
531eaa2ff6 Update src/openapi/products/SE-vouchers-TP.yaml
Fix some typos

Signed-off-by: Max Martens <m.martens@htm.nl>
2026-06-02 15:21:03 +00:00
Max Martens
7173bd3727 Finished JSON schema and all 3 relevant examples for TP vouchers OpenAPI spec (will also update vouchers supplier OpenAPI spec soon) 2026-06-01 11:17:22 +02:00
Max Martens
a09ad1ad08 Process PR feedback, first version of issuedVoucher JSON schema 2026-06-01 10:40:28 +02:00
Max Martens
f8010560cc Tweak query param 2026-05-07 09:52:29 +02:00
Max Martens
69908f58b0 Finished updating, will be shared with pass devs in this state - I tweaked some stuff, needs to be discussed if this is final desired spec, but good enough to give pass devs a general idea 2026-05-06 22:44:55 +02:00
Max Martens
9fb20a491f WIP update spec with examples for Ooievaarspas-AOW (still need to finish POST/PATCH) 2026-05-06 08:28:21 +02:00
2 changed files with 1032 additions and 271 deletions

View File

@ -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