DEV Community

Swipe Again for Swipe Again

Posted on

Braintree's Vault Knows the New Card. Your Retry Still Used the Old One.

The strangest Braintree failures start with good news. A customer's card was replaced, the network account updater did its work, and the Vault quietly held a fresh number with a later expiry. Support could see the update. Billing could see the update. Then the scheduled retry ran, charged the old payment method token, and failed again for exactly the same reason.

That is not an account updater failure. It is a plumbing failure between storage and execution: the system that stores credentials is not necessarily the system that decides which credential a retry will present. This teardown follows one renewal through that gap, step by step, because the fix is rarely to retry harder. It is to prove, before each attempt, which token will actually be used.

The annotated sequence

T-minus 30 days: the subscription is created. The customer checks out, Braintree tokenizes the card, and your subscription record stores a reference to that payment method. Annotation: note what you stored. Many teams store a token on the subscription or invoice at creation time, not a live pointer that says, in effect, always use this customer's current default method. That distinction looks harmless on day one and decides everything on day ninety.

T-minus 12 days: the issuer replaces the card. Fraud, loss, or a routine reissue triggers a new number. Account updater services pass the new credentials to the Vault, and the vaulted record is refreshed. Annotation: refreshed where? An update can land on the customer record while a second, older token still exists alongside it — a duplicate from a repeat checkout, a saved backup card, or a method attached to a different customer profile created by a support tool. The Vault knowing is not the same as your retry knowing which Vault entry to choose.

Day 0: the first renewal declines. The charge runs against a token that now points to cancelled credentials, or against the stale duplicate. The decline looks like a money problem when it is really an identity problem: which card did we mean? Annotation: record the token fingerprint, last four, and expiry actually attempted, not just the decline code. Without that, every later step is guesswork.

Day 1 to 3: dunning starts, correctly and uselessly. Your emails ask the customer to update a card they believe they already updated, because their bank told them the merchant would get the new details automatically. Trust leaks here. Annotation: before sending a card-update request, check whether a newer vaulted method already exists. If it does, the honest message is not update your card; it is we are retrying with the details your bank sent us.

Day 4: the retry re-reads stale state. A job loads the subscription, pulls the payment method captured when the invoice was created, and submits it again. The Vault's newer credentials never enter the picture because nothing re-resolved the customer's current default at retry time. For more on how Braintree dunning handles replaced cards, that re-resolution step is the hinge the whole sequence turns on.

Checks to run before any retry

First, re-fetch, do not remember. At retry time, load the customer fresh and resolve the current default payment method, then compare its fingerprint with the one that failed. If they differ, retry the new one and log the swap. If they match, you have a genuine decline to treat.

Second, deduplicate the Vault. List every method on the customer, flag duplicates and orphaned tokens, and make one method unambiguously primary. Retries should never have to guess.

Third, separate hard from soft signals. An expired or replaced card calls for credential repair. Insufficient funds calls for timing, ideally around when the customer is paid. Authentication or do-not-honor responses call for stopping and contacting the customer, not for burning attempts.

Fourth, check the descriptor. The name the customer sees on their statement should match the name on your emails and your product. A retry that finally succeeds can still turn into a chargeback or a panicked support ticket if the descriptor looks unfamiliar, especially after a confusing week of failure notices.

What to log so this is debuggable

Log, for every attempt: subscription ID, token attempted, fingerprint and last four, whether account updater had supplied a successor, the decline category, and the source of the token — subscription record, invoice snapshot, or fresh customer lookup. With those six fields, a stale-token failure announces itself in one query. Without them, teams blame the issuer, add more retries, and make the noise worse.

None of this requires heroic engineering. It requires treating a retry as a new decision, not a replay. Swipe Again's failed payment recovery exists for subscription businesses that want that decision made carefully — decline-aware retries and clear customer messaging for a flat $179/mo — but the checks above are worth doing in any stack, today, before the next cohort renews against a card that was replaced weeks ago.

Top comments (0)