Back to Blog
Billing

Security Deposits API Webhooks: Keep Booking Status Accurate

Map security-deposit API webhooks to current booking state, verify signatures and handle final partial Stripe captures without inventing a remaining hold.

October 13, 20265 min read
P
PayRequest Team
PayRequest Editorial Team

Security-deposit API webhooks should update a booking from the current deposit record, not from an assumed sequence of messages. Verify the signature, preserve the booking-to-deposit mapping and retrieve authoritative state when an event could be stale or incomplete. A partial Stripe capture can be final even though the captured amount is smaller than the original hold.

This guide gives rental-software developers a state-mapping worksheet. For endpoint setup, use the Security Deposits API overview.

How should a security-deposit API webhook be verified?

PayRequest documents `X-PayRequest-Signature` as `sha256=` followed by the HMAC-SHA256 digest of the raw request body, using the configured webhook secret. Verify those original bytes before parsing or changing the body. Compare signatures with a suitable constant-time comparison and read the event name from `X-PayRequest-Event`.

The PayRequest reference lists the supported event names. Do not assume a Stripe signature header or timestamp scheme applies to PayRequest. Its public deposit page does not specify a delivery-order guarantee, event-ID schema or replay window; check the complete webhook contract before designing around those details.

Map events to booking decisions

A webhook is a notification about a deposit, not permission to charge for damage or hand over equipment. Keep the inspection, agreement and operator decision in your rental system.

Notification or retrieved stateBooking interpretationOperator or integration action
deposit.created / pendingRequest exists; no confirmed holdAwait customer authorization
deposit.authorizedFunds were reservedRetrieve state and capture_before before handover
deposit.capturedCapture completedRecord the actual captured amount and final state
deposit.partially_capturedProvider-specific partial outcomeRetrieve current state; do not infer another capture is possible
deposit.releasedAuthorization releasedClose the hold record; avoid calling it a refund
deposit.expiredConfirmed hold is no longer capturableEscalate any unresolved obligation
deposit.failedDeposit operation failedInspect current record and failure context

Store the latest API state alongside the booking ID and deposit ID. Keep payment status separate from booking cancellation, inspection completion and equipment return. These processes can happen at different times.

Why does a partial Stripe capture emit deposit.captured?

PayRequest's documented Stripe path supports one final capture. In the reference example, €350 is authorized, €150 is captured and €200 is released. The result is `captured`, with captured_amount of 150.00; it emits `deposit.captured`.

Your application must not calculate “€200 still secured” by subtracting the captured amount from the original amount. That remainder is released and unavailable for a second capture. The provider concept is explained in Stripe's authorization and capture documentation. For operator decisions, use the partial-capture guide.

How do you handle duplicates and delayed events?

Design your booking update so repeating the same notification does not repeat a customer message or capture action. Persist receipt and processing outcome, and use a documented delivery identifier if the contract supplies one. If it does not, do not invent a payload field: reconcile the current deposit and make the resulting business action idempotent in your own database.

As a design example, an authorized notification arrives after your local record already shows a final capture. Retrieve the deposit instead of moving the booking back to “funds reserved.” Stripe separately documents duplicate events and unordered delivery in its webhook guide; that guidance explains the general integration risk, without establishing PayRequest's retry schedule.

What should the customer see?

Show request pending, funds reserved, amount captured, released or expired using confirmed data. A processing or expired authorization attempt can still have API status pending with additional metadata; it is different from an expired previously confirmed hold.

Connect PayRequest security deposits to your booking record and retain rental-fee collection through payment links. Review account allowances and use the integration acceptance checklist before launch.

Editorial note: AI assisted with this article and cover. Public API documentation was reviewed on 13 October 2026; no webhook delivery or live capture was tested. The state worksheet is an original integration recommendation.

Frequently Asked Questions

Does deposit.partially_captured mean I can always capture again?

No. Retrieve the current deposit and provider-supported capabilities. PayRequest’s documented Stripe flow makes one final capture, including when only part of the amount is charged.

Is a pending authorization attempt the same as an expired hold?

No. A pending request can carry processing or expired-attempt metadata without a confirmed hold. The expired API status refers to a previously confirmed authorization that expired.

Share this article