Case Study 2: Credit Card Authorization System

Background

Coastal Federal Bank (CFB) issues approximately 2.8 million credit cards across its consumer, business, and premium product lines. Every time a cardholder presents their card at a merchant terminal, an authorization request travels from the point-of-sale device through the payment network to CFB's mainframe authorization engine -- a COBOL program called CCAUTH that must return a decision within 250 milliseconds.

The authorization engine is the bank's single most critical real-time system. A false decline frustrates the cardholder and costs the bank interchange revenue. A false approval exposes the bank to fraud losses. In 2023, CFB processed an average of 3.4 million authorization requests per day, approving 94.2% and declining 5.8%.

In early 2024, CFB's fraud analytics team identified a gap in the authorization engine: the existing logic used simple threshold checks for fraud detection but did not combine multiple risk factors into a single decision. The team requested an enhancement to implement multi-factor authorization -- a system that evaluates card status, available credit, transaction velocity, merchant category, and fraud risk indicators simultaneously, using compound conditions and multi-dimensional decision logic.

Priya Venkatesh, a senior COBOL developer with 11 years of experience in payment systems, was assigned to redesign the authorization decision engine. This case study examines her implementation, which demonstrates EVALUATE for transaction routing, nested IF for multi-factor checks, 88-level conditions for card and transaction states, and complex compound conditions for authorization rules.

The Business Requirements

The authorization engine must evaluate each incoming transaction against six sequential checks:

  1. Card Status Check -- Is the card active? Cards that are blocked, stolen, lost, or frozen must be declined immediately.
  2. Available Credit Check -- Does the cardholder have sufficient available credit for the transaction amount?
  3. Transaction Velocity Check -- Has this card been used an abnormal number of times in the last 24 hours?
  4. Merchant Category Check -- Is the merchant category code (MCC) restricted for this card product?
  5. Fraud Score Check -- Does the real-time fraud scoring model flag this transaction as suspicious?
  6. Multi-Factor Risk Assessment -- Combining transaction amount, geographic location, and fraud score into a final risk determination.

Each check can produce one of three outcomes: - PASS -- The transaction clears this check and proceeds to the next - FLAG -- The transaction is marked for post-authorization review but continues - FAIL -- The transaction is immediately declined with a specific response code

