| 开发者 | gsheetplugins |
|---|---|
| 更新时间 | 2026年9月7日 01:49 |
| PHP版本: | 7.4 及以上 |
| WordPress版本: | 7.1 |
| 版权: | GPL-2.0-or-later |
| 版权网址: | 版权信息 |
[gsma_user_info].[gsma_login_form] shortcode, instead of WordPress's default login screen.membership-google-sheets folder to /wp-content/plugins/ (or upload the ZIP under Plugins → Add New → Upload Plugin).name@project.iam.gserviceaccount.com) as an Editor (required for the Sales feature and the Pro add-on's Group Email; Viewer is enough if you only use page protection). The sheet stays private to everyone else.GOLD, PLATINUM)./d/ and /edit) |
| Sheet (Tab) Name | Optional. Leave blank to use the spreadsheet's first tab automatically. |
| Email Column | Column letter containing email addresses (default: A) |
| Membership Code Column | Column letter containing membership codes (default: B) |
| Header Row Number | Row number of the header; data starts on the next row (default: 1) |
| Cache Duration (seconds) | How long to cache the sheet data locally (default: 300). Set 0 to disable. |
| Warning Window (days) | Days before expiration to start showing members a renewal warning (default: 14) |
| Grace Period (days) | Days of continued access after expiration before it's revoked (default: 10) |
| Expired-Access Message | Message shown once a membership has expired and the grace period has passed |
| Login Redirect URL | Where to send unauthenticated visitors trying to access a restricted page |
| Access-Denied Redirect URL| Where to redirect logged-in users without the required membership |
| Access-Denied Message | Message to display instead of redirecting (if no redirect URL is set) |
| Access Control Match Mode | Exact match, or "letters mode," where the member's code must contain every letter in the required set |
| Custom Login Page | The WordPress page containing [gsma_login_form]; leave on Auto-detect to let the plugin find it, or fall back to WordPress's default login page |No — never. You only share it with the service account email address. It remains completely private to all other users.
The OpenSSL extension is needed to sign the JWT for authentication. It is enabled by default on virtually all shared and managed WordPress hosts (including WP Engine, Kinsta, SiteGround, Flywheel, and others).
No. Users with the manage_options capability always bypass all membership checks.
It is stored in your WordPress database (the wp_options table), protected by the same security as your WordPress installation. It is never sent to the browser or written to a file.
After the cache expires (default 5 minutes / 300 seconds). Reduce the cache duration in settings or click Clear Cache to force an immediate refresh.
The plugin logs an error and denies access as a safe default. Use Save & Test Main Roster in settings to verify connectivity.
This works for any member already on the roster, whether they got there through the plugin's own purchase pathway or not — a name typed in manually, imported from a spreadsheet, added after a mailed-in check, however your roster is maintained. The sign-in flow doesn't care how someone became a member, only that their email is on the sheet. It's part of the free plugin. There's no separate account-creation step. A member enters their email, and what happens next depends on whether they've signed in before:
With the GSheet Membership Pro add-on, you can connect a real mailbox (Google sign-in or an App Password) on the main settings page and send ALL plugin email — login verification codes, purchase confirmations, gift notices and group emails — from that account. Because mail truly originates from the mailbox, SPF/DKIM/DMARC align and messages stop landing in spam, with no separate SMTP plugin needed.
With the GSheet Membership Pro add-on, the Group Email page in Membership Access lets you compose a message and send it to your roster — everyone, or a subset filtered by membership code. Delivery runs through the site's own batched mailer, or optionally through a connected Mailchimp account (the audience is synced to your membership filter before every send). Chapter sites always send to their own local roster only. Every send gets individual per-member delivery, unsubscribe links, throttled background sending, and a per-recipient send log with retry/cancel. There are two ways to trigger a send: filling out the compose form yourself, or Email-in — forwarding a single email to a dedicated mailbox, covered next.
Email-in is the second way to send a Group Email: instead of the compose form, you forward a message to a dedicated mailbox (e.g. blast@example.org). The plugin checks that mailbox on a schedule (IMAP), and any message from an authorized sender is queued to the roster through the exact same engine as the compose form — same audience rules, same per-member delivery, unsubscribe links, and send log with retry/cancel.
imap.gmail.com, port 993, the mailbox address as username, and the App Password.The From: address of an email can be forged by anyone (spoofing) — an allowlist alone is not sufficient protection for something that can email your whole membership. The required subject keyword acts as a shared secret: only people who know it can trigger a send, even if they forge an authorized From: address. The keyword is stripped from the subject before delivery, so members never see it.
Meeting notes [codes: GOLD,SILVER]. The tag is removed before delivery. Without a tag, the membership code filter saved on the Group Email page is applied; if that filter is blank, all members receive the message. Works on both main and chapter sites.The Sales half of GSheet Membership puts a configurable buy-membership picker on any page and, on a successful payment, writes (or updates) the buyer's row in your private Google Sheet so they can immediately log in on your site.
[gsms_admin_picker] shortcode lets a site administrator apply a membership directly to the sheet without taking a payment, perfect for comp memberships, cheque / cash-in-hand orders, or back-filling an old purchase.openssl, hash, and mbstring extensions (already enabled on every major WordPress host).[gsma_membership_purchase] — that is the buy page.[gsma_user_info] on it (that shortcode shows the buyer's status with an inline login form when they're not yet signed in). Select that page on the Settings sub-page under Thank-you page.[gsma_login_form] — renders the sign-in form (email, then a first-time verification code or a returning password) on the page you choose as the Custom Login Page. Independent of the Sales feature — every site can use it.[gsma_membership_purchase] — renders the full picker (Delivery × Duration × Postage) with live total and the Buy membership button. Place this on the page where you want to take payments.[gsms_admin_picker] — admin-only variant of the picker that applies a membership directly to the sheet without any payment. Only site administrators (manage_options) see it; everyone else sees a polite notice.[gsma_user_info] — place it on the thank-you page so buyers see their membership status (and an inline login form when they aren't logged in).Stripe:
/wp-json/gsma-sales/v1/stripe-webhook).checkout.session.completed.whsec_...) and paste it into Webhook signing secret on the plugin's Payments page./wp-json/gsma-sales/v1/paypal-webhook).CHECKOUT.ORDER.APPROVED and PAYMENT.CAPTURE.COMPLETED.Almost everything in this plugin can be exercised before you ever sign up for Stripe or PayPal.
TEST).pk_test_... and sk_test_... keys, and save.stripe listen --forward-to https://yoursite.example/wp-json/gsma-sales/v1/stripe-webhook
The CLI prints a whsec_... signing secret — paste that into Webhook signing secret and save.
4. Visit the buy page, fill in any email/name, click Buy membership, and on the Stripe checkout page use the official test card:
paid from Stripe and inserted (or updated) for the sheet.The first delivery is processed normally. Any duplicate of the same event is identified and returns HTTP 200 with status: duplicate without writing to the sheet. Two concurrent deliveries for the same event are serialized via an atomic per-event lock; the loser receives HTTP 409 so the gateway retries it. From 1.7.13 each processed event is stored as its own wp_options row with a 72-hour TTL — there is no fixed-size eviction window that could cause old-but-recent events to fall off and be reprocessed.
The plugin returns HTTP 500 to the gateway (so it retries delivery automatically), records a "failed" entry on the Recent Purchases page, and shows a persistent admin notice until the next successful write. The buyer confirmation email is not sent for a failed write — only a successful upsert triggers it. You can manually rerun the upsert from the Recent Purchases page.
No. The gateway has captured the payment regardless of what happens on your site. The sheet write being deferred (and retried) means the buyer's membership row catches up automatically.
Yes. Renewals extend the existing expiration date forward, so an early renewal never shortens the buyer's coverage. A lifetime purchase clears the expiration cell entirely.
The cancelled checkout row is kept visible in Recent Purchases for auditing, but it never blocks a retry. If the gateway somehow delivers a capture event for an order the cancel handler already marked cancelled, the finalisation pipeline now detects and recovers that row automatically rather than treating it as already-done.
It depends on how you take card payments: