PlexySDK DOCS

Real-Time Account Updater

Automatically check for card updates at the moment of payment to maximize authorization rates

Real-Time Account Updater

Real-Time Account Updater queries card networks for updated credentials at the exact moment you attempt a payment. If the card has been replaced or renewed, Plexy automatically uses the new details, maximizing your chances of a successful authorization.

How It Works

When you submit a payment with Real-Time Account Updater enabled, Plexy checks for card updates before sending the authorization request:

The Real-Time Account Updater query typically adds 50-200ms to payment processing. This small latency increase is usually offset by significantly higher authorization rates.

Enabling Real-Time Updates

Per-Payment Basis

Enable Real-Time Account Updater for individual payments:

curl -X POST https://api.plexypay.com/v2/payments \
  -H "x-api-key: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 4999,
    "currency": "USD",
    "customer": "cus_abc123",
    "payment_method": "pm_card_visa_abc123",
    "off_session": true,
    "account_updater": {
      "enabled": true,
      "mode": "realtime"
    },
    "metadata": {
      "subscription_id": "sub_xyz789"
    }
  }'
import { Plexy } from '@plexy/plexy-web';

const plexy = new Plexy({
  apiKey: process.env.PLEXY_SECRET_KEY,
});

const payment = await plexy.payments.create({
  amount: 4999,
  currency: 'USD',
  customer: 'cus_abc123',
  payment_method: 'pm_card_visa_abc123',
  off_session: true,
  account_updater: {
    enabled: true,
    mode: 'realtime',
  },
  metadata: {
    subscription_id: 'sub_xyz789',
  },
});

console.log('Payment status:', payment.status);

if (payment.account_updater_result) {
  console.log('Card was updated:', payment.account_updater_result.update_type);
}
import os
from plexy import Plexy

plexy = Plexy(api_key=os.environ['PLEXY_SECRET_KEY'])

payment = plexy.payments.create(
    amount=4999,
    currency='USD',
    customer='cus_abc123',
    payment_method='pm_card_visa_abc123',
    off_session=True,
    account_updater={
        'enabled': True,
        'mode': 'realtime',
    },
    metadata={
        'subscription_id': 'sub_xyz789',
    },
)

print(f"Payment status: {payment.status}")

if payment.account_updater_result:
    print(f"Card was updated: {payment.account_updater_result['update_type']}")

Account-Level Default

Enable Real-Time Account Updater for all off-session payments in Plexy Dashboard:

Navigate to Settings > Account Management > Account Updater.

Toggle Real-Time Account Updater to enabled.

Choose when to apply:

  • All off-session payments (recommended)
  • Subscription payments only
  • Payments over threshold amount

API Response Fields

When Real-Time Account Updater runs, the payment response includes additional fields:

Successful Payment with Update

{
  "id": "pay_xyz789",
  "object": "payment",
  "amount": 4999,
  "currency": "USD",
  "status": "succeeded",
  "customer": "cus_abc123",
  "payment_method": "pm_card_visa_abc123",
  "payment_method_details": {
    "type": "card",
    "card": {
      "brand": "visa",
      "last4": "8910",
      "exp_month": 6,
      "exp_year": 2030
    }
  },
  "account_updater_result": {
    "queried": true,
    "update_found": true,
    "update_type": "new_pan",
    "update_applied": true,
    "previous_card": {
      "last4": "4242",
      "exp_month": 12,
      "exp_year": 2026
    },
    "updated_card": {
      "last4": "8910",
      "exp_month": 6,
      "exp_year": 2030
    }
  },
  "created_at": "2026-03-25T10:30:00Z"
}

Payment with No Update Needed

{
  "id": "pay_abc456",
  "object": "payment",
  "amount": 4999,
  "currency": "USD",
  "status": "succeeded",
  "customer": "cus_abc123",
  "payment_method": "pm_card_visa_abc123",
  "payment_method_details": {
    "type": "card",
    "card": {
      "brand": "visa",
      "last4": "4242",
      "exp_month": 12,
      "exp_year": 2028
    }
  },
  "account_updater_result": {
    "queried": true,
    "update_found": false,
    "update_type": "no_update"
  },
  "created_at": "2026-03-25T10:35:00Z"
}

Payment Failed - Account Closed

{
  "id": "pay_def789",
  "object": "payment",
  "amount": 4999,
  "currency": "USD",
  "status": "failed",
  "failure_code": "card_not_supported",
  "failure_message": "The card account has been closed.",
  "customer": "cus_abc123",
  "payment_method": "pm_card_visa_abc123",
  "account_updater_result": {
    "queried": true,
    "update_found": true,
    "update_type": "account_closed",
    "update_applied": false,
    "action_required": "contact_cardholder"
  },
  "created_at": "2026-03-25T10:40:00Z"
}

Response Field Reference

FieldTypeDescription
account_updater_result.queriedbooleanWhether Account Updater was checked
account_updater_result.update_foundbooleanWhether an update was found
account_updater_result.update_typestringType of update: new_pan, new_expiry, account_closed, contact_cardholder, no_update
account_updater_result.update_appliedbooleanWhether the update was applied to the payment method
account_updater_result.previous_cardobjectCard details before the update
account_updater_result.updated_cardobjectCard details after the update
account_updater_result.action_requiredstringRecommended action if update couldn't be applied

