Release 2.1.0 - BACS Direct Debit notifications + refactor - #200
Conversation
🟡 Risk Classification: MINORApproval route: AI Review + Human Approval Classification reasons
Operational gates
Files analysed: 1 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: Sound, but needs your judgementThis PR needs a human approval. The code itself reads as correct; whether it should land depends on context I don't have. The diff provided contains only the version bump from 2.0.0 to 2.1.0; all the substantive changes described in the PR (BacsClient, ACH/SEPA models, InstrumentType changes, CheckoutApi wiring, breaking removal of InstrumentData) are not visible in this diff, so the actual code cannot be verified here. For you to decide
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 |
|



Breaking changes (check at the end
)
This release introduces support for Bacs Direct Debit and ACH payment instruments, as well as improvements and clarifications to the SDK's type documentation. The main changes include adding Bacs and ACH instrument models, enabling Bacs notifications, and updating type definitions to support new use cases and improve clarity.
Bacs Direct Debit support:
BacsClient) with support for sending pre-notification requests (send_notification) and corresponding request/response types. (lib/checkout_sdk/apm/apm.rb,lib/checkout_sdk/apm/bacs/bacs_client.rb,lib/checkout_sdk/apm/bacs/bacs_notification_request.rb,lib/checkout_sdk/apm/bacs/bacs_notification_type.rb) [1] [2] [3] [4]CheckoutApi, making it available asapi.bacs. (lib/checkout_sdk/checkout_api.rb) [1] [2] [3]lib/checkout_sdk/instruments/create/create_bacs_instrument_data.rb,lib/checkout_sdk/instruments/create/create_bacs_billing_address.rb,lib/checkout_sdk/instruments/create/create_bacs_account_holder.rb,lib/checkout_sdk/instruments/create/create_bacs_instrument_account.rb,lib/checkout_sdk/instruments/bacs_payment_type.rb) [1] [2] [3] [4] [5]BACSas a supported payment source and instrument type. (lib/checkout_sdk/common/payment_source_type.rb,lib/checkout_sdk/common/instrument_type.rb) [1] [2]ACH Direct Debit support:
lib/checkout_sdk/instruments/create/create_ach_account_holder.rb,lib/checkout_sdk/instruments/create/create_ach_instrument_data.rb,lib/checkout_sdk/instruments/ach_account_type.rb) [1] [2] [3]ACHas a supported instrument and payment source type. (lib/checkout_sdk/common/instrument_type.rb,lib/checkout_sdk/common/payment_source_type.rb) [1] [2]SEPA Direct Debit improvements:
lib/checkout_sdk/instruments/create/create_sepa_account_holder.rb,lib/checkout_sdk/instruments/create/create_sepa_billing_address.rb) [1] [2]Type and documentation enhancements:
AccountHolderType,CustomerRequest, andInstrumentType, clarifying usage and adding new values such asGOVERNMENTandBACS. (lib/checkout_sdk/common/account_holder_type.rb,lib/checkout_sdk/common/customer_request.rb,lib/checkout_sdk/common/instrument_type.rb) [1] [2] [3]These changes add significant new functionality for direct debit payments and improve the SDK's clarity and extensibility.
Breaking changes


Two, plus a set of behaviour changes that make previously-invalid requests valid. Everything else in this PR is additive.
1.
CheckoutSdk::Instruments::InstrumentDatahas been removedIt was a single class serving the SEPA instrument's
instrument_data, and it carried two defects:payment_typeYARD pointed atCheckoutSdk::Payments::PaymentType— the payment-level enum (Regular,Recurring,Moto,Installment,Unscheduled). SEPA instruments declarepayment_typeas lowercaserecurring/regular, so following the documentation produced a request the API rejects. The repo's own integration spec did exactly that.date_of_signaturewas documented asDateTime. The field isformat: dateand the API expectsyyyy-MM-dd, so aDateTimeserialized to a full timestamp.It is replaced by per-scheme, spec-literal classes. The store and update shapes are genuinely different in the specification — different required sets and different
maxLengthvalues on the same fields — so they are separate types rather than one shared one.Migration
InstrumentSepaitself is unchanged apart from gaining thecustomerattribute the specification declares. Because the SDK is duck-typed, aHashalso works if you prefer not to adopt the new classes.2.
CheckoutSdk::Instruments::PaymentNetworkvalues changed casingFour of six values were wrong on the wire. The constant names are unchanged, so nothing fails to load — but the string sent to the API is different:
PaymentNetwork::FPS'Fps''fps'PaymentNetwork::ACH'Ach''ach'PaymentNetwork::FEDWIRE'Fedwire''fedwire'PaymentNetwork::SWIFT'Swift''swift'LOCALandSEPAwere already correct. These are query-parameter values onGET /validation/bank-accounts/{country}/{currency}; the specification declares all six lowercase, so the four capitalized ones were silently ignored as a filter rather than rejected. If you were passing them and relying on the unfiltered result, the response will now be narrower — which is the documented behaviour. If you hardcoded the lowercase strings yourself, nothing changes for you.Behaviour changes that fix previously-invalid requests
Neither is a compile or load break in Ruby, but both change what a correct integration should send.
Payments::AchSource#account_typenow documentsPayments::AchSourceAccountType(savings/checking/cash). It previously pointed atCommon::AccountType, which issavings/current/cash.PaymentRequestAchSourceis the only schema in the specification declaringchecking, and it does not acceptcurrent— soCommon::AccountType::CURRENTnever produced a valid ACH payment source, andcheckingcould not be named at all.Common::AccountTypeis unchanged and remains correct for the seven bank-account positions that do declarecurrent.date_of_signatureon both SEPA instrument-data classes is ayyyy-MM-ddString, not aDateTime. See above.What's new (additive)
cko.bacs.send_notification(request)—POST /apms/bacs/notifications, secret key. Sends a Bacs Direct Debit pre-notification. Registered on the current-APICheckoutApionly; the previous platform does not expose it.Bacs, SEPA and ACH instruments —
InstrumentBacs,InstrumentAch,UpdateInstrumentBacs,UpdateInstrumentSepa,UpdateInstrumentAch, plus 15 value classes and 5 enums (SepaPaymentType,BacsPaymentType,SepaMandateType,AchAccountType,InstrumentAccountHolderType).Payment sources —
BacsSource, plus the 12 APM variants that had no dedicated class:AlipayCnSource,AlipayHkSource,DanaSource,GcashSource,KakaopaySource,MobilePaySource,PayNowSource,SwishSource(withSwishAccountHolderandSwishBillingDescriptor),TngSource,TruemoneySource,TwintSource,VippsSource. Ruby now covers all 39 request-source variants the specification declares.SepaSource#mandate_type— theCore/B2Bmandate type the SEPA payment source declares and the SDK could not send.Enum additions —
Common::InstrumentType:ACH,BACS.Common::PaymentSourceType:BACS,MOBILEPAY,PAYNOW,SWISH,TWINT,VIPPS.Common::AccountHolderType:GOVERNMENT.Two casing traps documented in the code
Both are real specification behaviour, not SDK quirks, and both now carry regression tests so they cannot be "tidied up" later:
payment_typeis capitalized (Recurring/Regular); SEPApayment_typeis lowercase (recurring/regular). Two separate enums; the values are not interchangeable.account_holder.typeon the SEPA payment source: the specification declaresIndividual/Corporatecapitalized at that one position, against 23 lowercase account-holder-type positions elsewhere — including the sibling ACH source. Send lowercase. Every Checkout.com SDK sends lowercase, and this is pending confirmation from the API owners as a likely specification defect. Documented on the attribute.