Auto Rescue for SEPA
Intelligent retry strategies for SEPA Direct Debit payment failures and R-transactions
Auto Rescue for SEPA
Auto Rescue for SEPA automatically handles failed SEPA Direct Debit payments, including R-transactions (returns, refusals, and reversals). SEPA Direct Debit has unique timing requirements and failure modes that require specialized retry strategies.
SEPA Direct Debit Lifecycle
Understanding the SEPA payment lifecycle is essential for effective recovery:
R-Transaction Types
SEPA returns (R-transactions) have specific codes and meanings:
Return Codes (Most Common)
| Code | Name | Description | Retryable |
|---|---|---|---|
AC01 | Incorrect Account Number | IBAN is wrong | No |
AC04 | Closed Account | Account has been closed | No |
AC06 | Blocked Account | Account is blocked | Maybe |
AG01 | Transaction Forbidden | Not authorized for DD | No |
AG02 | Invalid Bank Operation Code | Technical error | Yes |
AM04 | Insufficient Funds | Not enough balance | Yes |
AM05 | Duplicate Collection | Already debited | No |
BE05 | Unknown Creditor ID | Creditor not recognized | No |
FF01 | Invalid File Format | Technical error | Yes |
MD01 | No Mandate | Mandate not found/cancelled | No |
MD06 | Refund Request | Customer requested refund | No |
MS02 | Reason Not Specified | Customer refused | Maybe |
MS03 | Reason Not Specified | Agent refused | Maybe |
RC01 | Bank Identifier Incorrect | BIC is wrong | No |
SL01 | Service Not Allowed | DD not permitted | No |
R-transactions typically arrive 2-5 business days after the debit date. Plexy automatically monitors for returns and initiates Auto Rescue when appropriate.
How Auto Rescue Handles SEPA
Enabling Auto Rescue for SEPA
curl -X POST https://api.plexypay.com/v2/payments \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"amount": 4999,
"currency": "EUR",
"customer": "cus_abc123",
"payment_method": "pm_sepa_debit_xyz789",
"payment_method_options": {
"sepa_debit": {
"mandate": "md_abc123"
}
},
"auto_rescue": {
"enabled": true,
"max_retries": 3,
"retry_window_days": 21
},
"metadata": {
"subscription_id": "sub_monthly_123"
}
}'SEPA-Specific Configuration
Retry Timing
SEPA has minimum timing requirements:
| Constraint | Requirement |
|---|---|
| Minimum retry delay | 2 business days after R-transaction |
| Due date lead time | D-2 for Core, D-1 for B2B |
| Pre-notification | 14 days before first debit, unless agreed otherwise |
| Settlement time | 2-5 business days |
Configure timing accordingly:
curl -X POST https://api.plexypay.com/v2/payments \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"amount": 4999,
"currency": "EUR",
"customer": "cus_abc123",
"payment_method": "pm_sepa_debit_xyz789",
"auto_rescue": {
"enabled": true,
"sepa_options": {
"min_retry_interval_days": 5,
"send_prenotification": true,
"prenotification_days": 5
},
"max_retries": 3
}
}'R-Code Strategies
Configure different strategies based on R-transaction codes:
curl -X POST https://api.plexypay.com/v2/payments \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"amount": 4999,
"currency": "EUR",
"customer": "cus_abc123",
"payment_method": "pm_sepa_debit_xyz789",
"auto_rescue": {
"enabled": true,
"r_code_strategies": {
"AM04": {
"retry": true,
"schedule_days": [5, 12, 20],
"notify_customer": true
},
"AC06": {
"retry": true,
"max_retries": 1,
"schedule_days": [7],
"escalate_on_failure": true
},
"MD01": {
"retry": false,
"action": "contact_customer",
"deactivate_mandate": true
},
"MD06": {
"retry": false,
"action": "process_refund"
}
}
}
}'Webhook Events
payment.sepa_return_received
Sent when an R-transaction is received.
{
"id": "evt_abc123",
"type": "payment.sepa_return_received",
"created_at": "2026-03-28T09:15:00Z",
"data": {
"payment": "pay_xyz789",
"customer": "cus_abc123",
"amount": 4999,
"currency": "EUR",
"mandate": "md_abc123",
"r_transaction": {
"code": "AM04",
"reason": "Insufficient Funds",
"received_at": "2026-03-28T09:15:00Z",
"original_debit_date": "2026-03-25"
},
"auto_rescue": {
"enabled": true,
"will_retry": true,
"next_retry_at": "2026-04-02T10:00:00Z"
}
}
}payment.rescue_retry (SEPA)
Sent when a SEPA retry is being attempted.
{
"id": "evt_def456",
"type": "payment.rescue_retry",
"created_at": "2026-04-02T10:00:00Z",
"data": {
"payment": "pay_xyz789",
"customer": "cus_abc123",
"payment_method_type": "sepa_debit",
"retry_number": 1,
"previous_r_code": "AM04",
"debit_date": "2026-04-07",
"prenotification_sent": true,
"retry_strategy": {
"r_code_category": "insufficient_funds",
"timing_reason": "payday_alignment"
}
}
}payment.rescue_succeeded (SEPA)
Sent when a SEPA payment is successfully recovered.
{
"id": "evt_ghi789",
"type": "payment.rescue_succeeded",
"created_at": "2026-04-10T14:30:00Z",
"data": {
"payment": "pay_xyz789",
"customer": "cus_abc123",
"amount": 4999,
"currency": "EUR",
"retry_number": 1,
"total_attempts": 2,
"days_to_recover": 15,
"settlement_date": "2026-04-10"
}
}sepa_mandate.requires_attention
Sent when a mandate issue is detected.
{
"id": "evt_jkl012",
"type": "sepa_mandate.requires_attention",
"created_at": "2026-03-28T09:20:00Z",
"data": {
"mandate": "md_abc123",
"customer": "cus_abc123",
"issue": "mandate_cancelled",
"r_code": "MD01",
"triggered_by_payment": "pay_xyz789",
"recommendation": "Contact customer to set up a new mandate"
}
}Handling R-Transaction Types
Insufficient Funds (AM04)
The most common return reason, often resolved with proper timing.
curl -X POST https://api.plexypay.com/v2/payments \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"amount": 4999,
"currency": "EUR",
"customer": "cus_abc123",
"payment_method": "pm_sepa_debit_xyz789",
"auto_rescue": {
"enabled": true,
"r_code_strategies": {
"AM04": {
"retry": true,
"schedule_days": [5, 16, 26],
"max_retries": 3,
"notify_customer_after_attempt": 1
}
}
}
}'Account Closed (AC04) or Incorrect (AC01)
Permanent issues requiring new account details.
app.post('/webhooks/plexy', async (req, res) => {
const event = verifyWebhook(req);
if (event.type === 'payment.sepa_return_received') {
const { r_transaction, customer } = event.data;
if (['AC01', 'AC04'].includes(r_transaction.code)) {
// Deactivate the payment method
await plexy.paymentMethods.update(event.data.payment_method, {
active: false,
deactivation_reason: r_transaction.reason,
});
// Contact customer for new account details
await sendEmail(customer, 'sepa_account_invalid', {
reason: r_transaction.reason,
update_url: 'https://yoursite.com/update-payment',
});
}
}
res.status(200).send('OK');
});Mandate Issues (MD01, MD06)
Mandate-related returns require special handling.
When you receive an MD01 return, cancel the mandate via PATCH https://api.plexypay.com/v2/mandates/{mandate_id} and notify the customer to set up a new one. When you receive an MD06 return, issue a refund via POST https://api.plexypay.com/v2/refunds:
curl -X POST https://api.plexypay.com/v2/refunds \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"payment": "pay_xyz789",
"reason": "customer_request_via_bank"
}'SEPA Core vs B2B
Auto Rescue handles both SEPA schemes:
| Aspect | SEPA Core | SEPA B2B |
|---|---|---|
| Refund right | 8 weeks (no questions) | None |
| Mandate verification | Optional | Required |
| Minimum lead time | D-2 | D-1 |
| Retry approach | More conservative | Can be more aggressive |
Configure by Scheme
curl -X POST https://api.plexypay.com/v2/payments \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"amount": 4999,
"currency": "EUR",
"customer": "cus_abc123",
"payment_method": "pm_sepa_debit_xyz789",
"payment_method_options": {
"sepa_debit": {
"mandate": "md_abc123",
"scheme": "b2b"
}
},
"auto_rescue": {
"enabled": true,
"sepa_options": {
"scheme_specific": {
"core": {
"max_retries": 2,
"retry_window_days": 14
},
"b2b": {
"max_retries": 3,
"retry_window_days": 21
}
}
}
}
}'Pre-Notification Management
SEPA requires customer notification before debits:
curl -X POST https://api.plexypay.com/v2/payments \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"amount": 4999,
"currency": "EUR",
"customer": "cus_abc123",
"payment_method": "pm_sepa_debit_xyz789",
"auto_rescue": {
"enabled": true,
"sepa_options": {
"send_prenotification": true,
"prenotification_days": 5,
"prenotification_template": "retry_notification"
}
}
}'Pre-Notification Webhook
{
"id": "evt_mno345",
"type": "sepa_prenotification.sent",
"created_at": "2026-03-27T10:00:00Z",
"data": {
"payment": "pay_xyz789",
"customer": "cus_abc123",
"amount": 4999,
"currency": "EUR",
"debit_date": "2026-04-01",
"is_retry": true,
"retry_number": 1,
"notification_type": "email"
}
}Best Practices
Timing Around Paydays
In Europe, common paydays include:
- End of month (25th-31st)
- Mid-month (15th)
- Beginning of month (1st-5th)
// Optimal retry schedule for EU paydays
auto_rescue: {
enabled: true,
sepa_options: {
// Schedule debits for 2-3 days after typical paydays
preferred_debit_days: [3, 17, 28],
},
}Monitor Mandate Health
Track mandate-related returns:
// Fetch mandate analytics
const mandateHealth = await plexy.analytics.getMandateHealth({
start_date: '2026-01-01',
end_date: '2026-03-31',
});
// Response includes:
// {
// "total_mandates": 5234,
// "active": 5012,
// "cancelled_by_customer": 89,
// "cancelled_by_r_transaction": 133,
// "r_transaction_breakdown": {
// "MD01": 98,
// "MD06": 35
// }
// }Respect Customer Requests
When you receive MD06 (refund request by customer), consider:
- Processing the refund promptly
- Reviewing the customer's subscription status
- Reaching out to understand the reason
- Potentially pausing future debits
if (r_code === 'MD06') {
// Customer went to their bank for a refund - take it seriously
await pauseSubscription(customer);
await sendEmail(customer, 'subscription_paused', {
reason: 'bank_refund_request',
contact_us: true,
});
}Know When to Stop
Unlike cards, SEPA retries should be more conservative:
| Factor | Recommendation |
|---|---|
| Max retries | 2-3 (not 4-5 like cards) |
| Window | 14-21 days |
| After MD01/MD06 | Never retry |
| Multiple AM04s | Consider contacting customer |
Next Steps
- Auto Rescue Overview - General Auto Rescue concepts
- Auto Rescue for Cards - Card-specific strategies
- SEPA Direct Debit Guide - Full SEPA integration details