Handling Update Types

New Card Number (new_pan)

The cardholder received a replacement card with a new number.

if (payment.account_updater_result?.update_type === 'new_pan') {
  // Card was automatically updated
  // Log the change for your records
  await logCardUpdate({
    customer: payment.customer,
    oldLast4: payment.account_updater_result.previous_card.last4,
    newLast4: payment.account_updater_result.updated_card.last4,
    reason: 'account_updater_new_pan',
  });

  // Update any customer-facing displays
  await updateCustomerCardDisplay(payment.customer);
}

New Expiration Date (new_expiry)

The card was renewed with a new expiration date.

if (payment.account_updater_result?.update_type === 'new_expiry') {
  // Card expiry was automatically updated
  const { previous_card, updated_card } = payment.account_updater_result;

  console.log(
    `Card expiry updated from ${previous_card.exp_month}/${previous_card.exp_year} ` +
      `to ${updated_card.exp_month}/${updated_card.exp_year}`,
  );
}

Account Closed

The cardholder's account has been closed. The payment will fail.

if (payment.account_updater_result?.update_type === 'account_closed') {
  // Mark the payment method as inactive
  await plexy.paymentMethods.update(payment.payment_method, {
    active: false,
    deactivation_reason: 'account_closed',
  });

  // Queue customer outreach
  await notificationService.send({
    type: 'payment_method_expired',
    customer: payment.customer,
    message:
      'Your saved card is no longer valid. Please update your payment method.',
  });
}

Contact Cardholder

No update was found, but the card may be outdated. The payment may still succeed, but you should follow up with the customer.

if (payment.account_updater_result?.update_type === 'contact_cardholder') {
  if (payment.status === 'succeeded') {
    // Payment succeeded, but card may need attention soon
    await queueFollowUp({
      customer: payment.customer,
      priority: 'low',
      reason: 'card_may_need_update',
    });
  } else {
    // Payment failed, contact customer urgently
    await queueFollowUp({
      customer: payment.customer,
      priority: 'high',
      reason: 'payment_failed_update_card',
    });
  }
}

Webhook Notifications

In addition to the API response, Plexy sends webhooks for card updates:

payment_method.updated

Sent when a card is successfully updated during a real-time query.

{
  "id": "evt_abc123",
  "type": "payment_method.updated",
  "created_at": "2026-03-25T10:30:00Z",
  "data": {
    "payment_method": "pm_card_visa_abc123",
    "customer": "cus_abc123",
    "update_source": "realtime_account_updater",
    "update_type": "new_pan",
    "triggered_by_payment": "pay_xyz789",
    "changes": {
      "last4": {
        "old": "4242",
        "new": "8910"
      },
      "exp_month": {
        "old": 12,
        "new": 6
      },
      "exp_year": {
        "old": 2026,
        "new": 2030
      }
    }
  }
}

Best Practices

Enable for All Recurring Payments

Real-Time Account Updater is most valuable for recurring and subscription payments:

async function processSubscriptionPayment(subscription) {
  const payment = await plexy.payments.create({
    amount: subscription.amount,
    currency: subscription.currency,
    customer: subscription.customer,
    payment_method: subscription.payment_method,
    off_session: true,
    account_updater: {
      enabled: true,
      mode: 'realtime',
    },
    metadata: {
      subscription_id: subscription.id,
      billing_period: subscription.current_period,
    },
  });

  return payment;
}

Combine with Auto Rescue

If Real-Time Account Updater reports an account closure or contact recommendation, enable Auto Rescue for fallback retries:

const payment = await plexy.payments.create({
  amount: 4999,
  currency: 'USD',
  customer: 'cus_abc123',
  payment_method: 'pm_card_visa_abc123',
  off_session: true,
  account_updater: {
    enabled: true,
    mode: 'realtime',
  },
  auto_rescue: {
    enabled: true,
    max_retries: 4,
  },
});

Log All Updates

Keep a record of all card updates for compliance and customer service:

app.post('/webhooks/plexy', async (req, res) => {
  const event = verifyWebhook(req);

  if (event.type === 'payment_method.updated') {
    await db.cardUpdates.create({
      payment_method: event.data.payment_method,
      customer: event.data.customer,
      update_source: event.data.update_source,
      update_type: event.data.update_type,
      changes: event.data.changes,
      triggered_by: event.data.triggered_by_payment,
      timestamp: event.created_at,
    });
  }

  res.status(200).send('OK');
});

Latency Considerations

Real-Time Account Updater adds processing time:

ScenarioAdditional Latency
No update found50-100ms
Update found and applied100-200ms
Network timeout (falls back)500ms max

If the Real-Time Account Updater query times out, Plexy automatically proceeds with the original card details. The payment will still be attempted.

Disabling for Time-Sensitive Payments

For extremely time-sensitive transactions, you can disable Real-Time Account Updater:

const payment = await plexy.payments.create({
  amount: 100,
  currency: 'USD',
  customer: 'cus_abc123',
  payment_method: 'pm_card_visa_abc123',
  account_updater: {
    enabled: false, // Skip real-time check for this payment
  },
});

Next Steps

На этой странице