API Status Support Dashboard

Dunning Management

Automatically handle failed recurring payments with smart retry logic.


Overview

Dunning is the process of recovering failed subscription payments. AuxVault's dunning system automatically:


How Dunning Works

Payment Fails β†’ Retry 1 (1 day) β†’ Retry 2 (3 days) β†’ Retry 3 (7 days) β†’ Pause/Cancel

Default Retry Schedule:


Get Dunning Settings

Endpoint

GET /api/v1/merchants/:merchantId/dunning-settings
curl https://dev.auxcore.net/api/v1/merchants/merchant_123/dunning-settings \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "X-Tenant-ID: your-tenant-id"

Response:

{
  "success": true,
  "data": {
    "enabled": true,
    "maxRetries": 3,
    "retrySchedule": [1, 3, 7],
    "emailNotifications": true,
    "actionAfterMaxRetries": "pause",
    "gracePeriodDays": 3
  }
}

Update Dunning Settings

Endpoint

PUT /api/v1/merchants/:merchantId/dunning-settings
curl -X PUT https://dev.auxcore.net/api/v1/merchants/merchant_123/dunning-settings \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "X-Tenant-ID: your-tenant-id" \
  -H "Content-Type: application/json" \
  -d '{
    "enabled": true,
    "maxRetries": 4,
    "retrySchedule": [1, 3, 5, 10],
    "emailNotifications": true,
    "actionAfterMaxRetries": "cancel"
  }'

Configuration Options

Max Retries

Number of retry attempts before giving up:

{
  "maxRetries": 3
}

Recommended: 3-4 retries

Retry Schedule

Days to wait between retry attempts:

{
  "retrySchedule": [1, 3, 7]
}

Common schedules:

Action After Max Retries

What to do when all retries fail:

Action Description Use When
pause Pause subscription Default, allows reactivation
cancel Cancel subscription Permanent cancellation
manual_review Flag for review Custom handling needed
{
  "actionAfterMaxRetries": "pause"
}

Grace Period

Days to maintain access after failure:

{
  "gracePeriodDays": 3
}

Customer keeps access for 3 days while retries happen.

Email Notifications

Send emails to customers:

{
  "emailNotifications": true,
  "emailTemplate": "payment_failed_default"
}

Monitor Failed Payments

List Failed Payments

GET /api/v1/recurring/failed-payments
curl "https://dev.auxcore.net/api/v1/recurring/failed-payments?status=retrying" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "X-Tenant-ID": your-tenant-id"

Response:

{
  "success": true,
  "data": {
    "failedPayments": [
      {
        "id": "fp_abc123",
        "subscriptionId": "sub_456",
        "customerId": "cust_789",
        "amount": 99.00,
        "failureReason": "Insufficient funds",
        "attemptCount": 2,
        "nextRetryAt": "2026-01-31T12:00:00Z",
        "status": "retrying"
      }
    ]
  }
}

Manual Retry

Force an immediate retry:

Endpoint

POST /api/v1/recurring/:subscriptionId/retry-payment
curl -X POST https://dev.auxcore.net/api/v1/recurring/sub_abc123/retry-payment \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "X-Tenant-ID: your-tenant-id"

Response:

{
  "success": true,
  "data": {
    "transactionId": "txn_retry_123",
    "status": "approved",
    "message": "Payment successfully recovered"
  }
}

Process Auto-Retry (Cron)

Trigger automatic retry processing:

Endpoint

POST /api/v1/recurring/process-auto-retry
curl -X POST https://dev.auxcore.net/api/v1/recurring/process-auto-retry \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "X-Tenant-ID: your-tenant-id"

Response:

{
  "success": true,
  "data": {
    "processed": 25,
    "recovered": 18,
    "stillFailing": 7,
    "paused": 0
  }
}

Cron Schedule

Run this endpoint on a schedule:

# Every 6 hours
0 */6 * * * curl -X POST https://dev.auxcore.net/api/v1/recurring/process-auto-retry

Webhooks

subscription.payment_failed

{
  "type": "subscription.payment_failed",
  "data": {
    "subscriptionId": "sub_abc123",
    "customerId": "cust_456",
    "amount": 99.00,
    "attemptCount": 1,
    "declineReason": "Insufficient funds",
    "nextRetryAt": "2026-01-29T12:00:00Z"
  }
}

subscription.payment_recovered

{
  "type": "subscription.payment_recovered",
  "data": {
    "subscriptionId": "sub_abc123",
    "transactionId": "txn_recovered_789",
    "amount": 99.00,
    "attemptCount": 2,
    "recoveredAt": "2026-01-30T10:00:00Z"
  }
}

subscription.dunning_failed

{
  "type": "subscription.dunning_failed",
  "data": {
    "subscriptionId": "sub_abc123",
    "customerId": "cust_456",
    "amount": 99.00,
    "attemptCount": 3,
    "action": "paused",
    "lastError": "Card declined"
  }
}

Email Notifications

Payment Failed Email

Automatically sent on first failure:

Subject: Payment Failed - Action Required
Content:

Final Notice Email

Sent before final retry:

Subject: Final Payment Attempt - Subscription at Risk
Content:

Payment Recovered Email

Sent when payment succeeds:

Subject: Payment Successful - Subscription Active
Content:


Analytics

Track dunning performance:

curl "https://dev.auxcore.net/api/v1/analytics/dunning?period=30d" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "X-Tenant-ID: your-tenant-id"

Response:

{
  "success": true,
  "data": {
    "totalFailures": 150,
    "recovered": 120,
    "stillRetrying": 20,
    "paused": 10,
    "recoveryRate": 0.80,
    "averageRetriesForRecovery": 1.8,
    "failureReasons": {
      "insufficient_funds": 60,
      "card_declined": 40,
      "card_expired": 30,
      "other": 20
    }
  }
}

Common Failure Reasons

Reason Common Cause Customer Action
Insufficient funds Not enough balance Add funds to account
Card declined Card issuer declined Try different card
Card expired Card past expiry date Update card details
Invalid card Card info incorrect Verify card details
Fraud suspected Flagged as suspicious Contact bank

Best Practices

βœ… DO:

❌ DON'T:


Improving Recovery Rates

1. Update Card Before Expiration

# Send email 30 days before card expires
curl -X POST /api/v1/notifications/card-expiration-reminder \
  -d '{"customerId": "cust_123"}'

2. Smart Retry Timing

Retry on payday (1st and 15th of month):

{
  "retrySchedule": "smart",
  "preferredDays": [1, 15]
}

3. Account Updater

Automatically update expired cards:

{
  "accountUpdater": true
}

4. Multiple Payment Methods

Allow backup payment methods:

{
  "allowBackupCard": true
}

Testing Dunning

Trigger Failed Payment

# Use decline test card
curl -X POST https://dev.auxcore.net/api/v1/recurring/sub_test_123/process-payment \
  -d '{
    "card": {
      "number": "4000000000000002"
    }
  }'
# Should fail and trigger dunning

Test Retry Logic

# Check retry schedule
curl https://dev.auxcore.net/api/v1/recurring/sub_test_123

# Manual retry
curl -X POST https://dev.auxcore.net/api/v1/recurring/sub_test_123/retry-payment

Next Steps


Need help? Contact support@auxvault.com