Skip to content

Payments

Every payment in Easy Invoice is its own post (easy_invoice_payment CPT). The invoice's payment status is derived from the related Payment records — that's how partial payments, refunds, and split payments work without breaking the invoice.

What a payment is

  • Custom post type: easy_invoice_payment (includes/EasyInvoice.php:349–377).
  • Public: no.
  • Admin UI: hidden submenu — visible from Easy Invoice → Payments.

Each Payment links to one invoice via post meta. An invoice can have many payment records (partial flows, refunds, split methods).

Recording a manual payment

Open Easy Invoice → Add New Payment.

  1. Pick the invoice from the dropdown (search by invoice number).
  2. Set the Payment date (defaults to today).
  3. Pick the Gateway — usually Manual for cash / wire / cheque.
  4. Enter the Amount (full or partial).
  5. Add a Transaction ID (optional reference).
  6. Pick a Status: Completed for normal, Pending while you wait on bank clearance, Refunded after issuing a refund.
  7. Click Save.

Easy Invoice then:

  1. Sums all completed payments for the invoice.
  2. Compares against the invoice total.
  3. Updates the invoice's _payment_status meta:
    • completed — sum ≥ total.
    • partial-paid0 < sum < total (Pro shows partial).
    • unpaid — sum is zero.
  4. Fires easy_invoice_payment_completed (action) for completed payments.

The decision logic lives in PaymentController::should_update_invoice_status (includes/Controllers/PaymentController.php:1219) and respects the easy_invoice_should_update_invoice_status filter.

Gateway-driven payments

When a client pays via a configured gateway, Easy Invoice creates the Payment record automatically.

GatewayWhen it createsWebhook endpoint
PayPal (Free)After PayPal IPN returns success.n/a (IPN handler)
Manual (Free)Never — admin creates manually.n/a
Stripe PROAfter Stripe webhook fires payment_intent.succeeded.admin-ajax.php?action=easy_invoice_stripe_webhook
Square PROAfter Square webhook + 15-min reconcile cron.admin-ajax.php?action=easy_invoice_square_webhook
Mollie PROAfter Mollie webhook returns paid.admin-ajax.php?action=easy_invoice_mollie_webhook
Authorize.Net PROAfter Authorize.Net post returns.admin-ajax.php?action=easy_invoice_authorizenet_response
Bank Transfer PROCreated in pending-bank status; admin marks completed.n/a
Cheque PROCreated in pending-cheque; admin marks completed.n/a
Cash PROOn client click; mark completed manually after collection.n/a
Moneris PROAfter Moneris response.n/a

For full webhook setup, see Payment gateways.

Partial payments

PROPartial payments module

Pro lets clients pay any amount toward an invoice. The remaining balance stays open and can be paid later via the same public link.

Unlock partials →

How it works:

  1. Enable under Settings → Partial Payments (Pro only).
  2. Set a minimum partial (e.g. 25 % of total).
  3. The public invoice page shows an editable amount field.
  4. Each partial creates a Payment record — invoice status reflects "partial-paid".
  5. When the sum reaches the total, status flips to "completed" automatically.

The easy_invoice_display_total filter (PartialPayments.php:22) lets templates show paid vs balance side by side.

Deposit invoices

PRODeposit invoices module

Charge a deposit (e.g. 50% upfront) and bill the balance later as a follow-up invoice. Each deposit is its own Payment record linked to the parent invoice.

Unlock deposits →

Two flows are supported:

  • Single deposit + balance — charge X % now, the remainder when work is done.
  • Multi-stage — charge a series of percentages (e.g. 30 / 40 / 30).

Set up under Settings → Deposit Invoices.

Refunds

A refund is a status change on the Payment record:

  1. Issue the refund in the gateway dashboard (Stripe, PayPal, etc.).
  2. Open Easy Invoice → Payments → find the payment.
  3. Edit → set Status to Refunded.
  4. Save.

The invoice's _payment_status recomputes — if the only successful payment was refunded, the invoice goes back to unpaid. If you partially refunded, status reflects the new sum (e.g. partial-paid).

Stripe refunds via the gateway dashboard don't auto-mirror back to Easy Invoice. Plan for the two-step manual mirror.

Payment reminders

Free: bank / cheque pending reminder

Cron easy_invoice_payment_reminder runs daily and emails clients who have payments stuck in pending-bank or pending-cheque for more than N days. Configure under Settings → Advanced → Payment reminder days.

Pro: full reminder engine

PROPayment reminder cadence

Send N days before due, on due day, and X days after due. Independent templates and frequencies for each.

Unlock reminders →

Pro cron easy_invoice_send_payment_reminders runs daily — see Settings → Email → Payment Reminder.

Receipts

When a payment completes, Easy Invoice can email a receipt:

  • Free: configure under Settings → Email → Payment Received.
  • Pro: receipts are also stored as separate documents (action easy_invoice_pro_receipt_generatedReceiptController.php:273) and can be downloaded individually.

Reports tied to payments

Open Easy Invoice → Reports for:

  • Revenue over time (line chart).
  • Status breakdown (paid vs unpaid vs overdue).
  • Payment-method mix (which gateway brings the most money).
  • Top clients (by total paid).

All charts are Chart.js, rendered client-side.

Where to go next