The Complete Program

       IDENTIFICATION DIVISION.
       PROGRAM-ID. CCAUTH.
      *================================================================*
      * Program:     CCAUTH
      * Description: Credit Card Multi-Factor Authorization Engine
      * Author:      Priya Venkatesh
      * Date:        2024-04-10
      * Purpose:     Demonstrates conditional logic patterns for
      *              real-time credit card authorization at
      *              Coastal Federal Bank.
      *================================================================*

       DATA DIVISION.
       WORKING-STORAGE SECTION.

      *================================================================*
      * PROGRAM CONSTANTS                                              *
      *================================================================*
       01  WS-C-VELOCITY-LIMITS.
           05  WS-C-MAX-DAILY-TXN    PIC 9(03)  VALUE 025.
           05  WS-C-MAX-HOURLY-TXN   PIC 9(02)  VALUE 008.
           05  WS-C-HIGH-VALUE-LIMIT  PIC 9(07)V99
               VALUE 5000.00.
           05  WS-C-VERY-HIGH-VALUE   PIC 9(07)V99
               VALUE 10000.00.

       01  WS-C-FRAUD-THRESHOLDS.
           05  WS-C-FRAUD-LOW-MAX     PIC 9(03) VALUE 030.
           05  WS-C-FRAUD-MED-MAX     PIC 9(03) VALUE 060.
           05  WS-C-FRAUD-HIGH-MAX    PIC 9(03) VALUE 080.

       01  WS-C-REPORT-SEP            PIC X(65) VALUE ALL '='.
       01  WS-C-DETAIL-SEP            PIC X(65) VALUE ALL '-'.

      *================================================================*
      * PROCESSING FLAGS                                               *
      *================================================================*
       01  WS-F-CONTINUE-FLAG         PIC X(01) VALUE 'Y'.
           88  WS-CONTINUE-PROCESSING            VALUE 'Y'.
           88  WS-STOP-PROCESSING                VALUE 'N'.

       01  WS-F-REVIEW-FLAG           PIC X(01) VALUE 'N'.
           88  WS-NEEDS-REVIEW                   VALUE 'Y'.
           88  WS-NO-REVIEW-NEEDED               VALUE 'N'.

       01  WS-F-FLAG-COUNT            PIC 9(02) VALUE ZERO.

      *================================================================*
      * AUTHORIZATION RESULT                                           *
      *================================================================*
       01  WS-AUTH-RESULT.
           05  WS-AUTH-RESPONSE-CODE  PIC X(02) VALUE SPACES.
               88  AUTH-APPROVED                 VALUE '00'.
               88  AUTH-APPROVED-REVIEW          VALUE '01'.
               88  AUTH-CALL-CENTER              VALUE '02'.
               88  AUTH-DECLINED-CREDIT          VALUE '51'.
               88  AUTH-DECLINED-CARD            VALUE '05'.
               88  AUTH-DECLINED-STOLEN          VALUE '43'.
               88  AUTH-DECLINED-LOST            VALUE '41'.
               88  AUTH-DECLINED-FROZEN          VALUE '62'.
               88  AUTH-DECLINED-VELOCITY        VALUE '65'.
               88  AUTH-DECLINED-FRAUD           VALUE '59'.
               88  AUTH-DECLINED-MCC             VALUE '57'.
               88  AUTH-SYSTEM-ERROR             VALUE '96'.
           05  WS-AUTH-MESSAGE        PIC X(50) VALUE SPACES.
           05  WS-AUTH-RISK-LEVEL     PIC X(01) VALUE SPACE.
               88  RISK-LOW                      VALUE 'L'.
               88  RISK-MEDIUM                   VALUE 'M'.
               88  RISK-HIGH                     VALUE 'H'.
               88  RISK-CRITICAL                 VALUE 'C'.
           05  WS-AUTH-FLAGS-RAISED   PIC 9(02) VALUE ZERO.

      *================================================================*
      * CARD INFORMATION (from card master file)                       *
      *================================================================*
       01  WS-CARD-INFO.
           05  WS-CARD-NUMBER         PIC X(16).
           05  WS-CARD-STATUS         PIC X(01).
               88  CARD-ACTIVE                   VALUE 'A'.
               88  CARD-BLOCKED                  VALUE 'B'.
               88  CARD-STOLEN                   VALUE 'S'.
               88  CARD-LOST                     VALUE 'L'.
               88  CARD-FROZEN                   VALUE 'Z'.
               88  CARD-EXPIRED                  VALUE 'E'.
               88  CARD-USABLE                   VALUE 'A'.
               88  CARD-COMPROMISED              VALUE 'S' 'L'.
               88  CARD-INACTIVE
                   VALUE 'B' 'S' 'L' 'Z' 'E'.
           05  WS-CARD-PRODUCT        PIC X(02).
               88  PRODUCT-STANDARD              VALUE 'ST'.
               88  PRODUCT-GOLD                  VALUE 'GD'.
               88  PRODUCT-PLATINUM              VALUE 'PT'.
               88  PRODUCT-BUSINESS              VALUE 'BZ'.
               88  PRODUCT-PREMIUM
                   VALUE 'GD' 'PT'.
           05  WS-CREDIT-LIMIT        PIC 9(07)V99.
           05  WS-CURRENT-BALANCE     PIC 9(07)V99.
           05  WS-AVAILABLE-CREDIT    PIC S9(07)V99.
           05  WS-DAILY-TXN-COUNT     PIC 9(03).
           05  WS-HOURLY-TXN-COUNT    PIC 9(02).
           05  WS-CARDHOLDER-NAME     PIC X(25).

      *================================================================*
      * TRANSACTION INFORMATION (from authorization request)           *
      *================================================================*
       01  WS-TXN-INFO.
           05  WS-TXN-AMOUNT          PIC 9(07)V99.
           05  WS-TXN-MERCHANT-NAME   PIC X(25).
           05  WS-TXN-MCC             PIC X(04).
               88  MCC-GAMBLING
                   VALUE '7800' '7801' '7802' '7995'.
               88  MCC-CASH-ADVANCE
                   VALUE '6010' '6011' '6012'.
               88  MCC-WIRE-TRANSFER
                   VALUE '4829'.
               88  MCC-CRYPTO
                   VALUE '6051'.
               88  MCC-HIGH-RISK-MCC
                   VALUE '7800' '7801' '7802' '7995'
                         '6010' '6011' '6012'
                         '4829' '6051'.
               88  MCC-RETAIL
                   VALUE '5200' THRU '5499'
                         '5500' THRU '5699'
                         '5700' THRU '5799'.
               88  MCC-GROCERY
                   VALUE '5411' '5422' '5441' '5451'.
               88  MCC-RESTAURANT
                   VALUE '5812' '5813' '5814'.
           05  WS-TXN-COUNTRY         PIC X(03).
               88  TXN-DOMESTIC                  VALUE 'USA'.
               88  TXN-CANADA                    VALUE 'CAN'.
               88  TXN-ALLIED-COUNTRY
                   VALUE 'USA' 'CAN' 'GBR' 'AUS'.
               88  TXN-HIGH-RISK-COUNTRY
                   VALUE 'NGA' 'ROU' 'UKR' 'RUS' 'BRA'.
               88  TXN-CROSS-BORDER              VALUE
                   'CAN' 'GBR' 'AUS' 'FRA' 'DEU'
                   'JPN' 'NGA' 'ROU' 'UKR' 'RUS' 'BRA'
                   'MEX' 'IND' 'CHN' 'KOR'.
           05  WS-TXN-ENTRY-MODE      PIC X(02).
               88  ENTRY-CHIP                    VALUE 'CP'.
               88  ENTRY-CONTACTLESS             VALUE 'CL'.
               88  ENTRY-SWIPE                   VALUE 'SW'.
               88  ENTRY-MANUAL                  VALUE 'MN'.
               88  ENTRY-ECOMMERCE               VALUE 'EC'.
               88  ENTRY-CARD-PRESENT
                   VALUE 'CP' 'CL' 'SW'.
               88  ENTRY-CARD-NOT-PRESENT
                   VALUE 'MN' 'EC'.
           05  WS-TXN-FRAUD-SCORE     PIC 9(03).
               88  FRAUD-LOW-RISK    VALUE 000 THRU 030.
               88  FRAUD-MED-RISK    VALUE 031 THRU 060.
               88  FRAUD-HIGH-RISK   VALUE 061 THRU 080.
               88  FRAUD-CRITICAL    VALUE 081 THRU 100.
               88  FRAUD-ACCEPTABLE  VALUE 000 THRU 060.

      *================================================================*
      * MCC RESTRICTION TABLE (by product)                             *
      *================================================================*
       01  WS-MCC-RESTRICTIONS.
           05  WS-STANDARD-RESTRICTED PIC X(01) VALUE 'Y'.
               88  STD-HAS-MCC-LIMITS            VALUE 'Y'.
           05  WS-BUSINESS-RESTRICTED PIC X(01) VALUE 'N'.
               88  BIZ-NO-MCC-LIMITS             VALUE 'N'.

      *================================================================*
      * DISPLAY FIELDS                                                 *
      *================================================================*
       01  WS-DSP-AMOUNT              PIC $$$,$$$,$$9.99.
       01  WS-DSP-SCORE               PIC ZZ9.
       01  WS-DSP-COUNT               PIC ZZ9.

      *--- Test data counter ---
       01  WS-TEST-TXN-NUMBER         PIC 9(01) VALUE ZERO.

       PROCEDURE DIVISION.
       0000-MAIN-CONTROL.
           PERFORM 1000-INITIALIZATION
           PERFORM 2000-PROCESS-TRANSACTIONS
           STOP RUN
           .

      *================================================================*
      * 1000-INITIALIZATION                                            *
      *================================================================*
       1000-INITIALIZATION.
           DISPLAY WS-C-REPORT-SEP
           DISPLAY '  COASTAL FEDERAL BANK'
           DISPLAY '  CREDIT CARD AUTHORIZATION ENGINE'
           DISPLAY WS-C-REPORT-SEP
           DISPLAY SPACES
           .

      *================================================================*
      * 2000-PROCESS-TRANSACTIONS: Run authorization for test cases    *
      *================================================================*
       2000-PROCESS-TRANSACTIONS.
      *    Transaction 1: Normal domestic retail purchase
           PERFORM 2010-CLEAR-AUTH
           PERFORM 2100-LOAD-TXN-1
           PERFORM 3000-AUTHORIZE-TRANSACTION
           PERFORM 4000-DISPLAY-RESULT

      *    Transaction 2: Cross-border high-value from compromised
      *                   card
           PERFORM 2010-CLEAR-AUTH
           PERFORM 2100-LOAD-TXN-2
           PERFORM 3000-AUTHORIZE-TRANSACTION
           PERFORM 4000-DISPLAY-RESULT

      *    Transaction 3: E-commerce gambling purchase with high
      *                   fraud score
           PERFORM 2010-CLEAR-AUTH
           PERFORM 2100-LOAD-TXN-3
           PERFORM 3000-AUTHORIZE-TRANSACTION
           PERFORM 4000-DISPLAY-RESULT

      *    Transaction 4: Normal restaurant purchase, velocity alert
           PERFORM 2010-CLEAR-AUTH
           PERFORM 2100-LOAD-TXN-4
           PERFORM 3000-AUTHORIZE-TRANSACTION
           PERFORM 4000-DISPLAY-RESULT

      *    Transaction 5: Large cross-border purchase, medium fraud
           PERFORM 2010-CLEAR-AUTH
           PERFORM 2100-LOAD-TXN-5
           PERFORM 3000-AUTHORIZE-TRANSACTION
           PERFORM 4000-DISPLAY-RESULT
           .

      *================================================================*
      * 2010-CLEAR-AUTH: Reset authorization fields                    *
      *================================================================*
       2010-CLEAR-AUTH.
           INITIALIZE WS-AUTH-RESULT
           INITIALIZE WS-CARD-INFO
           INITIALIZE WS-TXN-INFO
           SET WS-CONTINUE-PROCESSING TO TRUE
           SET WS-NO-REVIEW-NEEDED    TO TRUE
           MOVE ZERO TO WS-F-FLAG-COUNT
           .

      *================================================================*
      * LOAD TEST TRANSACTION 1: Normal domestic retail                *
      *================================================================*
       2100-LOAD-TXN-1.
           MOVE '4532100098761234' TO WS-CARD-NUMBER
           SET  CARD-ACTIVE       TO TRUE
           SET  PRODUCT-GOLD      TO TRUE
           MOVE 10000.00          TO WS-CREDIT-LIMIT
           MOVE 03200.00          TO WS-CURRENT-BALANCE
           MOVE 06800.00          TO WS-AVAILABLE-CREDIT
           MOVE 003               TO WS-DAILY-TXN-COUNT
           MOVE 001               TO WS-HOURLY-TXN-COUNT
           MOVE 'SMITH, JENNIFER L.'  TO WS-CARDHOLDER-NAME

           MOVE 00125.50          TO WS-TXN-AMOUNT
           MOVE 'TARGET STORE #4521'  TO WS-TXN-MERCHANT-NAME
           MOVE '5311'            TO WS-TXN-MCC
           SET  TXN-DOMESTIC      TO TRUE
           SET  ENTRY-CHIP        TO TRUE
           MOVE 012               TO WS-TXN-FRAUD-SCORE
           .

      *================================================================*
      * LOAD TEST TRANSACTION 2: Stolen card, cross-border             *
      *================================================================*
       2100-LOAD-TXN-2.
           MOVE '4532100098769876' TO WS-CARD-NUMBER
           SET  CARD-STOLEN       TO TRUE
           SET  PRODUCT-STANDARD  TO TRUE
           MOVE 05000.00          TO WS-CREDIT-LIMIT
           MOVE 01200.00          TO WS-CURRENT-BALANCE
           MOVE 03800.00          TO WS-AVAILABLE-CREDIT
           MOVE 012               TO WS-DAILY-TXN-COUNT
           MOVE 006               TO WS-HOURLY-TXN-COUNT
           MOVE 'JONES, MARK R.'      TO WS-CARDHOLDER-NAME

           MOVE 02500.00          TO WS-TXN-AMOUNT
           MOVE 'ELECTRONICS SHOP'    TO WS-TXN-MERCHANT-NAME
           MOVE '5732'            TO WS-TXN-MCC
           MOVE 'ROU'             TO WS-TXN-COUNTRY
           SET  ENTRY-ECOMMERCE   TO TRUE
           MOVE 085               TO WS-TXN-FRAUD-SCORE
           .

      *================================================================*
      * LOAD TEST TRANSACTION 3: E-commerce gambling, high fraud       *
      *================================================================*
       2100-LOAD-TXN-3.
           MOVE '4532100098765555' TO WS-CARD-NUMBER
           SET  CARD-ACTIVE       TO TRUE
           SET  PRODUCT-STANDARD  TO TRUE
           MOVE 08000.00          TO WS-CREDIT-LIMIT
           MOVE 02100.00          TO WS-CURRENT-BALANCE
           MOVE 05900.00          TO WS-AVAILABLE-CREDIT
           MOVE 005               TO WS-DAILY-TXN-COUNT
           MOVE 002               TO WS-HOURLY-TXN-COUNT
           MOVE 'DAVIS, ANNA K.'      TO WS-CARDHOLDER-NAME

           MOVE 00500.00          TO WS-TXN-AMOUNT
           MOVE 'LUCKY STAR CASINO'   TO WS-TXN-MERCHANT-NAME
           MOVE '7995'            TO WS-TXN-MCC
           SET  TXN-DOMESTIC      TO TRUE
           SET  ENTRY-ECOMMERCE   TO TRUE
           MOVE 072               TO WS-TXN-FRAUD-SCORE
           .

      *================================================================*
      * LOAD TEST TRANSACTION 4: Velocity alert on restaurant          *
      *================================================================*
       2100-LOAD-TXN-4.
           MOVE '4532100098764444' TO WS-CARD-NUMBER
           SET  CARD-ACTIVE       TO TRUE
           SET  PRODUCT-PLATINUM  TO TRUE
           MOVE 25000.00          TO WS-CREDIT-LIMIT
           MOVE 08500.00          TO WS-CURRENT-BALANCE
           MOVE 16500.00          TO WS-AVAILABLE-CREDIT
           MOVE 022               TO WS-DAILY-TXN-COUNT
           MOVE 007               TO WS-HOURLY-TXN-COUNT
           MOVE 'WILSON, THOMAS P.'   TO WS-CARDHOLDER-NAME

           MOVE 00087.25          TO WS-TXN-AMOUNT
           MOVE 'OLIVE GARDEN #312'   TO WS-TXN-MERCHANT-NAME
           MOVE '5812'            TO WS-TXN-MCC
           SET  TXN-DOMESTIC      TO TRUE
           SET  ENTRY-CONTACTLESS TO TRUE
           MOVE 025               TO WS-TXN-FRAUD-SCORE
           .

      *================================================================*
      * LOAD TEST TRANSACTION 5: Cross-border, large, medium fraud     *
      *================================================================*
       2100-LOAD-TXN-5.
           MOVE '4532100098763333' TO WS-CARD-NUMBER
           SET  CARD-ACTIVE       TO TRUE
           SET  PRODUCT-BUSINESS  TO TRUE
           MOVE 50000.00          TO WS-CREDIT-LIMIT
           MOVE 12000.00          TO WS-CURRENT-BALANCE
           MOVE 38000.00          TO WS-AVAILABLE-CREDIT
           MOVE 004               TO WS-DAILY-TXN-COUNT
           MOVE 001               TO WS-HOURLY-TXN-COUNT
           MOVE 'GARCIA, CARLOS M.'   TO WS-CARDHOLDER-NAME

           MOVE 07800.00          TO WS-TXN-AMOUNT
           MOVE 'TECH SUPPLIES LTD'   TO WS-TXN-MERCHANT-NAME
           MOVE '5045'            TO WS-TXN-MCC
           MOVE 'GBR'             TO WS-TXN-COUNTRY
           SET  ENTRY-CHIP        TO TRUE
           MOVE 048               TO WS-TXN-FRAUD-SCORE
           .

      *================================================================*
      * 3000-AUTHORIZE-TRANSACTION: The authorization decision flow    *
      * Each check uses the CONTINUE-PROCESSING flag pattern.          *
      * When any check sets STOP-PROCESSING, subsequent checks         *
      * are skipped.                                                   *
      *================================================================*
       3000-AUTHORIZE-TRANSACTION.
           IF WS-CONTINUE-PROCESSING
               PERFORM 3100-CHECK-CARD-STATUS
           END-IF

           IF WS-CONTINUE-PROCESSING
               PERFORM 3200-CHECK-AVAILABLE-CREDIT
           END-IF

           IF WS-CONTINUE-PROCESSING
               PERFORM 3300-CHECK-VELOCITY
           END-IF

           IF WS-CONTINUE-PROCESSING
               PERFORM 3400-CHECK-MERCHANT-CATEGORY
           END-IF

           IF WS-CONTINUE-PROCESSING
               PERFORM 3500-CHECK-FRAUD-SCORE
           END-IF

           IF WS-CONTINUE-PROCESSING
               PERFORM 3600-MULTI-FACTOR-ASSESSMENT
           END-IF

      *    Final approval if all checks passed
           IF WS-CONTINUE-PROCESSING
               PERFORM 3700-FINAL-APPROVAL
           END-IF
           .

      *================================================================*
      * 3100-CHECK-CARD-STATUS                                         *
      * Uses EVALUATE TRUE with 88-level conditions for clean          *
      * multi-way branching on card status.                            *
      *================================================================*
       3100-CHECK-CARD-STATUS.
           EVALUATE TRUE
               WHEN CARD-ACTIVE
                   CONTINUE

               WHEN CARD-STOLEN
                   SET AUTH-DECLINED-STOLEN TO TRUE
                   MOVE 'Card reported stolen - retain card'
                       TO WS-AUTH-MESSAGE
                   SET RISK-CRITICAL TO TRUE
                   SET WS-STOP-PROCESSING TO TRUE

               WHEN CARD-LOST
                   SET AUTH-DECLINED-LOST TO TRUE
                   MOVE 'Card reported lost'
                       TO WS-AUTH-MESSAGE
                   SET RISK-CRITICAL TO TRUE
                   SET WS-STOP-PROCESSING TO TRUE

               WHEN CARD-BLOCKED
                   SET AUTH-DECLINED-CARD TO TRUE
                   MOVE 'Card is blocked by issuer'
                       TO WS-AUTH-MESSAGE
                   SET RISK-HIGH TO TRUE
                   SET WS-STOP-PROCESSING TO TRUE

               WHEN CARD-FROZEN
                   SET AUTH-DECLINED-FROZEN TO TRUE
                   MOVE 'Card is temporarily frozen'
                       TO WS-AUTH-MESSAGE
                   SET RISK-MEDIUM TO TRUE
                   SET WS-STOP-PROCESSING TO TRUE

               WHEN CARD-EXPIRED
                   SET AUTH-DECLINED-CARD TO TRUE
                   MOVE 'Card has expired'
                       TO WS-AUTH-MESSAGE
                   SET RISK-LOW TO TRUE
                   SET WS-STOP-PROCESSING TO TRUE

               WHEN OTHER
                   SET AUTH-SYSTEM-ERROR TO TRUE
                   MOVE 'Unknown card status'
                       TO WS-AUTH-MESSAGE
                   SET RISK-HIGH TO TRUE
                   SET WS-STOP-PROCESSING TO TRUE
           END-EVALUATE
           .

      *================================================================*
      * 3200-CHECK-AVAILABLE-CREDIT                                    *
      * Nested IF for credit limit check with near-limit warning.      *
      *================================================================*
       3200-CHECK-AVAILABLE-CREDIT.
           IF WS-AVAILABLE-CREDIT < WS-TXN-AMOUNT
               SET AUTH-DECLINED-CREDIT TO TRUE
               MOVE 'Insufficient available credit'
                   TO WS-AUTH-MESSAGE
               SET RISK-LOW TO TRUE
               SET WS-STOP-PROCESSING TO TRUE
           ELSE
      *        Check if transaction would use more than 90%
      *        of remaining credit
               IF WS-TXN-AMOUNT > ZERO
                   AND WS-AVAILABLE-CREDIT > ZERO
                   IF (WS-TXN-AMOUNT / WS-AVAILABLE-CREDIT)
                       > 0.90
                       SET WS-NEEDS-REVIEW TO TRUE
                       ADD 1 TO WS-F-FLAG-COUNT
                   END-IF
               END-IF
           END-IF
           .

      *================================================================*
      * 3300-CHECK-VELOCITY                                            *
      * Compound conditions check both daily and hourly velocity.      *
      *================================================================*
       3300-CHECK-VELOCITY.
      *    Hard decline: hourly velocity exceeded
           IF WS-HOURLY-TXN-COUNT >= WS-C-MAX-HOURLY-TXN
               SET AUTH-DECLINED-VELOCITY TO TRUE
               MOVE 'Hourly transaction velocity exceeded'
                   TO WS-AUTH-MESSAGE
               SET RISK-HIGH TO TRUE
               SET WS-STOP-PROCESSING TO TRUE
           ELSE
      *        Soft flag: daily velocity approaching limit
               IF WS-DAILY-TXN-COUNT >= WS-C-MAX-DAILY-TXN
                   SET AUTH-DECLINED-VELOCITY TO TRUE
                   MOVE 'Daily transaction velocity exceeded'
                       TO WS-AUTH-MESSAGE
                   SET RISK-HIGH TO TRUE
                   SET WS-STOP-PROCESSING TO TRUE
               ELSE
      *            Warning: high daily count with card-not-present
                   IF WS-DAILY-TXN-COUNT >= 15
                       AND ENTRY-CARD-NOT-PRESENT
                       SET WS-NEEDS-REVIEW TO TRUE
                       ADD 1 TO WS-F-FLAG-COUNT
                   END-IF
               END-IF
           END-IF
           .

      *================================================================*
      * 3400-CHECK-MERCHANT-CATEGORY                                   *
      * EVALUATE with ALSO for two-dimensional decision:               *
      * card product type vs. merchant category.                       *
      *================================================================*
       3400-CHECK-MERCHANT-CATEGORY.
           EVALUATE TRUE ALSO TRUE
      *        Standard cards: gambling and cash advance restricted
               WHEN PRODUCT-STANDARD
                   ALSO MCC-GAMBLING
                   SET AUTH-DECLINED-MCC TO TRUE
                   MOVE 'Merchant category restricted'
                       TO WS-AUTH-MESSAGE
                   SET WS-STOP-PROCESSING TO TRUE

               WHEN PRODUCT-STANDARD
                   ALSO MCC-CASH-ADVANCE
                   SET AUTH-DECLINED-MCC TO TRUE
                   MOVE 'Cash advance not allowed on this card'
                       TO WS-AUTH-MESSAGE
                   SET WS-STOP-PROCESSING TO TRUE

      *        Standard cards: crypto restricted
               WHEN PRODUCT-STANDARD
                   ALSO MCC-CRYPTO
                   SET AUTH-DECLINED-MCC TO TRUE
                   MOVE 'Cryptocurrency purchase restricted'
                       TO WS-AUTH-MESSAGE
                   SET WS-STOP-PROCESSING TO TRUE

      *        Gold/Platinum: gambling flagged, not blocked
               WHEN PRODUCT-PREMIUM
                   ALSO MCC-GAMBLING
                   SET WS-NEEDS-REVIEW TO TRUE
                   ADD 1 TO WS-F-FLAG-COUNT

      *        Business cards: no MCC restrictions
               WHEN PRODUCT-BUSINESS
                   ALSO ANY
                   CONTINUE

      *        All other combinations: pass
               WHEN OTHER
                   CONTINUE
           END-EVALUATE
           .

      *================================================================*
      * 3500-CHECK-FRAUD-SCORE                                         *
      * Multi-level fraud response based on score ranges.              *
      *================================================================*
       3500-CHECK-FRAUD-SCORE.
           EVALUATE TRUE
               WHEN FRAUD-LOW-RISK
                   CONTINUE

               WHEN FRAUD-MED-RISK
      *            Medium risk: flag for review but continue
                   SET WS-NEEDS-REVIEW TO TRUE
                   ADD 1 TO WS-F-FLAG-COUNT

               WHEN FRAUD-HIGH-RISK
      *            High risk: compound condition determines outcome
      *            High fraud + card not present = decline
      *            High fraud + card present = flag and continue
                   IF ENTRY-CARD-NOT-PRESENT
                       SET AUTH-DECLINED-FRAUD TO TRUE
                       MOVE 'High fraud risk - CNP transaction'
                           TO WS-AUTH-MESSAGE
                       SET RISK-HIGH TO TRUE
                       SET WS-STOP-PROCESSING TO TRUE
                   ELSE
                       SET WS-NEEDS-REVIEW TO TRUE
                       ADD 1 TO WS-F-FLAG-COUNT
                   END-IF

               WHEN FRAUD-CRITICAL
      *            Critical: immediate decline regardless
                   SET AUTH-DECLINED-FRAUD TO TRUE
                   MOVE 'Critical fraud risk score'
                       TO WS-AUTH-MESSAGE
                   SET RISK-CRITICAL TO TRUE
                   SET WS-STOP-PROCESSING TO TRUE
           END-EVALUATE
           .

      *================================================================*
      * 3600-MULTI-FACTOR-ASSESSMENT                                   *
      * The most complex check: combines geographic risk, transaction  *
      * amount, entry mode, and accumulated flags into a final         *
      * risk determination using EVALUATE TRUE ALSO TRUE.              *
      *================================================================*
       3600-MULTI-FACTOR-ASSESSMENT.
      *    First dimension: geographic risk
      *    Second dimension: transaction amount threshold

           EVALUATE TRUE ALSO TRUE
      *        High-risk country: always decline
               WHEN TXN-HIGH-RISK-COUNTRY
                   ALSO ANY
                   SET AUTH-DECLINED-FRAUD TO TRUE
                   MOVE 'Transaction from high-risk country'
                       TO WS-AUTH-MESSAGE
                   SET RISK-CRITICAL TO TRUE
                   SET WS-STOP-PROCESSING TO TRUE

      *        Cross-border + very high value: call center referral
               WHEN TXN-CROSS-BORDER
                   ALSO WS-TXN-AMOUNT > WS-C-VERY-HIGH-VALUE
                   SET AUTH-CALL-CENTER TO TRUE
                   MOVE 'Large cross-border: manual review'
                       TO WS-AUTH-MESSAGE
                   SET RISK-HIGH TO TRUE
                   SET WS-STOP-PROCESSING TO TRUE

      *        Cross-border + high value + not low fraud: flag
               WHEN TXN-CROSS-BORDER
                   ALSO WS-TXN-AMOUNT > WS-C-HIGH-VALUE-LIMIT
                   IF NOT FRAUD-LOW-RISK
                       SET WS-NEEDS-REVIEW TO TRUE
                       ADD 1 TO WS-F-FLAG-COUNT
                   END-IF

      *        Cross-border + card not present + any flags: flag
               WHEN TXN-CROSS-BORDER
                   ALSO OTHER
                   IF ENTRY-CARD-NOT-PRESENT
                       AND WS-F-FLAG-COUNT > 0
                       SET WS-NEEDS-REVIEW TO TRUE
                       ADD 1 TO WS-F-FLAG-COUNT
                   END-IF

      *        Domestic, any amount: no additional action
               WHEN TXN-DOMESTIC
                   ALSO ANY
                   CONTINUE

      *        Allied country, any amount: no additional action
               WHEN TXN-ALLIED-COUNTRY
                   ALSO ANY
                   CONTINUE

      *        Default: pass through
               WHEN OTHER
                   CONTINUE
           END-EVALUATE
           .

      *================================================================*
      * 3700-FINAL-APPROVAL                                            *
      * If we reach this point, all checks passed. Determine           *
      * whether to approve clean or approve with review.               *
      *================================================================*
       3700-FINAL-APPROVAL.
           MOVE WS-F-FLAG-COUNT TO WS-AUTH-FLAGS-RAISED

           IF WS-NEEDS-REVIEW
      *        Multiple flags or high-value with flags: call center
               IF WS-F-FLAG-COUNT >= 3
                   OR (WS-TXN-AMOUNT > WS-C-HIGH-VALUE-LIMIT
                       AND WS-F-FLAG-COUNT >= 2)
                   SET AUTH-CALL-CENTER TO TRUE
                   MOVE 'Multiple risk factors: manual review'
                       TO WS-AUTH-MESSAGE
                   SET RISK-HIGH TO TRUE
               ELSE
      *            Approved with post-transaction review
                   SET AUTH-APPROVED-REVIEW TO TRUE
                   MOVE 'Approved with monitoring'
                       TO WS-AUTH-MESSAGE
                   SET RISK-MEDIUM TO TRUE
               END-IF
           ELSE
      *        Clean approval
               SET AUTH-APPROVED TO TRUE
               MOVE 'Approved' TO WS-AUTH-MESSAGE
               SET RISK-LOW TO TRUE
           END-IF
           .

      *================================================================*
      * 4000-DISPLAY-RESULT: Show the authorization decision           *
      *================================================================*
       4000-DISPLAY-RESULT.
           DISPLAY WS-C-DETAIL-SEP
           DISPLAY '  Card:     '
               WS-CARD-NUMBER(1:4) '-****-****-'
               WS-CARD-NUMBER(13:4)
           DISPLAY '  Holder:   ' WS-CARDHOLDER-NAME
           DISPLAY '  Merchant: ' WS-TXN-MERCHANT-NAME
           DISPLAY '  MCC:      ' WS-TXN-MCC
               '  Country: ' WS-TXN-COUNTRY
               '  Entry: ' WS-TXN-ENTRY-MODE

           MOVE WS-TXN-AMOUNT TO WS-DSP-AMOUNT
           DISPLAY '  Amount:   ' WS-DSP-AMOUNT

           MOVE WS-TXN-FRAUD-SCORE TO WS-DSP-SCORE
           DISPLAY '  Fraud Score: ' WS-DSP-SCORE
               '  Card Status: ' WS-CARD-STATUS
               '  Product: ' WS-CARD-PRODUCT

           DISPLAY SPACES

           EVALUATE TRUE
               WHEN AUTH-APPROVED
                   DISPLAY '  >> RESPONSE: 00 - APPROVED'
               WHEN AUTH-APPROVED-REVIEW
                   DISPLAY '  >> RESPONSE: 01 - APPROVED'
                       ' (MONITORING)'
               WHEN AUTH-CALL-CENTER
                   DISPLAY '  >> RESPONSE: 02 - REFER TO'
                       ' CALL CENTER'
               WHEN AUTH-DECLINED-CREDIT
                   DISPLAY '  >> RESPONSE: 51 - DECLINED'
                       ' (INSUFFICIENT CREDIT)'
               WHEN AUTH-DECLINED-CARD
                   DISPLAY '  >> RESPONSE: 05 - DECLINED'
                       ' (CARD STATUS)'
               WHEN AUTH-DECLINED-STOLEN
                   DISPLAY '  >> RESPONSE: 43 - DECLINED'
                       ' (STOLEN CARD)'
               WHEN AUTH-DECLINED-LOST
                   DISPLAY '  >> RESPONSE: 41 - DECLINED'
                       ' (LOST CARD)'
               WHEN AUTH-DECLINED-FROZEN
                   DISPLAY '  >> RESPONSE: 62 - DECLINED'
                       ' (CARD FROZEN)'
               WHEN AUTH-DECLINED-VELOCITY
                   DISPLAY '  >> RESPONSE: 65 - DECLINED'
                       ' (VELOCITY)'
               WHEN AUTH-DECLINED-FRAUD
                   DISPLAY '  >> RESPONSE: 59 - DECLINED'
                       ' (FRAUD)'
               WHEN AUTH-DECLINED-MCC
                   DISPLAY '  >> RESPONSE: 57 - DECLINED'
                       ' (RESTRICTED MCC)'
               WHEN AUTH-SYSTEM-ERROR
                   DISPLAY '  >> RESPONSE: 96 - SYSTEM ERROR'
               WHEN OTHER
                   DISPLAY '  >> RESPONSE: UNKNOWN'
           END-EVALUATE

           DISPLAY '  Message:  ' WS-AUTH-MESSAGE
           DISPLAY '  Risk:     ' WS-AUTH-RISK-LEVEL
               '  Flags: ' WS-F-FLAG-COUNT
           DISPLAY SPACES
           .

