# Buildmerce Agent Orders — 1.1.2

Create an agreed WooCommerce order from a protected sales-agent portal, then email the client a payment link. This is the free WordPress.org edition. All included functionality is available without a Buildmerce account or license. See the release verification section for completed checks and remaining gateway-specific testing.

## Install or upgrade

1. Back up the site and install the candidate on HTTPS staging first.
2. Upload the installable ZIP in **Plugins → Add New Plugin → Upload Plugin**. This directory edition uses the `buildmerce-agent-orders` folder. If upgrading from the private `buildmerce-agent-paylater` edition, deactivate that edition before activating this one. Existing agent accounts, options, portal page, shortcode and order metadata are retained. Keep only one edition active.
3. Open **WooCommerce → Agent Orders**. Select the portal page, payment methods and other settings.
4. An administrator creates individual WordPress users with the **Payment Agent** role. Agents do not need Administrator or Shop Manager access.
5. Use the portal page created at activation. For a custom published page, add the **Agent Payment Portal** block, or the legacy `[buildmerce_agent_paylater]` shortcode, then select that page in settings.
6. Exclude the portal, checkout/order-pay and order-received URLs from caching at every plugin, host and CDN layer.
7. Reload any already-open payment forms after updating to 1.1.2; the address nonce is now scoped to the current order key. Previously emailed payment URLs remain usable. Verify real email receipt and a sandbox payment using the installed gateway before deploying.

Minimum declared requirements: WordPress 6.4, WooCommerce 8.2, PHP 7.4 and HTTPS. Verified runtime: WordPress 7.1.3, WooCommerce 11.2.1 and PHP 8.3.6. Declared minimums are not a claim that every intervening version or gateway has been tested.

### What stays intact on upgrade

Orders, agent users, capabilities, order metadata, the page, shortcode and previously emailed links retain their identities. Existing 1.0.x installations retain direct payment links and the agent-page password form. New installations default to WordPress sign-in and standard WooCommerce email verification. Review both settings explicitly when onboarding another store.

## Merchant settings

| Setting | Behavior |
|---|---|
| Portal page | Published page containing the portal block or shortcode; automatic page is the fallback. |
| Portal heading | Custom heading for signed-in agents. |
| Agent sign-in | WordPress sign-in, or the password form on the portal. Use native sign-in for SSO/MFA/authentication plugin flows. |
| Payment-link access | Standard WooCommerce email verification, or direct access for valid full agent-created guest order links. |
| Payment methods | Allow selected methods that WooCommerce considers available; no selection means all normally available methods. |
| Maximum quantity | Whole number from 1 to 9999, checked on the server. |
| Maximum request total | Optional total limit in the store currency, using a dot decimal separator. |
| New-request delay | Delay from 1 to 300 seconds, per authenticated agent, using WooCommerce’s rate limiter. |
| Requests per page | 10, 20 or 50; history includes pagination and status filtering. |
| Captured-payment status | Processing for fulfillment, or Completed for work requiring no further fulfillment. Gateway holds/authorization/declines keep their normal behavior. |

Settings are available to administrators/shop managers with `manage_woocommerce`. Agent accounts can create requests and view/resend their own requests. They cannot change settings, manage other users, alter catalog prices or issue refunds. Standard WooCommerce administration remains available to authorized store managers.

## Agent form and amount

Required: product name, SKU, unit price and client email. Optional: quantity, PO/reference, client first/last name, company, client message and a private internal note.

**Final charge = unit price × quantity.** Include agreed delivery/tax in that amount where applicable. This version does not itemize taxes, calculate shipping rates, apply cart coupons or recalculate the amount from the customer’s address. It is for agreed custom-order charges, not automatic tax quotation.

Only the store’s configured currency is supported. Dot-decimal prices with the configured precision are required; zero, negatives, exponent notation and silent decimal rounding are rejected. The built-in upper bound is 999,999,999 minor currency units. Currency precision from zero to six decimal places is supported. A configured store limit can be lower.

The entered name/SKU are a snapshot on an ad-hoc product line. An existing SKU does not link the catalog product, reduce stock, grant downloads, create a subscription or invoke product options. The store team handles fulfillment/inventory. Each request currently contains one line; quantity can exceed one.

## Payment and delivery

Submitting creates a pending-payment guest order and sends WooCommerce’s Order details/Customer invoice email with a payment link and a Pay now button in the standard HTML template. Use WooCommerce email settings for the store sender, branding and invoice content.

The client enters the payment method’s billing address. **Shipping address is the same as billing** starts checked. Unchecking reveals separate shipping name, company, street, city, province/state, postcode and country fields. Both addresses are validated before saving or payment. Hidden shipping fields are disabled and are not submitted while copying billing. The saved choice/address remains available after a declined attempt. Available countries follow WooCommerce’s store settings.

The installed gateway processes the transaction and records its normal order state/transaction details. This plugin has no card form, card storage, Authorize.Net credentials or separate card API integration. A gateway must support WooCommerce’s order-pay flow. No universal compatibility claim is made for all gateways, themes or checkout customizations.

