Skip to content

COPAUA0C

Source: app-authorization-ims-db2-mq/cbl/COPAUA0C.cbl

Type: CICS transaction program

COPAUA0C — Card Authorization Decision Program

Purpose

COPAUA0C is a CICS/IMS/MQ program that processes card authorization requests received via MQ, decides whether to approve or decline each transaction based on available credit, and sends an authorization response back to the requesting queue. It is the core decisioning engine in the CardDemo authorization flow, checking the card cross-reference, account, customer, and pending-authorization data before rendering a decision. It also persists authorization activity (summary balances and detail records) to an IMS database for later reconciliation.

How it works

  • MAIN-PARA drives the whole program: 1000-INITIALIZE2000-MAIN-PROCESS9000-TERMINATE, then issues EXEC CICS RETURN.
  • 1000-INITIALIZE: Retrieves CICS start-up data (EXEC CICS RETRIEVE INTO MQTM) to get the request queue name and trigger data, sets an MQ wait interval (5000), opens the request queue (1100-OPEN-REQUEST-QUEUE, via MQOPEN), then does a first read from the queue (3100-READ-REQUEST-MQ).
  • 2000-MAIN-PROCESS loops (PERFORM UNTIL NO-MORE-MSG-AVAILABLE OR WS-LOOP-END):
  • 2100-EXTRACT-REQUEST-MSG unstrings the raw MQ message text (comma-delimited) into the PENDING-AUTH-REQUEST fields (date, time, card number, auth type, amount, merchant details, etc.) and converts the amount text to numeric via FUNCTION NUMVAL.
  • 5000-PROCESS-AUTH performs the actual authorization logic (see below).
  • The program increments a processed-message counter, issues EXEC CICS SYNCPOINT to commit the unit of work, resets the IMS PSB-scheduled flag, and either stops the loop (after WS-REQSTS-PROCESS-LIMIT = 500 messages) or reads the next message.
  • 5000-PROCESS-AUTH — the core decision path:
  • Assumes approval (APPROVE-AUTH), then schedules the IMS PSB (1200-SCHEDULE-PSB).
  • Looks up the card in the cross-reference file (5100-READ-XREF-RECORD).
  • If found, reads the account master (5200-READ-ACCT-RECORD), customer master (5300-READ-CUST-RECORD), the IMS pending-authorization summary segment (5500-READ-AUTH-SUMMRY), and a currently empty profile-data hook (5600-READ-PROFILE-DATA, just CONTINUE).
  • 6000-MAKE-DECISION computes available credit (from the IMS summary segment if found, else from the account master) and compares it to the transaction amount to approve or decline, setting response codes and reason codes, then builds the pipe/comma-delimited response string.
  • 7100-SEND-RESPONSE sends this response to the reply queue via MQPUT1.
  • If the card was found in xref, 8000-WRITE-AUTH-TO-DB updates the IMS summary segment (8400-UPDATE-SUMMARY) and inserts a new detail segment (8500-INSERT-AUTH).
  • 9000-TERMINATE closes the request MQ queue (9100-CLOSE-REQUEST-QUEUE via MQCLOSE).
  • 9500-LOG-ERROR is the common error-logging paragraph, invoked from nearly every I/O step; it performs 9990-END-ROUTINE, which itself performs 9000-TERMINATE — meaning any logged error triggers program termination, not just a warning message.

Inputs & outputs

