Compare commits

..

106 Commits

Author SHA1 Message Date
c45f2059f4 OVPAY-2473 - Fixed HATEOAS in example. 2026-03-16 16:11:12 +01:00
53185d10b1 Merge pull request 'feature/OVPAY-2473' (#55) from feature/OVPAY-2473 into develop
Reviewed-on: #55
2026-03-16 13:56:18 +00:00
f237f677e3 OVPAY-2473 - Improved examples part 2. 2026-03-16 14:45:05 +01:00
9bb7320299 OVPAY-2473 - Improved examples. 2026-03-16 14:35:59 +01:00
1bf9fa2fd0 OVPAY-2473 - Improved URIs. 2026-03-16 13:34:42 +01:00
903adbe238 OVPAY-2473 - Added HATEOAS for trip correction in trips list. 2026-03-16 13:23:15 +01:00
b6586891fc OVPAY-2473 - Fixed semantic errors. 2026-03-16 13:08:02 +01:00
8b148b22ac OVPAY-2387 - Updated examples for GET /notificationcategories. 2026-03-11 15:44:16 +01:00
44dae159b8 OVPAY-2473 - Added HATEOAS for trip correction. 2026-03-05 13:10:48 +01:00
a7e32f6122 OVPAY-2473 - Added examples for GET trip details. 2026-03-05 12:37:04 +01:00
513045c146 OVPAY-2473 - Added endpoint for POSTing missing tap. 2026-03-05 12:19:24 +01:00
8c4542a151 OVPAY-2473 - Added endpoint for getting stops. 2026-03-05 12:11:35 +01:00
0749e927dc OVPAY-2473 - Added existing trip endpoints. 2026-03-05 10:09:44 +01:00
2b02e52c22 OVPAY-2294 - Removed bulk endpoints. 2026-03-04 15:32:25 +01:00
2cb6f910df Merge pull request 'OVPAY-2201 - Added endpoints for contract changes.' (#54) from feature/OVPAY-2201 into develop
Reviewed-on: #54
2026-03-04 09:44:38 +00:00
1269f8916f Merge pull request 'feature/OVPAY-2442' (#53) from feature/OVPAY-2442 into develop
Reviewed-on: #53
2026-03-04 09:39:44 +00:00
c3af1e9adf OVPAY-2201 - ChangeMoments signle entity. 2026-03-02 10:04:54 +01:00
5d307d9808 OVPAY-2442 - Changed all bulk endpoints to single inserts and patches (yarr). 2026-02-23 17:03:24 +01:00
105e81b5c4 OVPAY-2201 - Added endpoints for contract changes. 2026-02-23 14:42:07 +01:00
24b4832c69 fixed examples post payment 2026-02-19 12:07:29 +01:00
03372074d9 removed incorrect deviceId 2026-02-19 11:59:18 +01:00
bf0ebee435 added claim value to supplier voucher GET and added seperate swagger for voucher check sales TP 2026-02-16 13:38:45 +01:00
541b0662f1 OVPAY-2442 - Improved descriptions. 2026-02-13 14:49:44 +01:00
594475331f OVPAY-2442 - Added touchpointId query param. 2026-02-13 14:47:12 +01:00
42c49693f1 OVPAY-2442 - Added PATCH /issuedvouchers. 2026-02-13 14:30:32 +01:00
62f001c902 OVPAY-2442 - Added POST /issuedvouchers. 2026-02-13 14:17:17 +01:00
a71aa2e4df OVPAY-2442 - Nested product entity for GET /voucherdefinitions. 2026-02-13 12:42:30 +01:00
5e2b646a30 OVPAY-2442 - Added query params. Updated examples. 2026-02-11 16:31:08 +01:00
7ab0de07c4 OVPAY-2442 - Created endpoints for GET /voucherdefinitions and /issuedvouchers. 2026-02-11 12:01:45 +01:00
Max Martens
39e5042350 Added feature: bulk clearing (set to null) of a given product attribute for all products in a given product tree - actually applies the modified products via PUT API 2026-02-05 17:42:17 +01:00
2d742ca3f1 OVPAY-973 - Added query param deviceId for GET and PUT notificationpreferences. 2026-02-05 13:13:15 +01:00
97c58dc3fe Merge pull request 'features/OVPAY2313-V2-swaggers-infoplaza' (#52) from features/OVPAY2313-V2-swaggers-infoplaza into develop
Reviewed-on: #52
2026-02-05 10:01:01 +00:00
d06da1401e fixed ovpasNumber mistake 2026-02-05 10:54:13 +01:00
04d46e0891 Merge branch 'develop' of https://git.integratielaag.nl/HTM/ovpay into features/OVPAY2313-V2-swaggers-infoplaza 2026-02-05 10:32:25 +01:00
c31554a526 Merge pull request 'features/customers-v2-SE' (#51) from features/customers-v2-SE into develop
Reviewed-on: #51
2026-02-05 09:31:49 +00:00
9d9039d732 products and fixed productCategory Id 2026-02-04 10:33:38 +01:00
93efb6b8f7 Merge branch 'develop' of https://git.integratielaag.nl/HTM/ovpay into features/OVPAY2313-V2-swaggers-infoplaza 2026-02-04 09:57:24 +01:00
77953a726a OVPAY-973 - Fixed TP endpoints. Updated response and request body. 2026-01-30 16:00:20 +01:00
Max Martens
bbf21e61f7 Fixed all addressTypes 2026-01-29 14:09:08 +01:00
681e9f7671 fixed casing mismatch ovpaytokenid and tokens transfer reponsestatus path 2026-01-28 13:56:05 +01:00
c9b54a095d restored crud file 2026-01-28 13:50:36 +01:00
e3139fdd6d Merge pull request 'OVPAY-2346 - Implemented /issuedvouchers/{code}.' (#48) from feature/OVPAY-2346 into develop
Reviewed-on: #48
2026-01-28 09:33:47 +00:00
4b932a0628 lowercase paths 2026-01-28 10:03:21 +01:00
43bf7bfff3 lowercase paths 2026-01-28 10:02:56 +01:00
007cf4bdef added customerprofileId to device response 2026-01-28 09:55:23 +01:00
baee1e8622 misplaced customerprofileId 2026-01-28 09:53:01 +01:00
ba314674a3 misplaced customerprofileId 2026-01-28 09:48:20 +01:00
1f51eaadc6 something 2026-01-28 09:47:21 +01:00
5838b14ac5 added GET on devices 2026-01-28 09:44:32 +01:00
14817cc621 fixed security semenantic error 2026-01-27 17:10:08 +01:00
c1fbc0dc90 touchpoint V2 endpoints customer total 2026-01-27 16:34:51 +01:00
9b8cf65525 changes 2026-01-27 15:34:35 +01:00
8f907896be Merge branch 'develop' of https://git.integratielaag.nl/HTM/ovpay into develop 2026-01-27 10:42:32 +01:00
591347e080 OVPAY-973 - Added ovPayTokenId example to POST. 2026-01-27 10:42:21 +01:00
da7afd63fc Merge pull request 'feature/OVPAY-973' (#50) from feature/OVPAY-973 into develop
Reviewed-on: #50
2026-01-27 09:37:03 +00:00
2c88fac238 added voucher example product instance 2026-01-26 13:09:44 +01:00
6a24636d50 OVPAY-973 - Added ovPayTokenId to POST /notificationsubscriptions. 2026-01-23 17:08:12 +01:00
c7fa48b554 OVPAY-2394 - Fixed schema for patch NotificationSubscription. 2026-01-22 09:28:27 +01:00
5133903efb OVPAY-2394 - Added example for no notificationCategories found. 2026-01-21 11:03:45 +01:00
447912e081 OVPAY-973 - Added alias to request and response bodies. 2026-01-19 15:08:42 +01:00
e2d78ec969 created generic endpoint for product Instances 2026-01-19 14:51:38 +01:00
c6facc5a70 OVPAY-973 - Added GET/PUT /customers/notificationpreferences. 2026-01-19 14:31:01 +01:00
cf0d24632f Merge pull request 'feature/OVPAY-2394' (#49) from feature/OVPAY-2394 into develop
Reviewed-on: #49
2026-01-14 12:06:39 +00:00
aa4721c651 OVPAY-2394 - Processed review remarks. 2026-01-14 13:05:32 +01:00
46bf7874d9 OVPAY-2394 - Added POST, PATCH and DELETE operations for NotificationPreferences. 2026-01-13 16:08:39 +01:00
1a14918f4a OVPAY-2394 - Added PATCH /notificationsubscriptions/{uuid}. 2026-01-13 15:45:52 +01:00
7147318900 OVPAY-2394 - Added resourceNameId to Channel. 2026-01-13 15:38:48 +01:00
e0f78d2e38 OVPAY-2394 - Updated GET /notificationsubscriptions examples. 2026-01-13 15:19:49 +01:00
ab57e27c1d OVPAY-2394 - Added OriginSubscription. 2026-01-12 15:08:32 +01:00
68c7ccc279 OVPAY-2394 - Added groupName to NotificationCategory. Added query params. 2026-01-12 13:41:20 +01:00
80c9fe7599 OVPAY-2346 - Processed review remarks. 2026-01-05 14:04:40 +01:00
8946026860 Added fromInclusive and untilInclusive. 2026-01-05 13:34:12 +01:00
e6b2146706 OVPAY-2346 - Implemented /issuedvouchers/{code}. 2025-12-30 14:57:43 +01:00
fb8723124a Merge pull request 'OVPAY-2378 - Updated spec for /contractpayments.' (#46) from feature/OVPAY-2378 into develop
Reviewed-on: #46
Reviewed-by: Max Martens <m.martens@htm.nl>
2025-12-29 12:31:57 +00:00
6d7c260e9e OVPAY-2378 - PaymentMethod in NL. 2025-12-29 12:32:59 +01:00
292588b7ba OVPAY-2378 - Updated spec for /contractpayments. 2025-12-29 12:01:12 +01:00
4bd216bd37 Merge pull request 'features/OVPAY2294-vouchers-in-orders' (#45) from features/OVPAY2294-vouchers-in-orders into develop
Reviewed-on: #45
Reviewed-by: Bas Boterman <b.boterman@htm.nl>
2025-12-16 13:57:40 +00:00
bfaa1ddcb1 fixed comments 2025-12-16 14:52:23 +01:00
55bac27561 simplified order_orderVoucherId 2025-12-15 15:36:51 +01:00
Max Martens
715a9668fc Clear up name and description of token transfer V2 endpoints 2025-12-15 14:27:48 +01:00
b4f20a9758 moved changes to TP orders to another branch and made equal to develop in this branch 2025-12-15 11:50:39 +01:00
22cb3ddd92 added query param deviceId 2025-12-15 11:43:03 +01:00
1f3e2289dc finished CRUD endpoints 2025-12-15 11:40:42 +01:00
3ff55e5888 Merge branch 'develop' of https://git.integratielaag.nl/HTM/ovpay into features/OVPAY2294-vouchers-in-orders 2025-12-15 10:44:01 +01:00
987f64a081 dubbele alias 2025-12-15 10:40:40 +01:00
00448486f3 added ovpasnumber to get token response 2025-12-15 10:39:33 +01:00
ed61633579 Merge pull request 'TapConnect V5 ticket events export schema reverse-engineered from real data' (#43) from feature/OVPAY-2345-TapConnect-Elastic into develop
Reviewed-on: #43
2025-12-15 09:01:20 +00:00
d34ba20d19 Merge branch 'develop' of https://git.integratielaag.nl/HTM/ovpay into features/OVPAY2294-vouchers-in-orders 2025-12-12 11:09:30 +01:00
3e1f23afe3 Merge pull request 'features/Edit-TP-notification' (#44) from features/Edit-TP-notification into develop
Reviewed-on: #44
2025-12-11 13:51:28 +00:00
Max Martens
6260cc5d63 Now supports handling events for TRIPS as well as ALERTS. Need to manually add xBOTs to queue using API 9853 2025-12-10 16:49:15 +01:00
d9157d04ef removed account or private from desc patch 2025-12-10 12:40:48 +01:00
f57f17e645 removed email from notification patch 2025-12-10 12:37:12 +01:00
3ae52206fc OVPAY-2370 - Status codes async jobs. 2025-12-10 12:26:09 +01:00
a52dfcab93 OVPAY-1946 - Fixed typo. 2025-12-09 16:57:10 +01:00
80b0de274e OVPAY-1946 - Updated examples. 2025-12-09 16:52:42 +01:00
38cfec81c8 removed is active from post body 2025-12-08 14:35:33 +01:00
Max Martens
3ffc525d48 Fix number typo 2025-12-08 13:30:22 +01:00
Max Martens
105a18c0ac TapConnect V5 ticket events export schema reverse-engineered from real data 2025-12-08 12:06:10 +01:00
7732ae13a6 Merge pull request 'added bulk endpoints to purchased product CRUD' (#42) from features/OVPAY2294-vouchers into develop
Reviewed-on: #42
2025-12-08 09:35:27 +00:00
4084a574c9 fixed the semantic error 2025-12-08 10:32:35 +01:00
3ebdf0090f added bulk status endpoints 2025-12-05 12:00:36 +01:00
b898288632 added bulk post to purchased product CRUD 2025-12-05 09:58:03 +01:00
dce4d5ea17 Update src/openapi/customers/SE-notifications.yaml
Fixed error in query param type.
2025-12-04 11:15:46 +00:00
e4b3ab4ccf added post voucher in SE orders 2025-12-01 16:54:10 +01:00
01aa8a9f1a Added get vouchers and voucher in response body's 2025-12-01 14:48:17 +01:00
bb917c3635 updated CRUD order swaggers for vouchers 2025-12-01 13:35:41 +01:00
24 changed files with 11842 additions and 693 deletions

View File

@ -8,7 +8,7 @@
</list> </list>
</option> </option>
</component> </component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="temurin-21" project-jdk-type="JavaSDK"> <component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="17" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" /> <output url="file://$PROJECT_DIR$/out" />
</component> </component>
</project> </project>

View File

@ -1,7 +1,9 @@
# ABTProducts PUT request body generator # ABTProducts PUT request body generator
Simple tool to quickly edit HTM products via ABTProducts REST API. Simple tool to quickly edit HTM products via ABTProducts REST API.
- Requires JRE 21 - Requires JRE 17
## Generating a PUT output (that you need to supply to PUT API yourself):
- Run via: `java -jar ABTProductsPUTGenerator.jar` - Run via: `java -jar ABTProductsPUTGenerator.jar`
- Specify custom input/output path via: `java -jar ABTProductsPUTGenerator.jar <inputPath> <outputPath>` - Specify custom input/output path via: `java -jar ABTProductsPUTGenerator.jar <inputPath> <outputPath>`
- Takes a ABTProducts GET response body in JSON format (product details) - Takes a ABTProducts GET response body in JSON format (product details)
@ -10,3 +12,14 @@ Simple tool to quickly edit HTM products via ABTProducts REST API.
- `curl -X PUT -H 'Content-Type: application/json' {baseUrl}/abt/abtproducts/1.0/38 --data @output.json` - `curl -X PUT -H 'Content-Type: application/json' {baseUrl}/abt/abtproducts/1.0/38 --data @output.json`
- Default input path: /input.json - Default input path: /input.json
- Default output path: /output.json (output is overwritten if it exists) - Default output path: /output.json (output is overwritten if it exists)
## Bulk clearing (set to null) of a certain product attribute for all productIds in a product-tree (SE product reponse)
- Run via: `java -jar ABTProductsPUTGenerator.jar clearAttribute <inputPath> <attributeToClear> <environment> <wso2BearerToken>`
- Takes a SE GET product tree response body or ABTProducts GET response body in JSON format
- Also needs the attribute to clear and the WSO2 environment and valid WSO2 bearer token for that environment
- Performs the following operations:
- Finds all productId's in the given product(tree) and for each productId found:
- GETs productdetails via ABTProducts API
- Converts it to PUT request body using the functionality in the previous section
- Replaces <attributeToClear> with `null`
- Actually sends the modified PUT request body to ABTProducts PUT API

View File

@ -58,8 +58,8 @@
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId> <artifactId>maven-compiler-plugin</artifactId>
<configuration> <configuration>
<source>21</source> <source>17</source>
<target>21</target> <target>17</target>
</configuration> </configuration>
</plugin> </plugin>
</plugins> </plugins>

View File

@ -3,8 +3,11 @@ package nl.htm.ovpay.abt;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Scanner;
import java.util.stream.Collectors;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -19,6 +22,15 @@ public class ABTProductsPUTGenerator {
private static final Logger LOGGER = LoggerFactory.getLogger(ABTProductsPUTGenerator.class); private static final Logger LOGGER = LoggerFactory.getLogger(ABTProductsPUTGenerator.class);
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
LOGGER.info("Starting ABTProductsPUTGenerator with arguments {}", Arrays.stream(args).toList());
if (args.length > 0 && args[0].equalsIgnoreCase("clearAttribute")) {
clearAttribute(args);
} else {
generateOutput(args);
}
}
private static void generateOutput(String[] args) throws Exception {
if (args.length != 2) { if (args.length != 2) {
LOGGER.info("To modify input/output path, use: java -jar ABTProductsPUTGenerator.jar <inputPath> <outputPath>"); LOGGER.info("To modify input/output path, use: java -jar ABTProductsPUTGenerator.jar <inputPath> <outputPath>");
} }
@ -40,6 +52,49 @@ public class ABTProductsPUTGenerator {
} }
} }
private static void clearAttribute(String[] args) throws Exception {
if (args.length != 5) {
LOGGER.error("Incorrect input parameters!");
LOGGER.error("To clear attribute, use: java -jar ABTProductsPUTGenerator.jar clearAttribute <inputPath> <attributeToClear> <environment> <wso2BearerToken>");
return;
}
var inputFile = args[1];
var attributeToClear = args[2];
var environment = args[3];
var wso2BearerToken = args[4];
try (InputStream is = getInputStream(inputFile)) {
ObjectMapper mapper = new ObjectMapper();
JsonNode jsonNode = mapper.readTree(is);
var productIds = jsonNode.findValues("productId").stream().filter(JsonNode::isValueNode).map(JsonNode::asText).toList();
LOGGER.info("Found productIds to process: {}", productIds);
LOGGER.warn("Are you SURE you want to set attribute \"{}\" for all these productIds on environment {} to NULL?", attributeToClear, environment);
LOGGER.warn("Type 'yes' to continue...");
var input = new Scanner(System.in).nextLine();
if (!input.equalsIgnoreCase("yes")) {
LOGGER.info("Aborting...");
return;
}
for (var productId : productIds) {
LOGGER.info("Getting product details for product {}...", productId);
var productJsonString = APIHelper.getProductDetails(environment, productId, wso2BearerToken);
var productJsonNode = mapper.readTree(productJsonString);
var putJsonNode = processJsonNode(productJsonNode);
LOGGER.info("Clearing attribute \"{}\" from product with productId {}...", attributeToClear, productId);
((ObjectNode)putJsonNode).putRawValue(attributeToClear, null);
LOGGER.info("PUT product details for product with productId {} with cleared attribute \"{}\"...", productId, attributeToClear);
LOGGER.info("PUT product details with JSON body: {}", putJsonNode.toPrettyString());
APIHelper.putProductDetails(environment, productId, putJsonNode.toString(), wso2BearerToken);
}
LOGGER.info("DONE clearing attribute \"{}\" for productIds {}!", attributeToClear, productIds);
}
}
private static InputStream getInputStream(String filePath) throws IOException { private static InputStream getInputStream(String filePath) throws IOException {
var externalResource = new File(filePath); var externalResource = new File(filePath);
if (externalResource.exists()) { if (externalResource.exists()) {

View File

@ -0,0 +1,89 @@
package nl.htm.ovpay.abt;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
import java.util.StringJoiner;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class APIHelper {
private static final Logger LOGGER = LoggerFactory.getLogger(APIHelper.class);
private static final String PRODUCT_DETAILS_URI = "https://services.<ENV>.api.htm.nl/abt/abtproducts/1.0/products/<PRODUCTID>";
public static String envToUriPart(String environment) {
return switch (environment) {
case "DEV" -> "dev";
case "ACC" -> "acc";
case "PRD" -> "";
default -> throw new IllegalArgumentException("Invalid environment: " + environment);
};
}
public static String getProductDetails(String environment, String productId, String wso2BearerToken) throws Exception {
var envUriPart = envToUriPart(environment);
var getProductDetailsUri = PRODUCT_DETAILS_URI.replace("<ENV>", envUriPart).replace("<PRODUCTID>", productId);
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, DummyX509TrustManager.getDummyArray(), new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
URL url = new URL(getProductDetailsUri);
URLConnection con = url.openConnection();
HttpURLConnection http = (HttpURLConnection)con;
http.setRequestMethod("GET");
http.setDoOutput(false);
http.setRequestProperty("Authorization", "Bearer " + wso2BearerToken);
http.connect();
try(InputStream is = http.getInputStream()) {
return new String(is.readAllBytes(), StandardCharsets.UTF_8);
}
}
public static void putProductDetails(String environment, String productId, String jsonBody, String wso2BearerToken) throws Exception {
var envUriPart = envToUriPart(environment);
var putProductDetailsUri = PRODUCT_DETAILS_URI.replace("<ENV>", envUriPart).replace("<PRODUCTID>", productId);
LOGGER.info("PUT product details to URI: {}", putProductDetailsUri);
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, DummyX509TrustManager.getDummyArray(), new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
URL url = new URL(putProductDetailsUri);
URLConnection con = url.openConnection();
HttpURLConnection http = (HttpURLConnection)con;
http.setRequestMethod("PUT");
http.setDoOutput(true);
http.setRequestProperty("Authorization", "Bearer " + wso2BearerToken);
http.setRequestProperty("Content-Type", "application/json");
byte[] out = jsonBody.getBytes(StandardCharsets.UTF_8);
int length = out.length;
http.setFixedLengthStreamingMode(length);
http.connect();
try(OutputStream os = http.getOutputStream()) {
os.write(out);
}
try(InputStream is = http.getInputStream()) {
LOGGER.info("Got response from PUT API: {}", new String(is.readAllBytes(), StandardCharsets.UTF_8));
}
}
}

View File

@ -0,0 +1,38 @@
package nl.htm.ovpay.abt;
import java.security.cert.X509Certificate;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
public final class DummyX509TrustManager implements X509TrustManager {
private static DummyX509TrustManager INSTANCE;
private DummyX509TrustManager() {
// prevent instantiation
}
public static DummyX509TrustManager getInstance() {
if (INSTANCE == null) {
INSTANCE = new DummyX509TrustManager();
}
return INSTANCE;
}
public static TrustManager[] getDummyArray() {
if (INSTANCE == null) {
INSTANCE = new DummyX509TrustManager();
}
return new TrustManager[] { INSTANCE };
}
public X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(X509Certificate[] certs, String authType) {
}
}

View File

@ -1,23 +1,33 @@
{ {
"productId": 251, "productId": 663,
"fikoArticleNumber": null,
"parentProductId": null, "parentProductId": null,
"gboPackageTemplateId": "30901", "layerInfo": {
"layerInfoId": 7,
"choiceKey": "isRenewable",
"choiceLabel": "Kies voor een doorlopend abonnement of een enkele termijn",
"isCustomChoice": false
},
"fikoArticleNumber": null,
"gboPackageTemplateId": "30001",
"tapConnectProductCode": null, "tapConnectProductCode": null,
"productName": "MaxTestPOST-21-okt-test-1 edited PUT", "productName": "Test OVPAY-2306",
"productDescription": "21-okt-test-1 edited PUT - reis met 90% korting gedurende de eerste F&F pilot!", "productDescription": "Test OVPAY-2306 (sellingPeriods in kindje verwijderen en later opnieuw weer kunnen toevoegen)",
"validityPeriod": null, "validityPeriod": {
"productTranslations": null, "validityPeriodId": 782,
"fromInclusive": "2025-12-31T23:00:00.000Z",
"toInclusive": "2026-03-30T22:00:00.000Z"
},
"productTranslations": [],
"allowedGboAgeProfiles": [],
"productOwner": { "productOwner": {
"productOwnerId": 1, "productOwnerId": 1,
"name": "Corneel Verstoep", "name": "Wie dit leest",
"organization": "HTM" "organization": "... is een aap."
}, },
"marketSegments": null, "marketSegments": [],
"customerSegments": null, "customerSegments": [],
"allowedGboAgeProfiles": null,
"productCategory": { "productCategory": {
"productCategoryId": 9, "productCategoryId": 1,
"isTravelProduct": true, "isTravelProduct": true,
"name": "Kortingsabonnement" "name": "Kortingsabonnement"
}, },
@ -25,32 +35,10 @@
"requiredCustomerLevelId": 1, "requiredCustomerLevelId": 1,
"name": "guest" "name": "guest"
}, },
"requiredProducts": null, "requiredProducts": [],
"incompatibleProducts": null, "incompatibleProducts": [],
"mandatoryCustomerDataItems": [ "mandatoryCustomerDataItems": [],
{ "requiredGboPersonalAttributes": [],
"mandatoryCustomerDataItemId": 4,
"customerDataItem": "emailAddress"
},
{
"mandatoryCustomerDataItemId": 5,
"customerDataItem": "address"
}
],
"requiredGboPersonalAttributes": [
{
"requiredGboPersonalAttributeId": 1,
"name": "NAME"
},
{
"requiredGboPersonalAttributeId": 2,
"name": "BIRTHDATE"
},
{
"requiredGboPersonalAttributeId": 3,
"name": "PHOTO"
}
],
"tokenTypes": [ "tokenTypes": [
{ {
"tokenTypeId": 1, "tokenTypeId": 1,
@ -61,72 +49,36 @@
"paymentMomentId": 1, "paymentMomentId": 1,
"name": "prepaid" "name": "prepaid"
}, },
"serviceOptions": null, "serviceOptions": [
"validityDuration": "P7D", {
"maxStartInFutureDuration": "P6W", "serviceOptionId": 4,
"isRenewable": false, "action": "cancel_notAllowed",
"description": "Stopzetting is niet toegestaan (doorgaans in combinatie met refund_notAllowed)"
},
{
"serviceOptionId": 10,
"action": "refund_notAllowed",
"description": "Terugbetaling niet toegestaan (doorgaans in combinatie met cancel_notAllowed)"
}
],
"validityDuration": "P1W",
"maxStartInFutureDuration": "P1W",
"isRenewable": null,
"sendInvoice": false, "sendInvoice": false,
"imageReference": "https://www.htm.nl/media/leif2leu/htm-logo-mobile.svg", "imageReference": null,
"productPageUrl": "https://www.htm.nl/nog-onbekende-product-pagina", "productPageUrl": null,
"termsUrl": "https://www.htm.nl/nog-onbekende-productvoorwaarden-pagina", "termsUrl": null,
"isSellableAtHtm": true, "isSellableAtHtm": true,
"needsSolvencyCheckConsumer": false, "needsSolvencyCheckConsumer": false,
"needsSolvencyCheckBusiness": false, "needsSolvencyCheckBusiness": false,
"sellingPeriods": [ "sellingPeriods": [
{ {
"sellingPeriodId": 240, "sellingPeriodId": 1382,
"fromInclusive": "2024-09-06T00:00:00.000+00:00", "fromInclusive": "2025-12-31T23:00:00.000Z",
"toInclusive": "2024-12-29T23:59:59.000+00:00", "toInclusive": "2026-03-30T22:00:00.000Z",
"salesTouchpoint": { "salesTouchpoint": {
"salesTouchpointId": 6, "salesTouchpointId": 3,
"name": "Service-engine", "name": "Website",
"isActive": true,
"retailer": {
"retailerId": 1000,
"name": "HTM intern beheer",
"street": "Koningin Julianaplein",
"number": 10,
"numberAddition": null,
"postalCode": "2595 AA",
"city": "Den Haag",
"country": "Nederland",
"emailAddress": "info@htm.nl",
"phoneNumber": "070 374 9002",
"taxId": null,
"imageReference": "https://www.htm.nl/typo3conf/ext/htm_template/Resources/Public/img/logo.svg"
}
},
"forbiddenPaymentMethods": null,
"sellingPrices": [
{
"sellingPriceId": 318,
"taxCode": "V21",
"taxPercentage": 21.0000,
"amountExclTax": 94,
"amountInclTax": 100,
"fromInclusive": "2024-09-06T00:00:00.000+00:00",
"toInclusive": "2024-12-18T23:59:59.000+00:00",
"internalPrice": 92.0000
},
{
"sellingPriceId": 319,
"taxCode": "V21",
"taxPercentage": 21.0000,
"amountExclTax": 98,
"amountInclTax": 102,
"fromInclusive": "2024-12-19T00:00:00.000+00:00",
"toInclusive": "2024-12-29T23:59:59.000+00:00",
"internalPrice": 0.0000
}
]
},
{
"sellingPeriodId": 241,
"fromInclusive": "2024-09-06T00:00:00.000+00:00",
"toInclusive": "2024-12-29T23:59:59.000+00:00",
"salesTouchpoint": {
"salesTouchpointId": 5,
"name": "Servicewinkel (Team Incident Masters)",
"isActive": true, "isActive": true,
"retailer": { "retailer": {
"retailerId": 1001, "retailerId": 1001,
@ -139,64 +91,196 @@
"country": "Nederland", "country": "Nederland",
"emailAddress": "info@htm.nl", "emailAddress": "info@htm.nl",
"phoneNumber": "070 374 9002", "phoneNumber": "070 374 9002",
"taxId": null, "taxId": 572309345923,
"imageReference": "https://www.htm.nl/typo3conf/ext/htm_template/Resources/Public/img/logo.svg" "imageReference": "https://www.htm.nl/media/leif2leu/htm-logo-mobile.svg"
} }
}, },
"forbiddenPaymentMethods": [ "forbiddenPaymentMethods": [],
"sellingPrices": []
}
],
"purchasePrices": [],
"productVariants": [
{
"productId": 664,
"parentProductId": 663,
"layerInfo": {
"layerInfoId": null,
"choiceKey": null,
"choiceLabel": null,
"isCustomChoice": false
},
"fikoArticleNumber": null,
"gboPackageTemplateId": "30001",
"tapConnectProductCode": null,
"productName": "Losse week - Test OVPAY-2306",
"productDescription": "Test OVPAY-2306 (sellingPeriods in kindje verwijderen en later opnieuw weer kunnen toevoegen)",
"validityPeriod": {
"validityPeriodId": 783,
"fromInclusive": "2025-12-31T23:00:00.000Z",
"toInclusive": "2026-03-30T22:00:00.000Z"
},
"productTranslations": [],
"allowedGboAgeProfiles": [],
"productOwner": {
"productOwnerId": 1,
"name": "Wie dit leest",
"organization": "... is een aap."
},
"marketSegments": [],
"customerSegments": [],
"productCategory": {
"productCategoryId": 1,
"isTravelProduct": true,
"name": "Kortingsabonnement"
},
"requiredCustomerLevel": {
"requiredCustomerLevelId": 1,
"name": "guest"
},
"requiredProducts": [],
"incompatibleProducts": [],
"mandatoryCustomerDataItems": [],
"requiredGboPersonalAttributes": [],
"tokenTypes": [
{ {
"forbiddenPaymentMethodId": 2, "tokenTypeId": 1,
"name": "creditcard", "name": "EMV"
"issuer": "Visa"
} }
], ],
"sellingPrices": [ "paymentMoment": {
"paymentMomentId": 1,
"name": "prepaid"
},
"serviceOptions": [
{ {
"sellingPriceId": 320, "serviceOptionId": 4,
"taxCode": "V21", "action": "cancel_notAllowed",
"taxPercentage": 21.0000, "description": "Stopzetting is niet toegestaan (doorgaans in combinatie met refund_notAllowed)"
"amountExclTax": 94,
"amountInclTax": 100,
"fromInclusive": "2024-09-06T00:00:00.000+00:00",
"toInclusive": "2024-12-18T23:59:59.000+00:00",
"internalPrice": 92.0000
}, },
{ {
"sellingPriceId": 321, "serviceOptionId": 10,
"taxCode": "V21", "action": "refund_notAllowed",
"taxPercentage": 21.0000, "description": "Terugbetaling niet toegestaan (doorgaans in combinatie met cancel_notAllowed)"
"amountExclTax": 98,
"amountInclTax": 102,
"fromInclusive": "2024-12-19T00:00:00.000+00:00",
"toInclusive": "2024-12-29T23:59:59.000+00:00",
"internalPrice": 0.0000
} }
] ],
} "validityDuration": "P1W",
], "maxStartInFutureDuration": "P1W",
"purchasePrices": [ "isRenewable": false,
{ "sendInvoice": false,
"purchasePriceId": 184, "imageReference": null,
"taxCode": "V21", "productPageUrl": null,
"taxPercentage": 21.0000, "termsUrl": null,
"amountExclTax": 0, "isSellableAtHtm": true,
"amountInclTax": 0, "needsSolvencyCheckConsumer": false,
"fromInclusive": "2024-09-01T00:00:00.000+00:00", "needsSolvencyCheckBusiness": false,
"toInclusive": "2024-12-31T23:59:59.000+00:00" "sellingPeriods": [
} {
], "sellingPeriodId": 1384,
"auditTrail": [ "fromInclusive": "2025-12-31T23:00:00.000Z",
{ "toInclusive": "2026-03-30T22:00:00.000Z",
"auditTrailId": 228, "salesTouchpoint": {
"action": "update", "salesTouchpointId": 3,
"user": "api", "name": "Website",
"timestamp": "2024-10-21T09:00:30.410+00:00" "isActive": true,
"retailer": {
"retailerId": 1001,
"name": "HTM externe touchpoints",
"street": "Koningin Julianaplein",
"number": 10,
"numberAddition": null,
"postalCode": "2595 AA",
"city": "Den Haag",
"country": "Nederland",
"emailAddress": "info@htm.nl",
"phoneNumber": "070 374 9002",
"taxId": 572309345923,
"imageReference": "https://www.htm.nl/media/leif2leu/htm-logo-mobile.svg"
}
},
"forbiddenPaymentMethods": [],
"sellingPrices": []
}
],
"purchasePrices": [],
"productVariants": []
}, },
{ {
"auditTrailId": 227, "productId": 665,
"action": "insert", "parentProductId": 663,
"user": "api", "layerInfo": {
"timestamp": "2024-10-21T08:58:39.237+00:00" "layerInfoId": null,
"choiceKey": null,
"choiceLabel": null,
"isCustomChoice": false
},
"fikoArticleNumber": null,
"gboPackageTemplateId": "30001",
"tapConnectProductCode": null,
"productName": "Doorlopend - Test OVPAY-2306",
"productDescription": "Test OVPAY-2306 (sellingPeriods in kindje verwijderen en later opnieuw weer kunnen toevoegen)",
"validityPeriod": {
"validityPeriodId": 784,
"fromInclusive": "2025-12-31T23:00:00.000Z",
"toInclusive": "2026-03-30T22:00:00.000Z"
},
"productTranslations": [],
"allowedGboAgeProfiles": [],
"productOwner": {
"productOwnerId": 1,
"name": "Wie dit leest",
"organization": "... is een aap."
},
"marketSegments": [],
"customerSegments": [],
"productCategory": {
"productCategoryId": 1,
"isTravelProduct": true,
"name": "Kortingsabonnement"
},
"requiredCustomerLevel": {
"requiredCustomerLevelId": 1,
"name": "guest"
},
"requiredProducts": [],
"incompatibleProducts": [],
"mandatoryCustomerDataItems": [],
"requiredGboPersonalAttributes": [],
"tokenTypes": [
{
"tokenTypeId": 1,
"name": "EMV"
}
],
"paymentMoment": {
"paymentMomentId": 1,
"name": "prepaid"
},
"serviceOptions": [
{
"serviceOptionId": 4,
"action": "cancel_notAllowed",
"description": "Stopzetting is niet toegestaan (doorgaans in combinatie met refund_notAllowed)"
},
{
"serviceOptionId": 10,
"action": "refund_notAllowed",
"description": "Terugbetaling niet toegestaan (doorgaans in combinatie met cancel_notAllowed)"
}
],
"validityDuration": "P1W",
"maxStartInFutureDuration": "P1W",
"isRenewable": true,
"sendInvoice": false,
"imageReference": null,
"productPageUrl": null,
"termsUrl": null,
"isSellableAtHtm": true,
"needsSolvencyCheckConsumer": false,
"needsSolvencyCheckBusiness": false,
"sellingPeriods": [],
"purchasePrices": [],
"productVariants": []
} }
] ]
} }

View File

@ -28,10 +28,33 @@ public final class Helpers {
return new JSONObject(string).get("alertId").toString(); return new JSONObject(string).get("alertId").toString();
} }
public static String getTripId(String string) throws IOException {
return new JSONObject(string).get("tripId").toString();
}
public static String getXbot(String string) throws IOException { public static String getXbot(String string) throws IOException {
return new JSONObject(string).get("xbot").toString(); return new JSONObject(string).get("xbot").toString();
} }
public static void getTripDetails(String tripId, String xbot, String gboBearerToken) throws Exception {
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, DummyX509TrustManager.getDummyArray(), new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
URL url = new URL("https://api.sbx.idbt.translink.nl/api/v3/id-media/tokens/xbot/" + xbot + "/trips/details/" + tripId);
URLConnection con = url.openConnection();
HttpURLConnection http = (HttpURLConnection)con;
http.setRequestMethod("GET");
http.setDoOutput(true);
http.setRequestProperty("Authorization", "Bearer " + gboBearerToken);
http.connect();
try(InputStream is = http.getInputStream()) {
String response = new String(is.readAllBytes(), StandardCharsets.UTF_8);
LOGGER.info("GBO API 8659 trip details response for xBOT " + xbot + " and tripId " + tripId + ": \n" + new JSONObject(response).toString(2));
}
}
public static void getAlertDetails(String alertId, String xBot, String gboBearerToken) throws Exception { public static void getAlertDetails(String alertId, String xBot, String gboBearerToken) throws Exception {
SSLContext sc = SSLContext.getInstance("SSL"); SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, DummyX509TrustManager.getDummyArray(), new java.security.SecureRandom()); sc.init(null, DummyX509TrustManager.getDummyArray(), new java.security.SecureRandom());
@ -48,7 +71,7 @@ public final class Helpers {
try(InputStream is = http.getInputStream()) { try(InputStream is = http.getInputStream()) {
String response = new String(is.readAllBytes(), StandardCharsets.UTF_8); String response = new String(is.readAllBytes(), StandardCharsets.UTF_8);
LOGGER.info("GBO API 8851 alert details response for xBOT " + xBot + ": \n" + new JSONObject(response).toString(2)); LOGGER.info("GBO API 8851 alert details response for xBOT " + xBot + " and alertId " + alertId + ": \n" + new JSONObject(response).toString(2));
} }
} }

View File

@ -16,14 +16,28 @@ public class RabbitConnector {
private static final Logger LOGGER = LoggerFactory.getLogger(RabbitConnector.class); private static final Logger LOGGER = LoggerFactory.getLogger(RabbitConnector.class);
// TRIPS
// SubscriptionId = 3e246de5-d3ad-468f-834b-1aaebf52244c
// Use API 9853 to manually add xBOT to queue
private static final String QUEUE_NAME = "BEID_3.TRIPS";
private static final String USER_NAME = "BEID_3_TRIPS_HlTT";
private static final String PASSWORD = "xJR4C8hIqhHQw0sn";
// ALERTS
// SubscriptionId = 17c8100b-88a2-4cef-b40d-8dca4f93d311
// Use API 9853 to manually add xBOT to queue
// private static final String QUEUE_NAME = "BEID_3.ALERTS";
// private static final String USER_NAME = "BEID_3_ALERTS_nZs3";
// private static final String PASSWORD = "VyubhPnczKgTB2zJ";
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
ConnectionFactory factory = new ConnectionFactory(); ConnectionFactory factory = new ConnectionFactory();
factory.setVirtualHost("/"); factory.setVirtualHost("/");
factory.setAutomaticRecoveryEnabled(true); factory.setAutomaticRecoveryEnabled(true);
factory.setPort(443); factory.setPort(443);
factory.setHost("not.sbx.idbt.translink.nl"); factory.setHost("not.sbx.idbt.translink.nl");
factory.setUsername("BEID_3_ALERTS_nZs3"); factory.setUsername(USER_NAME);
factory.setPassword("VyubhPnczKgTB2zJ"); factory.setPassword(PASSWORD);
factory.useSslProtocol("TLSv1.2"); factory.useSslProtocol("TLSv1.2");
factory.setExceptionHandler(new ForgivingExceptionHandler()); factory.setExceptionHandler(new ForgivingExceptionHandler());
Map<String, Object> configs = factory.getClientProperties(); Map<String, Object> configs = factory.getClientProperties();
@ -33,7 +47,7 @@ public class RabbitConnector {
Channel channel = connection.createChannel(); Channel channel = connection.createChannel();
DeliverCallback deliverCallback = initDeliverCallback(channel); DeliverCallback deliverCallback = initDeliverCallback(channel);
AMQP.Queue.DeclareOk queue = channel.queueDeclarePassive("BEID_3.ALERTS"); AMQP.Queue.DeclareOk queue = channel.queueDeclarePassive(QUEUE_NAME);
LOGGER.info( LOGGER.info(
"Declared queue: " + queue.getQueue() + ", consumer count: " + queue.getConsumerCount() + ", message count: " + "Declared queue: " + queue.getQueue() + ", consumer count: " + queue.getConsumerCount() + ", message count: " +
queue.getMessageCount()); queue.getMessageCount());
@ -52,17 +66,39 @@ public class RabbitConnector {
channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false); channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
LOGGER.info("Successfully acknowledged message with delivery tag: " + delivery.getEnvelope().getDeliveryTag()); LOGGER.info("Successfully acknowledged message with delivery tag: " + delivery.getEnvelope().getDeliveryTag());
LOGGER.info("Getting alert details via GBO API 8851..."); if (QUEUE_NAME.equals("BEID_3.TRIPS")) {
try { getTripDetails(message);
String alertId = Helpers.getAlertId(message); } else if (QUEUE_NAME.equals("BEID_3.ALERTS")) {
String xBot = Helpers.getXbot(message); getAlertDetails(message);
String gboBearerToken = Helpers.getGboBearerToken();
Helpers.getAlertDetails(alertId, xBot, gboBearerToken);
} catch (Exception e) {
throw new RuntimeException(e);
} }
}; };
} }
private static void getAlertDetails(String message) {
try {
String alertId = Helpers.getAlertId(message);
String xBot = Helpers.getXbot(message);
String gboBearerToken = Helpers.getGboBearerToken();
LOGGER.info("Getting alert details for xBOT {} and alertId {} via GBO API 8851...", xBot, alertId);
Helpers.getAlertDetails(alertId, xBot, gboBearerToken);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private static void getTripDetails(String message) {
try {
String tripId = Helpers.getTripId(message);
String xBot = Helpers.getXbot(message);
String gboBearerToken = Helpers.getGboBearerToken();
LOGGER.info("Getting trip details for xBOT {} and tripId {} via GBO API 8659...", xBot, tripId);
Helpers.getTripDetails(tripId, xBot, gboBearerToken);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
} }

View File

@ -386,10 +386,10 @@ paths:
"refundAmount": 2489, "refundAmount": 2489,
"refundMethods": ["creditInvoice", "iDeal"], "refundMethods": ["creditInvoice", "iDeal"],
} }
Unsuccesful validation: Unsuccessful validation:
summary: Unsuccesful validation summary: Unsuccessful validation
description: | description: |
Unsuccesful validation. The response contains the error message. Unsuccessful validation. The response contains the error message.
value: value:
{ {
"validationResult": false, "validationResult": false,
@ -574,6 +574,267 @@ paths:
}, },
}, },
} }
/contracts/{uuid}/changemoments:
parameters:
- in: header
name: X-HTM-JWT-AUTH-HEADER
schema:
type: string
example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
required: true
description: The JWT of the logged in customer.
- in: path
name: uuid
schema:
type: string
format: uuid
example: 9e224750-3065-471d-af57-85b9cffa7c89
required: true
description: The id of the contract to process.
get:
summary: Get all change moments for a given contract.
description: Get all change moments for a given contract.
tags:
- SE Contract Changes v2
responses:
"200":
description: OK
content:
application/json:
schema:
$ref: "#/components/schemas/unavailable"
examples:
All change moments of a contract:
summary: All change moments of a contract
description: |
All change moments of a contract. The response contains the
allowed change moments for the current contract term.
value:
{
"changeMoment": "termBound",
"termDuration": "P1M",
"billingDay": 18,
"changeFrom": "2024-08-10T00:00:00",
"changeUntil": "2024-08-10T03:59:59",
}
/contracts/{uuid}/changevalidation:
parameters:
- in: header
name: X-HTM-JWT-AUTH-HEADER
schema:
type: string
example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
required: true
description: The JWT of the logged in customer.
- in: path
name: uuid
schema:
type: string
format: uuid
example: 9e224750-3065-471d-af57-85b9cffa7c89
required: true
description: The id of the contract to process.
post:
summary: Validate a change for a given contract.
description: Validate a change for a given contract.
tags:
- SE Contract Changes v2
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/unavailable"
examples:
Validate a change to another product:
summary: Validate a change to another product
description: |
Validate a change to another product. The response contains the allowed change moments for the current contract term.
value: { "productId": 124, "startDate": "2025-10-08" }
responses:
"200":
description: OK
content:
application/json:
schema:
$ref: "#/components/schemas/unavailable"
examples:
Successfully validated change:
summary: Successfully validated change
description: |
Successfully validated a change. The response contains the allowed change moments for the current contract term.
value:
{
"validationResult": true,
"validationMessage": "",
"contract":
{
"contractId": "15b43d9b-367a-4952-87f6-3e0fa902486f",
"contractNumber": "D123456",
"customerProfileId": 42,
"orderId": "eb3d08f7-7feb-4f31-9f5b-daa634e51f48",
"orderLineId": "52efbbfc-8c28-4016-9ece-dc3ef9a70bd8",
"touchpointId": 2,
"contractStatus":
{ "contractStatusId": 2, "name": "active" },
"productId": 1,
"productName": "HTM Maand 20% korting",
"termDuration": "P0Y1M0D",
"billingDay": 15,
"highestInvoiceTerm": 1,
"created": "2024-08-01 15:01:00.000",
"ovPayTokenId": 1337,
"contractVersions":
[
{
"contractVersionId": 2,
"termsAndConditions": "https://www.htm.nl",
"productId": 124,
"productName": "Regiovrij Regio Centrum",
"taxCode": "V9",
"taxPercentage": 9.0,
"termAmountInclTax": 12,
"start": "2025-10-08",
},
{
"contractVersionId": 1,
"termsAndConditions": "https://www.htm.nl",
"productId": 123,
"productName": "Regiovrij Regio Zuid",
"taxCode": "V9",
"taxPercentage": 9.0,
"termAmountInclTax": 10,
"start": "2025-01-08",
"end": "2025-10-07",
},
],
},
}
Unsuccessful validation:
summary: Unsuccessful validation
description: |
Unsuccessful validation. The response contains the error message.
value:
{
"validationResult": false,
"validationMessage": "Contract status is not ACTIVE",
"contract": null,
}
/contracts/{uuid}/change:
parameters:
- in: header
name: X-HTM-JWT-AUTH-HEADER
schema:
type: string
example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
required: true
description: The JWT of the logged in customer.
- in: path
name: uuid
schema:
type: string
format: uuid
example: 9e224750-3065-471d-af57-85b9cffa7c89
required: true
description: The id of the contract to process.
post:
summary: Change a contract.
description: Change a contract.
tags:
- SE Contract Changes v2
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/unavailable"
examples:
Change to another product:
summary: Change to another product
description: |
Change to another product. The response contains the details of the changed contract.
value: { "productId": 124, "startDate": "2025-10-08" }
responses:
"200":
description: OK
content:
application/json:
schema:
$ref: "#/components/schemas/unavailable"
examples:
Successfully changed contract:
summary: Successfully changed contract
description: |
Successfully changed a contract. The response contains the details of the changed contract.
value:
{
"contractId": "15b43d9b-367a-4952-87f6-3e0fa902486f",
"contractNumber": "D123456",
"customerProfileId": 42,
"orderId": "eb3d08f7-7feb-4f31-9f5b-daa634e51f48",
"orderLineId": "52efbbfc-8c28-4016-9ece-dc3ef9a70bd8",
"touchpointId": 2,
"contractStatus":
{ "contractStatusId": 2, "name": "active" },
"productId": 1,
"productName": "HTM Maand 20% korting",
"termDuration": "P0Y1M0D",
"billingDay": 15,
"highestInvoiceTerm": 1,
"created": "2024-08-01 15:01:00.000",
"ovPayTokenId": 1337,
"contractVersions":
[
{
"contractVersionId": 2,
"termsAndConditions": "https://www.htm.nl",
"productId": 124,
"productName": "Regiovrij Regio Centrum",
"taxCode": "V9",
"taxPercentage": 9.0,
"termAmountInclTax": 12,
"start": "2025-10-08",
},
{
"contractVersionId": 1,
"termsAndConditions": "https://www.htm.nl",
"productId": 123,
"productName": "Regiovrij Regio Zuid",
"taxCode": "V9",
"taxPercentage": 9.0,
"termAmountInclTax": 10,
"start": "2025-01-08",
"end": "2025-10-07",
},
],
}
"400":
description: Bad Request
content:
application/json:
schema:
$ref: "#/components/schemas/unavailable"
examples:
Unsuccessful change due to invalid productId:
summary: Unsuccessful change due to invalid productId
description: |
Unsuccessful change due to invalid productId. The response contains the error message.
value:
{
"type": "https://htm.nl/api/v1/probs/validationerror",
"title": "Your request is not valid.",
"detail": "The chosen parameters for this contract change are not valid.",
"instance": "urn:uuid:4017fabc-1b28-11e8-accf-0ed5f89f718b",
"errors":
[
{
"code": "CHANGE_DATE_IN_THE_PAST",
"detail": "Chosen date of contract change is in the past. This is not alllowed.",
"path": "$.startDate",
"parameter": null,
},
],
}
/contractpayments: /contractpayments:
parameters: parameters:
- in: header - in: header
@ -597,9 +858,13 @@ paths:
schema: schema:
$ref: "#/components/schemas/unavailable" $ref: "#/components/schemas/unavailable"
examples: examples:
List all contract payments for a single debtor: Empty list:
summary: List all contract payments for a single debtor summary: Empty list
description: List all contract payments for single debtor with debtor number 'D123456'. description: List all contract payments for a debtor with no payments.
value: { "contractPayments": [] }
Successful direct debit:
summary: Successful direct debit
description: One payment for a debtor with a successful direct debit.
value: value:
{ {
"contractPayments": "contractPayments":
@ -607,8 +872,133 @@ paths:
{ {
"paymentId": "151845776", "paymentId": "151845776",
"totalAmount": "26.62", "totalAmount": "26.62",
"paymentMethod": "Twikey", "paymentMethod": "Automatische incasso",
"paymentDate": "2024-09-12", "paymentDate": "2024-09-12",
"iban": "NL25INGB******1337",
"invoice":
{
"invoiceId": "147722263",
"invoiceNumber": "F2024-0001",
"description": "HTM Maandkorting 20%",
"publicLink": "https://factuurinzien.nl/d/b0aac3f42f325f5dd6abc172f723caab5956524d/i/ddb245d6df67999eca48c4a71b5661b93038e20a",
},
"_links":
{
"get_contractdetails":
{
"href": "https://api.integratielaag.nl/abt/touchpoint/1.0/customers/contracts/5ca46c1a-cb9d-4c2d-960e-4471e8e28b6a",
"method": "GET",
},
},
},
],
}
Direct debit reversal:
summary: Direct debit reversal
description: One payment for a debtor with a reversed direct debit.
value:
{
"contractPayments":
[
{
"paymentId": "151845776",
"totalAmount": "-26.62",
"paymentMethod": "Stornering",
"paymentDate": "2024-09-12",
"iban": "NL25INGB******1337",
"invoice":
{
"invoiceId": "147722263",
"invoiceNumber": "F2024-0001",
"description": "HTM Maandkorting 20%",
"publicLink": "https://factuurinzien.nl/d/b0aac3f42f325f5dd6abc172f723caab5956524d/i/ddb245d6df67999eca48c4a71b5661b93038e20a",
},
"_links":
{
"get_contractdetails":
{
"href": "https://api.integratielaag.nl/abt/touchpoint/1.0/customers/contracts/5ca46c1a-cb9d-4c2d-960e-4471e8e28b6a",
"method": "GET",
},
},
},
],
}
iDEAL payment:
summary: iDEAL payment
description: One payment for a debtor with an iDEAL payment.
value:
{
"contractPayments":
[
{
"paymentId": "151845776",
"totalAmount": "26.62",
"paymentMethod": "iDEAL",
"paymentDate": "2024-09-12",
"iban": "NL25INGB******1337",
"invoice":
{
"invoiceId": "147722263",
"invoiceNumber": "F2024-0001",
"description": "HTM Maandkorting 20%",
"publicLink": "https://factuurinzien.nl/d/b0aac3f42f325f5dd6abc172f723caab5956524d/i/ddb245d6df67999eca48c4a71b5661b93038e20a",
},
"_links":
{
"get_contractdetails":
{
"href": "https://api.integratielaag.nl/abt/touchpoint/1.0/customers/contracts/5ca46c1a-cb9d-4c2d-960e-4471e8e28b6a",
"method": "GET",
},
},
},
],
}
Bank transfer:
summary: Bank transfer
description: One payment for a debtor with a bank transfer.
value:
{
"contractPayments":
[
{
"paymentId": "151845776",
"totalAmount": "26.62",
"paymentMethod": "Overboeking",
"paymentDate": "2024-09-12",
"iban": "NL25INGB******1337",
"invoice":
{
"invoiceId": "147722263",
"invoiceNumber": "F2024-0001",
"description": "HTM Maandkorting 20%",
"publicLink": "https://factuurinzien.nl/d/b0aac3f42f325f5dd6abc172f723caab5956524d/i/ddb245d6df67999eca48c4a71b5661b93038e20a",
},
"_links":
{
"get_contractdetails":
{
"href": "https://api.integratielaag.nl/abt/touchpoint/1.0/customers/contracts/5ca46c1a-cb9d-4c2d-960e-4471e8e28b6a",
"method": "GET",
},
},
},
],
}
List of four payments for one invoice:
summary: List of four payments for one invoice
description: Four payments for a debtor for one invoice; a direct debit, a direct debit reversal, a bank transfer and an iDEAL payment.
value:
{
"contractPayments":
[
{
"paymentId": "151845776",
"totalAmount": "26.62",
"paymentMethod": "Automatische incasso",
"paymentDate": "2024-09-12",
"iban": "NL25INGB******1337",
"invoice": "invoice":
{ {
"invoiceId": "147722263", "invoiceId": "147722263",
@ -626,22 +1016,67 @@ paths:
}, },
}, },
{ {
"paymentId": "151845851", "paymentId": "151845776",
"totalAmount": "45.21", "totalAmount": "-26.62",
"paymentMethod": "Twikey", "paymentMethod": "Stornering",
"paymentDate": "2024-09-12", "paymentDate": "2024-09-12",
"iban": "NL25INGB******1337",
"invoice": "invoice":
{ {
"invoiceId": "147722266", "invoiceId": "147722263",
"invoiceNumber": "F2024-0002", "invoiceNumber": "F2024-0001",
"description": "HTM Maandkorting 20%", "description": "HTM Maandkorting 20%",
"publicLink": "https://factuurinzien.nl/d/ddb245d6df67999eca48c4a71b5661b93038e20a/i/dp5h1i5cuu94nopiolkdst3u17vkmzo", "publicLink": "https://factuurinzien.nl/d/b0aac3f42f325f5dd6abc172f723caab5956524d/i/ddb245d6df67999eca48c4a71b5661b93038e20a",
}, },
"_links": "_links":
{ {
"get_contractdetails": "get_contractdetails":
{ {
"href": "https://api.integratielaag.nl/abt/touchpoint/1.0/customers/contracts/7b2f8c1a-3d9d-4c2d-960e-4471e8e28b6a", "href": "https://api.integratielaag.nl/abt/touchpoint/1.0/customers/contracts/5ca46c1a-cb9d-4c2d-960e-4471e8e28b6a",
"method": "GET",
},
},
},
{
"paymentId": "151845777",
"totalAmount": "10.00",
"paymentMethod": "Overboeking",
"paymentDate": "2024-09-13",
"iban": "NL25INGB******1337",
"invoice":
{
"invoiceId": "147722263",
"invoiceNumber": "F2024-0001",
"description": "HTM Maandkorting 20%",
"publicLink": "https://factuurinzien.nl/d/b0aac3f42f325f5dd6abc172f723caab5956524d/i/ddb245d6df67999eca48c4a71b5661b93038e20a",
},
"_links":
{
"get_contractdetails":
{
"href": "https://api.integratielaag.nl/abt/touchpoint/1.0/customers/contracts/5ca46c1a-cb9d-4c2d-960e-4471e8e28b6a",
"method": "GET",
},
},
},
{
"paymentId": "151845778",
"totalAmount": "16.62",
"paymentMethod": "iDEAL",
"paymentDate": "2024-09-14",
"iban": "NL25INGB******1337",
"invoice":
{
"invoiceId": "147722263",
"invoiceNumber": "F2024-0001",
"description": "HTM Maandkorting 20%",
"publicLink": "https://factuurinzien.nl/d/b0aac3f42f325f5dd6abc172f723caab5956524d/i/ddb245d6df67999eca48c4a71b5661b93038e20a",
},
"_links":
{
"get_contractdetails":
{
"href": "https://api.integratielaag.nl/abt/touchpoint/1.0/customers/contracts/5ca46c1a-cb9d-4c2d-960e-4471e8e28b6a",
"method": "GET", "method": "GET",
}, },
}, },

File diff suppressed because it is too large Load Diff

View File

@ -359,7 +359,6 @@ paths:
application/json: application/json:
schema: schema:
$ref: "#/components/schemas/CustomersResponse" $ref: "#/components/schemas/CustomersResponse"
/customers/tokens: /customers/tokens:
get: get:
tags: tags:
@ -491,6 +490,7 @@ paths:
"ovPayTokenId": 1, "ovPayTokenId": 1,
"xTat": "32089cc8-d187-47ff-a3a9-5c2558def811", "xTat": "32089cc8-d187-47ff-a3a9-5c2558def811",
"tokenType": { "tokenTypeId": 1, "name": "EMV" }, "tokenType": { "tokenTypeId": 1, "name": "EMV" },
"ovpasNumber": "",
"alias": "MyToken", "alias": "MyToken",
"tokenStatus": "tokenStatus":
{ "tokenStatusId": 2, "name": "Active" }, { "tokenStatusId": 2, "name": "Active" },
@ -567,6 +567,7 @@ paths:
"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",
"alias": "MyToken", "alias": "MyToken",
"tokenStatus": "tokenStatus":
{ "tokenStatusId": 2, "name": "Active" }, { "tokenStatusId": 2, "name": "Active" },
@ -649,6 +650,7 @@ paths:
"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",
"alias": "MyToken", "alias": "MyToken",
"tokenStatus": "tokenStatus":
{ "tokenStatusId": 2, "name": "Active" }, { "tokenStatusId": 2, "name": "Active" },
@ -771,6 +773,7 @@ paths:
"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",
"alias": "MyToken", "alias": "MyToken",
"tokenStatus": "tokenStatus":
{ "tokenStatusId": 2, "name": "Active" }, { "tokenStatusId": 2, "name": "Active" },
@ -868,6 +871,7 @@ paths:
"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",
"alias": "MyToken", "alias": "MyToken",
"tokenStatus": "tokenStatus":
{ "tokenStatusId": 2, "name": "Active" }, { "tokenStatusId": 2, "name": "Active" },
@ -983,6 +987,7 @@ paths:
"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",
"alias": "MyToken", "alias": "MyToken",
"tokenStatus": "tokenStatus":
{ "tokenStatusId": 2, "name": "Active" }, { "tokenStatusId": 2, "name": "Active" },
@ -1003,6 +1008,7 @@ paths:
"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": "OV31236",
"alias": "MyToken", "alias": "MyToken",
"tokenStatus": "tokenStatus":
{ "tokenStatusId": 3, "name": "Replaced (*)" }, { "tokenStatusId": 3, "name": "Replaced (*)" },
@ -1024,6 +1030,7 @@ paths:
"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": "OV36897",
"alias": "MyToken", "alias": "MyToken",
"tokenStatus": "tokenStatus":
{ "tokenStatusId": 4, "name": "On stock" }, { "tokenStatusId": 4, "name": "On stock" },
@ -1045,6 +1052,7 @@ paths:
"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": "OV33489",
"alias": "Mijn OV Pas", "alias": "Mijn OV Pas",
"tokenStatus": "tokenStatus":
{ "tokenStatusId": 5, "name": "Suspended" }, { "tokenStatusId": 5, "name": "Suspended" },
@ -1066,6 +1074,7 @@ paths:
"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": "OV48965",
"alias": "Mijn OV Pas", "alias": "Mijn OV Pas",
"tokenStatus": "tokenStatus":
{ {
@ -1111,6 +1120,7 @@ paths:
"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": "OV13458",
"alias": "My found token", "alias": "My found token",
"tokenStatus": "tokenStatus":
{ "tokenStatusId": 7, "name": "Renewed Active" }, { "tokenStatusId": 7, "name": "Renewed Active" },
@ -2210,7 +2220,7 @@ paths:
content: content:
application/json: application/json:
schema: schema:
$ref: "#/components/schemas/OvPayTokenProductInstancesResponse" $ref: "#/components/schemas/ProductInstancesResponse"
examples: examples:
getEmptyProductInstances: getEmptyProductInstances:
summary: No product-instances found on token summary: No product-instances found on token
@ -2223,6 +2233,7 @@ paths:
"productInstances": "productInstances":
[ [
{ {
"productInstanceId": "26d41861-f77e-4666-9cde-2c5c66ace0a2",
"productId": 1, "productId": 1,
"name": "HTM 90% Korting", "name": "HTM 90% Korting",
"status": "Active", "status": "Active",
@ -2239,11 +2250,6 @@ paths:
"contractId": "56B17EF-C436-9043-B76C-481797WEB464F", "contractId": "56B17EF-C436-9043-B76C-481797WEB464F",
"_links": "_links":
{ {
"self":
{
"href": "https://api.integratielaag.nl/abt/touchpoint/1.0/customers/tokens/1/productinstances/1",
"method": "GET",
},
"get_order": "get_order":
{ {
"href": "https://api.integratielaag.nl/abt/touchpoint/1.0/orders/501B17EF-36C4-4039-B92C-6517969B464E", "href": "https://api.integratielaag.nl/abt/touchpoint/1.0/orders/501B17EF-36C4-4039-B92C-6517969B464E",
@ -2403,7 +2409,7 @@ paths:
}, },
"_links": "_links":
{ {
"transfer_token": "transfer":
{ {
"href": "https://services.dev.api.htm.nl/abt/touchpoint/1.0/customers/tokens/1/transfer", "href": "https://services.dev.api.htm.nl/abt/touchpoint/1.0/customers/tokens/1/transfer",
"method": "POST", "method": "POST",
@ -3398,6 +3404,377 @@ paths:
responses: responses:
"200": "200":
description: OK description: OK
/productinstances:
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: string
example: feaaef83-a551-4283-8419-340b1ada3b55
required: false
description: The customerProfileId of a customer in the case of the SMP
- name: X-HTM-ROLE-HEADER
in: header
schema:
type: string
example: Customer
required: false
- name: deviceId
in: query
description: Id of the device you want to get the instantiated HTM products for.
schema:
type: string
format: uuid
- name: externalDeviceId
in: query
description: Id of the device you want to get the instantiated HTM products for.
schema:
type: string
- name: ovpayTokenId
in: query
description: Id of the ovpay token you want to get the instantiated HTM products for.
schema:
type: string
format: uuid
get:
summary: Get a list of all HTM products for a specific customer, device or token, at least one should be filled in
description: |-
Get a list of all HTM products instantiated for a specific customer, device or token, at least one of the query params should be filled in.
Only HTM products are returned.
Where relevant, operations to be performed are returned as HATEOAS links per product-instance.
tags:
- ProductInstances
responses:
"200":
description: OK
content:
application/json:
schema:
$ref: "#/components/schemas/ProductInstancesResponse"
examples:
getEmptyProductInstances:
summary: No product-instances found
value:
productInstances: {
"ovPayProducts":[],
"barcodeTickets": [],
"vouchers":[]
}
getSingleBarcodeProductInstanceForDevice:
summary: One BarcodeTicket product-instance
value:
{
"productInstances":{
"ovPayProducts":[],
"barcodeTickets":[
{
"productInstanceId": "0f0981bf-6d60-4b06-bc55-de1ba325f366",
"productId": 13,
"name": "HTM dagkaart",
"productCategory":
{
"productCategoryId": 5,
"name": "Barcode",
},
"orderId": "501B17EF-36C4-4039-B92C-6517969B464E",
"orderLineId": "38B17EF-36C4-4039-B92C-4817969B464E",
"status": "Active",
"ticketReference": "KJj43nejhbTxhr897287",
"issuedAt": "2020-03-21T00:00:00",
"activatedAt": null,
"blocked": false,
"cancelledAt": null,
"fraudDetected": false,
"barcode": "barcodeBytes",
"deviceId": "e2be51ae-2701-4803-a2d7-97d4b714482d",
"_links":
{
"get_order":
{
"href": "https://api.integratielaag.nl/abt/touchpoint/1.0/orders/501B17EF-36C4-4039-B92C-6517969B464E",
"method": "GET",
},
"patch_productinstance":
{
"href": "https://api.integratielaag.nl/abt/touchpoint/1.0/customers/productinstances/0f0981bf-6d60-4b06-bc55-de1ba325f366",
"method": "PATCH",
},
},
},
],
"vouchers":[]
}
}
getSingleOvpayProductInstanceForSpecificOvPayToken:
summary: One Ovpay product-instance
value:
{
"productInstances":{
"ovPayProducts":[ {
"productInstanceId": "26d41861-f77e-4666-9cde-2c5c66ace0a2",
"productId": 1,
"name": "HTM 90% Korting",
"status": "Active",
"isRenewable": true,
"productCategory":
{
"productCategoryId": 1,
"name": "Kortingsabonnement",
},
"fromInclusive": "2024-11-25T13:25:00+01:00",
"untilInclusive": "2024-12-25T03:59:59+01:00",
"orderId": "501B17EF-36C4-4039-B92C-6517969B464E",
"orderLineId": "38B17EF-36C4-4039-B92C-4817969B464E",
"contractId": "56B17EF-C436-9043-B76C-481797WEB464F",
"ovPayTokenId": 42,
"deviceId": null,
"_links":
{
"get_order":
{
"href": "https://api.integratielaag.nl/abt/touchpoint/1.0/orders/501B17EF-36C4-4039-B92C-6517969B464E",
"method": "GET",
},
"get_contract":
{
"href": "https://api.integratielaag.nl/abt/touchpoint/1.0/customers/contracts/56B17EF-C436-9043-B76C-481797WEB464F",
"method": "GET",
},
},
},
],
"barcodeTickets":[],
"vouchers":[]
}
}
getMultipleProductInstancesForCustomer:
summary: Multiple product-instances for a customer
value:
{
"productInstances":{
"ovPayProducts":[ {
"productInstanceId": "26d41861-f77e-4666-9cde-2c5c66ace0a2",
"productId": 1,
"name": "HTM 90% Korting",
"isRenewable": true,
"productCategory":
{
"productCategoryId": 1,
"name": "Kortingsabonnement",
},
"fromInclusive": "2024-11-25T13:25:00+01:00",
"untilInclusive": "2024-12-25T03:59:59+01:00",
"orderId": "501B17EF-36C4-4039-B92C-6517969B464E",
"orderLineId": "38B17EF-36C4-4039-B92C-4817969B464E",
"contractId": "56B17EF-C436-9043-B76C-481797WEB464F",
"ovPayTokenId": 42,
"deviceId": null,
"_links":
{
"get_order":
{
"href": "https://api.integratielaag.nl/abt/touchpoint/1.0/orders/501B17EF-36C4-4039-B92C-6517969B464E",
"method": "GET",
},
"get_contract":
{
"href": "https://api.integratielaag.nl/abt/touchpoint/1.0/customers/contracts/56B17EF-C436-9043-B76C-481797WEB464F",
"method": "GET",
},
},
},
],
"barcodeTickets":
[
{
"productInstanceId": "0f0981bf-6d60-4b06-bc55-de1ba325f366",
"productId": 13,
"name": "HTM dagkaart",
"productCategory":
{
"productCategoryId": 5,
"name": "Barcode",
},
"orderId": "501B17EF-36C4-4039-B92C-6517969B464E",
"orderLineId": "38B17EF-36C4-4039-B92C-4817969B464E",
"status": "Active",
"ticketReference": "KJj43nejhbTxhr897287",
"issuedAt": "2020-03-21T00:00:00",
"activatedAt": null,
"blocked": false,
"cancelledAt": null,
"fraudDetected": false,
"barcode": "barcodeBytes",
"deviceId": "e2be51ae-2701-4803-a2d7-97d4b714482d",
"_links":
{
"get_order":
{
"href": "https://api.integratielaag.nl/abt/touchpoint/1.0/orders/501B17EF-36C4-4039-B92C-6517969B464E",
"method": "GET",
},
"patch_productinstance":
{
"href": "https://api.integratielaag.nl/abt/touchpoint/1.0/customers/productinstances/0f0981bf-6d60-4b06-bc55-de1ba325f366",
"method": "PATCH",
},
},
},
],
"vouchers":[]
}
}
getSingleVoucherProductInstanceForCustomer:
summary: One voucher product-instance
value:
{
"productInstances":{
"ovPayProducts":[],
"barcodeTickets":[],
"vouchers":[
{
"productInstanceId": "07a55d42-ea42-4f5c-896a-b340ab084309",
"productId": 81,
"name": "HTM ooivaarspas voucher ",
"productCategory":
{
"productCategoryId": 9,
"name": "Voucher",
},
"voucherCode": "HTM45253",
"fromInclusive": "2026-01-01T00:00:00",
"untillInclusive": "2026-12-31T23:59:99",
"voucherStatus": {
"voucherStatusId": 2,
"name": "issued"
},
"mandatoryCustomerDataItems":
[
{
"mandatoryCustomerDataItemId": 8,
"customerDataItem": "padBirthDate",
},
{
"mandatoryCustomerDataItemId": 4,
"customerDataItem": "emailAddress",
},
]
}
]
}
}
/productinstances/{productInstanceId}:
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: string
example: feaaef83-a551-4283-8419-340b1ada3b55
required: false
description: The customerProfileId of a customer in the case of the SMP
- name: X-HTM-ROLE-HEADER
in: header
schema:
type: string
example: Customer
required: false
- name: productInstanceId
in: path
required: true
style: simple
description: Id of the product instance you want to change
schema:
type: string
format: uuid
example: 0f0981bf-6d60-4b06-bc55-de1ba325f366
patch:
summary: Update a productInstance
description: |-
Update the status of the give productInstance.
tags:
- ProductInstances
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/unavailable"
examples:
Update a productInstance status to active:
value:
{
"status": "Active"
}
responses:
"200":
description: OK
content:
application/json:
schema:
$ref: "#/components/schemas/unavailable"
examples:
Update a productInstance status to active:
summary: Update a productInstance status to active
value:
{
"productInstances":
[
{
"productInstanceId": "0f0981bf-6d60-4b06-bc55-de1ba325f366",
"productId": 13,
"name": "HTM dagkaart",
"purchasedProductType": "TapConnect",
"status": "Active",
"isRenewable": false,
"productCategory":
{
"productCategoryId": 2,
"name": "Afgekocht reisrecht",
},
"fromInclusive": "2024-11-25T13:25:00+01:00",
"untilInclusive": null,
"orderId": "501B17EF-36C4-4039-B92C-6517969B464E",
"orderLineId": "38B17EF-36C4-4039-B92C-4817969B464E",
"contractId": null,
"content": {
"ticketReference": "KJj43nejhbTxhr897287",
"issuedAt": "2020-03-21T00:00:00",
"activatedAt": "2020-03-21T00:00:00",
"blocked": false,
"cancelledAt": null,
"fraudDetected": false,
"barcode": "barcodeBytes"
},
"_links":
{
"get_order":
{
"href": "https://api.integratielaag.nl/abt/touchpoint/1.0/orders/501B17EF-36C4-4039-B92C-6517969B464E",
"method": "GET",
},
"patch_productinstance":
{
"href": "https://api.integratielaag.nl/abt/touchpoint/1.0/customers/productinstances/0f0981bf-6d60-4b06-bc55-de1ba325f366",
"method": "PATCH",
},
},
},
],
}
components: components:
schemas: schemas:
unavailable: unavailable:
@ -3786,20 +4163,39 @@ components:
method: method:
type: string type: string
example: GET example: GET
OvPayTokenProductInstancesResponse: ProductInstancesResponse:
type: object type: object
required:
- productInstances
properties: properties:
productInstances: productInstances:
type: array type: array
items: items:
type: object type: object
required:
- productInstanceId
- productId
- name
- status
- purchasedProductType
- isRenewable
- productCategory
- _links
properties: properties:
productInstanceId:
type: string
format: uuid
example: 0f0981bf-6d60-4b06-bc55-de1ba325f366
productId: productId:
type: integer type: integer
example: 1 example: 1
name: name:
type: string type: string
example: HTM 90% Korting example: HTM 90% Korting
purchasedProductType:
type: string
description: The type of product instance (e.g. GBO, TapConnect, physical, etc.)
example: GBO
status: status:
type: string type: string
enum: ["Active", "Ended", "Refunded"] enum: ["Active", "Ended", "Refunded"]
@ -3840,6 +4236,10 @@ components:
format: uuid format: uuid
example: 56B17EF-C436-9043-B76C-481797WEB464F example: 56B17EF-C436-9043-B76C-481797WEB464F
description: Only present for subscriptions/contracts description: Only present for subscriptions/contracts
content:
type: object
description: Custom data for the product-instance, depending on the purchasedProductType
example: null
_links: _links:
type: object type: object
properties: properties:
@ -3854,21 +4254,31 @@ components:
example: GET example: GET
get_order: get_order:
type: object type: object
description: Always present for any HTM product-instance
properties: properties:
href: href:
type: string type: string
description: Always present for any HTM product-instance
example: https://api.integratielaag.nl/abt/touchpoint/1.0/orders/501B17EF-36C4-4039-B92C-6517969B464E example: https://api.integratielaag.nl/abt/touchpoint/1.0/orders/501B17EF-36C4-4039-B92C-6517969B464E
method: method:
type: string type: string
example: GET example: GET
get_contract: get_contract:
type: object type: object
description: Only present for subscriptions/contracts
properties: properties:
href: href:
type: string type: string
description: Only present for subscriptions/contracts
example: https://api.integratielaag.nl/abt/touchpoint/1.0/customers/contracts/56B17EF-C436-9043-B76C-481797WEB464F example: https://api.integratielaag.nl/abt/touchpoint/1.0/customers/contracts/56B17EF-C436-9043-B76C-481797WEB464F
method: method:
type: string type: string
example: GET example: GET
patch_productinstance:
type: object
description: Only present for TapConnect product-instances that need to be activated
properties:
href:
type: string
example: https://api.integratielaag.nl/abt/touchpoint/1.0/customers/productinstances/0f0981bf-6d60-4b06-bc55-de1ba325f366
method:
type: string
example: PATCH

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -417,38 +417,56 @@ paths:
example: example:
Entries: Entries:
phoneTypes: phoneTypes:
- name: mobile - name: Mobiel
id: 1 id: 1
- name: fixed line - name: Thuis
id: 2 id: 2
- name: Ouders
id: 3
- name: Bewindvoerder
id: 4
- name: Home
id: 5
- name: Mobile
id: 6
- name: Work
id: 7
- name: Noodtelefoon
id: 8
addressTypes: addressTypes:
- name: home - name: Shipping
id: 1 id: 1
- name: office - name: Billing
id: 2 id: 2
customerStatuses: customerStatuses:
- name: active - name: Inactive
id: 1 id: 1
- name: blocked - name: Active
id: 2 id: 2
- name: inactive - name: Blocked
id: 3 id: 3
- name: new - name: Frozen
id: 4 id: 4
- name: Cleared
id: 5
tokenTypes: tokenTypes:
- name: Debit card - name: EMV
id: 1 id: 1
- name: Credit card
id: 2
- name: OVPas physical - name: OVPas physical
id: 3 id: 2
- name: OVPas digital - name: OVPas digital
id: 4 id: 3
directDebitMandateTypes: directDebitMandateTypes:
- name: Paper Contract - name: Paper Contract
id: 1 id: 1
- name: PIN transaction - name: PIN transaction
id: 2 id: 2
- name: SEPA eMandate
id: 3
- name: Digital signature
id: 4
- name: IDEAL transaction
id: 5
tokenStatuses: tokenStatuses:
- name: Expired - name: Expired
id: 1 id: 1

File diff suppressed because it is too large Load Diff

View File

@ -2999,8 +2999,12 @@ paths:
transactionItems: transactionItems:
- transactionItemId: d8ee7035-fa3d-400e-9ad5-4fe8c4c73eb7 - transactionItemId: d8ee7035-fa3d-400e-9ad5-4fe8c4c73eb7
status: returned to src status: returned to src
aggregationReference: null
accountingSystemReference: null
- transactionItemId: 88910e83-4b1e-4fde-ab13-bd8bb60cbcd3 - transactionItemId: 88910e83-4b1e-4fde-ab13-bd8bb60cbcd3
status: returned to src status: returned to src
aggregationReference: null
accountingSystemReference: null
List of transactions items to return: List of transactions items to return:
summary: List of transaction items to return to transaction database summary: List of transaction items to return to transaction database
description: List of transaction items to return to transaction database in bulk. description: List of transaction items to return to transaction database in bulk.
@ -3008,8 +3012,12 @@ paths:
transactionItems: transactionItems:
- transactionItemId: eacb9bdc-c6b5-4277-942b-cebb102944f5 - transactionItemId: eacb9bdc-c6b5-4277-942b-cebb102944f5
status: returned to trx-db status: returned to trx-db
aggregationReference: null
accountingSystemReference: null
- transactionItemId: 2f361bfb-9df0-4e0f-af7c-7b9be3e7bc61 - transactionItemId: 2f361bfb-9df0-4e0f-af7c-7b9be3e7bc61
status: returned to trx-db status: returned to trx-db
aggregationReference: null
accountingSystemReference: null
responses: responses:
"202": "202":
description: Accepted description: Accepted
@ -3061,10 +3069,32 @@ paths:
Body of a batch of transaction items that was successfully patched. Body of a batch of transaction items that was successfully patched.
A number of transaction items were patched. A number of transaction items were patched.
value: value:
startTime: 2025-02-14T05:32:47.067Z
status: Finished
clientTrackingId: 08584620957189579629541919368CU00
summary: summary:
created: 0 created: 0
updated: 15 updated: 15
total: 15 total: 15
"202":
description: OK
content:
application/json:
schema:
$ref: "#/components/schemas/GetResponseStatus"
examples:
Batch is still being processed:
summary: Batch is still being processed
description: |
Batch is still being processed
value:
startTime: 2025-02-14T05:32:47.067Z
status: Running
clientTrackingId: 08584620957189579629541919368CU00
summary:
created: 0
updated: 0
total: 0
security: security:
- default: [] - default: []
x-auth-type: Application & Application User x-auth-type: Application & Application User
@ -3089,8 +3119,10 @@ paths:
processingFailures: processingFailures:
- processingFailureId: d8ee7035-fa3d-400e-9ad5-4fe8c4c73eb7 - processingFailureId: d8ee7035-fa3d-400e-9ad5-4fe8c4c73eb7
resolved: true resolved: true
change: Configuratie aangepast voor artikelnummer 1337.
- processingFailureId: 88910e83-4b1e-4fde-ab13-bd8bb60cbcd3 - processingFailureId: 88910e83-4b1e-4fde-ab13-bd8bb60cbcd3
resolved: true resolved: true
change: Configuratie aangepast voor artikelnummer 1337.
responses: responses:
"202": "202":
description: Accepted description: Accepted
@ -3142,10 +3174,32 @@ paths:
Body of a batch of processing failures that was successfully patched. Body of a batch of processing failures that was successfully patched.
A number of processing failures were patched. A number of processing failures were patched.
value: value:
startTime: 2025-02-14T05:32:47.067Z
status: Finished
clientTrackingId: 08584620957189579629541919368CU00
summary: summary:
created: 0 created: 0
updated: 15 updated: 15
total: 15 total: 15
"202":
description: OK
content:
application/json:
schema:
$ref: "#/components/schemas/GetResponseStatus"
examples:
Batch is still being processed:
summary: Batch is still being processed
description: |
Batch is still being processed
value:
startTime: 2025-02-14T05:32:47.067Z
status: Running
clientTrackingId: 08584620957189579629541919368CU00
summary:
created: 0
updated: 0
total: 0
security: security:
- default: [] - default: []
x-auth-type: Application & Application User x-auth-type: Application & Application User

View File

@ -5,6 +5,12 @@ info:
description: CRUD APIs for ABT Orders database. These are NOT the functional APIs from Service Engine. description: CRUD APIs for ABT Orders database. These are NOT the functional APIs from Service Engine.
servers: servers:
- url: https://services.acc.api.htm.nl/abt/abtorder/1.0 - url: https://services.acc.api.htm.nl/abt/abtorder/1.0
tags:
- name: Order
- name: Order Line
- name: Payment
- name: Customer
- name: Order Voucher
paths: paths:
/orders: /orders:
get: get:
@ -50,6 +56,14 @@ paths:
example: 1 example: 1
required: false required: false
description: The id of the touch point where the order was initiated. description: The id of the touch point where the order was initiated.
- in: query
name: deviceId
schema:
type: string
format: uuid
example: "7a28bd54-7ca9-499a-a722-d15ab858ab99"
required: false
description: The id of the device used to place the order.
- in: query - in: query
name: languageId name: languageId
schema: schema:
@ -98,6 +112,14 @@ 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
@ -119,6 +141,7 @@ paths:
"touchPointId": 1, "touchPointId": 1,
"name": "Perplex" "name": "Perplex"
}, },
"deviceId": "42e77532-d831-41da-b07a-7edb9bb7f004",
"language": "language":
{ {
"languageId": 1, "languageId": 1,
@ -148,6 +171,30 @@ paths:
"description": "Betaling in behandeling", "description": "Betaling in behandeling",
}, },
], ],
"orderVouchers": [
{
"orderVoucherId": "399bd3b3-9721-4f09-a936-d64637de1621",
"issuedVoucher":{
"issuedVoucherId": "a0996218-bc5e-4826-9020-cda98a32838d",
"voucherCode": "Voucher1234",
"purchasedProductId": 31,
"fromInclusive": "2025-03-22T08:55:00",
"untillInclusive": "2026-03-22T08:55:00"
},
"orderLineId": null
},
{
"orderVoucherId": "f6c7ac42-1811-4e4d-82af-53e18fe16110",
"issuedVoucher":{
"issuedVoucherId": "54668baf-4905-4e9a-af02-09c170f295ed",
"voucherCode": "Voucher124",
"purchasedProductId": 35,
"fromInclusive": "2025-03-22T08:55:00",
"untillInclusive": "2026-03-22T08:55:00"
},
"orderLineId": "7a7a9d1a-3fc8-4058-a28b-082860aaa311"
}
],
"orderLines": "orderLines":
[ [
{ {
@ -277,7 +324,7 @@ paths:
{ {
"orderCustomerAddressId": "aa50047c-58ac-4f15-9448-ee000dfc6893", "orderCustomerAddressId": "aa50047c-58ac-4f15-9448-ee000dfc6893",
"addressType": "addressType":
{ "addressTypeId": 3, "name": "Billing" }, { "addressTypeId": 2, "name": "Billing" },
"street": "Kon. Julianaplein", "street": "Kon. Julianaplein",
"houseNumber": 10, "houseNumber": 10,
"houseNumberSuffix": "a", "houseNumberSuffix": "a",
@ -327,19 +374,22 @@ paths:
"customerProfileId": 1337, "customerProfileId": 1337,
"totalAmount": 121, "totalAmount": 121,
"touchPointId": 1, "touchPointId": 1,
"deviceId": "b8ca9fdf-0bb9-4e49-b48d-41e395563377",
"languageId": 1, "languageId": 1,
"createdOn": "2024-03-22T09:00:00", "createdOn": "2024-03-22T09:00:00",
"order_OrderStatus": "order_OrderStatus":
[ [
{ {
"orderStatusId": 4, "orderStatusId": 1,
"createdOn": "2024-03-22T09:00:00",
"description": "Order succesvol betaald",
},
{
"orderStatusId": 3,
"createdOn": "2024-03-22T08:55:00", "createdOn": "2024-03-22T08:55:00",
"description": "Betaling in behandeling", "description": "Concept order",
},
],
"orderVouchers":
[
{
"issuedVoucherId": "e81b2197-a6c2-45b6-9560-8ce8442e8604",
"orderLineId": "97824d2e-5189-456d-b6da-4cca511a7685"
}, },
], ],
"orderLines": "orderLines":
@ -390,57 +440,6 @@ paths:
], ],
}, },
], ],
"payments":
[
{
"createdOn": "2024-03-22T09:00:00",
"amountDebit": 121,
"paymentMethodId": 1,
"touchPointId": 1,
"isRefund": false,
"htmPaymentReference": "HTM-1234",
"pspPaymentReference": "Buckaroo-1234",
"paymentStatuses":
[
{
"createdOn": "2024-03-22T09:00:00",
"statusCode": "190",
"statusDescription": "Success",
"statusSubCode": "S001",
"statusSubDescription": "PaymentSuccessFul",
},
],
"mandateInput":
{
"directDebitMandateTypeId": 1,
"createdOn": "2024-03-22T09:00:00",
"bic": "RABONL2U",
"iban": "NL44RABO0123456789",
"ascription": "J. de Vries",
"place": "Den Haag",
},
},
],
"orderCustomer":
{
"birthname": "Jan",
"surname": "Vries",
"prefix": "de",
"emailAddress": "jandevries@outlook.com",
"dateOfBirth": "1970-01-01",
"orderCustomerAddresses":
[
{
"addressTypeId": 1,
"street": "Kon. Julianaplein",
"houseNumber": 10,
"houseNumberSuffix": "a",
"postalCode": "2595 AA",
"city": "Den Haag",
"country": "NL",
},
],
},
} }
responses: responses:
"201": "201":
@ -487,6 +486,7 @@ paths:
"touchPointId": 1, "touchPointId": 1,
"name": "Perplex" "name": "Perplex"
}, },
"deviceId": null,
"language": "language":
{ {
"languageId": 1, "languageId": 1,
@ -512,6 +512,7 @@ paths:
"description": "Betaling in behandeling", "description": "Betaling in behandeling",
}, },
], ],
"orderVouchers": null,
"orderLines": "orderLines":
[ [
{ {
@ -634,7 +635,7 @@ paths:
{ {
"orderCustomerAddressId": "aa50047c-58ac-4f15-9448-ee000dfc6893", "orderCustomerAddressId": "aa50047c-58ac-4f15-9448-ee000dfc6893",
"addressType": "addressType":
{ "addressTypeId": 3, "name": "Billing" }, { "addressTypeId": 2, "name": "Billing" },
"street": "Kon. Julianaplein", "street": "Kon. Julianaplein",
"houseNumber": 10, "houseNumber": 10,
"houseNumberSuffix": "a", "houseNumberSuffix": "a",
@ -658,6 +659,7 @@ paths:
example: example:
{ {
"customerProfileId": 1337, "customerProfileId": 1337,
"deviceId": "fe68e624-b75f-48ca-a179-d5f86a8ab7d5",
"totalAmount": 121, "totalAmount": 121,
"languageId": 1, "languageId": 1,
"lastUpdatedOn": "2024-03-22T09:00:00", "lastUpdatedOn": "2024-03-22T09:00:00",
@ -678,6 +680,7 @@ paths:
responses: responses:
"200": "200":
description: OK description: OK
/orders/{orderId}/statuses: /orders/{orderId}/statuses:
parameters: parameters:
- in: path - in: path
@ -715,6 +718,143 @@ paths:
{ {
"order_orderStatusId": "b9cf0096-4211-4be6-ac21-7bc34bc8e066", "order_orderStatusId": "b9cf0096-4211-4be6-ac21-7bc34bc8e066",
} }
/orders/{orderId}/ordervouchers:
parameters:
- in: path
name: orderId
schema:
type: string
format: uuid
example: d1dd439b-6072-4b97-89c9-724268865b93
required: true
description: The id of the order to process.
post:
summary: Add an order voucher.
description: Add an order voucher.
tags:
- Order Voucher
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/unavailable"
example:
{
"issuedVoucherId": "eec6af41-1a60-49f6-a92e-440054a92f13",
"orderLineId": "7a9d6e15-7c5c-421d-9ea9-00b9bb6dbe67"
}
responses:
"201":
description: Created
content:
application/json:
schema:
$ref: "#/components/schemas/unavailable"
example:
{
"orderVoucherId": "b9cf0096-4211-4be6-ac21-7bc34bc8e066",
}
/ordervouchers:
parameters:
- in: query
name: orderVoucherId
schema:
type: string
format: uuid
example: d1dd439b-6072-4b97-89c9-724268865b93
required: false
description: The id of the orderVoucher you are looking for.
- in: query
name: orderId
schema:
type: string
example: 90c926b9-3178-4757-acca-34cff66b980c
required: false
description: The id of the order
- in: query
name: orderLineId
schema:
type: string
example: 9e3363c8-e776-4675-b108-99b8c2e38eb6
required: false
description: The id of the orderLine
get:
summary: Find vouchers on the order
description: Find vouchers on the order
tags:
- Order Voucher
responses:
"200":
description: OK
content:
application/json:
schema:
$ref: "#/components/schemas/unavailable"
example:
[
{
"orderVoucherId": "19ef6882-8eda-43bf-b48e-9b4ff8745a50",
"issuedVoucher":{
"issuedVoucherId": "54668baf-4905-4e9a-af02-09c170f295ed",
"voucherCode": "Voucher124",
"purchasedProductId": 35,
"fromInclusive": "2025-03-22T08:55:00",
"untillInclusive": "2026-03-22T08:55:00"
},
"orderId": "f59e4769-53a0-4156-8991-6f9119ba629f",
"orderLineId": "eeb86071-4f59-405d-b2be-7d7a77044bfa"
}
]
/ordervouchers/{ordervoucherId}:
parameters:
- in: path
name: ordervoucherId
schema:
type: string
format: uuid
example: d1dd439b-6072-4b97-89c9-724268865b93
required: true
description: The id of the order to process.
patch:
summary: Update an order voucher.
description: Update an order voucher.
tags:
- Order Voucher
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/unavailable"
example:
{
"issuedVoucherId": "eec6af41-1a60-49f6-a92e-440054a92f13",
"orderLineId": "7a9d6e15-7c5c-421d-9ea9-00b9bb6dbe67"
}
responses:
"200":
description: OK
content:
application/json:
schema:
$ref: "#/components/schemas/unavailable"
example:
{
"orderVoucherId": "b9cf0096-4211-4be6-ac21-7bc34bc8e066",
}
delete:
summary: Delete an order voucher.
description: Delete an order voucher.
tags:
- Order Voucher
responses:
"200":
description: OK
content:
application/json:
schema:
$ref: "#/components/schemas/unavailable"
example:
{}
/orders/{orderId}/orderlines: /orders/{orderId}/orderlines:
parameters: parameters:
- in: path - in: path
@ -820,7 +960,7 @@ paths:
application/json: application/json:
schema: schema:
$ref: "#/components/schemas/unavailable" $ref: "#/components/schemas/unavailable"
example: examples:
Minimum orderline requestBody: Minimum orderline requestBody:
value: value:
{ {
@ -906,7 +1046,7 @@ paths:
"orderCustomerAddresses": "orderCustomerAddresses":
[ [
{ {
"addressTypeId": 3, "addressTypeId": 2,
"street": "Kon. Julianaplein", "street": "Kon. Julianaplein",
"houseNumber": 10, "houseNumber": 10,
"houseNumberSuffix": "a", "houseNumberSuffix": "a",
@ -2187,7 +2327,7 @@ paths:
{ {
"orderCustomerAddressId": "aa50047c-58ac-4f15-9448-ee000dfc6893", "orderCustomerAddressId": "aa50047c-58ac-4f15-9448-ee000dfc6893",
"addressType": "addressType":
{ "addressTypeId": 3, "name": "Billing" }, { "addressTypeId": 2, "name": "Billing" },
"street": "Kon. Julianaplein", "street": "Kon. Julianaplein",
"houseNumber": 10, "houseNumber": 10,
"houseNumberSuffix": "a", "houseNumberSuffix": "a",
@ -2257,7 +2397,7 @@ paths:
$ref: "#/components/schemas/unavailable" $ref: "#/components/schemas/unavailable"
example: example:
{ {
"addressTypeId": 3, "addressTypeId": 2,
"street": "Kon. Julianaplein", "street": "Kon. Julianaplein",
"houseNumber": 10, "houseNumber": 10,
"houseNumberSuffix": "a", "houseNumberSuffix": "a",
@ -2307,7 +2447,7 @@ paths:
type: integer type: integer
explode: false explode: false
required: false required: false
description: Filter on possible types of addresses. 1 = Shipping, 3 = Billing. description: Filter on possible types of addresses. 1 = Shipping, 2 = Billing.
- in: query - in: query
name: street name: street
schema: schema:
@ -2363,7 +2503,7 @@ paths:
"orderCustomerAddressId": "aa50047c-58ac-4f15-9448-ee000dfc6893", "orderCustomerAddressId": "aa50047c-58ac-4f15-9448-ee000dfc6893",
"orderCustomerId": "540d8b7a-d626-443f-8f99-c24398604d7a", "orderCustomerId": "540d8b7a-d626-443f-8f99-c24398604d7a",
"orderId": "73cca95a-81d1-468f-a8bf-99b36367001a", "orderId": "73cca95a-81d1-468f-a8bf-99b36367001a",
"addressType": { "addressTypeId": 3, "name": "Billing" }, "addressType": { "addressTypeId": 2, "name": "Billing" },
"street": "Kon. Julianaplein", "street": "Kon. Julianaplein",
"houseNumber": 10, "houseNumber": 10,
"houseNumberSuffix": "a", "houseNumberSuffix": "a",

View File

@ -426,21 +426,18 @@ paths:
], ],
"orderAccountingStatuses": [], "orderAccountingStatuses": [],
"validationResult": "invalid", "validationResult": "invalid",
"validations": "additionalRemarks":
[ [
{ {
"code": "MANDATE_REQUIRED", "code": "MANDATE_REQUIRED",
"detail": "A valid mandate is required before purchasing this product.",
"path": null,
"parameter": "directDebitMandateId", "parameter": "directDebitMandateId",
"type": "REMARK",
}, },
],
"validationErrors":
[
{ {
"code": "STARTDATE_TOO_FAR_IN_FUTURE",
"detail": "Startdate of this product should be at most 60 days in the future.", "detail": "Startdate of this product should be at most 60 days in the future.",
"path": "$.orders[?(@.orderId=='1e441d7d-50d6-4006-aca7-5e87e2f218df')].orderLines[?(@.orderLineId=='cccada2c-d5ea-48ab-b4be-f590e16b5468')].validFrom", "pointer": "#/0/startDate",
"parameter": null,
"type": "ERROR",
}, },
], ],
}, },
@ -691,21 +688,18 @@ paths:
], ],
"orderAccountingStatuses": [], "orderAccountingStatuses": [],
"validationResult": "invalid", "validationResult": "invalid",
"validations": "additionalRemarks":
[ [
{ {
"code": "MANDATE_REQUIRED", "code": "MANDATE_REQUIRED",
"detail": "A valid mandate is required before purchasing this product.",
"path": null,
"parameter": "directDebitMandateId", "parameter": "directDebitMandateId",
"type": "REMARK",
}, },
],
"validationErrors":
[
{ {
"code": "STARTDATE_TOO_FAR_IN_FUTURE",
"detail": "Startdate of this product should be at most 60 days in the future.", "detail": "Startdate of this product should be at most 60 days in the future.",
"path": "$.orders[?(@.orderId=='1e441d7d-50d6-4006-aca7-5e87e2f218df')].orderLines[?(@.orderLineId=='cccada2c-d5ea-48ab-b4be-f590e16b5468')].validFrom", "pointer": "#/0/startDate",
"parameter": null,
"type": "ERROR",
}, },
], ],
}, },
@ -721,17 +715,23 @@ paths:
$ref: "#/components/schemas/unavailable" $ref: "#/components/schemas/unavailable"
example: example:
{ {
"type": "https://htm.nl/api/v1/probs/400/badrequest", "type": "https://htm.nl/api/v1/probs/validationerror",
"title": "Your request is not valid.", "title": "Your request is not valid.",
"detail": "One or more required attributes are missing or invalid.", "detail": "The combination of tokens and/or products chosen is not valid. See errors for more details.",
"instance": "urn:uuid:4017fabc-1b28-11e8-accf-0ed5f89f718b", "instance": "urn:uuid:4017fabc-1b28-11e8-accf-0ed5f89f718b",
"errors": "errors":
[ [
{ {
"code": "REQUIRED_ATTRIBUTE_MISSING", "detail": "Startdate of this product should be at most 60 days in the future.",
"detail": "One ore more required attributes are missing.", "pointer": "#/0/startDate",
"pointer": "$.orderLines[0].productId", "ovPayTokenId": 123,
"parameter": null, "productId": 2,
},
{
"detail": "Combination of product and token type is not valid.",
"pointer": "#/1/ovPayTokenId",
"ovPayTokenId": 123,
"productId": 3,
}, },
], ],
} }
@ -926,21 +926,18 @@ paths:
], ],
"orderAccountingStatuses": [], "orderAccountingStatuses": [],
"validationResult": "invalid", "validationResult": "invalid",
"validations": "additionalRemarks":
[ [
{ {
"code": "MANDATE_REQUIRED", "code": "MANDATE_REQUIRED",
"detail": "A valid mandate is required before purchasing this product.",
"path": null,
"parameter": "directDebitMandateId", "parameter": "directDebitMandateId",
"type": "REMARK",
}, },
],
"validationErrors":
[
{ {
"code": "STARTDATE_TOO_FAR_IN_FUTURE",
"detail": "Startdate of this product should be at most 60 days in the future.", "detail": "Startdate of this product should be at most 60 days in the future.",
"path": "$.orders[?(@.orderId=='1e441d7d-50d6-4006-aca7-5e87e2f218df')].orderLines[?(@.orderLineId=='cccada2c-d5ea-48ab-b4be-f590e16b5468')].validFrom", "pointer": "#/0/startDate",
"parameter": null,
"type": "ERROR",
}, },
], ],
}, },
@ -1121,21 +1118,18 @@ paths:
], ],
"orderAccountingStatuses": [], "orderAccountingStatuses": [],
"validationResult": "invalid", "validationResult": "invalid",
"validations": "additionalRemarks":
[ [
{ {
"code": "MANDATE_REQUIRED", "code": "MANDATE_REQUIRED",
"detail": "A valid mandate is required before purchasing this product.",
"path": null,
"parameter": "directDebitMandateId", "parameter": "directDebitMandateId",
"type": "REMARK",
}, },
],
"validationErrors":
[
{ {
"code": "STARTDATE_TOO_FAR_IN_FUTURE",
"detail": "Startdate of this product should be at most 60 days in the future.", "detail": "Startdate of this product should be at most 60 days in the future.",
"path": "$.orders[?(@.orderId=='1e441d7d-50d6-4006-aca7-5e87e2f218df')].orderLines[?(@.orderLineId=='cccada2c-d5ea-48ab-b4be-f590e16b5468')].validFrom", "pointer": "#/0/startDate",
"parameter": null,
"type": "ERROR",
}, },
], ],
}, },
@ -1254,7 +1248,8 @@ paths:
}, },
], ],
"validationResult": null, "validationResult": null,
"validations": [], "additionalRemarks": [],
"validationErrors": [],
}, },
], ],
"payments": "payments":
@ -1319,7 +1314,7 @@ paths:
{ {
"orderCustomerAddressId": "aa50047c-58ac-4f15-9448-ee000dfc6893", "orderCustomerAddressId": "aa50047c-58ac-4f15-9448-ee000dfc6893",
"addressType": "addressType":
{ "addressTypeId": 3, "name": "Billing" }, { "addressTypeId": 2, "name": "Billing" },
"street": "Kon. Julianaplein", "street": "Kon. Julianaplein",
"houseNumber": 10, "houseNumber": 10,
"houseNumberSuffix": "a", "houseNumberSuffix": "a",
@ -1533,21 +1528,18 @@ paths:
], ],
"orderAccountingStatuses": [], "orderAccountingStatuses": [],
"validationResult": "invalid", "validationResult": "invalid",
"validations": "additionalRemarks":
[ [
{ {
"code": "MANDATE_REQUIRED", "code": "MANDATE_REQUIRED",
"detail": "A valid mandate is required before purchasing this product.",
"path": null,
"parameter": "directDebitMandateId", "parameter": "directDebitMandateId",
"type": "REMARK",
}, },
],
"validationErrors":
[
{ {
"code": "STARTDATE_TOO_FAR_IN_FUTURE",
"detail": "Startdate of this product should be at most 60 days in the future.", "detail": "Startdate of this product should be at most 60 days in the future.",
"path": "$.orders[?(@.orderId=='1e441d7d-50d6-4006-aca7-5e87e2f218df')].orderLines[?(@.orderLineId=='cccada2c-d5ea-48ab-b4be-f590e16b5468')].validFrom", "pointer": "#/0/startDate",
"parameter": null,
"type": "ERROR",
}, },
], ],
}, },
@ -1563,17 +1555,23 @@ paths:
$ref: "#/components/schemas/unavailable" $ref: "#/components/schemas/unavailable"
example: example:
{ {
"type": "https://htm.nl/api/v1/probs/400/badrequest", "type": "https://htm.nl/api/v1/probs/validationerror",
"title": "Your request is not valid.", "title": "Your request is not valid.",
"detail": "One or more required attributes are missing or invalid.", "detail": "The combination of tokens and/or products chosen is not valid. See errors for more details.",
"instance": "urn:uuid:4017fabc-1b28-11e8-accf-0ed5f89f718b", "instance": "urn:uuid:4017fabc-1b28-11e8-accf-0ed5f89f718b",
"errors": "errors":
[ [
{ {
"code": "REQUIRED_ATTRIBUTE_MISSING", "detail": "Startdate of this product should be at most 60 days in the future.",
"detail": "One ore more required attributes are missing.", "pointer": "#/0/startDate",
"pointer": "$.orderLines[0].productId", "ovPayTokenId": 123,
"parameter": null, "productId": 2,
},
{
"detail": "Combination of product and token type is not valid.",
"pointer": "#/1/ovPayTokenId",
"ovPayTokenId": 123,
"productId": 3,
}, },
], ],
} }
@ -1593,7 +1591,7 @@ paths:
$ref: "#/components/schemas/unavailable" $ref: "#/components/schemas/unavailable"
example: example:
{ {
"type": "https://htm.nl/api/v1/probs/400/badrequest", "type": "https://htm.nl/api/v1/probs/validationerror",
"title": "Your request is not valid.", "title": "Your request is not valid.",
"detail": "The order can not be deleted.", "detail": "The order can not be deleted.",
"instance": "urn:uuid:4017fabc-1b28-11e8-accf-0ed5f89f718b", "instance": "urn:uuid:4017fabc-1b28-11e8-accf-0ed5f89f718b",
@ -1836,16 +1834,14 @@ paths:
], ],
"orderAccountingStatuses": [], "orderAccountingStatuses": [],
"validationResult": "preliminary", "validationResult": "preliminary",
"validations": "additionalRemarks":
[ [
{ {
"code": "PRODUCT_CHOICE_REQUIRED", "code": "PRODUCT_CHOICE_REQUIRED",
"detail": "The chosen product is not a leaf node product. Please choose one of its child products.", "parameter": "orderline.productId",
"path": "$.orders[?(@.orderId=='1e441d7d-50d6-4006-aca7-5e87e2f218df')].orderLines[?(@.orderLineId=='cccada2c-d5ea-48ab-b4be-f590e16b5468')].productId",
"parameter": null,
"type": "REMARK",
}, },
], ],
"validationErrors": [],
}, },
], ],
"payments": [], "payments": [],
@ -2012,30 +2008,22 @@ paths:
], ],
"orderAccountingStatuses": [], "orderAccountingStatuses": [],
"validationResult": "preliminary", "validationResult": "preliminary",
"validations": "additionalRemarks":
[ [
{ {
"code": "PERSONALACCOUNTDATA_BIRTHDATE_REQUIRED", "code": "PERSONALACCOUNTDATA_BIRTHDATE_REQUIRED",
"detail": "Personal account data birthdate is required for this product.", "parameter": "personalaccountdata.birthdate",
"path": "$.orders[?(@.orderId=='1e441d7d-50d6-4006-aca7-5e87e2f218df')].orderLines[?(@.orderLineId=='cccada2c-d5ea-48ab-b4be-f590e16b5468')].customerTokens[0].personalAccountData.birthdate",
"parameter": null,
"type": "REMARK",
}, },
{ {
"code": "TOKEN_REQUIRED", "code": "TOKEN_REQUIRED",
"detail": "A valid customer token is required before purchasing this product.",
"path": null,
"parameter": "customerToken", "parameter": "customerToken",
"type": "REMARK",
}, },
{ {
"code": "VALIDFROM_REQUIRED", "code": "VALIDFROM_REQUIRED",
"detail": "A valid 'valid from' date is required for this product.", "parameter": "orderline.validFrom",
"path": "$.orders[?(@.orderId=='1e441d7d-50d6-4006-aca7-5e87e2f218df')].orderLines[?(@.orderLineId=='cccada2c-d5ea-48ab-b4be-f590e16b5468')].validFrom",
"parameter": null,
"type": "REMARK",
}, },
], ],
"validationErrors": [],
}, },
], ],
"payments": [], "payments": [],
@ -2049,17 +2037,23 @@ paths:
$ref: "#/components/schemas/unavailable" $ref: "#/components/schemas/unavailable"
example: example:
{ {
"type": "https://htm.nl/api/v1/probs/400/badrequest", "type": "https://htm.nl/api/v1/probs/validationerror",
"title": "Your request is not valid.", "title": "Your request is not valid.",
"detail": "One or more required attributes are missing or invalid.", "detail": "The combination of tokens and/or products chosen is not valid. See errors for more details.",
"instance": "urn:uuid:4017fabc-1b28-11e8-accf-0ed5f89f718b", "instance": "urn:uuid:4017fabc-1b28-11e8-accf-0ed5f89f718b",
"errors": "errors":
[ [
{ {
"code": "REQUIRED_ATTRIBUTE_MISSING", "detail": "Startdate of this product should be at most 60 days in the future.",
"detail": "One ore more required attributes are missing.", "pointer": "#/0/startDate",
"pointer": "$.orderLines[0].productId", "ovPayTokenId": 123,
"parameter": null, "productId": 2,
},
{
"detail": "Combination of product and token type is not valid.",
"pointer": "#/1/ovPayTokenId",
"ovPayTokenId": 123,
"productId": 3,
}, },
], ],
} }
@ -2182,23 +2176,18 @@ paths:
"customerTokens": [], "customerTokens": [],
"orderAccountingStatuses": [], "orderAccountingStatuses": [],
"validationResult": "preliminary", "validationResult": "preliminary",
"validations": "additionalRemarks":
[ [
{ {
"code": "MANDATE_REQUIRED", "code": "MANDATE_REQUIRED",
"detail": "A valid mandate is required before purchasing this product.",
"path": null,
"parameter": "directDebitMandateId", "parameter": "directDebitMandateId",
"type": "REMARK",
}, },
{ {
"code": "CUSTOMERTOKEN_REQUIRED", "code": "CUSTOMERTOKEN_REQUIRED",
"detail": "A valid customer token is required before purchasing this product.",
"path": null,
"parameter": "customerTokenId", "parameter": "customerTokenId",
"type": "REMARK",
}, },
], ],
"validationErrors": [],
}, },
], ],
"payments": [], "payments": [],
@ -2212,17 +2201,17 @@ paths:
$ref: "#/components/schemas/unavailable" $ref: "#/components/schemas/unavailable"
example: example:
{ {
"type": "https://htm.nl/api/v1/probs/400/badrequest", "type": "https://htm.nl/api/v1/probs/validationerror",
"title": "Your request is not valid.", "title": "Your request is not valid.",
"detail": "One or more required attributes are missing or invalid.", "detail": "The start date of the product is not allowed. See errors for more details.",
"instance": "urn:uuid:4017fabc-1b28-11e8-accf-0ed5f89f718b", "instance": "urn:uuid:4017fabc-1b28-11e8-accf-0ed5f89f718b",
"errors": "errors":
[ [
{ {
"code": "REQUIRED_ATTRIBUTE_MISSING", "detail": "Startdate of this product should be at most 60 days in the future.",
"detail": "One ore more required attributes are missing.", "pointer": "#/0/startDate",
"pointer": "$.orderLines[0].productId", "ovPayTokenId": 123,
"parameter": null, "productId": 2,
}, },
], ],
} }
@ -2286,17 +2275,17 @@ paths:
$ref: "#/components/schemas/unavailable" $ref: "#/components/schemas/unavailable"
example: example:
{ {
"type": "https://htm.nl/api/v1/probs/400/badrequest", "type": "https://htm.nl/api/v1/probs/validationerror",
"title": "Your request is not valid.", "title": "Your request is not valid.",
"detail": "One or more required attributes are missing or invalid.", "detail": "The combination of tokens and/or products chosen is not valid. See errors for more details.",
"instance": "urn:uuid:4017fabc-1b28-11e8-accf-0ed5f89f718b", "instance": "urn:uuid:4017fabc-1b28-11e8-accf-0ed5f89f718b",
"errors": "errors":
[ [
{ {
"code": "REQUIRED_ATTRIBUTE_MISSING", "detail": "Product requires product with productId=2",
"detail": "One ore more required attributes are missing.", "pointer": "#/1/orderLine",
"pointer": "$.orderLines[0].productId", "orderLineId": "0574440e-7fa0-401f-b907-539c91633a5d",
"parameter": null, "productId": 3,
}, },
], ],
} }
@ -2517,16 +2506,14 @@ paths:
], ],
"orderAccountingStatuses": [], "orderAccountingStatuses": [],
"validationResult": "preliminary", "validationResult": "preliminary",
"validations": "additionalRemarks":
[ [
{ {
"code": "PERSONALACCOUNTDATA_BIRTHDATE_REQUIRED", "code": "PERSONALACCOUNTDATA_BIRTHDATE_REQUIRED",
"detail": "Personal account data birthdate is required for this product.", "parameter": "personalaccountdata.birthdate",
"path": "$.orders[?(@.orderId=='1e441d7d-50d6-4006-aca7-5e87e2f218df')].orderLines[?(@.orderLineId=='cccada2c-d5ea-48ab-b4be-f590e16b5468')].customerTokens[0].personalAccountData.birthdate",
"parameter": null,
"type": "REMARK",
}, },
], ],
"validationErrors": [],
}, },
], ],
"payments": [], "payments": [],
@ -2734,7 +2721,8 @@ paths:
], ],
"orderAccountingStatuses": [], "orderAccountingStatuses": [],
"validationResult": "valid", "validationResult": "valid",
"validations": [], "additionalRemarks": [],
"validationErrors": [],
}, },
], ],
"payments": [], "payments": [],
@ -2822,16 +2810,14 @@ paths:
"customerTokens": [], "customerTokens": [],
"orderAccountingStatuses": [], "orderAccountingStatuses": [],
"validationResult": "preliminary", "validationResult": "preliminary",
"validations": "additionalRemarks":
[ [
{ {
"code": "CUSTOMERTOKEN_REQUIRED", "code": "CUSTOMERTOKEN_REQUIRED",
"detail": "A valid customer token is required before purchasing this product.",
"path": null,
"parameter": "customerTokenId", "parameter": "customerTokenId",
"type": "REMARK",
}, },
], ],
"validationErrors": [],
}, },
], ],
"payments": [], "payments": [],
@ -3051,7 +3037,8 @@ paths:
], ],
"orderAccountingStatuses": [], "orderAccountingStatuses": [],
"validationResult": "valid", "validationResult": "valid",
"validations": [], "additionalRemarks": [],
"validationErrors": [],
}, },
], ],
"payments": [], "payments": [],
@ -3264,14 +3251,12 @@ paths:
], ],
"orderAccountingStatuses": [], "orderAccountingStatuses": [],
"validationResult": "invalid", "validationResult": "invalid",
"validations": "additionalRemarks": [],
"validationErrors":
[ [
{ {
"code": "PERSONAL_ACCOUNT_DATA_AGE_PROFILE_MISMATCH",
"detail": "Product is for gboAgeProfile 19-65, given gboAgeProfile is 12-19", "detail": "Product is for gboAgeProfile 19-65, given gboAgeProfile is 12-19",
"path": "$.orders[?(@.orderId=='1e441d7d-50d6-4006-aca7-5e87e2f218df')].orderLines[?(@.orderLineId=='cccada2c-d5ea-48ab-b4be-f590e16b5468')].customerTokens[?(@.customerTokenId=='878ad7c1-cd8f-4bcf-a983-1bd8c6e6975e')].ovPayToken.personalAccountData.birthdate", "pointer": "#/customerTokens/878ad7c1-cd8f-4bcf-a983-1bd8c6e6975e/personalAccountData/birthdate",
"parameter": null,
"type": "ERROR",
}, },
], ],
}, },
@ -3451,7 +3436,8 @@ paths:
], ],
"orderAccountingStatuses": [], "orderAccountingStatuses": [],
"validationResult": "valid", "validationResult": "valid",
"validations": [], "additionalRemarks": [],
"validationErrors": [],
}, },
], ],
"payments": [], "payments": [],
@ -3610,7 +3596,8 @@ paths:
], ],
"orderAccountingStatuses": [], "orderAccountingStatuses": [],
"validationResult": "valid", "validationResult": "valid",
"validations": [], "additionalRemarks": [],
"validationErrors": [],
}, },
{ {
"orderLineId": "2cb04b38-e9a8-465a-a273-261c55a21b71", "orderLineId": "2cb04b38-e9a8-465a-a273-261c55a21b71",
@ -3658,7 +3645,8 @@ paths:
], ],
"orderAccountingStatuses": [], "orderAccountingStatuses": [],
"validationResult": "valid", "validationResult": "valid",
"validations": [], "additionalRemarks": [],
"validationErrors": [],
}, },
], ],
"payments": "payments":
@ -3700,7 +3688,7 @@ paths:
{ {
"orderCustomerAddressId": "94270188-4cf6-447e-bd49-e8186bcec073", "orderCustomerAddressId": "94270188-4cf6-447e-bd49-e8186bcec073",
"addressType": "addressType":
{ "addressTypeId": 3, "name": "Billing" }, { "addressTypeId": 2, "name": "Billing" },
"street": "Kon. Julianaplein", "street": "Kon. Julianaplein",
"houseNumber": 10, "houseNumber": 10,
"houseNumberSuffix": "a", "houseNumberSuffix": "a",
@ -3895,7 +3883,8 @@ paths:
], ],
"orderAccountingStatuses": [], "orderAccountingStatuses": [],
"validationResult": "valid", "validationResult": "valid",
"validations": [], "additionalRemarks": [],
"validationErrors": [],
}, },
], ],
"payments": "payments":
@ -3976,7 +3965,7 @@ paths:
{ {
"orderCustomerAddressId": "94270188-4cf6-447e-bd49-e8186bcec073", "orderCustomerAddressId": "94270188-4cf6-447e-bd49-e8186bcec073",
"addressTypeId": "addressTypeId":
{ "addressTypeId": 3, "name": "Billing" }, { "addressTypeId": 2, "name": "Billing" },
"street": "Kon. Julianaplein", "street": "Kon. Julianaplein",
"houseNumber": 10, "houseNumber": 10,
"houseNumberSuffix": "a", "houseNumberSuffix": "a",
@ -4091,21 +4080,18 @@ paths:
}, },
], ],
"validationResult": "invalid", "validationResult": "invalid",
"validations": "additionalRemarks":
[ [
{ {
"code": "MANDATE_REQUIRED", "code": "MANDATE_REQUIRED",
"detail": "A valid mandate is required before purchasing this product.",
"path": null,
"parameter": "directDebitMandateId", "parameter": "directDebitMandateId",
"type": "REMARK",
}, },
],
"validationErrors":
[
{ {
"code": "STARTDATE_TOO_FAR_IN_FUTURE",
"detail": "Startdate of this product should be at most 60 days in the future.", "detail": "Startdate of this product should be at most 60 days in the future.",
"path": "$.orders[?(@.orderId=='1e441d7d-50d6-4006-aca7-5e87e2f218df')].orderLines[?(@.orderLineId=='cccada2c-d5ea-48ab-b4be-f590e16b5468')].validFrom", "pointer": "#/0/startDate",
"parameter": null,
"type": "ERROR",
}, },
], ],
}, },
@ -4188,7 +4174,7 @@ paths:
{ {
"orderCustomerAddressId": "94270188-4cf6-447e-bd49-e8186bcec073", "orderCustomerAddressId": "94270188-4cf6-447e-bd49-e8186bcec073",
"addressTypeId": "addressTypeId":
{ "addressTypeId": 3, "name": "Billing" }, { "addressTypeId": 2, "name": "Billing" },
"street": "Kon. Julianaplein", "street": "Kon. Julianaplein",
"houseNumber": 10, "houseNumber": 10,
"houseNumberSuffix": "a", "houseNumberSuffix": "a",
@ -4240,7 +4226,7 @@ paths:
"orderCustomerAddresses": "orderCustomerAddresses":
[ [
{ {
"addressTypeId": 3, "addressTypeId": 2,
"street": "Kon. Julianaplein", "street": "Kon. Julianaplein",
"houseNumber": 10, "houseNumber": 10,
"houseNumberSuffix": "a", "houseNumberSuffix": "a",
@ -4429,7 +4415,8 @@ paths:
], ],
"orderAccountingStatuses": [], "orderAccountingStatuses": [],
"validationResult": "valid", "validationResult": "valid",
"validations": [], "additionalRemarks": [],
"validationErrors": [],
}, },
], ],
"payments": [], "payments": [],
@ -4446,7 +4433,7 @@ paths:
{ {
"orderCustomerAddressId": "94270188-4cf6-447e-bd49-e8186bcec073", "orderCustomerAddressId": "94270188-4cf6-447e-bd49-e8186bcec073",
"addressType": "addressType":
{ "addressTypeId": 3, "name": "Billing" }, { "addressTypeId": 2, "name": "Billing" },
"street": "Kon. Julianaplein", "street": "Kon. Julianaplein",
"houseNumber": 10, "houseNumber": 10,
"houseNumberSuffix": "a", "houseNumberSuffix": "a",
@ -4675,7 +4662,8 @@ paths:
], ],
"orderAccountingStatuses": [], "orderAccountingStatuses": [],
"validationResult": "valid", "validationResult": "valid",
"validations": [], "additionalRemarks": [],
"validationErrors": [],
}, },
], ],
"payments": [], "payments": [],
@ -4692,7 +4680,7 @@ paths:
{ {
"orderCustomerAddressId": "94270188-4cf6-447e-bd49-e8186bcec073", "orderCustomerAddressId": "94270188-4cf6-447e-bd49-e8186bcec073",
"addressType": "addressType":
{ "addressTypeId": 3, "name": "Billing" }, { "addressTypeId": 2, "name": "Billing" },
"street": "Kon. Julianaplein", "street": "Kon. Julianaplein",
"houseNumber": 10, "houseNumber": 10,
"houseNumberSuffix": "a", "houseNumberSuffix": "a",
@ -4736,7 +4724,7 @@ paths:
description: Add an address to a customer on an order description: Add an address to a customer on an order
value: value:
{ {
"addressTypeId": 3, "addressTypeId": 2,
"street": "Kon. Julianaplein", "street": "Kon. Julianaplein",
"houseNumber": 10, "houseNumber": 10,
"houseNumberSuffix": "a", "houseNumberSuffix": "a",
@ -4923,16 +4911,14 @@ paths:
], ],
"orderAccountingStatuses": [], "orderAccountingStatuses": [],
"validationResult": "preliminary", "validationResult": "preliminary",
"validations": "additionalRemarks":
[ [
{ {
"code": "MANDATE_REQUIRED", "code": "MANDATE_REQUIRED",
"detail": "Direct debit mandate is required for this order.",
"path": null,
"parameter": "directDebitMandateId", "parameter": "directDebitMandateId",
"type": "REMARK",
}, },
], ],
"validationErrors": [],
}, },
], ],
"payments": [], "payments": [],
@ -4949,7 +4935,7 @@ paths:
{ {
"orderCustomerAddressId": "a0ef57fa-395c-4a03-96e9-234c26dccea9", "orderCustomerAddressId": "a0ef57fa-395c-4a03-96e9-234c26dccea9",
"addressType": "addressType":
{ "addressTypeId": 3, "name": "Billing" }, { "addressTypeId": 2, "name": "Billing" },
"street": "Kon. Julianaplein", "street": "Kon. Julianaplein",
"houseNumber": 10, "houseNumber": 10,
"houseNumberSuffix": "a", "houseNumberSuffix": "a",
@ -4993,7 +4979,7 @@ paths:
description: Update order customer address description: Update order customer address
value: value:
{ {
"addressTypeId": 3, "addressTypeId": 2,
"street": "Kon. Julianaplein", "street": "Kon. Julianaplein",
"houseNumber": 101, "houseNumber": 101,
"houseNumberSuffix": "a", "houseNumberSuffix": "a",
@ -5180,16 +5166,14 @@ paths:
], ],
"orderAccountingStatuses": [], "orderAccountingStatuses": [],
"validationResult": "preliminary", "validationResult": "preliminary",
"validations": "additionalRemarks":
[ [
{ {
"code": "MANDATE_REQUIRED", "code": "MANDATE_REQUIRED",
"detail": "A valid mandate is required before purchasing this product.",
"path": null,
"parameter": "directDebitMandateId", "parameter": "directDebitMandateId",
"type": "REMARK",
}, },
], ],
"validationErrors": [],
}, },
], ],
"payments": [], "payments": [],
@ -5206,7 +5190,7 @@ paths:
{ {
"orderCustomerAddressId": "94270188-4cf6-447e-bd49-e8186bcec073", "orderCustomerAddressId": "94270188-4cf6-447e-bd49-e8186bcec073",
"addressType": "addressType":
{ "addressTypeId": 3, "name": "Billing" }, { "addressTypeId": 2, "name": "Billing" },
"street": "Kon. Julianaplein", "street": "Kon. Julianaplein",
"houseNumber": 101, "houseNumber": 101,
"houseNumberSuffix": "a", "houseNumberSuffix": "a",
@ -5302,17 +5286,17 @@ paths:
$ref: "#/components/schemas/unavailable" $ref: "#/components/schemas/unavailable"
example: example:
{ {
"type": "https://htm.nl/api/v1/probs/400/badrequest", "type": "https://htm.nl/api/v1/probs/validationerror",
"title": "Your request is not valid.", "title": "Your request is not valid.",
"detail": "One or more required attributes are missing or invalid.", "detail": "The combination of tokens and/or products chosen is not valid. See errors for more details.",
"instance": "urn:uuid:4017fabc-1b28-11e8-accf-0ed5f89f718b", "instance": "urn:uuid:4017fabc-1b28-11e8-accf-0ed5f89f718b",
"errors": "errors":
[ [
{ {
"code": "REQUIRED_ATTRIBUTE_MISSING", "detail": "Product requires product with productId=2",
"detail": "One ore more required attributes are missing.", "pointer": "#/1/orderLine",
"pointer": "$.orderLines[0].productId", "orderLineId": "0574440e-7fa0-401f-b907-539c91633a5d",
"parameter": null, "productId": 3,
}, },
], ],
} }
@ -5426,37 +5410,21 @@ paths:
summary: Missing parameter(s) summary: Missing parameter(s)
value: value:
{ {
"type": "https://htm.nl/api/v1/probs/400/badrequest", "type": "https://www.htm.nl/api/v1/400Error",
"title": "Your request is not valid.", "title": "Missing parameter(s)",
"detail": "One or more required parameters are missing or invalid.", "detail": "At least one of the following parameters must be present: birthDate, ovPayTokenId, customerTokenId, (serviceReferenceId and amount), (ovpasNumber and verificationCode)",
"instance": "urn:uuid:4017fabc-1b28-11e8-accf-0ed5f89f718b", "instance": "urn:uuid:13c8416f-7632-4c8b-8a16-2132197be60c",
"errors": "apiErrorCode": "htm.api.err.400.2",
[
{
"code": "REQUIRED_PARAMETER_MISSING",
"detail": "One ore more required parameters are missing.",
"pointer": null,
"parameter": "birthdate, ovPayTokenId, customerTokenId",
},
],
} }
Invalid date format: Invalid date format:
summary: Invalid date format summary: Invalid date format
value: value:
{ {
"type": "https://htm.nl/api/v1/probs/400/badrequest", "type": "https://www.htm.nl/api/v1/400Error",
"title": "Your request is not valid.", "title": "Invalid input",
"detail": "One or more parameters have an invalid format.", "detail": "The given birthDate is not a valid Date format",
"instance": "urn:uuid:4017fabc-1b28-11e8-accf-0ed5f89f718b", "instance": "urn:uuid:13c8416f-7632-4c8b-8a16-2132197be60c",
"errors": "apiErrorCode": "htm.api.err.400.3",
[
{
"code": "INVALID_PARAMETER_FORMAT",
"detail": "The given birthdate is not a valid Date format.",
"pointer": null,
"parameter": "birthdate",
},
],
} }
"404": "404":
description: Not found description: Not found
@ -5469,19 +5437,11 @@ paths:
summary: No birthdate present in PAD of OVpay token summary: No birthdate present in PAD of OVpay token
value: value:
{ {
"type": "https://htm.nl/api/v1/probs/404/notfound", "type": "https://www.htm.nl/api/v1/404Error",
"title": "Missing birthdate in PAD.", "title": "Missing birthdate in PAD",
"detail": "There is no birthdate present in the PAD of the OVpay token, or there is no PAD present at all.", "detail": "There is no birthdate present in the PAD of the OVpay token, or there is no PAD present at all",
"instance": "urn:uuid:4017fabc-1b28-11e8-accf-0ed5f89f718b", "instance": "urn:uuid:13c8416f-7632-4c8b-8a16-2132197be60c",
"errors": "apiErrorCode": "htm.api.err.404.1",
[
{
"code": "MISSING_BIRTHDATE_IN_PAD",
"detail": "Missing birthdate in PAD.",
"pointer": null,
"parameter": "birthdate",
},
],
} }
components: components:
securitySchemes: securitySchemes:

View File

@ -0,0 +1,234 @@
openapi: 3.0.1
info:
title: Service Engine APIs for HTM voucher for sales Touchpint
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.
version: "1.0"
servers:
- url: https://services.acc.api.htm.nl/abt/abtvouchersTouchpoint/1.0
paths:
/issuedvouchers:
get:
summary: Get a list of issued vouchers that were issued for a specific touch point
description:
Retrieve all issued vouchers for a specific touch point. This means that only products that have active sellingPeriods for touch points within the same
retailer as the calling touch point are returned.
parameters:
- name: touchpointId
in: query
required: false
description: |
This endpoint is meant for salesTouchpoints to check the existance and validity of the voucher a customer has supplied
schema:
type: integer
example: 1001
- name: issuedVoucherId
in: query
required: false
description: The unique identifier of the issued voucher instance to retrieve.
schema:
type: string
format: uuid
example: d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90
- name: voucherCode
in: query
required: false
description: The unique code of the issued voucher to retrieve.
schema:
type: string
example: VOUCHER123
tags:
- Vouchers
responses:
"200":
description: Successful retrieval of voucher instance
content:
application/json:
schema:
$ref: "#/components/schemas/unavailable"
examples:
Voucher for a product with required attributes:
summary: Voucher for a single product with required attributes
value:
{
"issuedVouchers":
[
{
"issuedVoucherId": "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90",
"voucherCode": "VOUCHER123",
"fromInclusive": "2024-10-04T00:00:00.000",
"untilInclusive": "2024-11-04T00:00:00.000",
"voucherStatus":
{ "voucherStatusId": 1, "name": "New" },
"product":
{
"productId": 263,
"productName": "HTM-80001",
"productDescription": "10 euro korting op Regiovrij maand.",
"productCategory":
{
"productCategoryId": 9,
"isTravelProduct": false,
"name": "Voucher",
},
"amountInclTax": -1000,
"requiredProducts":
[
{
"productId": 126,
"productName": "HTM-30001",
"productDescription": "Regiovrij maand.",
"_links":
{
"get_details":
{
"href": "https://api.integratielaag.nl/abt/touchpoint/1.0/products/126",
"method": "GET",
},
},
},
],
"_links":
{
"get_details":
{
"href": "https://api.integratielaag.nl/abt/touchpoint/1.0/products/263",
"method": "GET",
},
},
},
"mandatoryCustomerDataItems":
[
{
"mandatoryCustomerDataItemId": 8,
"customerDataItem": "padBirthDate"
},
{
"mandatoryCustomerDataItemId": 4,
"customerDataItem": "emailAddress"
},
],
},
],
}
Voucher for a whole order:
summary: Voucher for a whole order
value:
{
"issuedVouchers":
[
{
"issuedVoucherId": "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90",
"voucherCode": "VOUCHER123",
"fromInclusive": "2024-10-04T00:00:00.000",
"untilInclusive": "2024-11-04T00:00:00.000",
"voucherStatus":
{ "voucherStatusId": 1, "name": "New" },
"product":
{
"productId": 263,
"productName": "HTM-80002",
"productDescription": "10 euro korting op je gehele winkelmand.",
"productCategory":
{
"productCategoryId": 9,
"isTravelProduct": false,
"name": "Voucher",
},
"amountInclTax": -1000,
"requiredProducts": [],
"_links":
{
"get_details":
{
"href": "https://api.integratielaag.nl/abt/touchpoint/1.0/products/263",
"method": "GET",
},
},
},
},
"mandatoryCustomerDataItems": [],
],
}
"403":
description: Forbidden
content:
application/problem+json:
schema:
$ref: "#/components/schemas/rfc9457"
examples:
Access denied due to insufficient permissions:
summary: Access denied due to insufficient permissions
value:
{
"type": "https://example.com/probs/forbidden",
"title": "Access denied",
"detail": "You do not have permission to access this resource.",
"instance": "/issuedvouchers",
}
"404":
description: Not found
content:
application/problem+json:
schema:
$ref: "#/components/schemas/rfc9457"
examples:
Voucher not found:
summary: Voucher not found
value:
{
"type": "https://example.com/probs/not-found",
"title": "Voucher not found",
"detail": "The voucher with code VOUCHER123 does not exist.",
"instance": "/issuedvouchers",
}
"500":
description: Internal server error
content:
application/problem+json:
schema:
$ref: "#/components/schemas/rfc9457"
examples:
Unexpected server error:
summary: Unexpected server error
value:
{
"type": "https://example.com/probs/internal-server-error",
"title": "Internal Server Error",
"detail": "An unexpected error occurred while processing your request.",
"instance": "/issuedvouchers",
}
components:
securitySchemes:
bearerToken:
type: http
scheme: bearer
bearerFormat: JWT
schemas:
unavailable:
type: object
rfc9457:
type: object
properties:
type:
type: string
format: url
example: https://example.com/probs/out-of-credit
title:
type: string
example: You do not have enough credit.
detail:
type: string
example: Your current balance is 30, but that costs 50.
instance:
type: string
example: /account/12345/msgs/abc
balance:
type: string
example: 30
accounts:
type: array
items:
type: string
example:
- /account/12345
- /account/67890

View File

@ -0,0 +1,617 @@
openapi: 3.0.1
info:
title: Service Engine APIs for HTM voucher suppliers
description: Service Engine APIs for HTM vouchers suppliers, this means all instances responsible for supplying vouchers. These are NOT the CRUD APIs to the data hub. These are ALSO NOT the api's for sales touchpoints.
version: "1.0"
servers:
- url: https://services.acc.api.htm.nl/abt/abtvouchers/1.0
paths:
/voucherdefinitions:
get:
tags:
- Vouchers
summary: Get a list of all voucher definitions that a touch point is allowed to issue
description: |-
Get a list of all voucher definitions that the calling touch point is allowed to issue.
Essentially, this means that only products that have active sellingPeriods for touch points within the same
retailer as the calling touch point are returned.
parameters:
- name: touchpointId
in: query
required: false
description: |
Filter the voucher definitions on a specific touch point id. This means that only voucher definitions with active selling periods for the specified touch point are returned.
This query parameter is only intended for administrative purposes, since the touch point associated with the access token used in the request is used to determine which voucher definitions are returned. This query parameter can be used to retrieve voucher definitions for other touch points within the same retailer, for example to retrieve voucher definitions for a specific sales touch point that is different from the calling touch point.
schema:
type: integer
example: 1001
- name: productId
in: query
required: false
description: Filter the voucher definitions on a specific product id.
schema:
type: integer
example: 263
- name: requiredProductId
in: query
required: false
description: Filter the voucher definitions on a specific required product id. This means that only voucher definitions that have the specified product id in their requiredProducts list are returned.
schema:
type: integer
example: 126
- name: showOnlyActive
in: query
required: false
description: Filter the voucher definitions on active selling periods. If true, only voucher definitions with at least one active selling period are returned. If false, all voucher definitions are returned regardless of their selling periods.
schema:
type: boolean
example: true
responses:
"200":
description: OK
content:
application/json:
schema:
$ref: "#/components/schemas/unavailable"
examples:
No products / Empty list:
summary: No products / Empty list
description: No products
value: { "voucherDefinitions": [] }
List containing one voucher definition (called by touchpointId 1001):
summary: List containing one voucher definition (called by touchpointId 10010011)
description: TODO
value:
{
"voucherDefinitions":
[
{
"productId": 1002,
"productName": "Korting Ooievaarspas",
"productDescription": "Kortingsvoucher voor houders van een Ooievaarspas",
"validityPeriod":
{
"validityPeriodId": 144,
"fromInclusive": "2023-12-31T23:00:00.000+00:00",
"toInclusive": "2028-11-25T04:00:00.000+00:00",
},
"productCategory":
{
"productCategoryId": 9,
"isTravelProduct": false,
"name": "Voucher",
},
"requiredProducts":
[
{
"productId": 126,
"productName": "HTM-30001",
"productDescription": "Reis met 20% korting op je betaalpas bij HTM.",
},
],
"mandatoryCustomerDataItems":
[
{
"mandatoryCustomerDataItemId": 8,
"customerDataItem": "padBirthDate",
},
{
"mandatoryCustomerDataItemId": 4,
"customerDataItem": "emailAddress",
},
],
"imageReference": "https://www.htm.nl/media/leif2leu/htm-logo-mobile.svg",
"productPageUrl": "https://www.htm.nl/nog-onbekende-product-pagina",
"sellingPeriods":
[
{
"sellingPeriodId": 78,
"fromInclusive": "2024-09-30T23:00:00.000+00:00",
"toInclusive": "2028-11-17T23:00:00.000+00:00",
"salesTouchpoint":
{
"salesTouchpointId": 1001,
"name": "Gemeente Den Haag",
"isActive": true,
"retailer":
{
"retailerId": 1001,
"name": "Gemeente Den Haag",
"street": "Koningin Julianaplein",
"number": "10",
"numberAddition": null,
"postalCode": "2595 AA",
"city": "Den Haag",
"country": "Nederland",
"emailAddress": "info@denhaag.nl",
"phoneNumber": "070 374 9002",
"taxId": "572309345923",
"imageReference": "https://www.htm.nl/media/leif2leu/htm-logo-mobile.svg",
},
},
"forbiddenPaymentMethods": [],
"sellingPrices":
[
{
"sellingPriceId": 78,
"amountExclTax": null,
"amountInclTax": -100,
"fromInclusive": "2024-09-30T23:00:00.000+00:00",
"toInclusive": "2028-11-17T23:00:00.000+00:00",
"internalPrice": 0.0000,
"taxCode": "V09",
"taxPercentage": 9.0000,
},
],
},
],
},
],
}
"403":
description: Forbidden
content:
application/problem+json:
schema:
$ref: "#/components/schemas/rfc9457"
examples:
Access denied due to insufficient permissions:
summary: Access denied due to insufficient permissions
value:
{
"type": "https://example.com/probs/forbidden",
"title": "Access denied",
"detail": "You do not have permission to access this resource.",
"instance": "/voucherdefinitions",
}
"404":
description: Not found
content:
application/problem+json:
schema:
$ref: "#/components/schemas/rfc9457"
examples:
Voucher not found:
summary: Voucher not found
value:
{
"type": "https://example.com/probs/not-found",
"title": "Voucher not found",
"detail": "The voucher definition does not exist.",
"instance": "/voucherdefinitions",
}
"500":
description: Internal server error
content:
application/problem+json:
schema:
$ref: "#/components/schemas/rfc9457"
examples:
Unexpected server error:
summary: Unexpected server error
value:
{
"type": "https://example.com/probs/internal-server-error",
"title": "Internal Server Error",
"detail": "An unexpected error occurred while processing your request.",
"instance": "/voucherdefinitions",
}
/issuedvouchers:
get:
summary: Get a list of issued vouchers that were issued for a specific touch point
description:
Retrieve all issued vouchers for a specific touch point. This means that only products that have active sellingPeriods for touch points within the same
retailer as the calling touch point are returned.
parameters:
- name: touchpointId
in: query
required: false
description: |
Filter the issued vouchers on a specific touch point id. This means that only issued vouchers for products with active selling periods for the specified touch point are returned.
This query parameter is only intended for administrative purposes, since the touch point associated with the access token used in the request is used to determine which issued vouchers are returned. This query parameter can be used to retrieve issued vouchers for other touch points within the same retailer, for example to retrieve issued vouchers for a specific sales touch point that is different from the calling touch point.
schema:
type: integer
example: 1001
- name: issuedVoucherId
in: query
required: false
description: The unique identifier of the issued voucher instance to retrieve.
schema:
type: string
format: uuid
example: d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90
- name: voucherCode
in: query
required: false
description: The unique code of the issued voucher to retrieve.
schema:
type: string
example: VOUCHER123
- name: productId
in: query
required: false
description: The unique identifier of the product for which to retrieve all issued vouchers.
schema:
type: integer
example: 263
- name: highestVoucherStatusId
in: query
required: false
explode: false
description: |-
The highest voucher status id to filter the issued vouchers on.
- 1 = new
- 2 = issued
- 3 = redeemed
- 4 = revoked
- 5 = expired
schema:
type: array
items:
type: integer
example: [1, 2]
tags:
- Vouchers
responses:
"200":
description: Successful retrieval of voucher instance
content:
application/json:
schema:
$ref: "#/components/schemas/unavailable"
examples:
Voucher for a product with required attributes:
summary: Voucher for a single product with required attributes
value:
{
"issuedVouchers":
[
{
"issuedVoucherId": "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90",
"voucherCode": "VOUCHER123",
"fromInclusive": "2024-10-04T00:00:00.000",
"untilInclusive": "2024-11-04T00:00:00.000",
"voucherStatus":
{ "voucherStatusId": 1, "name": "New" },
"product":
{
"productId": 263,
"productName": "HTM-80001",
"productDescription": "10 euro korting op Regiovrij maand.",
"productCategory":
{
"productCategoryId": 9,
"isTravelProduct": false,
"name": "Voucher",
},
"amountInclTax": -1000,
"requiredProducts":
[
{
"productId": 126,
"productName": "HTM-30001",
"productDescription": "Regiovrij maand.",
"_links":
{
"get_details":
{
"href": "https://api.integratielaag.nl/abt/touchpoint/1.0/products/126",
"method": "GET",
},
},
},
],
"_links":
{
"get_details":
{
"href": "https://api.integratielaag.nl/abt/touchpoint/1.0/products/263",
"method": "GET",
},
},
},
"claims":
[
{
"mandatoryCustomerDataItem":
{
"mandatoryCustomerDataItemId": 8,
"customerDataItem": "padBirthDate",
},
"value": "1980-06-31",
},
{
"mandatoryCustomerDataItem":
{
"mandatoryCustomerDataItemId": 4,
"customerDataItem": "emailAddress",
},
"value": "harry@griffindor.co.uk",
},
],
},
],
}
Voucher for a whole order:
summary: Voucher for a whole order
value:
{
"issuedVouchers":
[
{
"issuedVoucherId": "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90",
"voucherCode": "VOUCHER123",
"fromInclusive": "2024-10-04T00:00:00.000",
"untilInclusive": "2024-11-04T00:00:00.000",
"voucherStatus":
{ "voucherStatusId": 1, "name": "New" },
"product":
{
"productId": 263,
"productName": "HTM-80002",
"productDescription": "10 euro korting op je gehele winkelmand.",
"productCategory":
{
"productCategoryId": 9,
"isTravelProduct": false,
"name": "Voucher",
},
"amountInclTax": -1000,
"requiredProducts": [],
"_links":
{
"get_details":
{
"href": "https://api.integratielaag.nl/abt/touchpoint/1.0/products/263",
"method": "GET",
},
},
},
},
"claims": [],
],
}
"403":
description: Forbidden
content:
application/problem+json:
schema:
$ref: "#/components/schemas/rfc9457"
examples:
Access denied due to insufficient permissions:
summary: Access denied due to insufficient permissions
value:
{
"type": "https://example.com/probs/forbidden",
"title": "Access denied",
"detail": "You do not have permission to access this resource.",
"instance": "/issuedvouchers",
}
"404":
description: Not found
content:
application/problem+json:
schema:
$ref: "#/components/schemas/rfc9457"
examples:
Voucher not found:
summary: Voucher not found
value:
{
"type": "https://example.com/probs/not-found",
"title": "Voucher not found",
"detail": "The voucher with code VOUCHER123 does not exist.",
"instance": "/issuedvouchers",
}
"500":
description: Internal server error
content:
application/problem+json:
schema:
$ref: "#/components/schemas/rfc9457"
examples:
Unexpected server error:
summary: Unexpected server error
value:
{
"type": "https://example.com/probs/internal-server-error",
"title": "Internal Server Error",
"detail": "An unexpected error occurred while processing your request.",
"instance": "/issuedvouchers",
}
post:
summary: Issue a voucher for a specific product
description: |
Issue a voucher for a specific product. The voucher will be issued for the touch point that is associated with the access token used in the request.
The product for which the voucher should be issued must have active selling periods for touch points within the same retailer as the calling touch point.
tags:
- Vouchers
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/unavailable"
examples:
Issue a voucher with prefilled voucher code:
summary: Issue a voucher with prefilled voucher code
value:
{
"voucherCode": "VOUCHER123",
"fromInclusive": "2024-10-04T00:00:00.000",
"untilInclusive": "2024-11-04T00:00:00.000",
"productId": 263,
"voucherClaims":
[
{
"mandatoryCustomerDataItemId": 8,
"value": "1970-01-01",
},
{
"mandatoryCustomerDataItemId": 4,
"value": "stasjo@html.nl",
},
],
}
Issue a voucher without prefilled voucher code:
summary: Issue a voucher without prefilled voucher code
value:
{
"fromInclusive": "2024-10-04T00:00:00.000",
"untilInclusive": "2024-11-04T00:00:00.000",
"productId": 263,
"voucherClaims":
[
{
"mandatoryCustomerDataItemId": 8,
"value": "1970-01-01",
},
{
"mandatoryCustomerDataItemId": 4,
"value": "stasjo@html.nl",
},
],
}
responses:
"201":
description: Created
content:
application/json:
schema:
$ref: "#/components/schemas/unavailable"
examples:
Successfully issued a voucher:
summary: Successfully issued a voucher
value:
{
"issuedVoucherId": "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90",
"voucherCode": "HKV-A7J-128-PYT",
"fromInclusive": "2024-10-04T00:00:00.000",
"untilInclusive": "2024-11-04T00:00:00.000",
"voucherStatus": { "voucherStatusId": 1, "name": "New" },
"product":
{
"productId": 263,
"productName": "HTM-80002",
"productDescription": "10 euro korting op je gehele winkelmand.",
"productCategory":
{
"productCategoryId": 9,
"isTravelProduct": false,
"name": "Voucher",
},
"amountInclTax": -1000,
"requiredProducts": [],
"_links":
{
"get_details":
{
"href": "https://api.integratielaag.nl/abt/touchpoint/1.0/products/263",
"method": "GET",
},
},
},
}
/issuedvouchers/{issuedVoucherId}:
parameters:
- name: issuedVoucherId
in: path
required: true
description: The unique identifier of the issued voucher instance to update the status for.
schema:
type: string
format: uuid
example: d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90
patch:
summary: Update the status of an issued voucher
description: Update the status of an issued voucher. This can be used to mark a voucher as redeemed, revoked or expired.
tags:
- Vouchers
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/unavailable"
examples:
Mark a voucher as expired:
summary: Mark a voucher as expired
value:
{
"voucherStatusId": 5,
}
responses:
"200":
description: OK
content:
application/json:
schema:
$ref: "#/components/schemas/unavailable"
examples:
Successfully updated the status of a voucher:
summary: Successfully updated the status of a voucher
value:
{
"issuedVoucherId": "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90",
"voucherCode": "HKV-A7J-128-PYT",
"fromInclusive": "2024-10-04T00:00:00.000",
"untilInclusive": "2024-11-04T00:00:00.000",
"voucherStatus": { "voucherStatusId": 5, "name": "Expired" },
"product":
{
"productId": 263,
"productName": "HTM-80002",
"productDescription": "10 euro korting op je gehele winkelmand.",
"productCategory":
{
"productCategoryId": 9,
"isTravelProduct": false,
"name": "Voucher",
},
"amountInclTax": -1000,
"requiredProducts": [],
"_links":
{
"get_details":
{
"href": "https://api.integratielaag.nl/abt/touchpoint/1.0/products/263",
"method": "GET",
},
},
},
}
components:
securitySchemes:
bearerToken:
type: http
scheme: bearer
bearerFormat: JWT
schemas:
unavailable:
type: object
rfc9457:
type: object
properties:
type:
type: string
format: url
example: https://example.com/probs/out-of-credit
title:
type: string
example: You do not have enough credit.
detail:
type: string
example: Your current balance is 30, but that costs 50.
instance:
type: string
example: /account/12345/msgs/abc
balance:
type: string
example: 30
accounts:
type: array
items:
type: string
example:
- /account/12345
- /account/67890

View File

@ -243,143 +243,6 @@ paths:
], ],
"href": null, "href": null,
} }
post:
tags:
- Purchased Product
summary: Create a new purchased product.
description: Create a new purchased product.
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 TapConnet 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": null,
"ticketReference": "KJj43nejhbTxhr897287",
"createdOn": "2024-10-04T12:34:56.000",
"lastUpdatedOn": "2024-10-04T12:34:56.000",
"createdBy": "user",
"lastUpdatedBy": "user",
},
],
"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",
"voucherStatusInstances":
[
{
"voucherStatusId": 1,
"createdOn": "2024-10-04T12:34:56.000",
},
],
"voucherClaims":
[
{
"mandatoryCustomerDataItemId": 8,
"value": "1999-12-31",
},
{
"mandatoryCustomerDataItemId": 4,
"value": "vlad.harkonnen@househarkonnen.net",
},
],
},
],
}
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
@ -1146,6 +1009,8 @@ paths:
"value": "vlad.harkonnen@househarkonnen.net", "value": "vlad.harkonnen@househarkonnen.net",
}, },
], ],
"fromInclusive": "2024-10-04T12:34:56.000",
"untilInclusive": "2025-10-04T12:34:56.000",
} }
responses: responses:
"201": "201":
@ -1241,6 +1106,8 @@ paths:
"value": "vlad.harkonnen@househarkonnen.net", "value": "vlad.harkonnen@househarkonnen.net",
}, },
], ],
"fromInclusive": "2024-10-04T12:34:56.000",
"untilInclusive": "2025-10-04T12:34:56.000",
}, },
], ],
} }
@ -1311,6 +1178,56 @@ components:
schemas: schemas:
unavailable: unavailable:
type: object type: object
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:

