Repository navigation
feat(setups): add missing payment methods, billing and payment type - #398
rodrigojara-cko wants to merge 8 commits into
Conversation
🟡 Risk Classification: MINORApproval route: AI Review + Human Approval Classification reasons
Operational gates
Files analysed: 54 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: Concerns worth a lookThis PR needs a human approval. Before you give it, these are the things I'd want resolved. This PR adds 29 new payment method classes, an EmptyAsObject serializer attribute, billing and payment_type fields to PaymentSetupRequest, and annotates all existing Setups object classes. The implementation is generally correct and well-documented, but there is one concrete correctness issue in JsonSerializer and one removed property that looks like a regression. Concerns
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 the 29 payment methods of the spec that were missing and the request billing; payment_type defaults to regular with constants for the six spec values. Members the spec does not have are deprecated.
…loat Bizum, PayByBank and Stablecoin extend PaymentMethodBase again, as before, so instanceof checks keep working. Their initialization property is redeclared with a deprecation notice because their schemas do not define it. Remove the Tamara initialization note that is not in the specification. MerchantAccount last_payment_amount is a number in the specification (example 55.99), so it is documented as float.
52464c2 to
1b84ae6
Compare
🟡 Risk Classification: MINORApproval route: AI Review + Human Approval Classification reasons
Operational gates
Files analysed: 56 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 |
The specification types last_payment_amount as a number (example 55.99), but the sandbox stores and returns 55 for 55.99. The doc says so, so the type is not changed back and forth; the specification is reported separately.
🟡 Risk Classification: MINORApproval route: AI Review + Human Approval Classification reasons
Operational gates
Files analysed: 56 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 |
json_encode writes an object with nothing set as [], and the API rejects that for alma, sequra and wechatpay with 422 payment_methods.<method>_property_invalid, while {} is accepted. A new EmptyAsObject class attribute, read by JsonSerializer like DateOnly, makes an annotated object with nothing set serialize as {}. It is applied to PaymentSetupPaymentMethod, so every Payment Setup payment method is covered. Empty lists and other objects are unchanged.
Document every MerchantAccount property from the specification.
🟡 Risk Classification: MINORApproval route: AI Review + Human Approval Classification reasons
Operational gates
Files analysed: 59 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 |
card_present is only hidden from the public API reference; the API still supports it. PaymentMethods::$card_present, CardPresent and CardPresentPin are restored as on master, and the test still checks it is sent under its key. The MerchantAccount test also asserts the literal last_payment_amount key with 55.99.
A PUT that omits initialization leaves the method disabled, so the initialization doc says to send enabled again on update, and that this is the API's behaviour, not stated in the specification.
🟡 Risk Classification: MINORApproval route: AI Review + Human Approval Classification reasons
Operational gates
Files analysed: 57 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 |
The API rejects any empty object sent as [] with 422 <path>_property_invalid and accepts {}, not only on payment methods: also the account holders, the SEPA mandate, the Tamara risk assessment, payment_methods, billing, customer, order and settings. Every class under Payments/Setups that maps a JSON object is now annotated #[EmptyAsObject]. Constants classes and classes shared with /payments are unchanged.
Tests cover every annotated class with nothing set, a scan that fails if a new Setups object class is not annotated, the request with empty top-level objects, the nested objects of the payment methods, and a generic JsonSerializer test with fixtures (inheritance, top level, nested, inside a list, empty lists stay []).
🟡 Risk Classification: MINORApproval route: AI Review + Human Approval Classification reasons
Operational gates
Files analysed: 100 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 |
The API keeps ideal, knet and bancontact invalid until description, language and account_holder_name are sent, although the specification marks them optional; their docs say so. The PaymentMethodBase initialization doc now says that an update replaces the payment methods, as on Tamara.
🟡 Risk Classification: MINORApproval route: AI Review + Human Approval Classification reasons
Operational gates
Files analysed: 100 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 |
|



