WP Manifestindependent plugin directory
manifest / ecommerce / paypal-additional-charge

PayPal Additional Charge for WooCommerce

WooCommerce plugin to create additional PayPal payment requests (invoices) for existing orders — no PayPal API needed, HPOS-compatible.

★ 0stars

Install

Download source zip No release zip yet

This is the repository archive. It installs, but the folder name will carry the branch suffix and updates will not flow.

Install straight from GitHub with WP-CLI:

wp plugin install https://github.com/manoj-intellect/paypal-additional-charge/archive/refs/heads/main.zip
No built-in updater. New versions won't appear under Dashboard → Updates. Install new releases yourself, or let Git Updater track the repository.

Create additional PayPal payment requests (invoices) for existing WooCommerce orders — without any direct PayPal API integration.


Overview

This plugin adds an Additional PayPal Charge meta box to the WooCommerce order edit screen. From there, an administrator can create a brand-new WooCommerce order that acts as an invoice for an additional amount and is paid through WooCommerce PayPal Payments using WooCommerce's standard Pay for Order flow.

It relies entirely on existing WooCommerce infrastructure:

  • WooCommerce
  • WooCommerce PayPal Payments
  • The built-in Customer Invoice email
  • The built-in Pay for Order page

There is no PayPal REST SDK and no direct PayPal API call. The payment is processed 100% through WooCommerce PayPal Payments.


