The architectural commitment
Vorel’s payment-collection architecture is sealed by an internal, audited architecture decision record (PCI vault-redirect to a PCI-compliant payment provider). The decision binds Vorel to a single payment shape:- The agent creates a hosted-checkout session via the payment provider’s server API.
- The agent sends your customer the provider’s hosted URL via SMS (voice channels) or an inline provider-branded button (chat channels).
- Your customer enters their card details directly into the provider’s hosted page.
- The provider acknowledges the payment via webhook to Vorel.
- Vorel receives the checkout session id, the payment-intent id, and a
payment_resolutionenum, nothing else.
SAQ-A merchant scope
Vorel’s PCI merchant scope is SAQ-A, Self-Assessment Questionnaire A. This is the questionnaire designed for merchants that have fully outsourced all cardholder data functions to PCI DSS validated third-party service providers, and retain no electronic storage, processing, or transmission of cardholder data on their systems or premises. The contrast with PCI Level 1 (the merchant scope that vendors who actually touch PANs must clear) is material:| Scope | Audit work | Annual cost | Vorel? |
|---|---|---|---|
| SAQ-A | Self-assessment questionnaire; no QSA engagement; quarterly ASV scan optional | ~$0 | Today |
| PCI Level 1 | Qualified Security Assessor (QSA) on-site audit; ~6-month observation; ROC document | 100K | Not the path |
The SMS-first user experience
When the voice agent reaches a point in the conversation where a payment is needed (a restaurant booking deposit, a salon appointment hold, an auto-service intake confirmation), the flow is:Agent creates a hosted-checkout session
Server-side, the agent calls the payment provider’s session-creation API with the amount,
currency, line items, and per-tenant provider account credentials. The provider returns a
single-use hosted URL.
Agent reads a short TTS line + simultaneously sends the SMS
The agent says, for a restaurant pack: “I’ll text you a secure link to hold your table.
Please complete it within 5 minutes.” The SMS arrives at the same time, carrying the hosted URL.
Customer completes payment on the provider's hosted page
Your customer taps the SMS link, enters their card on the provider’s PCI-validated checkout page,
and submits. Vorel has no DOM access to this page: there is no inline embed, no iframe, no
Vorel-injected JavaScript.
pending_payment state until the webhook arrives or the booking-hold window expires.
Per-pack timeouts
Different verticals have different urgency profiles. Restaurant diners are time-pressed and impatient; salon and auto-service customers can wait longer for the link to land. The per-pack windows are sealed in the same audited decision record:| Pack | Active-conversation timeout (agent waits) | Booking-hold window | Drop behavior |
|---|---|---|---|
| Restaurant | 5 minutes (diners time-pressed) | 24 hours | Graceful continuation; booking holds in pending_payment |
| Salon | 10 minutes | 24 hours | Same |
| Auto service | 10 minutes | 24 hours | Same |
| Real estate | n/a (real estate does not collect card payments at booking) | n/a | n/a |
pci_vault_redirect_failed), and emits a payment_resolution='customer_abandoned' outcome on the call cost record.
The three hard-forbidden builds
The decision record names three payment-collection patterns as architecturally hard-forbidden. They will not ship without a policy amendment plus a code change to the lint gate. Each is forbidden because shipping it would pull Vorel into a PCI scope Vorel has architecturally committed to avoid.- DTMF card capture on voice paths. The voice service does not accept keystroke-based card-number entry. Any future PR that adds DTMF-keystroke handling to a payment-adjacent code path is refused by the CI lint gate. Reason: the moment the voice path routes a keystroke that could be a card digit, that service is in PCI L1 scope.
- PAN, expiry, or CVC in any Vorel-hosted form. No Prisma model has a column for any of these. No log line carries them. No structured log field captures them. The lint gate greps every payment-flow file for these tokens and refuses to merge a match. Reason: the moment a Vorel-hosted form accepts a card field, the form host is in PCI L1 scope.
-
Persistent token storage outside the provider’s vault. Reusable payment-method tokens stay provider-side. Vorel only persists the checkout session id, the payment-intent id, and the
payment_resolutionenum; these are reference handles, not tokens that could be replayed against another payment processor. The lint gate refuses to merge a persistent token column on a payment-related Prisma model. Reason: a long-lived token that can be replayed against a payment processor is a stored-credential surface, and PCI scope follows it.
The booking-hold semantics
When the customer ends the call without completing payment, the agent does not retry, does not block the call until the webhook arrives, and does not lose the booking. The architectural pattern is:- The appointment / table reservation / intake slot is held in
pending_paymentstate for 24 hours. - The hosted-checkout URL remains valid for that 24-hour window.
- Your customer can return to the SMS link any time and complete checkout.
- On webhook completion within the window, the booking flips to confirmed.
- On window expiry without completion, the reservation auto-releases and an audit row records
customer_abandoned.
Audit-log actions
Every step of the payment flow lands inaudit_log. Operators see the trail at the per-tenant audit surface; auditors and CISO reviewers can pull the chain for any individual booking.
pci_vault_redirect_issued: agent created a hosted-checkout session and read the redirect line / sent the SMS.pci_vault_redirect_completed: the provider’s webhook acknowledged the payment within the booking-hold window.pci_vault_redirect_failed: the provider returned a hard failure, or the booking-hold window expired without completion.pci_enable_toggled: operator flippedtenants.pci_payment_enabled(enable/disable PCI flows per tenant).pci_vendor_changed: operator changed the configured PCI vendor (future-proofing; today a single hosted-checkout provider is the only allowed value).
voice_call_cost.payment_resolution column on each call carries the outcome enum: collected_via_vault, failed_at_vendor, customer_abandoned, expired_pre_redirect, or NULL (no PCI flow on this call). Retention on voice_call_cost is 365 days per the audited retention policy: sufficient for billing reconciliation and PCI audit evidence.
When is PCI enabled?
PCI payment collection is operator-enabled per tenant, not customer self-service. Your Vorel operator flipstenants.pci_payment_enabled after:
- You confirm you have an account with the supported payment provider, with API credentials Vorel can use for your tenant.
- Your vertical pack is one of the three packs PCI ships for at v1:
restaurant,salon,auto_service. - Your operator captures the per-tenant payment-provider credentials encrypted at rest the same way CRM credentials are.
What about chargebacks and refunds?
Chargeback handling lives on the payment provider’s side; the provider is the merchant of record for the payment processing. Vorel surfaces achargeback_received event when the provider notifies us, and the operator-side reconciliation surface shows the affected voice_call_cost row. Refunds run from the provider’s dashboard or via its API; Vorel does not initiate refunds programmatically.
Reversibility
Switching the underlying vault vendor (to an alternate PCI-compliant payment provider) is a code-level change at the vault-redirect handler. The architectural commitment (SAQ-A scope, no PAN/CVC/expiry on Vorel infrastructure, the three hard-forbidden builds) is not reversible without an audited policy amendment. If a future enterprise customer with ≥$100K/yr ACV requires Vorel to operate as a PCI Level 1 merchant, the decision record documents the conditions under which that path reopens: explicit founder authority, contract-conditional volume, and a new policy amendment. Until those conditions are met, vault-redirect is the only architecture Vorel ships.Related docs
- Compliance: PCI sub-processor disclosure, SAQ-A scope row.
- Security overview: encryption posture, audit-log policy, append-only tables.
- Data retention:
voice_call_cost.payment_resolutionretention (365 days for PCI reconciliation). - Pricing: which packs include payment collection at booking.