Resource Type Purpose
Request MQ queue (name from MQTM-QNAME/trigger data) MQ queue Source of authorization request messages, opened once (MQOPEN), read repeatedly (MQGET) up to 500 times per program invocation
Reply MQ queue (WS-REPLY-QNAME, from MQMD-REPLYTOQ) MQ queue Destination for the authorization response, written via MQPUT1
CCXREF (WS-CCXREF-FILE) CICS file (VSAM) Card cross-reference lookup: card number → customer ID / account ID (CVACT03Y layout)
ACCTDAT (WS-ACCTFILENAME) CICS file (VSAM) Account master record — credit limit, current balance (CVACT01Y layout)
CUSTDAT (WS-CUSTFILENAME) CICS file (VSAM) Customer master record (CVCUS01Y layout)
CARDDAT / CARDAIX (WS-CARDFILENAME, WS-CARDFILENAME-ACCT-PATH) CICS file names declared but not referenced in any EXEC CICS READ in this program (dead/unused declarations as far as parsed facts show)
IMS database via PSB PSBPAUTB IMS DB (DL/I) PAUTSUM0 root segment (pending authorization summary — credit limit/balance) read (GU) and updated; child detail segment (PENDING-AUTH-DETAILS/CIPAUDTY) inserted for each processed authorization
CCPAURQY / CCPAURLY copybooks In-memory layouts Request and response message formats used to parse the MQ message and build the reply string
CCPAUERY copybook In-memory layout Error log record layout (ERR-LOCATION, ERR-MESSAGE, ERR-CODE-1/2, ERR-EVENT-KEY) used by 9500-LOG-ERROR
CMQODV, CMQMDV, CMQV, CMQTML, CMQPMOV, CMQGMOV copybooks MQ control structures Object descriptors, message descriptors, constants, trigger data, put/get message options for MQOPEN/MQGET/MQPUT1/MQCLOSE calls

Things to know

  • Errors are fatal by design. 9500-LOG-ERROR always performs 9990-END-ROUTINE, which performs 9000-TERMINATE. This means even a single MQ, CICS, or IMS error during processing (e.g., a NOTFND on account read, classified as a "warning") still routes through logic that closes the queue and ends the program — worth verifying this is the intended behavior versus just logging and continuing, since the code sets warning-severity flags (ERR-WARNING) but the shared clean-up path still runs.
  • Hard-coded values: PSB name PSBPAUTB, transaction ID CP00, file names (ACCTDAT, CUSTDAT, CARDDAT, CARDAIX, CCXREF), message batch limit of 500 (WS-REQSTS-PROCESS-LIMIT), MQ wait interval of 5000 (ms, presumably), MQ message expiry of 50, and decline reason codes (3100, 4100, 4200, 4300, 5100, 5200, 9000) are all embedded directly in the code rather than externalized/configurable.
  • Message parsing is fragile: 2100-EXTRACT-REQUEST-MSG uses a straight UNSTRING ... DELIMITED BY ',' against the raw MQ payload with a fixed field order. Any change to the upstream message format (extra/missing commas, reordered fields) will silently misalign data into the wrong fields, with no validation shown.
  • Fraud/profile-based decline reasons are declared but not populated. The WS-DECLINE-REASON-FLG has 88-level conditions for CARD-NOT-ACTIVE, ACCOUNT-CLOSED, CARD-FRAUD, MERCHANT-FRAUD, and 6000-MAKE-DECISION evaluates them, but nothing in the shown code ever sets these conditions (only INSUFFICIENT-FUND is set) — 5600-READ-PROFILE-DATA is an empty stub (CONTINUE), suggesting fraud/profile checks are planned but not yet implemented.
  • PSB scheduling retry logic: 1200-SCHEDULE-PSB retries the DL/I SCHD once if the PSB is already scheduled (PSB-SCHEDULED-MORE-THAN-ONCE), issuing a TERM first. Other IMS failure conditions (RETRY-CONDITION 88-level: BA, FH, TE) are defined but do not appear to trigger any retry — only logged as critical errors.
  • Two files declared but seemingly unused: CARDDAT and CARDAIX filenames are set up in working storage but no EXEC CICS READ against them appears in the source shown — potentially vestigial from a related program, or used in a portion of the source not included here.
  • Decision logic depends on data source precedence: if an IMS pending-auth summary segment exists, its credit limit/balance is used; otherwise the account master's credit limit/balance is used. If the account isn't found at all, the authorization is unconditionally declined. Confirm this fallback hierarchy matches business intent, since IMS summary data and account master data could theoretically disagree.
  • Unit-of-work boundary: EXEC CICS SYNCPOINT is issued after each message is processed (commit per message), and the IMS PSB-scheduled flag is manually reset (IMS-PSB-NOT-SCHD) afterward — implying the PSB must be freshly rescheduled for every message, which happens in 5000-PROCESS-AUTH via 1200-SCHEDULE-PSB.

CICS commands

RETURN, RETRIEVE, READ, ASKTIME NOHANDLE, FORMATTIME, WRITEQ

Copybooks

