# Cardinal Commerce Integration Project Documentation

## Overview
This project implements a Cardinal Commerce integration for authentication flow using JWT tokens and iframe-based communication.

## Architecture Components

### 1. Main Page (pktest.php)
- Serves as the primary interface
- Manages credential configuration
- Implements hidden form/iframe mechanism for Cardinal endpoint communication
- Generates initial JWT for authentication request
- Displays modals for viewing payload and token information

#### Key Components:
- Credential Management:
  - ApiKey
  - ApiId
  - OrgUnit
- Transaction ID Generation:
  - Pure UUID v4 format for maximum compatibility
  - Used as `jti` claim in outgoing JWT
  - Example: `550e8400-e29b-41d4-a716-446655440000`
  - Follows RFC 4122 standard for UUID version 4
- JWT Construction:
  - Headers: `{alg: 'HS256', typ: 'JWT'}`
  - Key claims:
    - jti: Transaction ID
    - iat: Timestamp
    - iss: API ID
    - OrgUnitId: Organization Unit
    - ObjectifyPayload: true
    - Custom payload data
    - ReturnUrl: Points to return handler

### 2. Return Handler (return.php)
Handles Cardinal's response processing:

#### Response Processing
- Receives POST from Cardinal containing Response JWT (application/x-www-form-urlencoded)
- Validates the incoming JWT structure and claims:
  - Verifies JWT format (header.payload.signature)
  - Validates header algorithm is HS256
  - Verifies issuer matches our API ID
  - Checks for required ReferenceId in Payload
  - Extracts `aud` claim for transaction correlation
- Creates transaction log file named `[TrxId].txt` containing decoded JWT payload
- Returns JSON success response to Cardinal

#### Transaction Logging
- Response JWTs are automatically logged to disk
- Each transaction creates a file named after its transaction ID
- Files are stored in the same directory as return.php
- File contents are the decoded JWT payload in pretty-printed JSON format
- File creation failures are logged via error_log

#### Transaction Response Handling
- Client-side polling mechanism checks for response file through check_file.php
- Polls every second for up to 2 minutes
- Looks for file named `[TrxId].txt`
- When file is found:
  - Parses JWT payload from file contents
  - Extracts ReferenceId, ErrorNumber, and ErrorDescription from Payload
  - Displays comprehensive transaction status in UI
  - Shows Success/Error status based on ErrorNumber
- Includes proper error handling and timeout mechanism
- Uses safe interval management to prevent memory leaks

#### Supporting Files
- check_file.php:
  - Validates transaction ID format
  - Safely checks for existence of response file
  - Returns file contents as JSON if found
  - Includes security validations for file access

## Communication Flow

1. Initial Request:
   ```
   pktest.php -----------> Cardinal Endpoint
   Direct POST with JWT containing jti claim
   ```

2. Cardinal Response:
   ```
   Cardinal ------------> return.php
   POST with JWT (aud claim matches original jti)
   Creates [TrxId].txt file with decoded JWT
   ```

3. Result Processing:
   ```
   pktest.php ------------> filesystem
   Client-side polling for [TrxId].txt file
   Extract ReferenceId claim when file exists
   ```

## JWT Structure

### Outgoing JWT
```json
{
  "headers": {
    "alg": "HS256",
    "typ": "JWT"
  },
  "payload": {
    "jti": "[TrxId]",
    "iat": "[timestamp]",
    "iss": "[ApiId]",
    "OrgUnitId": "[OrgUnit]",
    "ObjectifyPayload": true,
    "Payload": {
      "MerchantOrigin": "https://test.com"
    },
    "ReturnUrl": "http://localhost:8000/return.php"
  }
}
```

### Incoming JWT (from Cardinal)
- Sent as POST parameter with key 'Response'
- Content-Type: application/x-www-form-urlencoded
- Structure:
  ```json
  {
    "headers": {
      "alg": "HS256"
    },
    "payload": {
      "iss": "582e0a2033fadd1260f990f6",
      "iat": "[timestamp]",
      "exp": "[timestamp+duration]",
      "jti": "[unique-id]",
      "aud": "[original-TrxId]",
      "Payload": {
        "ReferenceId": "[unique-reference]",
        "ErrorNumber": 0,
        "ErrorDescription": "Success"
      }
    }
  }
  ```

