```html

Manual Adjustments

Manual adjustments let administrators directly credit or debit any customer's wallet balance from the WordPress admin, with a required reason and full audit trail, without requiring a customer-initiated transaction.

Merchant Feature Admin Audit Ledger Credit & Debit Reason Tracking

Overview

Manual adjustments cover scenarios that fall outside the normal customer-facing flow: correcting a billing error, issuing a goodwill credit, reversing a mistaken debit, compensating for a delayed shipment, or zeroing out a balance before account closure. Every adjustment is written to the HMAC-chained audit ledger as an immutable entry, ensuring full traceability for accounting and compliance purposes.

Adjustments can be positive (credit) or negative (debit). Debiting below zero is blocked by default; a setting controls whether a balance can go negative. All adjustments trigger the customer's email notification if the corresponding email template is enabled.

How It Works

When an administrator submits a manual adjustment:

  1. WalletPro validates that the amount is non-zero and that the reason field is not empty.
  2. For debits, WalletPro checks the customer's current balance. If the debit would result in a negative balance and Allow negative balances is off, the adjustment is rejected with an admin notice.
  3. The balance is updated atomically in the wp_walletpro_balances table using a database-level transaction with row locking, preventing race conditions if another process modifies the same wallet simultaneously.
  4. A ledger entry is appended to wp_walletpro_ledger with: timestamp, actor (admin user ID), customer user ID, type (credit_manual or debit_manual), amount, currency, reason text, and an HMAC chain hash linking it to the previous entry.
  5. If the customer's wallet email notifications are enabled, WalletPro dispatches a walletpro_manual_adjustment email to the customer's billing address.
ℹ️

The HMAC chain means each ledger entry's hash depends on the previous entry's hash. Any retroactive modification of a ledger row breaks the chain and is detected by the Audit Log integrity check (WooCommerce > WalletPro > Audit Log > Verify Integrity).

Permissions

Performing manual adjustments requires the manage_woocommerce capability. Shop managers and administrators have this capability by default. Custom roles must be granted it explicitly through a role manager plugin or custom code.

To restrict manual adjustments to administrators only, use the walletpro_can_adjust_balance filter:

// Restrict manual adjustments to administrator role only
add_filter( 'walletpro_can_adjust_balance', function( $allowed, $admin_user ) {
    return user_can( $admin_user, 'administrator' );
}, 10, 2 );

Making an Adjustment from the Customer Profile

The quickest path to a single customer's wallet is through their user profile.

  1. Go to WooCommerce > Customers and open the customer record, or go to Users and open the user's profile.
  2. Scroll to the WalletPro Wallet meta box.
  3. The current balance is shown. Click Adjust Balance.
  4. A modal appears with the following fields:
    • Type, select Credit or Debit.
    • Amount, enter a positive decimal value. The store's default currency is used unless multi-currency wallets are enabled, in which case a currency selector appears.
    • Reason, free-text field, required. This text appears in the audit ledger and in the customer's wallet statement.
    • Notify customer, checkbox (checked by default if the Send adjustment emails setting is on).
  5. Click Apply Adjustment. The balance updates immediately and a success notice confirms the new balance.

Use descriptive, consistent reason text, for example "Goodwill credit, order #1234 delay" or "Balance correction, duplicate charge refund". The reason text is customer-visible in their printed wallet statement and exported CSV.

Bulk Adjustments from the Balances Overview

To adjust multiple customers at once:

  1. Go to WooCommerce > WalletPro > Balances.
  2. Use the search and filter controls to locate the target customers. Filters include: balance range, registration date, last transaction date, and customer role.
  3. Check the boxes next to the customers you want to adjust.
  4. Open the Bulk Actions dropdown and select Credit Wallets or Debit Wallets.
  5. Click Apply. A panel appears with:
    • Amount, the same amount is applied to every selected customer.
    • Reason, applied to every ledger entry created by this bulk operation.
    • Notify customers, sends the adjustment email to each affected customer.
  6. Click Confirm Bulk Adjustment. A progress indicator runs; the page refreshes when complete, showing a summary of how many wallets were updated and any that were skipped (for example, debits blocked by insufficient balance).
⚠️

Bulk adjustments cannot be undone in a single action. Each individual entry must be reversed separately. Test with a small set of customers before running a bulk adjustment across a large list.

Settings

Manual adjustment behavior is controlled under WooCommerce > WalletPro > Settings > Adjustments.

Setting Default Description
Allow negative balances Off When off, a manual debit that would push a balance below zero is blocked. When on, the balance can go negative and displays as a debt in the customer's wallet dashboard.
Require reason for adjustments On When on, the Reason field is enforced as non-empty. Turning this off is not recommended; it degrades audit quality.
Send adjustment emails On Controls whether the customer receives an email when their balance is manually adjusted. Admins can override per-adjustment using the Notify customer checkbox.
Adjustment email template WalletPro default Links to WooCommerce > Settings > Emails > Wallet Manual Adjustment where the subject and body can be customised.
Minimum debit amount 0.01 Prevents zero or sub-cent debits. Adjustable to enforce a floor (for example, 1.00 to avoid micro-adjustments).
Maximum single adjustment (unlimited) Optional cap on any single manual credit or debit. Useful for requiring secondary approval on large adjustments via external workflow.

Audit Log Entries

Every manual adjustment produces a ledger row visible at WooCommerce > WalletPro > Audit Log. You can filter by:

Each row shows: date/time (UTC), customer, actor, type, amount, running balance after the entry, reason text, and chain hash status (Valid / Broken).

To export a filtered set of ledger entries as CSV, click Export CSV above the table. The export includes all visible columns plus the raw HMAC hash for external verification. Scheduled CSV exports (including audit log extracts) can be configured at WooCommerce > WalletPro > Reports > Scheduled Exports.

WP-CLI

Manual adjustments can be scripted using WP-CLI, which is useful for bulk imports from external systems or automated reconciliation jobs.

# Credit a single customer
wp wallet adjust --user=42 --amount=25.00 --type=credit --reason="Promotional credit Q2"

# Debit a single customer
wp wallet adjust --user=42 --amount=10.00 --type=debit --reason="Fee correction"

# Bulk credit from a CSV (user_id,amount,reason columns)
wp wallet adjust --bulk=/path/to/adjustments.csv --type=credit

# Skip customer notification for scripted bulk runs
wp wallet adjust --user=42 --amount=5.00 --type=credit --reason="Migration credit" --no-notify

The --bulk flag accepts a CSV where each row specifies a customer. Required columns: user_id, amount. Optional columns: reason (falls back to the --reason flag value if omitted), currency.

See the WP-CLI reference for the full parameter list and wp wallet adjust --help output.

REST API

Manual adjustments are available via the REST API for headless or external integrations.

Endpoint: POST /wp-json/walletpro/v1/wallets/{user_id}/adjust

Parameter Type Required Description
type string Required credit or debit
amount string Required Decimal amount as a string, e.g. "25.00"
reason string Required Human-readable reason for the adjustment
currency string Optional ISO 4217 code. Defaults to the store's default currency.
notify boolean Optional Send customer email. Defaults to the Send adjustment emails setting value.

Example request:

POST /wp-json/walletpro/v1/wallets/42/adjust
Authorization: Basic <base64(user:app_password)>
Content-Type: application/json

{
  "type": "credit",
  "amount": "25.00",
  "reason": "Promotional credit Q2 2026",
  "currency": "USD",
  "notify": true
}

Example response (200 OK):

{
  "success": true,
  "ledger_id": 4821,
  "user_id": 42,
  "type": "credit_manual",
  "amount": "25.00",
  "currency": "USD",
  "balance_before": "10.50",
  "balance_after": "35.50",
  "reason": "Promotional credit Q2 2026",
  "actor_id": 1,
  "created_at": "2026-06-20T14:32:11Z",
  "chain_hash": "a3f8c2..."
}

Error response (422 Unprocessable Entity), insufficient balance for debit:

{
  "code": "walletpro_insufficient_balance",
  "message": "Debit of 50.00 USD exceeds current balance of 35.50 USD and negative balances are not allowed.",
  "data": {
    "status": 422,
    "current_balance": "35.50",
    "requested_debit": "50.00"
  }
}

Available Hooks

Use these hooks to extend or react to manual adjustments in custom code or a site-specific plugin.

Hook Type Description
walletpro_before_manual_adjustment action Fires before the balance is changed. Passes $user_id, $type, $amount, $reason, $actor_id. Throw a WalletPro_Exception to cancel the adjustment.
walletpro_after_manual_adjustment action Fires after the ledger entry is committed. Passes the $ledger_entry object (including balance_before, balance_after, ledger_id).
walletpro_can_adjust_balance filter Return false to block the adjustment. Passes $allowed (bool), $admin_user (WP_User).
walletpro_adjustment_email_args filter Modify the email template variables before the adjustment notification is sent. Passes $args array and $ledger_entry.
// Example: log all manual adjustments to an external system
add_action( 'walletpro_after_manual_adjustment', function( $entry ) {
    wp_remote_post( 'https://erp.example.com/wallet-events', [
        'body' => wp_json_encode( [
            'event'   => 'manual_adjustment',
            'user_id' => $entry->user_id,
            'type'    => $entry->type,
            'amount'  => $entry->amount,
            'reason'  => $entry->reason,
            'balance_after' => $entry->balance_after,
        ] ),
        'headers' => [ 'Content-Type' => 'application/json' ],
    ] );
} );

Customer-Visible Impact

After a manual adjustment is applied, the customer sees the change reflected immediately:

Customers cannot initiate, edit, or delete manual adjustment entries. The reason field is read-only from their side.

```