Week Ending 2026-07-17

Visa single-card enrollment — supported countries

  • You can now enroll Visa cards issued in Portugal (PRT) and Belgium (BEL) via single-card enrollment. Ask us if you need help with this configuration setting.

3DS / verification failure reasons — providerMessage + adviceCode

  • Failed verifications now expose two additional, more actionable fields. failureReason.providerMessage carries the provider's cardholder-safe message for the specific decline (e.g. "Your card does not support this type of purchase.") — safe to surface directly to a cardholder — and failureReason.adviceCode carries the issuer's authorization advice code verbatim (try_again_later / do_not_try_again / confirm_card) so your retry logic can branch on the issuer's actual guidance. Decode coverage also expanded across the Stripe and legacy-3DS paths (granular Stripe decline capture, full EMV reason tables), and declines that fail at create-time now leave a queryable verification record instead of none.

Card Enrollment SDK — enrollment progress stepper

  • The enrollment form now shows a progress stepper, and you can relabel each step. A new optional statusLabels config on openForm lets you override the four progress messages (creatingSubscription, startingVerification, verifying, finishing) to match your product's voice, alongside the existing terms.* options.

transaction.created / transaction.updated webhooks + GET /transactions

  • Transactions now report which messages were superseded by dedup, so a visible-message sum reconciles to settledAmount. The aggregation fold already dropped duplicate FINL_ADVC messages from _links.messages[] but discarded their identity — meaning a consumer summing the visible messages could land on a total that didn't match settledAmount with no way to see why. Transactions now carry an additive supersededMessageIds array listing the deduped message ids; _links.messages membership is unchanged (still append-only), so this is purely additive — use the array to explain any gap between visible messages and the settled total.

Sandbox

  • Commercial test cards are now available in the sandbox. If your account blocks consumer cards (blockedCardTypes: ['CONSUMER']), every prior sandbox test card resolved to CONSUMER in the live BIN lookup and was rejected — leaving integrators with nothing that passes the block. Sandbox enrollments now classify published test cards from the shared test-card registry (so a commercial card is treated as COMMERCIAL while the card-type control still runs), and new commercial PANs were added on both networks: Mastercard 5200828282828897 (frictionless) and 5555552500001001 (3DS challenge), Visa 4000000000003220 (3DS via Stripe). The sandbox test-card matrix now has a Product (Consumer/Commercial) column.
  • Correction to last week's VBDS sandbox note. Last week (release-notes-2026-07-10) announced a dedicated POST /simulate/ingestion/vbds endpoint for injecting synthetic Visa activity. That route was never wired onto the sandbox gateway (it returned 404), and has been removed from the docs. VBDS is pull-based: to simulate Visa activity, create a feed with POST /network-bulk-feeds — in sandbox this automatically fetches synthetic starter data sized by the newCards field (1–20, default 5), and you can re-drive the pipeline by attributing a scenario to the vbds source. Mastercard (SmartData) and Amex (GL) simulate-ingestion endpoints are unaffected.