# Automatic card updates

> How VINR refreshes saved card details when a bank re-issues a card, and how to handle brand changes.

VINR works with card networks to automatically update saved card details when a bank re-issues a card — for example, when a card expires or is reported lost or stolen. This lets customers continue using your service without interruption and reduces the rate of failed charges due to stale card data.

## How it works

When a card is re-issued, the issuing bank notifies the card network (Visa or Mastercard). The network passes updated details — new expiry date, and sometimes a new card number — to VINR. VINR applies the update to the stored `PaymentMethod` without any action required from you or the customer.

Coverage is broad across major Visa and Mastercard issuers in Bulgaria and the broader EEA.

## Webhook events

VINR fires webhook events when a card is updated:

- **`payment_method.updated`** — a card was updated via a VINR API call.
- **`payment_method.automatically_updated`** — the card network automatically updated a saved card.

Both events include the card's new expiration date and last four digits. If the update includes a new card number, the `fingerprint` changes.

```typescript
// POST /webhooks/vinr
const event = vinr.webhooks.verify(rawBody, req.headers['x-vinr-signature']);

if (event.type === 'payment_method.automatically_updated') {
  const card = event.data.object.card;
  const prev = event.data.previousAttributes?.card;

  console.log(`Card updated: ...${card.last4}, expires ${card.expMonth}/${card.expYear}`);

  if (prev?.fingerprint && prev.fingerprint !== card.fingerprint) {
    // PAN changed — notify the customer that their card on file has been updated
    await notifyCustomer(event.data.object.customer, 'card_updated');
  }
}
```

## Brand changes

In some cases, a card re-issuance changes the card's **brand** — for example, a Visa card re-issued as Mastercard. This is detected by comparing `brand` in `previousAttributes` with the new `brand` on the updated card.

> When a card's brand changes, you **cannot** charge it for any merchant-initiated transactions (MITs) until you obtain a new cardholder agreement. See [Customer-initiated & Merchant-initiated transactions](/docs/payments/payment-methods/add-payment-methods/cards/cit-mit).

```typescript
if (event.type === 'payment_method.automatically_updated') {
  const prevBrand = event.data.previousAttributes?.card?.brand;
  const newBrand  = event.data.object.card?.brand;

  if (prevBrand && newBrand && prevBrand !== newBrand) {
    // Block future MITs until re-authorization
    await flagForReAuthorization(event.data.object.customer);
    await notifyCustomer(event.data.object.customer, 'card_brand_changed');
  }
}
```

## Updating your own records

If you store card metadata (last 4 digits, expiry) in your own database for display purposes, sync it from the webhook payload rather than polling the API:

```typescript
if (event.type === 'payment_method.automatically_updated') {
  const { id, card } = event.data.object;
  await db.paymentMethods.update(id, {
    last4: card.last4,
    expMonth: card.expMonth,
    expYear: card.expYear,
    brand: card.brand,
  });
}
```

## See also

[Customer-initiated & Merchant-initiated](/docs/payments/payment-methods/add-payment-methods/cards/cit-mit) — Re-authorization requirements when a card brand changes.

[Update & replace](/docs/payments/payment-methods/manage-payment-methods/update) — Manual update and re-collection flows.