Solution Walkthrough

The Sequential Check Pattern with Continue Flag

The authorization flow uses the "continue processing" flag pattern introduced in Case Study 1 of this chapter. Each check paragraph is guarded by IF WS-CONTINUE-PROCESSING, so once any check sets WS-STOP-PROCESSING, all subsequent checks are skipped. This pattern has three benefits:

  1. Performance. Once a card is identified as stolen, there is no point checking available credit, velocity, or fraud score. In a system processing 3.4 million requests per day, skipping unnecessary checks saves significant CPU time.

  2. Correctness. Some checks depend on earlier checks passing. The credit check assumes the card is active. The fraud score check assumes the card has not already been declined for a prior reason. The sequential flag pattern enforces this dependency naturally.

  3. Extensibility. When CFB needed to add a new check (sanctions screening), the developer added a new paragraph and a single IF WS-CONTINUE-PROCESSING / PERFORM block. No existing checks needed modification.

EVALUATE TRUE for Card Status: Clean Multi-Way Branching

The card status check (3100-CHECK-CARD-STATUS) demonstrates EVALUATE TRUE with 88-level conditions. Each card status maps to a specific response code and message:

  • CARD-STOLEN produces response code 43 (the ISO 8583 standard code for "pick up card, stolen")
  • CARD-LOST produces response code 41 (the standard code for "pick up card, lost")
  • CARD-FROZEN produces response code 62 (restricted card)

