appycodes.

Surgical plugin work. Not 600 lines pasted into functions.php.

One feature, one integration, or one bug, done as a properly-namespaced, idempotent, version-controlled plugin or mu-plugin. Real software, in your repo, not in your cPanel.

mu-plugins/inspirelle-typeb-autocoupon.php

v1.2.0

<?php
/**
 * Plugin Name: INSPIRELLE Type-B Auto-Coupon
 * Description: Auto-applies pre-issued store credit on renewal checkout.
 * Author:      Appycodes  (https://appycodes.dev)
 * Version:     1.2.0
 * Requires:    WooCommerce 8.x, WC Subscriptions 6.x
 */

namespace Appycodes\Inspirelle\TypeBAutocoupon;

if ( ! defined( 'ABSPATH' ) ) { exit; }

// idempotent, per-session dedup, silent on failure, 0-order edge case handled
add_action( 'woocommerce_before_checkout_form', __NAMESPACE__ . '\\maybe_apply', 20 );

function maybe_apply(): void {
    // ...
}

What you get

Six engagement shapes

01

Surgical plugin work

One feature, one integration, one bug, done as a proper plugin or mu-plugin. Namespaced, idempotent, in version control.

02

WooCommerce extensions

Pricing rules, role-based access, custom shipping logic, gateway extensions, subscription extensions, ACF-driven inventory.

03

Third-party integrations

Zoho, Salesforce, HubSpot, custom APIs, written as plugins with proper hook architecture and error handling.

04

WP + Composer + CI

Version control + CI deploy pipelines. So plugins don't live in production cPanel forever, fixed by SSH and forgotten.

05

Plugin audits and takeovers

Taking over a plugin built by another team. Making it stable, idempotent, version-controlled, and predictable.

06

Public plugin releases

.org repo or private GitHub releases when the project requires distribution. SVN dance handled.

Evidence, three plugins, three shapes

What real WordPress plugin code looks like

mu-plugin, stateful, 0-order edge case

INSPIRELLE auto-coupon

Auto-applies a customer's pre-issued store-credit coupon on the renewal checkout. Email-restricted (only applies if the cart customer's email matches the coupon restriction), per-session deduplicated (won't keep re-applying after the customer removes it manually), silent on failure (no scary red notices), and overrides WooCommerce's default coupon notice with a branded message.

0-order edge case explicitly handled (where store credit fully covers the renewal, gateways behave differently). Per-session reset between browser sessions so a returning customer gets it again tomorrow.

// branded override
add_filter( 'woocommerce_coupon_message',
  function ( $msg, $msg_code, $coupon ) {
    if ( 'inspirelle_typeb' !== $coupon->get_code() ) return $msg;
    $amt = number_format( (float) $coupon->get_amount(), 2 );
    return "Your INSPIRELLE store credit of {$amt} has been applied to this renewal.";
  }, 10, 3
);

Plugin, namespaced, idempotent, dry-run-able

Localize Links

A WordPress plugin in the Appycodes\LocalizeLinks namespace that walks posts and rewrites internal links per locale, storing the localized content in per-locale postmeta (blog_content_{locale}).

Idempotent: skips posts where the target meta is already populated, unless --force is set. Dry-run mode surfaces what would change without writing. Per-link diff output logged. Filter hook (appycodes_localize_links_meta_key) so the meta key template is customisable per project. Action hook (appycodes_localize_links_before_post) so other plugins can extend.

# WP-CLI usage
wp localize-links run --locale=fr --dry-run
wp localize-links run --locale=fr           # writes
wp localize-links run --locale=fr --force   # re-writes existing

WooCommerce extension, ACF-driven, bug-fixed

Per-size stock plugin

WooCommerce extension for a garment store: ACF-driven per-size stock fields (XS / S / M / L / XL / XXL) summed to set total WC stock. Per-size add-to-cart validation reads the selected size from addon-* POST keys (because the site uses WooCommerce Product Add-ons). Stock reduction on order status change to processing / completed, guarded by a _appy_size_stock_reduced order meta flag for idempotency. Stock restoration on cancellation / refund.

Real bug we caught and fixed: the existing function had an if ($total_stock > 0) guard that prevented stock from updating to zero when all sizes sold out, leaving the product listed as in-stock when it wasn't. Removed the guard and properly set _manage_stock and _stock_status.

// BEFORE, bug
if ( $total_stock > 0 ) {  // never updates to zero
  update_post_meta( $id, '_stock', $total_stock );
}

// AFTER, fixed
update_post_meta( $id, '_stock', max(0, $total_stock) );
update_post_meta( $id, '_manage_stock', 'yes' );
update_post_meta( $id, '_stock_status',
  $total_stock > 0 ? 'instock' : 'outofstock' );

Pair with custom WordPress, WooCommerce, and subscriptions engineering. Integration-heavy plugins ride alongside API and integration work.

The plugin vs functions.php decision box

When functions.php is fine, and when it absolutely isn't

X-axis: lines of code. Y-axis: state and complexity. Each quadrant is what the right shape looks like.

Low LOC, medium state

Snippet plugin

Add a custom dashboard widget, wp-cli command

High LOC, stateful

Real plugin

WooCommerce extension, third-party integration, custom CPT engine

Low LOC, stateless

OK in functions.php

Conditional class on body, hook the_content once

Medium LOC, site-specific, must-not-deactivate

mu-plugin

INSPIRELLE auto-coupon, security headers, multisite-wide behaviour

Lines of code, lowHigh

Good fit if

When a plugin is the right call

  • Sites with one specific feature, integration, or bug that needs proper engineering
  • Operators who have 600+ lines in functions.php and would rather not
  • Teams who inherited a plugin from another agency and need someone to actually own it
  • WooCommerce stores needing a non-default behaviour shipped as production-grade code

Probably not a fit

When you don't need an agency for it

  • Full WordPress site builds, that's the Custom WordPress page
  • Snippets you'd find on Stack Overflow, those don't need an agency
  • Teams that won't put plugins in version control on principle

How we ship plugins

Composer + namespaces + CI. Like real software.

Plugin
PSR-4 autoloading, Composer, namespaced classes, proper hooks
mu-plugins
Site-specific code that must never be deactivated
Idempotency
Meta flags, checksums, dry-run modes, audit logs
CI
GitHub Actions / GitLab CI, PHPUnit, PHP_CodeSniffer, phpstan
Deploy
Composer-managed, version-controlled, staged rollout

One feature, done right

Bring the brief. We'll ship the plugin in your repo, not in your cPanel.

Contact