Auto Rescue
Automatically recover failed payments with intelligent retry logic and optimized timing
Auto Rescue
Auto Rescue automatically retries failed payments using machine learning-optimized strategies to maximize recovery rates. Instead of immediately failing a payment when declined, Auto Rescue analyzes the failure reason and schedules intelligent retries at optimal times.
How Auto Rescue Works
When a payment fails, Auto Rescue evaluates the decline reason and determines the best recovery strategy:
Why Auto Rescue Works
Auto Rescue combines multiple optimization techniques:
| Technique | Description | Impact |
|---|---|---|
| Optimal timing | ML-predicted best times to retry | +15-25% recovery |
| Account Updater | Check for card updates before retry | +5-10% recovery |
| Network tokens | Use network tokens when available | +2-5% auth rate |
| Decline analysis | Different strategies per decline type | Targeted retries |
| Issuer intelligence | Learned issuer behaviors and preferences | Better timing |
Enabling Auto Rescue
Per-Payment Basis
Enable Auto Rescue for individual payments:
curl -X POST https://api.plexypay.com/v2/payments \
-H "x-api-key: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"amount": 4999,
"currency": "USD",
"customer": "cus_abc123",
"payment_method": "pm_card_visa_abc123",
"off_session": true,
"auto_rescue": {
"enabled": true,
"max_retries": 4,
"retry_window_days": 14
},
"metadata": {
"subscription_id": "sub_xyz789"
}
}'import { Plexy } from '@plexy/plexy-web';
const plexy = new Plexy({
apiKey: process.env.PLEXY_SECRET_KEY,
});
const payment = await plexy.payments.create({
amount: 4999,
currency: 'USD',
customer: 'cus_abc123',
payment_method: 'pm_card_visa_abc123',
off_session: true,
auto_rescue: {
enabled: true,
max_retries: 4,
retry_window_days: 14,
},
metadata: {
subscription_id: 'sub_xyz789',
},
});
if (payment.status === 'requires_rescue') {
console.log('Payment failed, Auto Rescue initiated');
console.log('First retry scheduled:', payment.rescue_schedule.next_retry_at);
}import os
from plexy import Plexy
plexy = Plexy(api_key=os.environ['PLEXY_SECRET_KEY'])
payment = plexy.payments.create(
amount=4999,
currency='USD',
customer='cus_abc123',
payment_method='pm_card_visa_abc123',
off_session=True,
auto_rescue={
'enabled': True,
'max_retries': 4,
'retry_window_days': 14,
},
metadata={
'subscription_id': 'sub_xyz789',
},
)
if payment.status == 'requires_rescue':
print('Payment failed, Auto Rescue initiated')
print(f"First retry scheduled: {payment.rescue_schedule['next_retry_at']}")Account-Level Default
Enable Auto Rescue for all qualifying payments in Plexy Dashboard:
Go to Settings > Account Management > Auto Rescue.
Toggle Auto Rescue to enabled.
Set default parameters:
- Maximum retries: 1-8 retry attempts
- Retry window: 7-30 days
- Retry schedule: Automatic (ML-optimized) or Custom
Choose which payment types qualify:
- Subscription payments
- Off-session payments
- Payments over threshold amount
Configuration Options
| Parameter | Type | Default | Description |
|---|---|---|---|
enabled | boolean | false | Enable Auto Rescue for this payment |
max_retries | integer | 4 | Maximum number of retry attempts (1-8) |
retry_window_days | integer | 14 | Days to continue retrying (7-30) |
retry_schedule | string | "automatic" | "automatic" or "custom" |
custom_schedule_days | array | - | Custom retry days, e.g., [1, 3, 7, 14] |
notify_customer | boolean | true | Send customer notifications on retry events |
check_account_updater | boolean | true | Check for card updates before each retry |
Custom Retry Schedule
Define your own retry timing:
const payment = await plexy.payments.create({
amount: 4999,
currency: 'USD',
customer: 'cus_abc123',
payment_method: 'pm_card_visa_abc123',
off_session: true,
auto_rescue: {
enabled: true,
retry_schedule: 'custom',
custom_schedule_days: [1, 2, 5, 10, 15], // Retry on days 1, 2, 5, 10, 15
max_retries: 5,
},
});Decline Categories and Handling
Auto Rescue categorizes declines and applies different strategies:
Soft Declines (Retryable)
Temporary issues that often resolve with time.
| Decline Code | Description | Strategy |
|---|---|---|
insufficient_funds | Not enough balance | Retry after payday (1-3 days) |
try_again_later | Issuer requests retry | Retry in 24-48 hours |
exceeds_limit | Over daily/weekly limit | Retry after limit reset |
issuer_unavailable | Issuer system down | Immediate retry |
processing_error | Generic processing issue | Retry in 24 hours |
Technical Errors (Immediate Retry)
Infrastructure issues that may resolve quickly.
| Error Code | Description | Strategy |
|---|---|---|
network_timeout | Connection timeout | Immediate retry |
gateway_error | Payment gateway issue | Immediate retry |
system_error | Plexy system issue | Immediate retry |
Hard Declines (No Retry)
Permanent issues requiring customer action.
| Decline Code | Description | Action |
|---|---|---|
stolen_card | Card reported stolen | Stop, notify merchant |
lost_card | Card reported lost | Stop, notify merchant |
fraud_suspected | Issuer suspects fraud | Stop, contact customer |
card_not_supported | Card type not accepted | Stop, request new card |
account_closed | Account permanently closed | Stop, request new card |
Hard declines are never retried. Attempting to retry these can damage your relationship with issuers and increase your fraud rate.
Payment Status During Rescue
| Status | Description |
|---|---|
requires_rescue | Initial payment failed, retries scheduled |
rescue_in_progress | Currently attempting a retry |
succeeded | Payment recovered successfully |
failed | All retries exhausted, payment failed permanently |
rescue_cancelled | Auto Rescue was manually cancelled |
API Response with Auto Rescue
Initial Payment Failure
{
"id": "pay_xyz789",
"object": "payment",
"amount": 4999,
"currency": "USD",
"status": "requires_rescue",
"customer": "cus_abc123",
"payment_method": "pm_card_visa_abc123",
"failure_code": "insufficient_funds",
"failure_message": "The card has insufficient funds.",
"auto_rescue": {
"enabled": true,
"status": "active",
"attempts_made": 1,
"max_retries": 4,
"retry_window_ends_at": "2026-04-08T10:30:00Z"
},
"rescue_schedule": {
"next_retry_at": "2026-03-26T10:30:00Z",
"retry_number": 1,
"scheduled_retries": [
{ "retry_number": 1, "scheduled_at": "2026-03-26T10:30:00Z" },
{ "retry_number": 2, "scheduled_at": "2026-03-28T14:00:00Z" },
{ "retry_number": 3, "scheduled_at": "2026-04-01T10:30:00Z" },
{ "retry_number": 4, "scheduled_at": "2026-04-08T10:30:00Z" }
]
},
"created_at": "2026-03-25T10:30:00Z"
}Successful Recovery
{
"id": "pay_xyz789",
"object": "payment",
"amount": 4999,
"currency": "USD",
"status": "succeeded",
"customer": "cus_abc123",
"payment_method": "pm_card_visa_abc123",
"auto_rescue": {
"enabled": true,
"status": "recovered",
"attempts_made": 3,
"max_retries": 4,
"recovered_at": "2026-04-01T10:35:00Z"
},
"rescue_history": [
{
"attempt": 1,
"attempted_at": "2026-03-25T10:30:00Z",
"result": "failed",
"failure_code": "insufficient_funds"
},
{
"attempt": 2,
"attempted_at": "2026-03-26T10:30:00Z",
"result": "failed",
"failure_code": "insufficient_funds"
},
{
"attempt": 3,
"attempted_at": "2026-04-01T10:35:00Z",
"result": "succeeded"
}
],
"created_at": "2026-03-25T10:30:00Z"
}Webhook Events
payment.rescue_started
Sent when Auto Rescue begins for a failed payment.
{
"id": "evt_abc123",
"type": "payment.rescue_started",
"created_at": "2026-03-25T10:30:00Z",
"data": {
"payment": "pay_xyz789",
"customer": "cus_abc123",
"amount": 4999,
"currency": "USD",
"failure_code": "insufficient_funds",
"rescue_schedule": {
"max_retries": 4,
"first_retry_at": "2026-03-26T10:30:00Z",
"final_retry_at": "2026-04-08T10:30:00Z"
}
}
}payment.rescue_retry
Sent before each retry attempt.
{
"id": "evt_def456",
"type": "payment.rescue_retry",
"created_at": "2026-03-26T10:30:00Z",
"data": {
"payment": "pay_xyz789",
"customer": "cus_abc123",
"retry_number": 1,
"attempts_remaining": 3,
"account_updater_checked": true,
"card_was_updated": false
}
}payment.rescue_succeeded
Sent when a payment is successfully recovered.
{
"id": "evt_ghi789",
"type": "payment.rescue_succeeded",
"created_at": "2026-04-01T10:35:00Z",
"data": {
"payment": "pay_xyz789",
"customer": "cus_abc123",
"amount": 4999,
"currency": "USD",
"retry_number": 3,
"total_attempts": 3,
"days_to_recover": 7
}
}payment.rescue_failed
Sent when all retry attempts are exhausted.
{
"id": "evt_jkl012",
"type": "payment.rescue_failed",
"created_at": "2026-04-08T10:35:00Z",
"data": {
"payment": "pay_xyz789",
"customer": "cus_abc123",
"amount": 4999,
"currency": "USD",
"total_attempts": 5,
"final_failure_code": "insufficient_funds",
"recommendation": "Contact customer to update payment method"
}
}Managing Active Rescues
List Payments in Rescue
curl "https://api.plexypay.com/v2/payments?status=requires_rescue" \
-H "x-api-key: Bearer YOUR_API_KEY"const payments = await plexy.payments.list({
status: 'requires_rescue',
});
for (const payment of payments.data) {
console.log(`Payment ${payment.id}: next retry ${payment.rescue_schedule.next_retry_at}`);
}payments = plexy.payments.list(status='requires_rescue')
for payment in payments.data:
print(f"Payment {payment.id}: next retry {payment.rescue_schedule['next_retry_at']}")Cancel Auto Rescue
Stop retrying a specific payment:
curl -X POST https://api.plexypay.com/v2/payments/pay_xyz789/cancel_rescue \
-H "x-api-key: Bearer YOUR_API_KEY"const payment = await plexy.payments.cancelRescue('pay_xyz789');
console.log('Rescue cancelled:', payment.auto_rescue.status);payment = plexy.payments.cancel_rescue('pay_xyz789')
print(f"Rescue cancelled: {payment.auto_rescue['status']}")Trigger Immediate Retry
Force an immediate retry attempt:
curl -X POST https://api.plexypay.com/v2/payments/pay_xyz789/retry_now \
-H "x-api-key: Bearer YOUR_API_KEY"Best Practices
Combine with Customer Communication
Use webhooks to coordinate Auto Rescue with customer notifications:
app.post('/webhooks/plexy', async (req, res) => {
const event = verifyWebhook(req);
switch (event.type) {
case 'payment.rescue_started':
// Send initial notification
await sendEmail(event.data.customer, 'payment_failed_retrying', {
amount: formatCurrency(event.data.amount, event.data.currency),
next_retry: event.data.rescue_schedule.first_retry_at,
});
break;
case 'payment.rescue_failed':
// All retries failed - urgent action needed
await sendEmail(event.data.customer, 'payment_failed_final', {
amount: formatCurrency(event.data.amount, event.data.currency),
update_url: `https://yoursite.com/update-payment`,
});
break;
case 'payment.rescue_succeeded':
// Payment recovered - send confirmation
await sendEmail(event.data.customer, 'payment_recovered', {
amount: formatCurrency(event.data.amount, event.data.currency),
});
break;
}
res.status(200).send('OK');
});Monitor Recovery Metrics
Track Auto Rescue performance in Plexy Dashboard:
| Metric | Description | Target |
|---|---|---|
| Recovery rate | % of failed payments recovered | > 30% |
| Average recovery time | Days to successful retry | < 7 days |
| Retry success by attempt | Which retry number succeeds most | Optimize schedule |
| Recovery by decline type | Success rate per decline reason | Identify patterns |
Set Appropriate Retry Windows
Match your retry window to your billing cycle:
| Billing Cycle | Recommended Window | Rationale |
|---|---|---|
| Weekly | 7 days | Capture next week's billing |
| Monthly | 14-21 days | Allow for payday cycles |
| Annual | 30 days | Maximum recovery opportunity |
Next Steps
- Auto Rescue for Cards - Card-specific retry strategies
- Auto Rescue for SEPA - SEPA Direct Debit retries
- Account Updater - Keep cards current before retries