The WHEN OTHER clause catches any unexpected card status, producing a system error response. In production, this clause fires occasionally due to data migration errors or upstream system bugs. Without it, transactions with invalid card status codes would fall through without a decision -- a dangerous failure mode.

Nested IF for Credit Check with Near-Limit Warning

The credit check (3200-CHECK-AVAILABLE-CREDIT) uses nested IF to implement two levels of evaluation:

  1. Hard decline. If available credit is less than the transaction amount, decline immediately.
  2. Soft flag. If the transaction would consume more than 90% of remaining credit, flag it for review but allow it to continue.

The nested structure is natural here because the soft flag check only makes sense if the hard decline did not trigger. The division WS-TXN-AMOUNT / WS-AVAILABLE-CREDIT is protected by the outer IF (which guarantees WS-AVAILABLE-CREDIT >= WS-TXN-AMOUNT) and by the explicit check that both values are greater than zero, avoiding division by zero.

EVALUATE TRUE ALSO TRUE for Merchant Category Restrictions

The merchant category check (3400-CHECK-MERCHANT-CATEGORY) uses EVALUATE TRUE ALSO TRUE to create a two-dimensional decision matrix: card product type on one axis, merchant category on the other.

The business rules are expressed directly in the WHEN clauses: - Standard cards + gambling MCCs = decline - Standard cards + crypto = decline - Premium cards + gambling = flag (not decline) - Business cards + any MCC = no restrictions - Everything else = pass

