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.iso; 020 021import java.util.Objects; 022 023/** 024 * Implements a parser for card's service code as per ISO/IEC 7813:2006(E). 025 * 026 * @version $Revision$ $Date$ 027 */ 028public class ServiceCode { 029 030 final private char[] value; 031 032 /** 033 * Creates a ServiceCode instance. 034 * 035 * @param value Three-digit service code value. 036 */ 037 public ServiceCode(String value) { 038 039 Objects.requireNonNull(value); 040 041 if (!value.matches("^\\d{3}$")) { 042 throw new IllegalArgumentException("Invalid service code."); 043 } 044 045 this.value = value.toCharArray(); 046 } 047 048 /** 049 * Indicates whether the first digit signals private interchange (digit 7). 050 * 051 * @return {@code true} if the first digit is {@code '7'} 052 */ 053 public boolean isPrivate() { 054 return value[0] == '7'; 055 } 056 057 /** 058 * Indicates whether the first digit signals test (digit 9). 059 * 060 * @return {@code true} if the first digit is {@code '9'} 061 */ 062 public boolean isTest() { 063 return value[0] == '9'; 064 } 065 066 /** 067 * Indicates whether the first digit signals an ICC-capable card (digits 2, 6). 068 * 069 * @return {@code true} if the first digit is {@code '2'} or {@code '6'} 070 */ 071 public boolean isICC() { 072 return value[0] == '2' || value[0] == '6'; 073 } 074 075 /** 076 * Indicates whether the first digit signals international interchange (digits 1, 2). 077 * 078 * @return {@code true} if the first digit is {@code '1'} or {@code '2'} 079 */ 080 public boolean isInternational() { 081 return value[0] == '1' || value[0] == '2'; 082 } 083 084 /** 085 * Indicates whether the first digit signals national interchange (digits 5, 6). 086 * 087 * @return {@code true} if the first digit is {@code '5'} or {@code '6'} 088 */ 089 public boolean isNational() { 090 return value[0] == '5' || value[0] == '6'; 091 } 092 093 /** 094 * Indicates whether the third digit allows transactions with no restrictions (digits 0, 1, 6). 095 * 096 * @return {@code true} when no service restrictions apply 097 */ 098 public boolean hasNoRestrictions() { 099 return value[2] == '0' || value[2] == '1' || value[2] == '6'; 100 } 101 102 /** 103 * Indicates whether the third digit restricts use to goods and services (digits 2, 5, 7). 104 * 105 * @return {@code true} for goods-and-services-only service codes 106 */ 107 public boolean isGoodsAndServicesOnly() { 108 return value[2] == '2' || value[2] == '5' || value[2] == '7'; 109 } 110 111 /** 112 * Indicates whether the third digit restricts use to ATMs (digit 3). 113 * 114 * @return {@code true} for ATM-only service codes 115 */ 116 public boolean isATMOnly() { 117 return value[2] == '3'; 118 } 119 120 /** 121 * Indicates whether the third digit restricts use to cash transactions (digit 4). 122 * 123 * @return {@code true} for cash-only service codes 124 */ 125 public boolean isCashOnly() { 126 return value[2] == '4'; 127 } 128 129 /** 130 * Indicates whether a PIN is required for transactions with this service code. 131 * 132 * @return {@code true} when the third digit is {@code '0'}, {@code '3'}, or {@code '5'} 133 */ 134 public boolean isPINRequired() { 135 return value[2] == '0' || value[2] == '3' || value[2] == '5'; 136 } 137 138 /** 139 * Indicates whether the cardholder must be prompted for a PIN when a PED is available. 140 * 141 * @return {@code true} when the third digit is {@code '6'} or {@code '7'} 142 */ 143 public boolean mustPromptForPINIfPEDPresent() { 144 return value[2] == '6' || value[2] == '7'; 145 } 146 147 /** 148 * Indicates whether the second digit signals normal authorization processing (digit 0). 149 * 150 * @return {@code true} for normal authorization 151 */ 152 public boolean isNormalAuthorization() { 153 return value[1] == '0'; 154 } 155 156 /** 157 * Indicates whether the second digit signals issuer authorization is required (digit 2). 158 * 159 * @return {@code true} when issuer authorization is required 160 */ 161 public boolean isIssuerAuthorization() { 162 return value[1] == '2'; 163 } 164}