Issue reported by customer: marketing_at_am*(902.900)
Add locations & generate embed.
In the resulting locations the Directions link is wrong.
Store Locator Plus® Internal Docs
SLP Internal Documentation
Issue reported by customer: marketing_at_am*(902.900)
Add locations & generate embed.
In the resulting locations the Directions link is wrong.
GitHub Project Issue: New Manage Customers : Location Count Wrong
Follow on to this task: Sysadmin : Manage Customers UX Improvement
The list of customers shows locations 0 for multiple customers with locations.
File: WordPress/wp-content/plugins/myslp-dashboard/src/manage_customers/manage_customers.tsx
DataGridPro (from MUIx framework) properties…
— Data set
Most likely from
React.useEffect( () => {
fetchData();
}, [ fetchData ] );
Calls REST endpoint from
const restBase: string = slpReact.url.rest + 'myslp/v2/customers';
— Column definitions
const columns = React.useMemo( () => buildColumns( homeUrl, isMonthEnd ), [ homeUrl, isMonthEnd ] );
homeUrl most likely comes from the PHP class \MySLP_Manage_Customers::extendReactVars
set to WordPress get_home_url()
SaaS App backend via MySLP Dashboard plugin.
— Fetching Customers
PHP method \MySLP_REST_API::register_routes defines the registered routes for WordPress.
register_rest_route( $this->myslp_namespace, ‘/customers’,…)
Calls the PHP method \MySLP_REST_API::get_customers
Location count is coming from $this->myslp->User->location_count
This appears to be using a meta_query to fetch the user location data.
This is NOT accurate.
In some cases the MySLP_User object does not have a location_count user_meta property set.
If that is the case, it should call \SLP_Location_Manager::get_location_count for that user and store the result with
Fetched from user_meta with the location_count property.
This is likely where the AI decided to make this a source of truth for location counts.
case 'location_count':
case 'mapview_count':
$this->__get( 'user_meta' );
$this->$property = (int) ( $this->user_meta[ $property ][0] ?? 0 );
break;
Currently unused anywhere in the project.
This would ensure the app switched to the user’s blog and set_database_meta() then called:
\SLP_Location_Manager::get_location_count
This is the original method from the legacy app code to fetch location counts.
It queries the custom SLP database that is added for every user to get the count of records.
It comes from the linchpin Store Locator Plus base plugin.
$the_count = $this->slplus->database->get_Value( array(
'selectall_count',
'where_default'
) );
Update \MySLP_REST_API::get_customers must first call…
// Update count and user meta storing count.
$this->get_location_count_for_user( $user->ID );
This updates the myslp->User->location_count meta by querying the SLP custom table directly.
See myslp-dashboard git repo update SHA 4f54ff1154d0cf148c603000bdcd789a669ed8cc
Theme “twenty twelve does not exist” ranger creek categories
Sadly, some of the accounts like “ranger_creek” are not longer available and are not able to show the issue. It is difficult finding which accounts reproduce the errors and where.
I had to update the stripe connection which meant rewriting how subscription processing is managed including cancellations.
So for the customer mcampbell_at_tnwebtech_dot_com (830.828) this is what I have as the status:
original subscription 24th
last renewed feb 24th
cancelled mar 6th
stripe charged them mar 6th AND marked it cancelled april 6th
it should have marked the 24th subscription to cancel on mar 24th
Clearly a bug in the new cancellation processor.
Task: https://github.com/Store-Locator-Plus/myslp_aws_ecs_kit/issues/94
customer: mcampbell@tnwebtech.com
Current status according to Stripe: they have set their account to cancel on April 5th
Current subscription: *z8ku is deleted on Stripe now meaning it will not auto-renew
Please ensure that is what they want.
From the Stripe history:
The original subscription *9h4z
Started Oct 24 2023
Cancelled via SLP Dashboard on Mar 6th 2026 at 1:05AM (server time)
Was set to stop providing SLP maps on Mar 24th 2026
They then renewed (created the new subscription) Mar 6th at 1:08AM (server time)
This is set to expire on April 5th 2026
Yes, we have an issue with RENEW
If the prior subscription is still active (*9h4z in this case) it should set the new subscription (renewal) to start when that ends (Mar 24th 2026 06:21AM server time)
The bug is that is started immediately , thus the new 6th to 5th dates
That is OK for renewals that happen AFTER the maps are disabled (most users) but in this unique situation it needs to be addressed.
Started and cancelled March 6th 2026
Mar 6, 2026, 1:08:53 AM EDT POST/v1/subscriptions
{
"id": "sub_1T7rZBBvHKfBw2LGODU6z8ku",
"object": "subscription",
...
"cancel_at": null,
"cancel_at_period_end": false,
"canceled_at": null,
"cancellation_details": {
"comment": null,
"feedback": null,
"reason": null,
},
"collection_method": "charge_automatically",
"created": 1772777333,
"currency": "usd",
"current_period_end": 1775455733, // April 5 2026 06:22:13
"current_period_start": 1772777333,
"customer": "cus_OsOnxeaYjgqPNu",
...
"items": {
"object": "list",
"data": [
{
"id": "si_U63gr60piiTUmH",
"object": "subscription_item",
"billing_thresholds": null,
"created": 1772777334,
"current_period_end": 1775455733,
"current_period_start": 1772777333,
"discounts": [],
"metadata": {},
"plan": {
"id": "Professional",
"object": "plan",
"active": true,
"aggregate_usage": null,
"amount": 3500,
"amount_decimal": "3500",
"billing_scheme": "per_unit",
"created": 1500935159,
"currency": "usd",
"interval": "month",
"interval_count": 1,
"livemode": true,
"metadata": {},
"meter": null,
"nickname": null,
"product": "prod_BU6KhAFcwnXTef",
"tiers_mode": null,
"transform_usage": null,
"trial_period_days": null,
"usage_type": "licensed"
},
"price": {
"id": "Professional",
"object": "price",
"active": true,
"billing_scheme": "per_unit",
"created": 1500935159,
"currency": "usd",
"custom_unit_amount": null,
"livemode": true,
"lookup_key": null,
"metadata": {},
"nickname": null,
"product": "prod_BU6KhAFcwnXTef",
"recurring": {
"aggregate_usage": null,
"interval": "month",
"interval_count": 1,
"meter": null,
"trial_period_days": null,
"usage_type": "licensed"
},
"tax_behavior": "unspecified",
"tiers_mode": null,
"transform_quantity": null,
"type": "recurring",
"unit_amount": 3500,
"unit_amount_decimal": "3500"
},
"quantity": 1,
"subscription": "sub_1T7rZBBvHKfBw2LGODU6z8ku",
"tax_rates": []
}
],
...
},
...
"trial_settings": {
"end_behavior": {
"missing_payment_method": "create_invoice"
}
},
"trial_start": null
}
Mar 6, 2026, 1:09:11 AM EDT POST /v1/subscriptions/sub_1T7rZBBvHKfBw2LGODU6z8ku
{
"id": "sub_1T7rZBBvHKfBw2LGODU6z8ku",
"object": "subscription",
...
"cancel_at": 1775455733,
"cancel_at_period_end": true,
"canceled_at": 1772777351,
"cancellation_details": {
"comment": null,
"feedback": null,
"reason": "cancellation_requested"
},
"collection_method": "charge_automatically",
"created": 1772777333,
"currency": "usd",
"current_period_end": 1775455733,
"current_period_start": 1772777333,
"customer": "cus_OsOnxeaYjgqPNu",
...
}
Mar 6, 2026, 1:09:12 AM EDT DELETE/v1/subscriptions/sub_1T7rZBBvHKfBw2LGODU6z8ku