The ANY keyword in the business card rule means "regardless of merchant category." This is cleaner than listing every possible MCC. When CFB later added a new MCC restriction (online pharmaceuticals), the developer added a single WHEN clause to the EVALUATE without modifying any existing rules.

Compound Conditions in Fraud Score Check

The fraud score check (3500-CHECK-FRAUD-SCORE) demonstrates compound conditions within an EVALUATE structure. The high-risk fraud score (61-80) does not automatically decline the transaction. Instead, it uses a compound condition to differentiate between card-present and card-not-present transactions:

           IF ENTRY-CARD-NOT-PRESENT
               SET AUTH-DECLINED-FRAUD TO TRUE
               ...
           ELSE
               SET WS-NEEDS-REVIEW TO TRUE
               ...
           END-IF

The reasoning: a card-present transaction with a moderately high fraud score may simply reflect unusual spending patterns (a cardholder on vacation). A card-not-present transaction with the same score is far more likely to be actual fraud. The compound condition ENTRY-CARD-NOT-PRESENT combines with the EVALUATE branch for FRAUD-HIGH-RISK to express this two-factor rule cleanly.

The Multi-Factor Assessment: EVALUATE TRUE ALSO TRUE with Nested Conditions

The most complex check (3600-MULTI-FACTOR-ASSESSMENT) combines geographic risk with transaction amount in a two-dimensional EVALUATE, and then applies additional conditions within individual WHEN clauses:

           WHEN TXN-CROSS-BORDER
               ALSO WS-TXN-AMOUNT > WS-C-HIGH-VALUE-LIMIT
               IF NOT FRAUD-LOW-RISK
                   SET WS-NEEDS-REVIEW TO TRUE
                   ...
               END-IF

