1+ package com .adyen .model .nexo ;
2+
3+ import java .io .UnsupportedEncodingException ;
4+ import java .net .URLDecoder ;
5+ import java .nio .charset .StandardCharsets ;
6+ import java .util .Collections ;
7+ import java .util .LinkedHashMap ;
8+ import java .util .Map ;
9+ import java .util .Optional ;
10+
11+ /**
12+ * A helper class to parse and manage the key-value pairs within a PredefinedContent referenceID string.
13+ * The referenceID is expected to be in a URL query string format (e.g., {@code key1=value1&key2=value2}).
14+ */
15+ public final class PredefinedContentHelper {
16+
17+ private static final String KEY_EVENT = "event" ;
18+ private static final String KEY_TRANSACTION_ID = "TransactionID" ;
19+ private static final String KEY_TIME_STAMP = "TimeStamp" ;
20+
21+ /**
22+ * Defines the supported events for display notifications within a PredefinedContent reference ID.
23+ */
24+ public enum DisplayNotificationEvent {
25+ TENDER_CREATED ,
26+ CARD_INSERTED ,
27+ CARD_PRESENTED ,
28+ CARD_SWIPED ,
29+ WAIT_FOR_APP_SELECTION ,
30+ APPLICATION_SELECTED ,
31+ ASK_SIGNATURE ,
32+ CHECK_SIGNATURE ,
33+ SIGNATURE_CHECKED ,
34+ WAIT_FOR_PIN ,
35+ PIN_ENTERED ,
36+ PRINT_RECEIPT ,
37+ RECEIPT_PRINTED ,
38+ CARD_REMOVED ,
39+ TENDER_FINAL ,
40+ ASK_DCC ,
41+ DCC_ACCEPTED ,
42+ DCC_REJECTED ,
43+ ASK_GRATUITY ,
44+ GRATUITY_ENTERED ,
45+ BALANCE_QUERY_STARTED ,
46+ BALANCE_QUERY_COMPLETED ,
47+ LOAD_STARTED ,
48+ LOAD_COMPLETED ,
49+ PROVIDE_CARD_DETAILS ,
50+ CARD_DETAILS_PROVIDED
51+ }
52+
53+ private final Map <String , String > params ;
54+
55+ /**
56+ * Constructs a helper instance by parsing the provided reference ID.
57+ *
58+ * @param referenceId The string from {@link PredefinedContent#getReferenceID()},
59+ * expected to be in URL query string format.
60+ */
61+ public PredefinedContentHelper (String referenceId ) {
62+ this .params = parse (referenceId );
63+ }
64+
65+ /**
66+ * Extracts and validates the 'event' value from the reference ID.
67+ *
68+ * @return An {@link Optional} containing the {@link DisplayNotificationEvent} if it is present and valid,
69+ * otherwise an empty Optional.
70+ * <pre>{@code
71+ * PredefinedContentHelper helper = new PredefinedContentHelper("...&event=PIN_ENTERED");
72+ * helper.getEvent().ifPresent(event -> System.out.println(event)); // Prints PIN_ENTERED
73+ * }</pre>
74+ */
75+ public Optional <DisplayNotificationEvent > getEvent () {
76+ return get (KEY_EVENT ).flatMap (eventValue -> {
77+ try {
78+ return Optional .of (DisplayNotificationEvent .valueOf (eventValue ));
79+ } catch (IllegalArgumentException e ) {
80+ return Optional .empty (); // The event string is not a valid enum constant
81+ }
82+ });
83+ }
84+
85+ /**
86+ * Gets the transaction ID from the reference ID.
87+ *
88+ * @return An {@link Optional} containing the TransactionID, or an empty Optional if not present.
89+ */
90+ public Optional <String > getTransactionId () {
91+ return get (KEY_TRANSACTION_ID );
92+ }
93+
94+ /**
95+ * Gets the timestamp from the reference ID.
96+ *
97+ * @return An {@link Optional} containing the TimeStamp, or an empty Optional if not present.
98+ */
99+ public Optional <String > getTimeStamp () {
100+ return get (KEY_TIME_STAMP );
101+ }
102+
103+ /**
104+ * Gets the value for a given key from the reference ID.
105+ *
106+ * @param key The name of the parameter to retrieve.
107+ * @return An {@link Optional} containing the parameter's value, or an empty Optional if not present.
108+ */
109+ public Optional <String > get (String key ) {
110+ return Optional .ofNullable (params .get (key ));
111+ }
112+
113+ /**
114+ * Returns an unmodifiable view of all parsed parameters.
115+ *
116+ * @return An unmodifiable {@link Map} of all key-value pairs from the reference ID.
117+ */
118+ public Map <String , String > toMap () {
119+ return Collections .unmodifiableMap (params );
120+ }
121+
122+ /**
123+ * Parses a URL query-like string into a map.
124+ *
125+ * @param referenceId The string to parse.
126+ * @return A map of the parsed key-value pairs.
127+ */
128+ private static Map <String , String > parse (String referenceId ) {
129+ if (referenceId == null || referenceId .trim ().isEmpty ()) {
130+ return Collections .emptyMap ();
131+ }
132+
133+ Map <String , String > queryPairs = new LinkedHashMap <>();
134+ String [] pairs = referenceId .split ("&" );
135+ for (String pair : pairs ) {
136+ int idx = pair .indexOf ("=" );
137+ if (idx > 0 && idx < pair .length () - 1 ) {
138+ String key = URLDecoder .decode (pair .substring (0 , idx ), StandardCharsets .UTF_8 );
139+ String value = URLDecoder .decode (pair .substring (idx + 1 ), StandardCharsets .UTF_8 );
140+ queryPairs .put (key , value );
141+ }
142+ }
143+ return queryPairs ;
144+ }
145+ }
0 commit comments