When direct-link access is enabled, anyone holding the complete link can open the agent guest order and pay. The full order key, matching endpoint/order ID and native WooCommerce pay_for_order permission are checked; the policy does not bypass access for unrelated customer orders. Paid/cancelled orders remain subject to WooCommerce payment eligibility. To withdraw an unpaid request, a store manager cancels it. No custom link-expiry timer is included.

## Request history and email recovery

Agents filter their own requests by status and browse earlier pages. Reload to refresh gateway/order changes. An unpaid request can be resent, subject to a one-minute cooldown; paid/cancelled/refunded requests are not offered a payment resend.

A retry of the same submitted form is mapped to its existing order. A fresh form creates a new request. Email failure does not delete the order; use the existing request’s resend action rather than creating a duplicate order.

“Accepted by mail service” reports a successful mail callback, not inbox delivery. Check provider/SMTP logs and spam folders if receipt is missing. Incomplete order creation cancels the partial order and adds a private note. Logs use the WooCommerce `buildmerce-agent-paylater` source.

## Privacy, retention and removal

The plugin stores agent IDs, SKU/PO references, private notes, email-send outcomes and short-lived request records. WooCommerce owns customer email, billing/shipping information and order storage. There is no Buildmerce telemetry, license callback, external asset download or card-number collection in the plugin.

Privacy-policy text is available through WordPress’s privacy-policy helper. Use WooCommerce’s existing customer privacy/export/erasure and order-retention procedures; the extension’s metadata follows retained orders. Do not present this as a guarantee of legal compliance.

Deactivation stops submission-record cleanup and preserves business data, users, role and page. Request records are not autoloaded and are cleaned after at least 48 hours by WP-Cron. No automatic business-record deletion occurs on uninstall. Retire the portal/page and role through an intentional site-maintenance procedure if removing the workflow permanently.

## Translation

PHP, frontend JavaScript and block-editor strings use the `buildmerce-agent-orders` text domain. A POT template is in `languages/`. Generate/install locale MO files and JavaScript JSON catalogs using your usual WordPress translation workflow. No finished language pack or multilingual compatibility claim is included in this candidate.

## Request authorization

Agent create and resend handlers verify the current user's Payment Agent or WooCommerce management capability, HTTPS POST method and their action nonce locally before performing any order or email operation. Resend also checks ownership of the selected agent order. The optional frontend sign-in verifies its nonce before credential authentication and checks the resulting user's capabilities before setting authentication cookies.

Customer address updates require a valid agent-created payable order, matching order-pay endpoint and full order key, WooCommerce's native pay_for_order capability, the native WooCommerce payment nonce and an additional address nonce scoped to the order ID and secret key. A guest can pay an eligible guest order using its valid full link; assigning the order to a registered customer also makes the native payment capability apply to that customer. Address validators only receive posted data after these checks. Rendering an invalid POST ignores its address values.

Settings use WordPress's Settings API nonce and the manage_woocommerce capability. Read-only GET history, receipt and link queries validate current agent ownership or the complete order key and do not update orders or delete flash-notice state. Notice records expire after ten minutes.

## Release verification

Completed locally in an isolated WordPress installation:

- Native PHP syntax checks for every plugin PHP file.
- 36 standalone PHP logic checks for monetary input, settings, direct-link scope and address validation.
- JavaScript syntax and logic checks for totals, duplicate-click prevention and separate shipping fields.
- 90 request-security assertions in each order storage mode: guest/subscriber and revoked-role denials, missing/malformed/expired or wrong-user nonces, HTTPS and POST enforcement, cross-agent resend denial, authorized agent/manager operations, duplicate/rate-limit protection, guest payment and assigned-customer scope, key/endpoint/nonces and paid-order address protections, settings nonce/capability and frontend login permission checks.
- 46 real WordPress/WooCommerce assertions in legacy order storage and another 46 in HPOS: activation/page/role/block, portal rendering, HTML escaping, native order totals and agent-scoped history, direct links and invalid keys, copied/separate addresses and invalid nonces, HTML/plain-text invoice output, intercepted native invoice delivery and payment-completion status/transaction reference.

Runtime: WordPress 7.1.3, WooCommerce 11.2.1, PHP 8.3.6. The local test database used SQLite integration; MySQL/MariaDB and production gateway testing are still required on the merchant staging site. Mail was intercepted and no card transactions or external customer emails were sent. Calling WooCommerce payment_complete() in a test is not an Authorize.Net transaction test.

Plugin Check 2.1.0, including runtime checks, reports **0 errors and 24 advisory warnings**, with **no NonceVerification.Missing findings** and no missing-nonce suppressions. The remaining advisories are 21 nonce recommendations for read-only GET queries, 2 database-query advisories for the fresh cron cleanup lookup and 1 advisory for the native WooCommerce HPOS metadata query. They are retained for reviewer assessment. Merchant staging and directory review may identify additional issues. WordPress.org manual approval, actual inbox delivery, Authorize.Net sandbox/decline/refund tests, browser accessibility checks and Woo Marketplace QIT are separate checks and are not claimed here.
