Skip to content

fix: support PAL-based service URLs in _set_url_version (#474) - #511

Open
cobanfurkanx wants to merge 1 commit into
Adyen:mainfrom
cobanfurkanx:fix/pal-service-url-version-override
Open

cobanfurkanx wants to merge 1 commit into
Adyen:mainfrom
cobanfurkanx:fix/pal-service-url-version-override

Conversation

@cobanfurkanx

Copy link
Copy Markdown

Description

Fixes #474

AdyenClient._set_url_version previously used re.sub(r"\.com/v\d{1,2}", f".com/{new_version}", endpoint), which only matched endpoints where the version segment directly followed .com (such as Checkout and Management APIs).

As a result, PAL-based services where the version segment is located deeper in the path (e.g. /pal/servlet/Recurring/v68, /pal/servlet/Payment/v68, /pal/servlet/BinLookup/v54, /pal/servlet/Payout/v68) were never matched, causing version overrides (api_recurring_version, api_payment_version, etc.) to have no effect. Additionally, if only one service version override was configured on the client, other services without an override had their version corrupted to vNone.

Changes

  1. Path-agnostic version matching: Updated regex to r"/v\d+(?=/|$)" to match /v<version> anywhere in the path, supporting multi-digit versions without assuming a .com prefix.
  2. None guard: Added an early return if version is None: return endpoint to avoid touching endpoints for services that have no version override specified.
  3. Unit Tests: Added test coverage in test/DetermineEndpointTest.py covering PAL Recurring, PAL Payments, Checkout, None guard preservation, and multi-digit version overrides.

Tests

Ran the complete unit test suite:

  • 186/186 tests passing cleanly.

Update regex in AdyenClient._set_url_version to match version segments anywhere in the path (/v\d+(?=/|$)) instead of only immediately after .com. This allows version overrides on PAL-based services (Recurring, Payment, Payout, BinLookup) to take effect properly.

Also add a guard returning the unmodified endpoint when version is None to prevent overwriting unrelated service URLs.

Fixes Adyen#474
@cobanfurkanx
cobanfurkanx requested a review from a team as a code owner October 6, 2026 10:44
@sonarqubecloud

sonarqubecloud Bot commented Oct 6, 2026

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request updates the _set_url_version method in Adyen/client.py to safely handle missing service versions and support multi-digit version numbers using an updated regular expression. It also adds corresponding unit tests in test/DetermineEndpointTest.py. Feedback highlights a potential bug where the service name 'Payout' does not match the 'payouts' key in version_lookup, causing overrides to be ignored, and suggests using self.addCleanup in tests to prevent state pollution.

Comment thread Adyen/client.py
Comment on lines +325 to +327
version = version_lookup.get(service)
if version is None:
return endpoint

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

There is a mismatch between the service name used for the Payout service and the key defined in version_lookup. In _set_credentials (lines 250 and 270), the service name is checked as "Payout" (capitalized, singular). However, in version_lookup (line 312), the key is defined as "payouts" (lowercase, plural).

As a result, version_lookup.get("Payout") will return None, and any version override configured via api_payout_version will be silently ignored for the Payout service.

To fix this, we can fall back to checking "payouts" if the service is "Payout" and not found directly in version_lookup.

Suggested change
version = version_lookup.get(service)
if version is None:
return endpoint
version = version_lookup.get(service)
if version is None and service == "Payout":
version = version_lookup.get("payouts")
if version is None:
return endpoint

Comment on lines +190 to +195
def test_set_url_version_pal_recurring(self):
self.client.api_recurring_version = "70"
url = self.client._set_url_version("recurring", self.recurring_url + RECURRING_DETAILS)
expected = self.recurring_url.replace(f"/{self.recurring_version}", "/v70") + RECURRING_DETAILS
self.assertEqual(url, expected)
self.client.api_recurring_version = None

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

Modifying shared state (like self.client) inside test methods without guaranteed cleanup can lead to test pollution and flaky tests if an assertion fails before the cleanup line is reached.

Using self.addCleanup ensures that the cleanup is always executed, even if the test fails or raises an exception. This pattern should also be applied to the other new test cases (test_set_url_version_pal_payment, test_set_url_version_checkout, and test_set_url_version_multi_digit).

Suggested change
def test_set_url_version_pal_recurring(self):
self.client.api_recurring_version = "70"
url = self.client._set_url_version("recurring", self.recurring_url + RECURRING_DETAILS)
expected = self.recurring_url.replace(f"/{self.recurring_version}", "/v70") + RECURRING_DETAILS
self.assertEqual(url, expected)
self.client.api_recurring_version = None
def test_set_url_version_pal_recurring(self):
self.client.api_recurring_version = "70"
self.addCleanup(setattr, self.client, "api_recurring_version", None)
url = self.client._set_url_version("recurring", self.recurring_url + RECURRING_DETAILS)
expected = self.recurring_url.replace(f"/{self.recurring_version}", "/v70") + RECURRING_DETAILS
self.assertEqual(url, expected)

This branch has not been deployed

No deployments
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.

[Bug] api_*_version override has no effect on PAL-based service URLs

1 participant