Repository navigation
fix(payments): align retry types with spec, deprecate top fields - #260
Conversation
…fter_days The retry object of POST /payments has no max_attempts or end_after_days; they belong to dunning. Payment sessions now share CustomerRetry from common (the old import path still works). Retry and customer retry fields are documented.
🔴 Risk Classification: MAJORApproval route: AI Review + Human Approval Required Classification reasons
Operational gates
Files analysed: 4 wall-e 2026.06.19-02 · policy |
🔬 Debug — why this classification?Each reason code emitted by the classifier, its source clause in the AI in SDLC Control Framework, and what it means.
Kinds:
See issue #3 for the proposal to formalise this map as Appendix A of the standards doc. wall-e 2026.06.19-02 · debug |
🟢 Advisory review: Looks good to meThis PR still needs a human approval — wall-e cannot auto-approve it. For what it's worth, I read the diff and found nothing I'd block on. Deprecates top-level What I checked
This is not an approval. wall-e cannot auto-approve this PR — it is an opinion to help whoever does. Advisory review · us.anthropic.claude-sonnet-4-6 · wall-e 2026.06.19-02 |
🔴 Risk Classification: MAJORApproval route: AI Review + Human Approval Required Classification reasons
Operational gates
Files analysed: 4 wall-e 2026.06.19-02 · policy |
🔬 Debug — why this classification?Each reason code emitted by the classifier, its source clause in the AI in SDLC Control Framework, and what it means.
Kinds:
See issue #3 for the proposal to formalise this map as Appendix A of the standards doc. wall-e 2026.06.19-02 · debug |
|
This release brings Payment Setups in line with the API specification, adds card payouts to card, token and network token destinations, and adds unreferenced refunds. It also documents the payment retry types and deprecates the members the API does not accept, each with its replacement where one exists. Nothing is removed: every deprecated member keeps working until the next major version. **Added** Payment Setups (#258) - `PaymentSetupPaymentType` enum with the lowercase values the Payment Setups API accepts: `regular`, `recurring`, `moto`, `installment`, `pay_later`, `unscheduled`. - `Klarna.action` (`KlarnaAction`, with `type` (`KlarnaActionType.SDK`), `client_token` and `session_id`) and `Klarna.iban`. Both are response only. - `Stcpay.action` (`StcpayAction`, with `type` (`StcpayActionType.OTP`)). Response only. - `Tamara.initialization` (`PaymentMethodInitialization`, default `disabled`) and `Tamara.risk_assessment` (`TamaraRiskAssessment`, with `premium_customer`, `risk_score`, `order_count_last24h` and `linked_device_count`). Payouts and unreferenced refunds (#261) - `PaymentsClient.request_unreferenced_refund(unreferenced_refund_request, idempotency_key=None)` and `UnreferencedRefundRequest`, sent to `POST /payments`. The constructor sets `payment_type` to `UnreferencedRefund`. - Card payout and unreferenced refund destinations: `PaymentRequestCardDestination` (type `card`), `PaymentRequestNetworkTokenDestination` (type `network_token`) and `PaymentRequestTokenDestination` (type `token`). `PaymentRequestIdDestination` (type `id`) already existed. - `PaymentDestinationType.NETWORK_TOKEN`. - `NetworkTokenType` enum: `vts`, `mdes`, `applepay`, `googlepay`. - `CardPayoutProcessing` (`affiliate_id`, `affiliate_url`, `processing_speed`, `purchase_country`), used by `PayoutRequest.processing` and `UnreferencedRefundRequest.processing`. - `CardPayoutItem` (`type`, `sub_type`), the item type of `PayoutRequest.items`. **Changed** Payment Setups (#258) - `Tamara()` now sends `"initialization": "disabled"` when you do not set it; before, it sent no `initialization` at all. This matches the API's default on create and the other payment methods that already carried this default (Klarna, stc pay, Tabby, Bizum, Blik). Set `initialization` to `PaymentMethodInitialization.ENABLED` to enable Tamara. - `PaymentSetupsRequest.payment_type` is typed `PaymentSetupPaymentType` instead of `PaymentType`. Values from `PaymentType` are capitalized (for example `PayLater`), which the Payment Setups API rejects; use `PaymentSetupPaymentType` instead. - `PaymentSetupTerminal.local_date_time` is typed `datetime` instead of `str`. Pass a timezone aware `datetime` so the offset is sent; microseconds are not sent. A string still serializes as before. - `MerchantAccount.last_payment_amount` is typed `float` instead of `int`, as in the specification. - Docs: on update the API replaces the payment methods, so send `initialization` as `enabled` again to keep a method enabled. `Ideal.description`, `Knet.language` and `Bancontact.account_holder_name` are optional in the specification, but the API keeps the method invalid until they are sent. Payouts and unreferenced refunds (#261) - `PayoutRequest.processing` is typed `CardPayoutProcessing` instead of `ProcessingSettings`, and `PayoutRequest.items` holds `CardPayoutItem` instead of `Product`. - `PaymentRequestNetworkTokenSource.token_type` is typed `NetworkTokenType` instead of `str`. Plain strings still serialize as before. Payments (#260) - `checkout_sdk.payments.sessions.sessions` now uses `CustomerRetry` from `checkout_sdk.common.common`. The import from the sessions module still works. - `PaymentRetryRequest`, `DowntimeRetryRequest`, `DunningRetryRequest` and `CustomerRetry` are documented with their ranges and defaults. **Fixed** - Card payout items: use `CardPayoutItem`. Unlike `Product`, it does not send `"type": null` and `"sub_type": null` when they are not set (#261). **Deprecated** All of these are removed in the next major version. Payment Setups (#258) - `PaymentType` imported from `checkout_sdk.payments.setups.setups`: use `PaymentSetupPaymentType`. - `Klarna.payment_method_options`: use `Klarna.action`. - `Stcpay.payment_method_options`: use `Stcpay.action`. - `Tabby.payment_method_options`: no replacement. - `Bizum.payment_method_options`: no replacement. - `PaymentMethodOptions` and `PaymentMethodOption`: use `action` on Klarna and stc pay; no replacement for the other methods. - `PaymentMethodAction.client_token`: for Klarna use `Klarna.action.client_token`; no replacement for PayPal and instrument. - `PaymentMethodAction.session_id`: for Klarna use `Klarna.action.session_id`; no replacement for PayPal and instrument. - `Bizum.initialization`: no replacement. - `Blik.initialization`: no replacement. - `PaymentSetupInstrument.phone`: no replacement (the API ignores it). - `PaymentSetupInstrument.account_holder`: no replacement (the API ignores it). - `PaymentSetupInstrument.allow_update`: no replacement (the API ignores it). Payouts and unreferenced refunds (#261) - `AccountHolder.full_name`: no replacement. - `AccountHolder.gender`: no replacement. - `InstructionScheme.SWIFT`: no replacement (the request accepts only `local` and `instant`). - `PaymentInstruction.charge_bearer`: no replacement. - `PaymentInstruction.repair`: no replacement. - `PaymentInstruction.quote_id`: no replacement. - `PaymentBankAccountDestination.bank`: no replacement. Payments (#260) - `PaymentRetryRequest.max_attempts`: use `PaymentRetryRequest.dunning.max_attempts`. - `PaymentRetryRequest.end_after_days`: use `PaymentRetryRequest.dunning.end_after_days`. **Breaking changes required by the API**⚠️ None. **Breaking changes (SDK alignment)**⚠️ None.



Summary
Aligns the payment retry request types with the API.
CustomerRetryis now one shared type used by hosted payments, payment links and payment sessions, and the top-levelmax_attemptsandend_after_daysofPaymentRetryRequestare deprecated in favour ofdunning.Changes
checkout_sdk/common/common.py:CustomerRetry(max_attempts, 0 to 5, default 5) now lives here and is documented from the spec.checkout_sdk/payments/sessions/sessions.py: the duplicateCustomerRetryis removed; the module imports the shared one, sopayment_sessions.CustomerRetrykeeps working.checkout_sdk/payments/payments.py:PaymentRetryRequest,DunningRetryRequestandDowntimeRetryRequestdocumented from the spec (required, ranges, defaults). Top-levelmax_attemptsandend_after_daysmarked# Deprecated:; usedunning.max_attemptsanddunning.end_after_days. They still serialize when set and will be removed in the next major version.tests/payments/retry_request_serialization_test.py: every property,enabled=False,max_attempts=0, deprecated fields only when set,PaymentRetryRequestroundtrip with nestedDunningRetryRequestandDowntimeRetryRequest, andCustomerRetryon the three endpoints plus its roundtrip.API Reference
POST /payments(retry): https://api-reference.checkout.com/tag/payments/POST/payments.body.retryPOST /hosted-payments(customer_retry): https://api-reference.checkout.com/tag/hosted-payments-page/POST/hosted-payments.body.customer_retryPOST /payment-links(customer_retry): https://api-reference.checkout.com/tag/payment-links/POST/payment-links.body.customer_retryPOST /payment-sessions(customer_retry): https://api-reference.checkout.com/tag/flow/POST/payment-sessions.body.customer_retryBreaking changes
None. The deprecated fields still serialize when set.
README
Not affected: the README does not document these types.