Integration guide
Recovering failed Braintree payments
Braintree gives you unusually detailed decline information — processor response codes, gateway rejection reasons and its own retry settings. Most teams never use it, because the follow-up lives in a separate marketing tool that only knows the payment failed. RRLabs keeps that detail attached to the outreach.
Quick answer
Braintree recovery is driven by subscription and dispute webhook notifications plus gateway rejection reasons, letting you separate soft declines worth retrying from hard declines that need a new payment method.
Events that matter
- subscription_charged_unsuccessfully
- A recurring charge was declined.
- subscription_charged_successfully
- The charge cleared — close the attempt.
- subscription_went_past_due
- Braintree exhausted its own retries.
- dispute_opened
- Stop outreach and route the case to support.
Setting it up
- 1
Register the destination
Add your RRLabs endpoint as a Braintree webhook destination and enable the subscription and dispute notifications.
- 2
Parse with the SDK
Braintree signs each notification; the payload is parsed with the SDK before anything is queued.
- 3
Use the decline detail
Processor response codes and gateway rejection reasons decide whether to retry quietly or ask for a new card.
- 4
Suppress on disputes
An open dispute halts recovery messaging for that customer immediately.
Parse a Braintree webhook notification
// Braintree → Settings → Webhooks (destination URL)
const notification = await gateway.webhookNotification.parse(bt_signature, bt_payload);
if (notification.kind === "subscription_charged_unsuccessfully") {
const sub = notification.subscription;
const tx = sub.transactions?.[0];
await rrlabs.enqueueRecovery({
provider: "braintree",
externalId: sub.id,
amountCents: Math.round(Number(sub.price) * 100),
currency: "USD",
declineCode: tx?.processorResponseCode ?? tx?.gatewayRejectionReason ?? null,
});
}
if (notification.kind === "subscription_charged_successfully") {
await rrlabs.closeRecovery({ provider: "braintree", externalId: notification.subscription.id });
}Manual recovery vs. automated recovery
| Capability | Braintree alone | With RRLabs |
|---|---|---|
| Decline handling | Retry settings applied uniformly | Response-code-aware plan per failure |
| Channels | Whatever your ESP sends | Email, WhatsApp and SMS where consented |
| Dispute safety | Manual suppression | Automatic hold when a dispute opens |
| Attribution | Gateway totals | Recovered charges linked to the outreach that preceded them |
| Source of truth | Braintree | Braintree — vaulted payment methods never leave it |
Frequently asked questions
Does RRLabs touch vaulted payment methods?
No. Payment methods stay in the Braintree vault; RRLabs works from notification metadata and customer contact details.
Can I keep Braintree's own retry schedule?
Yes. Braintree keeps retrying the charge while RRLabs handles the customer-facing sequence around those attempts.
What about PayPal-funded subscriptions?
PayPal failures arrive through the same subscription notifications, so they enter the same recovery queue with their own reason code.