CardPointe Gateway Integration Complete

โœ… What's Been Completed

1. CardPointe Adapter - app/services/payment_processors/fiserv_adapter.rb

2. Updated Payment View - app/views/app/quotes/payment.html.erb

3. Updated Quotes Controller - app/controllers/app/quotes_controller.rb

4. Database Migrations

5. Accounts Controller Fix - app/controllers/app/accounts_controller.rb

6. CardPointe Credentials - .kamal/secrets

7. Fiserv Validation Testing - โœ… COMPLETED


๐Ÿš€ How It Works

Payment Flow with CardPointe HIT

Customer โ†’ Payment Page
           โ†“
        [Frontend JavaScript]
           โ†“ (Load CardPointe HIT iframe)
        https://fts-uat.cardconnect.com/itoke/ajax-tokenizer.html
           โ†“ (Customer enters card data in iframe)
        CardPointe tokenizes card data
           โ†“ (postMessage returns token + expiry)
        JavaScript captures token and expiry
           โ†“ (Submit form)
        POST /order/:token/process_payment
           โ†“
        PaymentProcessorFactory.for_order(@order)
           โ†“
        FiservAdapter.authorize_with_token
           โ†“
        1. Create customer profile ID (local)
        2. POST /cardconnect/rest/auth (CardPointe API)
        3. Parse expiry (MMYY/MMYYY/MMYYYY โ†’ month/year)
           โ†“
        Save PaymentProfile + Order status
           โ†“
        Send email notifications
           โ†“
        Redirect to complete page

Key Differences from Original Plan

Original Plan (Commerce Hub) What We Actually Built (CardPointe)
Fiserv Commerce Hub CardPointe Gateway (Fiserv subsidiary)
Hosted Fields Hosted iFrame Tokenizer (HIT)
HMAC authentication Basic authentication
Payment session API Direct iframe tokenization
SessionID flow Token + expiry via postMessage
/ch/payments/v1/charges /cardconnect/rest/auth

๐Ÿ” PCI Compliance - SAQ A Achieved

CardPointe HIT Benefits


๐Ÿงช Testing Results

โœ… Completed Tests

๐Ÿšง Pending Tests


๐Ÿ“Š Database Schema

PaymentProfile

- processor              # 'fiserv' (for CardPointe)
- processor_customer_id  # Local customer ID (e.g., 'fiserv_490000000069_contact_3')
- processor_token_id     # CardPointe token (e.g., '9418594164541111')
- card_type              # Parsed from response
- last_four              # Last 4 digits
- expiration_month       # Parsed from expiry (1-12)
- expiration_year        # Parsed from expiry (full year, e.g., 2027)
- company_id             # NULLABLE - belongs to company
- contact_id             # NULLABLE - OR belongs to contact
- is_default             # Default payment method flag

PaymentTransaction

- processor                # 'fiserv'
- processor_transaction_id # CardPointe retref (e.g., '279971160962')
- transaction_type         # 'authorization', 'capture', 'refund'
- status                   # 'approved', 'declined'
- amount                   # Decimal amount
- response_code            # CardPointe respcode
- metadata (jsonb)         # Processor-specific data

๐Ÿšจ Issues Encountered & Fixed

1. PaymentProfile Creation Error

2. Non-numeric Expiry Error

3. Expiration Validation Failed

4. Expiry Format Variations

5. Unknown Attribute Error

6. NOT NULL Constraint Violation

7. Account Creation Page 500 Error


๐Ÿ“ Files Changed/Created

Created:

Modified:


๐ŸŽฏ Next Steps

1. Production Approval (In Progress)

2. Implement Stored Credential Framework (Required for Production)

Per Visa/Mastercard mandate, we need to add these parameters to production requests:

# In FiservAdapter.authorize_with_token
payload = {
  # ... existing fields ...
  cof: "C",              # C = Customer-initiated, M = Merchant-initiated
  cofscheduled: "N"      # Y = Recurring, N = One-time
}

Action items:

3. Code Cleanup

4. Additional Testing

5. Documentation Updates


๐Ÿ”‘ Production Environment Setup

Required Environment Variables

# CardPointe Production
CARDPOINTE_API_URL=https://fts.cardconnect.com  # Production URL (not UAT)
CARDPOINTE_MERCHANT_ID=<production_merchant_id>
CARDPOINTE_API_USERNAME=<production_username>
CARDPOINTE_API_PASSWORD=<production_password>

# Payment Processor Selection
DEFAULT_PAYMENT_PROCESSOR=fiserv

# Authorize.Net (keep as backup if needed)
AUTHORIZENET_API_LOGIN_ID=<your_api_login_id>
AUTHORIZENET_TRANSACTION_KEY=<your_transaction_key>
AUTHORIZENET_SIGNATURE_KEY=<your_signature_key>
AUTHORIZENET_PUBLIC_CLIENT_KEY=<your_public_client_key>

Production Iframe URL

Update in app/views/app/quotes/payment.html.erb:

// Change from UAT:
iframe.src = 'https://fts-uat.cardconnect.com/itoke/ajax-tokenizer.html'

// To Production:
iframe.src = 'https://fts.cardconnect.com/itoke/ajax-tokenizer.html'

๐Ÿค Benefits Achieved

โœ… PCI SAQ-A Compliance - Reduced from SAQ A-EP (175+ questions) โœ… Payment Security - Card data never touches our servers โœ… Processor Agnostic - Can switch between CardPointe and Authorize.Net โœ… Backwards Compatible - Existing Authorize.Net profiles still work โœ… Cost Savings - Lower processing fees with CardPointe โœ… Flexible Expiry Handling - Works with any expiry format from CardPointe โœ… Polymorphic Profiles - Supports both company and contact payments โœ… Validation Complete - Ready for production approval


๐Ÿ“ž Support Resources

CardPointe Documentation:

Fiserv Support:

Test Cards (UAT):

Amount-Driven Response Codes (UAT):


โœจ Success Metrics


Last Updated: 2025-10-06 Status: UAT Complete, Awaiting Production Credentials