Dunning profiles
Overview
Dunning profiles let you customize payment recovery behavior beyond the default settings. Each profile defines:
- Retry schedule: How many retries and how often
- Failure handling: What happens when all retries fail
- Email notifications: Which emails to send at each retry step
Profiles are applied at the start of a dunning cycle and remain locked for that cycle. Changes to a profile don’t affect in-flight dunning cycles.
Profile types
PaymentKit supports two types of dunning profiles with fundamentally different retry strategies:
Mutual exclusivity: A subscription uses either an adaptive or custom profile, never both. If multiple profiles match, custom profile assignments take precedence.
Adaptive profiles (system defaults)
Adaptive profiles are system-managed and use intelligent retry scheduling that responds to decline types:
Intelligent retry behaviors
Adaptive profiles automatically inject additional retry attempts based on decline type:
The 12-retry ceiling for adaptive profiles reserves capacity for these system-injected retries, ensuring you never exceed the network’s 15-retry-per-card limit.
System defaults cannot be modified or deleted, but you can clone them to create custom variations.
Custom profiles
Custom profiles give you full control over retry behavior with fixed, predictable intervals. Create custom profiles when you need deterministic retry schedules or have specific compliance requirements.
What custom profiles provide:
- Full 15-retry ceiling (the network maximum)
- Fixed
retry_interval_hoursfor all retry attempts - Consistent, predictable timing between retries
What custom profiles don’t include:
- No technical retries (TECHNICAL declines use standard interval)
- No liquidity retries (SOFT declines use standard interval)
- No final retry injection (renewal wall clamps retries but doesn’t inject a final one)
Custom profiles treat all decline types identically, using your configured retry_interval_hours for every retry attempt.
Create a profile
Profile settings
Email map
The email_map array controls which email templates are sent at each retry step:
Use retry_step: -1 to target the final retry, regardless of how many retries are configured.
Clone a profile
Create a copy of an existing profile (including system defaults):
Archive a profile
Archiving soft-deletes a profile. Archived profiles don’t appear in the default list but remain accessible by ID. In-flight dunning cycles using the profile continue unaffected.
Profile assignments
By default, PaymentKit selects a system default profile based on the subscription’s billing cycle. Use profile assignments to override this for specific prices or billing cycle categories.
Resolution order
When a dunning cycle starts, PaymentKit resolves the profile using a 2-tier priority:
- Price assignment — If the subscription’s price has a profile assigned, use that profile
- Cycle-length assignment — If no price assignment, check for a cycle_length category assignment
- System default — Fall back to the system default for the billing cycle type
Assign to a price
Target a specific product price for custom dunning behavior:
Assign to a cycle length
Target all subscriptions with a specific billing cycle category:
Valid cycle lengths: daily, short, medium, long
List assignments
Delete an assignment
Profile snapshots
When a dunning cycle starts, PaymentKit captures a snapshot of the assigned profile’s settings. This snapshot is immutable for the duration of the dunning cycle.
Changes to a profile (including archiving) don’t affect dunning cycles already in progress. Each cycle uses its frozen snapshot.
This ensures predictable behavior:
- Updating
max_retriesfrom 8 to 5 won’t suddenly cut short an in-progress cycle - Archiving a profile won’t disrupt active dunning cycles using it
- New dunning cycles always get the latest profile settings
The snapshot is stored in the dunning state and includes all profile fields:
Best practices
System defaults are optimized for common billing cycles. Clone them as a starting point for custom profiles.
Assign profiles to specific prices (e.g., annual enterprise plans) rather than creating many cycle-length assignments.
When testing, create a profile with retry_interval_hours: 1 to see the full dunning cycle quickly.
Most merchants need 1-3 profiles. Complex assignment hierarchies are harder to reason about.