WP Manifestindependent plugin directory
manifest / ecommerce / woocommerce-payment-gateway

WooCommerce High-Risk Payment Gateway

WooCommerce payment gateway plugin: NMI (primary) + Stripe (failover), tokenization, idempotency, multi-step checkout, PCI DSS SAQ-A-EP docs

by Danh Le · github.com/odanree/woocommerce-payment-gateway · website

0stars
0forks

Install

No release zip yet. The repository archive installs, but the folder name will carry the branch suffix and updates will not flow:

wp plugin install https://github.com/odanree/woocommerce-payment-gateway/archive/refs/heads/master.zip

Custom WooCommerce payment gateway plugin integrating NMI (Network Merchants Inc) as the primary processor and Stripe as a drop-in failover — targeting high-risk merchant categories where processor relationships can be terminated with little notice.

Demonstrates: tokenization, webhook signature verification, idempotency controls, processor failover via config swap, multi-step checkout UX, and PCI DSS v4.0 SAQ-A-EP alignment documentation.


Why NMI + Stripe failover

High-risk merchants (supplements, CBD, adult content, firearms accessories, continuity subscriptions) are routinely dropped by payment processors. The failover design here treats processor portability as a first-class requirement:

Normal flow:   Order → NMI API → Capture → WooCommerce order status
Failover flow: Config change (ACTIVE_GATEWAY=stripe) → No code rewrite → Order → Stripe API

The same WC_Gateway_Failover_Manager class routes to either processor based on a single WordPress option — verified in tests to swap without any code change.


Architecture

Customer checkout
        │
        ▼
WC_Gateway_Multistep_Checkout
(3-step: Shipping → Payment → Review)
        │
        ▼
WC_Gateway_Failover_Manager
        │
        ├── active_gateway = 'nmi'  ──► WC_Gateway_NMI
        │                                   └── NMI Collect.js tokenization
        │                                   └── POST /api/transact.php
        │
        └── active_gateway = 'stripe' ──► WC_Gateway_Stripe_HighRisk
                                              └── Stripe.js Elements
                                              └── PaymentIntent API
        │
        ▼
WC_Idempotency
(deduplicates retry/double-submit via order hash)
        │
        ▼
WC_Tokenization_Manager
(stores processor tokens in wp_woocommerce_payment_tokens)
        │
        ▼
WC_Webhook_Handler
(NMI and Stripe webhooks → order status updates)

Stack

Layer Choice
Platform WordPress 6.4+ / WooCommerce 8.5+
Language PHP 8.1+
Primary processor NMI (Network Merchants Inc) Collect.js + REST API
Failover processor Stripe PaymentIntents API
Testing PHPUnit 10 + WooCommerce Unit Test Framework
Code style PHP_CodeSniffer (WordPress-Extra + WooCommerce)
CI GitHub Actions (lint + test)

Local development

Prerequisites

  • PHP 8.1+, Composer 2
  • WordPress + WooCommerce installed (or use the provided test bootstrap)
  • NMI sandbox account + Stripe test account
git clone https://github.com/odanree/woocommerce-payment-gateway.git
cd woocommerce-payment-gateway
composer install
cp .env.example .env
# Fill in NMI_SECURITY_KEY, STRIPE_SECRET_KEY, etc.

Run tests

composer test
# or directly:
./vendor/bin/phpunit --testdox

Install as a WordPress plugin

# Symlink or copy to wp-content/plugins/
ln -s /path/to/woocommerce-payment-gateway /path/to/wp-content/plugins/woocommerce-payment-gateway

# Or create a zip and upload via WP Admin
zip -r woocommerce-payment-gateway.zip . --exclude '.git/*' 'vendor/*' 'tests/*'

Configuration

After plugin activation, configure under WooCommerce → Settings → Payments:

Setting Description
Active Gateway nmi or stripe — switch to failover without any code change
NMI Security Key From NMI merchant portal (sandbox: use test key)
NMI Collect.js Key Tokenization public key
Stripe Secret Key sk_test_... for sandbox
Stripe Publishable Key pk_test_...
NMI Webhook URL https://your-store.com/wc-api/nmi_webhook
Stripe Webhook Secret From Stripe dashboard (used for signature verification)
Enable Test Mode Routes to processor sandbox environments

Processor failover

Switching processors requires one config change — no code rewrite:

// In wp-admin: WooCommerce → Settings → Payments → Active Gateway
// Change 'nmi' to 'stripe'

// Or programmatically:
update_option('wc_gateway_active', 'stripe');

The WC_Gateway_Failover_Manager handles the routing. See docs/adr/002-stripe-failover-config-swap.md for the decision rationale.


PCI DSS v4.0 SAQ-A-EP alignment

This plugin is scoped to SAQ-A-EP (not full PCI DSS QSA audit) because:

  • Cardholder data flows through the browser via tokenization (Collect.js / Stripe.js) — the server never sees raw card numbers
  • The server receives and processes tokens only
  • Payment page is hosted on the merchant's domain (EP = "e-commerce, partially outsourced")

Key controls implemented:

  • Tokenization via Collect.js (NMI) and Stripe Elements — no PAN on server
  • Webhook signature verification (HMAC-SHA256 for NMI, Stripe-Signature header for Stripe)
  • Idempotency keys prevent double-charges on network retries
  • TLS enforced at Nginx layer (see vps-woocommerce-stack)

See docs/pci-dss/ for full SAQ-A-EP alignment checklist, data flow diagram, and cardholder data environment scoping.


CI

Check Trigger
PHP_CodeSniffer (WP-Extra) push / PR
PHPUnit tests push / PR
Secret scan (gitleaks) push / PR