This three-factor rule says: "If the transaction is cross-border, AND the amount exceeds the high-value threshold, AND the fraud score is not low-risk, then flag for review." The EVALUATE handles two dimensions; the nested IF adds a third. This approach avoids the explosion of WHEN clauses that would be needed to express all three factors purely through EVALUATE ALSO.

The Flag Accumulation Pattern

Throughout the authorization flow, the WS-F-FLAG-COUNT variable accumulates the number of risk flags raised. The final approval logic (3700-FINAL-APPROVAL) uses this accumulated count in a compound condition:

           IF WS-F-FLAG-COUNT >= 3
               OR (WS-TXN-AMOUNT > WS-C-HIGH-VALUE-LIMIT
                   AND WS-F-FLAG-COUNT >= 2)

This rule says: "If three or more flags were raised, OR if the transaction is high-value and at least two flags were raised, route to the call center for manual review." The parentheses around the AND clause are essential -- without them, the OR would bind to WS-TXN-AMOUNT > WS-C-HIGH-VALUE-LIMIT instead of to the entire AND expression, completely changing the meaning.

Lessons Learned

1. 88-Level Conditions Transform Cryptic Codes into Business Language

The authorization response codes (00, 01, 02, 05, 41, 43, 51, 57, 59, 62, 65, 96) are ISO 8583 standard codes that are meaningful to payment system professionals but opaque to everyone else. By defining condition names like AUTH-DECLINED-STOLEN and AUTH-APPROVED-REVIEW, the program reads in business language. When the compliance team reviewed the authorization logic, they could verify the rules without a code-to-meaning reference guide.