## Security Features

1. JWT Validation:
   - Format validation (header.payload.signature)
   - Algorithm verification (HS256)
   - Issuer validation against API ID
   - Required claims validation (ReferenceId)
   - Transaction correlation via aud claim

2. File System Security:
   - UUID format validation for transaction IDs
   - Directory traversal prevention
   - Safe file handling with proper permissions
   - File locking for concurrent access
   - Validation of file existence and content

3. Error Handling:
   - Comprehensive error logging
   - Safe error responses to client
   - Proper HTTP status codes
   - Validation failure handling
   - File operation error tracking

4. Response Processing:
   - Content-Type validation
   - Request method validation
   - Required parameter checking
   - JSON validation of file contents
   - Safe response formatting

## Cardinal Endpoints
- Staging: https://centinelapistag.cardinalcommerce.com/V2/FIDO/Init

## Dependencies
- Bootstrap 5.3.0-alpha3 (CSS and JS)
- Native PHP JWT handling (currently manual implementation)

## Development Notes
- Local development server required
- Default port: 8000
- Requires PHP with JSON and hash extensions enabled

## Local Development Setup

### Running the Local Development Server
For local testing with Cardinal Commerce's callbacks, use PHP's built-in server with the following command:

```bash
php -S 0.0.0.0:8000
```

Important: Using `0.0.0.0` instead of `localhost` is crucial as it:
- Binds to all network interfaces, not just localhost
- Makes your development server accessible via your machine's IP address
- Allows Cardinal Commerce servers to send POST callbacks to your local environment

### Requirements for Local Testing
1. Network Requirements:
   - Open port 8000 on your local firewall
   - Network that allows incoming connections
   - No restrictive NAT or corporate firewall blocking inbound traffic
   
2. URL Handling:
   - The application automatically detects your machine's IP address
   - Generates proper callback URLs (e.g., `http://192.168.1.100:8000/return.php`)
   - Handles both local and production environments without configuration changes

3. Security Considerations:
   - Only use `0.0.0.0` binding in development
   - Ensure sensitive data is not exposed in development environment
   - Consider using SSH tunneling in restricted network environments

Note: If local testing is not possible due to network restrictions, deploying to a remote server remains an alternative option.

## Project Structure
```
/pktest/
├── check_file.php    # Transaction file checker with security validations
├── config.php        # Configuration management and credentials
├── dx.php           # Data exchange handler for Cardinal API
├── pktest.php       # Main entry point for FIDO authentication
├── PROJECT.md       # Project documentation
├── return.php       # Cardinal callback handler
└── utils.php        # Shared utility functions for URL/path handling
```

## Recent Changes and Improvements

### Dynamic URL Handling (utils.php)
New utility module implementing:
- `getBaseUrl()`: Detects server environment and constructs proper base URL
- `getReturnUrl()`: Generates dynamic return URL for Cardinal callbacks
- `getMerchantOrigin()`: Provides correct origin for CORS and security checks

### Configuration Updates (config.php)
- Removed hardcoded return URL
- All endpoint URLs now dynamically generated
- Structured configuration into logical sections:
  - API credentials
  - Account data
  - Persona information
  - Payment details
  - API endpoints

### Main Authentication Flow (pktest.php)
- Now uses dynamic URLs from utils.php
- MerchantOrigin automatically detected from current environment
- ReturnUrl dynamically generated based on deployment
- Improved error handling and timeout management
- Enhanced status display for transaction results

### Data Exchange Handler (dx.php)
- Integrated with utils.php for dynamic URL handling
- Uses automatically generated return URL
- Improved error handling and validation
- Enhanced payload construction with proper typing

### Security Improvements (check_file.php)
- Added CORS support for local development
- Enhanced origin validation
- Improved error logging
- Better file access security
- Added support for development URLs