Features

  • 🧾 Additional charge meta box on the order edit page — amount, reason, and a Create Payment Order button.
  • 🆕 Creates a real WooCommerce order for the same customer, carrying over billing, shipping, email, phone, currency, and tax context (but not the original products).
  • 💵 Single Fee line item (Additional charge for Order #111657) — the order total equals the fee amount.
  • 💳 PayPal Payments + Pending Payment — the customer pays via the standard Pay for Order page.
  • ✉️ Automatic Customer Invoice email with a Pay for this order link, reusing WooCommerce's own email template.
  • 🔗 Bidirectional linking between the original order and the payment order.
  • 🚫 Duplicate protection — won't create a second request while one is pending, processing, on-hold, or paid.
  • 🔄 Payment sync — when the payment order is paid, the original order is updated with the status, date, amount, transaction ID, and an order note.
  • ⚡ Full HPOS compatibility — uses WooCommerce CRUD APIs only; no direct wp_posts / wp_postmeta queries.
  • 🧩 Fully isolated from the Authorize.Net additional charge plugin — both can run side by side.

How it works

flowchart TD
    A[Admin opens order #111657] --> B[Enters amount + reason<br/>in meta box]
    B --> C[Clicks Create Payment Order]
    C --> D[New order #111658 created<br/>same customer, Fee item, PayPal, Pending]
    D --> E[Customer Invoice email sent<br/>with Pay for this order link]
    E --> F[Customer pays via<br/>WooCommerce PayPal Payments]
    F --> G[Original order #111657 updated:<br/>status Paid, date, amount, txn ID, note]
  1. Open an order and use the Additional PayPal Charge meta box.
  2. Enter an amount and a reason, then click Create Payment Order.
  3. The plugin creates a new order for the same customer with a single Fee item, set to PayPal Payments + Pending Payment.
  4. WooCommerce's built-in Customer Invoice email is sent with a Pay for this order link.
  5. When the customer pays, the original order is updated automatically with the payment result and an order note.

Installation

  1. Copy the paypal-additional-charge folder into wp-content/plugins/.
  2. In WP Admin → Plugins, activate PayPal Additional Charge for WooCommerce.
  3. Ensure WooCommerce and WooCommerce PayPal Payments are installed and active.

Requirements: WordPress 5.8+, WooCommerce, WooCommerce PayPal Payments, PHP 7.4+.


Usage

  1. Go to WooCommerce → Orders and open any order.
  2. In the Additional PayPal Charge meta box (right sidebar):
    • Enter the Charge amount (required, must be greater than zero).
    • Enter a Reason / description (required).
    • Click Create Payment Order.
  3. A confirmation prompt appears; confirm to create the order and email the customer.
  4. The meta box then shows the linked payment order, its status, and dates.

Once paid, the original order's meta box shows:

Additional Payment

Amount:         $10.00
Reason:         Additional charge for Order #111657
Status:         Paid
Payment Order:  #111658   ← clickable
Created:        July 3 2026
Paid:           July 4 2026

Architecture

The plugin follows a clean, modular, object-oriented structure with one responsibility per file.

paypal-additional-charge/
│
├── paypal-additional-charge.php     # Bootstrap, constants, HPOS declaration
│
├── includes/
│   ├── class-admin.php              # Meta box UI, validation, processing, notices
│   ├── class-order-manager.php      # Payment order creation, Fee item, linking, dup guard
│   ├── class-payment-sync.php       # Syncs paid status back to the original order
│   ├── class-email.php              # Customer Invoice email integration
│   ├── class-meta.php               # Meta keys + typed getters (single source of truth)
│   ├── class-hpos.php               # HPOS detection helpers
│   └── class-helper.php             # Gateway detection, admin URLs, formatting
│
├── assets/
│   ├── admin.css
│   └── admin.js
│
├── languages/
│   └── paypal-additional-charge.pot
│
├── readme.txt                       # WordPress.org-style readme
└── README.md                        # This file
Module Responsibility
PAC_Plugin Bootstrap, constants, text domain, HPOS + blocks compatibility declaration
PAC_Admin Meta box rendering, form validation, submission handling, admin notices
PAC_Order_Manager Creates the payment order, copies context, adds the Fee item, links both orders, enforces duplicate prevention
PAC_Payment_Sync Mirrors the paid result (status, date, amount, transaction ID, note) back to the original order
PAC_Email Triggers WooCommerce's Customer Invoice email and injects the requested intro copy
PAC_Meta Central registry of all meta keys, status constants, and typed getters
PAC_HPOS HPOS detection and order-screen ID resolution
PAC_Helper PayPal gateway detection, HPOS-aware admin URLs, price/date formatting

Order linking (metadata)

Both orders reference each other so the relationship survives independently.

Original order

Meta key Description
_paypal_additional_payment_order_id Linked payment order ID
_paypal_additional_payment_status pending | paid
_paypal_additional_amount Charge amount
_paypal_additional_reason Reason / description
_paypal_additional_created_date When the request was created
_paypal_additional_paid_date When it was paid (set on completion)
_paypal_additional_transaction_id PayPal transaction ID (if available)

Payment order

Meta key Description
_original_order_id The source order ID
_is_additional_payment_order yes flag identifying our orders
_additional_payment_reason Reason / description
_additional_payment_amount Fee amount

Duplicate protection

While a linked payment order is pending, processing, on-hold, or completed/paid, the meta box disables creating another request and explains why, with a link to the existing payment order. This is enforced both in the UI and inside PAC_Order_Manager::create_payment_order().


Email

No new email template is created. The plugin triggers WooCommerce's built-in Customer Invoice email (WC_Email_Customer_Invoice) and — only for orders it created — injects the requested intro copy via the woocommerce_email_before_order_table hook:

Hi John,

An order has been created for you on Tactical Scorpion Gear.

Your order details are below, with a link to make payment when you're ready.

[ Pay for this order ]

The email retains WooCommerce's standard layout: company logo, order title, order summary, fee line item, total, customer note, billing address, and footer.


HPOS compatibility

  • Declares compatibility with High Performance Order Storage (custom_order_tables) and Cart/Checkout Blocks.
  • All order access goes through WooCommerce CRUD (wc_get_order, $order->get_meta(), $order->update_meta_data(), $order->save()).
  • No direct wp_posts / wp_postmeta queries and no deprecated WooCommerce functions.

Compatibility

Requirement Status
WooCommerce ✅ Required
WooCommerce PayPal Payments ✅ Required
HPOS ✅ Compatible
Customer Invoice email ✅ Reused
Pay for Order page ✅ Reused
Authorize.Net dependency ❌ None
PayPal REST SDK / API calls ❌ None

Development notes

  • Follows WordPress Coding Standards and object-oriented PHP.
  • All input is sanitized; all output is escaped.
  • Nonce verification and capability checks (edit_shop_order) on every action.
  • Isolated namespacing (PAC_ classes, _paypal_additional_* meta) so it never collides with the Authorize.Net plugin.

Lint all PHP files:

for f in paypal-additional-charge.php includes/*.php; do php -l "$f"; done

Regenerate the translation template:

wp i18n make-pot . languages/paypal-additional-charge.pot

Changelog

1.0.0

  • Initial release.

License

Released under the GPLv2 (or later) license, consistent with WordPress and WooCommerce.