Problem Description

The Ifthenpay payment gateway has a fundamental limitation where Multibanco references can only use 4 digits for order IDs (range 1-9999). When order IDs exceed 9999, the system truncates to the rightmost 4 digits, causing frequent collisions.

Steps to Reproduce

  1. Create orders with IDs > 9999 (e.g., order 12345 and 22345)
  2. Both orders generate the same Multibanco reference containing "2345" followed by calculated check digits
  3. When payment callback arrives, system processes wrong order or fails

Expected Behavior

Each order should have a unique Multibanco reference, even for large order IDs.

Actual Behavior

  • Multiple orders share the same reference
  • Payment callbacks process incorrect orders
  • "Payment already processed" errors occur
  • Manual intervention required to resolve payments

Proposed Solution

Implement hash-based order ID mapping with collision detection:

  • Use CRC32 hash instead of simple truncation for order IDs > 9999
  • Map large order IDs to range 1000-9999 to avoid conflicts with small order IDs (1-999)
  • Add collision detection and logging
  • Implement intelligent payment selection based on amount matching
  • Maintain backward compatibility for order IDs ≤ 9999

Impact

  • High: Affects all sites with order IDs > 9999
  • Data integrity: Payments may be applied to wrong orders
  • User experience: Failed payments require manual resolution
Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

introfini created an issue. See original summary.

  • introfini committed 56f06657 on 2.0.x
    [#3550246] feat: Enhance payment gateway reliability and collision...
introfini’s picture

Status: Active » Fixed

Major improvements to Multibanco and MB Way payment gateways:

- Implement hash-based collision prevention for order IDs > 9999
- Add comprehensive webhook validation (entity, anti-phishing, amount)
- Fix order.paid event not firing reliably in webhook context
- Add proper dependency injection and logger service
- Implement collision-aware payment selection by amount matching
- Add configuration form validation
- Fix unnecessary payment saves on admin page loads
- Add Commerce Log integration for collision warnings

Technical changes:
- Replace simple truncation with CRC32 hash algorithm
- Store original order IDs for audit trail
- Validate all webhook parameters with proper HTTP status codes
- Explicitly save orders when balance reaches zero
- Add collision detection with database queries

New methods: processOrderIdForReference(), checkForOrderIdCollisions(),
findAllPaymentsByRemoteId(), selectBestPaymentCandidate()

New files: commerce_ifthenpay.services.yml, commerce_ifthenpay.commerce_log_categories.yml, commerce_ifthenpay.commerce_log_templates.yml

Backward compatible. No breaking changes.

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

introfini’s picture

A new mode is planned to use the new Ifthenpay API that doesn't have the order number limitations.

In the meantime, these changes significantly reduce the collision problem by:
- Using hash-based distribution instead of simple truncation
- Implementing collision detection and logging
- Providing intelligent payment selection by amount matching

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.