WooCommerce Payment Gateways by User Role
Show different WooCommerce payment gateways per user role: invoice for wholesale, cards for retail. Filter, snippet, plugin route and the guest-checkout trap.

A store that sells to both consumers and businesses has two different payment conversations. Retail shoppers want cards, wallets and the fastest possible checkout. Trade accounts want to pay on invoice with 14 or 30 day terms, and often cannot use a company card at all. Showing both audiences the same checkout means one of them is confused and the other is annoyed.
The fix is to make the gateway list depend on the user role of the person checking out: invoice and purchase order for approved trade roles, cards and wallets for everyone else. This guide covers the filter, the snippet, the plugin route and the three traps — guests, multiple roles, and role security — that break naive implementations.
What role-based payment rules are actually for
- Invoice / pay-on-account for wholesale. The single most common case, and the one with the most money attached.
- Hiding expensive consumer wallets from B2B. A trade order of €4,000 through a 3% wallet costs €120 in fees for no benefit.
- Restricting cash on delivery to a trusted role such as returning customers, while new accounts pay up front.
- Internal or staff ordering where a zero-cost internal gateway exists that customers must never see.
- Staged rollout of a new gateway, enabled for a test role before it goes live for everyone.
If the restriction depends on the product rather than the buyer, use a category rule instead — see restricting payments by product category.
The mechanism
As with every conditional payment gateways rule in WooCommerce, the work happens in `woocommerce_available_payment_gateways`. The gateway list is filtered server-side before checkout renders, so a role rule written here cannot be bypassed by editing the page.
```php add_filter( 'woocommerce_available_payment_gateways', function ( $gateways ) { if ( is_admin() ) { return $gateways; }
$user = wp_get_current_user(); $roles = (array) $user->roles;
if ( in_array( 'wholesale_customer', $roles, true ) ) { // Trade accounts: invoice only. return array_intersect_key( $gateways, array( 'cheque' => true ) ); }
// Everyone else, guests included: no invoice. unset( $gateways['cheque'] );
return $gateways; } ); ```
Note what this snippet does *not* do: it never assumes a logged-in user. Guests fall through to the second block, which is the behaviour you want.
Trap 1: guests have no role
`wp_get_current_user()` returns a user object with an empty `roles` array for logged-out visitors. Rules written as "if the role is not X, hide Y" behave correctly for guests only by accident; rules written as "if the role is X, show Y, else do nothing" leave guests looking at the full gateway list including your invoice option.
Write the guest case down explicitly, test it in a private window, and treat it as a first-class branch rather than a default.
Trap 2: users can hold several roles
WordPress users can have more than one role, and wholesale, membership and subscription plugins add them freely. A customer might be `customer` and `wholesale_customer` at once.
Pick a resolution rule and apply it consistently:
| Strategy | Behaviour | Use when |
|---|---|---|
| Most permissive | Any qualifying role unlocks the gateway | Roles grant privileges (wholesale invoice) |
| Strictest wins | Any restricting role removes the gateway | Roles express risk (COD-blocked customers) |
| Priority order | First matching role in your own list decides | Tiered pricing or membership levels |
For invoice payment, most-permissive is usually right: a trade buyer who also holds the default customer role should still see the invoice option.
Trap 3: the rule is only as strong as the role
Role-based payment terms are a commercial decision dressed as a technical one. Once a role can pay on account, anyone who obtains that role gets your credit terms. So:
- Never let users self-select a wholesale role at registration without approval.
- Keep role assignment manual, or behind an application form your team reviews.
- Audit the role's user list quarterly; accounts accumulate.
- Log role changes if you have a plugin that supports it, so a dispute has a trail.
Doing it without code
Once you have more than one role and more than one gateway, the snippet grows conditionals fast. WooCommerce Payment Gateway Per Product handles role conditions alongside product and category conditions in the same rule set, so "invoice for wholesale, but never for the clearance category" is two rows rather than a nested block of PHP. Rules stay visible in wp-admin, which matters when the person who wrote the snippet has moved on.
Combining role rules with pricing
Role-based payment is rarely the only role-based thing in a B2B store. It usually sits next to role-based prices and minimum order quantities. If you are building the wider setup, the WooCommerce B2B hub covers pricing and quantity rules, and the payment rule slots in as the last step: the trade customer sees trade prices, trade minimums, and a trade payment method.
Test plan
- Logged out — expected gateway set, invoice hidden.
- Default customer role — same as above.
- Wholesale role — invoice visible, consumer wallets hidden if that is the rule.
- A user holding both customer and wholesale roles — matches your resolution strategy.
- Admin creating an order in wp-admin — the rule must not lock your own team out.
- A wholesale customer paying an existing order from the account area — the pay-for-order page reads the same filter, so verify it there too.
Next step List your roles in one column and your gateways in another, then mark every intersection as allowed or blocked. If the grid has more than a couple of blocked cells, build it in [Payment Gateway Per Product](/plugins/woocommerce-payment-gateway-per-product) rather than in PHP.
FAQ
- How do I show a payment gateway only to a specific user role in WooCommerce?
- Hook woocommerce_available_payment_gateways, read the current user's roles with wp_get_current_user(), and unset the gateways that role should not see. Guests have no role, so treat them explicitly as their own case.
- How do I offer invoice payment to wholesale customers only?
- Enable a cheque or invoice gateway, then remove it for every role except your wholesale role. Pair it with an approval step so a self-registered account cannot pick the wholesale role and pay on account.
- What role does a guest checkout user have?
- None. wp_get_current_user() returns an empty roles array for logged-out shoppers, so a rule written only in terms of roles will silently apply the default set. Always define what guests may use before you ship the rule.
- Can a customer have more than one role?
- Yes, WordPress users can hold several roles at once, which is common when a membership or wholesale plugin adds one. Decide whether your rule is most-permissive or strictest-wins across the roles a user holds.
- Is role-based payment secure enough for pay-on-account?
- Only if the role itself is protected. Because the rule runs server-side on the gateway list, it cannot be bypassed from the browser, but anyone who can obtain the role gets the payment terms — so keep role assignment manual or approval-based.
This article is part of our WooCommerce payments topic hub, where the related plugins and guides live together.


