Skip to content

[LIS-109] PrestaShop Plugin Migration to integration-core - #71

Draft
kristinalogeecom wants to merge 13 commits into
masterfrom
LIS-109
Draft

kristinalogeecom wants to merge 13 commits into
masterfrom
LIS-109

Conversation

@kristinalogeecom

@kristinalogeecom kristinalogeecom commented Sep 16, 2026

Copy link
Copy Markdown
Collaborator

What is the goal?

Extend integration-core with the functionality required by the new integration flow and Admin UI.

The changes support:

  • Merchant Portal integration during onboarding and connection.
  • General Settings and configuration managed through the Merchant Portal.
  • Solicitation validation based on selling countries and General Settings.
  • Order management through the Admin API.
  • Additional widget settings validation.
  • Configuration and webhook changes required by the new integrations.

References

How is it being implemented?

Onboarding and connection

  • Added portalUrl to onboarding and connection responses so integrations can redirect merchants to the Merchant Portal.
  • Added portal URL resolution based on the store deployment.
  • Updated the connection flow to return only deployments that were actually connected and leave deployments without credentials untouched.
  • Added country configuration status handling for the Admin UI.
  • Added warning logging when configured selling countries are excluded because they are not available for the merchant.

Plugin configuration

  • Added orderIdentifier to General Settings.
  • Added an optional OrderIdentifiersProviderInterface so integrations can provide the order identifiers available on their platform.
  • Extended General Settings responses with selling countries, statistical data settings and available order identifiers.
  • Added support for saving the statistical data setting without changing the existing value when the field is omitted.

Solicitation

  • Introduced SolicitationRequest for the solicitation flow.

  • Added core-level validation for:

    • selling country configuration;
    • IP allowlists;
    • product exclusions;
    • category exclusions.
  • Validation is performed before making the solicitation request.

  • Ineligible carts return an empty successful solicitation response instead of an error.

  • Added a non-throwing country-to-merchant lookup for solicitation validation.

Order management

  • Added AdminAPI::orderManagement($storeId)->updateOrder().
  • The new API allows integrations to synchronize order changes, including delivery and invoice addresses and shipped/unshipped state.
  • Optional values are only updated when provided.

Widget settings and webhooks

  • Added validation for widget selectors, duplicate payment method configuration and widget styles.
  • Added dedicated exceptions for invalid widget settings.
  • Unknown webhook states now return 501 Not Implemented instead of 400.

Opportunistic refactorings

  • Added HTTP log masking for sensitive headers such as Authorization, Proxy-Authorization, Cookie and Set-Cookie.
  • Fixed selling country arrays being serialized as JSON objects when countries are removed from the configuration.
  • Improved facade typing so IDEs and PHPStan can resolve the concrete controllers returned by the API facades.

Caveats

  • CheckoutAPI::solicitation()->solicitFor() now accepts a SolicitationRequest instead of a CreateOrderRequestBuilder. This is a breaking change for existing consumers and requires integrations to update their solicitation calls.
  • OrderIdentifiersProviderInterface is optional, so existing integrations remain compatible if they do not implement it.
  • No database migrations are required.

Does it affect (change or update) any sensitive data?

Yes, the change reduces sensitive data exposure.

HTTP logs now mask Authorization, Proxy-Authorization, Cookie and Set-Cookie headers. No new category of sensitive data is introduced or stored.

How is it tested?

Automatic tests are executed with PHPUnit in the PHP 7.2 container.

Coverage was added or extended for:

  • Connection and onboarding, including portal URL resolution and skipped deployments.
  • General Settings, order identifiers and configuration webhooks.
  • Solicitation validation and order creation.
  • Order management.
  • HTTP header masking.
  • Widget settings validation.
  • Webhook validation.

Quality gates:

  • ./bin/phpcs
  • ./bin/phpstan (level 6)

How is it going to be deployed?

Standard deployment.

This is a Composer library. Consumers need to update the dependency to use the new functionality.

kristinalogeecom and others added 13 commits August 24, 2026 09:24
getCountryConfiguration() unsets the configurations whose country is no
longer sold in, which leaves gaps in the keys. Every caller passes the
result straight on: array_map preserves keys, so a gapped array reaches
json_encode and is serialized as an object instead of a list. A store
configured for ES, IT, FR and PT that stopped selling in IT answered
{"0":"ES","2":"FR","3":"PT"} for sellingCountries.

It reaches the general settings and banner settings of both AdminAPI and
the configuration webhook, and the Express Checkout payload, all through
getCountryConfiguration() or getCountryCodes().

ISSUE: LIS-109
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

@AleksandarBoljanovic AleksandarBoljanovic left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code review: two findings, both inline, both around the new getPortalUrl / consent handling in the connection flow.

);
$connected = $this->connectionService->connect($onboardingData->getConnections());

if (!empty($connected)) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The statistical-data consent is now saved only when connect() returned at least one connection. ConnectionService::connect() continues past every connection without credentials, so an onboarding submit where the merchant only toggles the consent checkbox and leaves the credential fields blank returns a SuccessfulConnectionResponse while silently persisting no consent change.

If the intent is "do not record consent for a store that never connected", that is reasonable, but the response should then not read as a success. If consent is meant to be independent of the connect outcome, the save belongs outside the if.

return null;
}

$portalUrl = $this->getPortalBaseUrl(reset($connections));

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reset($connections) picks an arbitrary deployment. With several deployments connected - and possibly mixed live/sandbox environments, since getPortalBaseUrl() branches on isLive() - the portal link handed to the back office points at whichever connection happens to sit first in the array, not at the one the merchant just connected or is currently looking at.

Worth either selecting the connection deliberately (by deployment/environment) or documenting that the first one is authoritative here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants