Repository navigation
feat(setups): add the setup payment type, confirm risk and tamara fields - #700
Conversation
payment_type used the payments PaymentType, which sends PayLater (rejected with 422) and cannot read the lowercase values the API returns. The confirm response gets risk, Tamara gets initialization and risk_assessment, and card_present is deprecated.
🟡 Risk Classification: MINORApproval route: AI Review + Human Approval Classification reasons
Operational gates
Files analysed: 19 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. This PR adds a dedicated 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 |
Adds round trip and spec example tests for every payment method without one, documents that the API stores last_payment_amount as an integer, and drops the initialization doc sentence the spec does not support.
🟡 Risk Classification: MINORApproval route: AI Review + Human Approval Classification reasons
Operational gates
Files analysed: 20 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 |
🟡 Risk Classification: MINORApproval route: AI Review + Human Approval Classification reasons
Operational gates
Files analysed: 20 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 |
MerchantAccount.lastPaymentAmount is a Double, the type the specification gives last_payment_amount, as in the other SDKs. card_present and its classes are restored as on master: the API still supports them.
🟡 Risk Classification: MINORApproval route: AI Review + Human Approval Classification reasons
Operational gates
Files analysed: 20 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 |
🟡 Risk Classification: MINORApproval route: AI Review + Human Approval Classification reasons
Operational gates
Files analysed: 23 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 |
🟡 Risk Classification: MINORApproval route: AI Review + Human Approval Classification reasons
Operational gates
Files analysed: 23 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 |
|
…suing This release adds the Payment Setup payment type, the risk settings on the Payment Setup confirm response and the Tamara risk assessment fields. It also adds the subscription details and the retry attempt count to payment responses, and lets you revoke and suspend Issuing cards without a request body. Customer retries on hosted payments and payment links now use the type the API accepts, and the update card headers the API no longer documents are deprecated. Every deprecated member keeps working and will be removed in the next major version. **Added** Issuing (#697) * `IssuingClient#revokeCard(String cardId)`, `#suspendCard(String cardId)`, `#revokeCardSync(String cardId)` and `#suspendCardSync(String cardId)`. The existing overloads that take a `RevokeCardRequest` or `SuspendCardRequest` now accept `null`, because the request body is optional in the API. Payment Setups (#700) * `PaymentSetupPaymentType` with the values of the Payment Setups API: `REGULAR` (`regular`), `RECURRING` (`recurring`), `MOTO` (`moto`), `INSTALLMENT` (`installment`), `PAY_LATER` (`pay_later`), `UNSCHEDULED` (`unscheduled`). * `PaymentSetupsConfirmResponse#risk` (`PaymentSetupRisk`). * `Tamara#initialization` (`PaymentMethodInitialization`, default `DISABLED`) and `Tamara#riskAssessment`, with the new `TamaraRiskAssessment` (`premiumCustomer`, `riskScore`, `orderCountLast24h`, `linkedDeviceCount`). Payments (#701) * `PaymentResponse#subscription` (`PaymentSubscription`). * `PaymentRetryResponse#attemptsMade`, returned by get payment details. **Changed** * `PaymentRetryRequest#enabled` is no longer deprecated. It is the required switch for asynchronous retries on payment requests (#701). * Request and response fields of payments, payment retries, hosted payments, payment links, payment sessions and Payment Setups now document whether they are required or optional, with the limits, defaults and enum values of the API reference (#700, #701). * Payment Setup payment methods document that an update replaces the payment methods, so `initialization` must be sent as `ENABLED` again to keep a method enabled (#700). **Fixed** * The `Retry` response of a payment request no longer reports `maxAttempts` as 6 when the API did not return it (#701). **Deprecated** All deprecated members keep working and will be removed in the next major version. * `CardUpdateHeaders` and the `IssuingClient#updateCard` and `#updateCardSync` overloads that take it: the API no longer documents the `return-encrypted-cvv` and `Encryption-Key` headers. Headers that are set are still sent. Use `updateCard(String, UpdateCardRequest)` or `updateCardSync(String, UpdateCardRequest)` (#697). * `HostedPaymentRequest#setCustomerRetry(PaymentRetryRequest)` and `HostedPaymentRequestBuilder#customerRetry(PaymentRetryRequest)`: customer retries only accept `max_attempts`, so only that value is kept. Use the `CustomerRetry` overloads (#701). * `PaymentLinkRequest#setCustomerRetry(PaymentRetryRequest)` and `PaymentLinkRequestBuilder#customerRetry(PaymentRetryRequest)`: same reason. Use the `CustomerRetry` overloads (#701). **Breaking changes required by the API**⚠️ * `PaymentSetupsRequest#paymentType`, `PaymentSetupsResponse#paymentType` and `PaymentSetupsConfirmResponse#paymentType` change from `com.checkout.payments.PaymentType` to `PaymentSetupPaymentType`. The Payment Setups API only accepts the lowercase values; the old type sent `PayLater`, which the API rejects with a 422, and read every value except `regular` as null. Migration: replace `PaymentType.X` with `PaymentSetupPaymentType.X` (#700). * `MerchantAccount#lastPaymentAmount` (Payment Setups customer) changes from `Long` to `Double`, because the API defines it as a number (for example `55.99`). Migration: pass a `Double` (for example `500d`) and read the getter as `Double` (#700). * `HostedPaymentRequest#customerRetry` and `PaymentLinkRequest#customerRetry` change from `PaymentRetryRequest` to `CustomerRetry`, because customer retries only accept `max_attempts` (0 to 5). Code that sets the field keeps compiling through the deprecated overloads; code that reads `getCustomerRetry()` now gets a `CustomerRetry`. Migration: `CustomerRetry.builder().maxAttempts(n).build()` (#701). **Dependencies** * gson 2.14.0, slf4j-api 2.0.18 and commons-codec 1.22.1, all still compatible with Java 8 (#702).
This release adds the Payment Setup payment type, the risk settings on the Payment Setup confirm response and the Tamara risk assessment fields. It also adds the subscription details and the retry attempt count to payment responses, and lets you revoke and suspend Issuing cards without a request body. Customer retries on hosted payments and payment links now use the type the API accepts, and the update card headers the API no longer documents are deprecated. Every deprecated member keeps working and will be removed in the next major version. **Added** Issuing (#697) * `IssuingClient#revokeCard(String cardId)`, `#suspendCard(String cardId)`, `#revokeCardSync(String cardId)` and `#suspendCardSync(String cardId)`. The existing overloads that take a `RevokeCardRequest` or `SuspendCardRequest` now accept `null`, because the request body is optional in the API. Payment Setups (#700) * `PaymentSetupPaymentType` with the values of the Payment Setups API: `REGULAR` (`regular`), `RECURRING` (`recurring`), `MOTO` (`moto`), `INSTALLMENT` (`installment`), `PAY_LATER` (`pay_later`), `UNSCHEDULED` (`unscheduled`). * `PaymentSetupsConfirmResponse#risk` (`PaymentSetupRisk`). * `Tamara#initialization` (`PaymentMethodInitialization`, default `DISABLED`) and `Tamara#riskAssessment`, with the new `TamaraRiskAssessment` (`premiumCustomer`, `riskScore`, `orderCountLast24h`, `linkedDeviceCount`). Payments (#701) * `PaymentResponse#subscription` (`PaymentSubscription`). * `PaymentRetryResponse#attemptsMade`, returned by get payment details. **Changed** * `PaymentRetryRequest#enabled` is no longer deprecated. It is the required switch for asynchronous retries on payment requests (#701). * Request and response fields of payments, payment retries, hosted payments, payment links, payment sessions and Payment Setups now document whether they are required or optional, with the limits, defaults and enum values of the API reference (#700, #701). * Payment Setup payment methods document that an update replaces the payment methods, so `initialization` must be sent as `ENABLED` again to keep a method enabled (#700). **Fixed** * The `Retry` response of a payment request no longer reports `maxAttempts` as 6 when the API did not return it (#701). **Deprecated** All deprecated members keep working and will be removed in the next major version. * `CardUpdateHeaders` and the `IssuingClient#updateCard` and `#updateCardSync` overloads that take it: the API no longer documents the `return-encrypted-cvv` and `Encryption-Key` headers. Headers that are set are still sent. Use `updateCard(String, UpdateCardRequest)` or `updateCardSync(String, UpdateCardRequest)` (#697). * `HostedPaymentRequest#setCustomerRetry(PaymentRetryRequest)` and `HostedPaymentRequestBuilder#customerRetry(PaymentRetryRequest)`: customer retries only accept `max_attempts`, so only that value is kept. Use the `CustomerRetry` overloads (#701). * `PaymentLinkRequest#setCustomerRetry(PaymentRetryRequest)` and `PaymentLinkRequestBuilder#customerRetry(PaymentRetryRequest)`: same reason. Use the `CustomerRetry` overloads (#701). **Breaking changes required by the API**⚠️ * `PaymentSetupsRequest#paymentType`, `PaymentSetupsResponse#paymentType` and `PaymentSetupsConfirmResponse#paymentType` change from `com.checkout.payments.PaymentType` to `PaymentSetupPaymentType`. The Payment Setups API only accepts the lowercase values; the old type sent `PayLater`, which the API rejects with a 422, and read every value except `regular` as null. Migration: replace `PaymentType.X` with `PaymentSetupPaymentType.X` (#700). * `MerchantAccount#lastPaymentAmount` (Payment Setups customer) changes from `Long` to `Double`, because the API defines it as a number (for example `55.99`). Migration: pass a `Double` (for example `500d`) and read the getter as `Double` (#700). * `HostedPaymentRequest#customerRetry` and `PaymentLinkRequest#customerRetry` change from `PaymentRetryRequest` to `CustomerRetry`, because customer retries only accept `max_attempts` (0 to 5). Code that sets the field keeps compiling through the deprecated overloads; code that reads `getCustomerRetry()` now gets a `CustomerRetry`. Migration: `CustomerRetry.builder().maxAttempts(n).build()` (#701). **Dependencies** * gson 2.14.0, slf4j-api 2.0.18 and commons-codec 1.22.1, all still compatible with Java 8 (#702).
This release adds the Payment Setup payment type, the risk settings on the Payment Setup confirm response and the Tamara risk assessment fields. It also adds the subscription details and the retry attempt count to payment responses, and lets you revoke and suspend Issuing cards without a request body. Customer retries on hosted payments and payment links now use the type the API accepts, and the update card headers the API no longer documents are deprecated. Every deprecated member keeps working and will be removed in the next major version. **Added** Issuing (#697) * `IssuingClient#revokeCard(String cardId)`, `#suspendCard(String cardId)`, `#revokeCardSync(String cardId)` and `#suspendCardSync(String cardId)`. The existing overloads that take a `RevokeCardRequest` or `SuspendCardRequest` now accept `null`, because the request body is optional in the API. Payment Setups (#700) * `PaymentSetupPaymentType` with the values of the Payment Setups API: `REGULAR` (`regular`), `RECURRING` (`recurring`), `MOTO` (`moto`), `INSTALLMENT` (`installment`), `PAY_LATER` (`pay_later`), `UNSCHEDULED` (`unscheduled`). * `PaymentSetupsConfirmResponse#risk` (`PaymentSetupRisk`). * `Tamara#initialization` (`PaymentMethodInitialization`, default `DISABLED`) and `Tamara#riskAssessment`, with the new `TamaraRiskAssessment` (`premiumCustomer`, `riskScore`, `orderCountLast24h`, `linkedDeviceCount`). Payments (#701) * `PaymentResponse#subscription` (`PaymentSubscription`). * `PaymentRetryResponse#attemptsMade`, returned by get payment details. **Changed** * `PaymentRetryRequest#enabled` is no longer deprecated. It is the required switch for asynchronous retries on payment requests (#701). * Request and response fields of payments, payment retries, hosted payments, payment links, payment sessions and Payment Setups now document whether they are required or optional, with the limits, defaults and enum values of the API reference (#700, #701). * Payment Setup payment methods document that an update replaces the payment methods, so `initialization` must be sent as `ENABLED` again to keep a method enabled (#700). **Fixed** * The `Retry` response of a payment request no longer reports `maxAttempts` as 6 when the API did not return it (#701). **Deprecated** All deprecated members keep working and will be removed in the next major version. * `CardUpdateHeaders` and the `IssuingClient#updateCard` and `#updateCardSync` overloads that take it: the API no longer documents the `return-encrypted-cvv` and `Encryption-Key` headers. Headers that are set are still sent. Use `updateCard(String, UpdateCardRequest)` or `updateCardSync(String, UpdateCardRequest)` (#697). * `HostedPaymentRequest#setCustomerRetry(PaymentRetryRequest)` and `HostedPaymentRequestBuilder#customerRetry(PaymentRetryRequest)`: customer retries only accept `max_attempts`, so only that value is kept. Use the `CustomerRetry` overloads (#701). * `PaymentLinkRequest#setCustomerRetry(PaymentRetryRequest)` and `PaymentLinkRequestBuilder#customerRetry(PaymentRetryRequest)`: same reason. Use the `CustomerRetry` overloads (#701). **Breaking changes required by the API**⚠️ * `PaymentSetupsRequest#paymentType`, `PaymentSetupsResponse#paymentType` and `PaymentSetupsConfirmResponse#paymentType` change from `com.checkout.payments.PaymentType` to `PaymentSetupPaymentType`. The Payment Setups API only accepts the lowercase values; the old type sent `PayLater`, which the API rejects with a 422, and read every value except `regular` as null. Migration: replace `PaymentType.X` with `PaymentSetupPaymentType.X` (#700). * `MerchantAccount#lastPaymentAmount` (Payment Setups customer) changes from `Long` to `Double`, because the API defines it as a number (for example `55.99`). Migration: pass a `Double` (for example `500d`) and read the getter as `Double` (#700). * `HostedPaymentRequest#customerRetry` and `PaymentLinkRequest#customerRetry` change from `PaymentRetryRequest` to `CustomerRetry`, because customer retries only accept `max_attempts` (0 to 5). Code that sets the field keeps compiling through the deprecated overloads; code that reads `getCustomerRetry()` now gets a `CustomerRetry`. Migration: `CustomerRetry.builder().maxAttempts(n).build()` (#701). **Dependencies** * gson 2.14.0, slf4j-api 2.0.18 and commons-codec 1.22.1, all still compatible with Java 8 (#702).



Summary
payment_typeon Payment Setup used the paymentsPaymentType, which sendsPayLater, rejected by the API with 422, and reads every lowercase value exceptregularas null. It now has its own enum with the six spec values. The confirm response gets theriskit was missing and Tamara getsinitializationandrisk_assessment.last_payment_amounttakes the specification's number type.Changes
entities/paymentType/PaymentSetupPaymentType.java(new):REGULAR,RECURRING,MOTO,INSTALLMENT,PAY_LATER,UNSCHEDULED, sent lowercase. Used byPaymentSetupsRequest(defaultREGULAR),PaymentSetupsResponseandPaymentSetupsConfirmResponse;com.checkout.payments.PaymentTypeis unchanged.PaymentSetupsConfirmResponse.java:risk(PaymentSetupRisk).tamara/Tamara.java:initialization(defaultDISABLED, as the other methods) andriskAssessment;tamara/TamaraRiskAssessment.java(new).customer/MerchantAccount.java:lastPaymentAmountisDouble(wasLong), the specification's number type, as the Flow and payment response fields. Its doc notes that the API currently stores it as an integer. The docs of all eight properties use the spec descriptions.Klarna,Bacs,CashApp,PayPal,Stcpay,Tabby,Tamara: theinitializationdoc gives the spec description and default, and says that an update replaces the payment methods, soENABLEDmust be sent again to keep a method enabled (API behaviour, not stated in the spec).PaymentMethods.java,Order.java, the request and both responses: docs completed against the spec.Bacs.allowPartialMatch,PayPal.brandNameandaction,Stcpay.otpandaction,Knet.language, and the class docs ofOrder,PaymentMethods,StcpayandTabby.ideal/Ideal.javadescription,knet/Knet.javalanguage,bancontact/Bancontact.javaaccountHolderName: the doc says that the specification marks the field optional, but the API keeps the method invalid until it is sent.PaymentSetupPaymentTypevalue written and read, the default, round trips through the request and both responses;PaymentSetupsConfirmResponseSerializationTestreads and round trips the confirmrisk; Order and Tamara round trips with literal keys and the spec examples;PaymentSetupsTestITuses the new enum.PaymentSetupsPaymentMethodsSerializationTest.java(new): a round trip with every property under its literal wire key and a spec example test for Ach, Sepa, Swish, P24, Qpay, Ideal, Knet, Bancontact, Multibanco, Blik, Bacs, Alipay CN, Alipay HK, GCash, TNG, Dana, KakaoPay, TrueMoney, Alma, Benefit, EPS, MBWay, MobilePay, Octopus, PayNow, Sequra, Twint, Vipps and WeChatPay;last_payment_amountround trip under its literal key with the spec example 55.99.PaymentSetupsNewFieldsSerializationTest.java,LocalDateFieldsRegressionTest.java:lastPaymentAmountuses 55.99.API Reference
POST /payments/setups:payment_type,payment_methodsPUT /payments/setups/{id}GET /payments/setups/{id}POST /payments/setups/{id}/confirm/{payment_method_name}Breaking changes required by the API
paymentTypeonPaymentSetupsRequest,PaymentSetupsResponseandPaymentSetupsConfirmResponseisPaymentSetupPaymentType; code passingcom.checkout.payments.PaymentTypemust switch, includingPaymentType.REGULAR, which no longer compiles there (usePaymentSetupPaymentType.REGULAR).PaymentSetupsConfirmResponsetakes the newriskargument.Breaking changes: type corrected to the specification
MerchantAccount.lastPaymentAmountisDoubleinstead ofLong. The specification types it as a number (example 55.99), which aLongcannot hold: if the API returns a decimal, reading the whole Payment Setup response fails. Code that passes aLong(for examplelastPaymentAmount(1000L)) or reads the value asLongstops compiling and must useDouble. The API currently stores the value as an integer (55.99 is stored as 55); that is reported separately.Breaking changes: default value
"initialization":"disabled"by default (master sent{}), as the other methods withinitialization. Harmless: an update replaces the payment methods, so omitting it also leaves Tamara disabled. Migration: setinitializationtoENABLEDto enable Tamara.Follow-ups
Reported internally, for later:
Order.itemsandOrder.shippingkeep the payments types until the next major version.PaymentSetupsConfirmResponse, a duplicate ofPaymentSetupsResponse) until the next major version.Resourcelinks, which the Payment Setups specification does not define.CardAccountHolderkeeps its name (the spec calls itPaymentSetupAccountHolder) until the next major version.terminal.local_date_timeis anInstantand loses the offset (tracked separately).latestPaymenton both responses stays typedObject(specPaymentDetails) until a later major version.README
No change needed.