Summary
Payment Setup now models the 29 payment methods of the spec that the SDK was missing and the
billingof the request.payment_typedefaults toregularwith a constants class for the six spec values (Payments\PaymentTypehas nopay_later, andPayLateris rejected with 422). Members the spec does not have are marked deprecated.Changes
Setups/Common/PaymentMethods/PaymentMethods.php:paynow,qpay,eps,ideal,knet,bancontact,benefit,blik,vipps,twint,alipay_cn,alipay_hk,gcash,tng,dana,mobilepay,tamara,mbway,multibanco,wechatpay,kakaopay,truemoney,octopus,p24,alma,swish,sequra,ach,sepa; docs completed against the spec.PayNow,Qpay,Eps,Ideal,Knet,Bancontact,Benefit,Blik,Vipps,Twint,AlipayCn,AlipayHk,GCash,Tng,Dana,MobilePay,Tamara,MbWay,Multibanco,WeChatPay,KakaoPay,TrueMoney,Octopus,P24,Alma,Swish,Sequra,Ach,Sepa, each underSetups/Common/PaymentMethods/<Method>/.AchAccountHolder,AchAccountHolderIdentification,P24AccountHolder,SwishAccountHolder,SepaAccountHolder,SepaMandate,TamaraRiskAssessment.KnetLanguage,AchAccountHolderType,PaymentSetupAchAccountType,SepaAccountHolderType,PaymentSetupSepaMandateType,Common/PaymentSetupTerminalType,Common/PaymentSetupOsType.Setups/Common/PaymentType/PaymentSetupPaymentType.php(new) andSetups/Request/PaymentSetupRequest.php:$payment_typedefault"regular", new$billing.Setups/Common/Billing/PaymentSetupBilling.php(new).Ideal/Ideal.php,Knet/Knet.php,Bancontact/Bancontact.php: thedescription,languageandaccount_holder_namedocs say that the specification marks them optional but the API keeps the method invalid until they are sent.Common/PaymentMethodBase.php,Tamara/Tamara.php: theinitializationdoc says that an update replaces the payment methods, soenabledmust be sent again to keep the method enabled; the specification does not state this, it is the API's behaviour.Bizum,PayByBank,Stablecoin: still extendPaymentMethodBaseas before. Their$initializationis redeclared in each class with a deprecation notice, because their schemas do not define it; the property, its name and what is sent do not change.Bizum::$payment_method_optionsdeprecated and documented.Setups/Common/Customer/MerchantAccount.php: every property documented from the spec;$last_payment_amountdocumented asfloat(the spec type isnumber, example55.99), noting that the API currently stores it as an integer.Common/EmptyAsObject.php(new): class attribute that makesJsonSerializerwrite an annotated object with nothing set as{}instead of[].JsonSerializer.php: reads#[EmptyAsObject]on the class and its parents, the same way it reads#[DateOnly]. Empty lists and every other object serialize as before.Setups/Common/PaymentMethods/Common/PaymentSetupPaymentMethod.php: annotated#[EmptyAsObject], which covers every payment method class.#[EmptyAsObject], every other class underPayments/Setupsthat maps a JSON object:PaymentSetupRequest,PaymentMethods,PaymentSetupBilling,PaymentSetupBillingDescriptor,Customer,Device,Email,MerchantAccount,Industry,AccommodationData,AccommodationHost,AirlineData,AirlineInsurance,AirlineInsurancePrice,PaymentSetupAccommodationAddress,PaymentSetupAccommodationRoom,Order,OrderSubMerchant,PaymentSetupAmountAllocation,AmountAllocationCommission,Settings,PaymentSetupPresentmentDetails,PaymentSetupRisk,PaymentSetupTerminal,AchAccountHolder,AchAccountHolderIdentification,ApplePayTokenData,ApplePayTokenDataHeader,BacsAccountHolder,CardDetails,CardToken,CardPresentPin,CashAppAction,CashAppAddress,CashAppCustomerProfile,CardAccountHolder,PaymentMethodAction,PaymentMethodOption,PaymentMethodOptions,WalletToken,GooglePayTokenData,PaymentSetupInstrumentAction,KlarnaAccountHolder,KlarnaAction,P24AccountHolder,PayByBankAction,PayByBankBank,PaypalAction,SepaAccountHolder,SepaMandate,StcpayAction,SwishAccountHolder,TamaraRiskAssessment. Constants classes are not annotated.PaymentSetupPaymentMethodsSerializationTest.php(new): literal key of every new method, declared properties against the spec, full round trips, constants, the spec examples, everypayment_typevalue and the default,billing.address, deprecated members still sent,Bizum,PayByBankandStablecoinstillinstanceof PaymentMethodBase, an empty payment method sent as{}(new and existing methods) while an emptyflagslist stays[].PaymentSetupEmptyObjectsSerializationTest.php(new): every Payment Setup object class with nothing set is sent as{}at the top level and nested; a scan ofPayments/Setupsfails if an object class is not annotated; the request with emptypayment_methods,settings,customer,orderandbilling; the empty account holders, SEPA mandate and Tamara risk assessment; an empty sharedAddressinsidebillingis unchanged.JsonSerializerTest.php,EmptyAsObjectParentFixture.php,EmptyAsObjectChildFixture.php,PlainObjectFixture.php(new fixtures): the attribute at the top level, nested, inside a list and inherited from a parent; empty lists stay[]; an object with values and an object without the attribute are unchanged.PaymentSetupFieldsSerializationTest.php:last_payment_amountround trip and literal key with55.99.PaymentSetupsIntegrationTest.php: uses the new constants.API Reference
POST /payments/setups:payment_type,payment_methodsPUT /payments/setups/{id}GET /payments/setups/{id}POST /payments/setups/{id}/confirm/{payment_method_name}Deprecated
All of them will be removed in the next major version.
$initializationonBizum,PayByBankandStablecoin. Their spec schemas have noinitializationand the API ignores it. No replacement.Bizum::$payment_method_options. Not part of the Bizum schema. No replacement.Breaking changes required by the API
PaymentSetupRequest::$payment_typenow uses the Payment Setup values, so its default changes from"Regular"to"regular". The API takes only the six lowercase spec values for the new types (PayLateris rejected with 422payment_type_property_invalid); it still stores"Regular"asregular. Code that compares the default with"Regular"sees the new value. UsePaymentSetupPaymentTypefor the other values.{}instead of[]. In the sandbox, every empty object sent as[]is rejected with 422<path>_property_invalidand the same request with{}returns 200. Checked for the payment methods (for examplepayment_methods.alma_property_invalid,sequra,wechatpay), for objects inside them (sepa.account_holder,sepa.mandate,ach.account_holder,swish.account_holder,p24.account_holder,tamara.risk_assessment), forpayment_methodsitself, and for the top-levelbilling,customer,orderandsettings. This also applies to the existing classes when they are sent empty. Objects with at least one value and lists are sent exactly as before.No class changes its parent:
PaymentMethodBaseandPaymentSetupPaymentMethodare unchanged, and every existing method keeps its base class.Follow-ups
account_funding_transactionon the Payment Setup is not modelled yet; reported internally and handled separately./paymentstypes (Payments\Product,Payments\ShippingDetails) until the next major version; reported internally.payment_type(defaultregular) unless the caller sets it tonull; reported internally.[]:Common\Address,Common\Phone,Payments\Product(order items),Payments\ShippingDetails,Payments\AccommodationGuest,Payments\FlightLegDetails,Payments\Passenger,Payments\Ticket. They are also used by other endpoints, so they are not changed here; reported internally.README
No change needed.