Appearance
Deals & Payments Playbook ​
Purpose: End-to-end steps to test deal funding, webhook updates, payout release, and refunds. Audience: Developer, Admin Prerequisites: Test Stripe keys configured; Edge Functions deployed/served; buyer/seller test accounts.
Actors & routes
- Buyer: funds the deal in-app (Stripe Elements) —
src/pages/Deal.tsx,src/components/deal/tabs/FinancingTab.tsx - Admin: releases payout or triggers refund —
src/pages/admin/AdminTransactions.tsx - Webhooks:
supabase/functions/stripe-webhook/index.ts
- Prep a deal
- Create or pick a deal (status
payment_requiredoroffer_accepted). - Verify transaction row:
transactionshasstatus='pending',amountset.
- Buyer funds the deal
- In UI (Deal page), click Fund; this invokes:
create-deal-payment→ returns{ client_secret }(FinancingTab.tsx:116-123)- Stripe Elements renders PaymentElement; confirm payment.
- Use Stripe test card: 4242 4242 4242 4242 (any future expiry, any CVC, any zip).
- Webhook processing
- On success, Stripe calls
stripe-webhook. - Verify mapping and status update after webhook:
- transactions.status becomes
funded - optional logs/notification entries
- transactions.status becomes
- SQL quick check:sql
select id, status, stripe_payment_id, updated_at from transactions where id = 'DEAL_UUID';
- Admin releases payout
- In Admin → Transactions, pick the funded deal and click Release Payout.
- This hits
/functions/v1/release-deal-payoutwith{ dealId }(AdminTransactions.tsx:237-243). - Verify result:
- Deal status may advance to
payout_released/completeddepending on flow.
- Deal status may advance to
- SQL quick check:sql
select id, status, updated_at from transactions where id = 'DEAL_UUID';
- Refund scenario (optional)
- In Admin → Transactions, pick the deal and click Refund.
- This hits
/functions/v1/refund-deal-paymentwith{ dealId }(AdminTransactions.tsx:255-261). - Verify:
- Stripe refund event processed (via webhook or function response)
- Transaction annotated accordingly (status
failed/cancelledor refund log)
- Emails & notifications
- Buyer/Seller/payment emails may be sent by edge functions (e.g.,
send-payment-email). - Check
email_logsfor entries created around funding/payout/refund.
- Troubleshooting
- No webhook updates:
- Verify
stripe-webhookendpoint and secret configured. - Inspect function logs; replay events via Stripe CLI.
- Verify
- Payment UI errors:
- Ensure
VITE_STRIPE_PUBLISHABLE_KEYis set and Elements loads; confirm clientSecret present.
- Ensure
- Payout/refund failures:
- Check function logs for errors; ensure admin role validation and correct dealId.
External Escrow Testing Scenarios ​
External Escrow Flow Testing ​
Provider Selection
- Create a deal in
payment_requiredstatus - As buyer, navigate to Deal page → Financing tab
- Verify provider selector shows both "Stripe Escrow" and "External Escrow" options
- Select "External Escrow (Verified by AcqMarketplace)"
- Verify deal.provider is set to 'escrow' and cannot be changed
- Create a deal in
External Details Submission
- Fill out external escrow form:
- Provider: "Other" (or any available option)
- Reference: "TEST-ESCROW-12345"
- URL: "https://example-escrow.com/transaction/12345"
- Submit form and verify:
external_escrow_provider,external_escrow_reference,external_escrow_urlare set- Event logged in
deal_events_log - Notifications sent to seller and admin
- Fill out external escrow form:
Admin Document Verification
- As admin, go to Admin → Transactions → select deal → External Escrow tab
- Verify external escrow details are displayed
- Click "Verify Docs" to approve documents
- Verify:
verification_statusset to 'verified'- Deal status advances to 'dd_in_progress' if appropriate
- Notifications sent to both parties
Admin Funds Confirmation
- In External Escrow tab, click "Mark Funds Confirmed"
- Verify:
external_funds_confirmed_attimestamp is set- Deal status becomes 'funded'
- Notifications sent to both parties
Buyer Confirmation
- As buyer, when deal reaches handover phase, confirm receipt
- Verify:
- Deal status becomes 'buyer_accepts'
- Event logged in
deal_events_log - Admin notification sent
Admin Finalize Release
- As admin, click "Finalize Release" in External Escrow tab
- Verify:
external_release_confirmed_attimestamp is set- Deal status becomes 'payout_released' then 'completed'
- Final notifications sent to both parties
External Escrow Edge Cases ​
Document Rejection
- Admin rejects documents instead of approving
- Verify deal can be resubmitted for verification
- Check proper notifications are sent
Missing External Details
- Test deal with external escrow but no details submitted
- Verify admin interface handles gracefully
Status Validation
- Test admin actions in wrong deal status
- Verify proper error messages and disabled states
Provider Immutability
- Try to change provider after selection
- Verify error message and no state change
External Escrow SQL Verification ​
sql
-- Check external escrow deal details
SELECT
id,
provider,
external_escrow_provider,
external_escrow_reference,
external_escrow_url,
verification_status,
external_funds_confirmed_at,
external_release_confirmed_at,
status
FROM transactions
WHERE provider = 'escrow';
-- Check external escrow events
SELECT
deal_id,
event_type,
details,
created_at
FROM deal_events_log
WHERE event_type IN (
'provider_set',
'external_details_submitted',
'docs_verified',
'external_funds_confirmed',
'buyer_confirmed',
'external_release_confirmed'
)
ORDER BY created_at DESC;References
- Buyer funding:
src/components/deal/tabs/FinancingTab.tsx:116-123 - Stripe Elements:
src/pages/Deal.tsx - Admin actions:
src/pages/admin/AdminTransactions.tsx:237-243, 255-261 - Webhook:
supabase/functions/stripe-webhook/index.ts - External Escrow Functions:
supabase/functions/set-deal-provider,supabase/functions/submit-external-escrow-details,supabase/functions/admin-verify-docs,supabase/functions/mark-external-funded,supabase/functions/buyer-confirm-receipt,supabase/functions/admin-finalize-external-release - Data Model:
docs/features/transactions.md,docs/data-model/schema.md