Vault capture deep-dive
For the admin-facing config and trigger choices, see Vault capture configuration. This page documents the service architecture and extension seams.
The pipeline at a glance
Order placement
│
▼
VaultTokenResolver
│ resolves the order's vault token (vault_payment_token row)
│ stores it on the byte8_preorder row at `vault_token_id`
│
▼
[ wait for trigger ]
│
├─ shipment_create → ShipmentPlugin marks vault_capture_pending
├─ shipment_track → TrackPlugin marks vault_capture_pending
└─ manual → admin grid action marks vault_capture_pending
│
▼
Cron/ProcessVaultCaptures (every 5 min)
│
▼
VaultMethodResolver → VaultCaptureService → gateway charge API
│
├─ success → status = succeeded → completion email
└─ failure → attempts++ → schedule retry
│
└─ if attempts ≥ max → fallback email + status = fallback_sent
Service classes
| Class | Role |
|---|---|
Model/Service/VaultTokenResolver | At order placement, finds the vault token used to pay the deposit. Stores vault_token_id and vault_method_code on the pre-order. |
Model/Service/VaultMethodResolver | Maps the order's payment method code to the right gateway adapter for vault charge. Pluggable. |
Model/Service/VaultCaptureService | The actual charge call. Wraps Magento Vault's CommandPool to execute the gateway's vault_authorize_capture command. |
Cron/ProcessVaultCaptures | The background worker that picks up vault_capture_pending pre-orders and retries with backoff. |
Plugin / extension points
Add a custom gateway adapter
If your gateway isn't auto-resolved by VaultMethodResolver, plugin around its resolveForOrder method:
public function aroundResolveForOrder(
VaultMethodResolver $subject,
callable $proceed,
OrderInterface $order
): VaultMethodInterface {
$methodCode = $order->getPayment()->getMethod();
if ($methodCode === 'my_custom_gateway_vault') {
return $this->myCustomAdapter;
}
return $proceed($order);
}
Override the retry schedule
The default schedule is attempts × retry_backoff_minutes. To change, plugin Cron/ProcessVaultCaptures::scheduleNextAttempt:
public function aroundScheduleNextAttempt(
ProcessVaultCaptures $subject,
callable $proceed,
PreorderInterface $preorder
): \DateTimeInterface {
// exponential backoff
return new \DateTimeImmutable("+{$preorder->getVaultCaptureAttempts() ** 2} hours");
}
Hook the success / failure events
VaultCaptureService dispatches:
byte8_preorder_vault_capture_success— after a successful charge, withpreorderandtransaction_idin the event data.byte8_preorder_vault_capture_failure— after a failed charge, withpreorderanderror_message.
Subscribe in etc/events.xml to wire alerts, Slack notifications, ERP updates, etc.
Schema
The byte8_preorder table carries:
| Column | Type | Notes |
|---|---|---|
vault_token_id | int | FK to vault_payment_token.entity_id |
vault_method_code | varchar | Payment method code for resolver dispatch |
vault_capture_status | varchar | Enum — see Model/Config/Source/VaultCaptureStatus |
vault_capture_attempts | int | Retry counter |
vault_capture_last_error | text | Last gateway error |
vault_capture_next_attempt_at | datetime | When the cron should next try |
vault_capture_completed_at | datetime | Success timestamp |
Plus quote_item.preorder_id so the pre-order context survives quote-to-order conversion.
Gateway-specific notes
- Stripe — works with
stripe_paymentsand the Stripe Magento connector's vault variants. Token format is the standardpm_...payment method ID. - Adyen — works with both
adyen_ccandadyen_oneclickvariants. Recurring contract reference must be present on the token. - Braintree — Vault stored as
braintreepayment method nonce → token. Both the standard and PayPal-via-Braintree flows are covered. - Authorize.net — Vault works via
authorizenet_directpostwith the CIM extension enabled. The vault token is the CIM customer profile ID. - PayPal Express — does NOT support vault capture. Pre-orders paid with PayPal Express are flagged
vault_capture_status = unsupportedat order placement and routed to the manual completion fallback automatically.
Failure modes
| Mode | What it looks like | What to do |
|---|---|---|
| Token expired | Gateway returns "Token not found" | Send the customer to the manual completion link via fallback email. |
| Customer card declined | Gateway returns insufficient funds / card-declined | Cron retries up to max_attempts. After that, fallback email. |
| Gateway outage | Network errors / 5xx | Cron retries automatically; usually clears within an hour. |
| Vault method changed | Customer deleted their stored card | vault_capture_status = unsupported, fallback email immediately. |
Related
- Vault capture configuration — the admin-facing settings.
- CLI commands —
preorder:vault:processandpreorder:vault:reset. - Cron jobs — the schedule that drives
ProcessVaultCaptures.