CCPAUERY, CCPAURLY, CCPAURQY, CIPAUDTY, CIPAUSMY, CMQGMOV, CMQMDV, CMQODV, CMQPMOV, CMQTML, CMQV, CVACT01Y, CVACT03Y, CVCUS01Y

Calls

MQCLOSE, MQGET, MQOPEN, MQPUT1

Paragraph flow

flowchart TD
    MAIN_PARA["MAIN-PARA"]
    1000_INITIALIZE["1000-INITIALIZE"]
    1000_EXIT["1000-EXIT"]
    1100_OPEN_REQUEST_QUEUE["1100-OPEN-REQUEST-QUEUE"]
    1100_EXIT["1100-EXIT"]
    1200_SCHEDULE_PSB["1200-SCHEDULE-PSB"]
    1200_EXIT["1200-EXIT"]
    2000_MAIN_PROCESS["2000-MAIN-PROCESS"]
    2000_EXIT["2000-EXIT"]
    2100_EXTRACT_REQUEST_MSG["2100-EXTRACT-REQUEST-MSG"]
    2100_EXIT["2100-EXIT"]
    3100_READ_REQUEST_MQ["3100-READ-REQUEST-MQ"]
    3100_EXIT["3100-EXIT"]
    5000_PROCESS_AUTH["5000-PROCESS-AUTH"]
    5000_EXIT["5000-EXIT"]
    5100_READ_XREF_RECORD["5100-READ-XREF-RECORD"]
    5100_EXIT["5100-EXIT"]
    5200_READ_ACCT_RECORD["5200-READ-ACCT-RECORD"]
    5200_EXIT["5200-EXIT"]
    5300_READ_CUST_RECORD["5300-READ-CUST-RECORD"]
    5300_EXIT["5300-EXIT"]
    5500_READ_AUTH_SUMMRY["5500-READ-AUTH-SUMMRY"]
    5500_EXIT["5500-EXIT"]
    5600_READ_PROFILE_DATA["5600-READ-PROFILE-DATA"]
    5600_EXIT["5600-EXIT"]
    6000_MAKE_DECISION["6000-MAKE-DECISION"]
    6000_EXIT["6000-EXIT"]
    7100_SEND_RESPONSE["7100-SEND-RESPONSE"]
    7100_EXIT["7100-EXIT"]
    8000_WRITE_AUTH_TO_DB["8000-WRITE-AUTH-TO-DB"]
    8000_EXIT["8000-EXIT"]
    8400_UPDATE_SUMMARY["8400-UPDATE-SUMMARY"]
    8400_EXIT["8400-EXIT"]
    8500_INSERT_AUTH["8500-INSERT-AUTH"]
    8500_EXIT["8500-EXIT"]
    9000_TERMINATE["9000-TERMINATE"]
    9000_EXIT["9000-EXIT"]
    9100_CLOSE_REQUEST_QUEUE["9100-CLOSE-REQUEST-QUEUE"]
    9100_EXIT["9100-EXIT"]
    9500_LOG_ERROR["9500-LOG-ERROR"]
    9500_EXIT["9500-EXIT"]
    9990_END_ROUTINE["9990-END-ROUTINE"]
    9990_EXIT["9990-EXIT"]
    1000_INITIALIZE --> 1100_OPEN_REQUEST_QUEUE
    1000_INITIALIZE --> 3100_READ_REQUEST_MQ
    1100_OPEN_REQUEST_QUEUE --> 9500_LOG_ERROR
    1200_SCHEDULE_PSB --> 9500_LOG_ERROR
    2000_MAIN_PROCESS --> 2100_EXTRACT_REQUEST_MSG
    2000_MAIN_PROCESS --> 3100_READ_REQUEST_MQ
    2000_MAIN_PROCESS --> 5000_PROCESS_AUTH
    3100_READ_REQUEST_MQ --> 9500_LOG_ERROR
    5000_PROCESS_AUTH --> 1200_SCHEDULE_PSB
    5000_PROCESS_AUTH --> 5100_READ_XREF_RECORD
    5000_PROCESS_AUTH --> 5200_READ_ACCT_RECORD
    5000_PROCESS_AUTH --> 5300_READ_CUST_RECORD
    5000_PROCESS_AUTH --> 5500_READ_AUTH_SUMMRY
    5000_PROCESS_AUTH --> 5600_READ_PROFILE_DATA
    5000_PROCESS_AUTH --> 6000_MAKE_DECISION
    5000_PROCESS_AUTH --> 7100_SEND_RESPONSE
    5000_PROCESS_AUTH --> 8000_WRITE_AUTH_TO_DB
    5100_READ_XREF_RECORD --> 9500_LOG_ERROR
    5200_READ_ACCT_RECORD --> 9500_LOG_ERROR
    5300_READ_CUST_RECORD --> 9500_LOG_ERROR
    5500_READ_AUTH_SUMMRY --> 9500_LOG_ERROR
    7100_SEND_RESPONSE --> 9500_LOG_ERROR
    8000_WRITE_AUTH_TO_DB --> 8400_UPDATE_SUMMARY
    8000_WRITE_AUTH_TO_DB --> 8500_INSERT_AUTH
    8400_UPDATE_SUMMARY --> 9500_LOG_ERROR
    8500_INSERT_AUTH --> 9500_LOG_ERROR
    9000_TERMINATE --> 9100_CLOSE_REQUEST_QUEUE
    9100_CLOSE_REQUEST_QUEUE --> 9500_LOG_ERROR
    9500_LOG_ERROR --> 9990_END_ROUTINE
    9990_END_ROUTINE --> 9000_TERMINATE
    MAIN_PARA --> 1000_INITIALIZE
    MAIN_PARA --> 2000_MAIN_PROCESS
    MAIN_PARA --> 9000_TERMINATE

