What it does
mam-stripe-manager is the Stripe integration for the MAM Suite. It does three jobs:
- Saved cards for app users. The app’s native PaymentSheet collects the card; the server only ever sees Stripe tokens. The plugin creates SetupIntents and ephemeral keys on demand, attaches the resulting PaymentMethod to the user’s Stripe Customer, and records a display name (“Visa ending in 4242”) for the checkout screen.
- Server-side charging and refunding of WooCommerce orders through the
mam_pmt_charge_card/mam_pmt_refund_cardfilters, including the checkout hold flow (authorize now at 120% of the order total, capture the real amount later) and idempotent, over-refund-guarded refunds. - Stripe Connect for marketplaces: vendor enrollment and onboarding, commission transfers to vendor accounts, and payout reconciliation driven by a Stripe webhook whose signing secret the plugin provisions itself — admins never copy a webhook secret.
Modern, low-PCI-scope Stripe usage
All charging is built on PaymentIntents and SetupIntents (pinned API version 2022-11-15), so payments are SCA/3DS-capable. Card numbers never touch your server — the app tokenizes through Stripe’s PaymentSheet and the server works only with pm_… / pi_… ids. That keeps the site’s PCI posture at SAQ-A.
The pieces
Saved cards (card on file)
App requests arrive through MAM Main’s AJAX dispatcher (mam_main_ajax) with these subactions:
| Subaction | What it does |
|---|---|
stripe_create_setup_intent |
Creates a SetupIntent (usage: off_session) for the user’s Stripe Customer and returns its client_secret to the PaymentSheet. |
stripe_create_ephemeral_key |
Returns an ephemeral key so the PaymentSheet can list the customer’s saved cards. |
stripe_set_default_payment_method |
Attaches the new PaymentMethod (or, for Android, the most recently attached one) to the customer and makes it the default. A payment method that already belongs to a different customer is refused. |
Charge / capture / hold
When MAM WooCommerce checkout has “place hold on order” enabled, the initial charge is created with capture = no for 120% of the order total — an authorization hold. The final amount (order total, optionally plus a tip) is captured later by passing the held PaymentIntent id back as last_charge_id. Charges are protected by:
- an amount ceiling — a non-tip charge may not exceed the order total × the hold tolerance (default 1.2, filter
mam_pmt_charge_amount_tolerance); - a duplicate-submission guard — an order that already holds a succeeded (or matching open-hold) intent for the same amount reuses it;
- Stripe idempotency keys — a network retry of the same attempt maps to the original PaymentIntent;
- zero-decimal currency awareness — amounts convert correctly for JPY/KRW-style currencies, and the currency comes from the order.
Refunds
mam_pmt_refund_card refunds a PaymentIntent (pi_…) or Charge (ch_…) with a Stripe idempotency key and a pre-check that the requested amount does not exceed the remaining refundable balance on the charge. Refund ids are appended to the order’s _stripe_refund_ids meta.
Stripe Connect vendor onboarding
Vendors enroll from the app via a Gravity Form; the plugin creates a Stripe Connect account for the vendor’s email, emails them a Stripe-hosted onboarding link, and completes the loop on a page containing the [mam_stripe_connect_return] shortcode. Approval status (stripe_approved) is kept current by an hourly scan of all connected accounts. See Recipe: Stripe Connect vendor onboarding.
Payouts and reconciliation
Order completion pays each vendor’s commission with a Stripe Transfer (idempotent per vendor/order/amount), records the transfer on the order, and emails the vendor. When Stripe later pays the vendor’s bank (payout.created / payout.paid webhook events from the connected account), the plugin links the payout back to the recorded transfer so the order shows when the vendor was actually paid. See Recipe: Payout flow and reconciliation.
The self-provisioning payout webhook (new in 26.19.1)
The webhook endpoint is POST /wp-json/mam-stripe/v1/webhook, and every delivery must carry a valid Stripe signature — unsigned or mis-signed posts are rejected, so forged payout events cannot touch order data.
Stripe only reveals an endpoint’s signing secret at the moment the endpoint is created. So instead of asking admins to create the endpoint in the Stripe dashboard and copy the whsec_… value over, the plugin creates its own endpoint:
- On any wp-admin page load (and on the arrival of a webhook it can’t verify), if no signing secret is stored for the current mode, the plugin calls Stripe’s API and creates a webhook endpoint pointing at the site’s own URL, listening for
payout.createdandpayout.paidon connected accounts, pinned to API version2022-11-15, described as “MAM Stripe Manager payout webhook (auto-provisioned)”. - It stores the returned signing secret and the endpoint id (options
mam-stripe-connect-live-whsec/mam-stripe-connect-test-whsec, plus an internal…-whsec-id). Provisioning is throttled to once per hour per mode, so a site without API keys can’t hammer Stripe. - Self-healing: if signature verification starts failing and the plugin owns the endpoint id, it checks whether its endpoint still exists in Stripe. If the endpoint was deleted (dashboard cleanup, account re-key), the stored secret is discarded and a fresh endpoint is provisioned automatically.
Admins do nothing. The two settings fields Stripe Webhook Live/Test Signing Secret exist only as a manual override: if a whsec_… value is already present (auto-filled or pasted), the plugin never overwrites it, and a manually pasted secret with no stored endpoint id is never “healed” away.
One-time cleanup: if you previously created a webhook endpoint for this site by hand in the Stripe dashboard, delete that old endpoint once. Its deliveries are signed with a different secret, so they will be rejected (which is harmless but noisy in the Stripe dashboard) — the auto-provisioned endpoint already covers the payout events.
Test mode vs. live mode
The plugin follows the WooCommerce Stripe gateway’s “Enable test mode” flag (the testmode value in the gateway’s settings). When test mode is on, the plugin uses the Test publishable/secret keys and the Test webhook signing secret; otherwise the Live set. Customer records and webhook endpoints are kept per mode. The app is told which mode it’s in via the stripe_mode phone-data key.
What the app receives
The plugin adds these keys to the app’s phone-data JSON: stripe_public_key (mode-appropriate; falls back to the Woo Stripe gateway’s publishable key), use_stripe, is_payment_valid, checkout_selected_payment_method, wp_tsl_nonce, woocommerce_billing_name, woocommerce_billing_address, stripe_merchant (site name, filter mam_stripe_merchant_name), and via mam_stripe_get_stripe_info: stripe_customer_id and stripe_mode.
HPOS compatibility
The plugin declares WooCommerce High-Performance Order Storage (custom_order_tables) compatibility, and all order meta reads/writes go through the WooCommerce CRUD (wc_get_order() / get_meta() / update_meta_data() / save()), so it works with both legacy post storage and HPOS.
Setup paths
mam-mainandmam-woocommerceare active; the entitlement filter returns a non-blocked record formam-stripe-manager.- Activate the plugin and enter your four Stripe API keys — see Recipe: Initial Stripe setup. The payout webhook provisions itself.
- (Marketplaces) Bind the vendor enrollment form and publish the return page — see Recipe: Stripe Connect vendor onboarding.
Related articles
- Recipe: Initial Stripe setup
- Recipe: Stripe Connect vendor onboarding
- Recipe: Payout flow and reconciliation
- Hook:
mam_pmt_charge_card - Hook:
mam_pmt_refund_card - Hook:
mam_stripe_connect_transfer - Hook:
mam_stripe_get_stripe_info - Hook:
mam_stripe_approved_vendors - Hooks: Stripe security filters
Metadata
| Field | Value |
|---|---|
| Article type | Plugin Overview |
| Plugin slug | mam-stripe-manager |
| Applies to plugin version | 26.19.1+ |
| Category | Plugin Reference |
| Depends on | MAM Main, MAM WooCommerce, WooCommerce |
| Works with | MAM WooCommerce Product Vendors (tips, cancellations, commission payouts), WooCommerce Product Vendors, MAM for Gravity Forms (vendor enrollment form), MAM Notification system (enrollment + transfer emails), MAM RFQ Manager for Product Vendors, MAM WooCommerce Ride Share |
| Hooks exposed | mam_pmt_charge_card, mam_pmt_refund_card, mam_stripe_connect_transfer, mam_stripe_get_stripe_info, mam_stripe_approved_vendors, mam_pmt_charge_amount_tolerance, mam_stripe_can_refresh_connect, mam_stripe_allowed_redirect, mam_stripe_transfer_vendor_on_order, mam_stripe_user_can_manage, mam_stripe_connect_account_country, mam_stripe_merchant_name |
| Shortcode | [mam_stripe_connect_return] |
| REST route | POST /wp-json/mam-stripe/v1/webhook |
| Last verified | 2026-06-10 |
