Skip to main content

MembershipStripeSettingsController

\Benecaster\REST\MembershipStripeSettingsController

Class Premium

Admin REST endpoints for the Settings → Payments panel. Auth: permission_callback_admin (manage_options + wp_rest nonce) on all three endpoints. Provides GET and POST /membership/stripe for reading and saving Stripe keys, the test-mode toggle, and the webhook signing secret, plus POST /membership/stripe/test to verify the current keyset against the live Stripe API. Shares the same underlying StripeClient storage as ListenerSupportStripeSettingsController — saving keys through either panel is reflected immediately in both, in both directions. This panel also carries the webhook_secret field; either panel can set the signing secret, since the secret is mode-independent and shared across both payment surfaces.

Constructor Dependencies

Type Description
\Benecaster\Payment\StripeClient All key/secret/webhook storage and the live Stripe SDK connection used by test_connection().

Methods

Method Visibility Since Description
register_routes(): void Public — Registers GET+POST /membership/stripe and POST /membership/stripe/test, all permission_callback_admin.
get_site( WP_REST_Request $request ): WP_REST_Response Public — GET /membership/stripe. Returns build_state() — the panel's current configuration with secret keys reduced to booleans (never the plaintext).
save_site( WP_REST_Request $request ): WP_REST_Response|WP_Error Public — POST /membership/stripe. test_mode and webhook_secret are written directly when their keys are present in the body (webhook_secret is mode-independent, written once, outside the per-mode loop). For each of test/live: a field's presence is checked with array_key_exists(), not emptiness — an OMITTED public/secret key field preserves the currently-stored value, while an explicit empty string reaches save_keyset() and clears it (after failing its prefix validation, since an empty string doesn't match a Stripe key prefix — see the notes below on the one exception this created). Returns the StripeClient's WP_Error verbatim if save_keyset() rejects a keyset (e.g. a live secret key pasted into the test field). Returns the refreshed build_state() on success.
test_connection( WP_REST_Request $request ): WP_REST_Response Public — POST /membership/stripe/test. 400 {ok: false} when StripeClient::sdk() is null (no secret key configured for the active mode). Otherwise calls the Stripe SDK's Account::retrieve() and returns {ok: true, mode, account_id, country} — the same fields the Stripe Dashboard shows, so an operator can confirm they connected the account they meant to. Any ApiErrorException or other Throwable is caught and returned as {ok: false, error: message} with a 400, never thrown.
build_state(): array — — Assembles the GET/POST response shape: test_mode, mode, both public keys (plaintext — publishable keys are not secret), both secret-key-set booleans (never the plaintext secret), is_configured, webhook_secret_set (boolean), and webhook_url.
current_public_key( string $mode ): string — — Reads the mode's publishable key directly from its wp_option (OPTION_PUBLIC_KEY_TEST / _LIVE).
current_secret_key( string $mode ): string — — Delegates to StripeClient::get_secret_key_for_mode() for the mode's stored secret key.

Notes

Extends the plugin's internal RestController base — not part of the public API; its own docblock tells add-on developers not to extend it, and to register independent routes on rest_api_init with the public benecaster_rest_permission_admin() function instead. Inherits register() (hooks register_routes() onto rest_api_init), the permission_callback_admin / permission_callback_editor / permission_callback_subscriber callbacks, rest_error(), and not_found().

There is no way to clear a saved Stripe secret key from the admin UI. Because an omitted field preserves the current value and an explicit empty string is rejected by save_keyset()'s prefix validation (benecaster_stripe_key_prefix_mismatch), the React panel's "leave blank to keep current" convention means blank can never mean "clear" either.