Title: ShipToVerified
Author: ShipToVerified
Published: <strong>April 13, 2026</strong>
Last modified: May 13, 2026

---

Search plugins

![](https://ps.w.org/shiptoverified/assets/icon-256x256.png?rev=3506402)

# ShipToVerified

 By [ShipToVerified](https://profiles.wordpress.org/pitchercompany/)

[Download](https://downloads.wordpress.org/plugin/shiptoverified.1.1.1.zip)

 * [Details](https://test.wordpress.org/plugins/shiptoverified/#description)
 * [Reviews](https://test.wordpress.org/plugins/shiptoverified/#reviews)
 *  [Installation](https://test.wordpress.org/plugins/shiptoverified/#installation)
 * [Development](https://test.wordpress.org/plugins/shiptoverified/#developers)

 [Support](https://wordpress.org/support/plugin/shiptoverified/)

## Description

ShipToVerified connects your WooCommerce store with the ShipToVerified service to
automate identity verification and adult signature compliance for regulated product
shipments.

The plugin handles the full verification lifecycle:

 * Evaluates whether an order requires adult signature or identity verification 
   based on the customer’s shipping destination and cart contents.
 * Notifies the ShipToVerified service when a qualifying order is placed.
 * Renders a secure identity verification widget on the order confirmation and account
   pages so the customer can complete verification without leaving your store.
 * Receives signed webhook events from ShipToVerified when a customer completes 
   or fails verification, and updates the WooCommerce order record accordingly.
 * Gives store administrators a manual verification option and a verification status
   panel directly inside the WooCommerce order screen.

#### Who needs this plugin?

Retailers that ship age-restricted, regulated, or compliance-sensitive products (
such as firearms accessories, tobacco, cannabis, or adult goods) to jurisdictions
that require adult signature delivery or government-issued identity verification
at the point of purchase.

#### How it works

 1. The merchant connects the store to ShipToVerified via an OAuth flow in WooCommerce
    > ShipToVerified.
 2. When a customer reaches the checkout page, the plugin sends the cart’s shipping
    state, order total, and product details to the ShipToVerified API to determine 
    whether the cart requires an adult signature fee or identity verification notice.
 3. When the customer places an order and it moves to processing or completed status,
    the plugin notifies ShipToVerified with the order ID so that a verification requirement
    can be assigned.
 4. On the order confirmation page (and optionally the account order-detail page), 
    the plugin loads an identity verification widget served by ShipToVerified that 
    guides the customer through document capture and liveness checks.
 5. Once the customer completes the verification flow, ShipToVerified sends a signed
    webhook back to the store. The plugin validates the signature, marks the order 
    as verified, and stores the verified name and address in the order meta.

#### External services

This plugin connects to the ShipToVerified API (`https://api.shiptoverified.com`).
A ShipToVerified merchant account is required. Connection is established by the 
store administrator during initial setup via OAuth.

**Checkout eligibility check**
 Triggered automatically on the checkout page for
every customer session (including guests) while the plugin is active and connected.
This call determines whether the current cart requires an adult signature fee or
identity verification notice.

 * When it runs: on every checkout page load and on each cart update (shipping address
   change, quantity change, etc.).
 * Data sent: customer’s shipping state (two-letter US state code), cart grand total,
   and line items (product ID, product name, quantity, and product category names).
 * Why it is sent: ShipToVerified maintains up-to-date jurisdiction rules for regulated
   products. Sending the cart snapshot allows the service to evaluate applicable
   state laws without storing a static ruleset inside the plugin.
 * Data received: a boolean indicating whether an adult signature fee and/or a verification
   notice should be displayed.

**Order created notification**
 Triggered once per order, when the order status 
first moves to processing or completed.

 * Data sent: WooCommerce order ID and store URL.
 * Why it is sent: this tells ShipToVerified to create a verification record linked
   to the order so it can manage the customer-facing verification flow and track
   completion.
 * Data received: a flag indicating whether the order requires identity verification.

**Widget initialization**
 Triggered on the order confirmation page (and optionally
the account order-detail page) when an order requires identity verification.

 * Data sent: WooCommerce order ID and store URL.
 * Why it is sent: ShipToVerified generates a short-lived, single-use widget token
   scoped to that order so that the verification session cannot be replayed or hijacked.
 * Data received: a widget token and a flag confirming verification is required.
 * A JavaScript file (`/widget.js`) is then loaded directly from `https://api.shiptoverified.
   com` to render the verification interface. This file is served by the ShipToVerified
   service and is part of the core service functionality (similar to how payment
   processors serve their checkout scripts).

**Webhook (inbound)**
 ShipToVerified sends a signed POST request to `/wp-json/shiptoverified/
v1/webhook` when a verification event occurs (e.g., customer completes or fails 
verification, or the verified shipping address changes).

 * Supported events: `verification.completed`, `address.updated`, `address.unverified`,`
   address.review_required`.
 * Data received: event type, event ID, order ID, verification ID, verified customer
   name, and verified shipping address (or the corrected/failed address for `address.
   updated` / `address.unverified`).
 * All webhook payloads are validated with an HMAC-SHA256 signature before processing.
 * Each event is idempotent: duplicate event IDs are ignored.

**Order data endpoint (inbound)**
 ShipToVerified may request full order details
via `GET /wp-json/shiptoverified/v1/order/{id}` to display order context inside 
the ShipToVerified merchant dashboard.

 * Data returned: order line items, customer name, and shipping address.
 * Authentication: requires the store’s API key in the `X-API-Key` header.

**Connection management (OAuth)**
 Used once during initial setup and optionally
to test or re-establish the connection.

 * Data sent: store URL, OAuth authorization code or callback parameters.
 * Data received: API key, webhook secret.

By installing, activating, and connecting this plugin, the store administrator consents
to the transmission of the above data to ShipToVerified on behalf of the store and
its customers, in accordance with the service terms.

 * Terms of Service: https://shiptoverified.com/terms
 * Privacy Policy: https://shiptoverified.com/privacy

Merchants are responsible for disclosing the use of this service to their customers
in their store’s privacy policy.

### Order Meta Keys

The plugin stores all verification data in WooCommerce order meta. Keys are defined
as constants in `src/App/Domains/Orders/Order.php`.

#### Verification state

 * `_requires_id_verification` — Set to `'yes'` when the STV backend determines 
   the order requires identity verification.
 * `_order_id_verified` — Set to `'yes'` when the customer successfully completes
   the verification flow (via widget or manual override).
 * `_is_ffl` — Set to `'yes'` when the order is flagged as an FFL (Federal Firearms
   License) order. FFL orders are excluded from identity verification and adult 
   signature workflows.

#### Verified identity data (written via webhook)

 * `_order_id_verified_name` — Full name as verified by STV (string).
 * `_order_id_verified_address` — Verified shipping address (serialized array).
 * `_order_id_verification_timestamp` — MySQL datetime string recording when verification
   completed.
 * `_stv_verification_id` — The STV-side verification UUID. Use this to look up 
   the verification record in the ShipToVerified dashboard.

#### Widget and notification state

 * `_stv_widget_token` — Short-lived, single-use token used to initialise the frontend
   verification widget. Generated by STV and stored temporarily; do not rely on 
   its value after the order is verified.
 * `_stv_order_created_notified` — Set to `'yes'` after the plugin has successfully
   notified the STV backend of a new order. Prevents duplicate notifications on 
   status re-changes.
 * `_stv_webhook_processed_{event_id}` — Idempotency guard. Written once per processed
   webhook event to prevent duplicate processing if STV delivers the same event 
   more than once. `{event_id}` is the event UUID from the STV webhook payload.

#### Reminder emails (manual verification flow)

 * `_id_verification_first_reminder_sent_at` — Timestamp of the first reminder email
   sent to the customer.
 * `_id_verification_second_reminder_sent_at` — Timestamp of the second reminder
   email sent to the customer.

### Hooks Reference

= Filters the plugin listens to =

 * `woocommerce_order_actions` (priority 10, 2 args) — Adds the **Mark as Manually
   Verified** entry to the order action dropdown in the admin order screen (`ManualVerifyOrderFilter::
   addManualVerificationOrderAction`).

#### Custom actions the plugin fires

Third-party code can hook into these to react to verification events.

    ```
    do_action( 'shiptoverified_order_id_verification_complete', int $order_id )
    ```

Fired when an order is marked as successfully verified — either by the STV webhook
completing the customer flow, or by the admin using the manual verify order action.
*`
$order_id` (int) — The WooCommerce order ID that was just verified.

    ```
    do_action( 'shiptoverified_add_ca_signature_fee', bool $requires )
    ```

Fired during checkout eligibility evaluation after the cart rules are checked against
the STV backend.
 * `$requires` (bool) — `true` if the current cart requires an 
adult signature fee; `false` otherwise. Hook into this to add or remove a fee line
item on the cart.

### REST API Endpoints

Both endpoints are registered under the namespace `shiptoverified/v1`.

#### GET /wp-json/shiptoverified/v1/order/{id}

Returns order details to the ShipToVerified merchant dashboard.

 * **Authentication:** `X-Api-Key` request header must match the `stv_api_key` WordPress
   option.
 * **Response:** order line items, customer name, and shipping address.
 * **Use:** called by the STV backend when a merchant views an order inside the 
   ShipToVerified dashboard.

#### POST /wp-json/shiptoverified/v1/webhook

Receives verification event callbacks from ShipToVerified.

 * **Authentication:** open endpoint, but every request is validated against an 
   HMAC-SHA256 signature in the `X-Stv-Signature` header using the `stv_webhook_secret`
   option. Requests with an invalid signature or a timestamp outside the 5-minute
   window are rejected with `403`.
 * **Payload fields:** `event_type`, `event_id`, `order_id`, `verification_id`, `
   verified_name`, `verified_address`.
 * **On success:** updates order meta, fires `shiptoverified_order_id_verification_complete`,
   returns `200`.

### Testing & Review Guide

This section is intended for WordPress.org and WooCommerce plugin reviewers. It 
explains how to test each feature end-to-end.

A sandbox/test account can be requested from the ShipToVerified team at support@shiptoverified.
com. Please mention that you are reviewing the plugin for WordPress.org.

#### Setup

 1. Install and activate WooCommerce. Create at least one simple product.
 2. Install and activate ShipToVerified.
 3. Go to WooCommerce > ShipToVerified and click “Connect with ShipToVerified”.
 4. Complete the OAuth flow. On success, the settings page shows a green “Connected”
    badge, the API key (read-only), and widget placement checkboxes.

Things to verify:

 * The “Connect” button generates a nonce-protected URL (action `stv_oauth_start`).
 * After authorization, `stv_api_key` and `stv_webhook_secret` are stored in `wp_options`.
 * The “Test Connection” button calls the STV API and reports success or failure.
 * Widget placement checkboxes (Thank You page, View Order, Order Tracking) save
   correctly.

#### Order Verification Flow

When an order moves to `processing` or `completed`, the plugin notifies ShipToVerified.

 1. Place a test order and complete payment so the order reaches `processing`.
 2. Open the order in WooCommerce > Orders.

Things to verify:

 * The order has meta `_stv_order_created_notified = yes` (notification was sent).
 * If the STV account is configured for verification, the order may be moved to “
   Awaiting Verification” status (`wc-await-verify`).
 * The admin order detail panel shows a “California ID Verification” section with
   either a green “Verified” badge or a yellow “Pending” badge.
 * FFL orders (meta `_is_ffl = yes`) are skipped entirely.
 * The notification is sent only once per order (idempotency via `_stv_order_created_notified`).

#### Verification Widget

The plugin injects a JavaScript widget on customer-facing order pages so the customer
can complete identity verification.

 1. Place an order that requires verification.
 2. On the Thank You page, the widget should render with a verification prompt.
 3. Alternatively, go to My Account > Orders > View Order for the same order.

The widget appears on these pages (controlled by settings checkboxes):

 * Thank You page (`woocommerce_thankyou`) — enabled by default.
 * My Account > View Order (`woocommerce_view_order`) — enabled by default.
 * Order Tracking (`woocommerce_order_tracking`) — disabled by default.

Things to verify:

 * The widget only renders for orders with `_requires_id_verification = yes`.
 * The widget does not render for already-verified orders (`_order_id_verified =
   yes`).
 * The widget does not render for FFL orders or FFL customers.
 * The widget does not render for admin users viewing the page.
 * The script is enqueued via `wp_register_script` / `wp_enqueue_script` (not echoed
   directly).

#### CA Adult Signature Notice

For orders shipping to California, the plugin can display a notice at checkout.

 1. Add products to the cart and go to checkout.
 2. Enter a California shipping address.
 3. If the STV account has adult signature rules configured, a notice appears above
    the payment section.
 4. Change the shipping state to a non-CA state — the notice should disappear.

Things to verify:

 * The notice renders inside `#ca-adult-signature-notice`.
 * The notice updates when the checkout form is refreshed (AJAX fragments).
 * FFL customers are excluded.
 * Results are cached per session to avoid redundant API calls (cache key: cart 
   hash + state + total).

#### Manual Verification

Admins can manually mark an order as verified.

 1. Open an order that requires verification in WooCommerce > Orders > Edit Order.
 2. In the “Order actions” dropdown, select “Mark ID Verified”.
 3. Click the action button.

Things to verify:

 * The plugin calls the STV manual-verify endpoint.
 * Order meta is updated: `_order_id_verified = yes`, `_order_id_verification_timestamp`,`
   _order_id_verified_name`, `_order_id_verified_address`.
 * An order note is added with the verification ID.
 * The action `shiptoverified_order_id_verification_complete` is fired.
 * If the order has parent/child relationships, verification propagates to related
   orders.
 * FFL orders are excluded.

#### REST API Endpoints

Test the endpoints with any HTTP client. Both endpoints require the `X-Api-Key` 
header set to the API key shown on the plugin settings page.

**Order details:**
 Send a GET request to `https://your-store.com/wp-json/shiptoverified/
v1/order/123` with the `X-Api-Key` header.

Expected response includes: `order_id`, `status`, `total`, `currency`, `billing_email`,`
customer`, `shipping_address`, `items`.

**Order statuses:**
 Send a GET request to `https://your-store.com/wp-json/shiptoverified/
v1/order-statuses` with the `X-Api-Key` header.

Things to verify:

 * Requests without a valid `X-Api-Key` return `401`.
 * Invalid order IDs return an appropriate error response.

#### Webhook Handling

The STV backend sends webhook events to `POST /wp-json/shiptoverified/v1/webhook`
when a customer completes verification.

Signature format: `X-Stv-Signature: t={unix_timestamp},v1={hmac_sha256_hex}` computed
over `{timestamp}.{raw_body}` using the `stv_webhook_secret`.

Things to verify:

 * Invalid signatures return `401`.
 * Expired timestamps (older than 5 minutes) return `401`.
 * Duplicate `event_id` values are ignored (returns `200` but no duplicate processing).
 * After a valid webhook: order meta and order notes are updated correctly.

#### Uninstall Cleanup

 1. Deactivate and delete the plugin from Plugins > Installed Plugins.

Things to verify:

 * All plugin options are removed from `wp_options`: `stv_api_url`, `stv_api_key`,`
   stv_webhook_secret`, `stv_settings`, `stv_site_url`, `id_to_verify_settings`.
 * Order meta is preserved (verification records must survive for compliance and
   audit purposes).

## Installation

 1. Sign in to WordPress as an Administrator user.
 2. Go to Plugins > Add New and search for “ShipToVerified”.
 3. Click Install Now, then Activate.
 4. Ensure WooCommerce is installed and active.
 5. From the WordPress admin, go to WooCommerce > ShipToVerified.
 6. Click “Connect with ShipToVerified” and complete the OAuth flow.
 7. Once connected, the plugin will automatically begin evaluating checkout eligibility
    and sending order notifications.

## FAQ

### Does this plugin work without WooCommerce?

No. WooCommerce must be installed and active. The plugin will silently do nothing
if WooCommerce is not detected.

### Does this plugin call an external API?

Yes. It communicates with `https://api.shiptoverified.com` for checkout eligibility
evaluation, order notifications, widget token generation, and connection management.
See the “External services” section above for a full breakdown of what data is sent,
when, and why.

### Does every checkout visitor trigger an API call?

Yes. When the plugin is active and connected, every customer who reaches the checkout
page will trigger a checkout eligibility check. This allows the plugin to display
accurate adult signature notices based on real-time jurisdiction rules. Guest checkouts
are included. The call uses only non-personal cart data (shipping state, order total,
product details) — no name, email, or payment information is transmitted at this
stage.

### Does this plugin load external JavaScript?

Yes. When an order requires identity verification, the plugin loads a widget script
directly from `https://api.shiptoverified.com`. This script renders the identity
verification interface and is served by ShipToVerified as part of its core service.
It is only loaded on the order confirmation and account order-detail pages, never
on the checkout page itself.

### What data is stored in WooCommerce order meta?

The plugin stores the following data in WooCommerce order meta when applicable:

 * Whether the order requires identity verification.
 * Whether identity verification has been completed.
 * The verified customer name and shipping address (received via webhook from ShipToVerified).
 * The verification timestamp.
 * The ShipToVerified verification ID.
 * A short-lived widget token (used only to render the verification interface).

### What happens on uninstall?

The plugin removes all its own options from the WordPress options table (API URL,
API key, webhook secret, plugin settings, and site URL). Order meta stored on individual
orders is not removed to preserve the verification audit trail.

### Is this plugin compatible with FFL (Federal Firearms License) orders?

Yes. Orders and customers flagged as FFL are automatically excluded from the identity
verification and adult signature workflows.

## Reviews

There are no reviews for this plugin.

## Contributors & Developers

“ShipToVerified” is open source software. The following people have contributed 
to this plugin.

Contributors

 *   [ ShipToVerified ](https://profiles.wordpress.org/pitchercompany/)
 *   [ PitcherCo ](https://profiles.wordpress.org/shiptoverified/)

[Translate “ShipToVerified” into your language.](https://translate.wordpress.org/projects/wp-plugins/shiptoverified)

### Interested in development?

[Browse the code](https://plugins.trac.wordpress.org/browser/shiptoverified/), check
out the [SVN repository](https://plugins.svn.wordpress.org/shiptoverified/), or 
subscribe to the [development log](https://plugins.trac.wordpress.org/log/shiptoverified/)
by [RSS](https://plugins.trac.wordpress.org/log/shiptoverified/?limit=100&mode=stop_on_copy&format=rss).

## Changelog

#### 1.1.1

 * Webhook handler now supports `address.review_required` — fired when an address-
   only verification is sitting on customer interaction (suggestion to accept, candidate
   list to pick from, or a missing unit/apartment number). The plugin adds a private
   order note describing what Radar returned and what input is needed, so merchants
   see the pending state in the WooCommerce order admin without having to check 
   the ShipToVerified dashboard. Note is posted once per order; duplicate event 
   deliveries are ignored via the existing idempotency guard.

#### 1.1.0

 * Add support for Radar-powered shipping address validation as a standalone post-
   checkout flow (separate from ID verification).
 * Webhook handler now supports two new events:
    - `address.updated` — fired when the customer accepts a Radar-suggested address
      or submits a corrected one. The plugin updates the WooCommerce shipping address
      and adds an order note with the new address.
    - `address.unverified` — fired when Radar cannot validate the shipping address.
      The plugin adds an order note flagging the order for manual review.
 * Widget injection no longer marks the order as `_requires_id_verification` when
   the verification flow is address-only. ID-only verifications continue to behave
   as before.
 * Webhook handlers defensively clear `_requires_id_verification` after a successful
   address validation so legacy/in-flight orders don’t stay tagged as ID-pending.

#### 1.0.0

 * Initial public release.

## Meta

 *  Version **1.1.1**
 *  Last updated **5 days ago**
 *  Active installations **Fewer than 10**
 *  WordPress version ** 6.0 or higher **
 *  Tested up to **6.9.4**
 *  PHP version ** 8.0 or higher **
 *  Language
 * [English (US)](https://wordpress.org/plugins/shiptoverified/)
 * Tags
 * [age verification](https://test.wordpress.org/plugins/tags/age-verification/)
   [compliance](https://test.wordpress.org/plugins/tags/compliance/)[Identity Verification](https://test.wordpress.org/plugins/tags/identity-verification/)
   [shipping](https://test.wordpress.org/plugins/tags/shipping/)[woocommerce](https://test.wordpress.org/plugins/tags/woocommerce/)
 *  [Advanced View](https://test.wordpress.org/plugins/shiptoverified/advanced/)

## Ratings

No reviews have been submitted yet.

[Your review](https://wordpress.org/support/plugin/shiptoverified/reviews/#new-post)

[See all reviews](https://wordpress.org/support/plugin/shiptoverified/reviews/)

## Contributors

 *   [ ShipToVerified ](https://profiles.wordpress.org/pitchercompany/)
 *   [ PitcherCo ](https://profiles.wordpress.org/shiptoverified/)

## Support

Got something to say? Need help?

 [View support forum](https://wordpress.org/support/plugin/shiptoverified/)