2. Composite 88-Level Conditions Reduce Error Rates

The composite conditions CARD-COMPROMISED (stolen or lost), CARD-INACTIVE (blocked, stolen, lost, frozen, expired), MCC-HIGH-RISK-MCC (all high-risk merchant categories), and ENTRY-CARD-NOT-PRESENT (manual or e-commerce) each combine multiple values under a single business concept. When a new entry mode was added (QR code payments, code 'QR'), the developer added it to ENTRY-CARD-PRESENT and every rule that tested card-present vs. card-not-present automatically included the new mode.

3. EVALUATE TRUE ALSO TRUE Replaces Massive Nested IF Structures

The merchant category check was originally implemented as a 67-line nested IF structure. After conversion to EVALUATE TRUE ALSO TRUE, it became 28 lines and was immediately understandable. More importantly, adding a new rule required adding a single WHEN clause rather than finding the correct insertion point in a nested IF chain.

4. The WHEN OTHER Clause Is Mandatory in Payment Systems

At 3.4 million transactions per day, "impossible" data conditions occur regularly -- a card status code of 'X' due to a database conversion error, a merchant category code with leading spaces due to a network translation issue, a country code that does not match any defined condition. The WHEN OTHER clause in every EVALUATE provides a safe default behavior for these cases. In a payment system, the safe default is typically to decline the transaction rather than to approve it by accident.

