From 09b70c9f4c91a06a991b539670cb89266438e392 Mon Sep 17 00:00:00 2001 From: "gocardless-ci-robot[bot]" <123969075+gocardless-ci-robot[bot]@users.noreply.github.com> Date: Tue, 6 Oct 2026 07:47:33 +0000 Subject: [PATCH] Changes generated by af3f0621c63af36f6bbccc4d487405d54a43eb13 This commit was automatically created from gocardless/client-library-templates@af3f0621c63af36f6bbccc4d487405d54a43eb13 by the `push-files` action. Workflow run: https://github.com/gocardless/client-library-templates/actions/runs/37431555305 --- CHANGELOG.md | 17 +++++++++++++++++ gocardless_pro/__init__.py | 2 +- gocardless_pro/api_client.py | 4 ++-- setup.py | 2 +- 4 files changed, 21 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e12012aa..16db4ae8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,23 @@ # Changelog +## 3.18.1 (2026-10-06) + +### Fixes + +#### Stop the generated idempotency key persisting in caller-owned state + +The generated `Idempotency-Key` was written into state owned by the caller: the +headers dictionary in Python, and the request object in .NET. An application that +reused either across independent create calls — a module-level custom-header +template, or one request object in a loop — sent the first call's key every time. +The API answers each repeat with `409 idempotent_creation_conflict`, which these +clients resolve by default by returning the resource the first call created, so +later creates returned the wrong resource with no error. + +The key is now generated per call without touching the caller's own objects, and +remains stable across network retries of the same call. + ## 3.18.0 (2026-10-06) ### Features diff --git a/gocardless_pro/__init__.py b/gocardless_pro/__init__.py index 14883fab..b6e69b3e 100644 --- a/gocardless_pro/__init__.py +++ b/gocardless_pro/__init__.py @@ -2,5 +2,5 @@ from .client import Client -__version__ = '3.18.0' +__version__ = '3.18.1' diff --git a/gocardless_pro/api_client.py b/gocardless_pro/api_client.py index 3227757f..db27f1ae 100644 --- a/gocardless_pro/api_client.py +++ b/gocardless_pro/api_client.py @@ -192,7 +192,7 @@ def _default_headers(self): 'Authorization': 'Bearer {0}'.format(self.access_token), 'Content-Type': 'application/json', 'GoCardless-Client-Library': 'gocardless-pro-python', - 'GoCardless-Client-Version': '3.18.0', + 'GoCardless-Client-Version': '3.18.1', 'User-Agent': self._user_agent(), 'GoCardless-Version': '2015-07-06', } @@ -201,7 +201,7 @@ def _user_agent(self): python_version = '.'.join(platform.python_version_tuple()[0:2]) vm_version = '{}.{}.{}-{}{}'.format(*sys.version_info) return ' '.join([ - 'gocardless-pro-python/3.18.0', + 'gocardless-pro-python/3.18.1', 'python/{0}'.format(python_version), '{0}/{1}'.format(platform.python_implementation(), vm_version), '{0}/{1}'.format(platform.system(), platform.release()), diff --git a/setup.py b/setup.py index 269bee93..8756ec96 100644 --- a/setup.py +++ b/setup.py @@ -6,7 +6,7 @@ setup( name = 'gocardless_pro', - version = '3.18.0', + version = '3.18.1', packages = find_packages(exclude=['tests']), install_requires = ['requests>=2.34.2'], python_requires = '>=3.6',