Started: 2023-10-24
Ended: 2026-03-06 01:05AM
Mar 6, 2026, 1:05:04 AM EDT POST/v1/subscriptions/sub_1O4dzSBvHKfBw2LGsKZp9h4z
{
"id": "sub_1O4dzSBvHKfBw2LGsKZp9h4z",
"object": "subscription",
"application": null,
"application_fee_percent": null,
"automatic_tax": {
"disabled_reason": null,
"enabled": false,
"liability": null
},
"billing_cycle_anchor": 1698128482,
"billing_cycle_anchor_config": null,
"billing_mode": {
"flexible": null,
"type": "classic"
},
"billing_thresholds": null,
"cancel_at": 1774333282, // Mar 24 2026 06:21:22 AM (correct)
"cancel_at_period_end": true,
"canceled_at": 1772777104, // Mar 6 2026 01:05:04 AM
"cancellation_details": {
"comment": null,
"feedback": null,
"reason": "cancellation_requested"
},
"collection_method": "charge_automatically",
"created": 1698128482,
"currency": "usd",
"current_period_end": 1774333282, // Mar 24 2026 06:21:22 AM (correct)
"current_period_start": 1771914082, // February 23 2026 11:21:22 PM
"customer": "cus_OsOnxeaYjgqPNu",
"customer_account": null,
"days_until_due": null,
"default_payment_method": null,
"default_source": null,
"default_tax_rates": [],
"description": null,
"discount": null,
"discounts": [],
"ended_at": null,
"invoice_settings": {
"account_tax_ids": null,
"issuer": {
"type": "self"
}
},
"items": {
"object": "list",
"data": [
{
"id": "si_OsOnhVkp9iBCCb",
"object": "subscription_item",
"billing_thresholds": null,
"created": 1698128483,
"current_period_end": 1774333282,
"current_period_start": 1771914082,
"discounts": [],
"metadata": {},
"plan": {
"id": "Professional",
"object": "plan",
"active": true,
"aggregate_usage": null,
"amount": 3500,
"amount_decimal": "3500",
"billing_scheme": "per_unit",
"created": 1500935159,
"currency": "usd",
"interval": "month",
"interval_count": 1,
"livemode": true,
"metadata": {},
"meter": null,
"nickname": null,
"product": "prod_BU6KhAFcwnXTef",
"tiers_mode": null,
"transform_usage": null,
"trial_period_days": null,
"usage_type": "licensed"
},
"price": {
"id": "Professional",
"object": "price",
"active": true,
"billing_scheme": "per_unit",
"created": 1500935159,
"currency": "usd",
"custom_unit_amount": null,
"livemode": true,
"lookup_key": null,
"metadata": {},
"nickname": null,
"product": "prod_BU6KhAFcwnXTef",
"recurring": {
"aggregate_usage": null,
"interval": "month",
"interval_count": 1,
"meter": null,
"trial_period_days": null,
"usage_type": "licensed"
},
"tax_behavior": "unspecified",
"tiers_mode": null,
"transform_quantity": null,
"type": "recurring",
"unit_amount": 3500,
"unit_amount_decimal": "3500"
},
"quantity": 1,
"subscription": "sub_1O4dzSBvHKfBw2LGsKZp9h4z",
"tax_rates": []
}
],
"has_more": false,
"total_count": 1,
"url": "/v1/subscription_items?subscription=sub_1O4dzSBvHKfBw2LGsKZp9h4z"
},
"latest_invoice": "in_1T4EzzBvHKfBw2LGXjuYItOu",
"livemode": true,
"metadata": {},
"next_pending_invoice_item_invoice": null,
"on_behalf_of": null,
"pause_collection": null,
"payment_settings": {
"payment_method_options": null,
"payment_method_types": null,
"save_default_payment_method": null
},
"pending_invoice_item_interval": null,
"pending_setup_intent": null,
"pending_update": null,
"plan": {
"id": "Professional",
"object": "plan",
"active": true,
"aggregate_usage": null,
"amount": 3500,
"amount_decimal": "3500",
"billing_scheme": "per_unit",
"created": 1500935159,
"currency": "usd",
"interval": "month",
"interval_count": 1,
"livemode": true,
"metadata": {},
"meter": null,
"nickname": null,
"product": "prod_BU6KhAFcwnXTef",
"tiers_mode": null,
"transform_usage": null,
"trial_period_days": null,
"usage_type": "licensed"
},
"quantity": 1,
"schedule": null,
"start_date": 1698128482,
"status": "active",
"test_clock": null,
"transfer_data": null,
"trial_end": null,
"trial_settings": {
"end_behavior": {
"missing_payment_method": "create_invoice"
}
},
"trial_start": null
}
Mar 6, 2026, 1:05:05 AM EDT DELETE/v1/subscriptions/sub_1O4dzSBvHKfBw2LGsKZp9h4z
Currently on Professional Plan
Expires 2026-05-21 06:08:53
Cancelled 2026-03-06 06:09:11
Current Stripe subscription: sub_1T7rZBBvHKfBw2LGODU6z8ku