5. Parentheses in Compound Conditions Are Not Optional

The final approval logic contains the compound condition (WS-TXN-AMOUNT > WS-C-HIGH-VALUE-LIMIT AND WS-F-FLAG-COUNT >= 2). Without the parentheses, COBOL's operator precedence (AND before OR) would evaluate this as WS-F-FLAG-COUNT >= 3 OR WS-TXN-AMOUNT > WS-C-HIGH-VALUE-LIMIT, which has an entirely different meaning. In a system where every authorization decision has financial consequences, misplaced precedence can cost the bank millions.

Discussion Questions

  1. The sequential check pattern skips all remaining checks after the first decline. Are there scenarios where continuing to evaluate subsequent checks (even after a decline) would be beneficial? How would you implement a "collect all decline reasons" approach while still maintaining the early-exit optimization?

  2. The merchant category check uses EVALUATE TRUE ALSO TRUE with two dimensions. If CFB wanted to add a third dimension (time of day -- business hours vs. after hours), how would you restructure the logic? Would EVALUATE TRUE ALSO TRUE ALSO TRUE be readable, or would a different approach be better?

  3. The fraud score thresholds (30, 60, 80) are stored as constants. If CFB wanted different thresholds for different card products (for example, business cards might have higher tolerance), how would you redesign the data structure and conditional logic?

  4. The program uses the WS-F-FLAG-COUNT to accumulate risk signals. What would happen if two different checks both flagged the same risk factor (for example, velocity and fraud score both detecting the same anomaly)? Is double-counting a problem, and how would you address it?

  5. Transaction 5 in the test data is a large cross-border purchase to the United Kingdom with a medium fraud score. Walk through the authorization flow step by step and predict the final decision. Which checks will flag the transaction, and what will the final response code be?