001/*
002 * jPOS Project [http://jpos.org]
003 * Copyright (C) 2000-2026 jPOS Software SRL
004 *
005 * This program is free software: you can redistribute it and/or modify
006 * it under the terms of the GNU Affero General Public License as
007 * published by the Free Software Foundation, either version 3 of the
008 * License, or (at your option) any later version.
009 *
010 * This program is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
013 * GNU Affero General Public License for more details.
014 *
015 * You should have received a copy of the GNU Affero General Public License
016 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
017 */
018
019package org.jpos.rc;
020
021import java.util.HashMap;
022import java.util.Map;
023
024public enum CMF implements IRC {
025    // Approved
026    APPROVED         (0, true),
027    HONOR_WITH_ID    (1, true),
028    APPROVED_PARTIAL (2, true),
029    APPROVED_VIP     (3, true),
030    APPROVED_UPDATE_TRACK3 (4, true),
031    APPROVED_ISSUER_SPECIFIED_ACCOUNT (5, true),
032    APPROVED_PARTIAL_ISSUER_SPECIFIED_ACCOUNT (6, true),
033    APPROVED_FEES_DISPUTED(8, true),
034    APPROVED_WITH_OVERDRAFT(9, true),
035    APPROVED_CUSTOMER_REACTIVATED(10, true),
036    APPROVED_TERMINAL_UNABLE_TO_PROCESS_ONLINE(11),
037    APPROVED_OFFLINE (12),
038    APPROVED_OFFLINE_REFERRAL (13),
039
040    // Denied Authorization
041    DO_NOT_HONOUR(1000),
042    EXPIRED (1001),
043    SUSPECTED_FRAUD(1002),
044    CONTACT_ACQUIRER(1003),
045    RESTRICTED_CARD(1004),
046    CONTACT_ACQUIRER_SECURITY(1005),
047    MAX_PIN_TRIES_EXCEEDED(1006),
048    REFER_TO_ISSUER(1007),
049    REFER_TO_ISSUER_SPECIAL(1008),
050    INVALID_CARD_ACCEPTOR(1009),
051    INVALID_AMOUNT(1010),
052    INVALID_CARD_NUMBER(1011),
053    PIN_DATA_REQUIRED(1012),
054    UNACCEPTABLE_FEE(1013),
055    NO_ACCOUNT_TYPE(1014),
056    UNSUPPORTED_FUNCTION(1015),
057    NOT_SUFFICIENT_FUNDS(1016),
058    INCORRECT_PIN(1017),
059    NO_CARD_RECORD(1018),
060    NOT_PERMITTED_TO_CARDHOLDER(1019),
061    NOT_PERMITTED_TO_TERMINAL(1020),
062    EXCEEDS_WITHDRAWAL_AMOUNT_LIMIT(1021),
063    SECURITY_VIOLATION(1022),
064    EXCEEDS_WITHDRAWAL_FREQUENCY_LIMIT(1023),
065    LAW_VIOLATION(1024),
066    CARD_NOT_EFFECTIVE(1025),
067    INVALID_PINBLOCK(1026),
068    PIN_LENGTH_ERROR(1027),
069    PIN_KEY_SYNC_ERROR(1028),
070    SUSPECTED_COUNTERFEIT_CARD_DONT_PICKUP(1029),
071    UNACCEPTED_CURRENCY(1030),
072    DECLINED_FEES_DISPUTED(1031),
073    LOST_OR_STOLEN_CARD(1032),
074    AUTHORIZATION_LIFECYCLE_UNACCEPTABLE(1033),
075    AUTHORIZATION_LIFECYCLE_EXPIRED(1034),
076    CLOSED_ACCOUNT(1035),
077    CLOSED_SAVINGS_ACCOUNT(1036),
078    CLOSED_CREDIT_ACCOUNT(1037),
079    CLOSED_ACCOUNT_TYPE(1038),
080    CLOSED_CHEQUE_ACCOUNT(1039),
081    BAD_DEBT(1040),
082    FROM_ACCOUNT_BAD_STATUS(1041),
083    TO_ACCOUNT_BAD_STATUS(1042),
084    CHEQUE_ALREADY_POSTED(1043),
085    INFORMATION_NOT_ON_FILE(1044),
086    CARD_VERIFICATION_DATA_FAILED(1045),
087    AMOUNT_NOT_FOUND(1046),
088    PIN_CHANGE_REQUIRED(1047),
089    NEW_PIN_INVALID(1048),
090    BANK_NOT_FOUND(1049),
091    BANK_NOT_EFFECTIVE(1050),
092    CUSTOMER_VENDOR_NOT_FOUND(1051),
093    CUSTOMER_VENDOR_NOT_EFFECTIVE(1052),
094    CUSTOMER_VENDOR_ACCOUNT_INVALID(1053),
095    VENDOR_NOT_FOUND(1054),
096    VENDOR_NOT_EFFECTIVE(1055),
097    VENDOR_DATA_INVALID(1056),
098    PAYMENT_DATE_INVALID(1057),
099    PERSONAL_ID_NOT_FOUND(1058),
100    SCHEDULED_TRANSACTION_EXISTS(1059),
101    ABORTED_AT_TERMINAL(1060),
102    UNSUPPORTED_TRANSACTION(1061),
103    CASHBACK_NOT_ALLOWED(1062),
104    CASHBACK_AMOUNT_EXCEEDED(1063),
105    DECLINED_PROCESSED_OFFLINE(1064),
106    DECLINED_UNABLE_TO_PROCESS(1065),
107    DECLINED_PROCESSED_OFFLINE_REFERRAL(1066),
108    ID_NUMBER_INVALID(1068),
109    DRIVER_NUMBER_INVALID(1069),
110    VID_INVALID(1070),
111    CERTIFICATE_EXPIRED(1071),
112    MISSING_FIELD(1802),
113    EXTRA_FIELD(1803),
114    INVALID_CARD(1804),
115    CARD_NOT_ACTIVE(1806),
116    CARD_NOT_CONFIGURED(1808),
117    SYSTEM_ERROR_DB(1811, false, true),
118    SYSTEM_ERROR_TXN(1812,false, true),
119    CONFIGURATION_ERROR(1818),
120
121    INVALID_TERMINAL(1819),
122    INACTIVE_TERMINAL(1820),
123    INVALID_MERCHANT(1821),
124    DUPLICATE_ENTITY(1822),
125    INVALID_ACQUIRER(1823),
126
127    INVALID_FIELD(1830),
128    MISCONFIGURED_ENDPOINT(1831),
129    INVALID_REQUEST(1832),
130    HOST_UNREACHABLE(1833),
131
132
133    // Denied Financial
134    FINANCIAL_DO_NOT_HONOUR (2000),
135    FINANCIAL_EXPIRED (2001),
136    FINANCIAL_SUSPECTED_FRAUD(2002),
137    FINANCIAL_CONTACT_ACQUIRER(2003),
138    FINANCIAL_RESTRICTED_CARD(2004),
139    FINANCIAL_CONTACT_ACQUIRER_SECURITY(2005),
140    FINANCIAL_MAX_PIN_TRIES_EXCEEDED(2006),
141    SPECIAL_CONDITIONS(2007),
142    LOST_CARD(2008),
143    STOLEN_CARD(2009),
144    SUSPECTED_COUNTERFEIT_CARD_PICKUP(2010),
145    MAX_DAILY_WITHDRAWAL(2011),
146    MAX_DAILY_AMOUNT(2012),
147
148    // File action
149    SUCCESSFUL(3000, true),
150    NOT_SUPPORTED_BY_RECEIVER(3001),
151    UNABLE_TO_LOCATE_RECORD(3002),
152    UPDATED_RECORD(3003),
153    FIELD_EDIT_ERROR(3004),
154    FILE_LOCKED_OUT(3005),
155    NOT_SUCCESSFUL(3006),
156    FORMAT_ERROR(3007),
157    DUPLICATE(3008),
158    UNKNOWN_FILE(3009),
159    INVALID_CARD_OR_CARDHOLDER_NUMBER(3010),
160
161    // Reversals
162    REVERSAL_ACCEPTED(4000, true),
163
164    // Reconciliation
165    RECONCILED_IN_BALANCE(5000, true),
166    RECONCILED_OUT_OF_BALANCE(5001),
167    AMOUNT_NOT_RECONCILED_TOTALS_PROVIDED(5002),
168    TOTALS_NOT_AVAILABLE(5003),
169    NOT_RECONCILED_TOTALS_PROVIDED(5004),
170
171    // Administrative messages
172    ADMIN_MESSAGE_ACCEPTED(6000, true),
173
174    // Fee collection
175    FEE_COLLECTION_ACCEPTED (7000, true),
176
177    // Network Management
178    NET_ACCEPTED (8000, true),
179    NET_RETRY(8001),
180
181    // Misc
182    ADVICE_ACK_NO_FINANCIAL(9000, true),
183    ADVICE_ACCEPTED(9001, true),
184    MESSAGE_ERROR(9100),
185    INVALID_TRANSACTION(9102),
186    RETRY_TRANSACTION(9103),
187    ACQUIRER_NOT_SUPPORTED(9105),
188    CUTOVER_IN_PROCESS(9106),
189    ISSUER_NOT_AVAILABLE(9107),
190    ROUTING_ERROR(9108),
191    SYSTEM_ERROR(9109),
192    ISSUER_SIGNED_OFF(9110),
193    ISSUER_TIMEOUT(9111),
194    ISSUER_UNAVAILABLE(9112),
195    DUPLICATE_TRANSMISSION(9113),
196    ORIGINAL_NOT_FOUND(9114),
197    RECONCILIATION_ERROR(9115),
198    MAC_INCORRECT(9116),
199    MAC_KEY_SYNC_ERROR(9117),
200    ZMK_NOT_AVAILABLE(9118),
201    CRYPTO_ERROR(9119),
202    HSM_ERROR_RETRY(9120),
203    HSM_ERROR (9121),
204    OUT_OF_SEQUENCE(9122),
205    REQUEST_IN_PROGRESS(9123),
206    INVALID_SECURITY_CODE(9124),
207    DATABASE_ERROR(9125),
208    CUSTOMER_VENDOR_FORMAT_ERROR(9128),
209    RECURRING_DATA_ERROR(9132),
210    UPDATE_NOT_ALLOWED(9133),
211    AGREEMENT_VIOLATION(9350),
212
213    GENERAL_DECLINE(9999),
214
215    // jPOS specific result codes
216    JPOS(10000),
217    INTERNAL_ERROR(19999,false,true),
218
219    // User specific result codes
220    USER(90000);
221
222    private final int irc;
223    private final String ircStr;
224
225    private final boolean success;
226    private final boolean inhibit;
227
228    private static final Map<Integer,IRC> lookupInt = new HashMap<>();
229    private static final Map<String,IRC>  lookupStr = new HashMap<>();
230    static {
231        // This section executes after all the enum instances have been constructed
232        for (IRC irc : values()) {
233            lookupInt.put(irc.irc(), irc);
234            lookupStr.put(irc.ircString(), irc);
235        }
236    }
237
238    CMF(int irc) {
239        this (irc, false, false);
240    }
241    CMF(int irc, boolean success) {
242        this(irc, success, false);
243    }
244    CMF(int irc, boolean success, boolean inhibit) {
245        this.irc = irc;
246        this.ircStr = String.format("%04d", irc);
247        this.success = success;
248        this.inhibit = inhibit;
249    }
250
251    @Override
252    public int irc() {
253        return irc;
254    }
255
256    @Override
257    public String ircString() {
258        return ircStr;
259    }
260
261    @Override
262    public boolean success() {
263        return success;
264    }
265
266    @Override
267    public boolean inhibit() {
268        return inhibit;
269    }
270
271    public static IRC valueOf(int i) {
272        return lookupInt.get(i);
273    }
274
275    /**
276     * Returns the {@code CMF} instance that has the given String as its jPOS-CMF Result Code
277     * (usually transmitted in DE-39).
278     *
279     * @param irc a String representing a jPOS-CMF Result Code
280     * @return the corresponding CMF instance or {@code null}
281     */
282    public static CMF fromIsoString(String irc) {
283        return (irc == null) ? null : (CMF)lookupStr.get(irc.trim());
284    }
285}