View File

@ -0,0 +1,477 @@
openapi: 3.0.1
info:
title: TapConnect
description: >-
Welcome to the TapConnect Issuing API documentation. These pages describe the endpoints available within TapConnect. Please note that for historical reasons, Date/times are always in the "Europe/Amsterdam" timezone. The endpoints in this document are grouped as follows:
- **Export endpoints**: Export related endpoints return information about events related to tickets that have been issued. This can be used for Business Intelligence purposes or for financial record keeping.
- **Product endpoints**: Product related endpoints return information about products that are available to you as a sales partner and the details of each of these products.
- **Ticket endpoints**: Ticket related endpoints allow you to manage tickets throughout their lifecycle. This includes ticket creation, retrieving ticket information, or retrieving the barcode for a ticket.
- **Journey endpoints**: Used to calculate the price of a journey and to issue a ticket for that journey using the external fare calculation engine.
For more information on TapConnect please visit [https://tapconnect.io](https://tapconnect.io) or [https://documentation.tapconnect.io](https://documentation.tapconnect.io).
version: '1.0'
servers:
- url: https://services.acc.api.htm.nl/tapconnect/1.0
tags:
- name: Export
description: >-
Export data that can be used to generate reports about issued tickets
and related information
paths:
/v5/ticket-events-export:
get:
summary: Elastic Search ticket events export
description: "Exports ticket events data from Elastic Search.\n\nBoth parameters\
\ are a string, and they have to represent a date. Consider the list of valid\
\ formats below:\n1. 2021 - searches for all events in a year\n2. 2021-02\
\ - searches for all events in a month\n3. 2021-02-02 - searches for all events\
\ in a day\n4. 2021-02-02T12 - searches for all events in a specific hour\n\
5. 2021-02-02T12:00 - searches for all events in a specific minute\n6. 2021-02-02T12:00:00\
\ - searches for all events in a specific second\n\nIf an error occur, the\
\ last element returned will be a message with \"An error occurred on Elasticsearch\"\
\ and it \nmeans that not all the results are returned.\n_Keep in mind that\
\ the above timestamps would also be accepted as Zulu: 2021-02-02T11:00:00Z\
\ (winter time)_\n"
parameters:
- explode: true
in: query
name: start
required: true
description: The date to be considered as the interval starting date
schema:
example: 2021-02-01T00:00:00
type: string
style: form
- explode: true
in: query
name: end
required: true
description: The date to be considered as the interval ending date
schema:
example: 2021-02-02T00:00:00
type: string
style: form
responses:
"200":
content:
application/json:
schema:
$ref: '#/components/schemas/v5_ticket_events_export_response'
description: Returns a JSON chunked array of ticket events exported from elastic search.
"400":
description: |
The request could not be validated. The request body or parameters contain incomplete or incorrect parameters. The body of the response will contain information about the problem.
"401":
description: |
Unauthorized call, you are not authorized to call this endpoint with the api key provided in the Authorization header. Please verify that your api key is correct and/or if you are authorized to call this endpoint.
"403":
description: |
Unauthorized call, you are not authorized to call this endpoint with the api key provided in the Authorization header. Please verify that your api key is correct and/or if you are authorized to call this endpoint.
"404":
description: |
The requested URL does not exist, or the requested object was not found.
"406":
description: |
The request was not accepted by the server. The body of the response will contain information about the problem.
tags:
- Export
components:
schemas:
v5_ticket_events_export_response:
type: array
items:
anyOf:
- $ref: '#/components/schemas/ActivateTicketEvent'
- $ref: '#/components/schemas/CreateBarcodeEvent'
- $ref: '#/components/schemas/CreateTicketEvent'
- $ref: '#/components/schemas/TapEvent'
- $ref: '#/components/schemas/InspectTicketEvent'
- $ref: '#/components/schemas/NotifyEvent'
ActivateTicketEvent:
properties:
eventId:
example: 1
type: number
eventType:
example: ACTIVATE_TICKET
type: string
occurredAt:
example: 2021-06-07T08:42:00.791992000Z
type: string
receivedAt:
example: 2021-06-07T08:42:00.791992000Z
type: string
timeToDie:
example: 2445836980
type: number
operators:
items:
example: HTM
type: string
type: array
createdBy:
example: HTM
type: string
definedBy:
example: HTM
type: string
ticketId:
example: hkbu3415fbidswd803nfdg7
type: string
validityStart:
example: 2021-06-06T22:00:00.000000000Z
type: string
validityEnd:
example: 2021-06-07T23:40:00.000000000Z
type: string
validityType:
example: FIXED
type: string
CreateBarcodeEvent:
properties:
eventId:
example: 2
type: number
eventType:
example: CREATE_BARCODE
type: string
occurredAt:
example: 2021-06-07T08:42:01.629279000Z
type: string
receivedAt:
example: 2021-06-07T08:42:01.629279000Z
type: string
timeToDie:
example: 2445836980
type: number
operators:
items:
example: HTM
type: string
type: array
createdBy:
example: HTM
type: string
definedBy:
example: HTM
type: string
ticketId:
example: 2huCpR99LHjGfiq8ZJoF
type: string
barcodeSignatureKeyId:
example: TCT07
type: string
barcodeValidityStart:
example: 2021-06-06T22:00:00.000000000Z
type: string
barcodeValidityEnd:
example: 2021-06-07T23:40:00.000000000Z
type: string
CreateTicketEvent:
properties:
eventId:
example: 0
type: number
eventType:
example: CREATE_TICKET
type: string
occurredAt:
example: 2021-06-07T08:42:00.790992000Z
type: string
receivedAt:
example: 2021-06-07T08:42:00.790992000Z
type: string
reportedAt:
example: 2021-06-07T08:42:00.790992000Z
type: string
timeToDie:
example: 2445836980
type: number
operators:
items:
example: HTM
type: string
type: array
createdBy:
example: HTM
type: string
definedBy:
example: HTM
type: string
ticketId:
example: 344BEuHcFkEChOPm06sY
type: string
serviceId:
example: HTM-0987-7477-0993
type: string
productName:
example: HTM Kinder Dagkaart
type: string
productCode:
example: "303"
type: string
productValidityPeriodUnit:
example: "DAYS"
type: string
productValidityPeriod:
example: 1
type: number
lifespanStart:
example: 2021-06-07
type: string
lifespanEnd:
example: 2021-06-08
type: string
language:
example: NL
type: string
salesChannelId:
example: "9999"
type: string
salesChannelName:
example: HTM App
type: string
startStation:
example: Haarlem
type: string
endStation:
example: Leiden Centraal
type: string
barcodeType:
example: UIC
type: string
validityType:
example: FIXED
type: string
refundable:
example: true
type: boolean
priceInCents:
example: 150,
type: number
numberOfAdults:
example: 1
type: number
numberOfChildren:
example: 0
type: number
roundToBusinessDay:
example: true
type: boolean
modalities:
example: ["BUS", "TRAM"]
type: array
items:
example: BUS
type: string
TapEvent:
properties:
eventId:
example: 5
type: number
eventType:
example: TAP
type: string
occurredAt:
example: 2021-06-07T08:42:00.790992000Z
type: string
receivedAt:
example: 2021-06-07T08:42:00.790992000Z
type: string
timeToDie:
example: 2445836980
type: number
validationAction:
example: CHECK_OUT
type: string
validationResult:
example: Approved
type: string
tapId:
example: a9aea0ae-52de-42cd-a2f1-93b80d9af389
type: string
operators:
items:
example: HTM
type: string
type: array
createdBy:
example: HTM
type: string
definedBy:
example: HTM
type: string
ticketId:
example: hkbu3415fbidswd803nfdg7
type: string
modality:
example: BUS
type: string
line:
example: "25"
type: string
trip:
example: "240"
type: string
vehicle:
example: "1512"
type: string
deviceId:
example: "13513A"
type: string
deviceType:
example: VBS
type: string
lastStopId:
example: "3409"
type: string
lastStopName:
example: Gramsbergenlaan
type: string
nextStopId:
example: "3409"
type: string
nextStopName:
example: Gramsbergenlaan
type: string
location:
type: object
properties:
lat:
example: 52.00089453333333
type: number
lon:
example: 4.004570666666667
type: number
InspectTicketEvent:
properties:
eventId:
example: 3
type: number
eventType:
example: INSPECT_TICKET
type: string
occurredAt:
example: 2021-06-07T08:42:00.790992000Z
type: string
receivedAt:
example: 2021-06-07T08:42:00.790992000Z
type: string
timeToDie:
example: 2445836980
type: number
operators:
items:
example: HTM
type: string
type: array
createdBy:
example: HTM
type: string
definedBy:
example: HTM
type: string
ticketId:
example: uv1hzvrRd7Xd1Fs9vTxi
type: string
modality:
example: BUS
type: string
deviceId:
example: 6959bd00eaec8e68
type: string
deviceType:
example: IBS
type: string
validationResult:
example: Approved
type: string
NotifyEvent:
properties:
eventId:
example: 1185
type: number
eventType:
example: NOTIFY
type: string
occurredAt:
example: 2021-06-07T08:42:00.790992000Z
type: string
receivedAt:
example: 2021-06-07T08:42:00.790992000Z
type: string
timeToDie:
example: 2445836980
type: number
tapId:
example: a9aea0ae-52de-42cd-a2f1-93b80d9af389
type: string
sequence:
example: 2
type: number
tapResponseTimeMillis:
example: 402
type: number
validationAction:
example: CHECK_OUT
type: string
validationMethod:
example: ONLINE
type: string
validationResult:
example: Approved
type: string
operators:
items:
example: HTM
type: string
type: array
createdBy:
example: HTM
type: string
definedBy:
example: HTM
type: string
modality:
example: TRAM
type: string
line:
example: "3"
type: string
trip:
example: "692"
type: string
vehicle:
example: "4058"
type: string
deviceId:
example: "13A886"
type: string
deviceType:
example: VBS
type: string
lastStopId:
example: "2005"
type: string
lastStopName:
example: Fahrenheitstraat
type: string
nextStopId:
example: "2011"
type: string
nextStopName:
example: Valkenbosplein
type: string
ticketId:
example: hkbu3415fbidswd803nfdg7
type: string
location:
type: object
properties:
lat:
example: 52.001300283333336
type: number
lon:
example: 4.004586633333333
type: number