Overview
Frictionless SPEI automatically processes bank transfers even when they don’t match an existing pending transaction. This feature enables two key scenarios:- Mismatched amounts: Customer deposits a different amount than expected
- Direct transfers: Customer transfers directly without initiating a checkout
PrerequisitesThis feature builds on standard SPEI payments. If you haven’t integrated SPEI yet, start with the SPEI Bank Transfers guide.
How It Works
CLABE + Identifier System
Every SPEI deposit uses two identification layers: CLABE (Tonder-managed)- Unique 18-digit account assigned by Tonder for each merchant + customer
- Primary deposit identifier
- Used for lookups and matching
external_id: Your internal reference (customer ID, transaction ID, etc.)additional_external_id: Optional second identifier for advanced use cases- Enables your reconciliation logic
Use Cases
Use Case 1: Mismatched Amount Deposits
Scenario: Customer initiates checkout but deposits a different amount. Example:- Customer creates checkout for 100 MXN
- Actually deposits 600 MXN
- System matches by CLABE and processes automatically
Use Case 2: Direct Transfers (No Checkout)
Scenario: Customer transfers directly to their CLABE without initiating checkout. Example:- Customer uses saved CLABE from previous deposit
- Transfers 700 MXN directly from banking app
- System finds last successful transaction for that CLABE
- Extracts identifier and creates new deposit
Implementation
Choose Your Strategy
Single Identifier (Recommended) Use the same identifier for both use cases - simplest approach. Example: Gaming platform usingplayer_id
- ✅ Simpler integration
- ✅ One reconciliation flow
- ✅ Always credit the same customer account
- Customer-centric reconciliation (gaming, wallets, accounts)
- Don’t need order-level tracking
- Manual handling of mismatched amounts is acceptable
Basic Setup (Single Identifier)
Payment Request:Advanced Setup (Dual Identifiers)
For merchants needing different identifiers per use case - enables transaction tracking for checkouts and customer tracking for frictionless deposits. When to use:- Need order-level tracking for checkouts (UC1)
- Need customer-level tracking for direct transfers (UC2)
- Want automatic order completion vs. manual top-ups
- More complex reconciliation requirements
Strategy Comparison
| Approach | UC1 Returns | UC2 Returns | Complexity | Best For |
|---|---|---|---|---|
| Single Identifier | player_id | player_id (history) | Simple | Customer-centric platforms |
| Dual Identifier | order_id | player_id (history) | Advanced | Order + customer tracking |
- Single: Same field both use cases, simpler integration, one reconciliation flow
- Dual: Different fields per use case, enables automatic order completion (UC1) and manual top-ups (UC2)
Custom Field Aliases
Use domain-specific field names instead of genericexternal_id terms.
Configuration Example:
| Industry | UC1 Identifier | UC2 Identifier |
|---|---|---|
| Gaming | order_id | player_id |
| E-commerce | order_id | customer_id |
| Services | transaction_id | account_id |
Custom aliases are agreed and configured during integration with Tonder support.
Webhook Fields Reference
Standard Fields
| Field | Type | Description |
|---|---|---|
clabe | string | CLABE that received the deposit |
amount | number | Actual amount deposited |
transaction_status | string | ”Success” for completed deposits |
Identifier Fields
| Field | Type | Use Case | Description |
|---|---|---|---|
external_id | string | UC1, UC2 (standard) | Primary identifier |
additional_external_id | string | UC2 (dual mode) | Secondary identifier for frictionless |
Special Flags (UC1 Only)
| Field | Type | Description |
|---|---|---|
mismatched_deposit | string | ”True” if amount differed |
original_expected_amount | string | Expected amount from checkout |
Best Practices
1. Choose Your Strategy
Start Simple:- Use single identifier (
external_idonly) for most use cases - Add dual identifiers only if you need different tracking per use case
- Custom aliases are optional enhancements
2. Always Validate
3. Handle Edge Cases
- Very large amount mismatches (>500%)
- Multiple deposits in short timeframe
- Unknown/invalid identifiers
- Missing
additional_external_idwhen expected
4. Logging
Log for audit trail:- CLABE used
- Identifiers received
- Amount mismatches
- Auto-creation events
- Reconciliation results
FAQ
Should I use single or dual identifiers?
Should I use single or dual identifiers?
Start with single identifier (just
external_id) - it’s simpler and works for most use cases. Only use dual identifiers if you specifically need different tracking for checkouts vs. frictionless deposits (e.g., automatic order completion vs. manual account top-ups).Do I need to store CLABEs in my database?
Do I need to store CLABEs in my database?
Optional. Tonder manages CLABEs and includes them in webhooks. Store them only if needed for customer service or analytics.
Can I use the same customer ID for both use cases?
Can I use the same customer ID for both use cases?
Yes! This is the recommended “single identifier” approach. Use
external_id: "PLAYER-12345" for everything, and both UC1 and UC2 will return the same player ID.What's the difference between external_id and additional_external_id?
What's the difference between external_id and additional_external_id?
external_id is returned for UC1 (when checkout exists). additional_external_id is returned for UC2 (no checkout). If you use single identifier strategy, you only need external_id for both.Can I use transaction UUIDs instead of customer IDs?
Can I use transaction UUIDs instead of customer IDs?
Yes, but this is less common. Most merchants use customer IDs (single identifier) or order IDs + customer IDs (dual identifier).
What happens if Use Case 2 can't find a historical transaction?
What happens if Use Case 2 can't find a historical transaction?
The deposit will fail to process automatically. Contact Tonder support to manually reconcile.
Can I change my field aliases after integration?
Can I change my field aliases after integration?
Contact Tonder support. Changes require configuration updates.
How do I know which use case was triggered?
How do I know which use case was triggered?
Check the webhook:
- UC1: Includes
mismatched_depositflag - UC2: Includes
concept: "Frictionless deposit - auto-created"
Integration Checklist
Choose identifier strategy (single or dual)
Decide on custom field aliases (optional)
Update payment requests to include identifiers
Update webhook handler to read identifiers
Implement reconciliation logic
Test UC1 in staging (mismatched amounts)
Test UC2 in staging (direct transfers)
Add logging and monitoring
Deploy to production
Next Steps
After implementing Frictionless SPEI:- Set up webhooks to receive real-time notifications for deposit events
- Review the Process Transaction API for complete request/response details
- Learn about SPEI Bank Transfers for standard SPEI setup