Currently using Classic billing mode.
Flexible Recommended: Provides accurate and predictable billing behavior and new capabilities. To access these improvements, which are only available in flexible billing mode, you must create new subscriptions with flexible billing mode or migrate your existing subscriptions.
*Classic: Uses the existing Stripe subscription behavior. This setting is maintained for backward compatibility with older integrations.
@Amelia -
In the MySLP Payments module (WordPress/wp-content/plugins/myslp-payments) there is an issue related to renewing cancelled subscriptions.
__
Make a note of this as general knowledge about the Store Locator Plus Saas Application:
- local (https://local.storelocatorplus.com) and staging (https://staging.storelocatorplus.com) servers may be using outdated data sets
- local and staging servers employ the Stripe TEST environment and related keys
- the production server uses live keys
- NEVER run tests against live Stripe customer data using live keys even on the staging or local servers
__
The following scenario is a real-world situation which played out on the production version of the SaaS application.
We have an issue with RENEW subscription.
- If the prior subscription is still active (sub_1O4dzSBvHKfBw2LGsKZp9h4z in this case) it should set the new subscription (sub_1T7rZBBvHKfBw2LGODU6z8ku) to start when the still-active subscription ends (Mar 24th 2026 06:21AM server time).
- The bug is that the new subscription started immediately setting a March 6th start date when an April 5th end date.
- The new subscription should have started on March 24th 2026 at 6:21AM.
- If the prior subscription is past the end (cancel_at) date, only then should the renewal start immediately. That was not the case in this situation.
Meta data about the customer and their interaction with the application:
customer: mcampbell@tnwebtech.com
Current status according to Stripe: they have set their account to cancel on April 5th
Current subscription: *z8ku is deleted on Stripe now meaning it will not auto-renew
Please ensure that is what they want.
From the Stripe history:
The original subscription *9h4z
Started Oct 24 2023
Cancelled via SLP Dashboard on Mar 6th 2026 at 1:05AM (server time)
Was set to stop providing SLP maps on Mar 24th 2026
They then renewed (created the new subscription) Mar 6th at 1:08AM (server time)
This is set to expire on April 5th 2026
in \stripe\MySLP_Stripe_Payments::renew_subscription add the trial_end argument.
// If the old subscription still has remaining paid time, defer the new
// subscription so it starts when the old period ends.
$prior_period_end = $this->subscription->current_period_end ?? null;
if ( $prior_period_end && $prior_period_end > time() ) {
$args['trial_end'] = $prior_period_end;
}
try {
$this->subscription = Subscription::create( $args );
Write a new E2E Test Specification "subscription_renewals".
The first test in the specification needs to test "Can renew a subscription before it has expired".
This is a corner case with some specific requirements.
- Login as a user with a current active subscription
- Go to My Profile and look for the current subscription ID, remember this value
- Go to My Profile and cancel the subscription
-- The current Stripe subscription ID should be posted and marked in Stripe as canceled
-- The current subscription should have a cancellation date at the end of the current period
- Go to My Profile and renew the subscription
-- This should create a new Stripe subscription ID
-- The new Stripe subscription ID should start when the current period ends
-- The new Stripe subscription should NOT start at the date/time of the renewal
-- The new Stripe subscription should be set to renew in a month (current period ends a month later)
Under Settings | Map the map center fallback is not rendering the map.

Settings ID: center_map
This is a Premier feature.
May be related to Google Maps and SLP Core script enqueue
Went to locator styles: default and selected it to get the baseline form the style server first.
The map bubble description format is not retaining whitespace (returns) with the default style.


The main locator page with the [slplus] shortcode generates the same message:
“Store Locator Plus® did not initialize properly.”
This issue is specific to the WordPress plugin stack and does not affect SaaS installations.
Widget areas are special places on a classic theme that can accept blocks — typically areas like your sidebar or footer. This guide will explain how to use widgets on your website.
Sites using modern block themes do not use widgets, so you won’t find Appearance → Widgets in your dashboard.
Without a theme that supports widgets, the only place you’ll get Appearance -> Widgets support is with the Power add on for the Store Pages “no store page” template. The “no store page” template has not been updated to use blocks instead of widgets.
Notice: Function WP_Scripts::add was called incorrectly. The script with the handle “google_maps” was enqueued with dependencies that are not registered: slp_core. Please see Debugging in WordPressfor more information. (This message was added in version 6.9.1.) in /var/www/html/wp-includes/functions.php on line 6131
\SLPlus::enqueue_google_maps_script calls enqueue scripts with slp_core as a dependency but it is missing when going to the Store Locator Plus | Locations page in the admin panel.
This is an issue with the updates to the My Profile interface from the 2602.01.01 version of the SLP SaaS platform.
Going to My Profile | Cancel Subscription is no longer working. It appears to post to the backend for processing, but there is not notification of cancellation and there is no update to the status.

When testing generate embed for “Freshy” the JS dev tools throws a warning:
[Log] (location.js, line 190)
Warning: foreach() argument must be of type array|object, null given in /var/www/html/wp-content/mu-plugins/store-locator-plus/include/module/ui/SLP_UI_Shortcode_slp_option.php on line 94
As per Foreach loop in SLP_UI_Shortcode_slp_option.php#69
Related to SLP Project issue: Cullgroup fatal error viewing dashboard (or logging in)#66
System log error.
[Tue Jan 20 16:44:46.077513 2026] [core:error] [pid 59] [client 127.0.0.1:47176] AH00124: Request exceeded the limit of 10 internal redirects due to probable configuration error. Use ‘LimitInternalRecursion’ to increase the limit if necessary. Use ‘LogLevel debug’ to get a backtrace.