Skip to content

refactor!: reorganize models by business domain and improve 3DS handling#37

Merged
gustavovalverde merged 1 commit intomainfrom
ref-models-3ds
Jun 2, 2025
Merged

refactor!: reorganize models by business domain and improve 3DS handling#37
gustavovalverde merged 1 commit intomainfrom
ref-models-3ds

Conversation

@gustavovalverde
Copy link
Member

Overview

This PR implements a comprehensive refactoring that delivers two major architectural improvements:

  1. Model reorganization from technical concerns to business domain alignment for improved developer experience
  2. Enhanced 3D Secure flow management with unified callback handling and robust session management

Changes Made

Model Organization Restructure

  • Before: Technical organization (schemas.py, secure.py) mixing different business domains
  • After: Business domain organization with dedicated directories:
    • payment/ - Core payment processing (Sale, Hold, Refund, Void, Post)
    • datavault/ - Card tokenization and token management
    • three_ds/ - 3D Secure authentication and challenge flows
    • payment_page/ - Hosted payment page integration
    • verification/ - Transaction status and verification
  • Simplified Naming: Sale instead of SaleTransactionModel, Hold instead of HoldTransactionModel
  • Backwards Compatibility: All existing imports continue to work seamlessly

3D Secure Flow Enhancements

Unified Callback Handling

# Before: Manual callback type detection required
if "threeDSMethodData" in form_data:
    # Handle method notification
elif "CRes" in form_data:
    # Handle challenge response

# After: Automatic detection and routing
response = await azul.handle_3ds_callback(secure_id, callback_data, form_data)

Enhanced Session Management

  • Structured session data with comprehensive status tracking
  • Automatic cleanup of completed transactions
  • Better error recovery and state management
  • Persistent session information for cross-request 3DS flows

Improved Response Processing

  • Consolidated _process_3ds_response() with better 3DS requirement detection
  • Enhanced challenge and method form handling
  • Cleaner transaction status extraction and mapping
  • More robust error handling throughout 3DS flows

Transaction Processing Consolidation

  • Common _process_secure_transaction() method eliminates code duplication
  • Unified handling for sale, token sale, and hold transactions
  • Consistent session data structure across transaction types
  • Better separation of concerns between transaction types and 3DS flows

Test Structure Improvements

  • Integration → E2E: Moved integration tests to e2e/ directory for accurate categorization
  • CI Workflow Split: Separate unit and end-to-end test execution for better pipeline efficiency
  • Maintained Coverage: All existing test functionality preserved with clearer organization

Development Experience Improvements

  • Intuitive Discovery: Models organized by business intent rather than technical implementation
  • Cleaner Imports: Simplified model names with consistent patterns
  • Better Documentation: Enhanced docstrings and decision documentation
  • Future-Proof Structure: Scalable organization for new Azul services

Key Technical Improvements

3DS Session Management

# Enhanced session data structure
session_data = {
    "azul_order_id": response.get("AzulOrderId"),
    "amount": request.Amount,
    "itbis": request.Itbis,
    "order_number": request.OrderNumber,
    "term_url": term_url,
    "status": "processing",
    "challenge_required": True,  # Dynamic flags
    "method_required": False,
}

Automatic 3DS Flow Detection

# Smart callback routing based on form data
async def handle_3ds_callback(self, secure_id, callback_data, form_data):
    if "threeDSMethodData" in form_data:
        return await self._handle_method_notification(secure_id)
    elif "CRes" in form_data or "cres" in form_data:
        return await self._handle_challenge_response(secure_id, cres)
    else:
        return await self._handle_return_redirect(secure_id)

Transaction Status Management

# Improved status tracking and cleanup
def _update_session_with_result(self, secure_id, result, is_final=False):
    status, error_description = self._get_transaction_status(result)
    # Update session with structured status information
    # Automatic cleanup for completed transactions

Benefits

For Developers

  1. Intuitive Model Discovery: Find payment models in payment/, 3DS models in three_ds/, etc.
  2. Simplified Integration: Unified 3DS callback handling reduces implementation complexity
  3. Better Error Handling: More structured exception management and recovery
  4. Cleaner Code: Reduced duplication and better separation of concerns

For Production Use

  1. Enhanced 3DS Reliability: Robust session management and automatic cleanup
  2. Better Error Recovery: Improved handling of edge cases and network issues
  3. Scalable Architecture: Future-ready structure for additional Azul services
  4. Maintained Compatibility: Zero breaking changes for existing implementations

For Maintenance

  1. Co-located Functionality: Related models and logic grouped by business domain
  2. Reduced Complexity: Consolidated 3DS processing with common patterns
  3. Better Testing: Clear separation between unit and end-to-end tests
  4. Documentation: Comprehensive decision records for future reference

- Restructure models from technical organization to business domain alignment
- Move from schemas.py/secure.py to domain directories (payment/, datavault/, three_ds/, payment_page/, verification/)
- Simplify model names removing verbose suffixes (Sale vs SaleTransactionModel)
- Implement unified 3DS callback handling with automatic detection and routing
- Add comprehensive session management for 3DS transactions with status tracking
- Improve 3DS response processing with better challenge and method detection
- Consolidate secure transaction processing with common transaction handler
- Enhance error handling and logging throughout 3DS flows
- Restructure test organization moving integration tests to e2e/ directory
- Split CI workflows into separate unit and end-to-end test execution
- Maintain full backwards compatibility for existing imports

The 3DS improvements provide a more robust and maintainable authentication flow
while the model reorganization aligns the SDK structure with Azul's business
organization, making both development and payment processing more intuitive.

BREAKING CHANGE: Internal imports may need updates, though public API remains compatible
@gustavovalverde gustavovalverde merged commit 7fd79e7 into main Jun 2, 2025
2 of 3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant