feat: Implement remaining active payment types, installment plans and basket v3 - #6
Open
sveneberth wants to merge 2 commits into
Open
feat: Implement remaining active payment types, installment plans and basket v3#6sveneberth wants to merge 2 commits into
sveneberth wants to merge 2 commits into
Conversation
`createPaymentType()` interpolated the `PaymentTypes` enum member itself, so the request went to `types/PaymentTypes.CARD` instead of `types/card`: > `"types/%s" % paymentType.method` -> `types/PaymentTypes.CARD` `method` holds the short code used in type ids (`crd`), while the types endpoint expects the full method name (`card`). Both are wrong when the enum member is stringified instead of its value.
… basket v3 Adds all payment methods Unzer currently lists as active: - `Alipay`, `ClickToPay`, `PayU`, `PostFinanceCard`, `PostFinanceEfinance`, `Prepayment`, `Przelewy24`, `Twint`, `Wechatpay`, `Wero` - `DirectBankTransfer` (`openbanking-pis`) with `ibanCountry` - `Eps` with `bic` - `SepaDirectDebit` and `PaylaterDirectDebit` with `iban`/`holder` - `PaylaterInstallment` with `inquiryId`, `numberOfRates`, `iban`, `country` and `holder` Installment needs two more steps around the payment type, both added to the client: `getPaylaterInstallmentPlans()` fetches the plans to present to the customer (new models `InstallmentPlans`, `InstallmentPlan`, `InstallmentRate`) and `riskCheckPaylaterInstallment()` pre-checks the customer data. Both, and the Pay later authorize calls, need the customer's IP, which `UnzerClient` now sends as `CLIENTIP` header when constructed with `client_ip`. It also requires a basket in the newer schema, so `Basket` gained `totalValueGross` and `BasketItem` gained `amountPerUnitGross` and `amountDiscountPerUnitGross`. Setting `totalValueGross` switches the basket to `/v3/baskets`; without it nothing changes. `fromDict()` of both models no longer fails on the keys of the other schema. Field names, type short codes and resource paths are taken from the PHP and Java SDK, not from the documentation, which contradicts them in several places (`obp` vs. `opb`, `holder` vs. `accountHolder`, `CLIENTIP` vs. `x-CLIENTIP`). `PaymentMethodTypes.EPS` is corrected to `eps` accordingly, and the keypair lookup in `get_configuration()` now compares case-insensitive. BREAKING CHANGE: `UnzerClient.endpoint` no longer contains the API version, which moved to `UnzerClient.apiVersion`, so that resources can be requested in a different version.
sveneberth
force-pushed
the
feat/payment-methods
branch
from
August 5, 2026 22:08
b727a8e to
fa787e2
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds every payment method Unzer currently lists as active, with full server-side support
for Installment and Direct Bank Transfer.
Payment types (15):
Alipay,ClickToPay,DirectBankTransfer,Eps,PayU,PaylaterDirectDebit,PaylaterInstallment,PostFinanceCard,PostFinanceEfinance,Prepayment,Przelewy24,SepaDirectDebit,Twint,Wechatpay,Wero.PaymentTypesgainedPAYU/WERO,PaymentMethodTypesgainedWERO.Installment needs two steps around the payment type, both on the client now:
New response models
InstallmentPlans,InstallmentPlan,InstallmentRateandRiskCheckResponse. The customer's IP, which the Pay later methods require, is sent asCLIENTIPheader viaUnzerClient(client_ip=…).Basket v3, which Installment requires:
BasketgainedtotalValueGross,BasketItemgained
amountPerUnitGross/amountDiscountPerUnitGross. SettingtotalValueGrossswitchesthe basket to
/v3/baskets; without it nothing changes.fromDict()of both models nolonger fails on the keys of the other schema.
Motivation
Only a handful of payment methods were available, and the two most requested ones —
Installment and Direct Bank Transfer — were unusable because Installment needs a plans
inquiry, a payment type with fields, and a v3 basket.
Verification
Field names, short codes and resource paths come from the PHP SDK, the Java SDK and the
OpenAPI specification (
api.unzer.com/swagger-ui/api-docs), not from the prosedocumentation, which contradicts them in eleven places, among them:
opbobp(typeIds-obp-…)/types/open-banking-pis/types/openbanking-pisaccountHolderholderx-CLIENTIPCLIENTIP/types/WeChatPay,/types/WerocountryinquiryId,numberOfRates)PaymentMethodTypes.EPSis corrected fromEPStoepsaccordingly — the specificationknows only
/v1/types/epsand the typeId prefixp-eps-, and uppercaseEPSappears theresolely as a documentation tag. To stay safe either way, the keypair lookup in
get_configuration()now compares case-insensitive.Checked mechanically for all 15 types: short code and resource path exist in the API
reference, request payloads match its request schemas field by field, and all four
response models match their response schemas field by field. Payloads carry only fields
that are set and never
null, which constraints such asminLengthwould reject.Baskets serialize and parse in both schemas, with
participantIdsent for v1 only andnotekept for v3. The complete installment flow (plans -> type -> basket -> risk check-> authorize) runs against the documented example payloads, and
pycodestylestays atthe five pre-existing violations. Not yet run against the sandbox API with a real
keypair.
Where documentation and specification disagree, the docstring at that spot records which
source was followed and why.
Breaking change
UnzerClient.endpointno longer contains the API version, which moved toUnzerClient.apiVersion, so resources can be requested in another version. Only affectscallers that override
endpoint. Version bumped 1.4.0 → 1.5.0.Note for review
The first commit is the separate fix PR #5 — please merge that one first.