Paragraphs

Paragraph Line Performs
MAIN-PARA 220 1000-INITIALIZE, 2000-MAIN-PROCESS, 9000-TERMINATE
1000-INITIALIZE 230 1100-OPEN-REQUEST-QUEUE, 3100-READ-REQUEST-MQ
1000-EXIT 249
1100-OPEN-REQUEST-QUEUE 255 9500-LOG-ERROR
1100-EXIT 286
1200-SCHEDULE-PSB 292 9500-LOG-ERROR
1200-EXIT 319
2000-MAIN-PROCESS 323 2100-EXTRACT-REQUEST-MSG, 5000-PROCESS-AUTH, 3100-READ-REQUEST-MQ
2000-EXIT 347
2100-EXTRACT-REQUEST-MSG 351
2100-EXIT 382
3100-READ-REQUEST-MQ 386 9500-LOG-ERROR
3100-EXIT 434
5000-PROCESS-AUTH 438 1200-SCHEDULE-PSB, 5100-READ-XREF-RECORD, 5200-READ-ACCT-RECORD, 5300-READ-CUST-RECORD, 5500-READ-AUTH-SUMMRY, 5600-READ-PROFILE-DATA
5000-EXIT 468
5100-READ-XREF-RECORD 472 9500-LOG-ERROR, 9500-LOG-ERROR
5100-EXIT 516
5200-READ-ACCT-RECORD 520 9500-LOG-ERROR, 9500-LOG-ERROR
5200-EXIT 564
5300-READ-CUST-RECORD 568 9500-LOG-ERROR, 9500-LOG-ERROR
5300-EXIT 612
5500-READ-AUTH-SUMMRY 616 9500-LOG-ERROR
5500-EXIT 643
5600-READ-PROFILE-DATA 647
5600-EXIT 653
6000-MAKE-DECISION 657
6000-EXIT 734
7100-SEND-RESPONSE 738 9500-LOG-ERROR
7100-EXIT 782
8000-WRITE-AUTH-TO-DB 786 8400-UPDATE-SUMMARY, 8500-INSERT-AUTH
8000-EXIT 794
8400-UPDATE-SUMMARY 798 9500-LOG-ERROR
8400-EXIT 850
8500-INSERT-AUTH 854 9500-LOG-ERROR
8500-EXIT 935
9000-TERMINATE 940 9100-CLOSE-REQUEST-QUEUE
9000-EXIT 950
9100-CLOSE-REQUEST-QUEUE 953 9500-LOG-ERROR
9100-EXIT 979
9500-LOG-ERROR 983 9990-END-ROUTINE
9500-EXIT 1012
9990-END-ROUTINE 1016 9000-TERMINATE
9990-EXIT 1024