From 3b23e16159421c19d32ceac09842a0ca737a1070 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matou=C5=A1=20Dzivjak?= Date: Thu, 23 Apr 2026 00:31:09 +0200 Subject: [PATCH 1/2] feat(sdk): flatten request body arguments in generated Python methods Update the Python SDK generator to expose declared top-level JSON request body fields as keyword-only method arguments instead of requiring explicit body= model construction, and regenerate the SDK with the new signatures. Refresh the README and examples to use the flattened call style so the public usage matches the generated API. --- README.md | 34 +- .../builder/intermediate_representation.go | 17 +- codegen/pkg/builder/methods.go | 115 +- codegen/pkg/builder/out.go | 52 + codegen/pkg/builder/transform.go | 44 +- codegen/pkg/builder/types.go | 179 +- codegen/templates/resource.py.tmpl | 34 +- codegen/templates/types.py.tmpl | 1 + examples/card_reader_checkout.py | 11 +- examples/sync.py | 13 +- sumup/_service.py | 29 + sumup/checkouts/__init__.py | 10 - sumup/checkouts/resource.py | 607 ++- sumup/customers/__init__.py | 4 - sumup/customers/resource.py | 131 +- sumup/members/__init__.py | 8 - sumup/members/resource.py | 389 +- sumup/memberships/__init__.py | 4 - sumup/memberships/resource.py | 191 +- sumup/merchants/__init__.py | 6 - sumup/merchants/resource.py | 146 +- sumup/payouts/__init__.py | 4 - sumup/payouts/resource.py | 139 +- sumup/readers/__init__.py | 12 - sumup/readers/resource.py | 545 ++- sumup/receipts/__init__.py | 2 - sumup/receipts/resource.py | 74 +- sumup/roles/__init__.py | 4 - sumup/roles/resource.py | 183 +- sumup/subaccounts/__init__.py | 10 - sumup/subaccounts/resource.py | 228 +- sumup/transactions/__init__.py | 10 - sumup/transactions/resource.py | 505 ++- sumup/types/__init__.py | 3920 +++++++++++++++++ tests/test_query_params.py | 27 +- tests/test_request_bodies.py | 44 +- tests/test_secret.py | 26 +- 37 files changed, 6578 insertions(+), 1180 deletions(-) diff --git a/README.md b/README.md index 0d060145..d79ce803 100644 --- a/README.md +++ b/README.md @@ -65,22 +65,19 @@ import os import uuid from sumup import Sumup -from sumup.checkouts import CreateCheckoutBody client = Sumup(api_key="sup_sk_MvxmLOl0...") merchant_code = os.environ["SUMUP_MERCHANT_CODE"] # Create a checkout checkout = client.checkouts.create( - body=CreateCheckoutBody( - amount=10.00, - currency="EUR", - checkout_reference=str(uuid.uuid4()), - merchant_code=merchant_code, - description="Test payment", - redirect_url="https://example.com/success", - return_url="https://example.com/webhook", - ) + amount=10.00, + currency="EUR", + checkout_reference=str(uuid.uuid4()), + merchant_code=merchant_code, + description="Test payment", + redirect_url="https://example.com/success", + return_url="https://example.com/webhook", ) print(f"Checkout ID: {checkout.id}") @@ -91,7 +88,6 @@ print(f"Checkout Reference: {checkout.checkout_reference}") ```python from sumup import Sumup -from sumup.readers import CreateReaderCheckoutBody, CreateReaderCheckoutBodyTotalAmount client = Sumup(api_key="sup_sk_MvxmLOl0...") @@ -99,15 +95,13 @@ client = Sumup(api_key="sup_sk_MvxmLOl0...") reader_checkout = client.readers.create_checkout( reader_id="your-reader-id", merchant_code="your-merchant-code", - body=CreateReaderCheckoutBody( - total_amount=CreateReaderCheckoutBodyTotalAmount( - value=1000, # 10.00 EUR (amount in cents) - currency="EUR", - minor_unit=2, - ), - description="Coffee purchase", - return_url="https://example.com/webhook", - ), + total_amount={ + "value": 1000, # 10.00 EUR (amount in cents) + "currency": "EUR", + "minor_unit": 2, + }, + description="Coffee purchase", + return_url="https://example.com/webhook", ) print(f"Reader checkout created: {reader_checkout}") diff --git a/codegen/pkg/builder/intermediate_representation.go b/codegen/pkg/builder/intermediate_representation.go index c81da55d..f2fdc143 100644 --- a/codegen/pkg/builder/intermediate_representation.go +++ b/codegen/pkg/builder/intermediate_representation.go @@ -19,11 +19,14 @@ type ClassDeclaration struct { Description string // AdditionalPropertiesType holds the value type for additional properties if enabled. AdditionalPropertiesType string + // RequestOnly marks request-only helper types that should not emit response models. + RequestOnly bool } type OneOfDeclaration struct { - Name string - Options []string + Name string + Options []string + RequestOnly bool } // Property holds the information for Property of a type. @@ -68,11 +71,21 @@ type TypeAlias struct { Type string // Comment holds the description of the type Comment string + // RequestOnly marks request-only helper types that should only emit input aliases. + RequestOnly bool } func (ta *TypeAlias) String() string { buf := new(strings.Builder) + if ta.RequestOnly { + fmt.Fprintf(buf, "%sInput = %s\n", ta.Name, inputTypeName(ta.Type)) + if ta.Comment != "" { + fmt.Fprintf(buf, "'''\n%s\n'''\n", ta.Comment) + } + return buf.String() + } fmt.Fprintf(buf, "%s = %s\n", ta.Name, ta.Type) + fmt.Fprintf(buf, "%sInput = %s\n", ta.Name, inputTypeName(ta.Type)) if ta.Comment != "" { fmt.Fprintf(buf, "'''\n%s\n'''\n", ta.Comment) } diff --git a/codegen/pkg/builder/methods.go b/codegen/pkg/builder/methods.go index 231948ae..b56e91e9 100644 --- a/codegen/pkg/builder/methods.go +++ b/codegen/pkg/builder/methods.go @@ -36,7 +36,9 @@ type Method struct { ResponseType *string Path string PathParams []Parameter - QueryParams *Parameter + QueryFields []Property + BodyType string + BodyFields []Property HasBody bool Responses []Response } @@ -48,13 +50,72 @@ func (mt Method) ParamsString() string { res.WriteString(", ") res.WriteString(fmt.Sprintf("%s: %s", strcase.ToSnake(p.Name), p.Type)) } - if mt.QueryParams != nil { + needsKeywordOnly := mt.HasFlattenedBody() || len(mt.QueryFields) > 0 + if mt.HasFlattenedBody() { + if needsKeywordOnly { + res.WriteString(", *") + } + for _, p := range mt.BodyFields { + res.WriteString(", ") + res.WriteString(p.MethodParameterString()) + } + } else if mt.HasBody { res.WriteString(", ") - res.WriteString(fmt.Sprintf("%s: typing.Optional[%s] = None", strcase.ToSnake(mt.QueryParams.Name), mt.QueryParams.Type)) + res.WriteString(fmt.Sprintf("body: %sInput", mt.BodyType)) + } + if len(mt.QueryFields) > 0 { + if !mt.HasFlattenedBody() { + res.WriteString(", *") + } + for _, p := range mt.QueryFields { + res.WriteString(", ") + res.WriteString(p.MethodParameterString()) + } } return res.String() } +func (mt Method) HasFlattenedBody() bool { + return len(mt.BodyFields) > 0 +} + +func (mt Method) BodyInitString() string { + if !mt.HasFlattenedBody() { + return "" + } + + var buf strings.Builder + buf.WriteString("body_data: dict[str, typing.Any] = {}\n") + for _, field := range mt.BodyFields { + if field.Optional { + fmt.Fprintf(&buf, "if not isinstance(%s, NotGivenType):\n", field.FieldName()) + fmt.Fprintf(&buf, "\tbody_data[%q] = %s\n", field.WireName(), field.BodyArgumentExpr()) + } else { + fmt.Fprintf(&buf, "body_data[%q] = %s\n", field.WireName(), field.BodyArgumentExpr()) + } + } + + return buf.String() +} + +func (mt Method) QueryInitString() string { + if len(mt.QueryFields) == 0 { + return "" + } + + var buf strings.Builder + buf.WriteString("query_data: dict[str, typing.Any] = {}\n") + for _, field := range mt.QueryFields { + if field.Optional { + fmt.Fprintf(&buf, "if not isinstance(%s, NotGivenType) and %s is not None:\n", field.FieldName(), field.FieldName()) + fmt.Fprintf(&buf, "\tquery_data[%q] = %s\n", field.WireName(), field.BodyArgumentExpr()) + } else { + fmt.Fprintf(&buf, "query_data[%q] = %s\n", field.WireName(), field.BodyArgumentExpr()) + } + } + return buf.String() +} + // pathsToMethods converts openapi3 path to golang methods. func (b *Builder) pathsToMethods(paths *v3.Paths) ([]*Method, error) { allMethods := make([]*Method, 0, paths.PathItems.Len()) @@ -128,25 +189,18 @@ func (b *Builder) operationToMethod(method, path string, o *v3.Operation) (*Meth } hasBody := false + bodyType := "" if o.RequestBody != nil { mt, ok := o.RequestBody.Content.Get("application/json") if ok && mt.Schema != nil { - params = append(params, Parameter{ - Name: "body", - Type: strcase.ToCamel(o.OperationId) + "Body", - }) + bodyType = strcase.ToCamel(o.OperationId) + "Body" hasBody = true } } - var queryParams *Parameter - if slices.ContainsFunc(o.Parameters, func(p *v3.Parameter) bool { - return p.In != "path" && p.In != "header" - }) { - queryParams = &Parameter{ - Name: "params", - Type: strcase.ToCamel(o.OperationId) + "Params", - } + queryFields, err := b.buildQueryFields(o) + if err != nil { + return nil, fmt.Errorf("build query parameters: %w", err) } responses := make([]Response, 0, o.Responses.Codes.Len()) @@ -194,12 +248,41 @@ func (b *Builder) operationToMethod(method, path string, o *v3.Operation) (*Meth ResponseType: respType, Path: pathBuilder(path), PathParams: params, - QueryParams: queryParams, + QueryFields: queryFields, + BodyType: bodyType, HasBody: hasBody, Responses: responses, }, nil } +func (b *Builder) buildQueryFields(o *v3.Operation) ([]Property, error) { + if len(o.Parameters) == 0 { + return nil, nil + } + + fields := make([]Property, 0) + paramsTypeName := strcase.ToCamel(o.OperationId) + "Params" + for _, p := range o.Parameters { + if p.In == "path" || p.In == "header" { + continue + } + if p.Schema == nil { + return nil, fmt.Errorf("parameter %q has no schema", p.Name) + } + alias := p.Name + name := parameterFieldName(alias) + typeName, _ := b.genSchema(p.Schema, paramsTypeName+strcase.ToCamel(name)) + fields = append(fields, Property{ + Name: name, + SerializedName: alias, + Type: typeName, + Optional: p.Required == nil || !*p.Required, + Comment: parameterPropertyDoc(p.Schema.Schema()), + }) + } + return fields, nil +} + func (b *Builder) getSuccessResponseType(o *v3.Operation) (*string, error) { type responseInfo struct { content *v3.MediaType diff --git a/codegen/pkg/builder/out.go b/codegen/pkg/builder/out.go index 068f2b1f..ed2e7a68 100644 --- a/codegen/pkg/builder/out.go +++ b/codegen/pkg/builder/out.go @@ -102,6 +102,7 @@ func (b *Builder) generateResourceIndex(tagName string, resourceTypes []string) type resourceTemplateData struct { PackageName string TypeNames []string + InputTypeNames []string Params []Writable Service string Methods []*Method @@ -127,6 +128,7 @@ func (b *Builder) generateResourceFile(tagName string, paths *v3.Paths) ([]strin if err != nil { return nil, fmt.Errorf("convert paths to methods: %w", err) } + flattenMethodBodies(methods, bodyTypes) slog.Info("generating file", slog.String("tag", tag.Name), @@ -142,6 +144,7 @@ func (b *Builder) generateResourceFile(tagName string, paths *v3.Paths) ([]strin if err := b.templates.ExecuteTemplate(serviceBuf, "resource.py.tmpl", resourceTemplateData{ PackageName: strcase.ToSnake(tag.Name), TypeNames: typeNames, + InputTypeNames: inputTypeNames(typeNames), Params: innerTypes, Service: strcase.ToCamel(tag.Name), Methods: methods, @@ -168,6 +171,9 @@ func (b *Builder) generateResourceFile(tagName string, paths *v3.Paths) ([]strin resourceTypes := make([]string, 0, len(innerTypes)) for _, t := range innerTypes { if typ, ok := t.(Type); ok { + if writableRequestOnly(t) { + continue + } resourceTypes = append(resourceTypes, typ.TypeName()) } } @@ -175,6 +181,31 @@ func (b *Builder) generateResourceFile(tagName string, paths *v3.Paths) ([]strin return resourceTypes, nil } +func flattenMethodBodies(methods []*Method, bodyTypes []Writable) { + bodyClasses := make(map[string]*ClassDeclaration) + for _, writable := range bodyTypes { + class, ok := writable.(*ClassDeclaration) + if !ok { + continue + } + if len(class.Fields) == 0 || class.AdditionalPropertiesType != "" { + continue + } + bodyClasses[class.Name] = class + } + + for _, method := range methods { + if !method.HasBody { + continue + } + class, ok := bodyClasses[method.BodyType] + if !ok { + continue + } + method.BodyFields = append([]Property(nil), class.Fields...) + } +} + func (b *Builder) generateResource(tagName string, paths *v3.Paths) error { if tagName == "" { return fmt.Errorf("empty tag name") @@ -322,3 +353,24 @@ func (b *Builder) schemaTypeNamesByTag(tagName string) []string { slices.Sort(typeNames) return typeNames } + +func inputTypeNames(typeNames []string) []string { + res := make([]string, 0, len(typeNames)) + for _, name := range typeNames { + res = append(res, name+"Input") + } + return res +} + +func writableRequestOnly(w Writable) bool { + switch typed := w.(type) { + case *ClassDeclaration: + return typed.RequestOnly + case *TypeAlias: + return typed.RequestOnly + case *OneOfDeclaration: + return typed.RequestOnly + default: + return false + } +} diff --git a/codegen/pkg/builder/transform.go b/codegen/pkg/builder/transform.go index bf3e1858..1ab7e32f 100644 --- a/codegen/pkg/builder/transform.go +++ b/codegen/pkg/builder/transform.go @@ -43,6 +43,8 @@ func (b *Builder) pathsToBodyTypes(paths *v3.Paths) []Writable { if ok && mt.Schema != nil { name := operationName + "Body" bodyObject, additionalTypes := b.createObject(mt.Schema.Schema(), name) + markRequestTypes(additionalTypes) + markRequestType(bodyObject) paramTypes = append(paramTypes, additionalTypes...) paramTypes = append(paramTypes, bodyObject) } @@ -66,7 +68,6 @@ func (b *Builder) pathsToParamTypes(paths *v3.Paths) []Writable { operationName := strcase.ToCamel(opSpec.OperationId) if len(opSpec.Parameters) > 0 { - fields := make([]Property, 0) fieldTypes := make([]Writable, 0) paramsTypeName := operationName + "Params" for _, p := range opSpec.Parameters { @@ -77,29 +78,11 @@ func (b *Builder) pathsToParamTypes(paths *v3.Paths) []Writable { alias := p.Name name := parameterFieldName(alias) - typeName, types := b.genSchema(p.Schema, paramsTypeName+strcase.ToCamel(name)) + _, types := b.genSchema(p.Schema, paramsTypeName+strcase.ToCamel(name)) + markRequestTypes(types) fieldTypes = append(fieldTypes, types...) - - fields = append(fields, Property{ - Name: name, - SerializedName: alias, - Type: typeName, - Optional: p.Required == nil || !*p.Required, - Comment: parameterPropertyDoc(p.Schema.Schema()), - }) - } - - if len(fields) != 0 { - paramsTpl := ClassDeclaration{ - Type: "struct", - Name: paramsTypeName, - Description: operationParamsDoc(paramsTypeName, opSpec), - Fields: fields, - } - - paramTypes = append(paramTypes, fieldTypes...) - paramTypes = append(paramTypes, ¶msTpl) } + paramTypes = append(paramTypes, fieldTypes...) } } } @@ -107,6 +90,23 @@ func (b *Builder) pathsToParamTypes(paths *v3.Paths) []Writable { return paramTypes } +func markRequestTypes(types []Writable) { + for _, typ := range types { + markRequestType(typ) + } +} + +func markRequestType(typ Writable) { + switch t := typ.(type) { + case *ClassDeclaration: + t.RequestOnly = true + case *TypeAlias: + t.RequestOnly = true + case *OneOfDeclaration: + t.RequestOnly = true + } +} + func parameterFieldName(name string) string { name = strings.ReplaceAll(name, "[]", "") name = strings.ReplaceAll(name, ".", "_") diff --git a/codegen/pkg/builder/types.go b/codegen/pkg/builder/types.go index 3d9a79e5..5c64ce47 100644 --- a/codegen/pkg/builder/types.go +++ b/codegen/pkg/builder/types.go @@ -24,6 +24,43 @@ func indent(n int, s string) string { func (c *ClassDeclaration) String() string { buf := new(strings.Builder) + if c.RequestOnly { + if c.AdditionalPropertiesType != "" { + valueType := "typing.Any" + if len(c.Fields) == 0 { + valueType = inputTypeName(c.AdditionalPropertiesType) + } + fmt.Fprintf(buf, "%sInput = typing.Mapping[str, %s]\n", c.Name, valueType) + if c.Description != "" { + fmt.Fprintf(buf, "'''\n%s\n'''\n", c.Description) + } + return buf.String() + } + fmt.Fprintf(buf, "class %sInput(typing_extensions.TypedDict, total=False):\n", c.Name) + if c.Description != "" { + fmt.Fprintf(buf, "\t'''\n\t%s\n\t'''\n", c.Description) + } + if len(c.Fields) == 0 { + fmt.Fprint(buf, "\tpass\n") + } else { + fields := append([]Property(nil), c.Fields...) + slices.SortFunc(fields, func(a, b Property) int { + if a.Optional && !b.Optional { + return 1 + } + if b.Optional && !a.Optional { + return -1 + } + return strings.Compare(a.Name, b.Name) + }) + for _, ft := range fields { + fmt.Fprint(buf, "\n") + fmt.Fprint(buf, indent(1, ft.TypedDictFieldString())) + } + } + fmt.Fprint(buf, "\n") + return buf.String() + } fmt.Fprintf(buf, "class %s(pydantic.BaseModel):\n", c.Name) if c.Description != "" { fmt.Fprintf(buf, "\t'''\n\t%s\n\t'''\n", c.Description) @@ -76,6 +113,28 @@ func (c *ClassDeclaration) String() string { fmt.Fprint(buf, "\t\tobject.__setattr__(self, \"__pydantic_extra__\", dict(value))\n") } fmt.Fprint(buf, "\n") + fmt.Fprintf(buf, "class %sDict(typing_extensions.TypedDict, total=False):\n", c.Name) + if len(c.Fields) == 0 { + fmt.Fprint(buf, "\tpass\n") + } else { + fields := append([]Property(nil), c.Fields...) + slices.SortFunc(fields, func(a, b Property) int { + if a.Optional && !b.Optional { + return 1 + } + if b.Optional && !a.Optional { + return -1 + } + return strings.Compare(a.Name, b.Name) + }) + for _, ft := range fields { + fmt.Fprint(buf, "\n") + fmt.Fprint(buf, indent(1, ft.TypedDictFieldString())) + } + } + fmt.Fprint(buf, "\n") + fmt.Fprintf(buf, "%sInput = %sDict\n", c.Name, c.Name) + fmt.Fprint(buf, "\n") return buf.String() } @@ -85,9 +144,18 @@ func (c *ClassDeclaration) TypeName() string { func (o *OneOfDeclaration) String() string { buf := new(strings.Builder) + options := make([]string, 0, len(o.Options)) + for _, option := range o.Options { + options = append(options, inputTypeName(option)) + } + if o.RequestOnly { + fmt.Fprintf(buf, "%sInput = typing.Union[%s]", o.Name, strings.Join(options, ", ")) + return buf.String() + } fmt.Fprintf(buf, "%s = typing.Union[", o.Name) fmt.Fprint(buf, strings.Join(o.Options, ", ")) - fmt.Fprintf(buf, "]") + fmt.Fprintf(buf, "]\n") + fmt.Fprintf(buf, "%sInput = typing.Union[%s]", o.Name, strings.Join(options, ", ")) return buf.String() } @@ -123,6 +191,51 @@ func (p *Property) String() string { return buf.String() } +func (p Property) FieldName() string { + return pythonFieldName(p.Name) +} + +func (p Property) WireName() string { + if p.SerializedName != "" { + return p.SerializedName + } + return p.FieldName() +} + +func (p Property) MethodParameterString() string { + typeName := p.MethodParameterType() + if p.Optional { + return fmt.Sprintf("%s: typing.Union[%s, NotGivenType] = NOT_GIVEN", p.FieldName(), typeName) + } + + return fmt.Sprintf("%s: %s", p.FieldName(), typeName) +} + +func (p Property) MethodParameterType() string { + return inputTypeName(p.Type) +} + +func (p Property) BodyArgumentExpr() string { + name := p.FieldName() + if strings.HasPrefix(p.Type, "list[") { + return fmt.Sprintf("list(%s)", name) + } + + return name +} + +func (p Property) TypedDictFieldString() string { + typeName := inputTypeName(p.Type) + if p.Comment != "" { + typeName = fmt.Sprintf("typing_extensions.Annotated[%s, typing_extensions.Doc(%#v)]", typeName, p.Comment) + } + if p.Optional { + return fmt.Sprintf("%s: typing_extensions.NotRequired[%s]", p.FieldName(), typeName) + } + + return fmt.Sprintf("%s: typing_extensions.Required[%s]", p.FieldName(), typeName) +} + func (e *EnumDeclaration[E]) String() string { buf := new(strings.Builder) fmt.Fprintf(buf, "%s = typing.Union[typing.Literal[", e.Name) @@ -134,6 +247,7 @@ func (e *EnumDeclaration[E]) String() string { fmt.Fprintf(buf, "%#v", v) } fmt.Fprintf(buf, "], %s]\n", pythonEnumBaseType(e.Type)) + fmt.Fprintf(buf, "%sInput = %s\n", e.Name, e.Name) return buf.String() } @@ -170,3 +284,66 @@ func pythonEnumBaseType(typeName string) string { return "typing.Any" } } + +func inputTypeName(typeName string) string { + switch { + case strings.HasPrefix(typeName, "list[") && strings.HasSuffix(typeName, "]"): + return "typing.Sequence[" + inputTypeName(typeName[5:len(typeName)-1]) + "]" + case strings.HasPrefix(typeName, "typing.Sequence[") && strings.HasSuffix(typeName, "]"): + return "typing.Sequence[" + inputTypeName(typeName[len("typing.Sequence["):len(typeName)-1]) + "]" + case strings.HasPrefix(typeName, "dict[") && strings.HasSuffix(typeName, "]"): + args := splitTypeArgs(typeName[5 : len(typeName)-1]) + if len(args) == 2 { + return fmt.Sprintf("typing.Mapping[%s, %s]", args[0], inputTypeName(args[1])) + } + case strings.HasPrefix(typeName, "typing.Mapping["), + strings.HasPrefix(typeName, "typing.Literal["), + strings.HasPrefix(typeName, "typing.Any"), + strings.HasPrefix(typeName, "typing_extensions."): + return typeName + case strings.HasPrefix(typeName, "typing.Union[") && strings.HasSuffix(typeName, "]"): + args := splitTypeArgs(typeName[len("typing.Union[") : len(typeName)-1]) + for i := range args { + args[i] = inputTypeName(args[i]) + } + return "typing.Union[" + strings.Join(args, ", ") + "]" + case strings.HasPrefix(typeName, "typing.Optional[") && strings.HasSuffix(typeName, "]"): + return "typing.Optional[" + inputTypeName(typeName[len("typing.Optional["):len(typeName)-1]) + "]" + case isPrimitiveType(typeName): + return typeName + default: + return typeName + "Input" + } + + return typeName +} + +func isPrimitiveType(typeName string) bool { + switch typeName { + case "str", "int", "float", "bool", "object", "datetime.date", "datetime.datetime", "datetime.time", "Secret": + return true + default: + return false + } +} + +func splitTypeArgs(s string) []string { + args := make([]string, 0, 2) + start := 0 + depth := 0 + for i, r := range s { + switch r { + case '[': + depth++ + case ']': + depth-- + case ',': + if depth == 0 { + args = append(args, strings.TrimSpace(s[start:i])) + start = i + 1 + } + } + } + args = append(args, strings.TrimSpace(s[start:])) + return args +} diff --git a/codegen/templates/resource.py.tmpl b/codegen/templates/resource.py.tmpl index f1f334bf..564d2420 100644 --- a/codegen/templates/resource.py.tmpl +++ b/codegen/templates/resource.py.tmpl @@ -1,11 +1,12 @@ # Code generated by `py-sdk-gen`. DO NOT EDIT. +# ruff: noqa: F401, F541 {{- with .TagDescription }} """ {{ . }} """ {{- end }} from __future__ import annotations -from .._service import Resource, AsyncResource, HeaderTypes +from .._service import Resource, AsyncResource, HeaderTypes, NotGivenType, NOT_GIVEN, serialize_query_params, serialize_request_data from .._exceptions import APIError {{- if .UsesSecret }} from .._secret import Secret @@ -13,6 +14,9 @@ from .._secret import Secret {{- with .TypeNames }} from ..types import {{ join ", " . }} {{- end }} +{{- with .InputTypeNames }} +from ..types import {{ join ", " . }} +{{- end }} import datetime import httpx import typing @@ -40,13 +44,21 @@ class {{.Service}}Resource(Resource): ''' {{ indent 2 . }} ''' +{{- end }} +{{- if .HasFlattenedBody }} +{{ indent 2 .BodyInitString }} + +{{- end }} +{{- if .QueryFields }} +{{ indent 2 .QueryInitString }} + {{- end }} resp = self._client.{{.Method}}({{.Path}}, {{- if .HasBody }} - json=body.model_dump(exclude_unset=True), + json=serialize_request_data({{- if .HasFlattenedBody }}body_data{{- else }}body{{- end }}), {{- end }} -{{- with .QueryParams }} - params=params.model_dump(by_alias=True, exclude_none=True) if params else None, +{{- if .QueryFields }} + params=serialize_query_params(query_data) if query_data else None, {{- end }} headers=headers, ) @@ -90,13 +102,21 @@ class Async{{.Service}}Resource(AsyncResource): ''' {{ indent 2 . }} ''' +{{- end }} +{{- if .HasFlattenedBody }} +{{ indent 2 .BodyInitString }} + +{{- end }} +{{- if .QueryFields }} +{{ indent 2 .QueryInitString }} + {{- end }} resp = await self._client.{{.Method}}({{.Path}}, {{- if .HasBody }} - json=body.model_dump(exclude_unset=True), + json=serialize_request_data({{- if .HasFlattenedBody }}body_data{{- else }}body{{- end }}), {{- end }} -{{- with .QueryParams }} - params=params.model_dump(by_alias=True, exclude_none=True) if params else None, +{{- if .QueryFields }} + params=serialize_query_params(query_data) if query_data else None, {{- end }} headers=headers, ) diff --git a/codegen/templates/types.py.tmpl b/codegen/templates/types.py.tmpl index d2145934..11be376e 100644 --- a/codegen/templates/types.py.tmpl +++ b/codegen/templates/types.py.tmpl @@ -3,6 +3,7 @@ from __future__ import annotations import datetime import typing import pydantic +import typing_extensions {{- if .UsesSecret }} from .._secret import Secret {{- end }} diff --git a/examples/card_reader_checkout.py b/examples/card_reader_checkout.py index fdf1f901..4140fff1 100644 --- a/examples/card_reader_checkout.py +++ b/examples/card_reader_checkout.py @@ -2,7 +2,6 @@ import asyncio from sumup import AsyncSumup -from sumup.readers import CreateReaderCheckoutBody, CreateReaderCheckoutBodyTotalAmount async def main(): @@ -15,14 +14,8 @@ async def main(): checkout = await client.readers.create_checkout( merchant_code=merchant_code, reader_id=reader.id, - body=CreateReaderCheckoutBody( - total_amount=CreateReaderCheckoutBodyTotalAmount( - currency="EUR", - minor_unit=2, - value=1000, - ), - description="sumup-py card reader checkout example", - ), + total_amount={"currency": "EUR", "minor_unit": 2, "value": 1000}, + description="sumup-py card reader checkout example", ) print(checkout) diff --git a/examples/sync.py b/examples/sync.py index 500717ef..6a020e11 100644 --- a/examples/sync.py +++ b/examples/sync.py @@ -1,7 +1,6 @@ import os from sumup import Sumup, APIError -from sumup.checkouts import CreateCheckoutBody, ListCheckoutsParams client = Sumup() @@ -13,19 +12,17 @@ print(readers) transactions = client.checkouts.list( - params=ListCheckoutsParams(checkout_reference="1231"), + checkout_reference="1231", headers={"Foo": "Bar"}, ) print(transactions) try: checkout = client.checkouts.create( - body=CreateCheckoutBody( - merchant_code=merchant.merchant_code, - amount=100.50, - checkout_reference="unique-checkout-ref-123", - currency="EUR", - ) + merchant_code=merchant.merchant_code, + amount=100.50, + checkout_reference="unique-checkout-ref-123", + currency="EUR", ) print(checkout) except APIError as e: diff --git a/sumup/_service.py b/sumup/_service.py index 453b2f4b..de95d08e 100644 --- a/sumup/_service.py +++ b/sumup/_service.py @@ -1,13 +1,26 @@ +import datetime import httpx import platform import sys import typing from functools import lru_cache +from collections.abc import Mapping, Sequence from ._api_version import __api_version__ from ._version import __version__ +from ._secret import Secret HeaderTypes = typing.Mapping[str, str] +PrimitiveQueryValue = typing.Optional[typing.Union[str, int, float]] +QueryValue = typing.Union[PrimitiveQueryValue, typing.Sequence[PrimitiveQueryValue]] +QueryParamTypes = typing.Mapping[str, QueryValue] + + +class NotGivenType: + __slots__ = () + + +NOT_GIVEN = NotGivenType() class BaseResource: @@ -16,6 +29,22 @@ def version() -> str: return f"v{__version__}" +def serialize_request_data(value: object) -> object: + if isinstance(value, Secret): + return value.value() + if isinstance(value, (datetime.datetime, datetime.date, datetime.time)): + return value.isoformat() + if isinstance(value, Mapping): + return {str(key): serialize_request_data(item) for key, item in value.items()} + if isinstance(value, Sequence) and not isinstance(value, (str, bytes, bytearray)): + return [serialize_request_data(item) for item in value] + return value + + +def serialize_query_params(value: QueryParamTypes) -> QueryParamTypes: + return typing.cast(QueryParamTypes, serialize_request_data(value)) + + def runtime_headers() -> dict[str, str]: return dict(_runtime_headers()) diff --git a/sumup/checkouts/__init__.py b/sumup/checkouts/__init__.py index b8f1e1c2..ce12ea7b 100755 --- a/sumup/checkouts/__init__.py +++ b/sumup/checkouts/__init__.py @@ -3,12 +3,7 @@ CheckoutsResource, AsyncCheckoutsResource, CreateCheckoutBodyPurpose, - CreateCheckoutBody, ProcessCheckoutBodyPaymentType, - ProcessCheckoutBody, - CreateApplePaySessionBody, - GetPaymentMethodsParams, - ListCheckoutsParams, GetPaymentMethods200ResponseAvailablePaymentMethod, GetPaymentMethods200Response, ProcessCheckoutResponse, @@ -42,12 +37,7 @@ "CheckoutsResource", "AsyncCheckoutsResource", "CreateCheckoutBodyPurpose", - "CreateCheckoutBody", "ProcessCheckoutBodyPaymentType", - "ProcessCheckoutBody", - "CreateApplePaySessionBody", - "GetPaymentMethodsParams", - "ListCheckoutsParams", "GetPaymentMethods200ResponseAvailablePaymentMethod", "GetPaymentMethods200Response", "ProcessCheckoutResponse", diff --git a/sumup/checkouts/resource.py b/sumup/checkouts/resource.py index 94c62479..98252566 100755 --- a/sumup/checkouts/resource.py +++ b/sumup/checkouts/resource.py @@ -1,4 +1,5 @@ # Code generated by `py-sdk-gen`. DO NOT EDIT. +# ruff: noqa: F401, F541 """ Checkouts represent online payment sessions that you create before attempting to charge a payer. A checkout captures the payment intent, such as the amount, currency, merchant, and optional customer or redirect settings, and then moves through its lifecycle as you process it. @@ -17,186 +18,265 @@ """ from __future__ import annotations -from .._service import Resource, AsyncResource, HeaderTypes +from .._service import ( + Resource, + AsyncResource, + HeaderTypes, + NotGivenType, + NOT_GIVEN, + serialize_query_params, + serialize_request_data, +) from .._exceptions import APIError from ..types import ( + AddressLegacy, Card, + CardType, Checkout, CheckoutAccepted, + CheckoutCreateRequest, CheckoutSuccess, Currency, + DetailsError, + EntryMode, + Error, + ErrorExtended, + ErrorForbidden, MandatePayload, + MandateResponse, + PaymentType, PersonalDetails, + Problem, + ProcessCheckout, + TransactionBase, + TransactionCheckoutInfo, +) +from ..types import ( + AddressLegacyInput, + CardInput, + CardTypeInput, + CheckoutInput, + CheckoutAcceptedInput, + CheckoutCreateRequestInput, + CheckoutSuccessInput, + CurrencyInput, + DetailsErrorInput, + EntryModeInput, + ErrorInput, + ErrorExtendedInput, + ErrorForbiddenInput, + MandatePayloadInput, + MandateResponseInput, + PaymentTypeInput, + PersonalDetailsInput, + ProblemInput, + ProcessCheckoutInput, + TransactionBaseInput, + TransactionCheckoutInfoInput, ) import datetime import httpx import typing import pydantic +import typing_extensions CreateCheckoutBodyPurpose = typing.Union[typing.Literal["CHECKOUT", "SETUP_RECURRING_PAYMENT"], str] +CreateCheckoutBodyPurposeInput = CreateCheckoutBodyPurpose -class CreateCheckoutBody(pydantic.BaseModel): +class CreateCheckoutBodyInput(typing_extensions.TypedDict, total=False): """ Request body for creating a checkout before processing payment. Define the payment amount, currency, merchant,and optional customer or redirect behavior here. """ - amount: float - """ - Amount to be charged to the payer, expressed in major units. - """ - - checkout_reference: str - """ - Merchant-defined reference for the new checkout. It should be unique enough for you to identify the payment attemptin your own systems. - Max length: 90 - """ - - currency: Currency - """ - Three-letter [ISO4217](https://en.wikipedia.org/wiki/ISO_4217) code of the currency for the amount. Currently supportedcurrency values are enumerated above. - """ - - merchant_code: str - """ - Merchant account that should receive the payment. - """ - - customer_id: typing.Optional[str] = None - """ - Merchant-scoped customer identifier. Required when setting up recurring payments and useful when the checkoutshould be linked to a returning payer. - """ - - description: typing.Optional[str] = None - """ - Short merchant-defined description shown in SumUp tools and reporting for easier identification of the checkout. - """ - - purpose: typing.Optional[CreateCheckoutBodyPurpose] = None - """ - Business purpose of the checkout. Use `CHECKOUT` for a standard payment and `SETUP_RECURRING_PAYMENT` whencollecting consent and payment details for future recurring charges. - Default: "CHECKOUT" - """ - - redirect_url: typing.Optional[str] = None - """ - URL where the payer should be sent after a redirect-based payment or SCA flow completes. This is required for[APMs](https://developer.sumup.com/online-payments/apm/introduction) and recommended for card checkouts thatmay require [3DS](https://developer.sumup.com/online-payments/features/3ds). If it is omitted, the [Payment Widget](https://developer.sumup.com/online-payments/checkouts)can render the challenge in an iframe instead of using a full-page redirect. - """ - - return_url: typing.Optional[str] = None - """ - Optional backend callback URL used by SumUp to notify your platform about processing updates for the checkout. - Format:uri - """ - - valid_until: typing.Optional[datetime.datetime] = None - """ - Optional expiration timestamp. The checkout must be processed before this moment, otherwise it becomes unusable.If omitted, the checkout does not have an explicit expiry time. - """ + amount: typing_extensions.Required[ + typing_extensions.Annotated[ + float, + typing_extensions.Doc("Amount to be charged to the payer, expressed in major units."), + ] + ] + checkout_reference: typing_extensions.Required[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Merchant-defined reference for the new checkout. It should be unique enough for you to identify the payment attemptin your own systems.\nMax length: 90" + ), + ] + ] + currency: typing_extensions.Required[ + typing_extensions.Annotated[ + CurrencyInput, + typing_extensions.Doc( + "Three-letter [ISO4217](https://en.wikipedia.org/wiki/ISO_4217) code of the currency for the amount. Currently supportedcurrency values are enumerated above." + ), + ] + ] + merchant_code: typing_extensions.Required[ + typing_extensions.Annotated[ + str, typing_extensions.Doc("Merchant account that should receive the payment.") + ] + ] + customer_id: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Merchant-scoped customer identifier. Required when setting up recurring payments and useful when the checkoutshould be linked to a returning payer." + ), + ] + ] + description: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Short merchant-defined description shown in SumUp tools and reporting for easier identification of the checkout." + ), + ] + ] + purpose: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + CreateCheckoutBodyPurposeInput, + typing_extensions.Doc( + 'Business purpose of the checkout. Use `CHECKOUT` for a standard payment and `SETUP_RECURRING_PAYMENT` whencollecting consent and payment details for future recurring charges.\nDefault: "CHECKOUT"' + ), + ] + ] + redirect_url: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "URL where the payer should be sent after a redirect-based payment or SCA flow completes. This is required for[APMs](https://developer.sumup.com/online-payments/apm/introduction) and recommended for card checkouts thatmay require [3DS](https://developer.sumup.com/online-payments/features/3ds). If it is omitted, the [Payment Widget](https://developer.sumup.com/online-payments/checkouts)can render the challenge in an iframe instead of using a full-page redirect." + ), + ] + ] + return_url: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Optional backend callback URL used by SumUp to notify your platform about processing updates for the checkout.\nFormat:uri" + ), + ] + ] + valid_until: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + datetime.datetime, + typing_extensions.Doc( + "Optional expiration timestamp. The checkout must be processed before this moment, otherwise it becomes unusable.If omitted, the checkout does not have an explicit expiry time." + ), + ] + ] ProcessCheckoutBodyPaymentType = typing.Union[ typing.Literal["apple_pay", "bancontact", "blik", "boleto", "card", "google_pay", "ideal"], str ] +ProcessCheckoutBodyPaymentTypeInput = ProcessCheckoutBodyPaymentType -ProcessCheckoutBodyGooglePay = dict[str, object] +ProcessCheckoutBodyGooglePayInput = typing.Mapping[str, object] """ Raw `PaymentData` object received from Google Pay. Send the Google Pay response payload as-is. """ -ProcessCheckoutBodyApplePay = dict[str, object] +ProcessCheckoutBodyApplePayInput = typing.Mapping[str, object] """ Raw payment token object received from Apple Pay. Send the Apple Pay response payload as-is. """ -class ProcessCheckoutBody(pydantic.BaseModel): +class ProcessCheckoutBodyInput(typing_extensions.TypedDict, total=False): """ Request body for attempting payment on an existing checkout. The required companion fields depend on theselected `payment_type`, for example card details, saved-card data, or payer information required by aspecific payment method. """ - payment_type: ProcessCheckoutBodyPaymentType - """ - Payment method used for this processing attempt. It determines which additional request fields are required. - """ - - apple_pay: typing.Optional[ProcessCheckoutBodyApplePay] = None - """ - Raw payment token object received from Apple Pay. Send the Apple Pay response payload as-is. - """ - - card: typing.Optional[Card] = None - """ - __Required when payment type is `card`.__ Details of the payment card. - """ - - customer_id: typing.Optional[str] = None - """ - Customer identifier associated with the saved payment instrument. Required when `token` is provided. - """ - - google_pay: typing.Optional[ProcessCheckoutBodyGooglePay] = None - """ - Raw `PaymentData` object received from Google Pay. Send the Google Pay response payload as-is. - """ - - installments: typing.Optional[int] = None - """ - Number of installments for deferred payments. Available only to merchant users in Brazil. - Min: 1 - Max: 12 - """ - - mandate: typing.Optional[MandatePayload] = None - """ - Mandate details used when a checkout should create a reusable card token for future recurring or merchant-initiated payments. - """ - - personal_details: typing.Optional[PersonalDetails] = None - """ - Personal details for the customer. - """ - - token: typing.Optional[str] = None - """ - Saved-card token to use instead of raw card details when processing with a previously stored payment instrument. - """ - - -class CreateApplePaySessionBody(pydantic.BaseModel): + payment_type: typing_extensions.Required[ + typing_extensions.Annotated[ + ProcessCheckoutBodyPaymentTypeInput, + typing_extensions.Doc( + "Payment method used for this processing attempt. It determines which additional request fields are required." + ), + ] + ] + apple_pay: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + ProcessCheckoutBodyApplePayInput, + typing_extensions.Doc( + "Raw payment token object received from Apple Pay. Send the Apple Pay response payload as-is." + ), + ] + ] + card: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + CardInput, + typing_extensions.Doc( + "__Required when payment type is `card`.__ Details of the payment card." + ), + ] + ] + customer_id: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Customer identifier associated with the saved payment instrument. Required when `token` is provided." + ), + ] + ] + google_pay: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + ProcessCheckoutBodyGooglePayInput, + typing_extensions.Doc( + "Raw `PaymentData` object received from Google Pay. Send the Google Pay response payload as-is." + ), + ] + ] + installments: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + int, + typing_extensions.Doc( + "Number of installments for deferred payments. Available only to merchant users in Brazil.\nMin: 1\nMax: 12" + ), + ] + ] + mandate: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + MandatePayloadInput, + typing_extensions.Doc( + "Mandate details used when a checkout should create a reusable card token for future recurring or merchant-initiated payments." + ), + ] + ] + personal_details: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + PersonalDetailsInput, typing_extensions.Doc("Personal details for the customer.") + ] + ] + token: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Saved-card token to use instead of raw card details when processing with a previously stored payment instrument." + ), + ] + ] + + +class CreateApplePaySessionBodyInput(typing_extensions.TypedDict, total=False): """ CreateApplePaySessionBody is a schema definition. """ - context: str - """ - the context to create this apple pay session. - Format: hostname - """ - - target: str - """ - The target url to create this apple pay session. - Format: uri - """ - - -class GetPaymentMethodsParams(pydantic.BaseModel): - """ - GetPaymentMethodsParams: query parameters for GetPaymentMethods - """ - - amount: typing.Optional[float] = None - - currency: typing.Optional[str] = None - - -class ListCheckoutsParams(pydantic.BaseModel): - """ - ListCheckoutsParams: query parameters for ListCheckouts - """ - - checkout_reference: typing.Optional[str] = None + context: typing_extensions.Required[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "the context to create this apple pay session.\nFormat: hostname" + ), + ] + ] + target: typing_extensions.Required[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc("The target url to create this apple pay session.\nFormat: uri"), + ] + ] class GetPaymentMethods200ResponseAvailablePaymentMethod(pydantic.BaseModel): @@ -210,6 +290,19 @@ class GetPaymentMethods200ResponseAvailablePaymentMethod(pydantic.BaseModel): """ +class GetPaymentMethods200ResponseAvailablePaymentMethodDict( + typing_extensions.TypedDict, total=False +): + id: typing_extensions.Required[ + typing_extensions.Annotated[str, typing_extensions.Doc("The ID of the payment method.")] + ] + + +GetPaymentMethods200ResponseAvailablePaymentMethodInput = ( + GetPaymentMethods200ResponseAvailablePaymentMethodDict +) + + class GetPaymentMethods200Response(pydantic.BaseModel): """ GetPaymentMethods200Response is a schema definition. @@ -220,13 +313,25 @@ class GetPaymentMethods200Response(pydantic.BaseModel): ] = None +class GetPaymentMethods200ResponseDict(typing_extensions.TypedDict, total=False): + available_payment_methods: typing_extensions.NotRequired[ + typing.Sequence[GetPaymentMethods200ResponseAvailablePaymentMethodInput] + ] + + +GetPaymentMethods200ResponseInput = GetPaymentMethods200ResponseDict + + ListCheckouts200Response = list[CheckoutSuccess] +ListCheckouts200ResponseInput = typing.Sequence[CheckoutSuccessInput] """ ListCheckouts200Response is a schema definition. """ ProcessCheckoutResponse = typing.Union[CheckoutSuccess, CheckoutAccepted] +ProcessCheckoutResponseInput = typing.Union[CheckoutSuccessInput, CheckoutAcceptedInput] CreateApplePaySession200Response = dict[str, object] +CreateApplePaySession200ResponseInput = typing.Mapping[str, object] """ CreateApplePaySession200Response is a schema definition. """ @@ -241,7 +346,9 @@ def __init__(self, client: httpx.Client) -> None: def list_available_payment_methods( self, merchant_code: str, - params: typing.Optional[GetPaymentMethodsParams] = None, + *, + amount: typing.Union[float, NotGivenType] = NOT_GIVEN, + currency: typing.Union[str, NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> GetPaymentMethods200Response: """ @@ -249,9 +356,15 @@ def list_available_payment_methods( Get payment methods available for the given merchant to use with a checkout. """ + query_data: dict[str, typing.Any] = {} + if not isinstance(amount, NotGivenType) and amount is not None: + query_data["amount"] = amount + if not isinstance(currency, NotGivenType) and currency is not None: + query_data["currency"] = currency + resp = self._client.get( f"/v0.1/merchants/{merchant_code}/payment-methods", - params=params.model_dump(by_alias=True, exclude_none=True) if params else None, + params=serialize_query_params(query_data) if query_data else None, headers=headers, ) if resp.status_code == 200: @@ -263,10 +376,22 @@ def list_available_payment_methods( body=resp.text, ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) def create( - self, body: CreateCheckoutBody, headers: typing.Optional[HeaderTypes] = None + self, + *, + checkout_reference: str, + amount: float, + currency: CurrencyInput, + merchant_code: str, + description: typing.Union[str, NotGivenType] = NOT_GIVEN, + return_url: typing.Union[str, NotGivenType] = NOT_GIVEN, + customer_id: typing.Union[str, NotGivenType] = NOT_GIVEN, + purpose: typing.Union[CreateCheckoutBodyPurposeInput, NotGivenType] = NOT_GIVEN, + valid_until: typing.Union[datetime.datetime, NotGivenType] = NOT_GIVEN, + redirect_url: typing.Union[str, NotGivenType] = NOT_GIVEN, + headers: typing.Optional[HeaderTypes] = None, ) -> Checkout: """ Create a checkout @@ -277,9 +402,27 @@ def create( Follow by processing a checkout to charge the provided payment instrument. """ + body_data: dict[str, typing.Any] = {} + body_data["checkout_reference"] = checkout_reference + body_data["amount"] = amount + body_data["currency"] = currency + body_data["merchant_code"] = merchant_code + if not isinstance(description, NotGivenType): + body_data["description"] = description + if not isinstance(return_url, NotGivenType): + body_data["return_url"] = return_url + if not isinstance(customer_id, NotGivenType): + body_data["customer_id"] = customer_id + if not isinstance(purpose, NotGivenType): + body_data["purpose"] = purpose + if not isinstance(valid_until, NotGivenType): + body_data["valid_until"] = valid_until + if not isinstance(redirect_url, NotGivenType): + body_data["redirect_url"] = redirect_url + resp = self._client.post( - "/v0.1/checkouts", - json=body.model_dump(exclude_unset=True), + f"/v0.1/checkouts", + json=serialize_request_data(body_data), headers=headers, ) if resp.status_code == 201: @@ -303,11 +446,12 @@ def create( body=resp.text, ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) def list( self, - params: typing.Optional[ListCheckoutsParams] = None, + *, + checkout_reference: typing.Union[str, NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> ListCheckouts200Response: """ @@ -315,9 +459,13 @@ def list( Lists created checkout resources according to the applied `checkout_reference`. """ + query_data: dict[str, typing.Any] = {} + if not isinstance(checkout_reference, NotGivenType) and checkout_reference is not None: + query_data["checkout_reference"] = checkout_reference + resp = self._client.get( - "/v0.1/checkouts", - params=params.model_dump(by_alias=True, exclude_none=True) if params else None, + f"/v0.1/checkouts", + params=serialize_query_params(query_data) if query_data else None, headers=headers, ) if resp.status_code == 200: @@ -327,7 +475,7 @@ def list( "The request is not authorized.", status=resp.status_code, body=resp.text ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) def get(self, id: str, headers: typing.Optional[HeaderTypes] = None) -> CheckoutSuccess: """ @@ -350,10 +498,22 @@ def get(self, id: str, headers: typing.Optional[HeaderTypes] = None) -> Checkout "The requested resource does not exist.", status=resp.status_code, body=resp.text ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) def process( - self, id: str, body: ProcessCheckoutBody, headers: typing.Optional[HeaderTypes] = None + self, + id: str, + *, + payment_type: ProcessCheckoutBodyPaymentTypeInput, + installments: typing.Union[int, NotGivenType] = NOT_GIVEN, + mandate: typing.Union[MandatePayloadInput, NotGivenType] = NOT_GIVEN, + card: typing.Union[CardInput, NotGivenType] = NOT_GIVEN, + google_pay: typing.Union[ProcessCheckoutBodyGooglePayInput, NotGivenType] = NOT_GIVEN, + apple_pay: typing.Union[ProcessCheckoutBodyApplePayInput, NotGivenType] = NOT_GIVEN, + token: typing.Union[str, NotGivenType] = NOT_GIVEN, + customer_id: typing.Union[str, NotGivenType] = NOT_GIVEN, + personal_details: typing.Union[PersonalDetailsInput, NotGivenType] = NOT_GIVEN, + headers: typing.Optional[HeaderTypes] = None, ) -> ProcessCheckoutResponse: """ Process a checkout @@ -362,9 +522,28 @@ def process( Follow this request with `Retrieve a checkout` to confirm its status. """ + body_data: dict[str, typing.Any] = {} + body_data["payment_type"] = payment_type + if not isinstance(installments, NotGivenType): + body_data["installments"] = installments + if not isinstance(mandate, NotGivenType): + body_data["mandate"] = mandate + if not isinstance(card, NotGivenType): + body_data["card"] = card + if not isinstance(google_pay, NotGivenType): + body_data["google_pay"] = google_pay + if not isinstance(apple_pay, NotGivenType): + body_data["apple_pay"] = apple_pay + if not isinstance(token, NotGivenType): + body_data["token"] = token + if not isinstance(customer_id, NotGivenType): + body_data["customer_id"] = customer_id + if not isinstance(personal_details, NotGivenType): + body_data["personal_details"] = personal_details + resp = self._client.put( f"/v0.1/checkouts/{id}", - json=body.model_dump(exclude_unset=True), + json=serialize_request_data(body_data), headers=headers, ) if resp.status_code == 200: @@ -392,7 +571,7 @@ def process( body=resp.text, ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) def deactivate(self, id: str, headers: typing.Optional[HeaderTypes] = None) -> Checkout: """ @@ -421,10 +600,10 @@ def deactivate(self, id: str, headers: typing.Optional[HeaderTypes] = None) -> C body=resp.text, ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) def create_apple_pay_session( - self, id: str, body: CreateApplePaySessionBody, headers: typing.Optional[HeaderTypes] = None + self, id: str, *, context: str, target: str, headers: typing.Optional[HeaderTypes] = None ) -> CreateApplePaySession200Response: """ Create an Apple Pay session @@ -436,9 +615,13 @@ def create_apple_pay_session( SumUp validates the merchant session request and returns the Apple Pay session object that your frontend should pass to Apple's JavaScript API. """ + body_data: dict[str, typing.Any] = {} + body_data["context"] = context + body_data["target"] = target + resp = self._client.put( f"/v0.2/checkouts/{id}/apple-pay-session", - json=body.model_dump(exclude_unset=True), + json=serialize_request_data(body_data), headers=headers, ) if resp.status_code == 200: @@ -452,7 +635,7 @@ def create_apple_pay_session( "The requested resource does not exist.", status=resp.status_code, body=resp.text ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) class AsyncCheckoutsResource(AsyncResource): @@ -464,7 +647,9 @@ def __init__(self, client: httpx.AsyncClient) -> None: async def list_available_payment_methods( self, merchant_code: str, - params: typing.Optional[GetPaymentMethodsParams] = None, + *, + amount: typing.Union[float, NotGivenType] = NOT_GIVEN, + currency: typing.Union[str, NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> GetPaymentMethods200Response: """ @@ -472,9 +657,15 @@ async def list_available_payment_methods( Get payment methods available for the given merchant to use with a checkout. """ + query_data: dict[str, typing.Any] = {} + if not isinstance(amount, NotGivenType) and amount is not None: + query_data["amount"] = amount + if not isinstance(currency, NotGivenType) and currency is not None: + query_data["currency"] = currency + resp = await self._client.get( f"/v0.1/merchants/{merchant_code}/payment-methods", - params=params.model_dump(by_alias=True, exclude_none=True) if params else None, + params=serialize_query_params(query_data) if query_data else None, headers=headers, ) if resp.status_code == 200: @@ -486,10 +677,22 @@ async def list_available_payment_methods( body=resp.text, ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) async def create( - self, body: CreateCheckoutBody, headers: typing.Optional[HeaderTypes] = None + self, + *, + checkout_reference: str, + amount: float, + currency: CurrencyInput, + merchant_code: str, + description: typing.Union[str, NotGivenType] = NOT_GIVEN, + return_url: typing.Union[str, NotGivenType] = NOT_GIVEN, + customer_id: typing.Union[str, NotGivenType] = NOT_GIVEN, + purpose: typing.Union[CreateCheckoutBodyPurposeInput, NotGivenType] = NOT_GIVEN, + valid_until: typing.Union[datetime.datetime, NotGivenType] = NOT_GIVEN, + redirect_url: typing.Union[str, NotGivenType] = NOT_GIVEN, + headers: typing.Optional[HeaderTypes] = None, ) -> Checkout: """ Create a checkout @@ -500,9 +703,27 @@ async def create( Follow by processing a checkout to charge the provided payment instrument. """ + body_data: dict[str, typing.Any] = {} + body_data["checkout_reference"] = checkout_reference + body_data["amount"] = amount + body_data["currency"] = currency + body_data["merchant_code"] = merchant_code + if not isinstance(description, NotGivenType): + body_data["description"] = description + if not isinstance(return_url, NotGivenType): + body_data["return_url"] = return_url + if not isinstance(customer_id, NotGivenType): + body_data["customer_id"] = customer_id + if not isinstance(purpose, NotGivenType): + body_data["purpose"] = purpose + if not isinstance(valid_until, NotGivenType): + body_data["valid_until"] = valid_until + if not isinstance(redirect_url, NotGivenType): + body_data["redirect_url"] = redirect_url + resp = await self._client.post( - "/v0.1/checkouts", - json=body.model_dump(exclude_unset=True), + f"/v0.1/checkouts", + json=serialize_request_data(body_data), headers=headers, ) if resp.status_code == 201: @@ -526,11 +747,12 @@ async def create( body=resp.text, ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) async def list( self, - params: typing.Optional[ListCheckoutsParams] = None, + *, + checkout_reference: typing.Union[str, NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> ListCheckouts200Response: """ @@ -538,9 +760,13 @@ async def list( Lists created checkout resources according to the applied `checkout_reference`. """ + query_data: dict[str, typing.Any] = {} + if not isinstance(checkout_reference, NotGivenType) and checkout_reference is not None: + query_data["checkout_reference"] = checkout_reference + resp = await self._client.get( - "/v0.1/checkouts", - params=params.model_dump(by_alias=True, exclude_none=True) if params else None, + f"/v0.1/checkouts", + params=serialize_query_params(query_data) if query_data else None, headers=headers, ) if resp.status_code == 200: @@ -550,7 +776,7 @@ async def list( "The request is not authorized.", status=resp.status_code, body=resp.text ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) async def get(self, id: str, headers: typing.Optional[HeaderTypes] = None) -> CheckoutSuccess: """ @@ -573,10 +799,22 @@ async def get(self, id: str, headers: typing.Optional[HeaderTypes] = None) -> Ch "The requested resource does not exist.", status=resp.status_code, body=resp.text ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) async def process( - self, id: str, body: ProcessCheckoutBody, headers: typing.Optional[HeaderTypes] = None + self, + id: str, + *, + payment_type: ProcessCheckoutBodyPaymentTypeInput, + installments: typing.Union[int, NotGivenType] = NOT_GIVEN, + mandate: typing.Union[MandatePayloadInput, NotGivenType] = NOT_GIVEN, + card: typing.Union[CardInput, NotGivenType] = NOT_GIVEN, + google_pay: typing.Union[ProcessCheckoutBodyGooglePayInput, NotGivenType] = NOT_GIVEN, + apple_pay: typing.Union[ProcessCheckoutBodyApplePayInput, NotGivenType] = NOT_GIVEN, + token: typing.Union[str, NotGivenType] = NOT_GIVEN, + customer_id: typing.Union[str, NotGivenType] = NOT_GIVEN, + personal_details: typing.Union[PersonalDetailsInput, NotGivenType] = NOT_GIVEN, + headers: typing.Optional[HeaderTypes] = None, ) -> ProcessCheckoutResponse: """ Process a checkout @@ -585,9 +823,28 @@ async def process( Follow this request with `Retrieve a checkout` to confirm its status. """ + body_data: dict[str, typing.Any] = {} + body_data["payment_type"] = payment_type + if not isinstance(installments, NotGivenType): + body_data["installments"] = installments + if not isinstance(mandate, NotGivenType): + body_data["mandate"] = mandate + if not isinstance(card, NotGivenType): + body_data["card"] = card + if not isinstance(google_pay, NotGivenType): + body_data["google_pay"] = google_pay + if not isinstance(apple_pay, NotGivenType): + body_data["apple_pay"] = apple_pay + if not isinstance(token, NotGivenType): + body_data["token"] = token + if not isinstance(customer_id, NotGivenType): + body_data["customer_id"] = customer_id + if not isinstance(personal_details, NotGivenType): + body_data["personal_details"] = personal_details + resp = await self._client.put( f"/v0.1/checkouts/{id}", - json=body.model_dump(exclude_unset=True), + json=serialize_request_data(body_data), headers=headers, ) if resp.status_code == 200: @@ -615,7 +872,7 @@ async def process( body=resp.text, ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) async def deactivate(self, id: str, headers: typing.Optional[HeaderTypes] = None) -> Checkout: """ @@ -644,10 +901,10 @@ async def deactivate(self, id: str, headers: typing.Optional[HeaderTypes] = None body=resp.text, ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) async def create_apple_pay_session( - self, id: str, body: CreateApplePaySessionBody, headers: typing.Optional[HeaderTypes] = None + self, id: str, *, context: str, target: str, headers: typing.Optional[HeaderTypes] = None ) -> CreateApplePaySession200Response: """ Create an Apple Pay session @@ -659,9 +916,13 @@ async def create_apple_pay_session( SumUp validates the merchant session request and returns the Apple Pay session object that your frontend should pass to Apple's JavaScript API. """ + body_data: dict[str, typing.Any] = {} + body_data["context"] = context + body_data["target"] = target + resp = await self._client.put( f"/v0.2/checkouts/{id}/apple-pay-session", - json=body.model_dump(exclude_unset=True), + json=serialize_request_data(body_data), headers=headers, ) if resp.status_code == 200: @@ -675,4 +936,4 @@ async def create_apple_pay_session( "The requested resource does not exist.", status=resp.status_code, body=resp.text ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) diff --git a/sumup/customers/__init__.py b/sumup/customers/__init__.py index f2e36468..e530c1cd 100755 --- a/sumup/customers/__init__.py +++ b/sumup/customers/__init__.py @@ -2,8 +2,6 @@ from .resource import ( CustomersResource, AsyncCustomersResource, - CreateCustomerBody, - UpdateCustomerBody, ) from ..types import ( AddressLegacy, @@ -22,8 +20,6 @@ __all__ = [ "CustomersResource", "AsyncCustomersResource", - "CreateCustomerBody", - "UpdateCustomerBody", "AddressLegacy", "CardType", "Customer", diff --git a/sumup/customers/resource.py b/sumup/customers/resource.py index ba4e7310..39a0828a 100755 --- a/sumup/customers/resource.py +++ b/sumup/customers/resource.py @@ -1,4 +1,5 @@ # Code generated by `py-sdk-gen`. DO NOT EDIT. +# ruff: noqa: F401, F541 """ Allow your regular customers to save their information with the Customers model. @@ -8,46 +9,76 @@ """ from __future__ import annotations -from .._service import Resource, AsyncResource, HeaderTypes +from .._service import ( + Resource, + AsyncResource, + HeaderTypes, + NotGivenType, + NOT_GIVEN, + serialize_query_params, + serialize_request_data, +) from .._exceptions import APIError from ..types import ( + AddressLegacy, + CardType, Customer, + Error, + ErrorExtended, + ErrorForbidden, + MandateResponse, PaymentInstrumentResponse, PersonalDetails, + Problem, +) +from ..types import ( + AddressLegacyInput, + CardTypeInput, + CustomerInput, + ErrorInput, + ErrorExtendedInput, + ErrorForbiddenInput, + MandateResponseInput, + PaymentInstrumentResponseInput, + PersonalDetailsInput, + ProblemInput, ) +import datetime import httpx import typing import pydantic +import typing_extensions -class CreateCustomerBody(pydantic.BaseModel): +class CreateCustomerBodyInput(typing_extensions.TypedDict, total=False): """ Saved customer details. """ - customer_id: str - """ - Unique ID of the customer. - """ + customer_id: typing_extensions.Required[ + typing_extensions.Annotated[str, typing_extensions.Doc("Unique ID of the customer.")] + ] + personal_details: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + PersonalDetailsInput, typing_extensions.Doc("Personal details for the customer.") + ] + ] - personal_details: typing.Optional[PersonalDetails] = None - """ - Personal details for the customer. - """ - -class UpdateCustomerBody(pydantic.BaseModel): +class UpdateCustomerBodyInput(typing_extensions.TypedDict, total=False): """ UpdateCustomerBody is a schema definition. """ - personal_details: typing.Optional[PersonalDetails] = None - """ - Personal details for the customer. - """ + personal_details: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + PersonalDetailsInput, typing_extensions.Doc("Personal details for the customer.") + ] + ] ListPaymentInstruments200Response = list[PaymentInstrumentResponse] +ListPaymentInstruments200ResponseInput = typing.Sequence[PaymentInstrumentResponseInput] """ ListPaymentInstruments200Response is a schema definition. """ @@ -60,16 +91,25 @@ def __init__(self, client: httpx.Client) -> None: super().__init__(client) def create( - self, body: CreateCustomerBody, headers: typing.Optional[HeaderTypes] = None + self, + *, + customer_id: str, + personal_details: typing.Union[PersonalDetailsInput, NotGivenType] = NOT_GIVEN, + headers: typing.Optional[HeaderTypes] = None, ) -> Customer: """ Create a customer Creates a new saved customer resource which you can later manipulate and save payment instruments to. """ + body_data: dict[str, typing.Any] = {} + body_data["customer_id"] = customer_id + if not isinstance(personal_details, NotGivenType): + body_data["personal_details"] = personal_details + resp = self._client.post( - "/v0.1/customers", - json=body.model_dump(exclude_unset=True), + f"/v0.1/customers", + json=serialize_request_data(body_data), headers=headers, ) if resp.status_code == 201: @@ -93,7 +133,7 @@ def create( body=resp.text, ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) def get(self, customer_id: str, headers: typing.Optional[HeaderTypes] = None) -> Customer: """ @@ -122,12 +162,13 @@ def get(self, customer_id: str, headers: typing.Optional[HeaderTypes] = None) -> "The requested resource does not exist.", status=resp.status_code, body=resp.text ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) def update( self, customer_id: str, - body: UpdateCustomerBody, + *, + personal_details: typing.Union[PersonalDetailsInput, NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> Customer: """ @@ -137,9 +178,13 @@ def update( The request only overwrites the parameters included in the request, all other parameters will remain with theirinitially assigned values. """ + body_data: dict[str, typing.Any] = {} + if not isinstance(personal_details, NotGivenType): + body_data["personal_details"] = personal_details + resp = self._client.put( f"/v0.1/customers/{customer_id}", - json=body.model_dump(exclude_unset=True), + json=serialize_request_data(body_data), headers=headers, ) if resp.status_code == 200: @@ -159,7 +204,7 @@ def update( "The requested resource does not exist.", status=resp.status_code, body=resp.text ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) def list_payment_instruments( self, customer_id: str, headers: typing.Optional[HeaderTypes] = None @@ -192,7 +237,7 @@ def list_payment_instruments( "The requested resource does not exist.", status=resp.status_code, body=resp.text ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) def deactivate_payment_instrument( self, customer_id: str, token: str, headers: typing.Optional[HeaderTypes] = None @@ -225,7 +270,7 @@ def deactivate_payment_instrument( "The requested resource does not exist.", status=resp.status_code, body=resp.text ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) class AsyncCustomersResource(AsyncResource): @@ -235,16 +280,25 @@ def __init__(self, client: httpx.AsyncClient) -> None: super().__init__(client) async def create( - self, body: CreateCustomerBody, headers: typing.Optional[HeaderTypes] = None + self, + *, + customer_id: str, + personal_details: typing.Union[PersonalDetailsInput, NotGivenType] = NOT_GIVEN, + headers: typing.Optional[HeaderTypes] = None, ) -> Customer: """ Create a customer Creates a new saved customer resource which you can later manipulate and save payment instruments to. """ + body_data: dict[str, typing.Any] = {} + body_data["customer_id"] = customer_id + if not isinstance(personal_details, NotGivenType): + body_data["personal_details"] = personal_details + resp = await self._client.post( - "/v0.1/customers", - json=body.model_dump(exclude_unset=True), + f"/v0.1/customers", + json=serialize_request_data(body_data), headers=headers, ) if resp.status_code == 201: @@ -268,7 +322,7 @@ async def create( body=resp.text, ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) async def get(self, customer_id: str, headers: typing.Optional[HeaderTypes] = None) -> Customer: """ @@ -297,12 +351,13 @@ async def get(self, customer_id: str, headers: typing.Optional[HeaderTypes] = No "The requested resource does not exist.", status=resp.status_code, body=resp.text ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) async def update( self, customer_id: str, - body: UpdateCustomerBody, + *, + personal_details: typing.Union[PersonalDetailsInput, NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> Customer: """ @@ -312,9 +367,13 @@ async def update( The request only overwrites the parameters included in the request, all other parameters will remain with theirinitially assigned values. """ + body_data: dict[str, typing.Any] = {} + if not isinstance(personal_details, NotGivenType): + body_data["personal_details"] = personal_details + resp = await self._client.put( f"/v0.1/customers/{customer_id}", - json=body.model_dump(exclude_unset=True), + json=serialize_request_data(body_data), headers=headers, ) if resp.status_code == 200: @@ -334,7 +393,7 @@ async def update( "The requested resource does not exist.", status=resp.status_code, body=resp.text ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) async def list_payment_instruments( self, customer_id: str, headers: typing.Optional[HeaderTypes] = None @@ -367,7 +426,7 @@ async def list_payment_instruments( "The requested resource does not exist.", status=resp.status_code, body=resp.text ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) async def deactivate_payment_instrument( self, customer_id: str, token: str, headers: typing.Optional[HeaderTypes] = None @@ -400,4 +459,4 @@ async def deactivate_payment_instrument( "The requested resource does not exist.", status=resp.status_code, body=resp.text ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) diff --git a/sumup/members/__init__.py b/sumup/members/__init__.py index 0b9d7496..152cad86 100755 --- a/sumup/members/__init__.py +++ b/sumup/members/__init__.py @@ -2,10 +2,6 @@ from .resource import ( MembersResource, AsyncMembersResource, - CreateMerchantMemberBody, - UpdateMerchantMemberBodyUser, - UpdateMerchantMemberBody, - ListMerchantMembersParams, ListMerchantMembers200Response, ) from ..types import ( @@ -23,10 +19,6 @@ __all__ = [ "MembersResource", "AsyncMembersResource", - "CreateMerchantMemberBody", - "UpdateMerchantMemberBodyUser", - "UpdateMerchantMemberBody", - "ListMerchantMembersParams", "ListMerchantMembers200Response", "Attributes", "Invite", diff --git a/sumup/members/resource.py b/sumup/members/resource.py index 16e1905b..b3ae8a23 100755 --- a/sumup/members/resource.py +++ b/sumup/members/resource.py @@ -1,135 +1,154 @@ # Code generated by `py-sdk-gen`. DO NOT EDIT. +# ruff: noqa: F401, F541 """ Endpoints to manage account members. Members are users that have membership within merchant accounts. """ from __future__ import annotations -from .._service import Resource, AsyncResource, HeaderTypes +from .._service import ( + Resource, + AsyncResource, + HeaderTypes, + NotGivenType, + NOT_GIVEN, + serialize_query_params, + serialize_request_data, +) from .._exceptions import APIError from .._secret import Secret from ..types import ( Attributes, + Invite, Member, MembershipStatus, + MembershipUser, + MembershipUserClassic, Metadata, + Problem, +) +from ..types import ( + AttributesInput, + InviteInput, + MemberInput, + MembershipStatusInput, + MembershipUserInput, + MembershipUserClassicInput, + MetadataInput, + ProblemInput, ) +import datetime import httpx import typing import pydantic +import typing_extensions -class CreateMerchantMemberBody(pydantic.BaseModel): +class CreateMerchantMemberBodyInput(typing_extensions.TypedDict, total=False): """ CreateMerchantMemberBody is a schema definition. """ - email: str - """ - Email address of the member to add. - Format: email - """ - - roles: list[str] - """ - List of roles to assign to the new member. - """ - - attributes: typing.Optional[Attributes] = None - """ - Object attributes that are modifiable only by SumUp applications. - """ - - is_managed_user: typing.Optional[bool] = None - """ - True if the user is managed by the merchant. In this case, we'll created a virtual user with the provided passwordand nickname. - """ - - metadata: typing.Optional[Metadata] = None - """ - Set of user-defined key-value pairs attached to the object. Partial updates are not supported. When updating, alwayssubmit whole metadata. Maximum of 64 parameters are allowed in the object. - Max properties: 64 - """ - - nickname: typing.Optional[str] = None - """ - Nickname of the member to add. Only used if `is_managed_user` is true. Used for display purposes only. - """ - - password: typing.Optional[Secret] = None - """ - Password of the member to add. Only used if `is_managed_user` is true. In the case of service accounts, thepassword is not used and can not be defined by the caller. - Format: password - Min length: 8 - """ - - -class UpdateMerchantMemberBodyUser(pydantic.BaseModel): + email: typing_extensions.Required[ + typing_extensions.Annotated[ + str, typing_extensions.Doc("Email address of the member to add.\nFormat: email") + ] + ] + roles: typing_extensions.Required[ + typing_extensions.Annotated[ + typing.Sequence[str], + typing_extensions.Doc("List of roles to assign to the new member."), + ] + ] + attributes: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + AttributesInput, + typing_extensions.Doc( + "Object attributes that are modifiable only by SumUp applications." + ), + ] + ] + is_managed_user: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + bool, + typing_extensions.Doc( + "True if the user is managed by the merchant. In this case, we'll created a virtual user with the provided passwordand nickname." + ), + ] + ] + metadata: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + MetadataInput, + typing_extensions.Doc( + "Set of user-defined key-value pairs attached to the object. Partial updates are not supported. When updating, alwayssubmit whole metadata. Maximum of 64 parameters are allowed in the object.\nMax properties: 64" + ), + ] + ] + nickname: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Nickname of the member to add. Only used if `is_managed_user` is true. Used for display purposes only." + ), + ] + ] + password: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + Secret, + typing_extensions.Doc( + "Password of the member to add. Only used if `is_managed_user` is true. In the case of service accounts, thepassword is not used and can not be defined by the caller.\nFormat: password\nMin length: 8" + ), + ] + ] + + +class UpdateMerchantMemberBodyUserInput(typing_extensions.TypedDict, total=False): """ Allows you to update user data of managed users. """ - nickname: typing.Optional[str] = None - """ - User's preferred name. Used for display purposes only. - """ - - password: typing.Optional[Secret] = None - """ - Password of the member to add. Only used if `is_managed_user` is true. - Format: password - Min length: 8 - """ - - -class UpdateMerchantMemberBody(pydantic.BaseModel): + nickname: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, typing_extensions.Doc("User's preferred name. Used for display purposes only.") + ] + ] + password: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + Secret, + typing_extensions.Doc( + "Password of the member to add. Only used if `is_managed_user` is true.\nFormat: password\nMin length: 8" + ), + ] + ] + + +class UpdateMerchantMemberBodyInput(typing_extensions.TypedDict, total=False): """ UpdateMerchantMemberBody is a schema definition. """ - attributes: typing.Optional[Attributes] = None - """ - Object attributes that are modifiable only by SumUp applications. - """ - - metadata: typing.Optional[Metadata] = None - """ - Set of user-defined key-value pairs attached to the object. Partial updates are not supported. When updating, alwayssubmit whole metadata. Maximum of 64 parameters are allowed in the object. - Max properties: 64 - """ - - roles: typing.Optional[list[str]] = None - - user: typing.Optional[UpdateMerchantMemberBodyUser] = None - """ - Allows you to update user data of managed users. - """ - - -class ListMerchantMembersParams(pydantic.BaseModel): - """ - ListMerchantMembersParams: query parameters for ListMerchantMembers - """ - - email: typing.Optional[str] = None - - limit: typing.Optional[int] = None - - offset: typing.Optional[int] = None - - roles: typing.Optional[list[str]] = None - - scroll: typing.Optional[bool] = None - - status: typing.Optional[MembershipStatus] = None - """ - The status of the membership. - """ - - user_id: typing.Optional[str] = pydantic.Field( - default=None, - serialization_alias="user.id", - validation_alias=pydantic.AliasChoices("user.id", "user_id"), - ) + attributes: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + AttributesInput, + typing_extensions.Doc( + "Object attributes that are modifiable only by SumUp applications." + ), + ] + ] + metadata: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + MetadataInput, + typing_extensions.Doc( + "Set of user-defined key-value pairs attached to the object. Partial updates are not supported. When updating, alwayssubmit whole metadata. Maximum of 64 parameters are allowed in the object.\nMax properties: 64" + ), + ] + ] + roles: typing_extensions.NotRequired[typing.Sequence[str]] + user: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + UpdateMerchantMemberBodyUserInput, + typing_extensions.Doc("Allows you to update user data of managed users."), + ] + ] class ListMerchantMembers200Response(pydantic.BaseModel): @@ -142,6 +161,14 @@ class ListMerchantMembers200Response(pydantic.BaseModel): total_count: typing.Optional[int] = None +class ListMerchantMembers200ResponseDict(typing_extensions.TypedDict, total=False): + items: typing_extensions.Required[typing.Sequence[MemberInput]] + total_count: typing_extensions.NotRequired[int] + + +ListMerchantMembers200ResponseInput = ListMerchantMembers200ResponseDict + + class MembersResource(Resource): """API resource for the Members endpoints.""" @@ -151,7 +178,14 @@ def __init__(self, client: httpx.Client) -> None: def list( self, merchant_code: str, - params: typing.Optional[ListMerchantMembersParams] = None, + *, + offset: typing.Union[int, NotGivenType] = NOT_GIVEN, + limit: typing.Union[int, NotGivenType] = NOT_GIVEN, + scroll: typing.Union[bool, NotGivenType] = NOT_GIVEN, + email: typing.Union[str, NotGivenType] = NOT_GIVEN, + user_id: typing.Union[str, NotGivenType] = NOT_GIVEN, + status: typing.Union[MembershipStatusInput, NotGivenType] = NOT_GIVEN, + roles: typing.Union[typing.Sequence[str], NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> ListMerchantMembers200Response: """ @@ -159,9 +193,25 @@ def list( Lists merchant members. """ + query_data: dict[str, typing.Any] = {} + if not isinstance(offset, NotGivenType) and offset is not None: + query_data["offset"] = offset + if not isinstance(limit, NotGivenType) and limit is not None: + query_data["limit"] = limit + if not isinstance(scroll, NotGivenType) and scroll is not None: + query_data["scroll"] = scroll + if not isinstance(email, NotGivenType) and email is not None: + query_data["email"] = email + if not isinstance(user_id, NotGivenType) and user_id is not None: + query_data["user.id"] = user_id + if not isinstance(status, NotGivenType) and status is not None: + query_data["status"] = status + if not isinstance(roles, NotGivenType) and roles is not None: + query_data["roles"] = list(roles) + resp = self._client.get( f"/v0.1/merchants/{merchant_code}/members", - params=params.model_dump(by_alias=True, exclude_none=True) if params else None, + params=serialize_query_params(query_data) if query_data else None, headers=headers, ) if resp.status_code == 200: @@ -169,12 +219,19 @@ def list( elif resp.status_code == 404: raise APIError("Merchant not found.", status=resp.status_code, body=resp.text) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) def create( self, merchant_code: str, - body: CreateMerchantMemberBody, + *, + is_managed_user: typing.Union[bool, NotGivenType] = NOT_GIVEN, + email: str, + password: typing.Union[Secret, NotGivenType] = NOT_GIVEN, + nickname: typing.Union[str, NotGivenType] = NOT_GIVEN, + roles: typing.Sequence[str], + metadata: typing.Union[MetadataInput, NotGivenType] = NOT_GIVEN, + attributes: typing.Union[AttributesInput, NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> Member: """ @@ -182,9 +239,23 @@ def create( Create a merchant member. """ + body_data: dict[str, typing.Any] = {} + if not isinstance(is_managed_user, NotGivenType): + body_data["is_managed_user"] = is_managed_user + body_data["email"] = email + if not isinstance(password, NotGivenType): + body_data["password"] = password + if not isinstance(nickname, NotGivenType): + body_data["nickname"] = nickname + body_data["roles"] = list(roles) + if not isinstance(metadata, NotGivenType): + body_data["metadata"] = metadata + if not isinstance(attributes, NotGivenType): + body_data["attributes"] = attributes + resp = self._client.post( f"/v0.1/merchants/{merchant_code}/members", - json=body.model_dump(exclude_unset=True), + json=serialize_request_data(body_data), headers=headers, ) if resp.status_code == 201: @@ -200,7 +271,7 @@ def create( body=resp.text, ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) def get( self, merchant_code: str, member_id: str, headers: typing.Optional[HeaderTypes] = None @@ -219,13 +290,17 @@ def get( elif resp.status_code == 404: raise APIError("Merchant or member not found.", status=resp.status_code, body=resp.text) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) def update( self, merchant_code: str, member_id: str, - body: UpdateMerchantMemberBody, + *, + roles: typing.Union[typing.Sequence[str], NotGivenType] = NOT_GIVEN, + metadata: typing.Union[MetadataInput, NotGivenType] = NOT_GIVEN, + attributes: typing.Union[AttributesInput, NotGivenType] = NOT_GIVEN, + user: typing.Union[UpdateMerchantMemberBodyUserInput, NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> Member: """ @@ -233,9 +308,19 @@ def update( Update the merchant member. """ + body_data: dict[str, typing.Any] = {} + if not isinstance(roles, NotGivenType): + body_data["roles"] = list(roles) + if not isinstance(metadata, NotGivenType): + body_data["metadata"] = metadata + if not isinstance(attributes, NotGivenType): + body_data["attributes"] = attributes + if not isinstance(user, NotGivenType): + body_data["user"] = user + resp = self._client.put( f"/v0.1/merchants/{merchant_code}/members/{member_id}", - json=body.model_dump(exclude_unset=True), + json=serialize_request_data(body_data), headers=headers, ) if resp.status_code == 200: @@ -261,7 +346,7 @@ def update( body=resp.text, ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) def delete( self, merchant_code: str, member_id: str, headers: typing.Optional[HeaderTypes] = None @@ -280,7 +365,7 @@ def delete( elif resp.status_code == 404: raise APIError("Merchant or member not found.", status=resp.status_code, body=resp.text) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) class AsyncMembersResource(AsyncResource): @@ -292,7 +377,14 @@ def __init__(self, client: httpx.AsyncClient) -> None: async def list( self, merchant_code: str, - params: typing.Optional[ListMerchantMembersParams] = None, + *, + offset: typing.Union[int, NotGivenType] = NOT_GIVEN, + limit: typing.Union[int, NotGivenType] = NOT_GIVEN, + scroll: typing.Union[bool, NotGivenType] = NOT_GIVEN, + email: typing.Union[str, NotGivenType] = NOT_GIVEN, + user_id: typing.Union[str, NotGivenType] = NOT_GIVEN, + status: typing.Union[MembershipStatusInput, NotGivenType] = NOT_GIVEN, + roles: typing.Union[typing.Sequence[str], NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> ListMerchantMembers200Response: """ @@ -300,9 +392,25 @@ async def list( Lists merchant members. """ + query_data: dict[str, typing.Any] = {} + if not isinstance(offset, NotGivenType) and offset is not None: + query_data["offset"] = offset + if not isinstance(limit, NotGivenType) and limit is not None: + query_data["limit"] = limit + if not isinstance(scroll, NotGivenType) and scroll is not None: + query_data["scroll"] = scroll + if not isinstance(email, NotGivenType) and email is not None: + query_data["email"] = email + if not isinstance(user_id, NotGivenType) and user_id is not None: + query_data["user.id"] = user_id + if not isinstance(status, NotGivenType) and status is not None: + query_data["status"] = status + if not isinstance(roles, NotGivenType) and roles is not None: + query_data["roles"] = list(roles) + resp = await self._client.get( f"/v0.1/merchants/{merchant_code}/members", - params=params.model_dump(by_alias=True, exclude_none=True) if params else None, + params=serialize_query_params(query_data) if query_data else None, headers=headers, ) if resp.status_code == 200: @@ -310,12 +418,19 @@ async def list( elif resp.status_code == 404: raise APIError("Merchant not found.", status=resp.status_code, body=resp.text) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) async def create( self, merchant_code: str, - body: CreateMerchantMemberBody, + *, + is_managed_user: typing.Union[bool, NotGivenType] = NOT_GIVEN, + email: str, + password: typing.Union[Secret, NotGivenType] = NOT_GIVEN, + nickname: typing.Union[str, NotGivenType] = NOT_GIVEN, + roles: typing.Sequence[str], + metadata: typing.Union[MetadataInput, NotGivenType] = NOT_GIVEN, + attributes: typing.Union[AttributesInput, NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> Member: """ @@ -323,9 +438,23 @@ async def create( Create a merchant member. """ + body_data: dict[str, typing.Any] = {} + if not isinstance(is_managed_user, NotGivenType): + body_data["is_managed_user"] = is_managed_user + body_data["email"] = email + if not isinstance(password, NotGivenType): + body_data["password"] = password + if not isinstance(nickname, NotGivenType): + body_data["nickname"] = nickname + body_data["roles"] = list(roles) + if not isinstance(metadata, NotGivenType): + body_data["metadata"] = metadata + if not isinstance(attributes, NotGivenType): + body_data["attributes"] = attributes + resp = await self._client.post( f"/v0.1/merchants/{merchant_code}/members", - json=body.model_dump(exclude_unset=True), + json=serialize_request_data(body_data), headers=headers, ) if resp.status_code == 201: @@ -341,7 +470,7 @@ async def create( body=resp.text, ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) async def get( self, merchant_code: str, member_id: str, headers: typing.Optional[HeaderTypes] = None @@ -360,13 +489,17 @@ async def get( elif resp.status_code == 404: raise APIError("Merchant or member not found.", status=resp.status_code, body=resp.text) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) async def update( self, merchant_code: str, member_id: str, - body: UpdateMerchantMemberBody, + *, + roles: typing.Union[typing.Sequence[str], NotGivenType] = NOT_GIVEN, + metadata: typing.Union[MetadataInput, NotGivenType] = NOT_GIVEN, + attributes: typing.Union[AttributesInput, NotGivenType] = NOT_GIVEN, + user: typing.Union[UpdateMerchantMemberBodyUserInput, NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> Member: """ @@ -374,9 +507,19 @@ async def update( Update the merchant member. """ + body_data: dict[str, typing.Any] = {} + if not isinstance(roles, NotGivenType): + body_data["roles"] = list(roles) + if not isinstance(metadata, NotGivenType): + body_data["metadata"] = metadata + if not isinstance(attributes, NotGivenType): + body_data["attributes"] = attributes + if not isinstance(user, NotGivenType): + body_data["user"] = user + resp = await self._client.put( f"/v0.1/merchants/{merchant_code}/members/{member_id}", - json=body.model_dump(exclude_unset=True), + json=serialize_request_data(body_data), headers=headers, ) if resp.status_code == 200: @@ -402,7 +545,7 @@ async def update( body=resp.text, ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) async def delete( self, merchant_code: str, member_id: str, headers: typing.Optional[HeaderTypes] = None @@ -421,4 +564,4 @@ async def delete( elif resp.status_code == 404: raise APIError("Merchant or member not found.", status=resp.status_code, body=resp.text) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) diff --git a/sumup/memberships/__init__.py b/sumup/memberships/__init__.py index 8cb041ed..90f5c48d 100755 --- a/sumup/memberships/__init__.py +++ b/sumup/memberships/__init__.py @@ -2,8 +2,6 @@ from .resource import ( MembershipsResource, AsyncMembershipsResource, - ListMembershipsParamsResourceParentType, - ListMembershipsParams, ListMemberships200Response, ) from ..types import ( @@ -21,8 +19,6 @@ __all__ = [ "MembershipsResource", "AsyncMembershipsResource", - "ListMembershipsParamsResourceParentType", - "ListMembershipsParams", "ListMemberships200Response", "Attributes", "Invite", diff --git a/sumup/memberships/resource.py b/sumup/memberships/resource.py index 7eab945b..22834a75 100755 --- a/sumup/memberships/resource.py +++ b/sumup/memberships/resource.py @@ -1,88 +1,53 @@ # Code generated by `py-sdk-gen`. DO NOT EDIT. +# ruff: noqa: F401, F541 """ Endpoints to manage user's memberships. Memberships are used to connect the user to merchant accounts and to grant them access to the merchant's resources via roles. """ from __future__ import annotations -from .._service import Resource, AsyncResource, HeaderTypes +from .._service import ( + Resource, + AsyncResource, + HeaderTypes, + NotGivenType, + NOT_GIVEN, + serialize_query_params, + serialize_request_data, +) from .._exceptions import APIError from ..types import ( + Attributes, + Invite, Membership, + MembershipResource, MembershipStatus, + Metadata, + Problem, ResourceType, ) +from ..types import ( + AttributesInput, + InviteInput, + MembershipInput, + MembershipResourceInput, + MembershipStatusInput, + MetadataInput, + ProblemInput, + ResourceTypeInput, +) +import datetime import httpx import typing import pydantic +import typing_extensions -class ListMembershipsParamsResourceParentType(pydantic.BaseModel): +class ListMembershipsParamsResourceParentTypeInput(typing_extensions.TypedDict, total=False): """ ListMembershipsParamsResourceParentType is a schema definition. """ - -class ListMembershipsParams(pydantic.BaseModel): - """ - ListMembershipsParams: query parameters for ListMemberships - """ - - kind: typing.Optional[ResourceType] = None - """ - The type of the membership resource. - Possible values are: - * `merchant` - merchant account(s) - * `organization` - organization(s) - """ - - limit: typing.Optional[int] = None - - offset: typing.Optional[int] = None - - resource_attributes_sandbox: typing.Optional[bool] = pydantic.Field( - default=None, - serialization_alias="resource.attributes.sandbox", - validation_alias=pydantic.AliasChoices( - "resource.attributes.sandbox", "resource_attributes_sandbox" - ), - ) - - resource_name: typing.Optional[str] = pydantic.Field( - default=None, - serialization_alias="resource.name", - validation_alias=pydantic.AliasChoices("resource.name", "resource_name"), - ) - - resource_parent_id: typing.Optional[str] = pydantic.Field( - default=None, - serialization_alias="resource.parent.id", - validation_alias=pydantic.AliasChoices("resource.parent.id", "resource_parent_id"), - ) - - resource_parent_type: typing.Optional[ListMembershipsParamsResourceParentType] = pydantic.Field( - default=None, - serialization_alias="resource.parent.type", - validation_alias=pydantic.AliasChoices("resource.parent.type", "resource_parent_type"), - ) - - resource_type: typing.Optional[ResourceType] = pydantic.Field( - default=None, - serialization_alias="resource.type", - validation_alias=pydantic.AliasChoices("resource.type", "resource_type"), - ) - """ - The type of the membership resource. - Possible values are: - * `merchant` - merchant account(s) - * `organization` - organization(s) - """ - - roles: typing.Optional[list[str]] = None - - status: typing.Optional[MembershipStatus] = None - """ - The status of the membership. - """ + pass class ListMemberships200Response(pydantic.BaseModel): @@ -95,6 +60,14 @@ class ListMemberships200Response(pydantic.BaseModel): total_count: int +class ListMemberships200ResponseDict(typing_extensions.TypedDict, total=False): + items: typing_extensions.Required[typing.Sequence[MembershipInput]] + total_count: typing_extensions.Required[int] + + +ListMemberships200ResponseInput = ListMemberships200ResponseDict + + class MembershipsResource(Resource): """API resource for the Memberships endpoints.""" @@ -103,7 +76,19 @@ def __init__(self, client: httpx.Client) -> None: def list( self, - params: typing.Optional[ListMembershipsParams] = None, + *, + offset: typing.Union[int, NotGivenType] = NOT_GIVEN, + limit: typing.Union[int, NotGivenType] = NOT_GIVEN, + kind: typing.Union[ResourceTypeInput, NotGivenType] = NOT_GIVEN, + status: typing.Union[MembershipStatusInput, NotGivenType] = NOT_GIVEN, + resource_type: typing.Union[ResourceTypeInput, NotGivenType] = NOT_GIVEN, + resource_attributes_sandbox: typing.Union[bool, NotGivenType] = NOT_GIVEN, + resource_name: typing.Union[str, NotGivenType] = NOT_GIVEN, + resource_parent_id: typing.Union[str, NotGivenType] = NOT_GIVEN, + resource_parent_type: typing.Union[ + ListMembershipsParamsResourceParentTypeInput, NotGivenType + ] = NOT_GIVEN, + roles: typing.Union[typing.Sequence[str], NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> ListMemberships200Response: """ @@ -111,9 +96,34 @@ def list( List memberships of the current user. """ + query_data: dict[str, typing.Any] = {} + if not isinstance(offset, NotGivenType) and offset is not None: + query_data["offset"] = offset + if not isinstance(limit, NotGivenType) and limit is not None: + query_data["limit"] = limit + if not isinstance(kind, NotGivenType) and kind is not None: + query_data["kind"] = kind + if not isinstance(status, NotGivenType) and status is not None: + query_data["status"] = status + if not isinstance(resource_type, NotGivenType) and resource_type is not None: + query_data["resource.type"] = resource_type + if ( + not isinstance(resource_attributes_sandbox, NotGivenType) + and resource_attributes_sandbox is not None + ): + query_data["resource.attributes.sandbox"] = resource_attributes_sandbox + if not isinstance(resource_name, NotGivenType) and resource_name is not None: + query_data["resource.name"] = resource_name + if not isinstance(resource_parent_id, NotGivenType) and resource_parent_id is not None: + query_data["resource.parent.id"] = resource_parent_id + if not isinstance(resource_parent_type, NotGivenType) and resource_parent_type is not None: + query_data["resource.parent.type"] = resource_parent_type + if not isinstance(roles, NotGivenType) and roles is not None: + query_data["roles"] = list(roles) + resp = self._client.get( - "/v0.1/memberships", - params=params.model_dump(by_alias=True, exclude_none=True) if params else None, + f"/v0.1/memberships", + params=serialize_query_params(query_data) if query_data else None, headers=headers, ) if resp.status_code == 200: @@ -129,7 +139,7 @@ def list( body=resp.text, ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) class AsyncMembershipsResource(AsyncResource): @@ -140,7 +150,19 @@ def __init__(self, client: httpx.AsyncClient) -> None: async def list( self, - params: typing.Optional[ListMembershipsParams] = None, + *, + offset: typing.Union[int, NotGivenType] = NOT_GIVEN, + limit: typing.Union[int, NotGivenType] = NOT_GIVEN, + kind: typing.Union[ResourceTypeInput, NotGivenType] = NOT_GIVEN, + status: typing.Union[MembershipStatusInput, NotGivenType] = NOT_GIVEN, + resource_type: typing.Union[ResourceTypeInput, NotGivenType] = NOT_GIVEN, + resource_attributes_sandbox: typing.Union[bool, NotGivenType] = NOT_GIVEN, + resource_name: typing.Union[str, NotGivenType] = NOT_GIVEN, + resource_parent_id: typing.Union[str, NotGivenType] = NOT_GIVEN, + resource_parent_type: typing.Union[ + ListMembershipsParamsResourceParentTypeInput, NotGivenType + ] = NOT_GIVEN, + roles: typing.Union[typing.Sequence[str], NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> ListMemberships200Response: """ @@ -148,9 +170,34 @@ async def list( List memberships of the current user. """ + query_data: dict[str, typing.Any] = {} + if not isinstance(offset, NotGivenType) and offset is not None: + query_data["offset"] = offset + if not isinstance(limit, NotGivenType) and limit is not None: + query_data["limit"] = limit + if not isinstance(kind, NotGivenType) and kind is not None: + query_data["kind"] = kind + if not isinstance(status, NotGivenType) and status is not None: + query_data["status"] = status + if not isinstance(resource_type, NotGivenType) and resource_type is not None: + query_data["resource.type"] = resource_type + if ( + not isinstance(resource_attributes_sandbox, NotGivenType) + and resource_attributes_sandbox is not None + ): + query_data["resource.attributes.sandbox"] = resource_attributes_sandbox + if not isinstance(resource_name, NotGivenType) and resource_name is not None: + query_data["resource.name"] = resource_name + if not isinstance(resource_parent_id, NotGivenType) and resource_parent_id is not None: + query_data["resource.parent.id"] = resource_parent_id + if not isinstance(resource_parent_type, NotGivenType) and resource_parent_type is not None: + query_data["resource.parent.type"] = resource_parent_type + if not isinstance(roles, NotGivenType) and roles is not None: + query_data["roles"] = list(roles) + resp = await self._client.get( - "/v0.1/memberships", - params=params.model_dump(by_alias=True, exclude_none=True) if params else None, + f"/v0.1/memberships", + params=serialize_query_params(query_data) if query_data else None, headers=headers, ) if resp.status_code == 200: @@ -166,4 +213,4 @@ async def list( body=resp.text, ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) diff --git a/sumup/merchants/__init__.py b/sumup/merchants/__init__.py index 94e5421f..9148f533 100755 --- a/sumup/merchants/__init__.py +++ b/sumup/merchants/__init__.py @@ -2,9 +2,6 @@ from .resource import ( MerchantsResource, AsyncMerchantsResource, - GetMerchantParams, - ListPersonsParams, - GetPersonParams, ) from ..types import ( Address, @@ -35,9 +32,6 @@ __all__ = [ "MerchantsResource", "AsyncMerchantsResource", - "GetMerchantParams", - "ListPersonsParams", - "GetPersonParams", "Address", "Attributes", "BasePerson", diff --git a/sumup/merchants/resource.py b/sumup/merchants/resource.py index 2a909b77..b272e672 100755 --- a/sumup/merchants/resource.py +++ b/sumup/merchants/resource.py @@ -1,43 +1,73 @@ # Code generated by `py-sdk-gen`. DO NOT EDIT. +# ruff: noqa: F401, F541 """ Merchant account represents a single business entity at SumUp. """ from __future__ import annotations -from .._service import Resource, AsyncResource, HeaderTypes +from .._service import ( + Resource, + AsyncResource, + HeaderTypes, + NotGivenType, + NOT_GIVEN, + serialize_query_params, + serialize_request_data, +) from .._exceptions import APIError from ..types import ( + Address, + Attributes, + BasePerson, + Branding, + BusinessProfile, + ChangeStatus, + ClassicMerchantIdentifiers, + Company, + CompanyIdentifier, + CompanyIdentifiers, + CountryCode, + LegalType, ListPersonsResponseBody, Merchant, + Meta, + Ownership, Person, + PersonalIdentifier, + PhoneNumber, + Problem, + Timestamps, + Version, +) +from ..types import ( + AddressInput, + AttributesInput, + BasePersonInput, + BrandingInput, + BusinessProfileInput, + ChangeStatusInput, + ClassicMerchantIdentifiersInput, + CompanyInput, + CompanyIdentifierInput, + CompanyIdentifiersInput, + CountryCodeInput, + LegalTypeInput, + ListPersonsResponseBodyInput, + MerchantInput, + MetaInput, + OwnershipInput, + PersonInput, + PersonalIdentifierInput, + PhoneNumberInput, + ProblemInput, + TimestampsInput, + VersionInput, ) +import datetime import httpx import typing import pydantic - - -class GetMerchantParams(pydantic.BaseModel): - """ - GetMerchantParams: query parameters for GetMerchant - """ - - version: typing.Optional[str] = None - - -class ListPersonsParams(pydantic.BaseModel): - """ - ListPersonsParams: query parameters for ListPersons - """ - - version: typing.Optional[str] = None - - -class GetPersonParams(pydantic.BaseModel): - """ - GetPersonParams: query parameters for GetPerson - """ - - version: typing.Optional[str] = None +import typing_extensions class MerchantsResource(Resource): @@ -49,7 +79,8 @@ def __init__(self, client: httpx.Client) -> None: def get( self, merchant_code: str, - params: typing.Optional[GetMerchantParams] = None, + *, + version: typing.Union[str, NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> Merchant: """ @@ -59,9 +90,13 @@ def get( Merchant documentation: https://developer.sumup.com/tools/models/merchant """ + query_data: dict[str, typing.Any] = {} + if not isinstance(version, NotGivenType) and version is not None: + query_data["version"] = version + resp = self._client.get( f"/v1/merchants/{merchant_code}", - params=params.model_dump(by_alias=True, exclude_none=True) if params else None, + params=serialize_query_params(query_data) if query_data else None, headers=headers, ) if resp.status_code == 200: @@ -71,12 +106,13 @@ def get( "The requested Merchant does not exist.", status=resp.status_code, body=resp.text ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) def list_persons( self, merchant_code: str, - params: typing.Optional[ListPersonsParams] = None, + *, + version: typing.Union[str, NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> ListPersonsResponseBody: """ @@ -86,9 +122,13 @@ def list_persons( Persons documentation: https://developer.sumup.com/tools/models/merchant#persons """ + query_data: dict[str, typing.Any] = {} + if not isinstance(version, NotGivenType) and version is not None: + query_data["version"] = version + resp = self._client.get( f"/v1/merchants/{merchant_code}/persons", - params=params.model_dump(by_alias=True, exclude_none=True) if params else None, + params=serialize_query_params(query_data) if query_data else None, headers=headers, ) if resp.status_code == 200: @@ -98,13 +138,14 @@ def list_persons( "The requested Merchant does not exist.", status=resp.status_code, body=resp.text ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) def get_person( self, merchant_code: str, person_id: str, - params: typing.Optional[GetPersonParams] = None, + *, + version: typing.Union[str, NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> Person: """ @@ -114,9 +155,13 @@ def get_person( Persons documentation: https://developer.sumup.com/tools/models/merchant#persons """ + query_data: dict[str, typing.Any] = {} + if not isinstance(version, NotGivenType) and version is not None: + query_data["version"] = version + resp = self._client.get( f"/v1/merchants/{merchant_code}/persons/{person_id}", - params=params.model_dump(by_alias=True, exclude_none=True) if params else None, + params=serialize_query_params(query_data) if query_data else None, headers=headers, ) if resp.status_code == 200: @@ -126,7 +171,7 @@ def get_person( "The requested Person does not exist.", status=resp.status_code, body=resp.text ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) class AsyncMerchantsResource(AsyncResource): @@ -138,7 +183,8 @@ def __init__(self, client: httpx.AsyncClient) -> None: async def get( self, merchant_code: str, - params: typing.Optional[GetMerchantParams] = None, + *, + version: typing.Union[str, NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> Merchant: """ @@ -148,9 +194,13 @@ async def get( Merchant documentation: https://developer.sumup.com/tools/models/merchant """ + query_data: dict[str, typing.Any] = {} + if not isinstance(version, NotGivenType) and version is not None: + query_data["version"] = version + resp = await self._client.get( f"/v1/merchants/{merchant_code}", - params=params.model_dump(by_alias=True, exclude_none=True) if params else None, + params=serialize_query_params(query_data) if query_data else None, headers=headers, ) if resp.status_code == 200: @@ -160,12 +210,13 @@ async def get( "The requested Merchant does not exist.", status=resp.status_code, body=resp.text ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) async def list_persons( self, merchant_code: str, - params: typing.Optional[ListPersonsParams] = None, + *, + version: typing.Union[str, NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> ListPersonsResponseBody: """ @@ -175,9 +226,13 @@ async def list_persons( Persons documentation: https://developer.sumup.com/tools/models/merchant#persons """ + query_data: dict[str, typing.Any] = {} + if not isinstance(version, NotGivenType) and version is not None: + query_data["version"] = version + resp = await self._client.get( f"/v1/merchants/{merchant_code}/persons", - params=params.model_dump(by_alias=True, exclude_none=True) if params else None, + params=serialize_query_params(query_data) if query_data else None, headers=headers, ) if resp.status_code == 200: @@ -187,13 +242,14 @@ async def list_persons( "The requested Merchant does not exist.", status=resp.status_code, body=resp.text ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) async def get_person( self, merchant_code: str, person_id: str, - params: typing.Optional[GetPersonParams] = None, + *, + version: typing.Union[str, NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> Person: """ @@ -203,9 +259,13 @@ async def get_person( Persons documentation: https://developer.sumup.com/tools/models/merchant#persons """ + query_data: dict[str, typing.Any] = {} + if not isinstance(version, NotGivenType) and version is not None: + query_data["version"] = version + resp = await self._client.get( f"/v1/merchants/{merchant_code}/persons/{person_id}", - params=params.model_dump(by_alias=True, exclude_none=True) if params else None, + params=serialize_query_params(query_data) if query_data else None, headers=headers, ) if resp.status_code == 200: @@ -215,4 +275,4 @@ async def get_person( "The requested Person does not exist.", status=resp.status_code, body=resp.text ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) diff --git a/sumup/payouts/__init__.py b/sumup/payouts/__init__.py index d182de3c..38b1cf5c 100755 --- a/sumup/payouts/__init__.py +++ b/sumup/payouts/__init__.py @@ -4,10 +4,8 @@ AsyncPayoutsResource, ListPayoutsV1ParamsFormat, ListPayoutsV1ParamsOrder, - ListPayoutsV1Params, ListPayoutsParamsFormat, ListPayoutsParamsOrder, - ListPayoutsParams, ) from ..types import ( Error, @@ -22,10 +20,8 @@ "AsyncPayoutsResource", "ListPayoutsV1ParamsFormat", "ListPayoutsV1ParamsOrder", - "ListPayoutsV1Params", "ListPayoutsParamsFormat", "ListPayoutsParamsOrder", - "ListPayoutsParams", "Error", "ErrorExtended", "FinancialPayouts", diff --git a/sumup/payouts/resource.py b/sumup/payouts/resource.py index 9179a768..95d590db 100755 --- a/sumup/payouts/resource.py +++ b/sumup/payouts/resource.py @@ -1,4 +1,5 @@ # Code generated by `py-sdk-gen`. DO NOT EDIT. +# ruff: noqa: F401, F541 """ The Payouts model will allow you to track funds you’ve received from SumUp. @@ -6,9 +7,18 @@ """ from __future__ import annotations -from .._service import Resource, AsyncResource, HeaderTypes +from .._service import ( + Resource, + AsyncResource, + HeaderTypes, + NotGivenType, + NOT_GIVEN, + serialize_query_params, + serialize_request_data, +) from .._exceptions import APIError -from ..types import FinancialPayouts +from ..types import Error, ErrorExtended, FinancialPayouts, Problem +from ..types import ErrorInput, ErrorExtendedInput, FinancialPayoutsInput, ProblemInput import datetime import httpx import typing @@ -16,45 +26,16 @@ import typing_extensions ListPayoutsV1ParamsFormat = typing.Union[typing.Literal["csv", "json"], str] +ListPayoutsV1ParamsFormatInput = ListPayoutsV1ParamsFormat ListPayoutsV1ParamsOrder = typing.Union[typing.Literal["asc", "desc"], str] - - -class ListPayoutsV1Params(pydantic.BaseModel): - """ - ListPayoutsV1Params: query parameters for ListPayoutsV1 - """ - - end_date: datetime.date - - start_date: datetime.date - - format: typing.Optional[ListPayoutsV1ParamsFormat] = None - - limit: typing.Optional[int] = None - - order: typing.Optional[ListPayoutsV1ParamsOrder] = None - +ListPayoutsV1ParamsOrderInput = ListPayoutsV1ParamsOrder ListPayoutsParamsFormat = typing.Union[typing.Literal["csv", "json"], str] +ListPayoutsParamsFormatInput = ListPayoutsParamsFormat ListPayoutsParamsOrder = typing.Union[typing.Literal["asc", "desc"], str] - - -class ListPayoutsParams(pydantic.BaseModel): - """ - ListPayoutsParams: query parameters for ListPayouts - """ - - end_date: datetime.date - - start_date: datetime.date - - format: typing.Optional[ListPayoutsParamsFormat] = None - - limit: typing.Optional[int] = None - - order: typing.Optional[ListPayoutsParamsOrder] = None +ListPayoutsParamsOrderInput = ListPayoutsParamsOrder class PayoutsResource(Resource): @@ -66,7 +47,12 @@ def __init__(self, client: httpx.Client) -> None: def list( self, merchant_code: str, - params: typing.Optional[ListPayoutsV1Params] = None, + *, + start_date: datetime.date, + end_date: datetime.date, + format: typing.Union[ListPayoutsV1ParamsFormatInput, NotGivenType] = NOT_GIVEN, + limit: typing.Union[int, NotGivenType] = NOT_GIVEN, + order: typing.Union[ListPayoutsV1ParamsOrderInput, NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> FinancialPayouts: """ @@ -74,9 +60,19 @@ def list( Lists ordered payouts for the merchant account. """ + query_data: dict[str, typing.Any] = {} + query_data["start_date"] = start_date + query_data["end_date"] = end_date + if not isinstance(format, NotGivenType) and format is not None: + query_data["format"] = format + if not isinstance(limit, NotGivenType) and limit is not None: + query_data["limit"] = limit + if not isinstance(order, NotGivenType) and order is not None: + query_data["order"] = order + resp = self._client.get( f"/v1.0/merchants/{merchant_code}/payouts", - params=params.model_dump(by_alias=True, exclude_none=True) if params else None, + params=serialize_query_params(query_data) if query_data else None, headers=headers, ) if resp.status_code == 200: @@ -92,12 +88,17 @@ def list( "The request is not authorized.", status=resp.status_code, body=resp.text ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) @typing_extensions.deprecated("This method is deprecated") def list_deprecated( self, - params: typing.Optional[ListPayoutsParams] = None, + *, + start_date: datetime.date, + end_date: datetime.date, + format: typing.Union[ListPayoutsParamsFormatInput, NotGivenType] = NOT_GIVEN, + limit: typing.Union[int, NotGivenType] = NOT_GIVEN, + order: typing.Union[ListPayoutsParamsOrderInput, NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> FinancialPayouts: """ @@ -105,9 +106,19 @@ def list_deprecated( Lists ordered payouts for the merchant account. """ + query_data: dict[str, typing.Any] = {} + query_data["start_date"] = start_date + query_data["end_date"] = end_date + if not isinstance(format, NotGivenType) and format is not None: + query_data["format"] = format + if not isinstance(limit, NotGivenType) and limit is not None: + query_data["limit"] = limit + if not isinstance(order, NotGivenType) and order is not None: + query_data["order"] = order + resp = self._client.get( - "/v0.1/me/financials/payouts", - params=params.model_dump(by_alias=True, exclude_none=True) if params else None, + f"/v0.1/me/financials/payouts", + params=serialize_query_params(query_data) if query_data else None, headers=headers, ) if resp.status_code == 200: @@ -123,7 +134,7 @@ def list_deprecated( "The request is not authorized.", status=resp.status_code, body=resp.text ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) class AsyncPayoutsResource(AsyncResource): @@ -135,7 +146,12 @@ def __init__(self, client: httpx.AsyncClient) -> None: async def list( self, merchant_code: str, - params: typing.Optional[ListPayoutsV1Params] = None, + *, + start_date: datetime.date, + end_date: datetime.date, + format: typing.Union[ListPayoutsV1ParamsFormatInput, NotGivenType] = NOT_GIVEN, + limit: typing.Union[int, NotGivenType] = NOT_GIVEN, + order: typing.Union[ListPayoutsV1ParamsOrderInput, NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> FinancialPayouts: """ @@ -143,9 +159,19 @@ async def list( Lists ordered payouts for the merchant account. """ + query_data: dict[str, typing.Any] = {} + query_data["start_date"] = start_date + query_data["end_date"] = end_date + if not isinstance(format, NotGivenType) and format is not None: + query_data["format"] = format + if not isinstance(limit, NotGivenType) and limit is not None: + query_data["limit"] = limit + if not isinstance(order, NotGivenType) and order is not None: + query_data["order"] = order + resp = await self._client.get( f"/v1.0/merchants/{merchant_code}/payouts", - params=params.model_dump(by_alias=True, exclude_none=True) if params else None, + params=serialize_query_params(query_data) if query_data else None, headers=headers, ) if resp.status_code == 200: @@ -161,12 +187,17 @@ async def list( "The request is not authorized.", status=resp.status_code, body=resp.text ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) @typing_extensions.deprecated("This method is deprecated") async def list_deprecated( self, - params: typing.Optional[ListPayoutsParams] = None, + *, + start_date: datetime.date, + end_date: datetime.date, + format: typing.Union[ListPayoutsParamsFormatInput, NotGivenType] = NOT_GIVEN, + limit: typing.Union[int, NotGivenType] = NOT_GIVEN, + order: typing.Union[ListPayoutsParamsOrderInput, NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> FinancialPayouts: """ @@ -174,9 +205,19 @@ async def list_deprecated( Lists ordered payouts for the merchant account. """ + query_data: dict[str, typing.Any] = {} + query_data["start_date"] = start_date + query_data["end_date"] = end_date + if not isinstance(format, NotGivenType) and format is not None: + query_data["format"] = format + if not isinstance(limit, NotGivenType) and limit is not None: + query_data["limit"] = limit + if not isinstance(order, NotGivenType) and order is not None: + query_data["order"] = order + resp = await self._client.get( - "/v0.1/me/financials/payouts", - params=params.model_dump(by_alias=True, exclude_none=True) if params else None, + f"/v0.1/me/financials/payouts", + params=serialize_query_params(query_data) if query_data else None, headers=headers, ) if resp.status_code == 200: @@ -192,4 +233,4 @@ async def list_deprecated( "The request is not authorized.", status=resp.status_code, body=resp.text ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) diff --git a/sumup/readers/__init__.py b/sumup/readers/__init__.py index 67037c03..349b43f0 100755 --- a/sumup/readers/__init__.py +++ b/sumup/readers/__init__.py @@ -2,13 +2,7 @@ from .resource import ( ReadersResource, AsyncReadersResource, - CreateReaderBody, - UpdateReaderBody, - CreateReaderCheckoutBodyAade, - CreateReaderCheckoutBodyAffiliate, CreateReaderCheckoutBodyCardType, - CreateReaderCheckoutBodyTotalAmount, - CreateReaderCheckoutBody, ListReaders200Response, ) from ..types import ( @@ -36,13 +30,7 @@ __all__ = [ "ReadersResource", "AsyncReadersResource", - "CreateReaderBody", - "UpdateReaderBody", - "CreateReaderCheckoutBodyAade", - "CreateReaderCheckoutBodyAffiliate", "CreateReaderCheckoutBodyCardType", - "CreateReaderCheckoutBodyTotalAmount", - "CreateReaderCheckoutBody", "ListReaders200Response", "BadRequest", "CreateReaderCheckoutError", diff --git a/sumup/readers/resource.py b/sumup/readers/resource.py index d9e52e78..dd8df521 100755 --- a/sumup/readers/resource.py +++ b/sumup/readers/resource.py @@ -1,133 +1,196 @@ # Code generated by `py-sdk-gen`. DO NOT EDIT. +# ruff: noqa: F401, F541 """ A reader represents a device that accepts payments. You can use the SumUp Solo to accept in-person payments. """ from __future__ import annotations -from .._service import Resource, AsyncResource, HeaderTypes +from .._service import ( + Resource, + AsyncResource, + HeaderTypes, + NotGivenType, + NOT_GIVEN, + serialize_query_params, + serialize_request_data, +) from .._exceptions import APIError from ..types import ( + BadRequest, + CreateReaderCheckoutError, + CreateReaderCheckoutRequest, CreateReaderCheckoutResponse, + CreateReaderCheckoutUnprocessableEntity, + CreateReaderTerminateError, + CreateReaderTerminateUnprocessableEntity, Metadata, + NotFound, + Problem, Reader, + ReaderDevice, ReaderId, ReaderName, ReaderPairingCode, + ReaderStatus, StatusResponse, + Unauthorized, +) +from ..types import ( + BadRequestInput, + CreateReaderCheckoutErrorInput, + CreateReaderCheckoutRequestInput, + CreateReaderCheckoutResponseInput, + CreateReaderCheckoutUnprocessableEntityInput, + CreateReaderTerminateErrorInput, + CreateReaderTerminateUnprocessableEntityInput, + MetadataInput, + NotFoundInput, + ProblemInput, + ReaderInput, + ReaderDeviceInput, + ReaderIdInput, + ReaderNameInput, + ReaderPairingCodeInput, + ReaderStatusInput, + StatusResponseInput, + UnauthorizedInput, ) +import datetime import httpx import typing import pydantic +import typing_extensions -class CreateReaderBody(pydantic.BaseModel): +class CreateReaderBodyInput(typing_extensions.TypedDict, total=False): """ CreateReaderBody is a schema definition. """ - name: ReaderName - """ - Custom human-readable, user-defined name for easier identification of the reader. - Max length: 500 - """ - - pairing_code: ReaderPairingCode - """ - The pairing code is a 8 or 9 character alphanumeric string that is displayed on a SumUp Device after initiatingthe pairing. It is used to link the physical device to the created pairing. - Min length: 8 - Max length: 9 - """ - - metadata: typing.Optional[Metadata] = None - """ - Set of user-defined key-value pairs attached to the object. Partial updates are not supported. When updating, alwayssubmit whole metadata. Maximum of 64 parameters are allowed in the object. - Max properties: 64 - """ - - -class UpdateReaderBody(pydantic.BaseModel): + name: typing_extensions.Required[ + typing_extensions.Annotated[ + ReaderNameInput, + typing_extensions.Doc( + "Custom human-readable, user-defined name for easier identification of the reader.\nMax length: 500" + ), + ] + ] + pairing_code: typing_extensions.Required[ + typing_extensions.Annotated[ + ReaderPairingCodeInput, + typing_extensions.Doc( + "The pairing code is a 8 or 9 character alphanumeric string that is displayed on a SumUp Device after initiatingthe pairing. It is used to link the physical device to the created pairing.\nMin length: 8\nMax length: 9" + ), + ] + ] + metadata: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + MetadataInput, + typing_extensions.Doc( + "Set of user-defined key-value pairs attached to the object. Partial updates are not supported. When updating, alwayssubmit whole metadata. Maximum of 64 parameters are allowed in the object.\nMax properties: 64" + ), + ] + ] + + +class UpdateReaderBodyInput(typing_extensions.TypedDict, total=False): """ UpdateReaderBody is a schema definition. """ - metadata: typing.Optional[Metadata] = None - """ - Set of user-defined key-value pairs attached to the object. Partial updates are not supported. When updating, alwayssubmit whole metadata. Maximum of 64 parameters are allowed in the object. - Max properties: 64 - """ - - name: typing.Optional[ReaderName] = None - """ - Custom human-readable, user-defined name for easier identification of the reader. - Max length: 500 - """ + metadata: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + MetadataInput, + typing_extensions.Doc( + "Set of user-defined key-value pairs attached to the object. Partial updates are not supported. When updating, alwayssubmit whole metadata. Maximum of 64 parameters are allowed in the object.\nMax properties: 64" + ), + ] + ] + name: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + ReaderNameInput, + typing_extensions.Doc( + "Custom human-readable, user-defined name for easier identification of the reader.\nMax length: 500" + ), + ] + ] -class CreateReaderCheckoutBodyAade(pydantic.BaseModel): +class CreateReaderCheckoutBodyAadeInput(typing_extensions.TypedDict, total=False): """ Optional object containing data for transactions from ERP integrators in Greece that comply with the AADE1155 protocol. When such regulatory/business requirements apply, this object must be provided and contains the data needed tovalidate the transaction with the AADE signature provider. """ - provider_id: str - """ - The identifier of the AADE signature provider. - """ - - signature: str - """ - The base64 encoded signature of the transaction data. - """ - - signature_data: str - """ - The string containing the signed transaction data. - """ - - -CreateReaderCheckoutBodyAffiliateTags = dict[str, object] + provider_id: typing_extensions.Required[ + typing_extensions.Annotated[ + str, typing_extensions.Doc("The identifier of the AADE signature provider.") + ] + ] + signature: typing_extensions.Required[ + typing_extensions.Annotated[ + str, typing_extensions.Doc("The base64 encoded signature of the transaction data.") + ] + ] + signature_data: typing_extensions.Required[ + typing_extensions.Annotated[ + str, typing_extensions.Doc("The string containing the signed transaction data.") + ] + ] + + +CreateReaderCheckoutBodyAffiliateTagsInput = typing.Mapping[str, object] """ Additional metadata for the transaction. It is key-value object that can be associated with the transaction. """ -class CreateReaderCheckoutBodyAffiliate(pydantic.BaseModel): +class CreateReaderCheckoutBodyAffiliateInput(typing_extensions.TypedDict, total=False): """ Affiliate metadata for the transaction. It is a field that allow for integrators to track the source of the transaction. """ - app_id: str - """ - Application ID of the affiliate. - It is a unique identifier for the application and should be set by the integrator in the [Affiliate Keys](https://developer.sumup.com/affiliate-keys) page. - """ - - foreign_transaction_id: str - """ - Foreign transaction ID of the affiliate. - It is a unique identifier for the transaction. - It can be used later to fetch the transaction details via the [Transactions API](https://developer.sumup.com/api/transactions/get). - """ - - key: str - """ - Key of the affiliate. - It is a unique identifier for the key and should be generated by the integrator in the [Affiliate Keys](https://developer.sumup.com/affiliate-keys) page. - """ - - tags: typing.Optional[CreateReaderCheckoutBodyAffiliateTags] = None - """ - Additional metadata for the transaction. - It is key-value object that can be associated with the transaction. - """ + app_id: typing_extensions.Required[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Application ID of the affiliate.\nIt is a unique identifier for the application and should be set by the integrator in the [Affiliate Keys](https://developer.sumup.com/affiliate-keys) page." + ), + ] + ] + foreign_transaction_id: typing_extensions.Required[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Foreign transaction ID of the affiliate.\nIt is a unique identifier for the transaction.\nIt can be used later to fetch the transaction details via the [Transactions API](https://developer.sumup.com/api/transactions/get)." + ), + ] + ] + key: typing_extensions.Required[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Key of the affiliate.\nIt is a unique identifier for the key and should be generated by the integrator in the [Affiliate Keys](https://developer.sumup.com/affiliate-keys) page." + ), + ] + ] + tags: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + CreateReaderCheckoutBodyAffiliateTagsInput, + typing_extensions.Doc( + "Additional metadata for the transaction.\nIt is key-value object that can be associated with the transaction." + ), + ] + ] CreateReaderCheckoutBodyCardType = typing.Union[typing.Literal["credit", "debit"], str] +CreateReaderCheckoutBodyCardTypeInput = CreateReaderCheckoutBodyCardType -class CreateReaderCheckoutBodyTotalAmount(pydantic.BaseModel): +class CreateReaderCheckoutBodyTotalAmountInput(typing_extensions.TypedDict, total=False): """ Amount structure. @@ -136,108 +199,114 @@ class CreateReaderCheckoutBodyTotalAmount(pydantic.BaseModel): For example, EUR 1.00 is represented as value 100 with minor unit of 2. """ - currency: str - """ - Currency ISO 4217 code - """ - - minor_unit: int - """ - The minor units of the currency. - It represents the number of decimals of the currency. For the currencies CLP, COP and HUF, the minor unit is0. - Min: 0 - """ - - value: int - """ - Integer value of the amount. - Min: 0 - """ + currency: typing_extensions.Required[ + typing_extensions.Annotated[str, typing_extensions.Doc("Currency ISO 4217 code")] + ] + minor_unit: typing_extensions.Required[ + typing_extensions.Annotated[ + int, + typing_extensions.Doc( + "The minor units of the currency.\nIt represents the number of decimals of the currency. For the currencies CLP, COP and HUF, the minor unit is0.\nMin: 0" + ), + ] + ] + value: typing_extensions.Required[ + typing_extensions.Annotated[ + int, typing_extensions.Doc("Integer value of the amount.\nMin: 0") + ] + ] -class CreateReaderCheckoutBody(pydantic.BaseModel): +class CreateReaderCheckoutBodyInput(typing_extensions.TypedDict, total=False): """ Reader Checkout """ - total_amount: CreateReaderCheckoutBodyTotalAmount - """ - Amount structure. - - The amount is represented as an integer value altogether with the currency and the minor unit. - - For example, EUR 1.00 is represented as value 100 with minor unit of 2. - """ - - aade: typing.Optional[CreateReaderCheckoutBodyAade] = None - """ - Optional object containing data for transactions from ERP integrators in Greece that comply with the AADE1155 protocol. - When such regulatory/business requirements apply, this object must be provided and contains the data needed tovalidate the transaction with the AADE signature provider. - """ - - affiliate: typing.Optional[CreateReaderCheckoutBodyAffiliate] = None - """ - Affiliate metadata for the transaction. - It is a field that allow for integrators to track the source of the transaction. - """ - - card_type: typing.Optional[CreateReaderCheckoutBodyCardType] = None - """ - The card type of the card used for the transaction. - Is is required only for some countries (e.g: Brazil). - """ + total_amount: typing_extensions.Required[ + typing_extensions.Annotated[ + CreateReaderCheckoutBodyTotalAmountInput, + typing_extensions.Doc( + "Amount structure.\n\nThe amount is represented as an integer value altogether with the currency and the minor unit.\n\nFor example, EUR 1.00 is represented as value 100 with minor unit of 2." + ), + ] + ] + aade: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + CreateReaderCheckoutBodyAadeInput, + typing_extensions.Doc( + "Optional object containing data for transactions from ERP integrators in Greece that comply with the AADE1155 protocol.\nWhen such regulatory/business requirements apply, this object must be provided and contains the data needed tovalidate the transaction with the AADE signature provider." + ), + ] + ] + affiliate: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + CreateReaderCheckoutBodyAffiliateInput, + typing_extensions.Doc( + "Affiliate metadata for the transaction.\nIt is a field that allow for integrators to track the source of the transaction." + ), + ] + ] + card_type: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + CreateReaderCheckoutBodyCardTypeInput, + typing_extensions.Doc( + "The card type of the card used for the transaction.\nIs is required only for some countries (e.g: Brazil)." + ), + ] + ] + description: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc("Description of the checkout to be shown in the Merchant Sales"), + ] + ] + installments: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + int, + typing_extensions.Doc( + "Number of installments for the transaction.\nIt may vary according to the merchant country.\nFor example, in Brazil, the maximum number of installments is 12.\n\nOmit if the merchant country does support installments.\nOtherwise, the checkout will be rejected.\nMin: 1" + ), + ] + ] + return_url: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Webhook URL to which the payment result will be sent.\nIt must be a HTTPS url.\nFormat: uri" + ), + ] + ] + tip_rates: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + typing.Sequence[float], + typing_extensions.Doc( + "List of tipping rates to be displayed to the cardholder.\nThe rates are in percentage and should be between 0.01 and 0.99.\nThe list should be sorted in ascending order." + ), + ] + ] + tip_timeout: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + int, + typing_extensions.Doc( + "Time in seconds the cardholder has to select a tip rate.\nIf not provided, the default value is 30 seconds.\n\nIt can only be set if `tip_rates` is provided.\n\n**Note**: If the target device is a Solo, it must be in version 3.3.38.0 or higher.\nDefault: 30\n\nMin: 30\nMax: 120" + ), + ] + ] - description: typing.Optional[str] = None - """ - Description of the checkout to be shown in the Merchant Sales - """ - installments: typing.Optional[int] = None +class ListReaders200Response(pydantic.BaseModel): """ - Number of installments for the transaction. - It may vary according to the merchant country. - For example, in Brazil, the maximum number of installments is 12. - - Omit if the merchant country does support installments. - Otherwise, the checkout will be rejected. - Min: 1 - """ - - return_url: typing.Optional[str] = None + ListReaders200Response is a schema definition. """ - Webhook URL to which the payment result will be sent. - It must be a HTTPS url. - Format: uri - """ - tip_rates: typing.Optional[list[float]] = None - """ - List of tipping rates to be displayed to the cardholder. - The rates are in percentage and should be between 0.01 and 0.99. - The list should be sorted in ascending order. - """ + items: list[Reader] - tip_timeout: typing.Optional[int] = None - """ - Time in seconds the cardholder has to select a tip rate. - If not provided, the default value is 30 seconds. - - It can only be set if `tip_rates` is provided. - - **Note**: If the target device is a Solo, it must be in version 3.3.38.0 or higher. - Default: 30 - - Min: 30 - Max: 120 - """ +class ListReaders200ResponseDict(typing_extensions.TypedDict, total=False): + items: typing_extensions.Required[typing.Sequence[ReaderInput]] -class ListReaders200Response(pydantic.BaseModel): - """ - ListReaders200Response is a schema definition. - """ - items: list[Reader] +ListReaders200ResponseInput = ListReaders200ResponseDict class ReadersResource(Resource): @@ -267,12 +336,15 @@ def list( body=resp.text, ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) def create( self, merchant_code: str, - body: CreateReaderBody, + *, + pairing_code: ReaderPairingCodeInput, + name: ReaderNameInput, + metadata: typing.Union[MetadataInput, NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> Reader: """ @@ -280,9 +352,15 @@ def create( Create a new Reader for the merchant account. """ + body_data: dict[str, typing.Any] = {} + body_data["pairing_code"] = pairing_code + body_data["name"] = name + if not isinstance(metadata, NotGivenType): + body_data["metadata"] = metadata + resp = self._client.post( f"/v0.1/merchants/{merchant_code}/readers", - json=body.model_dump(exclude_unset=True), + json=serialize_request_data(body_data), headers=headers, ) if resp.status_code == 201: @@ -300,7 +378,7 @@ def create( "The Reader is not in a pending state.", status=resp.status_code, body=resp.text ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) def get( self, merchant_code: str, id: ReaderId, headers: typing.Optional[HeaderTypes] = None @@ -323,7 +401,7 @@ def get( body=resp.text, ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) def delete( self, merchant_code: str, id: ReaderId, headers: typing.Optional[HeaderTypes] = None @@ -346,13 +424,15 @@ def delete( body=resp.text, ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) def update( self, merchant_code: str, id: ReaderId, - body: UpdateReaderBody, + *, + name: typing.Union[ReaderNameInput, NotGivenType] = NOT_GIVEN, + metadata: typing.Union[MetadataInput, NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> Reader: """ @@ -360,9 +440,15 @@ def update( Update a Reader. """ + body_data: dict[str, typing.Any] = {} + if not isinstance(name, NotGivenType): + body_data["name"] = name + if not isinstance(metadata, NotGivenType): + body_data["metadata"] = metadata + resp = self._client.patch( f"/v0.1/merchants/{merchant_code}/readers/{id}", - json=body.model_dump(exclude_unset=True), + json=serialize_request_data(body_data), headers=headers, ) if resp.status_code == 200: @@ -380,13 +466,22 @@ def update( body=resp.text, ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) def create_checkout( self, merchant_code: str, reader_id: str, - body: CreateReaderCheckoutBody, + *, + aade: typing.Union[CreateReaderCheckoutBodyAadeInput, NotGivenType] = NOT_GIVEN, + affiliate: typing.Union[CreateReaderCheckoutBodyAffiliateInput, NotGivenType] = NOT_GIVEN, + card_type: typing.Union[CreateReaderCheckoutBodyCardTypeInput, NotGivenType] = NOT_GIVEN, + description: typing.Union[str, NotGivenType] = NOT_GIVEN, + installments: typing.Union[int, NotGivenType] = NOT_GIVEN, + return_url: typing.Union[str, NotGivenType] = NOT_GIVEN, + tip_rates: typing.Union[typing.Sequence[float], NotGivenType] = NOT_GIVEN, + tip_timeout: typing.Union[int, NotGivenType] = NOT_GIVEN, + total_amount: CreateReaderCheckoutBodyTotalAmountInput, headers: typing.Optional[HeaderTypes] = None, ) -> CreateReaderCheckoutResponse: """ @@ -404,9 +499,28 @@ def create_checkout( **Note**: If the target device is a Solo, it must be in version 3.3.24.3 or higher. """ + body_data: dict[str, typing.Any] = {} + if not isinstance(aade, NotGivenType): + body_data["aade"] = aade + if not isinstance(affiliate, NotGivenType): + body_data["affiliate"] = affiliate + if not isinstance(card_type, NotGivenType): + body_data["card_type"] = card_type + if not isinstance(description, NotGivenType): + body_data["description"] = description + if not isinstance(installments, NotGivenType): + body_data["installments"] = installments + if not isinstance(return_url, NotGivenType): + body_data["return_url"] = return_url + if not isinstance(tip_rates, NotGivenType): + body_data["tip_rates"] = list(tip_rates) + if not isinstance(tip_timeout, NotGivenType): + body_data["tip_timeout"] = tip_timeout + body_data["total_amount"] = total_amount + resp = self._client.post( f"/v0.1/merchants/{merchant_code}/readers/{reader_id}/checkout", - json=body.model_dump(exclude_unset=True), + json=serialize_request_data(body_data), headers=headers, ) if resp.status_code == 201: @@ -430,7 +544,7 @@ def create_checkout( body=resp.text, ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) def get_status( self, merchant_code: str, reader_id: str, headers: typing.Optional[HeaderTypes] = None @@ -481,7 +595,7 @@ def get_status( "Response when given reader is not found", status=resp.status_code, body=resp.text ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) def terminate_checkout( self, merchant_code: str, reader_id: str, headers: typing.Optional[HeaderTypes] = None @@ -529,7 +643,7 @@ def terminate_checkout( body=resp.text, ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) class AsyncReadersResource(AsyncResource): @@ -559,12 +673,15 @@ async def list( body=resp.text, ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) async def create( self, merchant_code: str, - body: CreateReaderBody, + *, + pairing_code: ReaderPairingCodeInput, + name: ReaderNameInput, + metadata: typing.Union[MetadataInput, NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> Reader: """ @@ -572,9 +689,15 @@ async def create( Create a new Reader for the merchant account. """ + body_data: dict[str, typing.Any] = {} + body_data["pairing_code"] = pairing_code + body_data["name"] = name + if not isinstance(metadata, NotGivenType): + body_data["metadata"] = metadata + resp = await self._client.post( f"/v0.1/merchants/{merchant_code}/readers", - json=body.model_dump(exclude_unset=True), + json=serialize_request_data(body_data), headers=headers, ) if resp.status_code == 201: @@ -592,7 +715,7 @@ async def create( "The Reader is not in a pending state.", status=resp.status_code, body=resp.text ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) async def get( self, merchant_code: str, id: ReaderId, headers: typing.Optional[HeaderTypes] = None @@ -615,7 +738,7 @@ async def get( body=resp.text, ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) async def delete( self, merchant_code: str, id: ReaderId, headers: typing.Optional[HeaderTypes] = None @@ -638,13 +761,15 @@ async def delete( body=resp.text, ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) async def update( self, merchant_code: str, id: ReaderId, - body: UpdateReaderBody, + *, + name: typing.Union[ReaderNameInput, NotGivenType] = NOT_GIVEN, + metadata: typing.Union[MetadataInput, NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> Reader: """ @@ -652,9 +777,15 @@ async def update( Update a Reader. """ + body_data: dict[str, typing.Any] = {} + if not isinstance(name, NotGivenType): + body_data["name"] = name + if not isinstance(metadata, NotGivenType): + body_data["metadata"] = metadata + resp = await self._client.patch( f"/v0.1/merchants/{merchant_code}/readers/{id}", - json=body.model_dump(exclude_unset=True), + json=serialize_request_data(body_data), headers=headers, ) if resp.status_code == 200: @@ -672,13 +803,22 @@ async def update( body=resp.text, ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) async def create_checkout( self, merchant_code: str, reader_id: str, - body: CreateReaderCheckoutBody, + *, + aade: typing.Union[CreateReaderCheckoutBodyAadeInput, NotGivenType] = NOT_GIVEN, + affiliate: typing.Union[CreateReaderCheckoutBodyAffiliateInput, NotGivenType] = NOT_GIVEN, + card_type: typing.Union[CreateReaderCheckoutBodyCardTypeInput, NotGivenType] = NOT_GIVEN, + description: typing.Union[str, NotGivenType] = NOT_GIVEN, + installments: typing.Union[int, NotGivenType] = NOT_GIVEN, + return_url: typing.Union[str, NotGivenType] = NOT_GIVEN, + tip_rates: typing.Union[typing.Sequence[float], NotGivenType] = NOT_GIVEN, + tip_timeout: typing.Union[int, NotGivenType] = NOT_GIVEN, + total_amount: CreateReaderCheckoutBodyTotalAmountInput, headers: typing.Optional[HeaderTypes] = None, ) -> CreateReaderCheckoutResponse: """ @@ -696,9 +836,28 @@ async def create_checkout( **Note**: If the target device is a Solo, it must be in version 3.3.24.3 or higher. """ + body_data: dict[str, typing.Any] = {} + if not isinstance(aade, NotGivenType): + body_data["aade"] = aade + if not isinstance(affiliate, NotGivenType): + body_data["affiliate"] = affiliate + if not isinstance(card_type, NotGivenType): + body_data["card_type"] = card_type + if not isinstance(description, NotGivenType): + body_data["description"] = description + if not isinstance(installments, NotGivenType): + body_data["installments"] = installments + if not isinstance(return_url, NotGivenType): + body_data["return_url"] = return_url + if not isinstance(tip_rates, NotGivenType): + body_data["tip_rates"] = list(tip_rates) + if not isinstance(tip_timeout, NotGivenType): + body_data["tip_timeout"] = tip_timeout + body_data["total_amount"] = total_amount + resp = await self._client.post( f"/v0.1/merchants/{merchant_code}/readers/{reader_id}/checkout", - json=body.model_dump(exclude_unset=True), + json=serialize_request_data(body_data), headers=headers, ) if resp.status_code == 201: @@ -722,7 +881,7 @@ async def create_checkout( body=resp.text, ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) async def get_status( self, merchant_code: str, reader_id: str, headers: typing.Optional[HeaderTypes] = None @@ -773,7 +932,7 @@ async def get_status( "Response when given reader is not found", status=resp.status_code, body=resp.text ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) async def terminate_checkout( self, merchant_code: str, reader_id: str, headers: typing.Optional[HeaderTypes] = None @@ -821,4 +980,4 @@ async def terminate_checkout( body=resp.text, ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) diff --git a/sumup/receipts/__init__.py b/sumup/receipts/__init__.py index 4c6c29f3..11fbe3b6 100755 --- a/sumup/receipts/__init__.py +++ b/sumup/receipts/__init__.py @@ -2,7 +2,6 @@ from .resource import ( ReceiptsResource, AsyncReceiptsResource, - GetReceiptParams, ) from ..types import ( Error, @@ -23,7 +22,6 @@ __all__ = [ "ReceiptsResource", "AsyncReceiptsResource", - "GetReceiptParams", "Error", "EventId", "EventStatus", diff --git a/sumup/receipts/resource.py b/sumup/receipts/resource.py index 90fe073d..659e57c6 100755 --- a/sumup/receipts/resource.py +++ b/sumup/receipts/resource.py @@ -1,27 +1,53 @@ # Code generated by `py-sdk-gen`. DO NOT EDIT. +# ruff: noqa: F401, F541 """ The Receipts model obtains receipt-like details for specific transactions. """ from __future__ import annotations -from .._service import Resource, AsyncResource, HeaderTypes +from .._service import ( + Resource, + AsyncResource, + HeaderTypes, + NotGivenType, + NOT_GIVEN, + serialize_query_params, + serialize_request_data, +) from .._exceptions import APIError from ..types import ( + Error, + EventId, + EventStatus, + EventType, + Problem, Receipt, + ReceiptCard, + ReceiptEvent, + ReceiptMerchantData, + ReceiptReader, + ReceiptTransaction, + TransactionId, +) +from ..types import ( + ErrorInput, + EventIdInput, + EventStatusInput, + EventTypeInput, + ProblemInput, + ReceiptInput, + ReceiptCardInput, + ReceiptEventInput, + ReceiptMerchantDataInput, + ReceiptReaderInput, + ReceiptTransactionInput, + TransactionIdInput, ) +import datetime import httpx import typing import pydantic - - -class GetReceiptParams(pydantic.BaseModel): - """ - GetReceiptParams: query parameters for GetReceipt - """ - - mid: str - - tx_event_id: typing.Optional[int] = None +import typing_extensions class ReceiptsResource(Resource): @@ -33,7 +59,9 @@ def __init__(self, client: httpx.Client) -> None: def get( self, id: str, - params: typing.Optional[GetReceiptParams] = None, + *, + mid: str, + tx_event_id: typing.Union[int, NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> Receipt: """ @@ -41,9 +69,14 @@ def get( Retrieves receipt specific data for a transaction. """ + query_data: dict[str, typing.Any] = {} + query_data["mid"] = mid + if not isinstance(tx_event_id, NotGivenType) and tx_event_id is not None: + query_data["tx_event_id"] = tx_event_id + resp = self._client.get( f"/v1.1/receipts/{id}", - params=params.model_dump(by_alias=True, exclude_none=True) if params else None, + params=serialize_query_params(query_data) if query_data else None, headers=headers, ) if resp.status_code == 200: @@ -65,7 +98,7 @@ def get( body=resp.text, ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) class AsyncReceiptsResource(AsyncResource): @@ -77,7 +110,9 @@ def __init__(self, client: httpx.AsyncClient) -> None: async def get( self, id: str, - params: typing.Optional[GetReceiptParams] = None, + *, + mid: str, + tx_event_id: typing.Union[int, NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> Receipt: """ @@ -85,9 +120,14 @@ async def get( Retrieves receipt specific data for a transaction. """ + query_data: dict[str, typing.Any] = {} + query_data["mid"] = mid + if not isinstance(tx_event_id, NotGivenType) and tx_event_id is not None: + query_data["tx_event_id"] = tx_event_id + resp = await self._client.get( f"/v1.1/receipts/{id}", - params=params.model_dump(by_alias=True, exclude_none=True) if params else None, + params=serialize_query_params(query_data) if query_data else None, headers=headers, ) if resp.status_code == 200: @@ -109,4 +149,4 @@ async def get( body=resp.text, ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) diff --git a/sumup/roles/__init__.py b/sumup/roles/__init__.py index a0192e58..427a5c0f 100755 --- a/sumup/roles/__init__.py +++ b/sumup/roles/__init__.py @@ -2,8 +2,6 @@ from .resource import ( RolesResource, AsyncRolesResource, - CreateMerchantRoleBody, - UpdateMerchantRoleBody, ListMerchantRoles200Response, ) from ..types import ( @@ -16,8 +14,6 @@ __all__ = [ "RolesResource", "AsyncRolesResource", - "CreateMerchantRoleBody", - "UpdateMerchantRoleBody", "ListMerchantRoles200Response", "Metadata", "Problem", diff --git a/sumup/roles/resource.py b/sumup/roles/resource.py index f58d5002..379b1495 100755 --- a/sumup/roles/resource.py +++ b/sumup/roles/resource.py @@ -1,65 +1,75 @@ # Code generated by `py-sdk-gen`. DO NOT EDIT. +# ruff: noqa: F401, F541 """ Endpoints to manage custom roles. Custom roles allow you to tailor roles from individual permissions to match your needs. Once created, you can assign your custom roles to your merchant account members using the memberships. """ from __future__ import annotations -from .._service import Resource, AsyncResource, HeaderTypes +from .._service import ( + Resource, + AsyncResource, + HeaderTypes, + NotGivenType, + NOT_GIVEN, + serialize_query_params, + serialize_request_data, +) from .._exceptions import APIError -from ..types import Metadata, Role +from ..types import Metadata, Problem, Role +from ..types import MetadataInput, ProblemInput, RoleInput +import datetime import httpx import typing import pydantic +import typing_extensions -class CreateMerchantRoleBody(pydantic.BaseModel): +class CreateMerchantRoleBodyInput(typing_extensions.TypedDict, total=False): """ CreateMerchantRoleBody is a schema definition. """ - name: str - """ - User-defined name of the role. - """ - - permissions: list[str] - """ - User's permissions. - Max items: 100 - """ - - description: typing.Optional[str] = None - """ - User-defined description of the role. - """ - - metadata: typing.Optional[Metadata] = None - """ - Set of user-defined key-value pairs attached to the object. Partial updates are not supported. When updating, alwayssubmit whole metadata. Maximum of 64 parameters are allowed in the object. - Max properties: 64 - """ - - -class UpdateMerchantRoleBody(pydantic.BaseModel): + name: typing_extensions.Required[ + typing_extensions.Annotated[str, typing_extensions.Doc("User-defined name of the role.")] + ] + permissions: typing_extensions.Required[ + typing_extensions.Annotated[ + typing.Sequence[str], typing_extensions.Doc("User's permissions.\nMax items: 100") + ] + ] + description: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, typing_extensions.Doc("User-defined description of the role.") + ] + ] + metadata: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + MetadataInput, + typing_extensions.Doc( + "Set of user-defined key-value pairs attached to the object. Partial updates are not supported. When updating, alwayssubmit whole metadata. Maximum of 64 parameters are allowed in the object.\nMax properties: 64" + ), + ] + ] + + +class UpdateMerchantRoleBodyInput(typing_extensions.TypedDict, total=False): """ UpdateMerchantRoleBody is a schema definition. """ - description: typing.Optional[str] = None - """ - User-defined description of the role. - """ - - name: typing.Optional[str] = None - """ - User-defined name of the role. - """ - - permissions: typing.Optional[list[str]] = None - """ - User's permissions. - Max items: 100 - """ + description: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, typing_extensions.Doc("User-defined description of the role.") + ] + ] + name: typing_extensions.NotRequired[ + typing_extensions.Annotated[str, typing_extensions.Doc("User-defined name of the role.")] + ] + permissions: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + typing.Sequence[str], typing_extensions.Doc("User's permissions.\nMax items: 100") + ] + ] class ListMerchantRoles200Response(pydantic.BaseModel): @@ -70,6 +80,13 @@ class ListMerchantRoles200Response(pydantic.BaseModel): items: list[Role] +class ListMerchantRoles200ResponseDict(typing_extensions.TypedDict, total=False): + items: typing_extensions.Required[typing.Sequence[RoleInput]] + + +ListMerchantRoles200ResponseInput = ListMerchantRoles200ResponseDict + + class RolesResource(Resource): """API resource for the Roles endpoints.""" @@ -93,12 +110,16 @@ def list( elif resp.status_code == 404: raise APIError("Merchant not found.", status=resp.status_code, body=resp.text) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) def create( self, merchant_code: str, - body: CreateMerchantRoleBody, + *, + name: str, + permissions: typing.Sequence[str], + metadata: typing.Union[MetadataInput, NotGivenType] = NOT_GIVEN, + description: typing.Union[str, NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> Role: """ @@ -106,9 +127,17 @@ def create( Create a custom role for the merchant. Roles are defined by the set of permissions that they grant to the members thatthey are assigned to. """ + body_data: dict[str, typing.Any] = {} + body_data["name"] = name + body_data["permissions"] = list(permissions) + if not isinstance(metadata, NotGivenType): + body_data["metadata"] = metadata + if not isinstance(description, NotGivenType): + body_data["description"] = description + resp = self._client.post( f"/v0.1/merchants/{merchant_code}/roles", - json=body.model_dump(exclude_unset=True), + json=serialize_request_data(body_data), headers=headers, ) if resp.status_code == 201: @@ -118,7 +147,7 @@ def create( elif resp.status_code == 404: raise APIError("Merchant not found.", status=resp.status_code, body=resp.text) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) def get( self, merchant_code: str, role_id: str, headers: typing.Optional[HeaderTypes] = None @@ -137,7 +166,7 @@ def get( elif resp.status_code == 404: raise APIError("Merchant or role not found.", status=resp.status_code, body=resp.text) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) def delete( self, merchant_code: str, role_id: str, headers: typing.Optional[HeaderTypes] = None @@ -158,13 +187,16 @@ def delete( elif resp.status_code == 404: raise APIError("Merchant not found.", status=resp.status_code, body=resp.text) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) def update( self, merchant_code: str, role_id: str, - body: UpdateMerchantRoleBody, + *, + name: typing.Union[str, NotGivenType] = NOT_GIVEN, + permissions: typing.Union[typing.Sequence[str], NotGivenType] = NOT_GIVEN, + description: typing.Union[str, NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> Role: """ @@ -172,9 +204,17 @@ def update( Update a custom role. """ + body_data: dict[str, typing.Any] = {} + if not isinstance(name, NotGivenType): + body_data["name"] = name + if not isinstance(permissions, NotGivenType): + body_data["permissions"] = list(permissions) + if not isinstance(description, NotGivenType): + body_data["description"] = description + resp = self._client.patch( f"/v0.1/merchants/{merchant_code}/roles/{role_id}", - json=body.model_dump(exclude_unset=True), + json=serialize_request_data(body_data), headers=headers, ) if resp.status_code == 200: @@ -184,7 +224,7 @@ def update( elif resp.status_code == 404: raise APIError("Merchant not found.", status=resp.status_code, body=resp.text) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) class AsyncRolesResource(AsyncResource): @@ -210,12 +250,16 @@ async def list( elif resp.status_code == 404: raise APIError("Merchant not found.", status=resp.status_code, body=resp.text) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) async def create( self, merchant_code: str, - body: CreateMerchantRoleBody, + *, + name: str, + permissions: typing.Sequence[str], + metadata: typing.Union[MetadataInput, NotGivenType] = NOT_GIVEN, + description: typing.Union[str, NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> Role: """ @@ -223,9 +267,17 @@ async def create( Create a custom role for the merchant. Roles are defined by the set of permissions that they grant to the members thatthey are assigned to. """ + body_data: dict[str, typing.Any] = {} + body_data["name"] = name + body_data["permissions"] = list(permissions) + if not isinstance(metadata, NotGivenType): + body_data["metadata"] = metadata + if not isinstance(description, NotGivenType): + body_data["description"] = description + resp = await self._client.post( f"/v0.1/merchants/{merchant_code}/roles", - json=body.model_dump(exclude_unset=True), + json=serialize_request_data(body_data), headers=headers, ) if resp.status_code == 201: @@ -235,7 +287,7 @@ async def create( elif resp.status_code == 404: raise APIError("Merchant not found.", status=resp.status_code, body=resp.text) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) async def get( self, merchant_code: str, role_id: str, headers: typing.Optional[HeaderTypes] = None @@ -254,7 +306,7 @@ async def get( elif resp.status_code == 404: raise APIError("Merchant or role not found.", status=resp.status_code, body=resp.text) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) async def delete( self, merchant_code: str, role_id: str, headers: typing.Optional[HeaderTypes] = None @@ -275,13 +327,16 @@ async def delete( elif resp.status_code == 404: raise APIError("Merchant not found.", status=resp.status_code, body=resp.text) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) async def update( self, merchant_code: str, role_id: str, - body: UpdateMerchantRoleBody, + *, + name: typing.Union[str, NotGivenType] = NOT_GIVEN, + permissions: typing.Union[typing.Sequence[str], NotGivenType] = NOT_GIVEN, + description: typing.Union[str, NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> Role: """ @@ -289,9 +344,17 @@ async def update( Update a custom role. """ + body_data: dict[str, typing.Any] = {} + if not isinstance(name, NotGivenType): + body_data["name"] = name + if not isinstance(permissions, NotGivenType): + body_data["permissions"] = list(permissions) + if not isinstance(description, NotGivenType): + body_data["description"] = description + resp = await self._client.patch( f"/v0.1/merchants/{merchant_code}/roles/{role_id}", - json=body.model_dump(exclude_unset=True), + json=serialize_request_data(body_data), headers=headers, ) if resp.status_code == 200: @@ -301,4 +364,4 @@ async def update( elif resp.status_code == 404: raise APIError("Merchant not found.", status=resp.status_code, body=resp.text) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) diff --git a/sumup/subaccounts/__init__.py b/sumup/subaccounts/__init__.py index f9981c2a..e2fd2882 100755 --- a/sumup/subaccounts/__init__.py +++ b/sumup/subaccounts/__init__.py @@ -2,11 +2,6 @@ from .resource import ( SubaccountsResource, AsyncSubaccountsResource, - CreateSubAccountBodyPermissions, - CreateSubAccountBody, - UpdateSubAccountBodyPermissions, - UpdateSubAccountBody, - ListSubAccountsParams, ) from ..types import ( Operator, @@ -18,11 +13,6 @@ __all__ = [ "SubaccountsResource", "AsyncSubaccountsResource", - "CreateSubAccountBodyPermissions", - "CreateSubAccountBody", - "UpdateSubAccountBodyPermissions", - "UpdateSubAccountBody", - "ListSubAccountsParams", "Operator", "Permissions", "Problem", diff --git a/sumup/subaccounts/resource.py b/sumup/subaccounts/resource.py index 0436f4e4..7602f24c 100755 --- a/sumup/subaccounts/resource.py +++ b/sumup/subaccounts/resource.py @@ -1,100 +1,84 @@ # Code generated by `py-sdk-gen`. DO NOT EDIT. +# ruff: noqa: F401, F541 """ Endpoints for managing merchant sub-accounts (operators). """ from __future__ import annotations -from .._service import Resource, AsyncResource, HeaderTypes +from .._service import ( + Resource, + AsyncResource, + HeaderTypes, + NotGivenType, + NOT_GIVEN, + serialize_query_params, + serialize_request_data, +) from .._exceptions import APIError -from ..types import Operator +from ..types import Operator, Permissions, Problem +from ..types import OperatorInput, PermissionsInput, ProblemInput +import datetime import httpx import typing import pydantic import typing_extensions -class CreateSubAccountBodyPermissions(pydantic.BaseModel): +class CreateSubAccountBodyPermissionsInput(typing_extensions.TypedDict, total=False): """ CreateSubAccountBodyPermissions is a schema definition. """ - create_moto_payments: typing.Optional[bool] = None + create_moto_payments: typing_extensions.NotRequired[bool] + create_referral: typing_extensions.NotRequired[bool] + full_transaction_history_view: typing_extensions.NotRequired[bool] + refund_transactions: typing_extensions.NotRequired[bool] - create_referral: typing.Optional[bool] = None - full_transaction_history_view: typing.Optional[bool] = None - - refund_transactions: typing.Optional[bool] = None - - -class CreateSubAccountBody(pydantic.BaseModel): +class CreateSubAccountBodyInput(typing_extensions.TypedDict, total=False): """ CreateSubAccountBody is a schema definition. """ - password: str - """ - Min length: 8 - """ + password: typing_extensions.Required[ + typing_extensions.Annotated[str, typing_extensions.Doc("Min length: 8")] + ] + username: typing_extensions.Required[ + typing_extensions.Annotated[str, typing_extensions.Doc("Format: email")] + ] + nickname: typing_extensions.NotRequired[str] + permissions: typing_extensions.NotRequired[CreateSubAccountBodyPermissionsInput] - username: str - """ - Format: email - """ - nickname: typing.Optional[str] = None - - permissions: typing.Optional[CreateSubAccountBodyPermissions] = None - - -class UpdateSubAccountBodyPermissions(pydantic.BaseModel): +class UpdateSubAccountBodyPermissionsInput(typing_extensions.TypedDict, total=False): """ UpdateSubAccountBodyPermissions is a schema definition. """ - create_moto_payments: typing.Optional[bool] = None - - create_referral: typing.Optional[bool] = None + create_moto_payments: typing_extensions.NotRequired[bool] + create_referral: typing_extensions.NotRequired[bool] + full_transaction_history_view: typing_extensions.NotRequired[bool] + refund_transactions: typing_extensions.NotRequired[bool] - full_transaction_history_view: typing.Optional[bool] = None - refund_transactions: typing.Optional[bool] = None - - -class UpdateSubAccountBody(pydantic.BaseModel): +class UpdateSubAccountBodyInput(typing_extensions.TypedDict, total=False): """ UpdateSubAccountBody is a schema definition. """ - disabled: typing.Optional[bool] = None - - nickname: typing.Optional[str] = None - - password: typing.Optional[str] = None - """ - Min length: 8 - """ - - permissions: typing.Optional[UpdateSubAccountBodyPermissions] = None - - username: typing.Optional[str] = None - """ - Format: email - Max length: 256 - """ - - -class ListSubAccountsParams(pydantic.BaseModel): - """ - ListSubAccountsParams: query parameters for ListSubAccounts - """ - - include_primary: typing.Optional[bool] = None - - query: typing.Optional[str] = None + disabled: typing_extensions.NotRequired[bool] + nickname: typing_extensions.NotRequired[str] + password: typing_extensions.NotRequired[ + typing_extensions.Annotated[str, typing_extensions.Doc("Min length: 8")] + ] + permissions: typing_extensions.NotRequired[UpdateSubAccountBodyPermissionsInput] + username: typing_extensions.NotRequired[ + typing_extensions.Annotated[str, typing_extensions.Doc("Format: email\nMax length: 256")] + ] ListSubAccounts200Response = list[Operator] +ListSubAccounts200ResponseInput = typing.Sequence[OperatorInput] """ ListSubAccounts200Response is a schema definition. """ @@ -111,7 +95,9 @@ def __init__(self, client: httpx.Client) -> None: ) def list_sub_accounts( self, - params: typing.Optional[ListSubAccountsParams] = None, + *, + query: typing.Union[str, NotGivenType] = NOT_GIVEN, + include_primary: typing.Union[bool, NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> ListSubAccounts200Response: """ @@ -119,9 +105,15 @@ def list_sub_accounts( Returns list of operators for currently authorized user's merchant. """ + query_data: dict[str, typing.Any] = {} + if not isinstance(query, NotGivenType) and query is not None: + query_data["query"] = query + if not isinstance(include_primary, NotGivenType) and include_primary is not None: + query_data["include_primary"] = include_primary + resp = self._client.get( - "/v0.1/me/accounts", - params=params.model_dump(by_alias=True, exclude_none=True) if params else None, + f"/v0.1/me/accounts", + params=serialize_query_params(query_data) if query_data else None, headers=headers, ) if resp.status_code == 200: @@ -133,22 +125,36 @@ def list_sub_accounts( body=resp.text, ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) @typing_extensions.deprecated( "Subaccounts API is deprecated, to create a user in your merchant account please use [Create member](https://developer.sumup.com/api/members/create) instead." ) def create_sub_account( - self, body: CreateSubAccountBody, headers: typing.Optional[HeaderTypes] = None + self, + *, + username: str, + password: str, + nickname: typing.Union[str, NotGivenType] = NOT_GIVEN, + permissions: typing.Union[CreateSubAccountBodyPermissionsInput, NotGivenType] = NOT_GIVEN, + headers: typing.Optional[HeaderTypes] = None, ) -> Operator: """ Create an operator Creates new operator for currently authorized users' merchant. """ + body_data: dict[str, typing.Any] = {} + body_data["username"] = username + body_data["password"] = password + if not isinstance(nickname, NotGivenType): + body_data["nickname"] = nickname + if not isinstance(permissions, NotGivenType): + body_data["permissions"] = permissions + resp = self._client.post( - "/v0.1/me/accounts", - json=body.model_dump(exclude_unset=True), + f"/v0.1/me/accounts", + json=serialize_request_data(body_data), headers=headers, ) if resp.status_code == 200: @@ -158,7 +164,7 @@ def create_sub_account( "Operator creation was forbidden.", status=resp.status_code, body=resp.text ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) @typing_extensions.deprecated( "Subaccounts API is deprecated, to get a user that's a member of your merchant account please use [Get member](https://developer.sumup.com/api/members/get) instead." @@ -184,7 +190,7 @@ def compat_get_operator( body=resp.text, ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) @typing_extensions.deprecated( "Subaccounts API is deprecated, to update a user that's a member of your merchant account please use [Update member](https://developer.sumup.com/api/members/update) instead." @@ -192,7 +198,12 @@ def compat_get_operator( def update_sub_account( self, operator_id: int, - body: UpdateSubAccountBody, + *, + password: typing.Union[str, NotGivenType] = NOT_GIVEN, + username: typing.Union[str, NotGivenType] = NOT_GIVEN, + disabled: typing.Union[bool, NotGivenType] = NOT_GIVEN, + nickname: typing.Union[str, NotGivenType] = NOT_GIVEN, + permissions: typing.Union[UpdateSubAccountBodyPermissionsInput, NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> Operator: """ @@ -200,9 +211,21 @@ def update_sub_account( Updates operator. If the operator was disabled and their password is updated they will be unblocked. """ + body_data: dict[str, typing.Any] = {} + if not isinstance(password, NotGivenType): + body_data["password"] = password + if not isinstance(username, NotGivenType): + body_data["username"] = username + if not isinstance(disabled, NotGivenType): + body_data["disabled"] = disabled + if not isinstance(nickname, NotGivenType): + body_data["nickname"] = nickname + if not isinstance(permissions, NotGivenType): + body_data["permissions"] = permissions + resp = self._client.put( f"/v0.1/me/accounts/{operator_id}", - json=body.model_dump(exclude_unset=True), + json=serialize_request_data(body_data), headers=headers, ) if resp.status_code == 200: @@ -214,7 +237,7 @@ def update_sub_account( body=resp.text, ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) class AsyncSubaccountsResource(AsyncResource): @@ -228,7 +251,9 @@ def __init__(self, client: httpx.AsyncClient) -> None: ) async def list_sub_accounts( self, - params: typing.Optional[ListSubAccountsParams] = None, + *, + query: typing.Union[str, NotGivenType] = NOT_GIVEN, + include_primary: typing.Union[bool, NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> ListSubAccounts200Response: """ @@ -236,9 +261,15 @@ async def list_sub_accounts( Returns list of operators for currently authorized user's merchant. """ + query_data: dict[str, typing.Any] = {} + if not isinstance(query, NotGivenType) and query is not None: + query_data["query"] = query + if not isinstance(include_primary, NotGivenType) and include_primary is not None: + query_data["include_primary"] = include_primary + resp = await self._client.get( - "/v0.1/me/accounts", - params=params.model_dump(by_alias=True, exclude_none=True) if params else None, + f"/v0.1/me/accounts", + params=serialize_query_params(query_data) if query_data else None, headers=headers, ) if resp.status_code == 200: @@ -250,22 +281,36 @@ async def list_sub_accounts( body=resp.text, ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) @typing_extensions.deprecated( "Subaccounts API is deprecated, to create a user in your merchant account please use [Create member](https://developer.sumup.com/api/members/create) instead." ) async def create_sub_account( - self, body: CreateSubAccountBody, headers: typing.Optional[HeaderTypes] = None + self, + *, + username: str, + password: str, + nickname: typing.Union[str, NotGivenType] = NOT_GIVEN, + permissions: typing.Union[CreateSubAccountBodyPermissionsInput, NotGivenType] = NOT_GIVEN, + headers: typing.Optional[HeaderTypes] = None, ) -> Operator: """ Create an operator Creates new operator for currently authorized users' merchant. """ + body_data: dict[str, typing.Any] = {} + body_data["username"] = username + body_data["password"] = password + if not isinstance(nickname, NotGivenType): + body_data["nickname"] = nickname + if not isinstance(permissions, NotGivenType): + body_data["permissions"] = permissions + resp = await self._client.post( - "/v0.1/me/accounts", - json=body.model_dump(exclude_unset=True), + f"/v0.1/me/accounts", + json=serialize_request_data(body_data), headers=headers, ) if resp.status_code == 200: @@ -275,7 +320,7 @@ async def create_sub_account( "Operator creation was forbidden.", status=resp.status_code, body=resp.text ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) @typing_extensions.deprecated( "Subaccounts API is deprecated, to get a user that's a member of your merchant account please use [Get member](https://developer.sumup.com/api/members/get) instead." @@ -301,7 +346,7 @@ async def compat_get_operator( body=resp.text, ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) @typing_extensions.deprecated( "Subaccounts API is deprecated, to update a user that's a member of your merchant account please use [Update member](https://developer.sumup.com/api/members/update) instead." @@ -309,7 +354,12 @@ async def compat_get_operator( async def update_sub_account( self, operator_id: int, - body: UpdateSubAccountBody, + *, + password: typing.Union[str, NotGivenType] = NOT_GIVEN, + username: typing.Union[str, NotGivenType] = NOT_GIVEN, + disabled: typing.Union[bool, NotGivenType] = NOT_GIVEN, + nickname: typing.Union[str, NotGivenType] = NOT_GIVEN, + permissions: typing.Union[UpdateSubAccountBodyPermissionsInput, NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> Operator: """ @@ -317,9 +367,21 @@ async def update_sub_account( Updates operator. If the operator was disabled and their password is updated they will be unblocked. """ + body_data: dict[str, typing.Any] = {} + if not isinstance(password, NotGivenType): + body_data["password"] = password + if not isinstance(username, NotGivenType): + body_data["username"] = username + if not isinstance(disabled, NotGivenType): + body_data["disabled"] = disabled + if not isinstance(nickname, NotGivenType): + body_data["nickname"] = nickname + if not isinstance(permissions, NotGivenType): + body_data["permissions"] = permissions + resp = await self._client.put( f"/v0.1/me/accounts/{operator_id}", - json=body.model_dump(exclude_unset=True), + json=serialize_request_data(body_data), headers=headers, ) if resp.status_code == 200: @@ -331,4 +393,4 @@ async def update_sub_account( body=resp.text, ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) diff --git a/sumup/transactions/__init__.py b/sumup/transactions/__init__.py index 0372c3e0..c9d73b07 100755 --- a/sumup/transactions/__init__.py +++ b/sumup/transactions/__init__.py @@ -2,17 +2,12 @@ from .resource import ( TransactionsResource, AsyncTransactionsResource, - RefundTransactionBody, - GetTransactionV21Params, - GetTransactionParams, ListTransactionsV21ParamsOrder, ListTransactionsV21ParamsStatuse, ListTransactionsV21ParamsType, - ListTransactionsV21Params, ListTransactionsParamsOrder, ListTransactionsParamsStatuse, ListTransactionsParamsType, - ListTransactionsParams, ListTransactionsV21200Response, ListTransactions200Response, ) @@ -49,17 +44,12 @@ __all__ = [ "TransactionsResource", "AsyncTransactionsResource", - "RefundTransactionBody", - "GetTransactionV21Params", - "GetTransactionParams", "ListTransactionsV21ParamsOrder", "ListTransactionsV21ParamsStatuse", "ListTransactionsV21ParamsType", - "ListTransactionsV21Params", "ListTransactionsParamsOrder", "ListTransactionsParamsStatuse", "ListTransactionsParamsType", - "ListTransactionsParams", "ListTransactionsV21200Response", "ListTransactions200Response", "CardResponse", diff --git a/sumup/transactions/resource.py b/sumup/transactions/resource.py index d61125e7..2502136b 100755 --- a/sumup/transactions/resource.py +++ b/sumup/transactions/resource.py @@ -1,4 +1,5 @@ # Code generated by `py-sdk-gen`. DO NOT EDIT. +# ruff: noqa: F401, F541 """ Transactions represent completed or attempted payment operations processed for a merchant account. A transaction contains the core payment result, such as the amount, currency, payment method, creation time, and current high-level status. @@ -21,15 +22,72 @@ """ from __future__ import annotations -from .._service import Resource, AsyncResource, HeaderTypes +from .._service import ( + Resource, + AsyncResource, + HeaderTypes, + NotGivenType, + NOT_GIVEN, + serialize_query_params, + serialize_request_data, +) from .._exceptions import APIError from ..types import ( + CardResponse, + CardType, + Currency, + Device, + ElvCardAccount, EntryMode, + Error, + Event, + EventId, + EventStatus, + EventType, + HorizontalAccuracy, + Lat, + Link, + Lon, PaymentType, + Problem, + Product, + TransactionBase, + TransactionCheckoutInfo, + TransactionEvent, TransactionFull, TransactionHistory, + TransactionId, + TransactionMixinHistory, TransactionsHistoryLink, ) +from ..types import ( + CardResponseInput, + CardTypeInput, + CurrencyInput, + DeviceInput, + ElvCardAccountInput, + EntryModeInput, + ErrorInput, + EventInput, + EventIdInput, + EventStatusInput, + EventTypeInput, + HorizontalAccuracyInput, + LatInput, + LinkInput, + LonInput, + PaymentTypeInput, + ProblemInput, + ProductInput, + TransactionBaseInput, + TransactionCheckoutInfoInput, + TransactionEventInput, + TransactionFullInput, + TransactionHistoryInput, + TransactionIdInput, + TransactionMixinHistoryInput, + TransactionsHistoryLinkInput, +) import datetime import httpx import typing @@ -37,138 +95,67 @@ import typing_extensions -class RefundTransactionBody(pydantic.BaseModel): +class RefundTransactionBodyInput(typing_extensions.TypedDict, total=False): """ Optional amount for partial refunds of transactions. """ - amount: typing.Optional[float] = None - """ - Amount to be refunded. Eligible amount can't exceed the amount of the transaction and varies based on countryand currency. If you do not specify a value, the system performs a full refund of the transaction. - """ - - -class GetTransactionV21Params(pydantic.BaseModel): - """ - GetTransactionV21Params: query parameters for GetTransactionV2.1 - """ - - client_transaction_id: typing.Optional[str] = None - - foreign_transaction_id: typing.Optional[str] = None - - id: typing.Optional[str] = None - - transaction_code: typing.Optional[str] = None - - -class GetTransactionParams(pydantic.BaseModel): - """ - GetTransactionParams: query parameters for GetTransaction - """ - - id: typing.Optional[str] = None - - transaction_code: typing.Optional[str] = None + amount: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + float, + typing_extensions.Doc( + "Amount to be refunded. Eligible amount can't exceed the amount of the transaction and varies based on countryand currency. If you do not specify a value, the system performs a full refund of the transaction." + ), + ] + ] ListTransactionsV21ParamsOrder = typing.Union[typing.Literal["ascending", "descending"], str] +ListTransactionsV21ParamsOrderInput = ListTransactionsV21ParamsOrder ListTransactionsV21ParamsStatuse = typing.Union[ typing.Literal["CANCELLED", "CHARGE_BACK", "FAILED", "REFUNDED", "SUCCESSFUL"], str ] +ListTransactionsV21ParamsStatuseInput = ListTransactionsV21ParamsStatuse ListTransactionsV21ParamsType = typing.Union[ typing.Literal["CHARGE_BACK", "PAYMENT", "REFUND"], str ] - - -class ListTransactionsV21Params(pydantic.BaseModel): - """ - ListTransactionsV21Params: query parameters for ListTransactionsV2.1 - """ - - changes_since: typing.Optional[datetime.datetime] = None - - entry_modes: typing.Optional[list[EntryMode]] = pydantic.Field( - default=None, - serialization_alias="entry_modes[]", - validation_alias=pydantic.AliasChoices("entry_modes[]", "entry_modes"), - ) - - limit: typing.Optional[int] = None - - newest_ref: typing.Optional[str] = None - - newest_time: typing.Optional[datetime.datetime] = None - - oldest_ref: typing.Optional[str] = None - - oldest_time: typing.Optional[datetime.datetime] = None - - order: typing.Optional[ListTransactionsV21ParamsOrder] = None - - payment_types: typing.Optional[list[PaymentType]] = None - - statuses: typing.Optional[list[ListTransactionsV21ParamsStatuse]] = pydantic.Field( - default=None, - serialization_alias="statuses[]", - validation_alias=pydantic.AliasChoices("statuses[]", "statuses"), - ) - - transaction_code: typing.Optional[str] = None - - types: typing.Optional[list[ListTransactionsV21ParamsType]] = None - - users: typing.Optional[list[str]] = None - +ListTransactionsV21ParamsTypeInput = ListTransactionsV21ParamsType ListTransactionsParamsOrder = typing.Union[typing.Literal["ascending", "descending"], str] +ListTransactionsParamsOrderInput = ListTransactionsParamsOrder ListTransactionsParamsStatuse = typing.Union[ typing.Literal["CANCELLED", "CHARGE_BACK", "FAILED", "REFUNDED", "SUCCESSFUL"], str ] +ListTransactionsParamsStatuseInput = ListTransactionsParamsStatuse ListTransactionsParamsType = typing.Union[typing.Literal["CHARGE_BACK", "PAYMENT", "REFUND"], str] +ListTransactionsParamsTypeInput = ListTransactionsParamsType -class ListTransactionsParams(pydantic.BaseModel): +class ListTransactionsV21200Response(pydantic.BaseModel): """ - ListTransactionsParams: query parameters for ListTransactions + ListTransactionsV21200Response is a schema definition. """ - changes_since: typing.Optional[datetime.datetime] = None - - limit: typing.Optional[int] = None - - newest_ref: typing.Optional[str] = None - - newest_time: typing.Optional[datetime.datetime] = None - - oldest_ref: typing.Optional[str] = None - - oldest_time: typing.Optional[datetime.datetime] = None - - order: typing.Optional[ListTransactionsParamsOrder] = None + items: typing.Optional[list[TransactionHistory]] = None - payment_types: typing.Optional[list[PaymentType]] = None + links: typing.Optional[list[TransactionsHistoryLink]] = None - statuses: typing.Optional[list[ListTransactionsParamsStatuse]] = pydantic.Field( - default=None, - serialization_alias="statuses[]", - validation_alias=pydantic.AliasChoices("statuses[]", "statuses"), - ) - transaction_code: typing.Optional[str] = None +class ListTransactionsV21200ResponseDict(typing_extensions.TypedDict, total=False): + items: typing_extensions.NotRequired[typing.Sequence[TransactionHistoryInput]] + links: typing_extensions.NotRequired[typing.Sequence[TransactionsHistoryLinkInput]] - types: typing.Optional[list[ListTransactionsParamsType]] = None - users: typing.Optional[list[str]] = None +ListTransactionsV21200ResponseInput = ListTransactionsV21200ResponseDict -class ListTransactionsV21200Response(pydantic.BaseModel): +class ListTransactions200Response(pydantic.BaseModel): """ - ListTransactionsV21200Response is a schema definition. + ListTransactions200Response is a schema definition. """ items: typing.Optional[list[TransactionHistory]] = None @@ -176,14 +163,12 @@ class ListTransactionsV21200Response(pydantic.BaseModel): links: typing.Optional[list[TransactionsHistoryLink]] = None -class ListTransactions200Response(pydantic.BaseModel): - """ - ListTransactions200Response is a schema definition. - """ +class ListTransactions200ResponseDict(typing_extensions.TypedDict, total=False): + items: typing_extensions.NotRequired[typing.Sequence[TransactionHistoryInput]] + links: typing_extensions.NotRequired[typing.Sequence[TransactionsHistoryLinkInput]] - items: typing.Optional[list[TransactionHistory]] = None - links: typing.Optional[list[TransactionsHistoryLink]] = None +ListTransactions200ResponseInput = ListTransactions200ResponseDict class TransactionsResource(Resource): @@ -193,16 +178,24 @@ def __init__(self, client: httpx.Client) -> None: super().__init__(client) def refund( - self, txn_id: str, body: RefundTransactionBody, headers: typing.Optional[HeaderTypes] = None + self, + txn_id: str, + *, + amount: typing.Union[float, NotGivenType] = NOT_GIVEN, + headers: typing.Optional[HeaderTypes] = None, ): """ Refund a transaction Refunds an identified transaction either in full or partially. """ + body_data: dict[str, typing.Any] = {} + if not isinstance(amount, NotGivenType): + body_data["amount"] = amount + resp = self._client.post( f"/v0.1/me/refund/{txn_id}", - json=body.model_dump(exclude_unset=True), + json=serialize_request_data(body_data), headers=headers, ) if resp.status_code == 204: @@ -218,12 +211,16 @@ def refund( body=resp.text, ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) def get( self, merchant_code: str, - params: typing.Optional[GetTransactionV21Params] = None, + *, + id: typing.Union[str, NotGivenType] = NOT_GIVEN, + transaction_code: typing.Union[str, NotGivenType] = NOT_GIVEN, + foreign_transaction_id: typing.Union[str, NotGivenType] = NOT_GIVEN, + client_transaction_id: typing.Union[str, NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> TransactionFull: """ @@ -235,9 +232,25 @@ def get( - `foreign_transaction_id` - `client_transaction_id` """ + query_data: dict[str, typing.Any] = {} + if not isinstance(id, NotGivenType) and id is not None: + query_data["id"] = id + if not isinstance(transaction_code, NotGivenType) and transaction_code is not None: + query_data["transaction_code"] = transaction_code + if ( + not isinstance(foreign_transaction_id, NotGivenType) + and foreign_transaction_id is not None + ): + query_data["foreign_transaction_id"] = foreign_transaction_id + if ( + not isinstance(client_transaction_id, NotGivenType) + and client_transaction_id is not None + ): + query_data["client_transaction_id"] = client_transaction_id + resp = self._client.get( f"/v2.1/merchants/{merchant_code}/transactions", - params=params.model_dump(by_alias=True, exclude_none=True) if params else None, + params=serialize_query_params(query_data) if query_data else None, headers=headers, ) if resp.status_code == 200: @@ -251,12 +264,14 @@ def get( "The requested resource does not exist.", status=resp.status_code, body=resp.text ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) @typing_extensions.deprecated("This method is deprecated") def get_deprecated( self, - params: typing.Optional[GetTransactionParams] = None, + *, + id: typing.Union[str, NotGivenType] = NOT_GIVEN, + transaction_code: typing.Union[str, NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> TransactionFull: """ @@ -268,9 +283,15 @@ def get_deprecated( - `foreign_transaction_id` - `client_transaction_id` """ + query_data: dict[str, typing.Any] = {} + if not isinstance(id, NotGivenType) and id is not None: + query_data["id"] = id + if not isinstance(transaction_code, NotGivenType) and transaction_code is not None: + query_data["transaction_code"] = transaction_code + resp = self._client.get( - "/v0.1/me/transactions", - params=params.model_dump(by_alias=True, exclude_none=True) if params else None, + f"/v0.1/me/transactions", + params=serialize_query_params(query_data) if query_data else None, headers=headers, ) if resp.status_code == 200: @@ -284,12 +305,29 @@ def get_deprecated( "The requested resource does not exist.", status=resp.status_code, body=resp.text ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) def list( self, merchant_code: str, - params: typing.Optional[ListTransactionsV21Params] = None, + *, + transaction_code: typing.Union[str, NotGivenType] = NOT_GIVEN, + order: typing.Union[ListTransactionsV21ParamsOrderInput, NotGivenType] = NOT_GIVEN, + limit: typing.Union[int, NotGivenType] = NOT_GIVEN, + users: typing.Union[typing.Sequence[str], NotGivenType] = NOT_GIVEN, + statuses: typing.Union[ + typing.Sequence[ListTransactionsV21ParamsStatuseInput], NotGivenType + ] = NOT_GIVEN, + payment_types: typing.Union[typing.Sequence[PaymentTypeInput], NotGivenType] = NOT_GIVEN, + entry_modes: typing.Union[typing.Sequence[EntryModeInput], NotGivenType] = NOT_GIVEN, + types: typing.Union[ + typing.Sequence[ListTransactionsV21ParamsTypeInput], NotGivenType + ] = NOT_GIVEN, + changes_since: typing.Union[datetime.datetime, NotGivenType] = NOT_GIVEN, + newest_time: typing.Union[datetime.datetime, NotGivenType] = NOT_GIVEN, + newest_ref: typing.Union[str, NotGivenType] = NOT_GIVEN, + oldest_time: typing.Union[datetime.datetime, NotGivenType] = NOT_GIVEN, + oldest_ref: typing.Union[str, NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> ListTransactionsV21200Response: """ @@ -297,9 +335,37 @@ def list( Lists detailed history of all transactions associated with the merchant profile. """ + query_data: dict[str, typing.Any] = {} + if not isinstance(transaction_code, NotGivenType) and transaction_code is not None: + query_data["transaction_code"] = transaction_code + if not isinstance(order, NotGivenType) and order is not None: + query_data["order"] = order + if not isinstance(limit, NotGivenType) and limit is not None: + query_data["limit"] = limit + if not isinstance(users, NotGivenType) and users is not None: + query_data["users"] = list(users) + if not isinstance(statuses, NotGivenType) and statuses is not None: + query_data["statuses[]"] = list(statuses) + if not isinstance(payment_types, NotGivenType) and payment_types is not None: + query_data["payment_types"] = list(payment_types) + if not isinstance(entry_modes, NotGivenType) and entry_modes is not None: + query_data["entry_modes[]"] = list(entry_modes) + if not isinstance(types, NotGivenType) and types is not None: + query_data["types"] = list(types) + if not isinstance(changes_since, NotGivenType) and changes_since is not None: + query_data["changes_since"] = changes_since + if not isinstance(newest_time, NotGivenType) and newest_time is not None: + query_data["newest_time"] = newest_time + if not isinstance(newest_ref, NotGivenType) and newest_ref is not None: + query_data["newest_ref"] = newest_ref + if not isinstance(oldest_time, NotGivenType) and oldest_time is not None: + query_data["oldest_time"] = oldest_time + if not isinstance(oldest_ref, NotGivenType) and oldest_ref is not None: + query_data["oldest_ref"] = oldest_ref + resp = self._client.get( f"/v2.1/merchants/{merchant_code}/transactions/history", - params=params.model_dump(by_alias=True, exclude_none=True) if params else None, + params=serialize_query_params(query_data) if query_data else None, headers=headers, ) if resp.status_code == 200: @@ -315,12 +381,28 @@ def list( "The request is not authorized.", status=resp.status_code, body=resp.text ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) @typing_extensions.deprecated("This method is deprecated") def list_deprecated( self, - params: typing.Optional[ListTransactionsParams] = None, + *, + transaction_code: typing.Union[str, NotGivenType] = NOT_GIVEN, + order: typing.Union[ListTransactionsParamsOrderInput, NotGivenType] = NOT_GIVEN, + limit: typing.Union[int, NotGivenType] = NOT_GIVEN, + users: typing.Union[typing.Sequence[str], NotGivenType] = NOT_GIVEN, + statuses: typing.Union[ + typing.Sequence[ListTransactionsParamsStatuseInput], NotGivenType + ] = NOT_GIVEN, + payment_types: typing.Union[typing.Sequence[PaymentTypeInput], NotGivenType] = NOT_GIVEN, + types: typing.Union[ + typing.Sequence[ListTransactionsParamsTypeInput], NotGivenType + ] = NOT_GIVEN, + changes_since: typing.Union[datetime.datetime, NotGivenType] = NOT_GIVEN, + newest_time: typing.Union[datetime.datetime, NotGivenType] = NOT_GIVEN, + newest_ref: typing.Union[str, NotGivenType] = NOT_GIVEN, + oldest_time: typing.Union[datetime.datetime, NotGivenType] = NOT_GIVEN, + oldest_ref: typing.Union[str, NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> ListTransactions200Response: """ @@ -328,9 +410,35 @@ def list_deprecated( Lists detailed history of all transactions associated with the merchant profile. """ + query_data: dict[str, typing.Any] = {} + if not isinstance(transaction_code, NotGivenType) and transaction_code is not None: + query_data["transaction_code"] = transaction_code + if not isinstance(order, NotGivenType) and order is not None: + query_data["order"] = order + if not isinstance(limit, NotGivenType) and limit is not None: + query_data["limit"] = limit + if not isinstance(users, NotGivenType) and users is not None: + query_data["users"] = list(users) + if not isinstance(statuses, NotGivenType) and statuses is not None: + query_data["statuses[]"] = list(statuses) + if not isinstance(payment_types, NotGivenType) and payment_types is not None: + query_data["payment_types"] = list(payment_types) + if not isinstance(types, NotGivenType) and types is not None: + query_data["types"] = list(types) + if not isinstance(changes_since, NotGivenType) and changes_since is not None: + query_data["changes_since"] = changes_since + if not isinstance(newest_time, NotGivenType) and newest_time is not None: + query_data["newest_time"] = newest_time + if not isinstance(newest_ref, NotGivenType) and newest_ref is not None: + query_data["newest_ref"] = newest_ref + if not isinstance(oldest_time, NotGivenType) and oldest_time is not None: + query_data["oldest_time"] = oldest_time + if not isinstance(oldest_ref, NotGivenType) and oldest_ref is not None: + query_data["oldest_ref"] = oldest_ref + resp = self._client.get( - "/v0.1/me/transactions/history", - params=params.model_dump(by_alias=True, exclude_none=True) if params else None, + f"/v0.1/me/transactions/history", + params=serialize_query_params(query_data) if query_data else None, headers=headers, ) if resp.status_code == 200: @@ -346,7 +454,7 @@ def list_deprecated( "The request is not authorized.", status=resp.status_code, body=resp.text ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) class AsyncTransactionsResource(AsyncResource): @@ -356,16 +464,24 @@ def __init__(self, client: httpx.AsyncClient) -> None: super().__init__(client) async def refund( - self, txn_id: str, body: RefundTransactionBody, headers: typing.Optional[HeaderTypes] = None + self, + txn_id: str, + *, + amount: typing.Union[float, NotGivenType] = NOT_GIVEN, + headers: typing.Optional[HeaderTypes] = None, ): """ Refund a transaction Refunds an identified transaction either in full or partially. """ + body_data: dict[str, typing.Any] = {} + if not isinstance(amount, NotGivenType): + body_data["amount"] = amount + resp = await self._client.post( f"/v0.1/me/refund/{txn_id}", - json=body.model_dump(exclude_unset=True), + json=serialize_request_data(body_data), headers=headers, ) if resp.status_code == 204: @@ -381,12 +497,16 @@ async def refund( body=resp.text, ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) async def get( self, merchant_code: str, - params: typing.Optional[GetTransactionV21Params] = None, + *, + id: typing.Union[str, NotGivenType] = NOT_GIVEN, + transaction_code: typing.Union[str, NotGivenType] = NOT_GIVEN, + foreign_transaction_id: typing.Union[str, NotGivenType] = NOT_GIVEN, + client_transaction_id: typing.Union[str, NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> TransactionFull: """ @@ -398,9 +518,25 @@ async def get( - `foreign_transaction_id` - `client_transaction_id` """ + query_data: dict[str, typing.Any] = {} + if not isinstance(id, NotGivenType) and id is not None: + query_data["id"] = id + if not isinstance(transaction_code, NotGivenType) and transaction_code is not None: + query_data["transaction_code"] = transaction_code + if ( + not isinstance(foreign_transaction_id, NotGivenType) + and foreign_transaction_id is not None + ): + query_data["foreign_transaction_id"] = foreign_transaction_id + if ( + not isinstance(client_transaction_id, NotGivenType) + and client_transaction_id is not None + ): + query_data["client_transaction_id"] = client_transaction_id + resp = await self._client.get( f"/v2.1/merchants/{merchant_code}/transactions", - params=params.model_dump(by_alias=True, exclude_none=True) if params else None, + params=serialize_query_params(query_data) if query_data else None, headers=headers, ) if resp.status_code == 200: @@ -414,12 +550,14 @@ async def get( "The requested resource does not exist.", status=resp.status_code, body=resp.text ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) @typing_extensions.deprecated("This method is deprecated") async def get_deprecated( self, - params: typing.Optional[GetTransactionParams] = None, + *, + id: typing.Union[str, NotGivenType] = NOT_GIVEN, + transaction_code: typing.Union[str, NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> TransactionFull: """ @@ -431,9 +569,15 @@ async def get_deprecated( - `foreign_transaction_id` - `client_transaction_id` """ + query_data: dict[str, typing.Any] = {} + if not isinstance(id, NotGivenType) and id is not None: + query_data["id"] = id + if not isinstance(transaction_code, NotGivenType) and transaction_code is not None: + query_data["transaction_code"] = transaction_code + resp = await self._client.get( - "/v0.1/me/transactions", - params=params.model_dump(by_alias=True, exclude_none=True) if params else None, + f"/v0.1/me/transactions", + params=serialize_query_params(query_data) if query_data else None, headers=headers, ) if resp.status_code == 200: @@ -447,12 +591,29 @@ async def get_deprecated( "The requested resource does not exist.", status=resp.status_code, body=resp.text ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) async def list( self, merchant_code: str, - params: typing.Optional[ListTransactionsV21Params] = None, + *, + transaction_code: typing.Union[str, NotGivenType] = NOT_GIVEN, + order: typing.Union[ListTransactionsV21ParamsOrderInput, NotGivenType] = NOT_GIVEN, + limit: typing.Union[int, NotGivenType] = NOT_GIVEN, + users: typing.Union[typing.Sequence[str], NotGivenType] = NOT_GIVEN, + statuses: typing.Union[ + typing.Sequence[ListTransactionsV21ParamsStatuseInput], NotGivenType + ] = NOT_GIVEN, + payment_types: typing.Union[typing.Sequence[PaymentTypeInput], NotGivenType] = NOT_GIVEN, + entry_modes: typing.Union[typing.Sequence[EntryModeInput], NotGivenType] = NOT_GIVEN, + types: typing.Union[ + typing.Sequence[ListTransactionsV21ParamsTypeInput], NotGivenType + ] = NOT_GIVEN, + changes_since: typing.Union[datetime.datetime, NotGivenType] = NOT_GIVEN, + newest_time: typing.Union[datetime.datetime, NotGivenType] = NOT_GIVEN, + newest_ref: typing.Union[str, NotGivenType] = NOT_GIVEN, + oldest_time: typing.Union[datetime.datetime, NotGivenType] = NOT_GIVEN, + oldest_ref: typing.Union[str, NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> ListTransactionsV21200Response: """ @@ -460,9 +621,37 @@ async def list( Lists detailed history of all transactions associated with the merchant profile. """ + query_data: dict[str, typing.Any] = {} + if not isinstance(transaction_code, NotGivenType) and transaction_code is not None: + query_data["transaction_code"] = transaction_code + if not isinstance(order, NotGivenType) and order is not None: + query_data["order"] = order + if not isinstance(limit, NotGivenType) and limit is not None: + query_data["limit"] = limit + if not isinstance(users, NotGivenType) and users is not None: + query_data["users"] = list(users) + if not isinstance(statuses, NotGivenType) and statuses is not None: + query_data["statuses[]"] = list(statuses) + if not isinstance(payment_types, NotGivenType) and payment_types is not None: + query_data["payment_types"] = list(payment_types) + if not isinstance(entry_modes, NotGivenType) and entry_modes is not None: + query_data["entry_modes[]"] = list(entry_modes) + if not isinstance(types, NotGivenType) and types is not None: + query_data["types"] = list(types) + if not isinstance(changes_since, NotGivenType) and changes_since is not None: + query_data["changes_since"] = changes_since + if not isinstance(newest_time, NotGivenType) and newest_time is not None: + query_data["newest_time"] = newest_time + if not isinstance(newest_ref, NotGivenType) and newest_ref is not None: + query_data["newest_ref"] = newest_ref + if not isinstance(oldest_time, NotGivenType) and oldest_time is not None: + query_data["oldest_time"] = oldest_time + if not isinstance(oldest_ref, NotGivenType) and oldest_ref is not None: + query_data["oldest_ref"] = oldest_ref + resp = await self._client.get( f"/v2.1/merchants/{merchant_code}/transactions/history", - params=params.model_dump(by_alias=True, exclude_none=True) if params else None, + params=serialize_query_params(query_data) if query_data else None, headers=headers, ) if resp.status_code == 200: @@ -478,12 +667,28 @@ async def list( "The request is not authorized.", status=resp.status_code, body=resp.text ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) @typing_extensions.deprecated("This method is deprecated") async def list_deprecated( self, - params: typing.Optional[ListTransactionsParams] = None, + *, + transaction_code: typing.Union[str, NotGivenType] = NOT_GIVEN, + order: typing.Union[ListTransactionsParamsOrderInput, NotGivenType] = NOT_GIVEN, + limit: typing.Union[int, NotGivenType] = NOT_GIVEN, + users: typing.Union[typing.Sequence[str], NotGivenType] = NOT_GIVEN, + statuses: typing.Union[ + typing.Sequence[ListTransactionsParamsStatuseInput], NotGivenType + ] = NOT_GIVEN, + payment_types: typing.Union[typing.Sequence[PaymentTypeInput], NotGivenType] = NOT_GIVEN, + types: typing.Union[ + typing.Sequence[ListTransactionsParamsTypeInput], NotGivenType + ] = NOT_GIVEN, + changes_since: typing.Union[datetime.datetime, NotGivenType] = NOT_GIVEN, + newest_time: typing.Union[datetime.datetime, NotGivenType] = NOT_GIVEN, + newest_ref: typing.Union[str, NotGivenType] = NOT_GIVEN, + oldest_time: typing.Union[datetime.datetime, NotGivenType] = NOT_GIVEN, + oldest_ref: typing.Union[str, NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> ListTransactions200Response: """ @@ -491,9 +696,35 @@ async def list_deprecated( Lists detailed history of all transactions associated with the merchant profile. """ + query_data: dict[str, typing.Any] = {} + if not isinstance(transaction_code, NotGivenType) and transaction_code is not None: + query_data["transaction_code"] = transaction_code + if not isinstance(order, NotGivenType) and order is not None: + query_data["order"] = order + if not isinstance(limit, NotGivenType) and limit is not None: + query_data["limit"] = limit + if not isinstance(users, NotGivenType) and users is not None: + query_data["users"] = list(users) + if not isinstance(statuses, NotGivenType) and statuses is not None: + query_data["statuses[]"] = list(statuses) + if not isinstance(payment_types, NotGivenType) and payment_types is not None: + query_data["payment_types"] = list(payment_types) + if not isinstance(types, NotGivenType) and types is not None: + query_data["types"] = list(types) + if not isinstance(changes_since, NotGivenType) and changes_since is not None: + query_data["changes_since"] = changes_since + if not isinstance(newest_time, NotGivenType) and newest_time is not None: + query_data["newest_time"] = newest_time + if not isinstance(newest_ref, NotGivenType) and newest_ref is not None: + query_data["newest_ref"] = newest_ref + if not isinstance(oldest_time, NotGivenType) and oldest_time is not None: + query_data["oldest_time"] = oldest_time + if not isinstance(oldest_ref, NotGivenType) and oldest_ref is not None: + query_data["oldest_ref"] = oldest_ref + resp = await self._client.get( - "/v0.1/me/transactions/history", - params=params.model_dump(by_alias=True, exclude_none=True) if params else None, + f"/v0.1/me/transactions/history", + params=serialize_query_params(query_data) if query_data else None, headers=headers, ) if resp.status_code == 200: @@ -509,4 +740,4 @@ async def list_deprecated( "The request is not authorized.", status=resp.status_code, body=resp.text ) else: - raise APIError("Unexpected response", status=resp.status_code, body=resp.text) + raise APIError(f"Unexpected response", status=resp.status_code, body=resp.text) diff --git a/sumup/types/__init__.py b/sumup/types/__init__.py index 3212aae8..29d25f3e 100755 --- a/sumup/types/__init__.py +++ b/sumup/types/__init__.py @@ -3,8 +3,10 @@ import datetime import typing import pydantic +import typing_extensions CountryCode = str +CountryCodeInput = str """ An [ISO3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code. This definition users `oneOf` with a two-character string @@ -128,6 +130,137 @@ class Address(pydantic.BaseModel): """ +class AddressDict(typing_extensions.TypedDict, total=False): + country: typing_extensions.Required[ + typing_extensions.Annotated[ + CountryCodeInput, + typing_extensions.Doc( + "An [ISO3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2)\ncountry code. This definition users `oneOf` with a two-character string\ntype to allow for support of future countries in client code.\nMin length: 2\nMax length: 2\nPattern: ^[A-Z]{2}$" + ), + ] + ] + autonomous_community: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "In Spain, an autonomous community is the first sub-national level of political and administrative division.\nMax length: 512" + ), + ] + ] + city: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, typing_extensions.Doc("The city of the address.\nMax length: 512") + ] + ] + commune: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + 'In many countries, terms cognate with "commune" are used, referring to the community living in the area andthe common interest. Used in countries such as Chile.\nMax length: 512' + ), + ] + ] + county: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "A county is a geographic region of a country used for administrative or other purposes in some nations. Usedin countries such as Ireland, Romania, etc.\nMax length: 512" + ), + ] + ] + department: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "A department (French: département, Spanish: departamento) is an administrative or political division inseveral countries. Used in countries such as Colombia.\nMax length: 512" + ), + ] + ] + district: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "A district is a type of administrative division that in some countries is managed by the local government. Usedin countries such as Portugal.\nMax length: 512" + ), + ] + ] + eircode: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, typing_extensions.Doc("A postal address in Ireland.\nMax length: 512") + ] + ] + municipality: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "A municipality is usually a single administrative division having corporate status and powers of self-government orjurisdiction as granted by national and regional laws to which it is subordinate. Used in countries such asColombia.\nMax length: 512" + ), + ] + ] + neighborhood: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Locality level of the address. Used in countries such as Brazil or Chile.\nMax length: 512" + ), + ] + ] + post_code: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "The postal code (aka. zip code) of the address.\nMax length: 32" + ), + ] + ] + post_town: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "A post town is a required part of all postal addresses in the United Kingdom and Ireland, and a basic unitof the postal delivery system.\nMax length: 512" + ), + ] + ] + province: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "The province where the address is located. This may not be relevant in some countries.\nMax length: 512" + ), + ] + ] + region: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "The region where the address is located. This may not be relevant in some countries.\nMax length: 512" + ), + ] + ] + state: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + 'Most often, a country has a single state, with various administrative divisions. The term "state" is sometimesused to refer to the federated polities that make up the federation. Used in countries such as the United Statesand Brazil.\nMax length: 512' + ), + ] + ] + street_address: typing_extensions.NotRequired[ + typing_extensions.Annotated[typing.Sequence[str], typing_extensions.Doc("Max items: 2")] + ] + zip_code: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "A US system of postal codes used by the United States Postal Service (USPS).\nMax length: 512" + ), + ] + ] + + +AddressInput = AddressDict + + class AddressLegacy(pydantic.BaseModel): """ Profile's personal address information. @@ -164,7 +297,49 @@ class AddressLegacy(pydantic.BaseModel): """ +class AddressLegacyDict(typing_extensions.TypedDict, total=False): + city: typing_extensions.NotRequired[ + typing_extensions.Annotated[str, typing_extensions.Doc("City name from the address.")] + ] + country: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Two letter country code formatted according to [ISO3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2)." + ), + ] + ] + line_1: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "First line of the address with details of the street name and number." + ), + ] + ] + line_2: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Second line of the address with details of the building, unit, apartment, and floor numbers." + ), + ] + ] + postal_code: typing_extensions.NotRequired[ + typing_extensions.Annotated[str, typing_extensions.Doc("Postal code from the address.")] + ] + state: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, typing_extensions.Doc("State name or abbreviation from the address.") + ] + ] + + +AddressLegacyInput = AddressLegacyDict + + Attributes = dict[str, object] +AttributesInput = typing.Mapping[str, object] """ Object attributes that are modifiable only by SumUp applications. """ @@ -178,6 +353,7 @@ class AddressLegacy(pydantic.BaseModel): ], str, ] +BadRequestErrorsTypeInput = BadRequestErrorsType class BadRequestErrors(pydantic.BaseModel): @@ -196,6 +372,22 @@ class BadRequestErrors(pydantic.BaseModel): """ +class BadRequestErrorsDict(typing_extensions.TypedDict, total=False): + type: typing_extensions.Required[ + typing_extensions.Annotated[ + BadRequestErrorsTypeInput, typing_extensions.Doc("Key indicating type of error") + ] + ] + detail: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, typing_extensions.Doc("Fuller message giving context to error") + ] + ] + + +BadRequestErrorsInput = BadRequestErrorsDict + + class BadRequest(pydantic.BaseModel): """ 400 Bad Request @@ -204,7 +396,15 @@ class BadRequest(pydantic.BaseModel): errors: BadRequestErrors +class BadRequestDict(typing_extensions.TypedDict, total=False): + errors: typing_extensions.Required[BadRequestErrorsInput] + + +BadRequestInput = BadRequestDict + + ChangeStatus = str +ChangeStatusInput = str """ Reflects the status of changes submitted through the `PATCH` endpoints for the merchant or persons. If somechanges have not been applied yet, the status will be `pending`. If all changes have been applied, the status`done`. The status is only returned after write operations or on read endpoints when the `version` query parameter isprovided. @@ -227,6 +427,20 @@ class Ownership(pydantic.BaseModel): """ +class OwnershipDict(typing_extensions.TypedDict, total=False): + share: typing_extensions.Required[ + typing_extensions.Annotated[ + int, + typing_extensions.Doc( + "The percent of ownership shares held by the person expressed in percent mille (1/100000). Only persons withthe relationship `owner` can have ownership.\nFormat: int32\nMin: 25000\nMax: 100000" + ), + ] + ] + + +OwnershipInput = OwnershipDict + + class PersonalIdentifier(pydantic.BaseModel): """ PersonalIdentifier is a schema definition. @@ -245,7 +459,27 @@ class PersonalIdentifier(pydantic.BaseModel): """ +class PersonalIdentifierDict(typing_extensions.TypedDict, total=False): + ref: typing_extensions.Required[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "The unique reference for the personal identifier type.\nMax length: 32" + ), + ] + ] + value: typing_extensions.Required[ + typing_extensions.Annotated[ + str, typing_extensions.Doc("The company identifier value.\nMax length: 128") + ] + ] + + +PersonalIdentifierInput = PersonalIdentifierDict + + PhoneNumber = str +PhoneNumberInput = str """ A publicly available phone number in [E.164](https://en.wikipedia.org/wiki/E.164) format. @@ -253,6 +487,7 @@ class PersonalIdentifier(pydantic.BaseModel): """ Version = str +VersionInput = str """ The version of the resource. The version reflects a specific change submitted to the API via one of the `PATCH`endpoints. """ @@ -363,6 +598,125 @@ class BasePerson(pydantic.BaseModel): """ +class BasePersonDict(typing_extensions.TypedDict, total=False): + id: typing_extensions.Required[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "The unique identifier for the person. This is a [typeid](https://github.com/sumup/typeid).\nRead only" + ), + ] + ] + address: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + AddressInput, + typing_extensions.Doc( + "An address somewhere in the world. The address fields used depend on the country conventions. For example, inGreat Britain, `city` is `post_town`. In the United States, the top-level administrative unit used in addressesis `state`, whereas in Chile it's `region`.\nWhether an address is valid or not depends on whether the locally required fields are present. Fields not supported ina country will be ignored.\nAddress documentation: https://backstage.sumup.net/docs/default/Component/merchants/merchant/#addresses" + ), + ] + ] + birthdate: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + datetime.date, + typing_extensions.Doc( + "The date of birth of the individual, represented as an ISO 8601:2004 [ISO8601‑2004] YYYY-MM-DD format.\nFormat: date" + ), + ] + ] + change_status: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + ChangeStatusInput, + typing_extensions.Doc( + "Reflects the status of changes submitted through the `PATCH` endpoints for the merchant or persons. If somechanges have not been applied yet, the status will be `pending`. If all changes have been applied, the status`done`.\nThe status is only returned after write operations or on read endpoints when the `version` query parameter isprovided.\nRead only" + ), + ] + ] + citizenship: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + CountryCodeInput, + typing_extensions.Doc( + "An [ISO3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2)\ncountry code. This definition users `oneOf` with a two-character string\ntype to allow for support of future countries in client code.\nMin length: 2\nMax length: 2\nPattern: ^[A-Z]{2}$" + ), + ] + ] + country_of_residence: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "An [ISO3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code representing the countrywhere the person resides.\nMin length: 2\nMax length: 2" + ), + ] + ] + family_name: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, typing_extensions.Doc("The last name(s) of the individual.\nMax length: 60") + ] + ] + given_name: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, typing_extensions.Doc("The first name(s) of the individual.\nMax length: 60") + ] + ] + identifiers: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + typing.Sequence[PersonalIdentifierInput], + typing_extensions.Doc("A list of country-specific personal identifiers.\nMax items: 5"), + ] + ] + middle_name: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Middle name(s) of the End-User. Note that in some cultures, people can have multiple middle names; all canbe present, with the names being separated by space characters. Also note that in some cultures, middle namesare not used.\nMax length: 60" + ), + ] + ] + nationality: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "The persons nationality. May be an [ISO3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) countrycode, but legacy data may not conform to this standard." + ), + ] + ] + ownership: typing_extensions.NotRequired[OwnershipInput] + phone_number: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + PhoneNumberInput, + typing_extensions.Doc( + "A publicly available phone number in [E.164](https://en.wikipedia.org/wiki/E.164) format.\nMax length: 16" + ), + ] + ] + relationships: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + typing.Sequence[str], + typing_extensions.Doc( + "A list of roles the person has in the merchant or towards SumUp. A merchant must have at least one person withthe relationship `representative`.\nMin items: 1\nMax items: 1" + ), + ] + ] + user_id: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "A corresponding identity user ID for the person, if they have a user account." + ), + ] + ] + version: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + VersionInput, + typing_extensions.Doc( + "The version of the resource. The version reflects a specific change submitted to the API via one of the `PATCH`endpoints." + ), + ] + ] + + +BasePersonInput = BasePersonDict + + class Branding(pydantic.BaseModel): """ Settings used to apply the Merchant's branding to email receipts, invoices, checkouts, and other products. @@ -412,6 +766,73 @@ class Branding(pydantic.BaseModel): """ +class BrandingDict(typing_extensions.TypedDict, total=False): + background_color: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "A hex color value representing the preferred background color of this merchant." + ), + ] + ] + hero: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Data-URL encoded hero image for the merchant business.\nFormat: uri" + ), + ] + ] + icon: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, typing_extensions.Doc("An icon for the merchant. Must be square.\nFormat: uri") + ] + ] + logo: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "A logo for the merchant that will be used in place of the icon and without the merchant's name next to itif there's sufficient space.\nFormat: uri" + ), + ] + ] + primary_color: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "A hex color value representing the primary branding color of this merchant (your brand color)." + ), + ] + ] + primary_color_fg: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "A hex color value representing the color of the text displayed on branding color of this merchant." + ), + ] + ] + secondary_color: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "A hex color value representing the secondary branding color of this merchant (accent color used for buttons)." + ), + ] + ] + secondary_color_fg: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "A hex color value representing the color of the text displayed on secondary branding color of this merchant." + ), + ] + ] + + +BrandingInput = BrandingDict + + class BusinessProfile(pydantic.BaseModel): """ Business information about the merchant. This information will be visible to the merchant's customers. @@ -465,6 +886,65 @@ class BusinessProfile(pydantic.BaseModel): """ +class BusinessProfileDict(typing_extensions.TypedDict, total=False): + address: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + AddressInput, + typing_extensions.Doc( + "An address somewhere in the world. The address fields used depend on the country conventions. For example, inGreat Britain, `city` is `post_town`. In the United States, the top-level administrative unit used in addressesis `state`, whereas in Chile it's `region`.\nWhether an address is valid or not depends on whether the locally required fields are present. Fields not supported ina country will be ignored.\nAddress documentation: https://backstage.sumup.net/docs/default/Component/merchants/merchant/#addresses" + ), + ] + ] + branding: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + BrandingInput, + typing_extensions.Doc( + "Settings used to apply the Merchant's branding to email receipts, invoices, checkouts, and other products." + ), + ] + ] + dynamic_descriptor: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "The descriptor is the text that your customer sees on their bank account statement.\nThe more recognisable your descriptor is, the less risk you have of receiving disputes (e.g. chargebacks).\nMin length: 1\nMax length: 30\nPattern: ^[a-zA-Z0-9 \\-+\\'_.]{0,30}$" + ), + ] + ] + email: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, typing_extensions.Doc("A publicly available email address.\nMax length: 255") + ] + ] + name: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "The customer-facing business name.\nMin length: 1\nMax length: 150" + ), + ] + ] + phone_number: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + PhoneNumberInput, + typing_extensions.Doc( + "A publicly available phone number in [E.164](https://en.wikipedia.org/wiki/E.164) format.\nMax length: 16" + ), + ] + ] + website: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "The business's publicly available website.\nFormat: uri\nMax length: 255" + ), + ] + ] + + +BusinessProfileInput = BusinessProfileDict + + CardType = typing.Union[ typing.Literal[ "ALELO", @@ -494,10 +974,12 @@ class BusinessProfile(pydantic.BaseModel): ], str, ] +CardTypeInput = CardType CardExpiryMonth = typing.Union[ typing.Literal["01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12"], str ] +CardExpiryMonthInput = CardExpiryMonth class Card(pydantic.BaseModel): @@ -553,6 +1035,65 @@ class Card(pydantic.BaseModel): """ +class CardDict(typing_extensions.TypedDict, total=False): + cvv: typing_extensions.Required[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Three or four-digit card verification value (security code) of the payment card.\nWrite only\nMin length: 3\nMax length: 4" + ), + ] + ] + expiry_month: typing_extensions.Required[ + typing_extensions.Annotated[ + CardExpiryMonthInput, + typing_extensions.Doc( + "Month from the expiration time of the payment card. Accepted format is `MM`.\nWrite only" + ), + ] + ] + expiry_year: typing_extensions.Required[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Year from the expiration time of the payment card. Accepted formats are `YY` and `YYYY`.\nWrite only\nMin length: 2\nMax length: 4" + ), + ] + ] + name: typing_extensions.Required[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Name of the cardholder as it appears on the payment card.\nWrite only" + ), + ] + ] + number: typing_extensions.Required[ + typing_extensions.Annotated[ + str, typing_extensions.Doc("Number of the payment card (without spaces).\nWrite only") + ] + ] + type: typing_extensions.Required[ + typing_extensions.Annotated[ + CardTypeInput, + typing_extensions.Doc( + "Issuing card network of the payment card used for the transaction." + ), + ] + ] + zip_code: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Required five-digit ZIP code. Applicable only to merchant users in the USA.\nWrite only\nMin length: 5\nMax length: 5" + ), + ] + ] + + +CardInput = CardDict + + class CardResponse(pydantic.BaseModel): """ Details of the payment card. @@ -572,6 +1113,28 @@ class CardResponse(pydantic.BaseModel): """ +class CardResponseDict(typing_extensions.TypedDict, total=False): + last_4_digits: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Last 4 digits of the payment card number.\nRead only\nMin length: 4\nMax length: 4" + ), + ] + ] + type: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + CardTypeInput, + typing_extensions.Doc( + "Issuing card network of the payment card used for the transaction." + ), + ] + ] + + +CardResponseInput = CardResponseDict + + Currency = typing.Union[ typing.Literal[ "BGN", @@ -593,6 +1156,7 @@ class CardResponse(pydantic.BaseModel): ], str, ] +CurrencyInput = Currency EntryMode = typing.Union[ typing.Literal[ @@ -626,8 +1190,10 @@ class CardResponse(pydantic.BaseModel): ], str, ] +EntryModeInput = EntryMode MandateResponseStatus = typing.Union[typing.Literal["active", "inactive"], str] +MandateResponseStatusInput = MandateResponseStatus class MandateResponse(pydantic.BaseModel): @@ -651,6 +1217,29 @@ class MandateResponse(pydantic.BaseModel): """ +class MandateResponseDict(typing_extensions.TypedDict, total=False): + merchant_code: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, typing_extensions.Doc("Merchant account for which the mandate is valid.") + ] + ] + status: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + MandateResponseStatusInput, + typing_extensions.Doc("Current lifecycle status of the mandate."), + ] + ] + type: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc("Type of mandate stored for the checkout or payment instrument."), + ] + ] + + +MandateResponseInput = MandateResponseDict + + PaymentType = typing.Union[ typing.Literal[ "APM", @@ -667,10 +1256,12 @@ class MandateResponse(pydantic.BaseModel): ], str, ] +PaymentTypeInput = PaymentType TransactionBaseStatus = typing.Union[ typing.Literal["CANCELLED", "FAILED", "PENDING", "SUCCESSFUL"], str ] +TransactionBaseStatusInput = TransactionBaseStatus class TransactionBase(pydantic.BaseModel): @@ -720,6 +1311,62 @@ class TransactionBase(pydantic.BaseModel): """ +class TransactionBaseDict(typing_extensions.TypedDict, total=False): + amount: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + float, typing_extensions.Doc("Total amount of the transaction.") + ] + ] + currency: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + CurrencyInput, + typing_extensions.Doc( + "Three-letter [ISO4217](https://en.wikipedia.org/wiki/ISO_4217) code of the currency for the amount. Currently supportedcurrency values are enumerated above." + ), + ] + ] + id: typing_extensions.NotRequired[ + typing_extensions.Annotated[str, typing_extensions.Doc("Unique ID of the transaction.")] + ] + installments_count: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + int, + typing_extensions.Doc( + "Current number of the installment for deferred payments.\nMin: 1" + ), + ] + ] + payment_type: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + PaymentTypeInput, typing_extensions.Doc("Payment type used for the transaction.") + ] + ] + status: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + TransactionBaseStatusInput, typing_extensions.Doc("Current status of the transaction.") + ] + ] + timestamp: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + datetime.datetime, + typing_extensions.Doc( + "Date and time of the creation of the transaction. Response format expressed according to [ISO8601](https://en.wikipedia.org/wiki/ISO_8601) code." + ), + ] + ] + transaction_code: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Transaction code returned by the acquirer/processing entity after processing the transaction." + ), + ] + ] + + +TransactionBaseInput = TransactionBaseDict + + class TransactionCheckoutInfo(pydantic.BaseModel): """ Checkout-specific fields associated with a transaction. @@ -751,11 +1398,53 @@ class TransactionCheckoutInfo(pydantic.BaseModel): """ +class TransactionCheckoutInfoDict(typing_extensions.TypedDict, total=False): + auth_code: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Authorization code for the transaction sent by the payment card issuer or bank. Applicable only to card payments." + ), + ] + ] + entry_mode: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + EntryModeInput, typing_extensions.Doc("Entry mode of the payment details.") + ] + ] + merchant_code: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Unique code of the registered merchant to whom the payment is made." + ), + ] + ] + tip_amount: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + float, typing_extensions.Doc("Amount of the tip (out of the total transaction amount).") + ] + ] + vat_amount: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + float, + typing_extensions.Doc( + "Amount of the applicable VAT (out of the total transaction amount)." + ), + ] + ] + + +TransactionCheckoutInfoInput = TransactionCheckoutInfoDict + + CheckoutStatus = typing.Union[typing.Literal["EXPIRED", "FAILED", "PAID", "PENDING"], str] +CheckoutStatusInput = CheckoutStatus CheckoutTransactionStatus = typing.Union[ typing.Literal["CANCELLED", "FAILED", "PENDING", "SUCCESSFUL"], str ] +CheckoutTransactionStatusInput = CheckoutTransactionStatus class CheckoutTransaction(pydantic.BaseModel): @@ -830,6 +1519,97 @@ class CheckoutTransaction(pydantic.BaseModel): """ +class CheckoutTransactionDict(typing_extensions.TypedDict, total=False): + amount: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + float, typing_extensions.Doc("Total amount of the transaction.") + ] + ] + auth_code: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Authorization code for the transaction sent by the payment card issuer or bank. Applicable only to card payments." + ), + ] + ] + currency: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + CurrencyInput, + typing_extensions.Doc( + "Three-letter [ISO4217](https://en.wikipedia.org/wiki/ISO_4217) code of the currency for the amount. Currently supportedcurrency values are enumerated above." + ), + ] + ] + entry_mode: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + EntryModeInput, typing_extensions.Doc("Entry mode of the payment details.") + ] + ] + id: typing_extensions.NotRequired[ + typing_extensions.Annotated[str, typing_extensions.Doc("Unique ID of the transaction.")] + ] + installments_count: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + int, + typing_extensions.Doc( + "Current number of the installment for deferred payments.\nMin: 1" + ), + ] + ] + merchant_code: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Unique code of the registered merchant to whom the payment is made." + ), + ] + ] + payment_type: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + PaymentTypeInput, typing_extensions.Doc("Payment type used for the transaction.") + ] + ] + status: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + CheckoutTransactionStatusInput, + typing_extensions.Doc("Current status of the transaction."), + ] + ] + timestamp: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + datetime.datetime, + typing_extensions.Doc( + "Date and time of the creation of the transaction. Response format expressed according to [ISO8601](https://en.wikipedia.org/wiki/ISO_8601) code." + ), + ] + ] + tip_amount: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + float, typing_extensions.Doc("Amount of the tip (out of the total transaction amount).") + ] + ] + transaction_code: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Transaction code returned by the acquirer/processing entity after processing the transaction." + ), + ] + ] + vat_amount: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + float, + typing_extensions.Doc( + "Amount of the applicable VAT (out of the total transaction amount)." + ), + ] + ] + + +CheckoutTransactionInput = CheckoutTransactionDict + + class Checkout(pydantic.BaseModel): """ Core checkout resource returned by the Checkouts API. A checkout is created before payment processing andthen updated as payment attempts, redirects, and resulting transactions are attached to it. @@ -905,9 +1685,112 @@ class Checkout(pydantic.BaseModel): """ +class CheckoutDict(typing_extensions.TypedDict, total=False): + amount: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + float, + typing_extensions.Doc("Amount to be charged to the payer, expressed in major units."), + ] + ] + checkout_reference: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Merchant-defined reference for the checkout. Use it to correlate the SumUp checkout with your own order, cart,subscription, or payment attempt in your systems.\nMax length: 90" + ), + ] + ] + currency: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + CurrencyInput, + typing_extensions.Doc( + "Three-letter [ISO4217](https://en.wikipedia.org/wiki/ISO_4217) code of the currency for the amount. Currently supportedcurrency values are enumerated above." + ), + ] + ] + customer_id: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Merchant-scoped identifier of the customer associated with the checkout. Use it when storing payment instrumentsor reusing saved customer context for recurring and returning-payer flows." + ), + ] + ] + date: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + datetime.datetime, + typing_extensions.Doc( + "Date and time of the creation of the payment checkout. Response format expressed according to [ISO8601](https://en.wikipedia.org/wiki/ISO_8601) code." + ), + ] + ] + description: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Short merchant-defined description shown in SumUp tools and reporting. Use it to make the checkout easier torecognize in dashboards, support workflows, and reconciliation." + ), + ] + ] + id: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc("Unique SumUp identifier of the checkout resource.\nRead only"), + ] + ] + mandate: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + MandateResponseInput, + typing_extensions.Doc("Details of the mandate linked to the saved payment instrument."), + ] + ] + merchant_code: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, typing_extensions.Doc("Merchant account that receives the payment.") + ] + ] + return_url: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Optional backend callback URL used by SumUp to notify your platform about processing updates for the checkout.\nFormat:uri" + ), + ] + ] + status: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + CheckoutStatusInput, + typing_extensions.Doc( + "Current high-level state of the checkout. `PENDING` means the checkout exists but is not yet completed, `PAID`means a payment succeeded, `FAILED` means the latest processing attempt failed, and `EXPIRED` means the checkoutcan no longer be processed." + ), + ] + ] + transactions: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + typing.Sequence[CheckoutTransactionInput], + typing_extensions.Doc( + "Payment attempts and resulting transaction records linked to this checkout. Use the Transactions endpoints whenyou need the authoritative payment result and event history.\nUnique items only" + ), + ] + ] + valid_until: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + datetime.datetime, + typing_extensions.Doc( + "Optional expiration timestamp. The checkout must be processed before this moment, otherwise it becomes unusable.If omitted, the checkout does not have an explicit expiry time." + ), + ] + ] + + +CheckoutInput = CheckoutDict + + CheckoutAcceptedNextStepMechanism = typing.Union[typing.Literal["browser", "iframe"], str] +CheckoutAcceptedNextStepMechanismInput = CheckoutAcceptedNextStepMechanism CheckoutAcceptedNextStepPayload = dict[str, str] +CheckoutAcceptedNextStepPayloadInput = typing.Mapping[str, str] """ Parameters required to complete the next step. The exact keys depend on the payment provider and flow type. """ @@ -944,6 +1827,46 @@ class CheckoutAcceptedNextStep(pydantic.BaseModel): """ +class CheckoutAcceptedNextStepDict(typing_extensions.TypedDict, total=False): + mechanism: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + typing.Sequence[CheckoutAcceptedNextStepMechanismInput], + typing_extensions.Doc( + "Allowed presentation mechanisms for the next step. `iframe` means the flow can be embedded, while `browser` meansit can be completed through a full-page redirect." + ), + ] + ] + method: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, typing_extensions.Doc("HTTP method to use when following the next step.") + ] + ] + payload: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + CheckoutAcceptedNextStepPayloadInput, + typing_extensions.Doc( + "Parameters required to complete the next step. The exact keys depend on the payment provider and flow type." + ), + ] + ] + redirect_url: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Merchant URL where the payer returns after the external flow finishes." + ), + ] + ] + url: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, typing_extensions.Doc("URL to open or submit in order to continue processing.") + ] + ] + + +CheckoutAcceptedNextStepInput = CheckoutAcceptedNextStepDict + + class CheckoutAccepted(pydantic.BaseModel): """ Response returned when checkout processing requires an additional payer action, such as a 3DS challenge ora redirect to an external payment method page. @@ -955,9 +1878,24 @@ class CheckoutAccepted(pydantic.BaseModel): """ +class CheckoutAcceptedDict(typing_extensions.TypedDict, total=False): + next_step: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + CheckoutAcceptedNextStepInput, + typing_extensions.Doc( + "Instructions for the next action the payer or client must take." + ), + ] + ] + + +CheckoutAcceptedInput = CheckoutAcceptedDict + + CheckoutCreateRequestPurpose = typing.Union[ typing.Literal["CHECKOUT", "SETUP_RECURRING_PAYMENT"], str ] +CheckoutCreateRequestPurposeInput = CheckoutCreateRequestPurpose class CheckoutCreateRequest(pydantic.BaseModel): @@ -1019,11 +1957,94 @@ class CheckoutCreateRequest(pydantic.BaseModel): """ +class CheckoutCreateRequestDict(typing_extensions.TypedDict, total=False): + amount: typing_extensions.Required[ + typing_extensions.Annotated[ + float, + typing_extensions.Doc("Amount to be charged to the payer, expressed in major units."), + ] + ] + checkout_reference: typing_extensions.Required[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Merchant-defined reference for the new checkout. It should be unique enough for you to identify the payment attemptin your own systems.\nMax length: 90" + ), + ] + ] + currency: typing_extensions.Required[ + typing_extensions.Annotated[ + CurrencyInput, + typing_extensions.Doc( + "Three-letter [ISO4217](https://en.wikipedia.org/wiki/ISO_4217) code of the currency for the amount. Currently supportedcurrency values are enumerated above." + ), + ] + ] + merchant_code: typing_extensions.Required[ + typing_extensions.Annotated[ + str, typing_extensions.Doc("Merchant account that should receive the payment.") + ] + ] + customer_id: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Merchant-scoped customer identifier. Required when setting up recurring payments and useful when the checkoutshould be linked to a returning payer." + ), + ] + ] + description: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Short merchant-defined description shown in SumUp tools and reporting for easier identification of the checkout." + ), + ] + ] + purpose: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + CheckoutCreateRequestPurposeInput, + typing_extensions.Doc( + 'Business purpose of the checkout. Use `CHECKOUT` for a standard payment and `SETUP_RECURRING_PAYMENT` whencollecting consent and payment details for future recurring charges.\nDefault: "CHECKOUT"' + ), + ] + ] + redirect_url: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "URL where the payer should be sent after a redirect-based payment or SCA flow completes. This is required for[APMs](https://developer.sumup.com/online-payments/apm/introduction) and recommended for card checkouts thatmay require [3DS](https://developer.sumup.com/online-payments/features/3ds). If it is omitted, the [Payment Widget](https://developer.sumup.com/online-payments/checkouts)can render the challenge in an iframe instead of using a full-page redirect." + ), + ] + ] + return_url: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Optional backend callback URL used by SumUp to notify your platform about processing updates for the checkout.\nFormat:uri" + ), + ] + ] + valid_until: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + datetime.datetime, + typing_extensions.Doc( + "Optional expiration timestamp. The checkout must be processed before this moment, otherwise it becomes unusable.If omitted, the checkout does not have an explicit expiry time." + ), + ] + ] + + +CheckoutCreateRequestInput = CheckoutCreateRequestDict + + CheckoutSuccessStatus = typing.Union[typing.Literal["EXPIRED", "FAILED", "PAID", "PENDING"], str] +CheckoutSuccessStatusInput = CheckoutSuccessStatus CheckoutSuccessTransactionStatus = typing.Union[ typing.Literal["CANCELLED", "FAILED", "PENDING", "SUCCESSFUL"], str ] +CheckoutSuccessTransactionStatusInput = CheckoutSuccessTransactionStatus class CheckoutSuccessTransaction(pydantic.BaseModel): @@ -1098,6 +2119,97 @@ class CheckoutSuccessTransaction(pydantic.BaseModel): """ +class CheckoutSuccessTransactionDict(typing_extensions.TypedDict, total=False): + amount: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + float, typing_extensions.Doc("Total amount of the transaction.") + ] + ] + auth_code: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Authorization code for the transaction sent by the payment card issuer or bank. Applicable only to card payments." + ), + ] + ] + currency: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + CurrencyInput, + typing_extensions.Doc( + "Three-letter [ISO4217](https://en.wikipedia.org/wiki/ISO_4217) code of the currency for the amount. Currently supportedcurrency values are enumerated above." + ), + ] + ] + entry_mode: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + EntryModeInput, typing_extensions.Doc("Entry mode of the payment details.") + ] + ] + id: typing_extensions.NotRequired[ + typing_extensions.Annotated[str, typing_extensions.Doc("Unique ID of the transaction.")] + ] + installments_count: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + int, + typing_extensions.Doc( + "Current number of the installment for deferred payments.\nMin: 1" + ), + ] + ] + merchant_code: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Unique code of the registered merchant to whom the payment is made." + ), + ] + ] + payment_type: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + PaymentTypeInput, typing_extensions.Doc("Payment type used for the transaction.") + ] + ] + status: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + CheckoutSuccessTransactionStatusInput, + typing_extensions.Doc("Current status of the transaction."), + ] + ] + timestamp: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + datetime.datetime, + typing_extensions.Doc( + "Date and time of the creation of the transaction. Response format expressed according to [ISO8601](https://en.wikipedia.org/wiki/ISO_8601) code." + ), + ] + ] + tip_amount: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + float, typing_extensions.Doc("Amount of the tip (out of the total transaction amount).") + ] + ] + transaction_code: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Transaction code returned by the acquirer/processing entity after processing the transaction." + ), + ] + ] + vat_amount: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + float, + typing_extensions.Doc( + "Amount of the applicable VAT (out of the total transaction amount)." + ), + ] + ] + + +CheckoutSuccessTransactionInput = CheckoutSuccessTransactionDict + + class CheckoutSuccessPaymentInstrument(pydantic.BaseModel): """ Details of the saved payment instrument created or reused during checkout processing. @@ -1109,6 +2221,15 @@ class CheckoutSuccessPaymentInstrument(pydantic.BaseModel): """ +class CheckoutSuccessPaymentInstrumentDict(typing_extensions.TypedDict, total=False): + token: typing_extensions.NotRequired[ + typing_extensions.Annotated[str, typing_extensions.Doc("Token value")] + ] + + +CheckoutSuccessPaymentInstrumentInput = CheckoutSuccessPaymentInstrumentDict + + class CheckoutSuccess(pydantic.BaseModel): """ Checkout resource returned after a synchronous processing attempt. In addition to the base checkout fields, itcan include the resulting transaction identifiers and any newly created payment instrument token. @@ -1211,6 +2332,142 @@ class CheckoutSuccess(pydantic.BaseModel): """ +class CheckoutSuccessDict(typing_extensions.TypedDict, total=False): + amount: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + float, + typing_extensions.Doc("Amount to be charged to the payer, expressed in major units."), + ] + ] + checkout_reference: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Merchant-defined reference for the checkout. Use it to correlate the SumUp checkout with your own order, cart,subscription, or payment attempt in your systems.\nMax length: 90" + ), + ] + ] + currency: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + CurrencyInput, + typing_extensions.Doc( + "Three-letter [ISO4217](https://en.wikipedia.org/wiki/ISO_4217) code of the currency for the amount. Currently supportedcurrency values are enumerated above." + ), + ] + ] + customer_id: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Merchant-scoped identifier of the customer associated with the checkout. Use it when storing payment instrumentsor reusing saved customer context for recurring and returning-payer flows." + ), + ] + ] + date: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + datetime.datetime, + typing_extensions.Doc( + "Date and time of the creation of the payment checkout. Response format expressed according to [ISO8601](https://en.wikipedia.org/wiki/ISO_8601) code." + ), + ] + ] + description: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Short merchant-defined description shown in SumUp tools and reporting. Use it to make the checkout easier torecognize in dashboards, support workflows, and reconciliation." + ), + ] + ] + id: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc("Unique SumUp identifier of the checkout resource.\nRead only"), + ] + ] + mandate: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + MandateResponseInput, + typing_extensions.Doc("Details of the mandate linked to the saved payment instrument."), + ] + ] + merchant_code: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, typing_extensions.Doc("Merchant account that receives the payment.") + ] + ] + merchant_name: typing_extensions.NotRequired[ + typing_extensions.Annotated[str, typing_extensions.Doc("Name of the merchant")] + ] + payment_instrument: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + CheckoutSuccessPaymentInstrumentInput, + typing_extensions.Doc( + "Details of the saved payment instrument created or reused during checkout processing." + ), + ] + ] + redirect_url: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "URL where the payer is redirected after a redirect-based payment or SCA flow completes." + ), + ] + ] + return_url: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Optional backend callback URL used by SumUp to notify your platform about processing updates for the checkout.\nFormat:uri" + ), + ] + ] + status: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + CheckoutSuccessStatusInput, + typing_extensions.Doc( + "Current high-level state of the checkout. `PENDING` means the checkout exists but is not yet completed, `PAID`means a payment succeeded, `FAILED` means the latest processing attempt failed, and `EXPIRED` means the checkoutcan no longer be processed." + ), + ] + ] + transaction_code: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Transaction code of the successful transaction with which the payment for the checkout is completed.\nRead only" + ), + ] + ] + transaction_id: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Transaction ID of the successful transaction with which the payment for the checkout is completed.\nRead only" + ), + ] + ] + transactions: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + typing.Sequence[CheckoutSuccessTransactionInput], + typing_extensions.Doc( + "Payment attempts and resulting transaction records linked to this checkout. Use the Transactions endpoints whenyou need the authoritative payment result and event history.\nUnique items only" + ), + ] + ] + valid_until: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + datetime.datetime, + typing_extensions.Doc( + "Optional expiration timestamp. The checkout must be processed before this moment, otherwise it becomes unusable.If omitted, the checkout does not have an explicit expiry time." + ), + ] + ] + + +CheckoutSuccessInput = CheckoutSuccessDict + + class ClassicMerchantIdentifiers(pydantic.BaseModel): """ ClassicMerchantIdentifiers is a schema definition. @@ -1224,6 +2481,20 @@ class ClassicMerchantIdentifiers(pydantic.BaseModel): """ +class ClassicMerchantIdentifiersDict(typing_extensions.TypedDict, total=False): + id: typing_extensions.Required[ + typing_extensions.Annotated[ + int, + typing_extensions.Doc( + "Classic (serial) merchant ID.\nFormat: int64\nDeprecated: this operation is deprecated" + ), + ] + ] + + +ClassicMerchantIdentifiersInput = ClassicMerchantIdentifiersDict + + class CompanyIdentifier(pydantic.BaseModel): """ CompanyIdentifier is a schema definition. @@ -1242,12 +2513,33 @@ class CompanyIdentifier(pydantic.BaseModel): """ +class CompanyIdentifierDict(typing_extensions.TypedDict, total=False): + ref: typing_extensions.Required[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "The unique reference for the company identifier type as defined in the country SDK." + ), + ] + ] + value: typing_extensions.Required[ + typing_extensions.Annotated[ + str, typing_extensions.Doc("The company identifier value.\nMax length: 100") + ] + ] + + +CompanyIdentifierInput = CompanyIdentifierDict + + CompanyIdentifiers = list[CompanyIdentifier] +CompanyIdentifiersInput = typing.Sequence[CompanyIdentifierInput] """ A list of country-specific company identifiers. """ LegalType = str +LegalTypeInput = str """ The unique legal type reference as defined in the country SDK. We do not rely on IDs as used by other services.Consumers of this API are expected to use the country SDK to map to any other IDs, translation keys, ordescriptions. @@ -1323,6 +2615,79 @@ class Company(pydantic.BaseModel): """ +class CompanyDict(typing_extensions.TypedDict, total=False): + address: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + AddressInput, + typing_extensions.Doc( + "An address somewhere in the world. The address fields used depend on the country conventions. For example, inGreat Britain, `city` is `post_town`. In the United States, the top-level administrative unit used in addressesis `state`, whereas in Chile it's `region`.\nWhether an address is valid or not depends on whether the locally required fields are present. Fields not supported ina country will be ignored.\nAddress documentation: https://backstage.sumup.net/docs/default/Component/merchants/merchant/#addresses" + ), + ] + ] + attributes: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + AttributesInput, + typing_extensions.Doc( + "Object attributes that are modifiable only by SumUp applications." + ), + ] + ] + identifiers: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + CompanyIdentifiersInput, + typing_extensions.Doc("A list of country-specific company identifiers."), + ] + ] + legal_type: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + LegalTypeInput, + typing_extensions.Doc( + "The unique legal type reference as defined in the country SDK. We do not rely on IDs as used by other services.Consumers of this API are expected to use the country SDK to map to any other IDs, translation keys, ordescriptions.\nMin length: 4\nMax length: 64\nThe country SDK documentation for legal types.: https://developer.sumup.com/tools/glossary/merchant#legal-types" + ), + ] + ] + merchant_category_code: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "The merchant category code for the account as specified by [ISO18245](https://www.iso.org/standard/33365.html). MCCsare used to classify businesses based on the goods or services they provide.\nPattern: ^[0-9]{4}$" + ), + ] + ] + name: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, typing_extensions.Doc("The company's legal name.\nMin length: 1\nMax length: 150") + ] + ] + phone_number: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + PhoneNumberInput, + typing_extensions.Doc( + "A publicly available phone number in [E.164](https://en.wikipedia.org/wiki/E.164) format.\nMax length: 16" + ), + ] + ] + trading_address: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + AddressInput, + typing_extensions.Doc( + "An address somewhere in the world. The address fields used depend on the country conventions. For example, inGreat Britain, `city` is `post_town`. In the United States, the top-level administrative unit used in addressesis `state`, whereas in Chile it's `region`.\nWhether an address is valid or not depends on whether the locally required fields are present. Fields not supported ina country will be ignored.\nAddress documentation: https://backstage.sumup.net/docs/default/Component/merchants/merchant/#addresses" + ), + ] + ] + website: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "HTTP(S) URL of the company's website.\nFormat: uri\nMax length: 255" + ), + ] + ] + + +CompanyInput = CompanyDict + + class CreateReaderCheckoutErrorErrors(pydantic.BaseModel): """ CreateReaderCheckoutErrorErrors is a schema definition. @@ -1339,6 +2704,18 @@ class CreateReaderCheckoutErrorErrors(pydantic.BaseModel): """ +class CreateReaderCheckoutErrorErrorsDict(typing_extensions.TypedDict, total=False): + type: typing_extensions.Required[ + typing_extensions.Annotated[str, typing_extensions.Doc("Error code")] + ] + detail: typing_extensions.NotRequired[ + typing_extensions.Annotated[str, typing_extensions.Doc("Error message")] + ] + + +CreateReaderCheckoutErrorErrorsInput = CreateReaderCheckoutErrorErrorsDict + + class CreateReaderCheckoutError(pydantic.BaseModel): """ Error description @@ -1347,6 +2724,13 @@ class CreateReaderCheckoutError(pydantic.BaseModel): errors: CreateReaderCheckoutErrorErrors +class CreateReaderCheckoutErrorDict(typing_extensions.TypedDict, total=False): + errors: typing_extensions.Required[CreateReaderCheckoutErrorErrorsInput] + + +CreateReaderCheckoutErrorInput = CreateReaderCheckoutErrorDict + + class CreateReaderCheckoutRequestAade(pydantic.BaseModel): """ Optional object containing data for transactions from ERP integrators in Greece that comply with the AADE1155 protocol. @@ -1369,7 +2753,29 @@ class CreateReaderCheckoutRequestAade(pydantic.BaseModel): """ +class CreateReaderCheckoutRequestAadeDict(typing_extensions.TypedDict, total=False): + provider_id: typing_extensions.Required[ + typing_extensions.Annotated[ + str, typing_extensions.Doc("The identifier of the AADE signature provider.") + ] + ] + signature: typing_extensions.Required[ + typing_extensions.Annotated[ + str, typing_extensions.Doc("The base64 encoded signature of the transaction data.") + ] + ] + signature_data: typing_extensions.Required[ + typing_extensions.Annotated[ + str, typing_extensions.Doc("The string containing the signed transaction data.") + ] + ] + + +CreateReaderCheckoutRequestAadeInput = CreateReaderCheckoutRequestAadeDict + + CreateReaderCheckoutRequestAffiliateTags = dict[str, object] +CreateReaderCheckoutRequestAffiliateTagsInput = typing.Mapping[str, object] """ Additional metadata for the transaction. It is key-value object that can be associated with the transaction. @@ -1408,7 +2814,46 @@ class CreateReaderCheckoutRequestAffiliate(pydantic.BaseModel): """ +class CreateReaderCheckoutRequestAffiliateDict(typing_extensions.TypedDict, total=False): + app_id: typing_extensions.Required[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Application ID of the affiliate.\nIt is a unique identifier for the application and should be set by the integrator in the [Affiliate Keys](https://developer.sumup.com/affiliate-keys) page." + ), + ] + ] + foreign_transaction_id: typing_extensions.Required[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Foreign transaction ID of the affiliate.\nIt is a unique identifier for the transaction.\nIt can be used later to fetch the transaction details via the [Transactions API](https://developer.sumup.com/api/transactions/get)." + ), + ] + ] + key: typing_extensions.Required[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Key of the affiliate.\nIt is a unique identifier for the key and should be generated by the integrator in the [Affiliate Keys](https://developer.sumup.com/affiliate-keys) page." + ), + ] + ] + tags: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + CreateReaderCheckoutRequestAffiliateTagsInput, + typing_extensions.Doc( + "Additional metadata for the transaction.\nIt is key-value object that can be associated with the transaction." + ), + ] + ] + + +CreateReaderCheckoutRequestAffiliateInput = CreateReaderCheckoutRequestAffiliateDict + + CreateReaderCheckoutRequestCardType = typing.Union[typing.Literal["credit", "debit"], str] +CreateReaderCheckoutRequestCardTypeInput = CreateReaderCheckoutRequestCardType class CreateReaderCheckoutRequestTotalAmount(pydantic.BaseModel): @@ -1439,6 +2884,28 @@ class CreateReaderCheckoutRequestTotalAmount(pydantic.BaseModel): """ +class CreateReaderCheckoutRequestTotalAmountDict(typing_extensions.TypedDict, total=False): + currency: typing_extensions.Required[ + typing_extensions.Annotated[str, typing_extensions.Doc("Currency ISO 4217 code")] + ] + minor_unit: typing_extensions.Required[ + typing_extensions.Annotated[ + int, + typing_extensions.Doc( + "The minor units of the currency.\nIt represents the number of decimals of the currency. For the currencies CLP, COP and HUF, the minor unit is0.\nMin: 0" + ), + ] + ] + value: typing_extensions.Required[ + typing_extensions.Annotated[ + int, typing_extensions.Doc("Integer value of the amount.\nMin: 0") + ] + ] + + +CreateReaderCheckoutRequestTotalAmountInput = CreateReaderCheckoutRequestTotalAmountDict + + class CreateReaderCheckoutRequest(pydantic.BaseModel): """ Reader Checkout @@ -1516,6 +2983,82 @@ class CreateReaderCheckoutRequest(pydantic.BaseModel): """ +class CreateReaderCheckoutRequestDict(typing_extensions.TypedDict, total=False): + total_amount: typing_extensions.Required[ + typing_extensions.Annotated[ + CreateReaderCheckoutRequestTotalAmountInput, + typing_extensions.Doc( + "Amount structure.\n\nThe amount is represented as an integer value altogether with the currency and the minor unit.\n\nFor example, EUR 1.00 is represented as value 100 with minor unit of 2." + ), + ] + ] + aade: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + CreateReaderCheckoutRequestAadeInput, + typing_extensions.Doc( + "Optional object containing data for transactions from ERP integrators in Greece that comply with the AADE1155 protocol.\nWhen such regulatory/business requirements apply, this object must be provided and contains the data needed tovalidate the transaction with the AADE signature provider." + ), + ] + ] + affiliate: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + CreateReaderCheckoutRequestAffiliateInput, + typing_extensions.Doc( + "Affiliate metadata for the transaction.\nIt is a field that allow for integrators to track the source of the transaction." + ), + ] + ] + card_type: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + CreateReaderCheckoutRequestCardTypeInput, + typing_extensions.Doc( + "The card type of the card used for the transaction.\nIs is required only for some countries (e.g: Brazil)." + ), + ] + ] + description: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc("Description of the checkout to be shown in the Merchant Sales"), + ] + ] + installments: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + int, + typing_extensions.Doc( + "Number of installments for the transaction.\nIt may vary according to the merchant country.\nFor example, in Brazil, the maximum number of installments is 12.\n\nOmit if the merchant country does support installments.\nOtherwise, the checkout will be rejected.\nMin: 1" + ), + ] + ] + return_url: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Webhook URL to which the payment result will be sent.\nIt must be a HTTPS url.\nFormat: uri" + ), + ] + ] + tip_rates: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + typing.Sequence[float], + typing_extensions.Doc( + "List of tipping rates to be displayed to the cardholder.\nThe rates are in percentage and should be between 0.01 and 0.99.\nThe list should be sorted in ascending order." + ), + ] + ] + tip_timeout: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + int, + typing_extensions.Doc( + "Time in seconds the cardholder has to select a tip rate.\nIf not provided, the default value is 30 seconds.\n\nIt can only be set if `tip_rates` is provided.\n\n**Note**: If the target device is a Solo, it must be in version 3.3.38.0 or higher.\nDefault: 30\n\nMin: 30\nMax: 120" + ), + ] + ] + + +CreateReaderCheckoutRequestInput = CreateReaderCheckoutRequestDict + + class CreateReaderCheckoutResponseData(pydantic.BaseModel): """ CreateReaderCheckoutResponseData is a schema definition. @@ -1529,6 +3072,20 @@ class CreateReaderCheckoutResponseData(pydantic.BaseModel): """ +class CreateReaderCheckoutResponseDataDict(typing_extensions.TypedDict, total=False): + client_transaction_id: typing_extensions.Required[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "The client transaction ID is a unique identifier for the transaction that is generated for the client.\n\nIt can be used later to fetch the transaction details via the [Transactions API](https://developer.sumup.com/api/transactions/get)." + ), + ] + ] + + +CreateReaderCheckoutResponseDataInput = CreateReaderCheckoutResponseDataDict + + class CreateReaderCheckoutResponse(pydantic.BaseModel): """ CreateReaderCheckoutResponse is a schema definition. @@ -1537,7 +3094,15 @@ class CreateReaderCheckoutResponse(pydantic.BaseModel): data: CreateReaderCheckoutResponseData +class CreateReaderCheckoutResponseDict(typing_extensions.TypedDict, total=False): + data: typing_extensions.Required[CreateReaderCheckoutResponseDataInput] + + +CreateReaderCheckoutResponseInput = CreateReaderCheckoutResponseDict + + CreateReaderCheckoutUnprocessableEntityErrors = dict[str, object] +CreateReaderCheckoutUnprocessableEntityErrorsInput = typing.Mapping[str, object] """ CreateReaderCheckoutUnprocessableEntityErrors is a schema definition. """ @@ -1551,6 +3116,13 @@ class CreateReaderCheckoutUnprocessableEntity(pydantic.BaseModel): errors: CreateReaderCheckoutUnprocessableEntityErrors +class CreateReaderCheckoutUnprocessableEntityDict(typing_extensions.TypedDict, total=False): + errors: typing_extensions.Required[CreateReaderCheckoutUnprocessableEntityErrorsInput] + + +CreateReaderCheckoutUnprocessableEntityInput = CreateReaderCheckoutUnprocessableEntityDict + + class CreateReaderTerminateErrorErrors(pydantic.BaseModel): """ CreateReaderTerminateErrorErrors is a schema definition. @@ -1567,6 +3139,18 @@ class CreateReaderTerminateErrorErrors(pydantic.BaseModel): """ +class CreateReaderTerminateErrorErrorsDict(typing_extensions.TypedDict, total=False): + type: typing_extensions.Required[ + typing_extensions.Annotated[str, typing_extensions.Doc("Error code")] + ] + detail: typing_extensions.NotRequired[ + typing_extensions.Annotated[str, typing_extensions.Doc("Error message")] + ] + + +CreateReaderTerminateErrorErrorsInput = CreateReaderTerminateErrorErrorsDict + + class CreateReaderTerminateError(pydantic.BaseModel): """ Error description @@ -1575,7 +3159,15 @@ class CreateReaderTerminateError(pydantic.BaseModel): errors: CreateReaderTerminateErrorErrors +class CreateReaderTerminateErrorDict(typing_extensions.TypedDict, total=False): + errors: typing_extensions.Required[CreateReaderTerminateErrorErrorsInput] + + +CreateReaderTerminateErrorInput = CreateReaderTerminateErrorDict + + CreateReaderTerminateUnprocessableEntityErrors = dict[str, object] +CreateReaderTerminateUnprocessableEntityErrorsInput = typing.Mapping[str, object] """ CreateReaderTerminateUnprocessableEntityErrors is a schema definition. """ @@ -1589,6 +3181,13 @@ class CreateReaderTerminateUnprocessableEntity(pydantic.BaseModel): errors: CreateReaderTerminateUnprocessableEntityErrors +class CreateReaderTerminateUnprocessableEntityDict(typing_extensions.TypedDict, total=False): + errors: typing_extensions.Required[CreateReaderTerminateUnprocessableEntityErrorsInput] + + +CreateReaderTerminateUnprocessableEntityInput = CreateReaderTerminateUnprocessableEntityDict + + class PersonalDetails(pydantic.BaseModel): """ Personal details for the customer. @@ -1632,6 +3231,42 @@ class PersonalDetails(pydantic.BaseModel): """ +class PersonalDetailsDict(typing_extensions.TypedDict, total=False): + address: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + AddressLegacyInput, typing_extensions.Doc("Profile's personal address information.") + ] + ] + birth_date: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + datetime.date, typing_extensions.Doc("Date of birth of the customer.\nFormat: date") + ] + ] + email: typing_extensions.NotRequired[ + typing_extensions.Annotated[str, typing_extensions.Doc("Email address of the customer.")] + ] + first_name: typing_extensions.NotRequired[ + typing_extensions.Annotated[str, typing_extensions.Doc("First name of the customer.")] + ] + last_name: typing_extensions.NotRequired[ + typing_extensions.Annotated[str, typing_extensions.Doc("Last name of the customer.")] + ] + phone: typing_extensions.NotRequired[ + typing_extensions.Annotated[str, typing_extensions.Doc("Phone number of the customer.")] + ] + tax_id: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "An identification number user for tax purposes (e.g. CPF)\nMax length: 255" + ), + ] + ] + + +PersonalDetailsInput = PersonalDetailsDict + + class Customer(pydantic.BaseModel): """ Saved customer details. @@ -1648,6 +3283,20 @@ class Customer(pydantic.BaseModel): """ +class CustomerDict(typing_extensions.TypedDict, total=False): + customer_id: typing_extensions.Required[ + typing_extensions.Annotated[str, typing_extensions.Doc("Unique ID of the customer.")] + ] + personal_details: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + PersonalDetailsInput, typing_extensions.Doc("Personal details for the customer.") + ] + ] + + +CustomerInput = CustomerDict + + class DetailsErrorFailedConstraint(pydantic.BaseModel): """ DetailsErrorFailedConstraint is a schema definition. @@ -1658,6 +3307,14 @@ class DetailsErrorFailedConstraint(pydantic.BaseModel): reference: typing.Optional[str] = None +class DetailsErrorFailedConstraintDict(typing_extensions.TypedDict, total=False): + message: typing_extensions.NotRequired[str] + reference: typing_extensions.NotRequired[str] + + +DetailsErrorFailedConstraintInput = DetailsErrorFailedConstraintDict + + class DetailsError(pydantic.BaseModel): """ Error message structure. @@ -1684,6 +3341,27 @@ class DetailsError(pydantic.BaseModel): """ +class DetailsErrorDict(typing_extensions.TypedDict, total=False): + details: typing_extensions.NotRequired[ + typing_extensions.Annotated[str, typing_extensions.Doc("Details of the error.")] + ] + failed_constraints: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + typing.Sequence[DetailsErrorFailedConstraintInput], + typing_extensions.Doc("List of violated validation constraints."), + ] + ] + status: typing_extensions.NotRequired[ + typing_extensions.Annotated[float, typing_extensions.Doc("The status code.")] + ] + title: typing_extensions.NotRequired[ + typing_extensions.Annotated[str, typing_extensions.Doc("Short title of the error.")] + ] + + +DetailsErrorInput = DetailsErrorDict + + class Device(pydantic.BaseModel): """ Details of the device used to create the transaction. @@ -1715,6 +3393,27 @@ class Device(pydantic.BaseModel): """ +class DeviceDict(typing_extensions.TypedDict, total=False): + model: typing_extensions.NotRequired[ + typing_extensions.Annotated[str, typing_extensions.Doc("Device model.")] + ] + name: typing_extensions.NotRequired[ + typing_extensions.Annotated[str, typing_extensions.Doc("Device name.")] + ] + system_name: typing_extensions.NotRequired[ + typing_extensions.Annotated[str, typing_extensions.Doc("Device OS.")] + ] + system_version: typing_extensions.NotRequired[ + typing_extensions.Annotated[str, typing_extensions.Doc("Device OS version.")] + ] + uuid: typing_extensions.NotRequired[ + typing_extensions.Annotated[str, typing_extensions.Doc("Device UUID.")] + ] + + +DeviceInput = DeviceDict + + class ElvCardAccount(pydantic.BaseModel): """ Details of the ELV card account associated with the transaction. @@ -1741,6 +3440,26 @@ class ElvCardAccount(pydantic.BaseModel): """ +class ElvCardAccountDict(typing_extensions.TypedDict, total=False): + iban: typing_extensions.NotRequired[ + typing_extensions.Annotated[str, typing_extensions.Doc("ELV IBAN.")] + ] + last_4_digits: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, typing_extensions.Doc("ELV card account number last 4 digits.") + ] + ] + sequence_no: typing_extensions.NotRequired[ + typing_extensions.Annotated[int, typing_extensions.Doc("ELV card sequence number.")] + ] + sort_code: typing_extensions.NotRequired[ + typing_extensions.Annotated[str, typing_extensions.Doc("ELV card sort code.")] + ] + + +ElvCardAccountInput = ElvCardAccountDict + + class Error(pydantic.BaseModel): """ Error message structure. @@ -1757,6 +3476,18 @@ class Error(pydantic.BaseModel): """ +class ErrorDict(typing_extensions.TypedDict, total=False): + error_code: typing_extensions.NotRequired[ + typing_extensions.Annotated[str, typing_extensions.Doc("Platform code for the error.")] + ] + message: typing_extensions.NotRequired[ + typing_extensions.Annotated[str, typing_extensions.Doc("Short description of the error.")] + ] + + +ErrorInput = ErrorDict + + class ErrorExtended(pydantic.BaseModel): """ Error payload with the invalid parameter reference. @@ -1778,6 +3509,26 @@ class ErrorExtended(pydantic.BaseModel): """ +class ErrorExtendedDict(typing_extensions.TypedDict, total=False): + error_code: typing_extensions.NotRequired[ + typing_extensions.Annotated[str, typing_extensions.Doc("Platform code for the error.")] + ] + message: typing_extensions.NotRequired[ + typing_extensions.Annotated[str, typing_extensions.Doc("Short description of the error.")] + ] + param: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Parameter name (with relative location) to which the error applies. Parameters from embedded resources aredisplayed using dot notation. For example, `card.name` refers to the `name` parameter embedded in the `card`object." + ), + ] + ] + + +ErrorExtendedInput = ErrorExtendedDict + + class ErrorForbidden(pydantic.BaseModel): """ Error message for forbidden requests. @@ -1799,7 +3550,23 @@ class ErrorForbidden(pydantic.BaseModel): """ +class ErrorForbiddenDict(typing_extensions.TypedDict, total=False): + error_code: typing_extensions.NotRequired[ + typing_extensions.Annotated[str, typing_extensions.Doc("Platform code for the error.")] + ] + error_message: typing_extensions.NotRequired[ + typing_extensions.Annotated[str, typing_extensions.Doc("Short description of the error.")] + ] + status_code: typing_extensions.NotRequired[ + typing_extensions.Annotated[str, typing_extensions.Doc("HTTP status code for the error.")] + ] + + +ErrorForbiddenInput = ErrorForbiddenDict + + EventId = int +EventIdInput = int """ Unique ID of the transaction event. Format: int64 @@ -1811,10 +3578,13 @@ class ErrorForbidden(pydantic.BaseModel): ], str, ] +EventStatusInput = EventStatus EventType = typing.Union[typing.Literal["CHARGE_BACK", "PAYOUT", "PAYOUT_DEDUCTION", "REFUND"], str] +EventTypeInput = EventType TransactionId = str +TransactionIdInput = str """ Unique ID of the transaction. """ @@ -1887,7 +3657,64 @@ class Event(pydantic.BaseModel): """ +class EventDict(typing_extensions.TypedDict, total=False): + amount: typing_extensions.NotRequired[ + typing_extensions.Annotated[float, typing_extensions.Doc("Amount of the event.")] + ] + deducted_amount: typing_extensions.NotRequired[ + typing_extensions.Annotated[float, typing_extensions.Doc("Amount deducted for the event.")] + ] + deducted_fee_amount: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + float, typing_extensions.Doc("Amount of the fee deducted for the event.") + ] + ] + fee_amount: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + float, typing_extensions.Doc("Amount of the fee related to the event.") + ] + ] + id: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + EventIdInput, + typing_extensions.Doc("Unique ID of the transaction event.\nFormat: int64"), + ] + ] + installment_number: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + int, typing_extensions.Doc("Consecutive number of the installment.") + ] + ] + status: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + EventStatusInput, + typing_extensions.Doc( + "Status of the transaction event.\n\nNot every value is used for every event type.\n\n- `PENDING`: The event has been created but is not final yet. Used for events that are still being processed andwhose final outcome is not known yet.\n- `SCHEDULED`: The event is planned for a future payout cycle but has not been executed yet. This applies topayout events before money is actually sent out.\n- `RECONCILED`: The underlying payment has been matched with settlement data and is ready to continue through payoutprocessing, but the funds have not been paid out yet. This applies to payout events.\n- `PAID_OUT`: The payout event has been completed and the funds were included in a merchant payout.\n- `REFUNDED`: A refund event has been accepted and recorded in the refund flow. This is the status returned forrefund events once the transaction amount is being or has been returned to the payer.\n- `SUCCESSFUL`: The event completed successfully. Use this as the generic terminal success status for event typesthat do not expose a more specific business outcome such as `PAID_OUT` or `REFUNDED`.\n- `FAILED`: The event could not be completed. Typical examples are a payout that could not be executed oran event that was rejected during processing." + ), + ] + ] + timestamp: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + datetime.datetime, typing_extensions.Doc("Date and time of the transaction event.") + ] + ] + transaction_id: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + TransactionIdInput, typing_extensions.Doc("Unique ID of the transaction.") + ] + ] + type: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + EventTypeInput, typing_extensions.Doc("Type of the transaction event.") + ] + ] + + +EventInput = EventDict + + FinancialPayoutStatus = typing.Union[typing.Literal["FAILED", "SUCCESSFUL"], str] +FinancialPayoutStatusInput = FinancialPayoutStatus FinancialPayoutType = typing.Union[ typing.Literal[ @@ -1899,6 +3726,7 @@ class Event(pydantic.BaseModel): ], str, ] +FinancialPayoutTypeInput = FinancialPayoutType class FinancialPayout(pydantic.BaseModel): @@ -1928,12 +3756,31 @@ class FinancialPayout(pydantic.BaseModel): type: typing.Optional[FinancialPayoutType] = None +class FinancialPayoutDict(typing_extensions.TypedDict, total=False): + amount: typing_extensions.NotRequired[float] + currency: typing_extensions.NotRequired[str] + date: typing_extensions.NotRequired[ + typing_extensions.Annotated[datetime.date, typing_extensions.Doc("Format: date")] + ] + fee: typing_extensions.NotRequired[float] + id: typing_extensions.NotRequired[int] + reference: typing_extensions.NotRequired[str] + status: typing_extensions.NotRequired[FinancialPayoutStatusInput] + transaction_code: typing_extensions.NotRequired[str] + type: typing_extensions.NotRequired[FinancialPayoutTypeInput] + + +FinancialPayoutInput = FinancialPayoutDict + + FinancialPayouts = list[FinancialPayout] +FinancialPayoutsInput = typing.Sequence[FinancialPayoutInput] """ List of payout summaries. """ HorizontalAccuracy = float +HorizontalAccuracyInput = float """ Indication of the precision of the geographical position received from the payment terminal. """ @@ -1953,7 +3800,20 @@ class Invite(pydantic.BaseModel): expires_at: datetime.datetime +class InviteDict(typing_extensions.TypedDict, total=False): + email: typing_extensions.Required[ + typing_extensions.Annotated[ + str, typing_extensions.Doc("Email address of the invited user.\nFormat: email") + ] + ] + expires_at: typing_extensions.Required[datetime.datetime] + + +InviteInput = InviteDict + + Lat = float +LatInput = float """ Latitude value from the coordinates of the payment location (as received from the payment terminal reader). Min: 0 @@ -1993,6 +3853,37 @@ class Link(pydantic.BaseModel): """ +class LinkDict(typing_extensions.TypedDict, total=False): + href: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, typing_extensions.Doc("URL for accessing the related resource.\nFormat: uri") + ] + ] + max_amount: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + float, typing_extensions.Doc("Maximum allowed amount for the refund.") + ] + ] + min_amount: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + float, typing_extensions.Doc("Minimum allowed amount for the refund.") + ] + ] + rel: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, typing_extensions.Doc("Specifies the relation to the current resource.") + ] + ] + type: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, typing_extensions.Doc("Specifies the media type of the related resource.") + ] + ] + + +LinkInput = LinkDict + + class Person(pydantic.BaseModel): """ Person is a schema definition. @@ -2096,6 +3987,125 @@ class Person(pydantic.BaseModel): """ +class PersonDict(typing_extensions.TypedDict, total=False): + id: typing_extensions.Required[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "The unique identifier for the person. This is a [typeid](https://github.com/sumup/typeid).\nRead only" + ), + ] + ] + address: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + AddressInput, + typing_extensions.Doc( + "An address somewhere in the world. The address fields used depend on the country conventions. For example, inGreat Britain, `city` is `post_town`. In the United States, the top-level administrative unit used in addressesis `state`, whereas in Chile it's `region`.\nWhether an address is valid or not depends on whether the locally required fields are present. Fields not supported ina country will be ignored.\nAddress documentation: https://backstage.sumup.net/docs/default/Component/merchants/merchant/#addresses" + ), + ] + ] + birthdate: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + datetime.date, + typing_extensions.Doc( + "The date of birth of the individual, represented as an ISO 8601:2004 [ISO8601‑2004] YYYY-MM-DD format.\nFormat: date" + ), + ] + ] + change_status: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + ChangeStatusInput, + typing_extensions.Doc( + "Reflects the status of changes submitted through the `PATCH` endpoints for the merchant or persons. If somechanges have not been applied yet, the status will be `pending`. If all changes have been applied, the status`done`.\nThe status is only returned after write operations or on read endpoints when the `version` query parameter isprovided.\nRead only" + ), + ] + ] + citizenship: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + CountryCodeInput, + typing_extensions.Doc( + "An [ISO3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2)\ncountry code. This definition users `oneOf` with a two-character string\ntype to allow for support of future countries in client code.\nMin length: 2\nMax length: 2\nPattern: ^[A-Z]{2}$" + ), + ] + ] + country_of_residence: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "An [ISO3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code representing the countrywhere the person resides.\nMin length: 2\nMax length: 2" + ), + ] + ] + family_name: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, typing_extensions.Doc("The last name(s) of the individual.\nMax length: 60") + ] + ] + given_name: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, typing_extensions.Doc("The first name(s) of the individual.\nMax length: 60") + ] + ] + identifiers: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + typing.Sequence[PersonalIdentifierInput], + typing_extensions.Doc("A list of country-specific personal identifiers.\nMax items: 5"), + ] + ] + middle_name: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Middle name(s) of the End-User. Note that in some cultures, people can have multiple middle names; all canbe present, with the names being separated by space characters. Also note that in some cultures, middle namesare not used.\nMax length: 60" + ), + ] + ] + nationality: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "The persons nationality. May be an [ISO3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) countrycode, but legacy data may not conform to this standard." + ), + ] + ] + ownership: typing_extensions.NotRequired[OwnershipInput] + phone_number: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + PhoneNumberInput, + typing_extensions.Doc( + "A publicly available phone number in [E.164](https://en.wikipedia.org/wiki/E.164) format.\nMax length: 16" + ), + ] + ] + relationships: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + typing.Sequence[str], + typing_extensions.Doc( + "A list of roles the person has in the merchant or towards SumUp. A merchant must have at least one person withthe relationship `representative`.\nMin items: 1\nMax items: 1" + ), + ] + ] + user_id: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "A corresponding identity user ID for the person, if they have a user account." + ), + ] + ] + version: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + VersionInput, + typing_extensions.Doc( + "The version of the resource. The version reflects a specific change submitted to the API via one of the `PATCH`endpoints." + ), + ] + ] + + +PersonInput = PersonDict + + class ListPersonsResponseBody(pydantic.BaseModel): """ ListPersonsResponseBody is a schema definition. @@ -2104,7 +4114,15 @@ class ListPersonsResponseBody(pydantic.BaseModel): items: list[Person] +class ListPersonsResponseBodyDict(typing_extensions.TypedDict, total=False): + items: typing_extensions.Required[typing.Sequence[PersonInput]] + + +ListPersonsResponseBodyInput = ListPersonsResponseBodyDict + + Lon = float +LonInput = float """ Longitude value from the coordinates of the payment location (as received from the payment terminal reader). Min: 0 @@ -2112,6 +4130,7 @@ class ListPersonsResponseBody(pydantic.BaseModel): """ MandatePayloadType = typing.Union[typing.Literal["recurrent"], str] +MandatePayloadTypeInput = MandatePayloadType class MandatePayload(pydantic.BaseModel): @@ -2135,9 +4154,35 @@ class MandatePayload(pydantic.BaseModel): """ +class MandatePayloadDict(typing_extensions.TypedDict, total=False): + type: typing_extensions.Required[ + typing_extensions.Annotated[ + MandatePayloadTypeInput, + typing_extensions.Doc("Type of mandate to create for the saved payment instrument."), + ] + ] + user_agent: typing_extensions.Required[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Browser or client user agent observed when consent was collected." + ), + ] + ] + user_ip: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, typing_extensions.Doc("IP address of the payer when the mandate was accepted.") + ] + ] + + +MandatePayloadInput = MandatePayloadDict + + MembershipStatus = typing.Union[ typing.Literal["accepted", "disabled", "expired", "pending", "unknown"], str ] +MembershipStatusInput = MembershipStatus class MembershipUserClassic(pydantic.BaseModel): @@ -2152,6 +4197,15 @@ class MembershipUserClassic(pydantic.BaseModel): """ +class MembershipUserClassicDict(typing_extensions.TypedDict, total=False): + user_id: typing_extensions.Required[ + typing_extensions.Annotated[int, typing_extensions.Doc("Format: int32")] + ] + + +MembershipUserClassicInput = MembershipUserClassicDict + + class MembershipUser(pydantic.BaseModel): """ Information about the user associated with the membership. @@ -2205,7 +4259,71 @@ class MembershipUser(pydantic.BaseModel): """ +class MembershipUserDict(typing_extensions.TypedDict, total=False): + email: typing_extensions.Required[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "End-User's preferred e-mail address. Its value MUST conform to the RFC 5322 [RFC5322] addr-spec syntax. TheRP MUST NOT rely upon this value being unique, for unique identification use ID instead." + ), + ] + ] + id: typing_extensions.Required[ + typing_extensions.Annotated[ + str, typing_extensions.Doc("Identifier for the End-User (also called Subject).") + ] + ] + mfa_on_login_enabled: typing_extensions.Required[ + typing_extensions.Annotated[ + bool, typing_extensions.Doc("True if the user has enabled MFA on login.") + ] + ] + service_account_user: typing_extensions.Required[ + typing_extensions.Annotated[ + bool, typing_extensions.Doc("True if the user is a service account.") + ] + ] + virtual_user: typing_extensions.Required[ + typing_extensions.Annotated[ + bool, typing_extensions.Doc("True if the user is a virtual user (operator).") + ] + ] + classic: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + MembershipUserClassicInput, + typing_extensions.Doc( + "Classic identifiers of the user.\nDeprecated: this operation is deprecated" + ), + ] + ] + disabled_at: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + datetime.datetime, + typing_extensions.Doc( + "Time when the user has been disabled. Applies only to virtual users (`virtual_user: true`)." + ), + ] + ] + nickname: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, typing_extensions.Doc("User's preferred name. Used for display purposes only.") + ] + ] + picture: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "URL of the End-User's profile picture. This URL refers to an image file (for example, a PNG, JPEG, or GIFimage file), rather than to a Web page containing an image.\nFormat: uri" + ), + ] + ] + + +MembershipUserInput = MembershipUserDict + + Metadata = dict[str, object] +MetadataInput = typing.Mapping[str, object] """ Set of user-defined key-value pairs attached to the object. Partial updates are not supported. When updating, alwayssubmit whole metadata. Maximum of 64 parameters are allowed in the object. Max properties: 64 @@ -2270,7 +4388,72 @@ class Member(pydantic.BaseModel): """ +class MemberDict(typing_extensions.TypedDict, total=False): + created_at: typing_extensions.Required[ + typing_extensions.Annotated[ + datetime.datetime, + typing_extensions.Doc("The timestamp of when the member was created."), + ] + ] + id: typing_extensions.Required[ + typing_extensions.Annotated[str, typing_extensions.Doc("ID of the member.")] + ] + permissions: typing_extensions.Required[ + typing_extensions.Annotated[ + typing.Sequence[str], + typing_extensions.Doc( + "User's permissions.\nDeprecated: Permissions include only legacy permissions, please use roles instead. Member access is based on roles withina given resource and the permissions these roles grant." + ), + ] + ] + roles: typing_extensions.Required[ + typing_extensions.Annotated[typing.Sequence[str], typing_extensions.Doc("User's roles.")] + ] + status: typing_extensions.Required[ + typing_extensions.Annotated[ + MembershipStatusInput, typing_extensions.Doc("The status of the membership.") + ] + ] + updated_at: typing_extensions.Required[ + typing_extensions.Annotated[ + datetime.datetime, + typing_extensions.Doc("The timestamp of when the member was last updated."), + ] + ] + attributes: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + AttributesInput, + typing_extensions.Doc( + "Object attributes that are modifiable only by SumUp applications." + ), + ] + ] + invite: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + InviteInput, typing_extensions.Doc("Pending invitation for membership.") + ] + ] + metadata: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + MetadataInput, + typing_extensions.Doc( + "Set of user-defined key-value pairs attached to the object. Partial updates are not supported. When updating, alwayssubmit whole metadata. Maximum of 64 parameters are allowed in the object.\nMax properties: 64" + ), + ] + ] + user: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + MembershipUserInput, + typing_extensions.Doc("Information about the user associated with the membership."), + ] + ] + + +MemberInput = MemberDict + + ResourceType = str +ResourceTypeInput = str """ The type of the membership resource. Possible values are: @@ -2325,6 +4508,55 @@ class MembershipResource(pydantic.BaseModel): """ +class MembershipResourceDict(typing_extensions.TypedDict, total=False): + created_at: typing_extensions.Required[ + typing_extensions.Annotated[ + datetime.datetime, + typing_extensions.Doc("The timestamp of when the membership resource was created."), + ] + ] + id: typing_extensions.Required[ + typing_extensions.Annotated[ + str, typing_extensions.Doc("ID of the resource the membership is in.") + ] + ] + name: typing_extensions.Required[ + typing_extensions.Annotated[str, typing_extensions.Doc("Display name of the resource.")] + ] + type: typing_extensions.Required[ + typing_extensions.Annotated[ + ResourceTypeInput, + typing_extensions.Doc( + "The type of the membership resource.\nPossible values are:\n* `merchant` - merchant account(s)\n* `organization` - organization(s)" + ), + ] + ] + updated_at: typing_extensions.Required[ + typing_extensions.Annotated[ + datetime.datetime, + typing_extensions.Doc( + "The timestamp of when the membership resource was last updated." + ), + ] + ] + attributes: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + AttributesInput, + typing_extensions.Doc( + "Object attributes that are modifiable only by SumUp applications." + ), + ] + ] + logo: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, typing_extensions.Doc("Logo fo the resource.\nFormat: uri\nMax length: 256") + ] + ] + + +MembershipResourceInput = MembershipResourceDict + + class Membership(pydantic.BaseModel): """ A membership associates a user with a resource, memberships is defined by user, resource, resource type, andassociated roles. @@ -2396,7 +4628,85 @@ class Membership(pydantic.BaseModel): """ +class MembershipDict(typing_extensions.TypedDict, total=False): + created_at: typing_extensions.Required[ + typing_extensions.Annotated[ + datetime.datetime, + typing_extensions.Doc("The timestamp of when the membership was created."), + ] + ] + id: typing_extensions.Required[ + typing_extensions.Annotated[str, typing_extensions.Doc("ID of the membership.")] + ] + permissions: typing_extensions.Required[ + typing_extensions.Annotated[ + typing.Sequence[str], + typing_extensions.Doc( + "User's permissions.\nDeprecated: Permissions include only legacy permissions, please use roles instead. Member access is based on their roleswithin a given resource and the permissions these roles grant." + ), + ] + ] + resource: typing_extensions.Required[ + typing_extensions.Annotated[ + MembershipResourceInput, + typing_extensions.Doc("Information about the resource the membership is in."), + ] + ] + resource_id: typing_extensions.Required[ + typing_extensions.Annotated[ + str, typing_extensions.Doc("ID of the resource the membership is in.") + ] + ] + roles: typing_extensions.Required[ + typing_extensions.Annotated[typing.Sequence[str], typing_extensions.Doc("User's roles.")] + ] + status: typing_extensions.Required[ + typing_extensions.Annotated[ + MembershipStatusInput, typing_extensions.Doc("The status of the membership.") + ] + ] + type: typing_extensions.Required[ + typing_extensions.Annotated[ + ResourceTypeInput, + typing_extensions.Doc( + "The type of the membership resource.\nPossible values are:\n* `merchant` - merchant account(s)\n* `organization` - organization(s)" + ), + ] + ] + updated_at: typing_extensions.Required[ + typing_extensions.Annotated[ + datetime.datetime, + typing_extensions.Doc("The timestamp of when the membership was last updated."), + ] + ] + attributes: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + AttributesInput, + typing_extensions.Doc( + "Object attributes that are modifiable only by SumUp applications." + ), + ] + ] + invite: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + InviteInput, typing_extensions.Doc("Pending invitation for membership.") + ] + ] + metadata: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + MetadataInput, + typing_extensions.Doc( + "Set of user-defined key-value pairs attached to the object. Partial updates are not supported. When updating, alwayssubmit whole metadata. Maximum of 64 parameters are allowed in the object.\nMax properties: 64" + ), + ] + ] + + +MembershipInput = MembershipDict + + Meta = dict[str, str] +MetaInput = typing.Mapping[str, str] """ A set of key-value pairs that you can attach to an object. This can be useful for storing additional informationabout the object in a structured format. @@ -2422,6 +4732,28 @@ class Timestamps(pydantic.BaseModel): """ +class TimestampsDict(typing_extensions.TypedDict, total=False): + created_at: typing_extensions.Required[ + typing_extensions.Annotated[ + datetime.datetime, + typing_extensions.Doc( + "The date and time when the resource was created. This is a string as defined in [RFC 3339, section 5.6](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6).\nRead only" + ), + ] + ] + updated_at: typing_extensions.Required[ + typing_extensions.Annotated[ + datetime.datetime, + typing_extensions.Doc( + "The date and time when the resource was last updated. This is a string as defined in [RFC 3339, section 5.6](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6).\nReadonly" + ), + ] + ] + + +TimestampsInput = TimestampsDict + + class Merchant(pydantic.BaseModel): """ Merchant is a schema definition. @@ -2536,6 +4868,132 @@ class Merchant(pydantic.BaseModel): """ +class MerchantDict(typing_extensions.TypedDict, total=False): + country: typing_extensions.Required[ + typing_extensions.Annotated[ + CountryCodeInput, + typing_extensions.Doc( + "An [ISO3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2)\ncountry code. This definition users `oneOf` with a two-character string\ntype to allow for support of future countries in client code.\nMin length: 2\nMax length: 2\nPattern: ^[A-Z]{2}$" + ), + ] + ] + created_at: typing_extensions.Required[ + typing_extensions.Annotated[ + datetime.datetime, + typing_extensions.Doc( + "The date and time when the resource was created. This is a string as defined in [RFC 3339, section 5.6](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6).\nRead only" + ), + ] + ] + default_currency: typing_extensions.Required[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Three-letter [ISO currency code](https://en.wikipedia.org/wiki/ISO_4217) representing the default currency forthe account.\nRead only\nMin length: 3\nMax length: 3" + ), + ] + ] + default_locale: typing_extensions.Required[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Merchant's default locale, represented as a BCP47 [RFC5646](https://datatracker.ietf.org/doc/html/rfc5646) languagetag. This is typically an ISO 639-1 Alpha-2 [ISO639‑1](https://www.iso.org/iso-639-language-code) language codein lowercase and an ISO 3166-1 Alpha-2 [ISO3166‑1](https://www.iso.org/iso-3166-country-codes.html) countrycode in uppercase, separated by a dash. For example, en-US or fr-CA.\nIn multilingual countries this is the merchant's preferred locale out of those, that are officially spoken inthe country. In a countries with a single official language this will match the official language.\nMin length: 2\nMax length: 5" + ), + ] + ] + merchant_code: typing_extensions.Required[ + typing_extensions.Annotated[ + str, typing_extensions.Doc("Short unique identifier for the merchant.\nRead only") + ] + ] + updated_at: typing_extensions.Required[ + typing_extensions.Annotated[ + datetime.datetime, + typing_extensions.Doc( + "The date and time when the resource was last updated. This is a string as defined in [RFC 3339, section 5.6](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6).\nReadonly" + ), + ] + ] + alias: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "A user-facing name of the merchant account for use in dashboards and other user-facing applications. Forcustomer-facing business name see `merchant.business_profile`." + ), + ] + ] + avatar: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "A user-facing small-format logo for use in dashboards and other user-facing applications. For customer-facing brandingsee `merchant.business_profile.branding`.\nFormat: uri" + ), + ] + ] + business_profile: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + BusinessProfileInput, + typing_extensions.Doc( + "Business information about the merchant. This information will be visible to the merchant's customers." + ), + ] + ] + business_type: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "The business type.\n* `sole_trader`: The business is run by an self-employed individual.\n* `company`: The business is run as a company with one or more shareholders\n* `partnership`: The business is run as a company with two or more shareholders that can be also other legalentities\n* `non_profit`: The business is run as a nonprofit organization that operates for public or social benefit\n* `government_entity`: The business is state owned and operated" + ), + ] + ] + change_status: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + ChangeStatusInput, + typing_extensions.Doc( + "Reflects the status of changes submitted through the `PATCH` endpoints for the merchant or persons. If somechanges have not been applied yet, the status will be `pending`. If all changes have been applied, the status`done`.\nThe status is only returned after write operations or on read endpoints when the `version` query parameter isprovided.\nRead only" + ), + ] + ] + classic: typing_extensions.NotRequired[ClassicMerchantIdentifiersInput] + company: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + CompanyInput, + typing_extensions.Doc( + "Information about the company or business. This is legal information that is used for verification.\nCompany documentation: https://developer.sumup.com/tools/glossary/merchant#company" + ), + ] + ] + meta: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + MetaInput, + typing_extensions.Doc( + "A set of key-value pairs that you can attach to an object. This can be useful for storing additional informationabout the object in a structured format.\n\n**Warning**: Updating Meta will overwrite the existing data. Make sure to always include the complete JSON object." + ), + ] + ] + organization_id: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, typing_extensions.Doc("ID of the organization the merchant belongs to (if any).") + ] + ] + sandbox: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + bool, typing_extensions.Doc("True if the merchant is a sandbox for testing.") + ] + ] + version: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + VersionInput, + typing_extensions.Doc( + "The version of the resource. The version reflects a specific change submitted to the API via one of the `PATCH`endpoints." + ), + ] + ] + + +MerchantInput = MerchantDict + + class NotFoundErrors(pydantic.BaseModel): """ NotFoundErrors is a schema definition. @@ -2547,6 +5005,17 @@ class NotFoundErrors(pydantic.BaseModel): """ +class NotFoundErrorsDict(typing_extensions.TypedDict, total=False): + detail: typing_extensions.Required[ + typing_extensions.Annotated[ + str, typing_extensions.Doc("Fuller message giving context to error") + ] + ] + + +NotFoundErrorsInput = NotFoundErrorsDict + + class NotFound(pydantic.BaseModel): """ 404 Not Found @@ -2555,6 +5024,13 @@ class NotFound(pydantic.BaseModel): errors: NotFoundErrors +class NotFoundDict(typing_extensions.TypedDict, total=False): + errors: typing_extensions.Required[NotFoundErrorsInput] + + +NotFoundInput = NotFoundDict + + class Permissions(pydantic.BaseModel): """ Permissions assigned to an operator or user. @@ -2571,7 +5047,19 @@ class Permissions(pydantic.BaseModel): refund_transactions: bool +class PermissionsDict(typing_extensions.TypedDict, total=False): + admin: typing_extensions.Required[bool] + create_moto_payments: typing_extensions.Required[bool] + create_referral: typing_extensions.Required[bool] + full_transaction_history_view: typing_extensions.Required[bool] + refund_transactions: typing_extensions.Required[bool] + + +PermissionsInput = PermissionsDict + + OperatorAccountType = typing.Union[typing.Literal["normal", "operator"], str] +OperatorAccountTypeInput = OperatorAccountType class Operator(pydantic.BaseModel): @@ -2608,7 +5096,38 @@ class Operator(pydantic.BaseModel): nickname: typing.Optional[str] = None +class OperatorDict(typing_extensions.TypedDict, total=False): + account_type: typing_extensions.Required[OperatorAccountTypeInput] + created_at: typing_extensions.Required[ + typing_extensions.Annotated[ + datetime.datetime, + typing_extensions.Doc("The timestamp of when the operator was created."), + ] + ] + disabled: typing_extensions.Required[bool] + id: typing_extensions.Required[ + typing_extensions.Annotated[int, typing_extensions.Doc("Format: int32")] + ] + permissions: typing_extensions.Required[ + typing_extensions.Annotated[ + PermissionsInput, typing_extensions.Doc("Permissions assigned to an operator or user.") + ] + ] + updated_at: typing_extensions.Required[ + typing_extensions.Annotated[ + datetime.datetime, + typing_extensions.Doc("The timestamp of when the operator was last updated."), + ] + ] + username: typing_extensions.Required[str] + nickname: typing_extensions.NotRequired[str] + + +OperatorInput = OperatorDict + + PaymentInstrumentResponseType = typing.Union[typing.Literal["card"], str] +PaymentInstrumentResponseTypeInput = PaymentInstrumentResponseType class PaymentInstrumentResponseCard(pydantic.BaseModel): @@ -2630,6 +5149,28 @@ class PaymentInstrumentResponseCard(pydantic.BaseModel): """ +class PaymentInstrumentResponseCardDict(typing_extensions.TypedDict, total=False): + last_4_digits: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Last 4 digits of the payment card number.\nRead only\nMin length: 4\nMax length: 4" + ), + ] + ] + type: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + CardTypeInput, + typing_extensions.Doc( + "Issuing card network of the payment card used for the transaction." + ), + ] + ] + + +PaymentInstrumentResponseCardInput = PaymentInstrumentResponseCardDict + + class PaymentInstrumentResponse(pydantic.BaseModel): """ Payment Instrument Response @@ -2669,6 +5210,54 @@ class PaymentInstrumentResponse(pydantic.BaseModel): """ +class PaymentInstrumentResponseDict(typing_extensions.TypedDict, total=False): + active: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + bool, + typing_extensions.Doc( + "Indicates whether the payment instrument is active and can be used for payments. To deactivate it, send a`DELETE` request to the resource endpoint.\nRead only\nDefault: true" + ), + ] + ] + card: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + PaymentInstrumentResponseCardInput, + typing_extensions.Doc("Details of the payment card."), + ] + ] + created_at: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + datetime.datetime, + typing_extensions.Doc( + "Creation date of payment instrument. Response format expressed according to [ISO8601](https://en.wikipedia.org/wiki/ISO_8601) code." + ), + ] + ] + mandate: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + MandateResponseInput, + typing_extensions.Doc("Details of the mandate linked to the saved payment instrument."), + ] + ] + token: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Unique token identifying the saved payment card for a customer.\nRead only" + ), + ] + ] + type: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + PaymentInstrumentResponseTypeInput, + typing_extensions.Doc("Type of the payment instrument."), + ] + ] + + +PaymentInstrumentResponseInput = PaymentInstrumentResponseDict + + class Problem(pydantic.BaseModel): """ A RFC 9457 problem details object. @@ -2734,16 +5323,60 @@ def additional_properties(self, value: dict[str, object]) -> None: object.__setattr__(self, "__pydantic_extra__", dict(value)) +class ProblemDict(typing_extensions.TypedDict, total=False): + type: typing_extensions.Required[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc("A URI reference that identifies the problem type.\nFormat: uri"), + ] + ] + detail: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "A human-readable explanation specific to this occurrence of the problem." + ), + ] + ] + instance: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "A URI reference that identifies the specific occurrence of the problem.\nFormat: uri" + ), + ] + ] + status: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + int, + typing_extensions.Doc( + "The HTTP status code generated by the origin server for this occurrence of the problem." + ), + ] + ] + title: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, typing_extensions.Doc("A short, human-readable summary of the problem type.") + ] + ] + + +ProblemInput = ProblemDict + + ProcessCheckoutPaymentType = typing.Union[ typing.Literal["apple_pay", "bancontact", "blik", "boleto", "card", "google_pay", "ideal"], str ] +ProcessCheckoutPaymentTypeInput = ProcessCheckoutPaymentType ProcessCheckoutGooglePay = dict[str, object] +ProcessCheckoutGooglePayInput = typing.Mapping[str, object] """ Raw `PaymentData` object received from Google Pay. Send the Google Pay response payload as-is. """ ProcessCheckoutApplePay = dict[str, object] +ProcessCheckoutApplePayInput = typing.Mapping[str, object] """ Raw payment token object received from Apple Pay. Send the Apple Pay response payload as-is. """ @@ -2802,6 +5435,81 @@ class ProcessCheckout(pydantic.BaseModel): """ +class ProcessCheckoutDict(typing_extensions.TypedDict, total=False): + payment_type: typing_extensions.Required[ + typing_extensions.Annotated[ + ProcessCheckoutPaymentTypeInput, + typing_extensions.Doc( + "Payment method used for this processing attempt. It determines which additional request fields are required." + ), + ] + ] + apple_pay: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + ProcessCheckoutApplePayInput, + typing_extensions.Doc( + "Raw payment token object received from Apple Pay. Send the Apple Pay response payload as-is." + ), + ] + ] + card: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + CardInput, + typing_extensions.Doc( + "__Required when payment type is `card`.__ Details of the payment card." + ), + ] + ] + customer_id: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Customer identifier associated with the saved payment instrument. Required when `token` is provided." + ), + ] + ] + google_pay: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + ProcessCheckoutGooglePayInput, + typing_extensions.Doc( + "Raw `PaymentData` object received from Google Pay. Send the Google Pay response payload as-is." + ), + ] + ] + installments: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + int, + typing_extensions.Doc( + "Number of installments for deferred payments. Available only to merchant users in Brazil.\nMin: 1\nMax: 12" + ), + ] + ] + mandate: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + MandatePayloadInput, + typing_extensions.Doc( + "Mandate details used when a checkout should create a reusable card token for future recurring or merchant-initiated payments." + ), + ] + ] + personal_details: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + PersonalDetailsInput, typing_extensions.Doc("Personal details for the customer.") + ] + ] + token: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Saved-card token to use instead of raw card details when processing with a previously stored payment instrument." + ), + ] + ] + + +ProcessCheckoutInput = ProcessCheckoutDict + + class Product(pydantic.BaseModel): """ Purchase product. @@ -2865,7 +5573,54 @@ class Product(pydantic.BaseModel): """ +class ProductDict(typing_extensions.TypedDict, total=False): + name: typing_extensions.NotRequired[ + typing_extensions.Annotated[str, typing_extensions.Doc("Product name.")] + ] + price: typing_extensions.NotRequired[ + typing_extensions.Annotated[float, typing_extensions.Doc("Product price.\nFormat: decimal")] + ] + price_label: typing_extensions.NotRequired[ + typing_extensions.Annotated[str, typing_extensions.Doc("Product description.")] + ] + price_with_vat: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + float, typing_extensions.Doc("Product price incl. VAT.\nFormat: decimal") + ] + ] + quantity: typing_extensions.NotRequired[ + typing_extensions.Annotated[int, typing_extensions.Doc("Product quantity.")] + ] + single_vat_amount: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + float, typing_extensions.Doc("VAT amount for a single product.\nFormat: decimal") + ] + ] + total_price: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + float, typing_extensions.Doc("Quantity x product price.\nFormat: decimal") + ] + ] + total_with_vat: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + float, typing_extensions.Doc("Total price incl. VAT.\nFormat: decimal") + ] + ] + vat_amount: typing_extensions.NotRequired[ + typing_extensions.Annotated[float, typing_extensions.Doc("VAT amount.\nFormat: decimal")] + ] + vat_rate: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + float, typing_extensions.Doc("VAT percentage.\nFormat: decimal") + ] + ] + + +ProductInput = ProductDict + + ReaderDeviceModel = typing.Union[typing.Literal["solo", "virtual-solo"], str] +ReaderDeviceModelInput = ReaderDeviceModel class ReaderDevice(pydantic.BaseModel): @@ -2884,7 +5639,27 @@ class ReaderDevice(pydantic.BaseModel): """ +class ReaderDeviceDict(typing_extensions.TypedDict, total=False): + identifier: typing_extensions.Required[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "A unique identifier of the physical device (e.g. serial number)." + ), + ] + ] + model: typing_extensions.Required[ + typing_extensions.Annotated[ + ReaderDeviceModelInput, typing_extensions.Doc("Identifier of the model of the device.") + ] + ] + + +ReaderDeviceInput = ReaderDeviceDict + + ReaderId = str +ReaderIdInput = str """ Unique identifier of the object. @@ -2894,12 +5669,14 @@ class ReaderDevice(pydantic.BaseModel): """ ReaderName = str +ReaderNameInput = str """ Custom human-readable, user-defined name for easier identification of the reader. Max length: 500 """ ReaderStatus = typing.Union[typing.Literal["expired", "paired", "processing", "unknown"], str] +ReaderStatusInput = ReaderStatus class Reader(pydantic.BaseModel): @@ -2964,7 +5741,72 @@ class Reader(pydantic.BaseModel): """ +class ReaderDict(typing_extensions.TypedDict, total=False): + created_at: typing_extensions.Required[ + typing_extensions.Annotated[ + datetime.datetime, + typing_extensions.Doc("The timestamp of when the reader was created."), + ] + ] + device: typing_extensions.Required[ + typing_extensions.Annotated[ + ReaderDeviceInput, + typing_extensions.Doc("Information about the underlying physical device."), + ] + ] + id: typing_extensions.Required[ + typing_extensions.Annotated[ + ReaderIdInput, + typing_extensions.Doc( + "Unique identifier of the object.\n\nNote that this identifies the instance of the physical devices pairing with your SumUp account. If you [delete](https://developer.sumup.com/api/readers/delete-reader) areader, and pair the device again, the ID will be different. Do not use this ID to refer to a physical device.\nMinlength: 30\nMax length: 30" + ), + ] + ] + name: typing_extensions.Required[ + typing_extensions.Annotated[ + ReaderNameInput, + typing_extensions.Doc( + "Custom human-readable, user-defined name for easier identification of the reader.\nMax length: 500" + ), + ] + ] + status: typing_extensions.Required[ + typing_extensions.Annotated[ + ReaderStatusInput, + typing_extensions.Doc( + "The status of the reader object gives information about the current state of the reader.\n\nPossible values:\n\n- `unknown` - The reader status is unknown.\n- `processing` - The reader is created and waits for the physical device to confirm the pairing.\n- `paired` - The reader is paired with a merchant account and can be used with SumUp APIs.\n- `expired` - The pairing is expired and no longer usable with the account. The resource needs to get recreated." + ), + ] + ] + updated_at: typing_extensions.Required[ + typing_extensions.Annotated[ + datetime.datetime, + typing_extensions.Doc("The timestamp of when the reader was last updated."), + ] + ] + metadata: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + MetadataInput, + typing_extensions.Doc( + "Set of user-defined key-value pairs attached to the object. Partial updates are not supported. When updating, alwayssubmit whole metadata. Maximum of 64 parameters are allowed in the object.\nMax properties: 64" + ), + ] + ] + service_account_id: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Identifier of the system-managed service account associated with this reader.\nPresent only for readers that are already paired.\nThis field is currently in beta and may change.\nFormat: uuid" + ), + ] + ] + + +ReaderInput = ReaderDict + + ReaderCheckoutStatusChangePayloadStatus = typing.Union[typing.Literal["failed", "successful"], str] +ReaderCheckoutStatusChangePayloadStatusInput = ReaderCheckoutStatusChangePayloadStatus class ReaderCheckoutStatusChangePayload(pydantic.BaseModel): @@ -2996,6 +5838,39 @@ class ReaderCheckoutStatusChangePayload(pydantic.BaseModel): """ +class ReaderCheckoutStatusChangePayloadDict(typing_extensions.TypedDict, total=False): + client_transaction_id: typing_extensions.Required[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "The unique client transaction id. It is the same returned by the Checkout.\nFormat: uuid" + ), + ] + ] + merchant_code: typing_extensions.Required[ + typing_extensions.Annotated[ + str, typing_extensions.Doc("The merchant code associated with the transaction.") + ] + ] + status: typing_extensions.Required[ + typing_extensions.Annotated[ + ReaderCheckoutStatusChangePayloadStatusInput, + typing_extensions.Doc("The current status of the transaction."), + ] + ] + transaction_id: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "The transaction id. Deprecated: use `client_transaction_id` instead.\nFormat: uuid\nDeprecated: this operation is deprecated" + ), + ] + ] + + +ReaderCheckoutStatusChangePayloadInput = ReaderCheckoutStatusChangePayloadDict + + class ReaderCheckoutStatusChange(pydantic.BaseModel): """ The callback payload containing the status change of the Reader Checkout. @@ -3023,7 +5898,32 @@ class ReaderCheckoutStatusChange(pydantic.BaseModel): """ +class ReaderCheckoutStatusChangeDict(typing_extensions.TypedDict, total=False): + event_type: typing_extensions.Required[ + typing_extensions.Annotated[str, typing_extensions.Doc("Type of event.")] + ] + id: typing_extensions.Required[ + typing_extensions.Annotated[ + str, typing_extensions.Doc("Unique identifier for the event.\nFormat: uuid") + ] + ] + payload: typing_extensions.Required[ + typing_extensions.Annotated[ + ReaderCheckoutStatusChangePayloadInput, typing_extensions.Doc("The event payload.") + ] + ] + timestamp: typing_extensions.Required[ + typing_extensions.Annotated[ + datetime.datetime, typing_extensions.Doc("Timestamp of the event.") + ] + ] + + +ReaderCheckoutStatusChangeInput = ReaderCheckoutStatusChangeDict + + ReaderPairingCode = str +ReaderPairingCodeInput = str """ The pairing code is a 8 or 9 character alphanumeric string that is displayed on a SumUp Device after initiatingthe pairing. It is used to link the physical device to the created pairing. Min length: 8 @@ -3047,6 +5947,18 @@ class ReceiptCard(pydantic.BaseModel): """ +class ReceiptCardDict(typing_extensions.TypedDict, total=False): + last_4_digits: typing_extensions.NotRequired[ + typing_extensions.Annotated[str, typing_extensions.Doc("Card last 4 digits.")] + ] + type: typing_extensions.NotRequired[ + typing_extensions.Annotated[str, typing_extensions.Doc("Card Scheme.")] + ] + + +ReceiptCardInput = ReceiptCardDict + + class ReceiptEvent(pydantic.BaseModel): """ Transaction event details as rendered on the receipt. @@ -3100,6 +6012,51 @@ class ReceiptEvent(pydantic.BaseModel): """ +class ReceiptEventDict(typing_extensions.TypedDict, total=False): + amount: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, typing_extensions.Doc("Amount of the event.\nFormat: double") + ] + ] + id: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + EventIdInput, + typing_extensions.Doc("Unique ID of the transaction event.\nFormat: int64"), + ] + ] + receipt_no: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, typing_extensions.Doc("Receipt number associated with the event.") + ] + ] + status: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + EventStatusInput, + typing_extensions.Doc( + "Status of the transaction event.\n\nNot every value is used for every event type.\n\n- `PENDING`: The event has been created but is not final yet. Used for events that are still being processed andwhose final outcome is not known yet.\n- `SCHEDULED`: The event is planned for a future payout cycle but has not been executed yet. This applies topayout events before money is actually sent out.\n- `RECONCILED`: The underlying payment has been matched with settlement data and is ready to continue through payoutprocessing, but the funds have not been paid out yet. This applies to payout events.\n- `PAID_OUT`: The payout event has been completed and the funds were included in a merchant payout.\n- `REFUNDED`: A refund event has been accepted and recorded in the refund flow. This is the status returned forrefund events once the transaction amount is being or has been returned to the payer.\n- `SUCCESSFUL`: The event completed successfully. Use this as the generic terminal success status for event typesthat do not expose a more specific business outcome such as `PAID_OUT` or `REFUNDED`.\n- `FAILED`: The event could not be completed. Typical examples are a payout that could not be executed oran event that was rejected during processing." + ), + ] + ] + timestamp: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + datetime.datetime, typing_extensions.Doc("Date and time of the transaction event.") + ] + ] + transaction_id: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + TransactionIdInput, typing_extensions.Doc("Unique ID of the transaction.") + ] + ] + type: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + EventTypeInput, typing_extensions.Doc("Type of the transaction event.") + ] + ] + + +ReceiptEventInput = ReceiptEventDict + + class ReceiptMerchantDataMerchantProfileAddress(pydantic.BaseModel): """ ReceiptMerchantDataMerchantProfileAddress is a schema definition. @@ -3124,6 +6081,21 @@ class ReceiptMerchantDataMerchantProfileAddress(pydantic.BaseModel): region_name: typing.Optional[str] = None +class ReceiptMerchantDataMerchantProfileAddressDict(typing_extensions.TypedDict, total=False): + address_line1: typing_extensions.NotRequired[str] + address_line2: typing_extensions.NotRequired[str] + city: typing_extensions.NotRequired[str] + country: typing_extensions.NotRequired[str] + country_en_name: typing_extensions.NotRequired[str] + country_native_name: typing_extensions.NotRequired[str] + landline: typing_extensions.NotRequired[str] + post_code: typing_extensions.NotRequired[str] + region_name: typing_extensions.NotRequired[str] + + +ReceiptMerchantDataMerchantProfileAddressInput = ReceiptMerchantDataMerchantProfileAddressDict + + class ReceiptMerchantDataMerchantProfile(pydantic.BaseModel): """ Merchant profile details displayed on the receipt. @@ -3146,6 +6118,20 @@ class ReceiptMerchantDataMerchantProfile(pydantic.BaseModel): website: typing.Optional[str] = None +class ReceiptMerchantDataMerchantProfileDict(typing_extensions.TypedDict, total=False): + address: typing_extensions.NotRequired[ReceiptMerchantDataMerchantProfileAddressInput] + business_name: typing_extensions.NotRequired[str] + company_registration_number: typing_extensions.NotRequired[str] + email: typing_extensions.NotRequired[str] + language: typing_extensions.NotRequired[str] + merchant_code: typing_extensions.NotRequired[str] + vat_id: typing_extensions.NotRequired[str] + website: typing_extensions.NotRequired[str] + + +ReceiptMerchantDataMerchantProfileInput = ReceiptMerchantDataMerchantProfileDict + + class ReceiptMerchantData(pydantic.BaseModel): """ Receipt merchant data @@ -3162,6 +6148,23 @@ class ReceiptMerchantData(pydantic.BaseModel): """ +class ReceiptMerchantDataDict(typing_extensions.TypedDict, total=False): + locale: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, typing_extensions.Doc("Locale used for rendering localized receipt fields.") + ] + ] + merchant_profile: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + ReceiptMerchantDataMerchantProfileInput, + typing_extensions.Doc("Merchant profile details displayed on the receipt."), + ] + ] + + +ReceiptMerchantDataInput = ReceiptMerchantDataDict + + class ReceiptReader(pydantic.BaseModel): """ Card reader details displayed on the receipt. @@ -3178,7 +6181,20 @@ class ReceiptReader(pydantic.BaseModel): """ +class ReceiptReaderDict(typing_extensions.TypedDict, total=False): + code: typing_extensions.NotRequired[ + typing_extensions.Annotated[str, typing_extensions.Doc("Reader serial number.")] + ] + type: typing_extensions.NotRequired[ + typing_extensions.Annotated[str, typing_extensions.Doc("Reader type.")] + ] + + +ReceiptReaderInput = ReceiptReaderDict + + ReceiptTransactionProcessA = typing.Union[typing.Literal["CREDIT", "DEBIT"], str] +ReceiptTransactionProcessAInput = ReceiptTransactionProcessA class ReceiptTransactionProduct(pydantic.BaseModel): @@ -3245,6 +6261,50 @@ class ReceiptTransactionProduct(pydantic.BaseModel): """ +class ReceiptTransactionProductDict(typing_extensions.TypedDict, total=False): + description: typing_extensions.NotRequired[ + typing_extensions.Annotated[str, typing_extensions.Doc("Product description")] + ] + name: typing_extensions.NotRequired[ + typing_extensions.Annotated[str, typing_extensions.Doc("Product name")] + ] + price: typing_extensions.NotRequired[ + typing_extensions.Annotated[str, typing_extensions.Doc("Product price\nFormat: double")] + ] + price_with_vat: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, typing_extensions.Doc("Product price including VAT\nFormat: double") + ] + ] + quantity: typing_extensions.NotRequired[ + typing_extensions.Annotated[int, typing_extensions.Doc("Product quantity\nFormat: int64")] + ] + single_vat_amount: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, typing_extensions.Doc("VAT amount for a single product\nFormat: double") + ] + ] + total_price: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, typing_extensions.Doc("Quantity x product price\nFormat: double") + ] + ] + total_with_vat: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, typing_extensions.Doc("Total price including VAT\nFormat: double") + ] + ] + vat_amount: typing_extensions.NotRequired[ + typing_extensions.Annotated[str, typing_extensions.Doc("VAT amount\nFormat: double")] + ] + vat_rate: typing_extensions.NotRequired[ + typing_extensions.Annotated[str, typing_extensions.Doc("VAT rate\nFormat: double")] + ] + + +ReceiptTransactionProductInput = ReceiptTransactionProductDict + + class ReceiptTransactionVatRate(pydantic.BaseModel): """ ReceiptTransactionVatRate is a schema definition. @@ -3271,6 +6331,24 @@ class ReceiptTransactionVatRate(pydantic.BaseModel): """ +class ReceiptTransactionVatRateDict(typing_extensions.TypedDict, total=False): + gross: typing_extensions.NotRequired[ + typing_extensions.Annotated[float, typing_extensions.Doc("Gross")] + ] + net: typing_extensions.NotRequired[ + typing_extensions.Annotated[float, typing_extensions.Doc("Net")] + ] + rate: typing_extensions.NotRequired[ + typing_extensions.Annotated[float, typing_extensions.Doc("Rate")] + ] + vat: typing_extensions.NotRequired[ + typing_extensions.Annotated[float, typing_extensions.Doc("Vat")] + ] + + +ReceiptTransactionVatRateInput = ReceiptTransactionVatRateDict + + class ReceiptTransaction(pydantic.BaseModel): """ Transaction information. @@ -3377,7 +6455,92 @@ class ReceiptTransaction(pydantic.BaseModel): """ +class ReceiptTransactionDict(typing_extensions.TypedDict, total=False): + amount: typing_extensions.NotRequired[ + typing_extensions.Annotated[str, typing_extensions.Doc("Transaction amount.")] + ] + card: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + ReceiptCardInput, + typing_extensions.Doc("Payment card details displayed on the receipt."), + ] + ] + card_reader: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + ReceiptReaderInput, + typing_extensions.Doc("Card reader details displayed on the receipt."), + ] + ] + currency: typing_extensions.NotRequired[ + typing_extensions.Annotated[str, typing_extensions.Doc("Transaction currency.")] + ] + entry_mode: typing_extensions.NotRequired[ + typing_extensions.Annotated[str, typing_extensions.Doc("Transaction entry mode.")] + ] + events: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + typing.Sequence[ReceiptEventInput], typing_extensions.Doc("Events") + ] + ] + installments_count: typing_extensions.NotRequired[ + typing_extensions.Annotated[int, typing_extensions.Doc("Number of installments.")] + ] + merchant_code: typing_extensions.NotRequired[ + typing_extensions.Annotated[str, typing_extensions.Doc("Merchant code.")] + ] + payment_type: typing_extensions.NotRequired[ + typing_extensions.Annotated[str, typing_extensions.Doc("Transaction type.")] + ] + process_as: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + ReceiptTransactionProcessAInput, typing_extensions.Doc("Debit/Credit.") + ] + ] + products: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + typing.Sequence[ReceiptTransactionProductInput], typing_extensions.Doc("Products") + ] + ] + receipt_no: typing_extensions.NotRequired[ + typing_extensions.Annotated[str, typing_extensions.Doc("Receipt number")] + ] + status: typing_extensions.NotRequired[ + typing_extensions.Annotated[str, typing_extensions.Doc("Transaction processing status.")] + ] + timestamp: typing_extensions.NotRequired[ + typing_extensions.Annotated[datetime.datetime, typing_extensions.Doc("Time created at.")] + ] + tip_amount: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, typing_extensions.Doc("Tip amount (included in transaction amount).") + ] + ] + transaction_code: typing_extensions.NotRequired[ + typing_extensions.Annotated[str, typing_extensions.Doc("Transaction code.")] + ] + transaction_id: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + TransactionIdInput, typing_extensions.Doc("Unique ID of the transaction.") + ] + ] + vat_amount: typing_extensions.NotRequired[ + typing_extensions.Annotated[str, typing_extensions.Doc("Transaction VAT amount.")] + ] + vat_rates: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + typing.Sequence[ReceiptTransactionVatRateInput], typing_extensions.Doc("Vat rates.") + ] + ] + verification_method: typing_extensions.NotRequired[ + typing_extensions.Annotated[str, typing_extensions.Doc("Cardholder verification method.")] + ] + + +ReceiptTransactionInput = ReceiptTransactionDict + + ReceiptEmvData = dict[str, object] +ReceiptEmvDataInput = typing.Mapping[str, object] """ EMV-specific metadata returned for card-present payments. """ @@ -3397,6 +6560,16 @@ class ReceiptAcquirerData(pydantic.BaseModel): tid: typing.Optional[str] = None +class ReceiptAcquirerDataDict(typing_extensions.TypedDict, total=False): + authorization_code: typing_extensions.NotRequired[str] + local_time: typing_extensions.NotRequired[str] + return_code: typing_extensions.NotRequired[str] + tid: typing_extensions.NotRequired[str] + + +ReceiptAcquirerDataInput = ReceiptAcquirerDataDict + + class Receipt(pydantic.BaseModel): """ Receipt details for a transaction. @@ -3423,6 +6596,34 @@ class Receipt(pydantic.BaseModel): """ +class ReceiptDict(typing_extensions.TypedDict, total=False): + acquirer_data: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + ReceiptAcquirerDataInput, + typing_extensions.Doc("Acquirer-specific metadata related to the card authorization."), + ] + ] + emv_data: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + ReceiptEmvDataInput, + typing_extensions.Doc("EMV-specific metadata returned for card-present payments."), + ] + ] + merchant_data: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + ReceiptMerchantDataInput, typing_extensions.Doc("Receipt merchant data") + ] + ] + transaction_data: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + ReceiptTransactionInput, typing_extensions.Doc("Transaction information.") + ] + ] + + +ReceiptInput = ReceiptDict + + class Role(pydantic.BaseModel): """ A custom role that can be used to assign set of permissions to members. @@ -3471,9 +6672,57 @@ class Role(pydantic.BaseModel): """ +class RoleDict(typing_extensions.TypedDict, total=False): + created_at: typing_extensions.Required[ + typing_extensions.Annotated[ + datetime.datetime, typing_extensions.Doc("The timestamp of when the role was created.") + ] + ] + id: typing_extensions.Required[ + typing_extensions.Annotated[str, typing_extensions.Doc("Unique identifier of the role.")] + ] + is_predefined: typing_extensions.Required[ + typing_extensions.Annotated[ + bool, typing_extensions.Doc("True if the role is provided by SumUp.") + ] + ] + name: typing_extensions.Required[ + typing_extensions.Annotated[str, typing_extensions.Doc("User-defined name of the role.")] + ] + permissions: typing_extensions.Required[ + typing_extensions.Annotated[ + typing.Sequence[str], + typing_extensions.Doc("List of permission granted by this role.\nMax items: 100"), + ] + ] + updated_at: typing_extensions.Required[ + typing_extensions.Annotated[ + datetime.datetime, + typing_extensions.Doc("The timestamp of when the role was last updated."), + ] + ] + description: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, typing_extensions.Doc("User-defined description of the role.") + ] + ] + metadata: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + MetadataInput, + typing_extensions.Doc( + "Set of user-defined key-value pairs attached to the object. Partial updates are not supported. When updating, alwayssubmit whole metadata. Maximum of 64 parameters are allowed in the object.\nMax properties: 64" + ), + ] + ] + + +RoleInput = RoleDict + + StatusResponseDataConnectionType = typing.Union[ typing.Literal["Wi-Fi", "btle", "edge", "gprs", "lte", "umts", "usb"], str ] +StatusResponseDataConnectionTypeInput = StatusResponseDataConnectionType StatusResponseDataState = typing.Union[ typing.Literal[ @@ -3486,8 +6735,10 @@ class Role(pydantic.BaseModel): ], str, ] +StatusResponseDataStateInput = StatusResponseDataState StatusResponseDataStatus = typing.Union[typing.Literal["OFFLINE", "ONLINE"], str] +StatusResponseDataStatusInput = StatusResponseDataStatus class StatusResponseData(pydantic.BaseModel): @@ -3533,6 +6784,45 @@ class StatusResponseData(pydantic.BaseModel): """ +class StatusResponseDataDict(typing_extensions.TypedDict, total=False): + status: typing_extensions.Required[ + typing_extensions.Annotated[ + StatusResponseDataStatusInput, typing_extensions.Doc("Status of a device") + ] + ] + battery_level: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + float, typing_extensions.Doc("Battery level percentage\nMin: 0\nMax: 100") + ] + ] + battery_temperature: typing_extensions.NotRequired[ + typing_extensions.Annotated[int, typing_extensions.Doc("Battery temperature in Celsius")] + ] + connection_type: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + StatusResponseDataConnectionTypeInput, + typing_extensions.Doc("Type of connection used by the device"), + ] + ] + firmware_version: typing_extensions.NotRequired[ + typing_extensions.Annotated[str, typing_extensions.Doc("Firmware version of the device")] + ] + last_activity: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + datetime.datetime, + typing_extensions.Doc("Timestamp of the last activity from the device"), + ] + ] + state: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + StatusResponseDataStateInput, typing_extensions.Doc("Latest state of the device") + ] + ] + + +StatusResponseDataInput = StatusResponseDataDict + + class StatusResponse(pydantic.BaseModel): """ Status of a device @@ -3541,6 +6831,13 @@ class StatusResponse(pydantic.BaseModel): data: StatusResponseData +class StatusResponseDict(typing_extensions.TypedDict, total=False): + data: typing_extensions.Required[StatusResponseDataInput] + + +StatusResponseInput = StatusResponseDict + + class TransactionEvent(pydantic.BaseModel): """ Detailed information about a transaction event. @@ -3601,9 +6898,65 @@ class TransactionEvent(pydantic.BaseModel): """ +class TransactionEventDict(typing_extensions.TypedDict, total=False): + amount: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + float, typing_extensions.Doc("Amount of the event.\nFormat: decimal") + ] + ] + date: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + datetime.date, + typing_extensions.Doc("Date when the transaction event occurred.\nFormat: date"), + ] + ] + due_date: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + datetime.date, + typing_extensions.Doc("Date when the transaction event is due to occur.\nFormat: date"), + ] + ] + event_type: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + EventTypeInput, typing_extensions.Doc("Type of the transaction event.") + ] + ] + id: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + EventIdInput, + typing_extensions.Doc("Unique ID of the transaction event.\nFormat: int64"), + ] + ] + installment_number: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + int, + typing_extensions.Doc( + "Consecutive number of the installment that is paid. Applicable only payout events, i.e. `event_type = PAYOUT`." + ), + ] + ] + status: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + EventStatusInput, + typing_extensions.Doc( + "Status of the transaction event.\n\nNot every value is used for every event type.\n\n- `PENDING`: The event has been created but is not final yet. Used for events that are still being processed andwhose final outcome is not known yet.\n- `SCHEDULED`: The event is planned for a future payout cycle but has not been executed yet. This applies topayout events before money is actually sent out.\n- `RECONCILED`: The underlying payment has been matched with settlement data and is ready to continue through payoutprocessing, but the funds have not been paid out yet. This applies to payout events.\n- `PAID_OUT`: The payout event has been completed and the funds were included in a merchant payout.\n- `REFUNDED`: A refund event has been accepted and recorded in the refund flow. This is the status returned forrefund events once the transaction amount is being or has been returned to the payer.\n- `SUCCESSFUL`: The event completed successfully. Use this as the generic terminal success status for event typesthat do not expose a more specific business outcome such as `PAID_OUT` or `REFUNDED`.\n- `FAILED`: The event could not be completed. Typical examples are a payout that could not be executed oran event that was rejected during processing." + ), + ] + ] + timestamp: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + datetime.datetime, typing_extensions.Doc("Date and time of the transaction event.") + ] + ] + + +TransactionEventInput = TransactionEventDict + + TransactionMixinHistoryPayoutPlan = typing.Union[ typing.Literal["ACCELERATED_INSTALLMENT", "SINGLE_PAYMENT", "TRUE_INSTALLMENT"], str ] +TransactionMixinHistoryPayoutPlanInput = TransactionMixinHistoryPayoutPlan class TransactionMixinHistory(pydantic.BaseModel): @@ -3632,13 +6985,53 @@ class TransactionMixinHistory(pydantic.BaseModel): """ +class TransactionMixinHistoryDict(typing_extensions.TypedDict, total=False): + payout_plan: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + TransactionMixinHistoryPayoutPlanInput, + typing_extensions.Doc( + "Payout plan of the registered user at the time when the transaction was made." + ), + ] + ] + payouts_received: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + int, + typing_extensions.Doc( + "Number of payouts that are made to the registered user specified in the `user` property." + ), + ] + ] + payouts_total: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + int, + typing_extensions.Doc( + "Total number of payouts to the registered user specified in the `user` property." + ), + ] + ] + product_summary: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Short description of the payment. The value is taken from the `description` property of the related checkout resource." + ), + ] + ] + + +TransactionMixinHistoryInput = TransactionMixinHistoryDict + + TransactionFullStatus = typing.Union[ typing.Literal["CANCELLED", "FAILED", "PENDING", "SUCCESSFUL"], str ] +TransactionFullStatusInput = TransactionFullStatus TransactionFullPayoutPlan = typing.Union[ typing.Literal["ACCELERATED_INSTALLMENT", "SINGLE_PAYMENT", "TRUE_INSTALLMENT"], str ] +TransactionFullPayoutPlanInput = TransactionFullPayoutPlan TransactionFullSimplePaymentType = typing.Union[ typing.Literal[ @@ -3659,6 +7052,7 @@ class TransactionMixinHistory(pydantic.BaseModel): ], str, ] +TransactionFullSimplePaymentTypeInput = TransactionFullSimplePaymentType TransactionFullVerificationMethod = typing.Union[ typing.Literal[ @@ -3666,10 +7060,13 @@ class TransactionMixinHistory(pydantic.BaseModel): ], str, ] +TransactionFullVerificationMethodInput = TransactionFullVerificationMethod TransactionFullPayoutType = typing.Union[typing.Literal["BANK_ACCOUNT", "PREPAID_CARD"], str] +TransactionFullPayoutTypeInput = TransactionFullPayoutType TransactionFullProcessA = typing.Union[typing.Literal["CREDIT", "DEBIT"], str] +TransactionFullProcessAInput = TransactionFullProcessA class TransactionFullVatRate(pydantic.BaseModel): @@ -3702,6 +7099,36 @@ class TransactionFullVatRate(pydantic.BaseModel): """ +class TransactionFullVatRateDict(typing_extensions.TypedDict, total=False): + gross: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + float, + typing_extensions.Doc( + "Gross amount of products having this VAT rate applied.\nFormat: decimal" + ), + ] + ] + net: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + float, + typing_extensions.Doc( + "NET amount of products having this VAT rate applied.\nFormat: decimal" + ), + ] + ] + rate: typing_extensions.NotRequired[ + typing_extensions.Annotated[float, typing_extensions.Doc("VAT rate.\nFormat: decimal")] + ] + vat: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + float, typing_extensions.Doc("VAT amount of this rate applied.\nFormat: decimal") + ] + ] + + +TransactionFullVatRateInput = TransactionFullVatRateDict + + TransactionFullSimpleStatus = typing.Union[ typing.Literal[ "CANCELLED", @@ -3717,6 +7144,7 @@ class TransactionFullVatRate(pydantic.BaseModel): ], str, ] +TransactionFullSimpleStatusInput = TransactionFullSimpleStatus class TransactionFullLocation(pydantic.BaseModel): @@ -3744,6 +7172,36 @@ class TransactionFullLocation(pydantic.BaseModel): """ +class TransactionFullLocationDict(typing_extensions.TypedDict, total=False): + horizontal_accuracy: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + HorizontalAccuracyInput, + typing_extensions.Doc( + "Indication of the precision of the geographical position received from the payment terminal." + ), + ] + ] + lat: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + LatInput, + typing_extensions.Doc( + "Latitude value from the coordinates of the payment location (as received from the payment terminal reader).\nMin: 0\nMax: 90" + ), + ] + ] + lon: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + LonInput, + typing_extensions.Doc( + "Longitude value from the coordinates of the payment location (as received from the payment terminal reader).\nMin: 0\nMax: 180" + ), + ] + ] + + +TransactionFullLocationInput = TransactionFullLocationDict + + class TransactionFull(pydantic.BaseModel): """ Full transaction resource with checkout, payout, and event details. @@ -3980,17 +7438,302 @@ class TransactionFull(pydantic.BaseModel): """ +class TransactionFullDict(typing_extensions.TypedDict, total=False): + amount: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + float, typing_extensions.Doc("Total amount of the transaction.") + ] + ] + auth_code: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Authorization code for the transaction sent by the payment card issuer or bank. Applicable only to card payments." + ), + ] + ] + card: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + CardResponseInput, typing_extensions.Doc("Details of the payment card.") + ] + ] + client_transaction_id: typing_extensions.NotRequired[ + typing_extensions.Annotated[str, typing_extensions.Doc("Client transaction id.")] + ] + currency: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + CurrencyInput, + typing_extensions.Doc( + "Three-letter [ISO4217](https://en.wikipedia.org/wiki/ISO_4217) code of the currency for the amount. Currently supportedcurrency values are enumerated above." + ), + ] + ] + device_info: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + DeviceInput, + typing_extensions.Doc("Details of the device used to create the transaction."), + ] + ] + elv_account: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + ElvCardAccountInput, + typing_extensions.Doc( + "Details of the ELV card account associated with the transaction." + ), + ] + ] + entry_mode: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + EntryModeInput, typing_extensions.Doc("Entry mode of the payment details.") + ] + ] + events: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + typing.Sequence[EventInput], + typing_extensions.Doc("Compact list of events related to the transaction."), + ] + ] + fee_amount: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + float, typing_extensions.Doc("Transaction SumUp total fee amount.\nFormat: decimal") + ] + ] + foreign_transaction_id: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, typing_extensions.Doc("External/foreign transaction id (passed by clients).") + ] + ] + horizontal_accuracy: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + HorizontalAccuracyInput, + typing_extensions.Doc( + "Indication of the precision of the geographical position received from the payment terminal." + ), + ] + ] + id: typing_extensions.NotRequired[ + typing_extensions.Annotated[str, typing_extensions.Doc("Unique ID of the transaction.")] + ] + installments_count: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + int, + typing_extensions.Doc( + "Current number of the installment for deferred payments.\nMin: 1" + ), + ] + ] + lat: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + LatInput, + typing_extensions.Doc( + "Latitude value from the coordinates of the payment location (as received from the payment terminal reader).\nMin: 0\nMax: 90" + ), + ] + ] + links: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + typing.Sequence[LinkInput], + typing_extensions.Doc("List of hyperlinks for accessing related resources."), + ] + ] + local_time: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + datetime.datetime, + typing_extensions.Doc("Local date and time of the creation of the transaction."), + ] + ] + location: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + TransactionFullLocationInput, + typing_extensions.Doc( + "Details of the payment location as received from the payment terminal." + ), + ] + ] + lon: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + LonInput, + typing_extensions.Doc( + "Longitude value from the coordinates of the payment location (as received from the payment terminal reader).\nMin: 0\nMax: 180" + ), + ] + ] + merchant_code: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Unique code of the registered merchant to whom the payment is made." + ), + ] + ] + merchant_id: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + int, typing_extensions.Doc("SumUp merchant internal Id.\nFormat: int64") + ] + ] + payment_type: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + PaymentTypeInput, typing_extensions.Doc("Payment type used for the transaction.") + ] + ] + payout_date: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + datetime.date, typing_extensions.Doc("The date of the payout.\nFormat: date") + ] + ] + payout_plan: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + TransactionFullPayoutPlanInput, + typing_extensions.Doc( + "Payout plan of the registered user at the time when the transaction was made." + ), + ] + ] + payout_type: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + TransactionFullPayoutTypeInput, + typing_extensions.Doc("Payout type for the transaction."), + ] + ] + payouts_received: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + int, + typing_extensions.Doc( + "Number of payouts that are made to the registered user specified in the `user` property." + ), + ] + ] + payouts_total: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + int, + typing_extensions.Doc( + "Total number of payouts to the registered user specified in the `user` property." + ), + ] + ] + process_as: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + TransactionFullProcessAInput, typing_extensions.Doc("Debit/Credit.") + ] + ] + product_summary: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Short description of the payment. The value is taken from the `description` property of the related checkout resource." + ), + ] + ] + products: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + typing.Sequence[ProductInput], + typing_extensions.Doc( + "List of products from the merchant's catalogue for which the transaction serves as a payment." + ), + ] + ] + simple_payment_type: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + TransactionFullSimplePaymentTypeInput, + typing_extensions.Doc("Simple name of the payment type."), + ] + ] + simple_status: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + TransactionFullSimpleStatusInput, + typing_extensions.Doc( + "High-level status of the transaction from the merchant's perspective.\n\n- `PENDING`: The payment has been initiated and is still being processed. A final outcome is not available yet.\n-`SUCCESSFUL`: The payment was completed successfully.\n- `PAID_OUT`: The payment was completed successfully and the funds have already been included in a payout tothe merchant.\n- `FAILED`: The payment did not complete successfully.\n- `CANCELLED`: The payment was cancelled or reversed and is no longer payable or payable to the merchant.\n- `CANCEL_FAILED`: An attempt to cancel or reverse the payment was not completed successfully.\n- `REFUNDED`: The payment was refunded in full or in part.\n- `REFUND_FAILED`: An attempt to refund the payment was not completed successfully.\n- `CHARGEBACK`: The payment was subject to a chargeback.\n- `NON_COLLECTION`: The amount could not be collected from the merchant after a chargeback or related adjustment." + ), + ] + ] + status: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + TransactionFullStatusInput, typing_extensions.Doc("Current status of the transaction.") + ] + ] + tax_enabled: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + bool, + typing_extensions.Doc( + "Indicates whether tax deduction is enabled for the transaction." + ), + ] + ] + timestamp: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + datetime.datetime, + typing_extensions.Doc( + "Date and time of the creation of the transaction. Response format expressed according to [ISO8601](https://en.wikipedia.org/wiki/ISO_8601) code." + ), + ] + ] + tip_amount: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + float, typing_extensions.Doc("Amount of the tip (out of the total transaction amount).") + ] + ] + transaction_code: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Transaction code returned by the acquirer/processing entity after processing the transaction." + ), + ] + ] + transaction_events: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + typing.Sequence[TransactionEventInput], + typing_extensions.Doc("Detailed list of events related to the transaction."), + ] + ] + username: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Email address of the registered user (merchant) to whom the payment is made.\nFormat: email" + ), + ] + ] + vat_amount: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + float, + typing_extensions.Doc( + "Amount of the applicable VAT (out of the total transaction amount)." + ), + ] + ] + vat_rates: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + typing.Sequence[TransactionFullVatRateInput], + typing_extensions.Doc("List of VAT rates applicable to the transaction."), + ] + ] + verification_method: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + TransactionFullVerificationMethodInput, + typing_extensions.Doc("Verification method used for the transaction."), + ] + ] + + +TransactionFullInput = TransactionFullDict + + TransactionHistoryStatus = typing.Union[ typing.Literal["CANCELLED", "FAILED", "PENDING", "SUCCESSFUL"], str ] +TransactionHistoryStatusInput = TransactionHistoryStatus TransactionHistoryPayoutPlan = typing.Union[ typing.Literal["ACCELERATED_INSTALLMENT", "SINGLE_PAYMENT", "TRUE_INSTALLMENT"], str ] +TransactionHistoryPayoutPlanInput = TransactionHistoryPayoutPlan TransactionHistoryType = typing.Union[typing.Literal["CHARGE_BACK", "PAYMENT", "REFUND"], str] +TransactionHistoryTypeInput = TransactionHistoryType TransactionHistoryPayoutType = typing.Union[typing.Literal["BANK_ACCOUNT", "PREPAID_CARD"], str] +TransactionHistoryPayoutTypeInput = TransactionHistoryPayoutType class TransactionHistory(pydantic.BaseModel): @@ -4103,6 +7846,144 @@ class TransactionHistory(pydantic.BaseModel): """ +class TransactionHistoryDict(typing_extensions.TypedDict, total=False): + amount: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + float, typing_extensions.Doc("Total amount of the transaction.") + ] + ] + card_type: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + CardTypeInput, + typing_extensions.Doc( + "Issuing card network of the payment card used for the transaction." + ), + ] + ] + client_transaction_id: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, typing_extensions.Doc("Client-specific ID of the transaction.") + ] + ] + currency: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + CurrencyInput, + typing_extensions.Doc( + "Three-letter [ISO4217](https://en.wikipedia.org/wiki/ISO_4217) code of the currency for the amount. Currently supportedcurrency values are enumerated above." + ), + ] + ] + id: typing_extensions.NotRequired[ + typing_extensions.Annotated[str, typing_extensions.Doc("Unique ID of the transaction.")] + ] + installments_count: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + int, + typing_extensions.Doc( + "Current number of the installment for deferred payments.\nMin: 1" + ), + ] + ] + payment_type: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + PaymentTypeInput, typing_extensions.Doc("Payment type used for the transaction.") + ] + ] + payout_date: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + datetime.date, typing_extensions.Doc("Payout date (if paid out at once).\nFormat: date") + ] + ] + payout_plan: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + TransactionHistoryPayoutPlanInput, + typing_extensions.Doc( + "Payout plan of the registered user at the time when the transaction was made." + ), + ] + ] + payout_type: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + TransactionHistoryPayoutTypeInput, typing_extensions.Doc("Payout type.") + ] + ] + payouts_received: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + int, + typing_extensions.Doc( + "Number of payouts that are made to the registered user specified in the `user` property." + ), + ] + ] + payouts_total: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + int, + typing_extensions.Doc( + "Total number of payouts to the registered user specified in the `user` property." + ), + ] + ] + product_summary: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Short description of the payment. The value is taken from the `description` property of the related checkout resource." + ), + ] + ] + refunded_amount: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + float, typing_extensions.Doc("Total refunded amount.\nFormat: decimal") + ] + ] + status: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + TransactionHistoryStatusInput, + typing_extensions.Doc("Current status of the transaction."), + ] + ] + timestamp: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + datetime.datetime, + typing_extensions.Doc( + "Date and time of the creation of the transaction. Response format expressed according to [ISO8601](https://en.wikipedia.org/wiki/ISO_8601) code." + ), + ] + ] + transaction_code: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Transaction code returned by the acquirer/processing entity after processing the transaction." + ), + ] + ] + transaction_id: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + TransactionIdInput, typing_extensions.Doc("Unique ID of the transaction.") + ] + ] + type: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + TransactionHistoryTypeInput, + typing_extensions.Doc( + "Type of the transaction for the registered user specified in the `user` property." + ), + ] + ] + user: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + str, + typing_extensions.Doc( + "Email address of the registered user (merchant) to whom the payment is made.\nFormat: email" + ), + ] + ] + + +TransactionHistoryInput = TransactionHistoryDict + + class TransactionsHistoryLink(pydantic.BaseModel): """ Hypermedia link used for transaction history pagination. @@ -4119,9 +8000,22 @@ class TransactionsHistoryLink(pydantic.BaseModel): """ +class TransactionsHistoryLinkDict(typing_extensions.TypedDict, total=False): + href: typing_extensions.Required[ + typing_extensions.Annotated[str, typing_extensions.Doc("Location.")] + ] + rel: typing_extensions.Required[ + typing_extensions.Annotated[str, typing_extensions.Doc("Relation.")] + ] + + +TransactionsHistoryLinkInput = TransactionsHistoryLinkDict + + UnauthorizedErrorsType = typing.Union[ typing.Literal["INVALID_ACCESS_TOKEN", "INVALID_PASSWORD"], str ] +UnauthorizedErrorsTypeInput = UnauthorizedErrorsType class UnauthorizedErrors(pydantic.BaseModel): @@ -4140,9 +8034,35 @@ class UnauthorizedErrors(pydantic.BaseModel): """ +class UnauthorizedErrorsDict(typing_extensions.TypedDict, total=False): + detail: typing_extensions.Required[ + typing_extensions.Annotated[ + str, typing_extensions.Doc("Fuller message giving context to error") + ] + ] + type: typing_extensions.NotRequired[ + typing_extensions.Annotated[ + UnauthorizedErrorsTypeInput, + typing_extensions.Doc( + "Key indicating type of error. Present only for typed 401 responses (e.g. invalid token, invalid password). Absentfor generic unauthorized responses." + ), + ] + ] + + +UnauthorizedErrorsInput = UnauthorizedErrorsDict + + class Unauthorized(pydantic.BaseModel): """ 401 Unauthorized """ errors: UnauthorizedErrors + + +class UnauthorizedDict(typing_extensions.TypedDict, total=False): + errors: typing_extensions.Required[UnauthorizedErrorsInput] + + +UnauthorizedInput = UnauthorizedDict diff --git a/tests/test_query_params.py b/tests/test_query_params.py index 17f4fab9..7b0ba00a 100644 --- a/tests/test_query_params.py +++ b/tests/test_query_params.py @@ -2,21 +2,21 @@ import pytest import typing -from sumup.transactions import ListTransactionsV21Params +from sumup._service import NotGivenType @pytest.mark.parametrize( - ("params", "expected_query_items"), + ("kwargs", "expected_query_items"), [ - (ListTransactionsV21Params(limit=10), [("limit", "10")]), - (None, []), + ({"limit": 10}, [("limit", "10")]), + ({}, []), ( - ListTransactionsV21Params(statuses=["SUCCESSFUL", "FAILED"]), + {"statuses": ["SUCCESSFUL", "FAILED"]}, [("statuses[]", "SUCCESSFUL"), ("statuses[]", "FAILED")], ), ], ) -def test_transactions_list_query_params(params, expected_query_items, sdk_factory): +def test_transactions_list_query_params(kwargs, expected_query_items, sdk_factory): captured_request: dict[str, httpx.Request] = {} def handler(request: httpx.Request) -> httpx.Response: @@ -24,10 +24,6 @@ def handler(request: httpx.Request) -> httpx.Response: return httpx.Response(200, json={"items": []}) sdk = sdk_factory(handler) - kwargs = {} - if params is not None: - kwargs["params"] = params - response = sdk.transactions.list("merchant-123", **kwargs) assert response.items == [] @@ -38,11 +34,18 @@ def handler(request: httpx.Request) -> httpx.Response: def test_transactions_list_query_param_enums_are_typed(): - order_annotation = ListTransactionsV21Params.model_fields["order"].annotation + annotations = sdk_annotations() + order_annotation = annotations["order"] assert typing.get_origin(order_annotation) is typing.Union assert typing.get_args(order_annotation) == ( typing.Literal["ascending", "descending"], str, - type(None), + NotGivenType, ) + + +def sdk_annotations(): + from sumup.transactions.resource import TransactionsResource + + return typing.get_type_hints(TransactionsResource.list) diff --git a/tests/test_request_bodies.py b/tests/test_request_bodies.py index ae4a084a..ff12c610 100644 --- a/tests/test_request_bodies.py +++ b/tests/test_request_bodies.py @@ -1,10 +1,8 @@ +import datetime import json import httpx -from sumup.readers import CreateReaderCheckoutBody, CreateReaderCheckoutBodyTotalAmount -from sumup.subaccounts import UpdateSubAccountBody - def test_create_reader_checkout_omits_null_fields(sdk_factory): captured_request: dict[str, httpx.Request] = {} @@ -14,12 +12,12 @@ def handler(request: httpx.Request) -> httpx.Response: return httpx.Response(201, json={"data": {"client_transaction_id": "txn-123"}}) sdk = sdk_factory(handler) - body = CreateReaderCheckoutBody( - total_amount=CreateReaderCheckoutBodyTotalAmount(currency="EUR", minor_unit=2, value=1500) + response = sdk.readers.create_checkout( + "merchant-123", + "reader-456", + total_amount={"currency": "EUR", "minor_unit": 2, "value": 1500}, ) - response = sdk.readers.create_checkout("merchant-123", "reader-456", body) - assert response.data.client_transaction_id == "txn-123" assert "request" in captured_request request = captured_request["request"] @@ -29,6 +27,34 @@ def handler(request: httpx.Request) -> httpx.Response: } +def test_create_checkout_serializes_datetime_fields(sdk_factory): + captured_request: dict[str, httpx.Request] = {} + + def handler(request: httpx.Request) -> httpx.Response: + captured_request["request"] = request + return httpx.Response(201, json={"id": "checkout-123"}) + + sdk = sdk_factory(handler) + response = sdk.checkouts.create( + amount=15.0, + checkout_reference="checkout-ref", + currency="EUR", + merchant_code="merchant-123", + valid_until=datetime.datetime(2024, 1, 2, 3, 4, 5), + ) + + assert response.id == "checkout-123" + assert "request" in captured_request + request = captured_request["request"] + assert json.loads(request.content) == { + "amount": 15.0, + "checkout_reference": "checkout-ref", + "currency": "EUR", + "merchant_code": "merchant-123", + "valid_until": "2024-01-02T03:04:05", + } + + def test_update_subaccount_accepts_explicit_null_fields(sdk_factory): captured_request: dict[str, httpx.Request] = {} @@ -55,9 +81,7 @@ def handler(request: httpx.Request) -> httpx.Response: ) sdk = sdk_factory(handler) - body = UpdateSubAccountBody(nickname=None) - - response = sdk.subaccounts.update_sub_account(1, body) + response = sdk.subaccounts.update_sub_account(1, nickname=None) assert response.nickname is None assert "request" in captured_request diff --git a/tests/test_secret.py b/tests/test_secret.py index 4ea59d80..5533af2c 100644 --- a/tests/test_secret.py +++ b/tests/test_secret.py @@ -1,5 +1,5 @@ from sumup._secret import Secret -from sumup.members.resource import CreateMerchantMemberBody +from sumup._service import serialize_request_data def test_secret_masks_repr_but_preserves_value() -> None: @@ -11,17 +11,17 @@ def test_secret_masks_repr_but_preserves_value() -> None: assert secret == "super-secret" -def test_password_fields_use_secret_and_dump_plain_text() -> None: - body = CreateMerchantMemberBody( - email="user@example.com", - roles=["role_manager"], - is_managed_user=True, - password=Secret("super-secret"), - ) +def test_request_serialization_dumps_secret_plain_text() -> None: + payload = { + "email": "user@example.com", + "password": Secret("super-secret"), + "nested": {"password": Secret("super-secret")}, + } - assert isinstance(body.password, Secret) - dumped = body.model_dump() - assert dumped["password"] == "super-secret" + dumped = serialize_request_data(payload) - body_repr = repr(body) - assert "super-secret" not in body_repr + assert dumped == { + "email": "user@example.com", + "password": "super-secret", + "nested": {"password": "super-secret"}, + } From b573d2bc75afd4616f07e2f032680094425b38c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matou=C5=A1=20Dzivjak?= Date: Thu, 23 Apr 2026 09:02:38 +0200 Subject: [PATCH 2/2] chore: address warnings in tests/check --- codegen/pkg/builder/builder.go | 11 +- codegen/pkg/builder/collect.go | 66 +- codegen/pkg/builder/doc.go | 13 +- .../builder/intermediate_representation.go | 19 +- codegen/pkg/builder/methods.go | 12 +- codegen/pkg/builder/out.go | 58 +- codegen/pkg/builder/transform.go | 8 + codegen/pkg/builder/types.go | 77 +- sumup/__init__.py | 2 +- sumup/checkouts/__init__.py | 4 - sumup/checkouts/resource.py | 103 +- sumup/customers/resource.py | 22 +- sumup/members/resource.py | 59 +- sumup/memberships/resource.py | 19 +- sumup/merchants/resource.py | 24 - sumup/payouts/__init__.py | 8 - sumup/payouts/resource.py | 13 +- sumup/readers/__init__.py | 2 - sumup/readers/resource.py | 79 +- sumup/receipts/resource.py | 14 - sumup/roles/resource.py | 33 +- sumup/subaccounts/resource.py | 38 +- sumup/transactions/__init__.py | 12 - sumup/transactions/resource.py | 69 +- sumup/types/__init__.py | 3414 +---------------- tests/test_request_bodies.py | 5 +- 26 files changed, 329 insertions(+), 3855 deletions(-) diff --git a/codegen/pkg/builder/builder.go b/codegen/pkg/builder/builder.go index 011ef2e4..019c26d3 100644 --- a/codegen/pkg/builder/builder.go +++ b/codegen/pkg/builder/builder.go @@ -29,6 +29,8 @@ type Builder struct { // schemasByTag maps tags to respective schema references. schemasByTag map[string][]*base.SchemaProxy + // requestSchemasByTag maps tags to schemas referenced from request bodies/query params. + requestSchemasByTag map[string][]*base.SchemaProxy pathsByTag map[string]*v3.Paths @@ -58,10 +60,11 @@ func New(cfg Config, opts ...Option) *Builder { } b := &Builder{ - cfg: cfg, - schemasByTag: make(map[string][]*base.SchemaProxy), - pathsByTag: make(map[string]*v3.Paths), - templates: templates, + cfg: cfg, + schemasByTag: make(map[string][]*base.SchemaProxy), + requestSchemasByTag: make(map[string][]*base.SchemaProxy), + pathsByTag: make(map[string]*v3.Paths), + templates: templates, } for _, o := range opts { diff --git a/codegen/pkg/builder/collect.go b/codegen/pkg/builder/collect.go index ba70a141..2077192c 100644 --- a/codegen/pkg/builder/collect.go +++ b/codegen/pkg/builder/collect.go @@ -51,41 +51,51 @@ func (b *Builder) collectPaths() { func (b *Builder) collectSchemas() { // Map of schemas grouped by tag schemasByTag := make(map[string][]*base.SchemaProxy) + requestSchemasByTag := make(map[string][]*base.SchemaProxy) for path, pathItem := range b.spec.Paths.PathItems.FromOldest() { for method, op := range pathItem.GetOperations().FromOldest() { - c := make(SchemaProxyCollection, 0, 100) - c.collectSchemasInResponse(op) - c.collectSchemasInParams(op) - c.collectSchemasInRequest(op) - - for _, schema := range c { - if schema.GetReference() == "" { - continue - } - - if len(op.Tags) == 0 { - slog.Error("no tags for schema under operation", - slog.String("path", path), - slog.String("method", method), - slog.String("ref", schema.GetReference()), - ) - continue - } - - for _, tag := range op.Tags { - tagLower := strings.ToLower(tag) - if !slices.ContainsFunc(schemasByTag[tagLower], func(sp *base.SchemaProxy) bool { - return sp.GetReference() == schema.GetReference() - }) { - schemasByTag[tagLower] = append(schemasByTag[tagLower], schema) - } - } - } + allSchemas := make(SchemaProxyCollection, 0, 100) + allSchemas.collectSchemasInResponse(op) + allSchemas.collectSchemasInParams(op) + allSchemas.collectSchemasInRequest(op) + b.collectSchemasByTag(schemasByTag, path, method, op, allSchemas) + + requestSchemas := make(SchemaProxyCollection, 0, 100) + requestSchemas.collectSchemasInParams(op) + requestSchemas.collectSchemasInRequest(op) + b.collectSchemasByTag(requestSchemasByTag, path, method, op, requestSchemas) } } b.schemasByTag = schemasByTag + b.requestSchemasByTag = requestSchemasByTag +} + +func (b *Builder) collectSchemasByTag(dest map[string][]*base.SchemaProxy, path, method string, op *v3.Operation, schemas SchemaProxyCollection) { + for _, schema := range schemas { + if schema.GetReference() == "" { + continue + } + + if len(op.Tags) == 0 { + slog.Error("no tags for schema under operation", + slog.String("path", path), + slog.String("method", method), + slog.String("ref", schema.GetReference()), + ) + continue + } + + for _, tag := range op.Tags { + tagLower := strings.ToLower(tag) + if !slices.ContainsFunc(dest[tagLower], func(sp *base.SchemaProxy) bool { + return sp.GetReference() == schema.GetReference() + }) { + dest[tagLower] = append(dest[tagLower], schema) + } + } + } } type SchemaProxyCollection []*base.SchemaProxy diff --git a/codegen/pkg/builder/doc.go b/codegen/pkg/builder/doc.go index 80b08603..5ff22ab1 100644 --- a/codegen/pkg/builder/doc.go +++ b/codegen/pkg/builder/doc.go @@ -47,12 +47,6 @@ func methodDoc(operation *v3.Operation) string { return formatDoc(out.String()) } -// operationParamsDoc creates godoc comment for a struct representing -// parameters of an operation. -func operationParamsDoc(name string, operation *v3.Operation) string { - return formatDoc(name + ": query parameters for " + operation.OperationId) -} - // schemaDoc creates godoc for a schema. func schemaDoc(name string, schema *base.Schema) string { out := new(strings.Builder) @@ -191,5 +185,10 @@ func formatDoc(s string) string { } } - return strings.TrimSpace(out.String()) + return escapePythonDocString(strings.TrimSpace(out.String())) +} + +func escapePythonDocString(s string) string { + s = strings.ReplaceAll(s, "\\", "\\\\") + return s } diff --git a/codegen/pkg/builder/intermediate_representation.go b/codegen/pkg/builder/intermediate_representation.go index f2fdc143..ac659929 100644 --- a/codegen/pkg/builder/intermediate_representation.go +++ b/codegen/pkg/builder/intermediate_representation.go @@ -21,12 +21,15 @@ type ClassDeclaration struct { AdditionalPropertiesType string // RequestOnly marks request-only helper types that should not emit response models. RequestOnly bool + // GenerateInput indicates this type needs an Input companion. + GenerateInput bool } type OneOfDeclaration struct { - Name string - Options []string - RequestOnly bool + Name string + Options []string + RequestOnly bool + GenerateInput bool } // Property holds the information for Property of a type. @@ -53,6 +56,9 @@ type EnumDeclaration[E cmp.Ordered] struct { // Comment holds the description of the type Comment string Values []E + // RequestOnly marks request-only helper types that should only emit input aliases. + RequestOnly bool + GenerateInput bool } type Response struct { @@ -72,7 +78,8 @@ type TypeAlias struct { // Comment holds the description of the type Comment string // RequestOnly marks request-only helper types that should only emit input aliases. - RequestOnly bool + RequestOnly bool + GenerateInput bool } func (ta *TypeAlias) String() string { @@ -85,7 +92,9 @@ func (ta *TypeAlias) String() string { return buf.String() } fmt.Fprintf(buf, "%s = %s\n", ta.Name, ta.Type) - fmt.Fprintf(buf, "%sInput = %s\n", ta.Name, inputTypeName(ta.Type)) + if ta.GenerateInput { + fmt.Fprintf(buf, "%sInput = %s\n", ta.Name, inputTypeName(ta.Type)) + } if ta.Comment != "" { fmt.Fprintf(buf, "'''\n%s\n'''\n", ta.Comment) } diff --git a/codegen/pkg/builder/methods.go b/codegen/pkg/builder/methods.go index b56e91e9..e1649289 100644 --- a/codegen/pkg/builder/methods.go +++ b/codegen/pkg/builder/methods.go @@ -57,7 +57,7 @@ func (mt Method) ParamsString() string { } for _, p := range mt.BodyFields { res.WriteString(", ") - res.WriteString(p.MethodParameterString()) + res.WriteString(p.MethodParameterString(true)) } } else if mt.HasBody { res.WriteString(", ") @@ -69,7 +69,7 @@ func (mt Method) ParamsString() string { } for _, p := range mt.QueryFields { res.WriteString(", ") - res.WriteString(p.MethodParameterString()) + res.WriteString(p.MethodParameterString(false)) } } return res.String() @@ -89,9 +89,9 @@ func (mt Method) BodyInitString() string { for _, field := range mt.BodyFields { if field.Optional { fmt.Fprintf(&buf, "if not isinstance(%s, NotGivenType):\n", field.FieldName()) - fmt.Fprintf(&buf, "\tbody_data[%q] = %s\n", field.WireName(), field.BodyArgumentExpr()) + fmt.Fprintf(&buf, "\tbody_data[%q] = %s\n", field.WireName(), field.BodyArgumentExpr(true)) } else { - fmt.Fprintf(&buf, "body_data[%q] = %s\n", field.WireName(), field.BodyArgumentExpr()) + fmt.Fprintf(&buf, "body_data[%q] = %s\n", field.WireName(), field.BodyArgumentExpr(true)) } } @@ -108,9 +108,9 @@ func (mt Method) QueryInitString() string { for _, field := range mt.QueryFields { if field.Optional { fmt.Fprintf(&buf, "if not isinstance(%s, NotGivenType) and %s is not None:\n", field.FieldName(), field.FieldName()) - fmt.Fprintf(&buf, "\tquery_data[%q] = %s\n", field.WireName(), field.BodyArgumentExpr()) + fmt.Fprintf(&buf, "\tquery_data[%q] = %s\n", field.WireName(), field.BodyArgumentExpr(false)) } else { - fmt.Fprintf(&buf, "query_data[%q] = %s\n", field.WireName(), field.BodyArgumentExpr()) + fmt.Fprintf(&buf, "query_data[%q] = %s\n", field.WireName(), field.BodyArgumentExpr(false)) } } return buf.String() diff --git a/codegen/pkg/builder/out.go b/codegen/pkg/builder/out.go index ed2e7a68..e96ced00 100644 --- a/codegen/pkg/builder/out.go +++ b/codegen/pkg/builder/out.go @@ -29,7 +29,11 @@ func (b *Builder) generateSharedTypes() error { continue } typeName := strcase.ToCamel(name) - types = append(types, b.generateSchemaComponents(typeName, schema.Schema())...) + generated := b.generateSchemaComponents(typeName, schema.Schema()) + if b.isRequestSchema(typeName) { + markGenerateInput(generated) + } + types = append(types, generated...) } } usesSecret := usesSecretType(types) @@ -144,7 +148,7 @@ func (b *Builder) generateResourceFile(tagName string, paths *v3.Paths) ([]strin if err := b.templates.ExecuteTemplate(serviceBuf, "resource.py.tmpl", resourceTemplateData{ PackageName: strcase.ToSnake(tag.Name), TypeNames: typeNames, - InputTypeNames: inputTypeNames(typeNames), + InputTypeNames: inputTypeNames(b.requestSchemaTypeNamesByTag(tagName)), Params: innerTypes, Service: strcase.ToCamel(tag.Name), Methods: methods, @@ -362,6 +366,48 @@ func inputTypeNames(typeNames []string) []string { return res } +func (b *Builder) requestSchemaTypeNamesByTag(tagName string) []string { + resolvedSchemas := b.requestSchemasByTag[tagName] + typeNames := make([]string, 0, len(resolvedSchemas)) + for _, s := range resolvedSchemas { + if name := b.getReferenceSchema(s); name != "" { + typeNames = append(typeNames, name) + } + } + slices.Sort(typeNames) + return slices.Compact(typeNames) +} + +func (b *Builder) isRequestSchema(typeName string) bool { + for tagName := range b.requestSchemasByTag { + if slices.Contains(b.requestSchemaTypeNamesByTag(tagName), typeName) { + return true + } + } + return false +} + +func markGenerateInput(types []Writable) { + for _, typ := range types { + switch t := typ.(type) { + case *ClassDeclaration: + t.GenerateInput = true + case *TypeAlias: + t.GenerateInput = true + case *OneOfDeclaration: + t.GenerateInput = true + case *EnumDeclaration[string]: + t.GenerateInput = true + case *EnumDeclaration[int]: + t.GenerateInput = true + case *EnumDeclaration[int64]: + t.GenerateInput = true + case *EnumDeclaration[float64]: + t.GenerateInput = true + } + } +} + func writableRequestOnly(w Writable) bool { switch typed := w.(type) { case *ClassDeclaration: @@ -370,6 +416,14 @@ func writableRequestOnly(w Writable) bool { return typed.RequestOnly case *OneOfDeclaration: return typed.RequestOnly + case *EnumDeclaration[string]: + return typed.RequestOnly + case *EnumDeclaration[int]: + return typed.RequestOnly + case *EnumDeclaration[int64]: + return typed.RequestOnly + case *EnumDeclaration[float64]: + return typed.RequestOnly default: return false } diff --git a/codegen/pkg/builder/transform.go b/codegen/pkg/builder/transform.go index 1ab7e32f..0b9d0c97 100644 --- a/codegen/pkg/builder/transform.go +++ b/codegen/pkg/builder/transform.go @@ -104,6 +104,14 @@ func markRequestType(typ Writable) { t.RequestOnly = true case *OneOfDeclaration: t.RequestOnly = true + case *EnumDeclaration[string]: + t.RequestOnly = true + case *EnumDeclaration[int]: + t.RequestOnly = true + case *EnumDeclaration[int64]: + t.RequestOnly = true + case *EnumDeclaration[float64]: + t.RequestOnly = true } } diff --git a/codegen/pkg/builder/types.go b/codegen/pkg/builder/types.go index 5c64ce47..937d5e44 100644 --- a/codegen/pkg/builder/types.go +++ b/codegen/pkg/builder/types.go @@ -112,29 +112,31 @@ func (c *ClassDeclaration) String() string { fmt.Fprintf(buf, "\tdef additional_properties(self, value: dict[str, %s]) -> None:\n", c.AdditionalPropertiesType) fmt.Fprint(buf, "\t\tobject.__setattr__(self, \"__pydantic_extra__\", dict(value))\n") } - fmt.Fprint(buf, "\n") - fmt.Fprintf(buf, "class %sDict(typing_extensions.TypedDict, total=False):\n", c.Name) - if len(c.Fields) == 0 { - fmt.Fprint(buf, "\tpass\n") - } else { - fields := append([]Property(nil), c.Fields...) - slices.SortFunc(fields, func(a, b Property) int { - if a.Optional && !b.Optional { - return 1 - } - if b.Optional && !a.Optional { - return -1 + if c.GenerateInput { + fmt.Fprint(buf, "\n") + fmt.Fprintf(buf, "class %sDict(typing_extensions.TypedDict, total=False):\n", c.Name) + if len(c.Fields) == 0 { + fmt.Fprint(buf, "\tpass\n") + } else { + fields := append([]Property(nil), c.Fields...) + slices.SortFunc(fields, func(a, b Property) int { + if a.Optional && !b.Optional { + return 1 + } + if b.Optional && !a.Optional { + return -1 + } + return strings.Compare(a.Name, b.Name) + }) + for _, ft := range fields { + fmt.Fprint(buf, "\n") + fmt.Fprint(buf, indent(1, ft.TypedDictFieldString())) } - return strings.Compare(a.Name, b.Name) - }) - for _, ft := range fields { - fmt.Fprint(buf, "\n") - fmt.Fprint(buf, indent(1, ft.TypedDictFieldString())) } + fmt.Fprint(buf, "\n") + fmt.Fprintf(buf, "%sInput = %sDict\n", c.Name, c.Name) + fmt.Fprint(buf, "\n") } - fmt.Fprint(buf, "\n") - fmt.Fprintf(buf, "%sInput = %sDict\n", c.Name, c.Name) - fmt.Fprint(buf, "\n") return buf.String() } @@ -155,7 +157,9 @@ func (o *OneOfDeclaration) String() string { fmt.Fprintf(buf, "%s = typing.Union[", o.Name) fmt.Fprint(buf, strings.Join(o.Options, ", ")) fmt.Fprintf(buf, "]\n") - fmt.Fprintf(buf, "%sInput = typing.Union[%s]", o.Name, strings.Join(options, ", ")) + if o.GenerateInput { + fmt.Fprintf(buf, "%sInput = typing.Union[%s]", o.Name, strings.Join(options, ", ")) + } return buf.String() } @@ -202,9 +206,12 @@ func (p Property) WireName() string { return p.FieldName() } -func (p Property) MethodParameterString() string { +func (p Property) MethodParameterString(allowNone bool) string { typeName := p.MethodParameterType() if p.Optional { + if allowNone { + return fmt.Sprintf("%s: typing.Union[%s, None, NotGivenType] = NOT_GIVEN", p.FieldName(), typeName) + } return fmt.Sprintf("%s: typing.Union[%s, NotGivenType] = NOT_GIVEN", p.FieldName(), typeName) } @@ -215,9 +222,12 @@ func (p Property) MethodParameterType() string { return inputTypeName(p.Type) } -func (p Property) BodyArgumentExpr() string { +func (p Property) BodyArgumentExpr(allowNone bool) string { name := p.FieldName() if strings.HasPrefix(p.Type, "list[") { + if allowNone && p.Optional { + return fmt.Sprintf("(list(%s) if %s is not None else None)", name, name) + } return fmt.Sprintf("list(%s)", name) } @@ -237,17 +247,20 @@ func (p Property) TypedDictFieldString() string { } func (e *EnumDeclaration[E]) String() string { - buf := new(strings.Builder) - fmt.Fprintf(buf, "%s = typing.Union[typing.Literal[", e.Name) + values := make([]string, 0, len(e.Values)) slices.Sort(e.Values) - for i, v := range e.Values { - if i != 0 { - fmt.Fprint(buf, ", ") - } - fmt.Fprintf(buf, "%#v", v) + for _, v := range e.Values { + values = append(values, fmt.Sprintf("%#v", v)) + } + alias := fmt.Sprintf("typing.Union[typing.Literal[%s], %s]", strings.Join(values, ", "), pythonEnumBaseType(e.Type)) + if e.RequestOnly { + return fmt.Sprintf("%sInput = %s\n", e.Name, alias) + } + buf := new(strings.Builder) + fmt.Fprintf(buf, "%s = %s\n", e.Name, alias) + if e.GenerateInput { + fmt.Fprintf(buf, "%sInput = %s\n", e.Name, e.Name) } - fmt.Fprintf(buf, "], %s]\n", pythonEnumBaseType(e.Type)) - fmt.Fprintf(buf, "%sInput = %s\n", e.Name, e.Name) return buf.String() } diff --git a/sumup/__init__.py b/sumup/__init__.py index 2c7b40f7..55f9ae10 100644 --- a/sumup/__init__.py +++ b/sumup/__init__.py @@ -2,4 +2,4 @@ from sumup._service import Resource, AsyncResource from sumup._exceptions import APIError -__all__ = ["APIError", "AsyncResource", "AsyncSumup", "MerchantAccount", "Resource", "Sumup"] +__all__ = ["APIError", "AsyncResource", "AsyncSumup", "Resource", "Sumup"] diff --git a/sumup/checkouts/__init__.py b/sumup/checkouts/__init__.py index ce12ea7b..44279794 100755 --- a/sumup/checkouts/__init__.py +++ b/sumup/checkouts/__init__.py @@ -2,8 +2,6 @@ from .resource import ( CheckoutsResource, AsyncCheckoutsResource, - CreateCheckoutBodyPurpose, - ProcessCheckoutBodyPaymentType, GetPaymentMethods200ResponseAvailablePaymentMethod, GetPaymentMethods200Response, ProcessCheckoutResponse, @@ -36,8 +34,6 @@ __all__ = [ "CheckoutsResource", "AsyncCheckoutsResource", - "CreateCheckoutBodyPurpose", - "ProcessCheckoutBodyPaymentType", "GetPaymentMethods200ResponseAvailablePaymentMethod", "GetPaymentMethods200Response", "ProcessCheckoutResponse", diff --git a/sumup/checkouts/resource.py b/sumup/checkouts/resource.py index 98252566..58ff3c9e 100755 --- a/sumup/checkouts/resource.py +++ b/sumup/checkouts/resource.py @@ -55,24 +55,11 @@ AddressLegacyInput, CardInput, CardTypeInput, - CheckoutInput, - CheckoutAcceptedInput, CheckoutCreateRequestInput, - CheckoutSuccessInput, CurrencyInput, - DetailsErrorInput, - EntryModeInput, - ErrorInput, - ErrorExtendedInput, - ErrorForbiddenInput, MandatePayloadInput, - MandateResponseInput, - PaymentTypeInput, PersonalDetailsInput, - ProblemInput, ProcessCheckoutInput, - TransactionBaseInput, - TransactionCheckoutInfoInput, ) import datetime import httpx @@ -80,8 +67,9 @@ import pydantic import typing_extensions -CreateCheckoutBodyPurpose = typing.Union[typing.Literal["CHECKOUT", "SETUP_RECURRING_PAYMENT"], str] -CreateCheckoutBodyPurposeInput = CreateCheckoutBodyPurpose +CreateCheckoutBodyPurposeInput = typing.Union[ + typing.Literal["CHECKOUT", "SETUP_RECURRING_PAYMENT"], str +] class CreateCheckoutBodyInput(typing_extensions.TypedDict, total=False): @@ -166,10 +154,9 @@ class CreateCheckoutBodyInput(typing_extensions.TypedDict, total=False): ] -ProcessCheckoutBodyPaymentType = typing.Union[ +ProcessCheckoutBodyPaymentTypeInput = typing.Union[ typing.Literal["apple_pay", "bancontact", "blik", "boleto", "card", "google_pay", "ideal"], str ] -ProcessCheckoutBodyPaymentTypeInput = ProcessCheckoutBodyPaymentType ProcessCheckoutBodyGooglePayInput = typing.Mapping[str, object] """ @@ -290,19 +277,6 @@ class GetPaymentMethods200ResponseAvailablePaymentMethod(pydantic.BaseModel): """ -class GetPaymentMethods200ResponseAvailablePaymentMethodDict( - typing_extensions.TypedDict, total=False -): - id: typing_extensions.Required[ - typing_extensions.Annotated[str, typing_extensions.Doc("The ID of the payment method.")] - ] - - -GetPaymentMethods200ResponseAvailablePaymentMethodInput = ( - GetPaymentMethods200ResponseAvailablePaymentMethodDict -) - - class GetPaymentMethods200Response(pydantic.BaseModel): """ GetPaymentMethods200Response is a schema definition. @@ -313,25 +287,14 @@ class GetPaymentMethods200Response(pydantic.BaseModel): ] = None -class GetPaymentMethods200ResponseDict(typing_extensions.TypedDict, total=False): - available_payment_methods: typing_extensions.NotRequired[ - typing.Sequence[GetPaymentMethods200ResponseAvailablePaymentMethodInput] - ] - - -GetPaymentMethods200ResponseInput = GetPaymentMethods200ResponseDict - - ListCheckouts200Response = list[CheckoutSuccess] -ListCheckouts200ResponseInput = typing.Sequence[CheckoutSuccessInput] """ ListCheckouts200Response is a schema definition. """ ProcessCheckoutResponse = typing.Union[CheckoutSuccess, CheckoutAccepted] -ProcessCheckoutResponseInput = typing.Union[CheckoutSuccessInput, CheckoutAcceptedInput] + CreateApplePaySession200Response = dict[str, object] -CreateApplePaySession200ResponseInput = typing.Mapping[str, object] """ CreateApplePaySession200Response is a schema definition. """ @@ -385,12 +348,12 @@ def create( amount: float, currency: CurrencyInput, merchant_code: str, - description: typing.Union[str, NotGivenType] = NOT_GIVEN, - return_url: typing.Union[str, NotGivenType] = NOT_GIVEN, - customer_id: typing.Union[str, NotGivenType] = NOT_GIVEN, - purpose: typing.Union[CreateCheckoutBodyPurposeInput, NotGivenType] = NOT_GIVEN, - valid_until: typing.Union[datetime.datetime, NotGivenType] = NOT_GIVEN, - redirect_url: typing.Union[str, NotGivenType] = NOT_GIVEN, + description: typing.Union[str, None, NotGivenType] = NOT_GIVEN, + return_url: typing.Union[str, None, NotGivenType] = NOT_GIVEN, + customer_id: typing.Union[str, None, NotGivenType] = NOT_GIVEN, + purpose: typing.Union[CreateCheckoutBodyPurposeInput, None, NotGivenType] = NOT_GIVEN, + valid_until: typing.Union[datetime.datetime, None, NotGivenType] = NOT_GIVEN, + redirect_url: typing.Union[str, None, NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> Checkout: """ @@ -505,14 +468,14 @@ def process( id: str, *, payment_type: ProcessCheckoutBodyPaymentTypeInput, - installments: typing.Union[int, NotGivenType] = NOT_GIVEN, - mandate: typing.Union[MandatePayloadInput, NotGivenType] = NOT_GIVEN, - card: typing.Union[CardInput, NotGivenType] = NOT_GIVEN, - google_pay: typing.Union[ProcessCheckoutBodyGooglePayInput, NotGivenType] = NOT_GIVEN, - apple_pay: typing.Union[ProcessCheckoutBodyApplePayInput, NotGivenType] = NOT_GIVEN, - token: typing.Union[str, NotGivenType] = NOT_GIVEN, - customer_id: typing.Union[str, NotGivenType] = NOT_GIVEN, - personal_details: typing.Union[PersonalDetailsInput, NotGivenType] = NOT_GIVEN, + installments: typing.Union[int, None, NotGivenType] = NOT_GIVEN, + mandate: typing.Union[MandatePayloadInput, None, NotGivenType] = NOT_GIVEN, + card: typing.Union[CardInput, None, NotGivenType] = NOT_GIVEN, + google_pay: typing.Union[ProcessCheckoutBodyGooglePayInput, None, NotGivenType] = NOT_GIVEN, + apple_pay: typing.Union[ProcessCheckoutBodyApplePayInput, None, NotGivenType] = NOT_GIVEN, + token: typing.Union[str, None, NotGivenType] = NOT_GIVEN, + customer_id: typing.Union[str, None, NotGivenType] = NOT_GIVEN, + personal_details: typing.Union[PersonalDetailsInput, None, NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> ProcessCheckoutResponse: """ @@ -686,12 +649,12 @@ async def create( amount: float, currency: CurrencyInput, merchant_code: str, - description: typing.Union[str, NotGivenType] = NOT_GIVEN, - return_url: typing.Union[str, NotGivenType] = NOT_GIVEN, - customer_id: typing.Union[str, NotGivenType] = NOT_GIVEN, - purpose: typing.Union[CreateCheckoutBodyPurposeInput, NotGivenType] = NOT_GIVEN, - valid_until: typing.Union[datetime.datetime, NotGivenType] = NOT_GIVEN, - redirect_url: typing.Union[str, NotGivenType] = NOT_GIVEN, + description: typing.Union[str, None, NotGivenType] = NOT_GIVEN, + return_url: typing.Union[str, None, NotGivenType] = NOT_GIVEN, + customer_id: typing.Union[str, None, NotGivenType] = NOT_GIVEN, + purpose: typing.Union[CreateCheckoutBodyPurposeInput, None, NotGivenType] = NOT_GIVEN, + valid_until: typing.Union[datetime.datetime, None, NotGivenType] = NOT_GIVEN, + redirect_url: typing.Union[str, None, NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> Checkout: """ @@ -806,14 +769,14 @@ async def process( id: str, *, payment_type: ProcessCheckoutBodyPaymentTypeInput, - installments: typing.Union[int, NotGivenType] = NOT_GIVEN, - mandate: typing.Union[MandatePayloadInput, NotGivenType] = NOT_GIVEN, - card: typing.Union[CardInput, NotGivenType] = NOT_GIVEN, - google_pay: typing.Union[ProcessCheckoutBodyGooglePayInput, NotGivenType] = NOT_GIVEN, - apple_pay: typing.Union[ProcessCheckoutBodyApplePayInput, NotGivenType] = NOT_GIVEN, - token: typing.Union[str, NotGivenType] = NOT_GIVEN, - customer_id: typing.Union[str, NotGivenType] = NOT_GIVEN, - personal_details: typing.Union[PersonalDetailsInput, NotGivenType] = NOT_GIVEN, + installments: typing.Union[int, None, NotGivenType] = NOT_GIVEN, + mandate: typing.Union[MandatePayloadInput, None, NotGivenType] = NOT_GIVEN, + card: typing.Union[CardInput, None, NotGivenType] = NOT_GIVEN, + google_pay: typing.Union[ProcessCheckoutBodyGooglePayInput, None, NotGivenType] = NOT_GIVEN, + apple_pay: typing.Union[ProcessCheckoutBodyApplePayInput, None, NotGivenType] = NOT_GIVEN, + token: typing.Union[str, None, NotGivenType] = NOT_GIVEN, + customer_id: typing.Union[str, None, NotGivenType] = NOT_GIVEN, + personal_details: typing.Union[PersonalDetailsInput, None, NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> ProcessCheckoutResponse: """ diff --git a/sumup/customers/resource.py b/sumup/customers/resource.py index 39a0828a..c3db2553 100755 --- a/sumup/customers/resource.py +++ b/sumup/customers/resource.py @@ -31,18 +31,7 @@ PersonalDetails, Problem, ) -from ..types import ( - AddressLegacyInput, - CardTypeInput, - CustomerInput, - ErrorInput, - ErrorExtendedInput, - ErrorForbiddenInput, - MandateResponseInput, - PaymentInstrumentResponseInput, - PersonalDetailsInput, - ProblemInput, -) +from ..types import AddressLegacyInput, CustomerInput, PersonalDetailsInput import datetime import httpx import typing @@ -78,7 +67,6 @@ class UpdateCustomerBodyInput(typing_extensions.TypedDict, total=False): ListPaymentInstruments200Response = list[PaymentInstrumentResponse] -ListPaymentInstruments200ResponseInput = typing.Sequence[PaymentInstrumentResponseInput] """ ListPaymentInstruments200Response is a schema definition. """ @@ -94,7 +82,7 @@ def create( self, *, customer_id: str, - personal_details: typing.Union[PersonalDetailsInput, NotGivenType] = NOT_GIVEN, + personal_details: typing.Union[PersonalDetailsInput, None, NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> Customer: """ @@ -168,7 +156,7 @@ def update( self, customer_id: str, *, - personal_details: typing.Union[PersonalDetailsInput, NotGivenType] = NOT_GIVEN, + personal_details: typing.Union[PersonalDetailsInput, None, NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> Customer: """ @@ -283,7 +271,7 @@ async def create( self, *, customer_id: str, - personal_details: typing.Union[PersonalDetailsInput, NotGivenType] = NOT_GIVEN, + personal_details: typing.Union[PersonalDetailsInput, None, NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> Customer: """ @@ -357,7 +345,7 @@ async def update( self, customer_id: str, *, - personal_details: typing.Union[PersonalDetailsInput, NotGivenType] = NOT_GIVEN, + personal_details: typing.Union[PersonalDetailsInput, None, NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> Customer: """ diff --git a/sumup/members/resource.py b/sumup/members/resource.py index b3ae8a23..97a5fd7a 100755 --- a/sumup/members/resource.py +++ b/sumup/members/resource.py @@ -26,16 +26,7 @@ Metadata, Problem, ) -from ..types import ( - AttributesInput, - InviteInput, - MemberInput, - MembershipStatusInput, - MembershipUserInput, - MembershipUserClassicInput, - MetadataInput, - ProblemInput, -) +from ..types import AttributesInput, MembershipStatusInput, MetadataInput import datetime import httpx import typing @@ -161,14 +152,6 @@ class ListMerchantMembers200Response(pydantic.BaseModel): total_count: typing.Optional[int] = None -class ListMerchantMembers200ResponseDict(typing_extensions.TypedDict, total=False): - items: typing_extensions.Required[typing.Sequence[MemberInput]] - total_count: typing_extensions.NotRequired[int] - - -ListMerchantMembers200ResponseInput = ListMerchantMembers200ResponseDict - - class MembersResource(Resource): """API resource for the Members endpoints.""" @@ -225,13 +208,13 @@ def create( self, merchant_code: str, *, - is_managed_user: typing.Union[bool, NotGivenType] = NOT_GIVEN, + is_managed_user: typing.Union[bool, None, NotGivenType] = NOT_GIVEN, email: str, - password: typing.Union[Secret, NotGivenType] = NOT_GIVEN, - nickname: typing.Union[str, NotGivenType] = NOT_GIVEN, + password: typing.Union[Secret, None, NotGivenType] = NOT_GIVEN, + nickname: typing.Union[str, None, NotGivenType] = NOT_GIVEN, roles: typing.Sequence[str], - metadata: typing.Union[MetadataInput, NotGivenType] = NOT_GIVEN, - attributes: typing.Union[AttributesInput, NotGivenType] = NOT_GIVEN, + metadata: typing.Union[MetadataInput, None, NotGivenType] = NOT_GIVEN, + attributes: typing.Union[AttributesInput, None, NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> Member: """ @@ -297,10 +280,10 @@ def update( merchant_code: str, member_id: str, *, - roles: typing.Union[typing.Sequence[str], NotGivenType] = NOT_GIVEN, - metadata: typing.Union[MetadataInput, NotGivenType] = NOT_GIVEN, - attributes: typing.Union[AttributesInput, NotGivenType] = NOT_GIVEN, - user: typing.Union[UpdateMerchantMemberBodyUserInput, NotGivenType] = NOT_GIVEN, + roles: typing.Union[typing.Sequence[str], None, NotGivenType] = NOT_GIVEN, + metadata: typing.Union[MetadataInput, None, NotGivenType] = NOT_GIVEN, + attributes: typing.Union[AttributesInput, None, NotGivenType] = NOT_GIVEN, + user: typing.Union[UpdateMerchantMemberBodyUserInput, None, NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> Member: """ @@ -310,7 +293,7 @@ def update( """ body_data: dict[str, typing.Any] = {} if not isinstance(roles, NotGivenType): - body_data["roles"] = list(roles) + body_data["roles"] = list(roles) if roles is not None else None if not isinstance(metadata, NotGivenType): body_data["metadata"] = metadata if not isinstance(attributes, NotGivenType): @@ -424,13 +407,13 @@ async def create( self, merchant_code: str, *, - is_managed_user: typing.Union[bool, NotGivenType] = NOT_GIVEN, + is_managed_user: typing.Union[bool, None, NotGivenType] = NOT_GIVEN, email: str, - password: typing.Union[Secret, NotGivenType] = NOT_GIVEN, - nickname: typing.Union[str, NotGivenType] = NOT_GIVEN, + password: typing.Union[Secret, None, NotGivenType] = NOT_GIVEN, + nickname: typing.Union[str, None, NotGivenType] = NOT_GIVEN, roles: typing.Sequence[str], - metadata: typing.Union[MetadataInput, NotGivenType] = NOT_GIVEN, - attributes: typing.Union[AttributesInput, NotGivenType] = NOT_GIVEN, + metadata: typing.Union[MetadataInput, None, NotGivenType] = NOT_GIVEN, + attributes: typing.Union[AttributesInput, None, NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> Member: """ @@ -496,10 +479,10 @@ async def update( merchant_code: str, member_id: str, *, - roles: typing.Union[typing.Sequence[str], NotGivenType] = NOT_GIVEN, - metadata: typing.Union[MetadataInput, NotGivenType] = NOT_GIVEN, - attributes: typing.Union[AttributesInput, NotGivenType] = NOT_GIVEN, - user: typing.Union[UpdateMerchantMemberBodyUserInput, NotGivenType] = NOT_GIVEN, + roles: typing.Union[typing.Sequence[str], None, NotGivenType] = NOT_GIVEN, + metadata: typing.Union[MetadataInput, None, NotGivenType] = NOT_GIVEN, + attributes: typing.Union[AttributesInput, None, NotGivenType] = NOT_GIVEN, + user: typing.Union[UpdateMerchantMemberBodyUserInput, None, NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> Member: """ @@ -509,7 +492,7 @@ async def update( """ body_data: dict[str, typing.Any] = {} if not isinstance(roles, NotGivenType): - body_data["roles"] = list(roles) + body_data["roles"] = list(roles) if roles is not None else None if not isinstance(metadata, NotGivenType): body_data["metadata"] = metadata if not isinstance(attributes, NotGivenType): diff --git a/sumup/memberships/resource.py b/sumup/memberships/resource.py index 22834a75..c2f40a7b 100755 --- a/sumup/memberships/resource.py +++ b/sumup/memberships/resource.py @@ -25,16 +25,7 @@ Problem, ResourceType, ) -from ..types import ( - AttributesInput, - InviteInput, - MembershipInput, - MembershipResourceInput, - MembershipStatusInput, - MetadataInput, - ProblemInput, - ResourceTypeInput, -) +from ..types import MembershipStatusInput, ResourceTypeInput import datetime import httpx import typing @@ -60,14 +51,6 @@ class ListMemberships200Response(pydantic.BaseModel): total_count: int -class ListMemberships200ResponseDict(typing_extensions.TypedDict, total=False): - items: typing_extensions.Required[typing.Sequence[MembershipInput]] - total_count: typing_extensions.Required[int] - - -ListMemberships200ResponseInput = ListMemberships200ResponseDict - - class MembershipsResource(Resource): """API resource for the Memberships endpoints.""" diff --git a/sumup/merchants/resource.py b/sumup/merchants/resource.py index b272e672..f6da43a9 100755 --- a/sumup/merchants/resource.py +++ b/sumup/merchants/resource.py @@ -39,30 +39,6 @@ Timestamps, Version, ) -from ..types import ( - AddressInput, - AttributesInput, - BasePersonInput, - BrandingInput, - BusinessProfileInput, - ChangeStatusInput, - ClassicMerchantIdentifiersInput, - CompanyInput, - CompanyIdentifierInput, - CompanyIdentifiersInput, - CountryCodeInput, - LegalTypeInput, - ListPersonsResponseBodyInput, - MerchantInput, - MetaInput, - OwnershipInput, - PersonInput, - PersonalIdentifierInput, - PhoneNumberInput, - ProblemInput, - TimestampsInput, - VersionInput, -) import datetime import httpx import typing diff --git a/sumup/payouts/__init__.py b/sumup/payouts/__init__.py index 38b1cf5c..246a8308 100755 --- a/sumup/payouts/__init__.py +++ b/sumup/payouts/__init__.py @@ -2,10 +2,6 @@ from .resource import ( PayoutsResource, AsyncPayoutsResource, - ListPayoutsV1ParamsFormat, - ListPayoutsV1ParamsOrder, - ListPayoutsParamsFormat, - ListPayoutsParamsOrder, ) from ..types import ( Error, @@ -18,10 +14,6 @@ __all__ = [ "PayoutsResource", "AsyncPayoutsResource", - "ListPayoutsV1ParamsFormat", - "ListPayoutsV1ParamsOrder", - "ListPayoutsParamsFormat", - "ListPayoutsParamsOrder", "Error", "ErrorExtended", "FinancialPayouts", diff --git a/sumup/payouts/resource.py b/sumup/payouts/resource.py index 95d590db..8e033d7b 100755 --- a/sumup/payouts/resource.py +++ b/sumup/payouts/resource.py @@ -18,24 +18,19 @@ ) from .._exceptions import APIError from ..types import Error, ErrorExtended, FinancialPayouts, Problem -from ..types import ErrorInput, ErrorExtendedInput, FinancialPayoutsInput, ProblemInput import datetime import httpx import typing import pydantic import typing_extensions -ListPayoutsV1ParamsFormat = typing.Union[typing.Literal["csv", "json"], str] -ListPayoutsV1ParamsFormatInput = ListPayoutsV1ParamsFormat +ListPayoutsV1ParamsFormatInput = typing.Union[typing.Literal["csv", "json"], str] -ListPayoutsV1ParamsOrder = typing.Union[typing.Literal["asc", "desc"], str] -ListPayoutsV1ParamsOrderInput = ListPayoutsV1ParamsOrder +ListPayoutsV1ParamsOrderInput = typing.Union[typing.Literal["asc", "desc"], str] -ListPayoutsParamsFormat = typing.Union[typing.Literal["csv", "json"], str] -ListPayoutsParamsFormatInput = ListPayoutsParamsFormat +ListPayoutsParamsFormatInput = typing.Union[typing.Literal["csv", "json"], str] -ListPayoutsParamsOrder = typing.Union[typing.Literal["asc", "desc"], str] -ListPayoutsParamsOrderInput = ListPayoutsParamsOrder +ListPayoutsParamsOrderInput = typing.Union[typing.Literal["asc", "desc"], str] class PayoutsResource(Resource): diff --git a/sumup/readers/__init__.py b/sumup/readers/__init__.py index 349b43f0..cdf0234b 100755 --- a/sumup/readers/__init__.py +++ b/sumup/readers/__init__.py @@ -2,7 +2,6 @@ from .resource import ( ReadersResource, AsyncReadersResource, - CreateReaderCheckoutBodyCardType, ListReaders200Response, ) from ..types import ( @@ -30,7 +29,6 @@ __all__ = [ "ReadersResource", "AsyncReadersResource", - "CreateReaderCheckoutBodyCardType", "ListReaders200Response", "BadRequest", "CreateReaderCheckoutError", diff --git a/sumup/readers/resource.py b/sumup/readers/resource.py index dd8df521..caec0174 100755 --- a/sumup/readers/resource.py +++ b/sumup/readers/resource.py @@ -36,24 +36,11 @@ Unauthorized, ) from ..types import ( - BadRequestInput, - CreateReaderCheckoutErrorInput, CreateReaderCheckoutRequestInput, - CreateReaderCheckoutResponseInput, - CreateReaderCheckoutUnprocessableEntityInput, - CreateReaderTerminateErrorInput, - CreateReaderTerminateUnprocessableEntityInput, MetadataInput, - NotFoundInput, - ProblemInput, - ReaderInput, - ReaderDeviceInput, ReaderIdInput, ReaderNameInput, ReaderPairingCodeInput, - ReaderStatusInput, - StatusResponseInput, - UnauthorizedInput, ) import datetime import httpx @@ -186,8 +173,7 @@ class CreateReaderCheckoutBodyAffiliateInput(typing_extensions.TypedDict, total= ] -CreateReaderCheckoutBodyCardType = typing.Union[typing.Literal["credit", "debit"], str] -CreateReaderCheckoutBodyCardTypeInput = CreateReaderCheckoutBodyCardType +CreateReaderCheckoutBodyCardTypeInput = typing.Union[typing.Literal["credit", "debit"], str] class CreateReaderCheckoutBodyTotalAmountInput(typing_extensions.TypedDict, total=False): @@ -302,13 +288,6 @@ class ListReaders200Response(pydantic.BaseModel): items: list[Reader] -class ListReaders200ResponseDict(typing_extensions.TypedDict, total=False): - items: typing_extensions.Required[typing.Sequence[ReaderInput]] - - -ListReaders200ResponseInput = ListReaders200ResponseDict - - class ReadersResource(Resource): """API resource for the Readers endpoints.""" @@ -344,7 +323,7 @@ def create( *, pairing_code: ReaderPairingCodeInput, name: ReaderNameInput, - metadata: typing.Union[MetadataInput, NotGivenType] = NOT_GIVEN, + metadata: typing.Union[MetadataInput, None, NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> Reader: """ @@ -431,8 +410,8 @@ def update( merchant_code: str, id: ReaderId, *, - name: typing.Union[ReaderNameInput, NotGivenType] = NOT_GIVEN, - metadata: typing.Union[MetadataInput, NotGivenType] = NOT_GIVEN, + name: typing.Union[ReaderNameInput, None, NotGivenType] = NOT_GIVEN, + metadata: typing.Union[MetadataInput, None, NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> Reader: """ @@ -473,14 +452,18 @@ def create_checkout( merchant_code: str, reader_id: str, *, - aade: typing.Union[CreateReaderCheckoutBodyAadeInput, NotGivenType] = NOT_GIVEN, - affiliate: typing.Union[CreateReaderCheckoutBodyAffiliateInput, NotGivenType] = NOT_GIVEN, - card_type: typing.Union[CreateReaderCheckoutBodyCardTypeInput, NotGivenType] = NOT_GIVEN, - description: typing.Union[str, NotGivenType] = NOT_GIVEN, - installments: typing.Union[int, NotGivenType] = NOT_GIVEN, - return_url: typing.Union[str, NotGivenType] = NOT_GIVEN, - tip_rates: typing.Union[typing.Sequence[float], NotGivenType] = NOT_GIVEN, - tip_timeout: typing.Union[int, NotGivenType] = NOT_GIVEN, + aade: typing.Union[CreateReaderCheckoutBodyAadeInput, None, NotGivenType] = NOT_GIVEN, + affiliate: typing.Union[ + CreateReaderCheckoutBodyAffiliateInput, None, NotGivenType + ] = NOT_GIVEN, + card_type: typing.Union[ + CreateReaderCheckoutBodyCardTypeInput, None, NotGivenType + ] = NOT_GIVEN, + description: typing.Union[str, None, NotGivenType] = NOT_GIVEN, + installments: typing.Union[int, None, NotGivenType] = NOT_GIVEN, + return_url: typing.Union[str, None, NotGivenType] = NOT_GIVEN, + tip_rates: typing.Union[typing.Sequence[float], None, NotGivenType] = NOT_GIVEN, + tip_timeout: typing.Union[int, None, NotGivenType] = NOT_GIVEN, total_amount: CreateReaderCheckoutBodyTotalAmountInput, headers: typing.Optional[HeaderTypes] = None, ) -> CreateReaderCheckoutResponse: @@ -513,7 +496,7 @@ def create_checkout( if not isinstance(return_url, NotGivenType): body_data["return_url"] = return_url if not isinstance(tip_rates, NotGivenType): - body_data["tip_rates"] = list(tip_rates) + body_data["tip_rates"] = list(tip_rates) if tip_rates is not None else None if not isinstance(tip_timeout, NotGivenType): body_data["tip_timeout"] = tip_timeout body_data["total_amount"] = total_amount @@ -681,7 +664,7 @@ async def create( *, pairing_code: ReaderPairingCodeInput, name: ReaderNameInput, - metadata: typing.Union[MetadataInput, NotGivenType] = NOT_GIVEN, + metadata: typing.Union[MetadataInput, None, NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> Reader: """ @@ -768,8 +751,8 @@ async def update( merchant_code: str, id: ReaderId, *, - name: typing.Union[ReaderNameInput, NotGivenType] = NOT_GIVEN, - metadata: typing.Union[MetadataInput, NotGivenType] = NOT_GIVEN, + name: typing.Union[ReaderNameInput, None, NotGivenType] = NOT_GIVEN, + metadata: typing.Union[MetadataInput, None, NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> Reader: """ @@ -810,14 +793,18 @@ async def create_checkout( merchant_code: str, reader_id: str, *, - aade: typing.Union[CreateReaderCheckoutBodyAadeInput, NotGivenType] = NOT_GIVEN, - affiliate: typing.Union[CreateReaderCheckoutBodyAffiliateInput, NotGivenType] = NOT_GIVEN, - card_type: typing.Union[CreateReaderCheckoutBodyCardTypeInput, NotGivenType] = NOT_GIVEN, - description: typing.Union[str, NotGivenType] = NOT_GIVEN, - installments: typing.Union[int, NotGivenType] = NOT_GIVEN, - return_url: typing.Union[str, NotGivenType] = NOT_GIVEN, - tip_rates: typing.Union[typing.Sequence[float], NotGivenType] = NOT_GIVEN, - tip_timeout: typing.Union[int, NotGivenType] = NOT_GIVEN, + aade: typing.Union[CreateReaderCheckoutBodyAadeInput, None, NotGivenType] = NOT_GIVEN, + affiliate: typing.Union[ + CreateReaderCheckoutBodyAffiliateInput, None, NotGivenType + ] = NOT_GIVEN, + card_type: typing.Union[ + CreateReaderCheckoutBodyCardTypeInput, None, NotGivenType + ] = NOT_GIVEN, + description: typing.Union[str, None, NotGivenType] = NOT_GIVEN, + installments: typing.Union[int, None, NotGivenType] = NOT_GIVEN, + return_url: typing.Union[str, None, NotGivenType] = NOT_GIVEN, + tip_rates: typing.Union[typing.Sequence[float], None, NotGivenType] = NOT_GIVEN, + tip_timeout: typing.Union[int, None, NotGivenType] = NOT_GIVEN, total_amount: CreateReaderCheckoutBodyTotalAmountInput, headers: typing.Optional[HeaderTypes] = None, ) -> CreateReaderCheckoutResponse: @@ -850,7 +837,7 @@ async def create_checkout( if not isinstance(return_url, NotGivenType): body_data["return_url"] = return_url if not isinstance(tip_rates, NotGivenType): - body_data["tip_rates"] = list(tip_rates) + body_data["tip_rates"] = list(tip_rates) if tip_rates is not None else None if not isinstance(tip_timeout, NotGivenType): body_data["tip_timeout"] = tip_timeout body_data["total_amount"] = total_amount diff --git a/sumup/receipts/resource.py b/sumup/receipts/resource.py index 659e57c6..ada863d4 100755 --- a/sumup/receipts/resource.py +++ b/sumup/receipts/resource.py @@ -29,20 +29,6 @@ ReceiptTransaction, TransactionId, ) -from ..types import ( - ErrorInput, - EventIdInput, - EventStatusInput, - EventTypeInput, - ProblemInput, - ReceiptInput, - ReceiptCardInput, - ReceiptEventInput, - ReceiptMerchantDataInput, - ReceiptReaderInput, - ReceiptTransactionInput, - TransactionIdInput, -) import datetime import httpx import typing diff --git a/sumup/roles/resource.py b/sumup/roles/resource.py index 379b1495..82a973c3 100755 --- a/sumup/roles/resource.py +++ b/sumup/roles/resource.py @@ -16,7 +16,7 @@ ) from .._exceptions import APIError from ..types import Metadata, Problem, Role -from ..types import MetadataInput, ProblemInput, RoleInput +from ..types import MetadataInput import datetime import httpx import typing @@ -80,13 +80,6 @@ class ListMerchantRoles200Response(pydantic.BaseModel): items: list[Role] -class ListMerchantRoles200ResponseDict(typing_extensions.TypedDict, total=False): - items: typing_extensions.Required[typing.Sequence[RoleInput]] - - -ListMerchantRoles200ResponseInput = ListMerchantRoles200ResponseDict - - class RolesResource(Resource): """API resource for the Roles endpoints.""" @@ -118,8 +111,8 @@ def create( *, name: str, permissions: typing.Sequence[str], - metadata: typing.Union[MetadataInput, NotGivenType] = NOT_GIVEN, - description: typing.Union[str, NotGivenType] = NOT_GIVEN, + metadata: typing.Union[MetadataInput, None, NotGivenType] = NOT_GIVEN, + description: typing.Union[str, None, NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> Role: """ @@ -194,9 +187,9 @@ def update( merchant_code: str, role_id: str, *, - name: typing.Union[str, NotGivenType] = NOT_GIVEN, - permissions: typing.Union[typing.Sequence[str], NotGivenType] = NOT_GIVEN, - description: typing.Union[str, NotGivenType] = NOT_GIVEN, + name: typing.Union[str, None, NotGivenType] = NOT_GIVEN, + permissions: typing.Union[typing.Sequence[str], None, NotGivenType] = NOT_GIVEN, + description: typing.Union[str, None, NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> Role: """ @@ -208,7 +201,7 @@ def update( if not isinstance(name, NotGivenType): body_data["name"] = name if not isinstance(permissions, NotGivenType): - body_data["permissions"] = list(permissions) + body_data["permissions"] = list(permissions) if permissions is not None else None if not isinstance(description, NotGivenType): body_data["description"] = description @@ -258,8 +251,8 @@ async def create( *, name: str, permissions: typing.Sequence[str], - metadata: typing.Union[MetadataInput, NotGivenType] = NOT_GIVEN, - description: typing.Union[str, NotGivenType] = NOT_GIVEN, + metadata: typing.Union[MetadataInput, None, NotGivenType] = NOT_GIVEN, + description: typing.Union[str, None, NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> Role: """ @@ -334,9 +327,9 @@ async def update( merchant_code: str, role_id: str, *, - name: typing.Union[str, NotGivenType] = NOT_GIVEN, - permissions: typing.Union[typing.Sequence[str], NotGivenType] = NOT_GIVEN, - description: typing.Union[str, NotGivenType] = NOT_GIVEN, + name: typing.Union[str, None, NotGivenType] = NOT_GIVEN, + permissions: typing.Union[typing.Sequence[str], None, NotGivenType] = NOT_GIVEN, + description: typing.Union[str, None, NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> Role: """ @@ -348,7 +341,7 @@ async def update( if not isinstance(name, NotGivenType): body_data["name"] = name if not isinstance(permissions, NotGivenType): - body_data["permissions"] = list(permissions) + body_data["permissions"] = list(permissions) if permissions is not None else None if not isinstance(description, NotGivenType): body_data["description"] = description diff --git a/sumup/subaccounts/resource.py b/sumup/subaccounts/resource.py index 7602f24c..aaebe24b 100755 --- a/sumup/subaccounts/resource.py +++ b/sumup/subaccounts/resource.py @@ -16,7 +16,6 @@ ) from .._exceptions import APIError from ..types import Operator, Permissions, Problem -from ..types import OperatorInput, PermissionsInput, ProblemInput import datetime import httpx import typing @@ -78,7 +77,6 @@ class UpdateSubAccountBodyInput(typing_extensions.TypedDict, total=False): ListSubAccounts200Response = list[Operator] -ListSubAccounts200ResponseInput = typing.Sequence[OperatorInput] """ ListSubAccounts200Response is a schema definition. """ @@ -135,8 +133,10 @@ def create_sub_account( *, username: str, password: str, - nickname: typing.Union[str, NotGivenType] = NOT_GIVEN, - permissions: typing.Union[CreateSubAccountBodyPermissionsInput, NotGivenType] = NOT_GIVEN, + nickname: typing.Union[str, None, NotGivenType] = NOT_GIVEN, + permissions: typing.Union[ + CreateSubAccountBodyPermissionsInput, None, NotGivenType + ] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> Operator: """ @@ -199,11 +199,13 @@ def update_sub_account( self, operator_id: int, *, - password: typing.Union[str, NotGivenType] = NOT_GIVEN, - username: typing.Union[str, NotGivenType] = NOT_GIVEN, - disabled: typing.Union[bool, NotGivenType] = NOT_GIVEN, - nickname: typing.Union[str, NotGivenType] = NOT_GIVEN, - permissions: typing.Union[UpdateSubAccountBodyPermissionsInput, NotGivenType] = NOT_GIVEN, + password: typing.Union[str, None, NotGivenType] = NOT_GIVEN, + username: typing.Union[str, None, NotGivenType] = NOT_GIVEN, + disabled: typing.Union[bool, None, NotGivenType] = NOT_GIVEN, + nickname: typing.Union[str, None, NotGivenType] = NOT_GIVEN, + permissions: typing.Union[ + UpdateSubAccountBodyPermissionsInput, None, NotGivenType + ] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> Operator: """ @@ -291,8 +293,10 @@ async def create_sub_account( *, username: str, password: str, - nickname: typing.Union[str, NotGivenType] = NOT_GIVEN, - permissions: typing.Union[CreateSubAccountBodyPermissionsInput, NotGivenType] = NOT_GIVEN, + nickname: typing.Union[str, None, NotGivenType] = NOT_GIVEN, + permissions: typing.Union[ + CreateSubAccountBodyPermissionsInput, None, NotGivenType + ] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> Operator: """ @@ -355,11 +359,13 @@ async def update_sub_account( self, operator_id: int, *, - password: typing.Union[str, NotGivenType] = NOT_GIVEN, - username: typing.Union[str, NotGivenType] = NOT_GIVEN, - disabled: typing.Union[bool, NotGivenType] = NOT_GIVEN, - nickname: typing.Union[str, NotGivenType] = NOT_GIVEN, - permissions: typing.Union[UpdateSubAccountBodyPermissionsInput, NotGivenType] = NOT_GIVEN, + password: typing.Union[str, None, NotGivenType] = NOT_GIVEN, + username: typing.Union[str, None, NotGivenType] = NOT_GIVEN, + disabled: typing.Union[bool, None, NotGivenType] = NOT_GIVEN, + nickname: typing.Union[str, None, NotGivenType] = NOT_GIVEN, + permissions: typing.Union[ + UpdateSubAccountBodyPermissionsInput, None, NotGivenType + ] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ) -> Operator: """ diff --git a/sumup/transactions/__init__.py b/sumup/transactions/__init__.py index c9d73b07..d298256e 100755 --- a/sumup/transactions/__init__.py +++ b/sumup/transactions/__init__.py @@ -2,12 +2,6 @@ from .resource import ( TransactionsResource, AsyncTransactionsResource, - ListTransactionsV21ParamsOrder, - ListTransactionsV21ParamsStatuse, - ListTransactionsV21ParamsType, - ListTransactionsParamsOrder, - ListTransactionsParamsStatuse, - ListTransactionsParamsType, ListTransactionsV21200Response, ListTransactions200Response, ) @@ -44,12 +38,6 @@ __all__ = [ "TransactionsResource", "AsyncTransactionsResource", - "ListTransactionsV21ParamsOrder", - "ListTransactionsV21ParamsStatuse", - "ListTransactionsV21ParamsType", - "ListTransactionsParamsOrder", - "ListTransactionsParamsStatuse", - "ListTransactionsParamsType", "ListTransactionsV21200Response", "ListTransactions200Response", "CardResponse", diff --git a/sumup/transactions/resource.py b/sumup/transactions/resource.py index 2502136b..6b80c436 100755 --- a/sumup/transactions/resource.py +++ b/sumup/transactions/resource.py @@ -60,34 +60,7 @@ TransactionMixinHistory, TransactionsHistoryLink, ) -from ..types import ( - CardResponseInput, - CardTypeInput, - CurrencyInput, - DeviceInput, - ElvCardAccountInput, - EntryModeInput, - ErrorInput, - EventInput, - EventIdInput, - EventStatusInput, - EventTypeInput, - HorizontalAccuracyInput, - LatInput, - LinkInput, - LonInput, - PaymentTypeInput, - ProblemInput, - ProductInput, - TransactionBaseInput, - TransactionCheckoutInfoInput, - TransactionEventInput, - TransactionFullInput, - TransactionHistoryInput, - TransactionIdInput, - TransactionMixinHistoryInput, - TransactionsHistoryLinkInput, -) +from ..types import EntryModeInput, PaymentTypeInput import datetime import httpx import typing @@ -110,29 +83,25 @@ class RefundTransactionBodyInput(typing_extensions.TypedDict, total=False): ] -ListTransactionsV21ParamsOrder = typing.Union[typing.Literal["ascending", "descending"], str] -ListTransactionsV21ParamsOrderInput = ListTransactionsV21ParamsOrder +ListTransactionsV21ParamsOrderInput = typing.Union[typing.Literal["ascending", "descending"], str] -ListTransactionsV21ParamsStatuse = typing.Union[ +ListTransactionsV21ParamsStatuseInput = typing.Union[ typing.Literal["CANCELLED", "CHARGE_BACK", "FAILED", "REFUNDED", "SUCCESSFUL"], str ] -ListTransactionsV21ParamsStatuseInput = ListTransactionsV21ParamsStatuse -ListTransactionsV21ParamsType = typing.Union[ +ListTransactionsV21ParamsTypeInput = typing.Union[ typing.Literal["CHARGE_BACK", "PAYMENT", "REFUND"], str ] -ListTransactionsV21ParamsTypeInput = ListTransactionsV21ParamsType -ListTransactionsParamsOrder = typing.Union[typing.Literal["ascending", "descending"], str] -ListTransactionsParamsOrderInput = ListTransactionsParamsOrder +ListTransactionsParamsOrderInput = typing.Union[typing.Literal["ascending", "descending"], str] -ListTransactionsParamsStatuse = typing.Union[ +ListTransactionsParamsStatuseInput = typing.Union[ typing.Literal["CANCELLED", "CHARGE_BACK", "FAILED", "REFUNDED", "SUCCESSFUL"], str ] -ListTransactionsParamsStatuseInput = ListTransactionsParamsStatuse -ListTransactionsParamsType = typing.Union[typing.Literal["CHARGE_BACK", "PAYMENT", "REFUND"], str] -ListTransactionsParamsTypeInput = ListTransactionsParamsType +ListTransactionsParamsTypeInput = typing.Union[ + typing.Literal["CHARGE_BACK", "PAYMENT", "REFUND"], str +] class ListTransactionsV21200Response(pydantic.BaseModel): @@ -145,14 +114,6 @@ class ListTransactionsV21200Response(pydantic.BaseModel): links: typing.Optional[list[TransactionsHistoryLink]] = None -class ListTransactionsV21200ResponseDict(typing_extensions.TypedDict, total=False): - items: typing_extensions.NotRequired[typing.Sequence[TransactionHistoryInput]] - links: typing_extensions.NotRequired[typing.Sequence[TransactionsHistoryLinkInput]] - - -ListTransactionsV21200ResponseInput = ListTransactionsV21200ResponseDict - - class ListTransactions200Response(pydantic.BaseModel): """ ListTransactions200Response is a schema definition. @@ -163,14 +124,6 @@ class ListTransactions200Response(pydantic.BaseModel): links: typing.Optional[list[TransactionsHistoryLink]] = None -class ListTransactions200ResponseDict(typing_extensions.TypedDict, total=False): - items: typing_extensions.NotRequired[typing.Sequence[TransactionHistoryInput]] - links: typing_extensions.NotRequired[typing.Sequence[TransactionsHistoryLinkInput]] - - -ListTransactions200ResponseInput = ListTransactions200ResponseDict - - class TransactionsResource(Resource): """API resource for the Transactions endpoints.""" @@ -181,7 +134,7 @@ def refund( self, txn_id: str, *, - amount: typing.Union[float, NotGivenType] = NOT_GIVEN, + amount: typing.Union[float, None, NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ): """ @@ -467,7 +420,7 @@ async def refund( self, txn_id: str, *, - amount: typing.Union[float, NotGivenType] = NOT_GIVEN, + amount: typing.Union[float, None, NotGivenType] = NOT_GIVEN, headers: typing.Optional[HeaderTypes] = None, ): """ diff --git a/sumup/types/__init__.py b/sumup/types/__init__.py index 29d25f3e..f0ecac7f 100755 --- a/sumup/types/__init__.py +++ b/sumup/types/__init__.py @@ -6,7 +6,6 @@ import typing_extensions CountryCode = str -CountryCodeInput = str """ An [ISO3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code. This definition users `oneOf` with a two-character string @@ -130,137 +129,6 @@ class Address(pydantic.BaseModel): """ -class AddressDict(typing_extensions.TypedDict, total=False): - country: typing_extensions.Required[ - typing_extensions.Annotated[ - CountryCodeInput, - typing_extensions.Doc( - "An [ISO3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2)\ncountry code. This definition users `oneOf` with a two-character string\ntype to allow for support of future countries in client code.\nMin length: 2\nMax length: 2\nPattern: ^[A-Z]{2}$" - ), - ] - ] - autonomous_community: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "In Spain, an autonomous community is the first sub-national level of political and administrative division.\nMax length: 512" - ), - ] - ] - city: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, typing_extensions.Doc("The city of the address.\nMax length: 512") - ] - ] - commune: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - 'In many countries, terms cognate with "commune" are used, referring to the community living in the area andthe common interest. Used in countries such as Chile.\nMax length: 512' - ), - ] - ] - county: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "A county is a geographic region of a country used for administrative or other purposes in some nations. Usedin countries such as Ireland, Romania, etc.\nMax length: 512" - ), - ] - ] - department: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "A department (French: département, Spanish: departamento) is an administrative or political division inseveral countries. Used in countries such as Colombia.\nMax length: 512" - ), - ] - ] - district: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "A district is a type of administrative division that in some countries is managed by the local government. Usedin countries such as Portugal.\nMax length: 512" - ), - ] - ] - eircode: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, typing_extensions.Doc("A postal address in Ireland.\nMax length: 512") - ] - ] - municipality: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "A municipality is usually a single administrative division having corporate status and powers of self-government orjurisdiction as granted by national and regional laws to which it is subordinate. Used in countries such asColombia.\nMax length: 512" - ), - ] - ] - neighborhood: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "Locality level of the address. Used in countries such as Brazil or Chile.\nMax length: 512" - ), - ] - ] - post_code: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "The postal code (aka. zip code) of the address.\nMax length: 32" - ), - ] - ] - post_town: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "A post town is a required part of all postal addresses in the United Kingdom and Ireland, and a basic unitof the postal delivery system.\nMax length: 512" - ), - ] - ] - province: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "The province where the address is located. This may not be relevant in some countries.\nMax length: 512" - ), - ] - ] - region: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "The region where the address is located. This may not be relevant in some countries.\nMax length: 512" - ), - ] - ] - state: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - 'Most often, a country has a single state, with various administrative divisions. The term "state" is sometimesused to refer to the federated polities that make up the federation. Used in countries such as the United Statesand Brazil.\nMax length: 512' - ), - ] - ] - street_address: typing_extensions.NotRequired[ - typing_extensions.Annotated[typing.Sequence[str], typing_extensions.Doc("Max items: 2")] - ] - zip_code: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "A US system of postal codes used by the United States Postal Service (USPS).\nMax length: 512" - ), - ] - ] - - -AddressInput = AddressDict - - class AddressLegacy(pydantic.BaseModel): """ Profile's personal address information. @@ -353,7 +221,6 @@ class AddressLegacyDict(typing_extensions.TypedDict, total=False): ], str, ] -BadRequestErrorsTypeInput = BadRequestErrorsType class BadRequestErrors(pydantic.BaseModel): @@ -372,22 +239,6 @@ class BadRequestErrors(pydantic.BaseModel): """ -class BadRequestErrorsDict(typing_extensions.TypedDict, total=False): - type: typing_extensions.Required[ - typing_extensions.Annotated[ - BadRequestErrorsTypeInput, typing_extensions.Doc("Key indicating type of error") - ] - ] - detail: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, typing_extensions.Doc("Fuller message giving context to error") - ] - ] - - -BadRequestErrorsInput = BadRequestErrorsDict - - class BadRequest(pydantic.BaseModel): """ 400 Bad Request @@ -396,15 +247,7 @@ class BadRequest(pydantic.BaseModel): errors: BadRequestErrors -class BadRequestDict(typing_extensions.TypedDict, total=False): - errors: typing_extensions.Required[BadRequestErrorsInput] - - -BadRequestInput = BadRequestDict - - ChangeStatus = str -ChangeStatusInput = str """ Reflects the status of changes submitted through the `PATCH` endpoints for the merchant or persons. If somechanges have not been applied yet, the status will be `pending`. If all changes have been applied, the status`done`. The status is only returned after write operations or on read endpoints when the `version` query parameter isprovided. @@ -427,20 +270,6 @@ class Ownership(pydantic.BaseModel): """ -class OwnershipDict(typing_extensions.TypedDict, total=False): - share: typing_extensions.Required[ - typing_extensions.Annotated[ - int, - typing_extensions.Doc( - "The percent of ownership shares held by the person expressed in percent mille (1/100000). Only persons withthe relationship `owner` can have ownership.\nFormat: int32\nMin: 25000\nMax: 100000" - ), - ] - ] - - -OwnershipInput = OwnershipDict - - class PersonalIdentifier(pydantic.BaseModel): """ PersonalIdentifier is a schema definition. @@ -459,27 +288,7 @@ class PersonalIdentifier(pydantic.BaseModel): """ -class PersonalIdentifierDict(typing_extensions.TypedDict, total=False): - ref: typing_extensions.Required[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "The unique reference for the personal identifier type.\nMax length: 32" - ), - ] - ] - value: typing_extensions.Required[ - typing_extensions.Annotated[ - str, typing_extensions.Doc("The company identifier value.\nMax length: 128") - ] - ] - - -PersonalIdentifierInput = PersonalIdentifierDict - - PhoneNumber = str -PhoneNumberInput = str """ A publicly available phone number in [E.164](https://en.wikipedia.org/wiki/E.164) format. @@ -487,7 +296,6 @@ class PersonalIdentifierDict(typing_extensions.TypedDict, total=False): """ Version = str -VersionInput = str """ The version of the resource. The version reflects a specific change submitted to the API via one of the `PATCH`endpoints. """ @@ -598,125 +406,6 @@ class BasePerson(pydantic.BaseModel): """ -class BasePersonDict(typing_extensions.TypedDict, total=False): - id: typing_extensions.Required[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "The unique identifier for the person. This is a [typeid](https://github.com/sumup/typeid).\nRead only" - ), - ] - ] - address: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - AddressInput, - typing_extensions.Doc( - "An address somewhere in the world. The address fields used depend on the country conventions. For example, inGreat Britain, `city` is `post_town`. In the United States, the top-level administrative unit used in addressesis `state`, whereas in Chile it's `region`.\nWhether an address is valid or not depends on whether the locally required fields are present. Fields not supported ina country will be ignored.\nAddress documentation: https://backstage.sumup.net/docs/default/Component/merchants/merchant/#addresses" - ), - ] - ] - birthdate: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - datetime.date, - typing_extensions.Doc( - "The date of birth of the individual, represented as an ISO 8601:2004 [ISO8601‑2004] YYYY-MM-DD format.\nFormat: date" - ), - ] - ] - change_status: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - ChangeStatusInput, - typing_extensions.Doc( - "Reflects the status of changes submitted through the `PATCH` endpoints for the merchant or persons. If somechanges have not been applied yet, the status will be `pending`. If all changes have been applied, the status`done`.\nThe status is only returned after write operations or on read endpoints when the `version` query parameter isprovided.\nRead only" - ), - ] - ] - citizenship: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - CountryCodeInput, - typing_extensions.Doc( - "An [ISO3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2)\ncountry code. This definition users `oneOf` with a two-character string\ntype to allow for support of future countries in client code.\nMin length: 2\nMax length: 2\nPattern: ^[A-Z]{2}$" - ), - ] - ] - country_of_residence: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "An [ISO3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code representing the countrywhere the person resides.\nMin length: 2\nMax length: 2" - ), - ] - ] - family_name: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, typing_extensions.Doc("The last name(s) of the individual.\nMax length: 60") - ] - ] - given_name: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, typing_extensions.Doc("The first name(s) of the individual.\nMax length: 60") - ] - ] - identifiers: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - typing.Sequence[PersonalIdentifierInput], - typing_extensions.Doc("A list of country-specific personal identifiers.\nMax items: 5"), - ] - ] - middle_name: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "Middle name(s) of the End-User. Note that in some cultures, people can have multiple middle names; all canbe present, with the names being separated by space characters. Also note that in some cultures, middle namesare not used.\nMax length: 60" - ), - ] - ] - nationality: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "The persons nationality. May be an [ISO3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) countrycode, but legacy data may not conform to this standard." - ), - ] - ] - ownership: typing_extensions.NotRequired[OwnershipInput] - phone_number: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - PhoneNumberInput, - typing_extensions.Doc( - "A publicly available phone number in [E.164](https://en.wikipedia.org/wiki/E.164) format.\nMax length: 16" - ), - ] - ] - relationships: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - typing.Sequence[str], - typing_extensions.Doc( - "A list of roles the person has in the merchant or towards SumUp. A merchant must have at least one person withthe relationship `representative`.\nMin items: 1\nMax items: 1" - ), - ] - ] - user_id: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "A corresponding identity user ID for the person, if they have a user account." - ), - ] - ] - version: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - VersionInput, - typing_extensions.Doc( - "The version of the resource. The version reflects a specific change submitted to the API via one of the `PATCH`endpoints." - ), - ] - ] - - -BasePersonInput = BasePersonDict - - class Branding(pydantic.BaseModel): """ Settings used to apply the Merchant's branding to email receipts, invoices, checkouts, and other products. @@ -766,73 +455,6 @@ class Branding(pydantic.BaseModel): """ -class BrandingDict(typing_extensions.TypedDict, total=False): - background_color: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "A hex color value representing the preferred background color of this merchant." - ), - ] - ] - hero: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "Data-URL encoded hero image for the merchant business.\nFormat: uri" - ), - ] - ] - icon: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, typing_extensions.Doc("An icon for the merchant. Must be square.\nFormat: uri") - ] - ] - logo: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "A logo for the merchant that will be used in place of the icon and without the merchant's name next to itif there's sufficient space.\nFormat: uri" - ), - ] - ] - primary_color: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "A hex color value representing the primary branding color of this merchant (your brand color)." - ), - ] - ] - primary_color_fg: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "A hex color value representing the color of the text displayed on branding color of this merchant." - ), - ] - ] - secondary_color: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "A hex color value representing the secondary branding color of this merchant (accent color used for buttons)." - ), - ] - ] - secondary_color_fg: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "A hex color value representing the color of the text displayed on secondary branding color of this merchant." - ), - ] - ] - - -BrandingInput = BrandingDict - - class BusinessProfile(pydantic.BaseModel): """ Business information about the merchant. This information will be visible to the merchant's customers. @@ -856,7 +478,7 @@ class BusinessProfile(pydantic.BaseModel): The more recognisable your descriptor is, the less risk you have of receiving disputes (e.g. chargebacks). Min length: 1 Max length: 30 - Pattern: ^[a-zA-Z0-9 \-+\'_.]{0,30}$ + Pattern: ^[a-zA-Z0-9 \\-+\\'_.]{0,30}$ """ email: typing.Optional[str] = None @@ -886,65 +508,6 @@ class BusinessProfile(pydantic.BaseModel): """ -class BusinessProfileDict(typing_extensions.TypedDict, total=False): - address: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - AddressInput, - typing_extensions.Doc( - "An address somewhere in the world. The address fields used depend on the country conventions. For example, inGreat Britain, `city` is `post_town`. In the United States, the top-level administrative unit used in addressesis `state`, whereas in Chile it's `region`.\nWhether an address is valid or not depends on whether the locally required fields are present. Fields not supported ina country will be ignored.\nAddress documentation: https://backstage.sumup.net/docs/default/Component/merchants/merchant/#addresses" - ), - ] - ] - branding: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - BrandingInput, - typing_extensions.Doc( - "Settings used to apply the Merchant's branding to email receipts, invoices, checkouts, and other products." - ), - ] - ] - dynamic_descriptor: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "The descriptor is the text that your customer sees on their bank account statement.\nThe more recognisable your descriptor is, the less risk you have of receiving disputes (e.g. chargebacks).\nMin length: 1\nMax length: 30\nPattern: ^[a-zA-Z0-9 \\-+\\'_.]{0,30}$" - ), - ] - ] - email: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, typing_extensions.Doc("A publicly available email address.\nMax length: 255") - ] - ] - name: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "The customer-facing business name.\nMin length: 1\nMax length: 150" - ), - ] - ] - phone_number: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - PhoneNumberInput, - typing_extensions.Doc( - "A publicly available phone number in [E.164](https://en.wikipedia.org/wiki/E.164) format.\nMax length: 16" - ), - ] - ] - website: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "The business's publicly available website.\nFormat: uri\nMax length: 255" - ), - ] - ] - - -BusinessProfileInput = BusinessProfileDict - - CardType = typing.Union[ typing.Literal[ "ALELO", @@ -1113,28 +676,6 @@ class CardResponse(pydantic.BaseModel): """ -class CardResponseDict(typing_extensions.TypedDict, total=False): - last_4_digits: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "Last 4 digits of the payment card number.\nRead only\nMin length: 4\nMax length: 4" - ), - ] - ] - type: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - CardTypeInput, - typing_extensions.Doc( - "Issuing card network of the payment card used for the transaction." - ), - ] - ] - - -CardResponseInput = CardResponseDict - - Currency = typing.Union[ typing.Literal[ "BGN", @@ -1193,7 +734,6 @@ class CardResponseDict(typing_extensions.TypedDict, total=False): EntryModeInput = EntryMode MandateResponseStatus = typing.Union[typing.Literal["active", "inactive"], str] -MandateResponseStatusInput = MandateResponseStatus class MandateResponse(pydantic.BaseModel): @@ -1217,29 +757,6 @@ class MandateResponse(pydantic.BaseModel): """ -class MandateResponseDict(typing_extensions.TypedDict, total=False): - merchant_code: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, typing_extensions.Doc("Merchant account for which the mandate is valid.") - ] - ] - status: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - MandateResponseStatusInput, - typing_extensions.Doc("Current lifecycle status of the mandate."), - ] - ] - type: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc("Type of mandate stored for the checkout or payment instrument."), - ] - ] - - -MandateResponseInput = MandateResponseDict - - PaymentType = typing.Union[ typing.Literal[ "APM", @@ -1261,7 +778,6 @@ class MandateResponseDict(typing_extensions.TypedDict, total=False): TransactionBaseStatus = typing.Union[ typing.Literal["CANCELLED", "FAILED", "PENDING", "SUCCESSFUL"], str ] -TransactionBaseStatusInput = TransactionBaseStatus class TransactionBase(pydantic.BaseModel): @@ -1311,62 +827,6 @@ class TransactionBase(pydantic.BaseModel): """ -class TransactionBaseDict(typing_extensions.TypedDict, total=False): - amount: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - float, typing_extensions.Doc("Total amount of the transaction.") - ] - ] - currency: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - CurrencyInput, - typing_extensions.Doc( - "Three-letter [ISO4217](https://en.wikipedia.org/wiki/ISO_4217) code of the currency for the amount. Currently supportedcurrency values are enumerated above." - ), - ] - ] - id: typing_extensions.NotRequired[ - typing_extensions.Annotated[str, typing_extensions.Doc("Unique ID of the transaction.")] - ] - installments_count: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - int, - typing_extensions.Doc( - "Current number of the installment for deferred payments.\nMin: 1" - ), - ] - ] - payment_type: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - PaymentTypeInput, typing_extensions.Doc("Payment type used for the transaction.") - ] - ] - status: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - TransactionBaseStatusInput, typing_extensions.Doc("Current status of the transaction.") - ] - ] - timestamp: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - datetime.datetime, - typing_extensions.Doc( - "Date and time of the creation of the transaction. Response format expressed according to [ISO8601](https://en.wikipedia.org/wiki/ISO_8601) code." - ), - ] - ] - transaction_code: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "Transaction code returned by the acquirer/processing entity after processing the transaction." - ), - ] - ] - - -TransactionBaseInput = TransactionBaseDict - - class TransactionCheckoutInfo(pydantic.BaseModel): """ Checkout-specific fields associated with a transaction. @@ -1398,53 +858,11 @@ class TransactionCheckoutInfo(pydantic.BaseModel): """ -class TransactionCheckoutInfoDict(typing_extensions.TypedDict, total=False): - auth_code: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "Authorization code for the transaction sent by the payment card issuer or bank. Applicable only to card payments." - ), - ] - ] - entry_mode: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - EntryModeInput, typing_extensions.Doc("Entry mode of the payment details.") - ] - ] - merchant_code: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "Unique code of the registered merchant to whom the payment is made." - ), - ] - ] - tip_amount: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - float, typing_extensions.Doc("Amount of the tip (out of the total transaction amount).") - ] - ] - vat_amount: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - float, - typing_extensions.Doc( - "Amount of the applicable VAT (out of the total transaction amount)." - ), - ] - ] - - -TransactionCheckoutInfoInput = TransactionCheckoutInfoDict - - CheckoutStatus = typing.Union[typing.Literal["EXPIRED", "FAILED", "PAID", "PENDING"], str] -CheckoutStatusInput = CheckoutStatus CheckoutTransactionStatus = typing.Union[ typing.Literal["CANCELLED", "FAILED", "PENDING", "SUCCESSFUL"], str ] -CheckoutTransactionStatusInput = CheckoutTransactionStatus class CheckoutTransaction(pydantic.BaseModel): @@ -1519,97 +937,6 @@ class CheckoutTransaction(pydantic.BaseModel): """ -class CheckoutTransactionDict(typing_extensions.TypedDict, total=False): - amount: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - float, typing_extensions.Doc("Total amount of the transaction.") - ] - ] - auth_code: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "Authorization code for the transaction sent by the payment card issuer or bank. Applicable only to card payments." - ), - ] - ] - currency: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - CurrencyInput, - typing_extensions.Doc( - "Three-letter [ISO4217](https://en.wikipedia.org/wiki/ISO_4217) code of the currency for the amount. Currently supportedcurrency values are enumerated above." - ), - ] - ] - entry_mode: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - EntryModeInput, typing_extensions.Doc("Entry mode of the payment details.") - ] - ] - id: typing_extensions.NotRequired[ - typing_extensions.Annotated[str, typing_extensions.Doc("Unique ID of the transaction.")] - ] - installments_count: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - int, - typing_extensions.Doc( - "Current number of the installment for deferred payments.\nMin: 1" - ), - ] - ] - merchant_code: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "Unique code of the registered merchant to whom the payment is made." - ), - ] - ] - payment_type: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - PaymentTypeInput, typing_extensions.Doc("Payment type used for the transaction.") - ] - ] - status: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - CheckoutTransactionStatusInput, - typing_extensions.Doc("Current status of the transaction."), - ] - ] - timestamp: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - datetime.datetime, - typing_extensions.Doc( - "Date and time of the creation of the transaction. Response format expressed according to [ISO8601](https://en.wikipedia.org/wiki/ISO_8601) code." - ), - ] - ] - tip_amount: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - float, typing_extensions.Doc("Amount of the tip (out of the total transaction amount).") - ] - ] - transaction_code: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "Transaction code returned by the acquirer/processing entity after processing the transaction." - ), - ] - ] - vat_amount: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - float, - typing_extensions.Doc( - "Amount of the applicable VAT (out of the total transaction amount)." - ), - ] - ] - - -CheckoutTransactionInput = CheckoutTransactionDict - - class Checkout(pydantic.BaseModel): """ Core checkout resource returned by the Checkouts API. A checkout is created before payment processing andthen updated as payment attempts, redirects, and resulting transactions are attached to it. @@ -1685,112 +1012,9 @@ class Checkout(pydantic.BaseModel): """ -class CheckoutDict(typing_extensions.TypedDict, total=False): - amount: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - float, - typing_extensions.Doc("Amount to be charged to the payer, expressed in major units."), - ] - ] - checkout_reference: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "Merchant-defined reference for the checkout. Use it to correlate the SumUp checkout with your own order, cart,subscription, or payment attempt in your systems.\nMax length: 90" - ), - ] - ] - currency: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - CurrencyInput, - typing_extensions.Doc( - "Three-letter [ISO4217](https://en.wikipedia.org/wiki/ISO_4217) code of the currency for the amount. Currently supportedcurrency values are enumerated above." - ), - ] - ] - customer_id: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "Merchant-scoped identifier of the customer associated with the checkout. Use it when storing payment instrumentsor reusing saved customer context for recurring and returning-payer flows." - ), - ] - ] - date: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - datetime.datetime, - typing_extensions.Doc( - "Date and time of the creation of the payment checkout. Response format expressed according to [ISO8601](https://en.wikipedia.org/wiki/ISO_8601) code." - ), - ] - ] - description: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "Short merchant-defined description shown in SumUp tools and reporting. Use it to make the checkout easier torecognize in dashboards, support workflows, and reconciliation." - ), - ] - ] - id: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc("Unique SumUp identifier of the checkout resource.\nRead only"), - ] - ] - mandate: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - MandateResponseInput, - typing_extensions.Doc("Details of the mandate linked to the saved payment instrument."), - ] - ] - merchant_code: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, typing_extensions.Doc("Merchant account that receives the payment.") - ] - ] - return_url: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "Optional backend callback URL used by SumUp to notify your platform about processing updates for the checkout.\nFormat:uri" - ), - ] - ] - status: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - CheckoutStatusInput, - typing_extensions.Doc( - "Current high-level state of the checkout. `PENDING` means the checkout exists but is not yet completed, `PAID`means a payment succeeded, `FAILED` means the latest processing attempt failed, and `EXPIRED` means the checkoutcan no longer be processed." - ), - ] - ] - transactions: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - typing.Sequence[CheckoutTransactionInput], - typing_extensions.Doc( - "Payment attempts and resulting transaction records linked to this checkout. Use the Transactions endpoints whenyou need the authoritative payment result and event history.\nUnique items only" - ), - ] - ] - valid_until: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - datetime.datetime, - typing_extensions.Doc( - "Optional expiration timestamp. The checkout must be processed before this moment, otherwise it becomes unusable.If omitted, the checkout does not have an explicit expiry time." - ), - ] - ] - - -CheckoutInput = CheckoutDict - - CheckoutAcceptedNextStepMechanism = typing.Union[typing.Literal["browser", "iframe"], str] -CheckoutAcceptedNextStepMechanismInput = CheckoutAcceptedNextStepMechanism CheckoutAcceptedNextStepPayload = dict[str, str] -CheckoutAcceptedNextStepPayloadInput = typing.Mapping[str, str] """ Parameters required to complete the next step. The exact keys depend on the payment provider and flow type. """ @@ -1827,46 +1051,6 @@ class CheckoutAcceptedNextStep(pydantic.BaseModel): """ -class CheckoutAcceptedNextStepDict(typing_extensions.TypedDict, total=False): - mechanism: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - typing.Sequence[CheckoutAcceptedNextStepMechanismInput], - typing_extensions.Doc( - "Allowed presentation mechanisms for the next step. `iframe` means the flow can be embedded, while `browser` meansit can be completed through a full-page redirect." - ), - ] - ] - method: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, typing_extensions.Doc("HTTP method to use when following the next step.") - ] - ] - payload: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - CheckoutAcceptedNextStepPayloadInput, - typing_extensions.Doc( - "Parameters required to complete the next step. The exact keys depend on the payment provider and flow type." - ), - ] - ] - redirect_url: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "Merchant URL where the payer returns after the external flow finishes." - ), - ] - ] - url: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, typing_extensions.Doc("URL to open or submit in order to continue processing.") - ] - ] - - -CheckoutAcceptedNextStepInput = CheckoutAcceptedNextStepDict - - class CheckoutAccepted(pydantic.BaseModel): """ Response returned when checkout processing requires an additional payer action, such as a 3DS challenge ora redirect to an external payment method page. @@ -1878,20 +1062,6 @@ class CheckoutAccepted(pydantic.BaseModel): """ -class CheckoutAcceptedDict(typing_extensions.TypedDict, total=False): - next_step: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - CheckoutAcceptedNextStepInput, - typing_extensions.Doc( - "Instructions for the next action the payer or client must take." - ), - ] - ] - - -CheckoutAcceptedInput = CheckoutAcceptedDict - - CheckoutCreateRequestPurpose = typing.Union[ typing.Literal["CHECKOUT", "SETUP_RECURRING_PAYMENT"], str ] @@ -2039,12 +1209,10 @@ class CheckoutCreateRequestDict(typing_extensions.TypedDict, total=False): CheckoutSuccessStatus = typing.Union[typing.Literal["EXPIRED", "FAILED", "PAID", "PENDING"], str] -CheckoutSuccessStatusInput = CheckoutSuccessStatus CheckoutSuccessTransactionStatus = typing.Union[ typing.Literal["CANCELLED", "FAILED", "PENDING", "SUCCESSFUL"], str ] -CheckoutSuccessTransactionStatusInput = CheckoutSuccessTransactionStatus class CheckoutSuccessTransaction(pydantic.BaseModel): @@ -2119,97 +1287,6 @@ class CheckoutSuccessTransaction(pydantic.BaseModel): """ -class CheckoutSuccessTransactionDict(typing_extensions.TypedDict, total=False): - amount: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - float, typing_extensions.Doc("Total amount of the transaction.") - ] - ] - auth_code: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "Authorization code for the transaction sent by the payment card issuer or bank. Applicable only to card payments." - ), - ] - ] - currency: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - CurrencyInput, - typing_extensions.Doc( - "Three-letter [ISO4217](https://en.wikipedia.org/wiki/ISO_4217) code of the currency for the amount. Currently supportedcurrency values are enumerated above." - ), - ] - ] - entry_mode: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - EntryModeInput, typing_extensions.Doc("Entry mode of the payment details.") - ] - ] - id: typing_extensions.NotRequired[ - typing_extensions.Annotated[str, typing_extensions.Doc("Unique ID of the transaction.")] - ] - installments_count: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - int, - typing_extensions.Doc( - "Current number of the installment for deferred payments.\nMin: 1" - ), - ] - ] - merchant_code: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "Unique code of the registered merchant to whom the payment is made." - ), - ] - ] - payment_type: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - PaymentTypeInput, typing_extensions.Doc("Payment type used for the transaction.") - ] - ] - status: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - CheckoutSuccessTransactionStatusInput, - typing_extensions.Doc("Current status of the transaction."), - ] - ] - timestamp: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - datetime.datetime, - typing_extensions.Doc( - "Date and time of the creation of the transaction. Response format expressed according to [ISO8601](https://en.wikipedia.org/wiki/ISO_8601) code." - ), - ] - ] - tip_amount: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - float, typing_extensions.Doc("Amount of the tip (out of the total transaction amount).") - ] - ] - transaction_code: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "Transaction code returned by the acquirer/processing entity after processing the transaction." - ), - ] - ] - vat_amount: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - float, - typing_extensions.Doc( - "Amount of the applicable VAT (out of the total transaction amount)." - ), - ] - ] - - -CheckoutSuccessTransactionInput = CheckoutSuccessTransactionDict - - class CheckoutSuccessPaymentInstrument(pydantic.BaseModel): """ Details of the saved payment instrument created or reused during checkout processing. @@ -2221,15 +1298,6 @@ class CheckoutSuccessPaymentInstrument(pydantic.BaseModel): """ -class CheckoutSuccessPaymentInstrumentDict(typing_extensions.TypedDict, total=False): - token: typing_extensions.NotRequired[ - typing_extensions.Annotated[str, typing_extensions.Doc("Token value")] - ] - - -CheckoutSuccessPaymentInstrumentInput = CheckoutSuccessPaymentInstrumentDict - - class CheckoutSuccess(pydantic.BaseModel): """ Checkout resource returned after a synchronous processing attempt. In addition to the base checkout fields, itcan include the resulting transaction identifiers and any newly created payment instrument token. @@ -2332,142 +1400,6 @@ class CheckoutSuccess(pydantic.BaseModel): """ -class CheckoutSuccessDict(typing_extensions.TypedDict, total=False): - amount: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - float, - typing_extensions.Doc("Amount to be charged to the payer, expressed in major units."), - ] - ] - checkout_reference: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "Merchant-defined reference for the checkout. Use it to correlate the SumUp checkout with your own order, cart,subscription, or payment attempt in your systems.\nMax length: 90" - ), - ] - ] - currency: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - CurrencyInput, - typing_extensions.Doc( - "Three-letter [ISO4217](https://en.wikipedia.org/wiki/ISO_4217) code of the currency for the amount. Currently supportedcurrency values are enumerated above." - ), - ] - ] - customer_id: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "Merchant-scoped identifier of the customer associated with the checkout. Use it when storing payment instrumentsor reusing saved customer context for recurring and returning-payer flows." - ), - ] - ] - date: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - datetime.datetime, - typing_extensions.Doc( - "Date and time of the creation of the payment checkout. Response format expressed according to [ISO8601](https://en.wikipedia.org/wiki/ISO_8601) code." - ), - ] - ] - description: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "Short merchant-defined description shown in SumUp tools and reporting. Use it to make the checkout easier torecognize in dashboards, support workflows, and reconciliation." - ), - ] - ] - id: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc("Unique SumUp identifier of the checkout resource.\nRead only"), - ] - ] - mandate: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - MandateResponseInput, - typing_extensions.Doc("Details of the mandate linked to the saved payment instrument."), - ] - ] - merchant_code: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, typing_extensions.Doc("Merchant account that receives the payment.") - ] - ] - merchant_name: typing_extensions.NotRequired[ - typing_extensions.Annotated[str, typing_extensions.Doc("Name of the merchant")] - ] - payment_instrument: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - CheckoutSuccessPaymentInstrumentInput, - typing_extensions.Doc( - "Details of the saved payment instrument created or reused during checkout processing." - ), - ] - ] - redirect_url: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "URL where the payer is redirected after a redirect-based payment or SCA flow completes." - ), - ] - ] - return_url: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "Optional backend callback URL used by SumUp to notify your platform about processing updates for the checkout.\nFormat:uri" - ), - ] - ] - status: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - CheckoutSuccessStatusInput, - typing_extensions.Doc( - "Current high-level state of the checkout. `PENDING` means the checkout exists but is not yet completed, `PAID`means a payment succeeded, `FAILED` means the latest processing attempt failed, and `EXPIRED` means the checkoutcan no longer be processed." - ), - ] - ] - transaction_code: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "Transaction code of the successful transaction with which the payment for the checkout is completed.\nRead only" - ), - ] - ] - transaction_id: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "Transaction ID of the successful transaction with which the payment for the checkout is completed.\nRead only" - ), - ] - ] - transactions: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - typing.Sequence[CheckoutSuccessTransactionInput], - typing_extensions.Doc( - "Payment attempts and resulting transaction records linked to this checkout. Use the Transactions endpoints whenyou need the authoritative payment result and event history.\nUnique items only" - ), - ] - ] - valid_until: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - datetime.datetime, - typing_extensions.Doc( - "Optional expiration timestamp. The checkout must be processed before this moment, otherwise it becomes unusable.If omitted, the checkout does not have an explicit expiry time." - ), - ] - ] - - -CheckoutSuccessInput = CheckoutSuccessDict - - class ClassicMerchantIdentifiers(pydantic.BaseModel): """ ClassicMerchantIdentifiers is a schema definition. @@ -2481,20 +1413,6 @@ class ClassicMerchantIdentifiers(pydantic.BaseModel): """ -class ClassicMerchantIdentifiersDict(typing_extensions.TypedDict, total=False): - id: typing_extensions.Required[ - typing_extensions.Annotated[ - int, - typing_extensions.Doc( - "Classic (serial) merchant ID.\nFormat: int64\nDeprecated: this operation is deprecated" - ), - ] - ] - - -ClassicMerchantIdentifiersInput = ClassicMerchantIdentifiersDict - - class CompanyIdentifier(pydantic.BaseModel): """ CompanyIdentifier is a schema definition. @@ -2513,33 +1431,12 @@ class CompanyIdentifier(pydantic.BaseModel): """ -class CompanyIdentifierDict(typing_extensions.TypedDict, total=False): - ref: typing_extensions.Required[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "The unique reference for the company identifier type as defined in the country SDK." - ), - ] - ] - value: typing_extensions.Required[ - typing_extensions.Annotated[ - str, typing_extensions.Doc("The company identifier value.\nMax length: 100") - ] - ] - - -CompanyIdentifierInput = CompanyIdentifierDict - - CompanyIdentifiers = list[CompanyIdentifier] -CompanyIdentifiersInput = typing.Sequence[CompanyIdentifierInput] """ A list of country-specific company identifiers. """ LegalType = str -LegalTypeInput = str """ The unique legal type reference as defined in the country SDK. We do not rely on IDs as used by other services.Consumers of this API are expected to use the country SDK to map to any other IDs, translation keys, ordescriptions. @@ -2615,79 +1512,6 @@ class Company(pydantic.BaseModel): """ -class CompanyDict(typing_extensions.TypedDict, total=False): - address: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - AddressInput, - typing_extensions.Doc( - "An address somewhere in the world. The address fields used depend on the country conventions. For example, inGreat Britain, `city` is `post_town`. In the United States, the top-level administrative unit used in addressesis `state`, whereas in Chile it's `region`.\nWhether an address is valid or not depends on whether the locally required fields are present. Fields not supported ina country will be ignored.\nAddress documentation: https://backstage.sumup.net/docs/default/Component/merchants/merchant/#addresses" - ), - ] - ] - attributes: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - AttributesInput, - typing_extensions.Doc( - "Object attributes that are modifiable only by SumUp applications." - ), - ] - ] - identifiers: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - CompanyIdentifiersInput, - typing_extensions.Doc("A list of country-specific company identifiers."), - ] - ] - legal_type: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - LegalTypeInput, - typing_extensions.Doc( - "The unique legal type reference as defined in the country SDK. We do not rely on IDs as used by other services.Consumers of this API are expected to use the country SDK to map to any other IDs, translation keys, ordescriptions.\nMin length: 4\nMax length: 64\nThe country SDK documentation for legal types.: https://developer.sumup.com/tools/glossary/merchant#legal-types" - ), - ] - ] - merchant_category_code: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "The merchant category code for the account as specified by [ISO18245](https://www.iso.org/standard/33365.html). MCCsare used to classify businesses based on the goods or services they provide.\nPattern: ^[0-9]{4}$" - ), - ] - ] - name: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, typing_extensions.Doc("The company's legal name.\nMin length: 1\nMax length: 150") - ] - ] - phone_number: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - PhoneNumberInput, - typing_extensions.Doc( - "A publicly available phone number in [E.164](https://en.wikipedia.org/wiki/E.164) format.\nMax length: 16" - ), - ] - ] - trading_address: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - AddressInput, - typing_extensions.Doc( - "An address somewhere in the world. The address fields used depend on the country conventions. For example, inGreat Britain, `city` is `post_town`. In the United States, the top-level administrative unit used in addressesis `state`, whereas in Chile it's `region`.\nWhether an address is valid or not depends on whether the locally required fields are present. Fields not supported ina country will be ignored.\nAddress documentation: https://backstage.sumup.net/docs/default/Component/merchants/merchant/#addresses" - ), - ] - ] - website: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "HTTP(S) URL of the company's website.\nFormat: uri\nMax length: 255" - ), - ] - ] - - -CompanyInput = CompanyDict - - class CreateReaderCheckoutErrorErrors(pydantic.BaseModel): """ CreateReaderCheckoutErrorErrors is a schema definition. @@ -2704,18 +1528,6 @@ class CreateReaderCheckoutErrorErrors(pydantic.BaseModel): """ -class CreateReaderCheckoutErrorErrorsDict(typing_extensions.TypedDict, total=False): - type: typing_extensions.Required[ - typing_extensions.Annotated[str, typing_extensions.Doc("Error code")] - ] - detail: typing_extensions.NotRequired[ - typing_extensions.Annotated[str, typing_extensions.Doc("Error message")] - ] - - -CreateReaderCheckoutErrorErrorsInput = CreateReaderCheckoutErrorErrorsDict - - class CreateReaderCheckoutError(pydantic.BaseModel): """ Error description @@ -2724,13 +1536,6 @@ class CreateReaderCheckoutError(pydantic.BaseModel): errors: CreateReaderCheckoutErrorErrors -class CreateReaderCheckoutErrorDict(typing_extensions.TypedDict, total=False): - errors: typing_extensions.Required[CreateReaderCheckoutErrorErrorsInput] - - -CreateReaderCheckoutErrorInput = CreateReaderCheckoutErrorDict - - class CreateReaderCheckoutRequestAade(pydantic.BaseModel): """ Optional object containing data for transactions from ERP integrators in Greece that comply with the AADE1155 protocol. @@ -3072,20 +1877,6 @@ class CreateReaderCheckoutResponseData(pydantic.BaseModel): """ -class CreateReaderCheckoutResponseDataDict(typing_extensions.TypedDict, total=False): - client_transaction_id: typing_extensions.Required[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "The client transaction ID is a unique identifier for the transaction that is generated for the client.\n\nIt can be used later to fetch the transaction details via the [Transactions API](https://developer.sumup.com/api/transactions/get)." - ), - ] - ] - - -CreateReaderCheckoutResponseDataInput = CreateReaderCheckoutResponseDataDict - - class CreateReaderCheckoutResponse(pydantic.BaseModel): """ CreateReaderCheckoutResponse is a schema definition. @@ -3094,15 +1885,7 @@ class CreateReaderCheckoutResponse(pydantic.BaseModel): data: CreateReaderCheckoutResponseData -class CreateReaderCheckoutResponseDict(typing_extensions.TypedDict, total=False): - data: typing_extensions.Required[CreateReaderCheckoutResponseDataInput] - - -CreateReaderCheckoutResponseInput = CreateReaderCheckoutResponseDict - - CreateReaderCheckoutUnprocessableEntityErrors = dict[str, object] -CreateReaderCheckoutUnprocessableEntityErrorsInput = typing.Mapping[str, object] """ CreateReaderCheckoutUnprocessableEntityErrors is a schema definition. """ @@ -3116,13 +1899,6 @@ class CreateReaderCheckoutUnprocessableEntity(pydantic.BaseModel): errors: CreateReaderCheckoutUnprocessableEntityErrors -class CreateReaderCheckoutUnprocessableEntityDict(typing_extensions.TypedDict, total=False): - errors: typing_extensions.Required[CreateReaderCheckoutUnprocessableEntityErrorsInput] - - -CreateReaderCheckoutUnprocessableEntityInput = CreateReaderCheckoutUnprocessableEntityDict - - class CreateReaderTerminateErrorErrors(pydantic.BaseModel): """ CreateReaderTerminateErrorErrors is a schema definition. @@ -3139,18 +1915,6 @@ class CreateReaderTerminateErrorErrors(pydantic.BaseModel): """ -class CreateReaderTerminateErrorErrorsDict(typing_extensions.TypedDict, total=False): - type: typing_extensions.Required[ - typing_extensions.Annotated[str, typing_extensions.Doc("Error code")] - ] - detail: typing_extensions.NotRequired[ - typing_extensions.Annotated[str, typing_extensions.Doc("Error message")] - ] - - -CreateReaderTerminateErrorErrorsInput = CreateReaderTerminateErrorErrorsDict - - class CreateReaderTerminateError(pydantic.BaseModel): """ Error description @@ -3159,15 +1923,7 @@ class CreateReaderTerminateError(pydantic.BaseModel): errors: CreateReaderTerminateErrorErrors -class CreateReaderTerminateErrorDict(typing_extensions.TypedDict, total=False): - errors: typing_extensions.Required[CreateReaderTerminateErrorErrorsInput] - - -CreateReaderTerminateErrorInput = CreateReaderTerminateErrorDict - - CreateReaderTerminateUnprocessableEntityErrors = dict[str, object] -CreateReaderTerminateUnprocessableEntityErrorsInput = typing.Mapping[str, object] """ CreateReaderTerminateUnprocessableEntityErrors is a schema definition. """ @@ -3181,13 +1937,6 @@ class CreateReaderTerminateUnprocessableEntity(pydantic.BaseModel): errors: CreateReaderTerminateUnprocessableEntityErrors -class CreateReaderTerminateUnprocessableEntityDict(typing_extensions.TypedDict, total=False): - errors: typing_extensions.Required[CreateReaderTerminateUnprocessableEntityErrorsInput] - - -CreateReaderTerminateUnprocessableEntityInput = CreateReaderTerminateUnprocessableEntityDict - - class PersonalDetails(pydantic.BaseModel): """ Personal details for the customer. @@ -3307,14 +2056,6 @@ class DetailsErrorFailedConstraint(pydantic.BaseModel): reference: typing.Optional[str] = None -class DetailsErrorFailedConstraintDict(typing_extensions.TypedDict, total=False): - message: typing_extensions.NotRequired[str] - reference: typing_extensions.NotRequired[str] - - -DetailsErrorFailedConstraintInput = DetailsErrorFailedConstraintDict - - class DetailsError(pydantic.BaseModel): """ Error message structure. @@ -3341,27 +2082,6 @@ class DetailsError(pydantic.BaseModel): """ -class DetailsErrorDict(typing_extensions.TypedDict, total=False): - details: typing_extensions.NotRequired[ - typing_extensions.Annotated[str, typing_extensions.Doc("Details of the error.")] - ] - failed_constraints: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - typing.Sequence[DetailsErrorFailedConstraintInput], - typing_extensions.Doc("List of violated validation constraints."), - ] - ] - status: typing_extensions.NotRequired[ - typing_extensions.Annotated[float, typing_extensions.Doc("The status code.")] - ] - title: typing_extensions.NotRequired[ - typing_extensions.Annotated[str, typing_extensions.Doc("Short title of the error.")] - ] - - -DetailsErrorInput = DetailsErrorDict - - class Device(pydantic.BaseModel): """ Details of the device used to create the transaction. @@ -3393,27 +2113,6 @@ class Device(pydantic.BaseModel): """ -class DeviceDict(typing_extensions.TypedDict, total=False): - model: typing_extensions.NotRequired[ - typing_extensions.Annotated[str, typing_extensions.Doc("Device model.")] - ] - name: typing_extensions.NotRequired[ - typing_extensions.Annotated[str, typing_extensions.Doc("Device name.")] - ] - system_name: typing_extensions.NotRequired[ - typing_extensions.Annotated[str, typing_extensions.Doc("Device OS.")] - ] - system_version: typing_extensions.NotRequired[ - typing_extensions.Annotated[str, typing_extensions.Doc("Device OS version.")] - ] - uuid: typing_extensions.NotRequired[ - typing_extensions.Annotated[str, typing_extensions.Doc("Device UUID.")] - ] - - -DeviceInput = DeviceDict - - class ElvCardAccount(pydantic.BaseModel): """ Details of the ELV card account associated with the transaction. @@ -3440,26 +2139,6 @@ class ElvCardAccount(pydantic.BaseModel): """ -class ElvCardAccountDict(typing_extensions.TypedDict, total=False): - iban: typing_extensions.NotRequired[ - typing_extensions.Annotated[str, typing_extensions.Doc("ELV IBAN.")] - ] - last_4_digits: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, typing_extensions.Doc("ELV card account number last 4 digits.") - ] - ] - sequence_no: typing_extensions.NotRequired[ - typing_extensions.Annotated[int, typing_extensions.Doc("ELV card sequence number.")] - ] - sort_code: typing_extensions.NotRequired[ - typing_extensions.Annotated[str, typing_extensions.Doc("ELV card sort code.")] - ] - - -ElvCardAccountInput = ElvCardAccountDict - - class Error(pydantic.BaseModel): """ Error message structure. @@ -3476,18 +2155,6 @@ class Error(pydantic.BaseModel): """ -class ErrorDict(typing_extensions.TypedDict, total=False): - error_code: typing_extensions.NotRequired[ - typing_extensions.Annotated[str, typing_extensions.Doc("Platform code for the error.")] - ] - message: typing_extensions.NotRequired[ - typing_extensions.Annotated[str, typing_extensions.Doc("Short description of the error.")] - ] - - -ErrorInput = ErrorDict - - class ErrorExtended(pydantic.BaseModel): """ Error payload with the invalid parameter reference. @@ -3509,26 +2176,6 @@ class ErrorExtended(pydantic.BaseModel): """ -class ErrorExtendedDict(typing_extensions.TypedDict, total=False): - error_code: typing_extensions.NotRequired[ - typing_extensions.Annotated[str, typing_extensions.Doc("Platform code for the error.")] - ] - message: typing_extensions.NotRequired[ - typing_extensions.Annotated[str, typing_extensions.Doc("Short description of the error.")] - ] - param: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "Parameter name (with relative location) to which the error applies. Parameters from embedded resources aredisplayed using dot notation. For example, `card.name` refers to the `name` parameter embedded in the `card`object." - ), - ] - ] - - -ErrorExtendedInput = ErrorExtendedDict - - class ErrorForbidden(pydantic.BaseModel): """ Error message for forbidden requests. @@ -3550,23 +2197,7 @@ class ErrorForbidden(pydantic.BaseModel): """ -class ErrorForbiddenDict(typing_extensions.TypedDict, total=False): - error_code: typing_extensions.NotRequired[ - typing_extensions.Annotated[str, typing_extensions.Doc("Platform code for the error.")] - ] - error_message: typing_extensions.NotRequired[ - typing_extensions.Annotated[str, typing_extensions.Doc("Short description of the error.")] - ] - status_code: typing_extensions.NotRequired[ - typing_extensions.Annotated[str, typing_extensions.Doc("HTTP status code for the error.")] - ] - - -ErrorForbiddenInput = ErrorForbiddenDict - - EventId = int -EventIdInput = int """ Unique ID of the transaction event. Format: int64 @@ -3578,13 +2209,10 @@ class ErrorForbiddenDict(typing_extensions.TypedDict, total=False): ], str, ] -EventStatusInput = EventStatus EventType = typing.Union[typing.Literal["CHARGE_BACK", "PAYOUT", "PAYOUT_DEDUCTION", "REFUND"], str] -EventTypeInput = EventType TransactionId = str -TransactionIdInput = str """ Unique ID of the transaction. """ @@ -3657,64 +2285,7 @@ class Event(pydantic.BaseModel): """ -class EventDict(typing_extensions.TypedDict, total=False): - amount: typing_extensions.NotRequired[ - typing_extensions.Annotated[float, typing_extensions.Doc("Amount of the event.")] - ] - deducted_amount: typing_extensions.NotRequired[ - typing_extensions.Annotated[float, typing_extensions.Doc("Amount deducted for the event.")] - ] - deducted_fee_amount: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - float, typing_extensions.Doc("Amount of the fee deducted for the event.") - ] - ] - fee_amount: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - float, typing_extensions.Doc("Amount of the fee related to the event.") - ] - ] - id: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - EventIdInput, - typing_extensions.Doc("Unique ID of the transaction event.\nFormat: int64"), - ] - ] - installment_number: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - int, typing_extensions.Doc("Consecutive number of the installment.") - ] - ] - status: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - EventStatusInput, - typing_extensions.Doc( - "Status of the transaction event.\n\nNot every value is used for every event type.\n\n- `PENDING`: The event has been created but is not final yet. Used for events that are still being processed andwhose final outcome is not known yet.\n- `SCHEDULED`: The event is planned for a future payout cycle but has not been executed yet. This applies topayout events before money is actually sent out.\n- `RECONCILED`: The underlying payment has been matched with settlement data and is ready to continue through payoutprocessing, but the funds have not been paid out yet. This applies to payout events.\n- `PAID_OUT`: The payout event has been completed and the funds were included in a merchant payout.\n- `REFUNDED`: A refund event has been accepted and recorded in the refund flow. This is the status returned forrefund events once the transaction amount is being or has been returned to the payer.\n- `SUCCESSFUL`: The event completed successfully. Use this as the generic terminal success status for event typesthat do not expose a more specific business outcome such as `PAID_OUT` or `REFUNDED`.\n- `FAILED`: The event could not be completed. Typical examples are a payout that could not be executed oran event that was rejected during processing." - ), - ] - ] - timestamp: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - datetime.datetime, typing_extensions.Doc("Date and time of the transaction event.") - ] - ] - transaction_id: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - TransactionIdInput, typing_extensions.Doc("Unique ID of the transaction.") - ] - ] - type: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - EventTypeInput, typing_extensions.Doc("Type of the transaction event.") - ] - ] - - -EventInput = EventDict - - FinancialPayoutStatus = typing.Union[typing.Literal["FAILED", "SUCCESSFUL"], str] -FinancialPayoutStatusInput = FinancialPayoutStatus FinancialPayoutType = typing.Union[ typing.Literal[ @@ -3726,7 +2297,6 @@ class EventDict(typing_extensions.TypedDict, total=False): ], str, ] -FinancialPayoutTypeInput = FinancialPayoutType class FinancialPayout(pydantic.BaseModel): @@ -3756,31 +2326,12 @@ class FinancialPayout(pydantic.BaseModel): type: typing.Optional[FinancialPayoutType] = None -class FinancialPayoutDict(typing_extensions.TypedDict, total=False): - amount: typing_extensions.NotRequired[float] - currency: typing_extensions.NotRequired[str] - date: typing_extensions.NotRequired[ - typing_extensions.Annotated[datetime.date, typing_extensions.Doc("Format: date")] - ] - fee: typing_extensions.NotRequired[float] - id: typing_extensions.NotRequired[int] - reference: typing_extensions.NotRequired[str] - status: typing_extensions.NotRequired[FinancialPayoutStatusInput] - transaction_code: typing_extensions.NotRequired[str] - type: typing_extensions.NotRequired[FinancialPayoutTypeInput] - - -FinancialPayoutInput = FinancialPayoutDict - - FinancialPayouts = list[FinancialPayout] -FinancialPayoutsInput = typing.Sequence[FinancialPayoutInput] """ List of payout summaries. """ HorizontalAccuracy = float -HorizontalAccuracyInput = float """ Indication of the precision of the geographical position received from the payment terminal. """ @@ -3800,20 +2351,7 @@ class Invite(pydantic.BaseModel): expires_at: datetime.datetime -class InviteDict(typing_extensions.TypedDict, total=False): - email: typing_extensions.Required[ - typing_extensions.Annotated[ - str, typing_extensions.Doc("Email address of the invited user.\nFormat: email") - ] - ] - expires_at: typing_extensions.Required[datetime.datetime] - - -InviteInput = InviteDict - - Lat = float -LatInput = float """ Latitude value from the coordinates of the payment location (as received from the payment terminal reader). Min: 0 @@ -3853,37 +2391,6 @@ class Link(pydantic.BaseModel): """ -class LinkDict(typing_extensions.TypedDict, total=False): - href: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, typing_extensions.Doc("URL for accessing the related resource.\nFormat: uri") - ] - ] - max_amount: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - float, typing_extensions.Doc("Maximum allowed amount for the refund.") - ] - ] - min_amount: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - float, typing_extensions.Doc("Minimum allowed amount for the refund.") - ] - ] - rel: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, typing_extensions.Doc("Specifies the relation to the current resource.") - ] - ] - type: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, typing_extensions.Doc("Specifies the media type of the related resource.") - ] - ] - - -LinkInput = LinkDict - - class Person(pydantic.BaseModel): """ Person is a schema definition. @@ -3987,125 +2494,6 @@ class Person(pydantic.BaseModel): """ -class PersonDict(typing_extensions.TypedDict, total=False): - id: typing_extensions.Required[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "The unique identifier for the person. This is a [typeid](https://github.com/sumup/typeid).\nRead only" - ), - ] - ] - address: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - AddressInput, - typing_extensions.Doc( - "An address somewhere in the world. The address fields used depend on the country conventions. For example, inGreat Britain, `city` is `post_town`. In the United States, the top-level administrative unit used in addressesis `state`, whereas in Chile it's `region`.\nWhether an address is valid or not depends on whether the locally required fields are present. Fields not supported ina country will be ignored.\nAddress documentation: https://backstage.sumup.net/docs/default/Component/merchants/merchant/#addresses" - ), - ] - ] - birthdate: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - datetime.date, - typing_extensions.Doc( - "The date of birth of the individual, represented as an ISO 8601:2004 [ISO8601‑2004] YYYY-MM-DD format.\nFormat: date" - ), - ] - ] - change_status: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - ChangeStatusInput, - typing_extensions.Doc( - "Reflects the status of changes submitted through the `PATCH` endpoints for the merchant or persons. If somechanges have not been applied yet, the status will be `pending`. If all changes have been applied, the status`done`.\nThe status is only returned after write operations or on read endpoints when the `version` query parameter isprovided.\nRead only" - ), - ] - ] - citizenship: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - CountryCodeInput, - typing_extensions.Doc( - "An [ISO3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2)\ncountry code. This definition users `oneOf` with a two-character string\ntype to allow for support of future countries in client code.\nMin length: 2\nMax length: 2\nPattern: ^[A-Z]{2}$" - ), - ] - ] - country_of_residence: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "An [ISO3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code representing the countrywhere the person resides.\nMin length: 2\nMax length: 2" - ), - ] - ] - family_name: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, typing_extensions.Doc("The last name(s) of the individual.\nMax length: 60") - ] - ] - given_name: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, typing_extensions.Doc("The first name(s) of the individual.\nMax length: 60") - ] - ] - identifiers: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - typing.Sequence[PersonalIdentifierInput], - typing_extensions.Doc("A list of country-specific personal identifiers.\nMax items: 5"), - ] - ] - middle_name: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "Middle name(s) of the End-User. Note that in some cultures, people can have multiple middle names; all canbe present, with the names being separated by space characters. Also note that in some cultures, middle namesare not used.\nMax length: 60" - ), - ] - ] - nationality: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "The persons nationality. May be an [ISO3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) countrycode, but legacy data may not conform to this standard." - ), - ] - ] - ownership: typing_extensions.NotRequired[OwnershipInput] - phone_number: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - PhoneNumberInput, - typing_extensions.Doc( - "A publicly available phone number in [E.164](https://en.wikipedia.org/wiki/E.164) format.\nMax length: 16" - ), - ] - ] - relationships: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - typing.Sequence[str], - typing_extensions.Doc( - "A list of roles the person has in the merchant or towards SumUp. A merchant must have at least one person withthe relationship `representative`.\nMin items: 1\nMax items: 1" - ), - ] - ] - user_id: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "A corresponding identity user ID for the person, if they have a user account." - ), - ] - ] - version: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - VersionInput, - typing_extensions.Doc( - "The version of the resource. The version reflects a specific change submitted to the API via one of the `PATCH`endpoints." - ), - ] - ] - - -PersonInput = PersonDict - - class ListPersonsResponseBody(pydantic.BaseModel): """ ListPersonsResponseBody is a schema definition. @@ -4114,15 +2502,7 @@ class ListPersonsResponseBody(pydantic.BaseModel): items: list[Person] -class ListPersonsResponseBodyDict(typing_extensions.TypedDict, total=False): - items: typing_extensions.Required[typing.Sequence[PersonInput]] - - -ListPersonsResponseBodyInput = ListPersonsResponseBodyDict - - Lon = float -LonInput = float """ Longitude value from the coordinates of the payment location (as received from the payment terminal reader). Min: 0 @@ -4197,15 +2577,6 @@ class MembershipUserClassic(pydantic.BaseModel): """ -class MembershipUserClassicDict(typing_extensions.TypedDict, total=False): - user_id: typing_extensions.Required[ - typing_extensions.Annotated[int, typing_extensions.Doc("Format: int32")] - ] - - -MembershipUserClassicInput = MembershipUserClassicDict - - class MembershipUser(pydantic.BaseModel): """ Information about the user associated with the membership. @@ -4259,69 +2630,6 @@ class MembershipUser(pydantic.BaseModel): """ -class MembershipUserDict(typing_extensions.TypedDict, total=False): - email: typing_extensions.Required[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "End-User's preferred e-mail address. Its value MUST conform to the RFC 5322 [RFC5322] addr-spec syntax. TheRP MUST NOT rely upon this value being unique, for unique identification use ID instead." - ), - ] - ] - id: typing_extensions.Required[ - typing_extensions.Annotated[ - str, typing_extensions.Doc("Identifier for the End-User (also called Subject).") - ] - ] - mfa_on_login_enabled: typing_extensions.Required[ - typing_extensions.Annotated[ - bool, typing_extensions.Doc("True if the user has enabled MFA on login.") - ] - ] - service_account_user: typing_extensions.Required[ - typing_extensions.Annotated[ - bool, typing_extensions.Doc("True if the user is a service account.") - ] - ] - virtual_user: typing_extensions.Required[ - typing_extensions.Annotated[ - bool, typing_extensions.Doc("True if the user is a virtual user (operator).") - ] - ] - classic: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - MembershipUserClassicInput, - typing_extensions.Doc( - "Classic identifiers of the user.\nDeprecated: this operation is deprecated" - ), - ] - ] - disabled_at: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - datetime.datetime, - typing_extensions.Doc( - "Time when the user has been disabled. Applies only to virtual users (`virtual_user: true`)." - ), - ] - ] - nickname: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, typing_extensions.Doc("User's preferred name. Used for display purposes only.") - ] - ] - picture: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "URL of the End-User's profile picture. This URL refers to an image file (for example, a PNG, JPEG, or GIFimage file), rather than to a Web page containing an image.\nFormat: uri" - ), - ] - ] - - -MembershipUserInput = MembershipUserDict - - Metadata = dict[str, object] MetadataInput = typing.Mapping[str, object] """ @@ -4388,70 +2696,6 @@ class Member(pydantic.BaseModel): """ -class MemberDict(typing_extensions.TypedDict, total=False): - created_at: typing_extensions.Required[ - typing_extensions.Annotated[ - datetime.datetime, - typing_extensions.Doc("The timestamp of when the member was created."), - ] - ] - id: typing_extensions.Required[ - typing_extensions.Annotated[str, typing_extensions.Doc("ID of the member.")] - ] - permissions: typing_extensions.Required[ - typing_extensions.Annotated[ - typing.Sequence[str], - typing_extensions.Doc( - "User's permissions.\nDeprecated: Permissions include only legacy permissions, please use roles instead. Member access is based on roles withina given resource and the permissions these roles grant." - ), - ] - ] - roles: typing_extensions.Required[ - typing_extensions.Annotated[typing.Sequence[str], typing_extensions.Doc("User's roles.")] - ] - status: typing_extensions.Required[ - typing_extensions.Annotated[ - MembershipStatusInput, typing_extensions.Doc("The status of the membership.") - ] - ] - updated_at: typing_extensions.Required[ - typing_extensions.Annotated[ - datetime.datetime, - typing_extensions.Doc("The timestamp of when the member was last updated."), - ] - ] - attributes: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - AttributesInput, - typing_extensions.Doc( - "Object attributes that are modifiable only by SumUp applications." - ), - ] - ] - invite: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - InviteInput, typing_extensions.Doc("Pending invitation for membership.") - ] - ] - metadata: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - MetadataInput, - typing_extensions.Doc( - "Set of user-defined key-value pairs attached to the object. Partial updates are not supported. When updating, alwayssubmit whole metadata. Maximum of 64 parameters are allowed in the object.\nMax properties: 64" - ), - ] - ] - user: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - MembershipUserInput, - typing_extensions.Doc("Information about the user associated with the membership."), - ] - ] - - -MemberInput = MemberDict - - ResourceType = str ResourceTypeInput = str """ @@ -4508,55 +2752,6 @@ class MembershipResource(pydantic.BaseModel): """ -class MembershipResourceDict(typing_extensions.TypedDict, total=False): - created_at: typing_extensions.Required[ - typing_extensions.Annotated[ - datetime.datetime, - typing_extensions.Doc("The timestamp of when the membership resource was created."), - ] - ] - id: typing_extensions.Required[ - typing_extensions.Annotated[ - str, typing_extensions.Doc("ID of the resource the membership is in.") - ] - ] - name: typing_extensions.Required[ - typing_extensions.Annotated[str, typing_extensions.Doc("Display name of the resource.")] - ] - type: typing_extensions.Required[ - typing_extensions.Annotated[ - ResourceTypeInput, - typing_extensions.Doc( - "The type of the membership resource.\nPossible values are:\n* `merchant` - merchant account(s)\n* `organization` - organization(s)" - ), - ] - ] - updated_at: typing_extensions.Required[ - typing_extensions.Annotated[ - datetime.datetime, - typing_extensions.Doc( - "The timestamp of when the membership resource was last updated." - ), - ] - ] - attributes: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - AttributesInput, - typing_extensions.Doc( - "Object attributes that are modifiable only by SumUp applications." - ), - ] - ] - logo: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, typing_extensions.Doc("Logo fo the resource.\nFormat: uri\nMax length: 256") - ] - ] - - -MembershipResourceInput = MembershipResourceDict - - class Membership(pydantic.BaseModel): """ A membership associates a user with a resource, memberships is defined by user, resource, resource type, andassociated roles. @@ -4628,85 +2823,7 @@ class Membership(pydantic.BaseModel): """ -class MembershipDict(typing_extensions.TypedDict, total=False): - created_at: typing_extensions.Required[ - typing_extensions.Annotated[ - datetime.datetime, - typing_extensions.Doc("The timestamp of when the membership was created."), - ] - ] - id: typing_extensions.Required[ - typing_extensions.Annotated[str, typing_extensions.Doc("ID of the membership.")] - ] - permissions: typing_extensions.Required[ - typing_extensions.Annotated[ - typing.Sequence[str], - typing_extensions.Doc( - "User's permissions.\nDeprecated: Permissions include only legacy permissions, please use roles instead. Member access is based on their roleswithin a given resource and the permissions these roles grant." - ), - ] - ] - resource: typing_extensions.Required[ - typing_extensions.Annotated[ - MembershipResourceInput, - typing_extensions.Doc("Information about the resource the membership is in."), - ] - ] - resource_id: typing_extensions.Required[ - typing_extensions.Annotated[ - str, typing_extensions.Doc("ID of the resource the membership is in.") - ] - ] - roles: typing_extensions.Required[ - typing_extensions.Annotated[typing.Sequence[str], typing_extensions.Doc("User's roles.")] - ] - status: typing_extensions.Required[ - typing_extensions.Annotated[ - MembershipStatusInput, typing_extensions.Doc("The status of the membership.") - ] - ] - type: typing_extensions.Required[ - typing_extensions.Annotated[ - ResourceTypeInput, - typing_extensions.Doc( - "The type of the membership resource.\nPossible values are:\n* `merchant` - merchant account(s)\n* `organization` - organization(s)" - ), - ] - ] - updated_at: typing_extensions.Required[ - typing_extensions.Annotated[ - datetime.datetime, - typing_extensions.Doc("The timestamp of when the membership was last updated."), - ] - ] - attributes: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - AttributesInput, - typing_extensions.Doc( - "Object attributes that are modifiable only by SumUp applications." - ), - ] - ] - invite: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - InviteInput, typing_extensions.Doc("Pending invitation for membership.") - ] - ] - metadata: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - MetadataInput, - typing_extensions.Doc( - "Set of user-defined key-value pairs attached to the object. Partial updates are not supported. When updating, alwayssubmit whole metadata. Maximum of 64 parameters are allowed in the object.\nMax properties: 64" - ), - ] - ] - - -MembershipInput = MembershipDict - - Meta = dict[str, str] -MetaInput = typing.Mapping[str, str] """ A set of key-value pairs that you can attach to an object. This can be useful for storing additional informationabout the object in a structured format. @@ -4732,28 +2849,6 @@ class Timestamps(pydantic.BaseModel): """ -class TimestampsDict(typing_extensions.TypedDict, total=False): - created_at: typing_extensions.Required[ - typing_extensions.Annotated[ - datetime.datetime, - typing_extensions.Doc( - "The date and time when the resource was created. This is a string as defined in [RFC 3339, section 5.6](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6).\nRead only" - ), - ] - ] - updated_at: typing_extensions.Required[ - typing_extensions.Annotated[ - datetime.datetime, - typing_extensions.Doc( - "The date and time when the resource was last updated. This is a string as defined in [RFC 3339, section 5.6](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6).\nReadonly" - ), - ] - ] - - -TimestampsInput = TimestampsDict - - class Merchant(pydantic.BaseModel): """ Merchant is a schema definition. @@ -4868,132 +2963,6 @@ class Merchant(pydantic.BaseModel): """ -class MerchantDict(typing_extensions.TypedDict, total=False): - country: typing_extensions.Required[ - typing_extensions.Annotated[ - CountryCodeInput, - typing_extensions.Doc( - "An [ISO3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2)\ncountry code. This definition users `oneOf` with a two-character string\ntype to allow for support of future countries in client code.\nMin length: 2\nMax length: 2\nPattern: ^[A-Z]{2}$" - ), - ] - ] - created_at: typing_extensions.Required[ - typing_extensions.Annotated[ - datetime.datetime, - typing_extensions.Doc( - "The date and time when the resource was created. This is a string as defined in [RFC 3339, section 5.6](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6).\nRead only" - ), - ] - ] - default_currency: typing_extensions.Required[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "Three-letter [ISO currency code](https://en.wikipedia.org/wiki/ISO_4217) representing the default currency forthe account.\nRead only\nMin length: 3\nMax length: 3" - ), - ] - ] - default_locale: typing_extensions.Required[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "Merchant's default locale, represented as a BCP47 [RFC5646](https://datatracker.ietf.org/doc/html/rfc5646) languagetag. This is typically an ISO 639-1 Alpha-2 [ISO639‑1](https://www.iso.org/iso-639-language-code) language codein lowercase and an ISO 3166-1 Alpha-2 [ISO3166‑1](https://www.iso.org/iso-3166-country-codes.html) countrycode in uppercase, separated by a dash. For example, en-US or fr-CA.\nIn multilingual countries this is the merchant's preferred locale out of those, that are officially spoken inthe country. In a countries with a single official language this will match the official language.\nMin length: 2\nMax length: 5" - ), - ] - ] - merchant_code: typing_extensions.Required[ - typing_extensions.Annotated[ - str, typing_extensions.Doc("Short unique identifier for the merchant.\nRead only") - ] - ] - updated_at: typing_extensions.Required[ - typing_extensions.Annotated[ - datetime.datetime, - typing_extensions.Doc( - "The date and time when the resource was last updated. This is a string as defined in [RFC 3339, section 5.6](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6).\nReadonly" - ), - ] - ] - alias: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "A user-facing name of the merchant account for use in dashboards and other user-facing applications. Forcustomer-facing business name see `merchant.business_profile`." - ), - ] - ] - avatar: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "A user-facing small-format logo for use in dashboards and other user-facing applications. For customer-facing brandingsee `merchant.business_profile.branding`.\nFormat: uri" - ), - ] - ] - business_profile: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - BusinessProfileInput, - typing_extensions.Doc( - "Business information about the merchant. This information will be visible to the merchant's customers." - ), - ] - ] - business_type: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "The business type.\n* `sole_trader`: The business is run by an self-employed individual.\n* `company`: The business is run as a company with one or more shareholders\n* `partnership`: The business is run as a company with two or more shareholders that can be also other legalentities\n* `non_profit`: The business is run as a nonprofit organization that operates for public or social benefit\n* `government_entity`: The business is state owned and operated" - ), - ] - ] - change_status: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - ChangeStatusInput, - typing_extensions.Doc( - "Reflects the status of changes submitted through the `PATCH` endpoints for the merchant or persons. If somechanges have not been applied yet, the status will be `pending`. If all changes have been applied, the status`done`.\nThe status is only returned after write operations or on read endpoints when the `version` query parameter isprovided.\nRead only" - ), - ] - ] - classic: typing_extensions.NotRequired[ClassicMerchantIdentifiersInput] - company: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - CompanyInput, - typing_extensions.Doc( - "Information about the company or business. This is legal information that is used for verification.\nCompany documentation: https://developer.sumup.com/tools/glossary/merchant#company" - ), - ] - ] - meta: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - MetaInput, - typing_extensions.Doc( - "A set of key-value pairs that you can attach to an object. This can be useful for storing additional informationabout the object in a structured format.\n\n**Warning**: Updating Meta will overwrite the existing data. Make sure to always include the complete JSON object." - ), - ] - ] - organization_id: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, typing_extensions.Doc("ID of the organization the merchant belongs to (if any).") - ] - ] - sandbox: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - bool, typing_extensions.Doc("True if the merchant is a sandbox for testing.") - ] - ] - version: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - VersionInput, - typing_extensions.Doc( - "The version of the resource. The version reflects a specific change submitted to the API via one of the `PATCH`endpoints." - ), - ] - ] - - -MerchantInput = MerchantDict - - class NotFoundErrors(pydantic.BaseModel): """ NotFoundErrors is a schema definition. @@ -5005,17 +2974,6 @@ class NotFoundErrors(pydantic.BaseModel): """ -class NotFoundErrorsDict(typing_extensions.TypedDict, total=False): - detail: typing_extensions.Required[ - typing_extensions.Annotated[ - str, typing_extensions.Doc("Fuller message giving context to error") - ] - ] - - -NotFoundErrorsInput = NotFoundErrorsDict - - class NotFound(pydantic.BaseModel): """ 404 Not Found @@ -5024,13 +2982,6 @@ class NotFound(pydantic.BaseModel): errors: NotFoundErrors -class NotFoundDict(typing_extensions.TypedDict, total=False): - errors: typing_extensions.Required[NotFoundErrorsInput] - - -NotFoundInput = NotFoundDict - - class Permissions(pydantic.BaseModel): """ Permissions assigned to an operator or user. @@ -5047,19 +2998,7 @@ class Permissions(pydantic.BaseModel): refund_transactions: bool -class PermissionsDict(typing_extensions.TypedDict, total=False): - admin: typing_extensions.Required[bool] - create_moto_payments: typing_extensions.Required[bool] - create_referral: typing_extensions.Required[bool] - full_transaction_history_view: typing_extensions.Required[bool] - refund_transactions: typing_extensions.Required[bool] - - -PermissionsInput = PermissionsDict - - OperatorAccountType = typing.Union[typing.Literal["normal", "operator"], str] -OperatorAccountTypeInput = OperatorAccountType class Operator(pydantic.BaseModel): @@ -5096,38 +3035,7 @@ class Operator(pydantic.BaseModel): nickname: typing.Optional[str] = None -class OperatorDict(typing_extensions.TypedDict, total=False): - account_type: typing_extensions.Required[OperatorAccountTypeInput] - created_at: typing_extensions.Required[ - typing_extensions.Annotated[ - datetime.datetime, - typing_extensions.Doc("The timestamp of when the operator was created."), - ] - ] - disabled: typing_extensions.Required[bool] - id: typing_extensions.Required[ - typing_extensions.Annotated[int, typing_extensions.Doc("Format: int32")] - ] - permissions: typing_extensions.Required[ - typing_extensions.Annotated[ - PermissionsInput, typing_extensions.Doc("Permissions assigned to an operator or user.") - ] - ] - updated_at: typing_extensions.Required[ - typing_extensions.Annotated[ - datetime.datetime, - typing_extensions.Doc("The timestamp of when the operator was last updated."), - ] - ] - username: typing_extensions.Required[str] - nickname: typing_extensions.NotRequired[str] - - -OperatorInput = OperatorDict - - PaymentInstrumentResponseType = typing.Union[typing.Literal["card"], str] -PaymentInstrumentResponseTypeInput = PaymentInstrumentResponseType class PaymentInstrumentResponseCard(pydantic.BaseModel): @@ -5149,28 +3057,6 @@ class PaymentInstrumentResponseCard(pydantic.BaseModel): """ -class PaymentInstrumentResponseCardDict(typing_extensions.TypedDict, total=False): - last_4_digits: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "Last 4 digits of the payment card number.\nRead only\nMin length: 4\nMax length: 4" - ), - ] - ] - type: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - CardTypeInput, - typing_extensions.Doc( - "Issuing card network of the payment card used for the transaction." - ), - ] - ] - - -PaymentInstrumentResponseCardInput = PaymentInstrumentResponseCardDict - - class PaymentInstrumentResponse(pydantic.BaseModel): """ Payment Instrument Response @@ -5210,54 +3096,6 @@ class PaymentInstrumentResponse(pydantic.BaseModel): """ -class PaymentInstrumentResponseDict(typing_extensions.TypedDict, total=False): - active: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - bool, - typing_extensions.Doc( - "Indicates whether the payment instrument is active and can be used for payments. To deactivate it, send a`DELETE` request to the resource endpoint.\nRead only\nDefault: true" - ), - ] - ] - card: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - PaymentInstrumentResponseCardInput, - typing_extensions.Doc("Details of the payment card."), - ] - ] - created_at: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - datetime.datetime, - typing_extensions.Doc( - "Creation date of payment instrument. Response format expressed according to [ISO8601](https://en.wikipedia.org/wiki/ISO_8601) code." - ), - ] - ] - mandate: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - MandateResponseInput, - typing_extensions.Doc("Details of the mandate linked to the saved payment instrument."), - ] - ] - token: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "Unique token identifying the saved payment card for a customer.\nRead only" - ), - ] - ] - type: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - PaymentInstrumentResponseTypeInput, - typing_extensions.Doc("Type of the payment instrument."), - ] - ] - - -PaymentInstrumentResponseInput = PaymentInstrumentResponseDict - - class Problem(pydantic.BaseModel): """ A RFC 9457 problem details object. @@ -5323,47 +3161,6 @@ def additional_properties(self, value: dict[str, object]) -> None: object.__setattr__(self, "__pydantic_extra__", dict(value)) -class ProblemDict(typing_extensions.TypedDict, total=False): - type: typing_extensions.Required[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc("A URI reference that identifies the problem type.\nFormat: uri"), - ] - ] - detail: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "A human-readable explanation specific to this occurrence of the problem." - ), - ] - ] - instance: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "A URI reference that identifies the specific occurrence of the problem.\nFormat: uri" - ), - ] - ] - status: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - int, - typing_extensions.Doc( - "The HTTP status code generated by the origin server for this occurrence of the problem." - ), - ] - ] - title: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, typing_extensions.Doc("A short, human-readable summary of the problem type.") - ] - ] - - -ProblemInput = ProblemDict - - ProcessCheckoutPaymentType = typing.Union[ typing.Literal["apple_pay", "bancontact", "blik", "boleto", "card", "google_pay", "ideal"], str ] @@ -5573,54 +3370,7 @@ class Product(pydantic.BaseModel): """ -class ProductDict(typing_extensions.TypedDict, total=False): - name: typing_extensions.NotRequired[ - typing_extensions.Annotated[str, typing_extensions.Doc("Product name.")] - ] - price: typing_extensions.NotRequired[ - typing_extensions.Annotated[float, typing_extensions.Doc("Product price.\nFormat: decimal")] - ] - price_label: typing_extensions.NotRequired[ - typing_extensions.Annotated[str, typing_extensions.Doc("Product description.")] - ] - price_with_vat: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - float, typing_extensions.Doc("Product price incl. VAT.\nFormat: decimal") - ] - ] - quantity: typing_extensions.NotRequired[ - typing_extensions.Annotated[int, typing_extensions.Doc("Product quantity.")] - ] - single_vat_amount: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - float, typing_extensions.Doc("VAT amount for a single product.\nFormat: decimal") - ] - ] - total_price: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - float, typing_extensions.Doc("Quantity x product price.\nFormat: decimal") - ] - ] - total_with_vat: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - float, typing_extensions.Doc("Total price incl. VAT.\nFormat: decimal") - ] - ] - vat_amount: typing_extensions.NotRequired[ - typing_extensions.Annotated[float, typing_extensions.Doc("VAT amount.\nFormat: decimal")] - ] - vat_rate: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - float, typing_extensions.Doc("VAT percentage.\nFormat: decimal") - ] - ] - - -ProductInput = ProductDict - - ReaderDeviceModel = typing.Union[typing.Literal["solo", "virtual-solo"], str] -ReaderDeviceModelInput = ReaderDeviceModel class ReaderDevice(pydantic.BaseModel): @@ -5639,25 +3389,6 @@ class ReaderDevice(pydantic.BaseModel): """ -class ReaderDeviceDict(typing_extensions.TypedDict, total=False): - identifier: typing_extensions.Required[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "A unique identifier of the physical device (e.g. serial number)." - ), - ] - ] - model: typing_extensions.Required[ - typing_extensions.Annotated[ - ReaderDeviceModelInput, typing_extensions.Doc("Identifier of the model of the device.") - ] - ] - - -ReaderDeviceInput = ReaderDeviceDict - - ReaderId = str ReaderIdInput = str """ @@ -5676,7 +3407,6 @@ class ReaderDeviceDict(typing_extensions.TypedDict, total=False): """ ReaderStatus = typing.Union[typing.Literal["expired", "paired", "processing", "unknown"], str] -ReaderStatusInput = ReaderStatus class Reader(pydantic.BaseModel): @@ -5741,72 +3471,7 @@ class Reader(pydantic.BaseModel): """ -class ReaderDict(typing_extensions.TypedDict, total=False): - created_at: typing_extensions.Required[ - typing_extensions.Annotated[ - datetime.datetime, - typing_extensions.Doc("The timestamp of when the reader was created."), - ] - ] - device: typing_extensions.Required[ - typing_extensions.Annotated[ - ReaderDeviceInput, - typing_extensions.Doc("Information about the underlying physical device."), - ] - ] - id: typing_extensions.Required[ - typing_extensions.Annotated[ - ReaderIdInput, - typing_extensions.Doc( - "Unique identifier of the object.\n\nNote that this identifies the instance of the physical devices pairing with your SumUp account. If you [delete](https://developer.sumup.com/api/readers/delete-reader) areader, and pair the device again, the ID will be different. Do not use this ID to refer to a physical device.\nMinlength: 30\nMax length: 30" - ), - ] - ] - name: typing_extensions.Required[ - typing_extensions.Annotated[ - ReaderNameInput, - typing_extensions.Doc( - "Custom human-readable, user-defined name for easier identification of the reader.\nMax length: 500" - ), - ] - ] - status: typing_extensions.Required[ - typing_extensions.Annotated[ - ReaderStatusInput, - typing_extensions.Doc( - "The status of the reader object gives information about the current state of the reader.\n\nPossible values:\n\n- `unknown` - The reader status is unknown.\n- `processing` - The reader is created and waits for the physical device to confirm the pairing.\n- `paired` - The reader is paired with a merchant account and can be used with SumUp APIs.\n- `expired` - The pairing is expired and no longer usable with the account. The resource needs to get recreated." - ), - ] - ] - updated_at: typing_extensions.Required[ - typing_extensions.Annotated[ - datetime.datetime, - typing_extensions.Doc("The timestamp of when the reader was last updated."), - ] - ] - metadata: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - MetadataInput, - typing_extensions.Doc( - "Set of user-defined key-value pairs attached to the object. Partial updates are not supported. When updating, alwayssubmit whole metadata. Maximum of 64 parameters are allowed in the object.\nMax properties: 64" - ), - ] - ] - service_account_id: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "Identifier of the system-managed service account associated with this reader.\nPresent only for readers that are already paired.\nThis field is currently in beta and may change.\nFormat: uuid" - ), - ] - ] - - -ReaderInput = ReaderDict - - ReaderCheckoutStatusChangePayloadStatus = typing.Union[typing.Literal["failed", "successful"], str] -ReaderCheckoutStatusChangePayloadStatusInput = ReaderCheckoutStatusChangePayloadStatus class ReaderCheckoutStatusChangePayload(pydantic.BaseModel): @@ -5838,39 +3503,6 @@ class ReaderCheckoutStatusChangePayload(pydantic.BaseModel): """ -class ReaderCheckoutStatusChangePayloadDict(typing_extensions.TypedDict, total=False): - client_transaction_id: typing_extensions.Required[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "The unique client transaction id. It is the same returned by the Checkout.\nFormat: uuid" - ), - ] - ] - merchant_code: typing_extensions.Required[ - typing_extensions.Annotated[ - str, typing_extensions.Doc("The merchant code associated with the transaction.") - ] - ] - status: typing_extensions.Required[ - typing_extensions.Annotated[ - ReaderCheckoutStatusChangePayloadStatusInput, - typing_extensions.Doc("The current status of the transaction."), - ] - ] - transaction_id: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "The transaction id. Deprecated: use `client_transaction_id` instead.\nFormat: uuid\nDeprecated: this operation is deprecated" - ), - ] - ] - - -ReaderCheckoutStatusChangePayloadInput = ReaderCheckoutStatusChangePayloadDict - - class ReaderCheckoutStatusChange(pydantic.BaseModel): """ The callback payload containing the status change of the Reader Checkout. @@ -5898,30 +3530,6 @@ class ReaderCheckoutStatusChange(pydantic.BaseModel): """ -class ReaderCheckoutStatusChangeDict(typing_extensions.TypedDict, total=False): - event_type: typing_extensions.Required[ - typing_extensions.Annotated[str, typing_extensions.Doc("Type of event.")] - ] - id: typing_extensions.Required[ - typing_extensions.Annotated[ - str, typing_extensions.Doc("Unique identifier for the event.\nFormat: uuid") - ] - ] - payload: typing_extensions.Required[ - typing_extensions.Annotated[ - ReaderCheckoutStatusChangePayloadInput, typing_extensions.Doc("The event payload.") - ] - ] - timestamp: typing_extensions.Required[ - typing_extensions.Annotated[ - datetime.datetime, typing_extensions.Doc("Timestamp of the event.") - ] - ] - - -ReaderCheckoutStatusChangeInput = ReaderCheckoutStatusChangeDict - - ReaderPairingCode = str ReaderPairingCodeInput = str """ @@ -5947,18 +3555,6 @@ class ReceiptCard(pydantic.BaseModel): """ -class ReceiptCardDict(typing_extensions.TypedDict, total=False): - last_4_digits: typing_extensions.NotRequired[ - typing_extensions.Annotated[str, typing_extensions.Doc("Card last 4 digits.")] - ] - type: typing_extensions.NotRequired[ - typing_extensions.Annotated[str, typing_extensions.Doc("Card Scheme.")] - ] - - -ReceiptCardInput = ReceiptCardDict - - class ReceiptEvent(pydantic.BaseModel): """ Transaction event details as rendered on the receipt. @@ -6012,51 +3608,6 @@ class ReceiptEvent(pydantic.BaseModel): """ -class ReceiptEventDict(typing_extensions.TypedDict, total=False): - amount: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, typing_extensions.Doc("Amount of the event.\nFormat: double") - ] - ] - id: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - EventIdInput, - typing_extensions.Doc("Unique ID of the transaction event.\nFormat: int64"), - ] - ] - receipt_no: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, typing_extensions.Doc("Receipt number associated with the event.") - ] - ] - status: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - EventStatusInput, - typing_extensions.Doc( - "Status of the transaction event.\n\nNot every value is used for every event type.\n\n- `PENDING`: The event has been created but is not final yet. Used for events that are still being processed andwhose final outcome is not known yet.\n- `SCHEDULED`: The event is planned for a future payout cycle but has not been executed yet. This applies topayout events before money is actually sent out.\n- `RECONCILED`: The underlying payment has been matched with settlement data and is ready to continue through payoutprocessing, but the funds have not been paid out yet. This applies to payout events.\n- `PAID_OUT`: The payout event has been completed and the funds were included in a merchant payout.\n- `REFUNDED`: A refund event has been accepted and recorded in the refund flow. This is the status returned forrefund events once the transaction amount is being or has been returned to the payer.\n- `SUCCESSFUL`: The event completed successfully. Use this as the generic terminal success status for event typesthat do not expose a more specific business outcome such as `PAID_OUT` or `REFUNDED`.\n- `FAILED`: The event could not be completed. Typical examples are a payout that could not be executed oran event that was rejected during processing." - ), - ] - ] - timestamp: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - datetime.datetime, typing_extensions.Doc("Date and time of the transaction event.") - ] - ] - transaction_id: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - TransactionIdInput, typing_extensions.Doc("Unique ID of the transaction.") - ] - ] - type: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - EventTypeInput, typing_extensions.Doc("Type of the transaction event.") - ] - ] - - -ReceiptEventInput = ReceiptEventDict - - class ReceiptMerchantDataMerchantProfileAddress(pydantic.BaseModel): """ ReceiptMerchantDataMerchantProfileAddress is a schema definition. @@ -6081,21 +3632,6 @@ class ReceiptMerchantDataMerchantProfileAddress(pydantic.BaseModel): region_name: typing.Optional[str] = None -class ReceiptMerchantDataMerchantProfileAddressDict(typing_extensions.TypedDict, total=False): - address_line1: typing_extensions.NotRequired[str] - address_line2: typing_extensions.NotRequired[str] - city: typing_extensions.NotRequired[str] - country: typing_extensions.NotRequired[str] - country_en_name: typing_extensions.NotRequired[str] - country_native_name: typing_extensions.NotRequired[str] - landline: typing_extensions.NotRequired[str] - post_code: typing_extensions.NotRequired[str] - region_name: typing_extensions.NotRequired[str] - - -ReceiptMerchantDataMerchantProfileAddressInput = ReceiptMerchantDataMerchantProfileAddressDict - - class ReceiptMerchantDataMerchantProfile(pydantic.BaseModel): """ Merchant profile details displayed on the receipt. @@ -6118,20 +3654,6 @@ class ReceiptMerchantDataMerchantProfile(pydantic.BaseModel): website: typing.Optional[str] = None -class ReceiptMerchantDataMerchantProfileDict(typing_extensions.TypedDict, total=False): - address: typing_extensions.NotRequired[ReceiptMerchantDataMerchantProfileAddressInput] - business_name: typing_extensions.NotRequired[str] - company_registration_number: typing_extensions.NotRequired[str] - email: typing_extensions.NotRequired[str] - language: typing_extensions.NotRequired[str] - merchant_code: typing_extensions.NotRequired[str] - vat_id: typing_extensions.NotRequired[str] - website: typing_extensions.NotRequired[str] - - -ReceiptMerchantDataMerchantProfileInput = ReceiptMerchantDataMerchantProfileDict - - class ReceiptMerchantData(pydantic.BaseModel): """ Receipt merchant data @@ -6148,23 +3670,6 @@ class ReceiptMerchantData(pydantic.BaseModel): """ -class ReceiptMerchantDataDict(typing_extensions.TypedDict, total=False): - locale: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, typing_extensions.Doc("Locale used for rendering localized receipt fields.") - ] - ] - merchant_profile: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - ReceiptMerchantDataMerchantProfileInput, - typing_extensions.Doc("Merchant profile details displayed on the receipt."), - ] - ] - - -ReceiptMerchantDataInput = ReceiptMerchantDataDict - - class ReceiptReader(pydantic.BaseModel): """ Card reader details displayed on the receipt. @@ -6181,20 +3686,7 @@ class ReceiptReader(pydantic.BaseModel): """ -class ReceiptReaderDict(typing_extensions.TypedDict, total=False): - code: typing_extensions.NotRequired[ - typing_extensions.Annotated[str, typing_extensions.Doc("Reader serial number.")] - ] - type: typing_extensions.NotRequired[ - typing_extensions.Annotated[str, typing_extensions.Doc("Reader type.")] - ] - - -ReceiptReaderInput = ReceiptReaderDict - - ReceiptTransactionProcessA = typing.Union[typing.Literal["CREDIT", "DEBIT"], str] -ReceiptTransactionProcessAInput = ReceiptTransactionProcessA class ReceiptTransactionProduct(pydantic.BaseModel): @@ -6261,50 +3753,6 @@ class ReceiptTransactionProduct(pydantic.BaseModel): """ -class ReceiptTransactionProductDict(typing_extensions.TypedDict, total=False): - description: typing_extensions.NotRequired[ - typing_extensions.Annotated[str, typing_extensions.Doc("Product description")] - ] - name: typing_extensions.NotRequired[ - typing_extensions.Annotated[str, typing_extensions.Doc("Product name")] - ] - price: typing_extensions.NotRequired[ - typing_extensions.Annotated[str, typing_extensions.Doc("Product price\nFormat: double")] - ] - price_with_vat: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, typing_extensions.Doc("Product price including VAT\nFormat: double") - ] - ] - quantity: typing_extensions.NotRequired[ - typing_extensions.Annotated[int, typing_extensions.Doc("Product quantity\nFormat: int64")] - ] - single_vat_amount: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, typing_extensions.Doc("VAT amount for a single product\nFormat: double") - ] - ] - total_price: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, typing_extensions.Doc("Quantity x product price\nFormat: double") - ] - ] - total_with_vat: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, typing_extensions.Doc("Total price including VAT\nFormat: double") - ] - ] - vat_amount: typing_extensions.NotRequired[ - typing_extensions.Annotated[str, typing_extensions.Doc("VAT amount\nFormat: double")] - ] - vat_rate: typing_extensions.NotRequired[ - typing_extensions.Annotated[str, typing_extensions.Doc("VAT rate\nFormat: double")] - ] - - -ReceiptTransactionProductInput = ReceiptTransactionProductDict - - class ReceiptTransactionVatRate(pydantic.BaseModel): """ ReceiptTransactionVatRate is a schema definition. @@ -6331,24 +3779,6 @@ class ReceiptTransactionVatRate(pydantic.BaseModel): """ -class ReceiptTransactionVatRateDict(typing_extensions.TypedDict, total=False): - gross: typing_extensions.NotRequired[ - typing_extensions.Annotated[float, typing_extensions.Doc("Gross")] - ] - net: typing_extensions.NotRequired[ - typing_extensions.Annotated[float, typing_extensions.Doc("Net")] - ] - rate: typing_extensions.NotRequired[ - typing_extensions.Annotated[float, typing_extensions.Doc("Rate")] - ] - vat: typing_extensions.NotRequired[ - typing_extensions.Annotated[float, typing_extensions.Doc("Vat")] - ] - - -ReceiptTransactionVatRateInput = ReceiptTransactionVatRateDict - - class ReceiptTransaction(pydantic.BaseModel): """ Transaction information. @@ -6455,92 +3885,7 @@ class ReceiptTransaction(pydantic.BaseModel): """ -class ReceiptTransactionDict(typing_extensions.TypedDict, total=False): - amount: typing_extensions.NotRequired[ - typing_extensions.Annotated[str, typing_extensions.Doc("Transaction amount.")] - ] - card: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - ReceiptCardInput, - typing_extensions.Doc("Payment card details displayed on the receipt."), - ] - ] - card_reader: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - ReceiptReaderInput, - typing_extensions.Doc("Card reader details displayed on the receipt."), - ] - ] - currency: typing_extensions.NotRequired[ - typing_extensions.Annotated[str, typing_extensions.Doc("Transaction currency.")] - ] - entry_mode: typing_extensions.NotRequired[ - typing_extensions.Annotated[str, typing_extensions.Doc("Transaction entry mode.")] - ] - events: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - typing.Sequence[ReceiptEventInput], typing_extensions.Doc("Events") - ] - ] - installments_count: typing_extensions.NotRequired[ - typing_extensions.Annotated[int, typing_extensions.Doc("Number of installments.")] - ] - merchant_code: typing_extensions.NotRequired[ - typing_extensions.Annotated[str, typing_extensions.Doc("Merchant code.")] - ] - payment_type: typing_extensions.NotRequired[ - typing_extensions.Annotated[str, typing_extensions.Doc("Transaction type.")] - ] - process_as: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - ReceiptTransactionProcessAInput, typing_extensions.Doc("Debit/Credit.") - ] - ] - products: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - typing.Sequence[ReceiptTransactionProductInput], typing_extensions.Doc("Products") - ] - ] - receipt_no: typing_extensions.NotRequired[ - typing_extensions.Annotated[str, typing_extensions.Doc("Receipt number")] - ] - status: typing_extensions.NotRequired[ - typing_extensions.Annotated[str, typing_extensions.Doc("Transaction processing status.")] - ] - timestamp: typing_extensions.NotRequired[ - typing_extensions.Annotated[datetime.datetime, typing_extensions.Doc("Time created at.")] - ] - tip_amount: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, typing_extensions.Doc("Tip amount (included in transaction amount).") - ] - ] - transaction_code: typing_extensions.NotRequired[ - typing_extensions.Annotated[str, typing_extensions.Doc("Transaction code.")] - ] - transaction_id: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - TransactionIdInput, typing_extensions.Doc("Unique ID of the transaction.") - ] - ] - vat_amount: typing_extensions.NotRequired[ - typing_extensions.Annotated[str, typing_extensions.Doc("Transaction VAT amount.")] - ] - vat_rates: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - typing.Sequence[ReceiptTransactionVatRateInput], typing_extensions.Doc("Vat rates.") - ] - ] - verification_method: typing_extensions.NotRequired[ - typing_extensions.Annotated[str, typing_extensions.Doc("Cardholder verification method.")] - ] - - -ReceiptTransactionInput = ReceiptTransactionDict - - ReceiptEmvData = dict[str, object] -ReceiptEmvDataInput = typing.Mapping[str, object] """ EMV-specific metadata returned for card-present payments. """ @@ -6560,16 +3905,6 @@ class ReceiptAcquirerData(pydantic.BaseModel): tid: typing.Optional[str] = None -class ReceiptAcquirerDataDict(typing_extensions.TypedDict, total=False): - authorization_code: typing_extensions.NotRequired[str] - local_time: typing_extensions.NotRequired[str] - return_code: typing_extensions.NotRequired[str] - tid: typing_extensions.NotRequired[str] - - -ReceiptAcquirerDataInput = ReceiptAcquirerDataDict - - class Receipt(pydantic.BaseModel): """ Receipt details for a transaction. @@ -6596,34 +3931,6 @@ class Receipt(pydantic.BaseModel): """ -class ReceiptDict(typing_extensions.TypedDict, total=False): - acquirer_data: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - ReceiptAcquirerDataInput, - typing_extensions.Doc("Acquirer-specific metadata related to the card authorization."), - ] - ] - emv_data: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - ReceiptEmvDataInput, - typing_extensions.Doc("EMV-specific metadata returned for card-present payments."), - ] - ] - merchant_data: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - ReceiptMerchantDataInput, typing_extensions.Doc("Receipt merchant data") - ] - ] - transaction_data: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - ReceiptTransactionInput, typing_extensions.Doc("Transaction information.") - ] - ] - - -ReceiptInput = ReceiptDict - - class Role(pydantic.BaseModel): """ A custom role that can be used to assign set of permissions to members. @@ -6672,57 +3979,9 @@ class Role(pydantic.BaseModel): """ -class RoleDict(typing_extensions.TypedDict, total=False): - created_at: typing_extensions.Required[ - typing_extensions.Annotated[ - datetime.datetime, typing_extensions.Doc("The timestamp of when the role was created.") - ] - ] - id: typing_extensions.Required[ - typing_extensions.Annotated[str, typing_extensions.Doc("Unique identifier of the role.")] - ] - is_predefined: typing_extensions.Required[ - typing_extensions.Annotated[ - bool, typing_extensions.Doc("True if the role is provided by SumUp.") - ] - ] - name: typing_extensions.Required[ - typing_extensions.Annotated[str, typing_extensions.Doc("User-defined name of the role.")] - ] - permissions: typing_extensions.Required[ - typing_extensions.Annotated[ - typing.Sequence[str], - typing_extensions.Doc("List of permission granted by this role.\nMax items: 100"), - ] - ] - updated_at: typing_extensions.Required[ - typing_extensions.Annotated[ - datetime.datetime, - typing_extensions.Doc("The timestamp of when the role was last updated."), - ] - ] - description: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, typing_extensions.Doc("User-defined description of the role.") - ] - ] - metadata: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - MetadataInput, - typing_extensions.Doc( - "Set of user-defined key-value pairs attached to the object. Partial updates are not supported. When updating, alwayssubmit whole metadata. Maximum of 64 parameters are allowed in the object.\nMax properties: 64" - ), - ] - ] - - -RoleInput = RoleDict - - StatusResponseDataConnectionType = typing.Union[ typing.Literal["Wi-Fi", "btle", "edge", "gprs", "lte", "umts", "usb"], str ] -StatusResponseDataConnectionTypeInput = StatusResponseDataConnectionType StatusResponseDataState = typing.Union[ typing.Literal[ @@ -6735,10 +3994,8 @@ class RoleDict(typing_extensions.TypedDict, total=False): ], str, ] -StatusResponseDataStateInput = StatusResponseDataState StatusResponseDataStatus = typing.Union[typing.Literal["OFFLINE", "ONLINE"], str] -StatusResponseDataStatusInput = StatusResponseDataStatus class StatusResponseData(pydantic.BaseModel): @@ -6784,45 +4041,6 @@ class StatusResponseData(pydantic.BaseModel): """ -class StatusResponseDataDict(typing_extensions.TypedDict, total=False): - status: typing_extensions.Required[ - typing_extensions.Annotated[ - StatusResponseDataStatusInput, typing_extensions.Doc("Status of a device") - ] - ] - battery_level: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - float, typing_extensions.Doc("Battery level percentage\nMin: 0\nMax: 100") - ] - ] - battery_temperature: typing_extensions.NotRequired[ - typing_extensions.Annotated[int, typing_extensions.Doc("Battery temperature in Celsius")] - ] - connection_type: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - StatusResponseDataConnectionTypeInput, - typing_extensions.Doc("Type of connection used by the device"), - ] - ] - firmware_version: typing_extensions.NotRequired[ - typing_extensions.Annotated[str, typing_extensions.Doc("Firmware version of the device")] - ] - last_activity: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - datetime.datetime, - typing_extensions.Doc("Timestamp of the last activity from the device"), - ] - ] - state: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - StatusResponseDataStateInput, typing_extensions.Doc("Latest state of the device") - ] - ] - - -StatusResponseDataInput = StatusResponseDataDict - - class StatusResponse(pydantic.BaseModel): """ Status of a device @@ -6831,13 +4049,6 @@ class StatusResponse(pydantic.BaseModel): data: StatusResponseData -class StatusResponseDict(typing_extensions.TypedDict, total=False): - data: typing_extensions.Required[StatusResponseDataInput] - - -StatusResponseInput = StatusResponseDict - - class TransactionEvent(pydantic.BaseModel): """ Detailed information about a transaction event. @@ -6898,65 +4109,9 @@ class TransactionEvent(pydantic.BaseModel): """ -class TransactionEventDict(typing_extensions.TypedDict, total=False): - amount: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - float, typing_extensions.Doc("Amount of the event.\nFormat: decimal") - ] - ] - date: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - datetime.date, - typing_extensions.Doc("Date when the transaction event occurred.\nFormat: date"), - ] - ] - due_date: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - datetime.date, - typing_extensions.Doc("Date when the transaction event is due to occur.\nFormat: date"), - ] - ] - event_type: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - EventTypeInput, typing_extensions.Doc("Type of the transaction event.") - ] - ] - id: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - EventIdInput, - typing_extensions.Doc("Unique ID of the transaction event.\nFormat: int64"), - ] - ] - installment_number: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - int, - typing_extensions.Doc( - "Consecutive number of the installment that is paid. Applicable only payout events, i.e. `event_type = PAYOUT`." - ), - ] - ] - status: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - EventStatusInput, - typing_extensions.Doc( - "Status of the transaction event.\n\nNot every value is used for every event type.\n\n- `PENDING`: The event has been created but is not final yet. Used for events that are still being processed andwhose final outcome is not known yet.\n- `SCHEDULED`: The event is planned for a future payout cycle but has not been executed yet. This applies topayout events before money is actually sent out.\n- `RECONCILED`: The underlying payment has been matched with settlement data and is ready to continue through payoutprocessing, but the funds have not been paid out yet. This applies to payout events.\n- `PAID_OUT`: The payout event has been completed and the funds were included in a merchant payout.\n- `REFUNDED`: A refund event has been accepted and recorded in the refund flow. This is the status returned forrefund events once the transaction amount is being or has been returned to the payer.\n- `SUCCESSFUL`: The event completed successfully. Use this as the generic terminal success status for event typesthat do not expose a more specific business outcome such as `PAID_OUT` or `REFUNDED`.\n- `FAILED`: The event could not be completed. Typical examples are a payout that could not be executed oran event that was rejected during processing." - ), - ] - ] - timestamp: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - datetime.datetime, typing_extensions.Doc("Date and time of the transaction event.") - ] - ] - - -TransactionEventInput = TransactionEventDict - - TransactionMixinHistoryPayoutPlan = typing.Union[ typing.Literal["ACCELERATED_INSTALLMENT", "SINGLE_PAYMENT", "TRUE_INSTALLMENT"], str ] -TransactionMixinHistoryPayoutPlanInput = TransactionMixinHistoryPayoutPlan class TransactionMixinHistory(pydantic.BaseModel): @@ -6985,53 +4140,13 @@ class TransactionMixinHistory(pydantic.BaseModel): """ -class TransactionMixinHistoryDict(typing_extensions.TypedDict, total=False): - payout_plan: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - TransactionMixinHistoryPayoutPlanInput, - typing_extensions.Doc( - "Payout plan of the registered user at the time when the transaction was made." - ), - ] - ] - payouts_received: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - int, - typing_extensions.Doc( - "Number of payouts that are made to the registered user specified in the `user` property." - ), - ] - ] - payouts_total: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - int, - typing_extensions.Doc( - "Total number of payouts to the registered user specified in the `user` property." - ), - ] - ] - product_summary: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "Short description of the payment. The value is taken from the `description` property of the related checkout resource." - ), - ] - ] - - -TransactionMixinHistoryInput = TransactionMixinHistoryDict - - TransactionFullStatus = typing.Union[ typing.Literal["CANCELLED", "FAILED", "PENDING", "SUCCESSFUL"], str ] -TransactionFullStatusInput = TransactionFullStatus TransactionFullPayoutPlan = typing.Union[ typing.Literal["ACCELERATED_INSTALLMENT", "SINGLE_PAYMENT", "TRUE_INSTALLMENT"], str ] -TransactionFullPayoutPlanInput = TransactionFullPayoutPlan TransactionFullSimplePaymentType = typing.Union[ typing.Literal[ @@ -7052,7 +4167,6 @@ class TransactionMixinHistoryDict(typing_extensions.TypedDict, total=False): ], str, ] -TransactionFullSimplePaymentTypeInput = TransactionFullSimplePaymentType TransactionFullVerificationMethod = typing.Union[ typing.Literal[ @@ -7060,13 +4174,10 @@ class TransactionMixinHistoryDict(typing_extensions.TypedDict, total=False): ], str, ] -TransactionFullVerificationMethodInput = TransactionFullVerificationMethod TransactionFullPayoutType = typing.Union[typing.Literal["BANK_ACCOUNT", "PREPAID_CARD"], str] -TransactionFullPayoutTypeInput = TransactionFullPayoutType TransactionFullProcessA = typing.Union[typing.Literal["CREDIT", "DEBIT"], str] -TransactionFullProcessAInput = TransactionFullProcessA class TransactionFullVatRate(pydantic.BaseModel): @@ -7099,36 +4210,6 @@ class TransactionFullVatRate(pydantic.BaseModel): """ -class TransactionFullVatRateDict(typing_extensions.TypedDict, total=False): - gross: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - float, - typing_extensions.Doc( - "Gross amount of products having this VAT rate applied.\nFormat: decimal" - ), - ] - ] - net: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - float, - typing_extensions.Doc( - "NET amount of products having this VAT rate applied.\nFormat: decimal" - ), - ] - ] - rate: typing_extensions.NotRequired[ - typing_extensions.Annotated[float, typing_extensions.Doc("VAT rate.\nFormat: decimal")] - ] - vat: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - float, typing_extensions.Doc("VAT amount of this rate applied.\nFormat: decimal") - ] - ] - - -TransactionFullVatRateInput = TransactionFullVatRateDict - - TransactionFullSimpleStatus = typing.Union[ typing.Literal[ "CANCELLED", @@ -7144,7 +4225,6 @@ class TransactionFullVatRateDict(typing_extensions.TypedDict, total=False): ], str, ] -TransactionFullSimpleStatusInput = TransactionFullSimpleStatus class TransactionFullLocation(pydantic.BaseModel): @@ -7172,36 +4252,6 @@ class TransactionFullLocation(pydantic.BaseModel): """ -class TransactionFullLocationDict(typing_extensions.TypedDict, total=False): - horizontal_accuracy: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - HorizontalAccuracyInput, - typing_extensions.Doc( - "Indication of the precision of the geographical position received from the payment terminal." - ), - ] - ] - lat: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - LatInput, - typing_extensions.Doc( - "Latitude value from the coordinates of the payment location (as received from the payment terminal reader).\nMin: 0\nMax: 90" - ), - ] - ] - lon: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - LonInput, - typing_extensions.Doc( - "Longitude value from the coordinates of the payment location (as received from the payment terminal reader).\nMin: 0\nMax: 180" - ), - ] - ] - - -TransactionFullLocationInput = TransactionFullLocationDict - - class TransactionFull(pydantic.BaseModel): """ Full transaction resource with checkout, payout, and event details. @@ -7438,302 +4488,17 @@ class TransactionFull(pydantic.BaseModel): """ -class TransactionFullDict(typing_extensions.TypedDict, total=False): - amount: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - float, typing_extensions.Doc("Total amount of the transaction.") - ] - ] - auth_code: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "Authorization code for the transaction sent by the payment card issuer or bank. Applicable only to card payments." - ), - ] - ] - card: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - CardResponseInput, typing_extensions.Doc("Details of the payment card.") - ] - ] - client_transaction_id: typing_extensions.NotRequired[ - typing_extensions.Annotated[str, typing_extensions.Doc("Client transaction id.")] - ] - currency: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - CurrencyInput, - typing_extensions.Doc( - "Three-letter [ISO4217](https://en.wikipedia.org/wiki/ISO_4217) code of the currency for the amount. Currently supportedcurrency values are enumerated above." - ), - ] - ] - device_info: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - DeviceInput, - typing_extensions.Doc("Details of the device used to create the transaction."), - ] - ] - elv_account: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - ElvCardAccountInput, - typing_extensions.Doc( - "Details of the ELV card account associated with the transaction." - ), - ] - ] - entry_mode: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - EntryModeInput, typing_extensions.Doc("Entry mode of the payment details.") - ] - ] - events: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - typing.Sequence[EventInput], - typing_extensions.Doc("Compact list of events related to the transaction."), - ] - ] - fee_amount: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - float, typing_extensions.Doc("Transaction SumUp total fee amount.\nFormat: decimal") - ] - ] - foreign_transaction_id: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, typing_extensions.Doc("External/foreign transaction id (passed by clients).") - ] - ] - horizontal_accuracy: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - HorizontalAccuracyInput, - typing_extensions.Doc( - "Indication of the precision of the geographical position received from the payment terminal." - ), - ] - ] - id: typing_extensions.NotRequired[ - typing_extensions.Annotated[str, typing_extensions.Doc("Unique ID of the transaction.")] - ] - installments_count: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - int, - typing_extensions.Doc( - "Current number of the installment for deferred payments.\nMin: 1" - ), - ] - ] - lat: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - LatInput, - typing_extensions.Doc( - "Latitude value from the coordinates of the payment location (as received from the payment terminal reader).\nMin: 0\nMax: 90" - ), - ] - ] - links: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - typing.Sequence[LinkInput], - typing_extensions.Doc("List of hyperlinks for accessing related resources."), - ] - ] - local_time: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - datetime.datetime, - typing_extensions.Doc("Local date and time of the creation of the transaction."), - ] - ] - location: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - TransactionFullLocationInput, - typing_extensions.Doc( - "Details of the payment location as received from the payment terminal." - ), - ] - ] - lon: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - LonInput, - typing_extensions.Doc( - "Longitude value from the coordinates of the payment location (as received from the payment terminal reader).\nMin: 0\nMax: 180" - ), - ] - ] - merchant_code: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "Unique code of the registered merchant to whom the payment is made." - ), - ] - ] - merchant_id: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - int, typing_extensions.Doc("SumUp merchant internal Id.\nFormat: int64") - ] - ] - payment_type: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - PaymentTypeInput, typing_extensions.Doc("Payment type used for the transaction.") - ] - ] - payout_date: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - datetime.date, typing_extensions.Doc("The date of the payout.\nFormat: date") - ] - ] - payout_plan: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - TransactionFullPayoutPlanInput, - typing_extensions.Doc( - "Payout plan of the registered user at the time when the transaction was made." - ), - ] - ] - payout_type: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - TransactionFullPayoutTypeInput, - typing_extensions.Doc("Payout type for the transaction."), - ] - ] - payouts_received: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - int, - typing_extensions.Doc( - "Number of payouts that are made to the registered user specified in the `user` property." - ), - ] - ] - payouts_total: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - int, - typing_extensions.Doc( - "Total number of payouts to the registered user specified in the `user` property." - ), - ] - ] - process_as: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - TransactionFullProcessAInput, typing_extensions.Doc("Debit/Credit.") - ] - ] - product_summary: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "Short description of the payment. The value is taken from the `description` property of the related checkout resource." - ), - ] - ] - products: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - typing.Sequence[ProductInput], - typing_extensions.Doc( - "List of products from the merchant's catalogue for which the transaction serves as a payment." - ), - ] - ] - simple_payment_type: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - TransactionFullSimplePaymentTypeInput, - typing_extensions.Doc("Simple name of the payment type."), - ] - ] - simple_status: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - TransactionFullSimpleStatusInput, - typing_extensions.Doc( - "High-level status of the transaction from the merchant's perspective.\n\n- `PENDING`: The payment has been initiated and is still being processed. A final outcome is not available yet.\n-`SUCCESSFUL`: The payment was completed successfully.\n- `PAID_OUT`: The payment was completed successfully and the funds have already been included in a payout tothe merchant.\n- `FAILED`: The payment did not complete successfully.\n- `CANCELLED`: The payment was cancelled or reversed and is no longer payable or payable to the merchant.\n- `CANCEL_FAILED`: An attempt to cancel or reverse the payment was not completed successfully.\n- `REFUNDED`: The payment was refunded in full or in part.\n- `REFUND_FAILED`: An attempt to refund the payment was not completed successfully.\n- `CHARGEBACK`: The payment was subject to a chargeback.\n- `NON_COLLECTION`: The amount could not be collected from the merchant after a chargeback or related adjustment." - ), - ] - ] - status: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - TransactionFullStatusInput, typing_extensions.Doc("Current status of the transaction.") - ] - ] - tax_enabled: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - bool, - typing_extensions.Doc( - "Indicates whether tax deduction is enabled for the transaction." - ), - ] - ] - timestamp: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - datetime.datetime, - typing_extensions.Doc( - "Date and time of the creation of the transaction. Response format expressed according to [ISO8601](https://en.wikipedia.org/wiki/ISO_8601) code." - ), - ] - ] - tip_amount: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - float, typing_extensions.Doc("Amount of the tip (out of the total transaction amount).") - ] - ] - transaction_code: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "Transaction code returned by the acquirer/processing entity after processing the transaction." - ), - ] - ] - transaction_events: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - typing.Sequence[TransactionEventInput], - typing_extensions.Doc("Detailed list of events related to the transaction."), - ] - ] - username: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "Email address of the registered user (merchant) to whom the payment is made.\nFormat: email" - ), - ] - ] - vat_amount: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - float, - typing_extensions.Doc( - "Amount of the applicable VAT (out of the total transaction amount)." - ), - ] - ] - vat_rates: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - typing.Sequence[TransactionFullVatRateInput], - typing_extensions.Doc("List of VAT rates applicable to the transaction."), - ] - ] - verification_method: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - TransactionFullVerificationMethodInput, - typing_extensions.Doc("Verification method used for the transaction."), - ] - ] - - -TransactionFullInput = TransactionFullDict - - TransactionHistoryStatus = typing.Union[ typing.Literal["CANCELLED", "FAILED", "PENDING", "SUCCESSFUL"], str ] -TransactionHistoryStatusInput = TransactionHistoryStatus TransactionHistoryPayoutPlan = typing.Union[ typing.Literal["ACCELERATED_INSTALLMENT", "SINGLE_PAYMENT", "TRUE_INSTALLMENT"], str ] -TransactionHistoryPayoutPlanInput = TransactionHistoryPayoutPlan TransactionHistoryType = typing.Union[typing.Literal["CHARGE_BACK", "PAYMENT", "REFUND"], str] -TransactionHistoryTypeInput = TransactionHistoryType TransactionHistoryPayoutType = typing.Union[typing.Literal["BANK_ACCOUNT", "PREPAID_CARD"], str] -TransactionHistoryPayoutTypeInput = TransactionHistoryPayoutType class TransactionHistory(pydantic.BaseModel): @@ -7846,144 +4611,6 @@ class TransactionHistory(pydantic.BaseModel): """ -class TransactionHistoryDict(typing_extensions.TypedDict, total=False): - amount: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - float, typing_extensions.Doc("Total amount of the transaction.") - ] - ] - card_type: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - CardTypeInput, - typing_extensions.Doc( - "Issuing card network of the payment card used for the transaction." - ), - ] - ] - client_transaction_id: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, typing_extensions.Doc("Client-specific ID of the transaction.") - ] - ] - currency: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - CurrencyInput, - typing_extensions.Doc( - "Three-letter [ISO4217](https://en.wikipedia.org/wiki/ISO_4217) code of the currency for the amount. Currently supportedcurrency values are enumerated above." - ), - ] - ] - id: typing_extensions.NotRequired[ - typing_extensions.Annotated[str, typing_extensions.Doc("Unique ID of the transaction.")] - ] - installments_count: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - int, - typing_extensions.Doc( - "Current number of the installment for deferred payments.\nMin: 1" - ), - ] - ] - payment_type: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - PaymentTypeInput, typing_extensions.Doc("Payment type used for the transaction.") - ] - ] - payout_date: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - datetime.date, typing_extensions.Doc("Payout date (if paid out at once).\nFormat: date") - ] - ] - payout_plan: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - TransactionHistoryPayoutPlanInput, - typing_extensions.Doc( - "Payout plan of the registered user at the time when the transaction was made." - ), - ] - ] - payout_type: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - TransactionHistoryPayoutTypeInput, typing_extensions.Doc("Payout type.") - ] - ] - payouts_received: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - int, - typing_extensions.Doc( - "Number of payouts that are made to the registered user specified in the `user` property." - ), - ] - ] - payouts_total: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - int, - typing_extensions.Doc( - "Total number of payouts to the registered user specified in the `user` property." - ), - ] - ] - product_summary: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "Short description of the payment. The value is taken from the `description` property of the related checkout resource." - ), - ] - ] - refunded_amount: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - float, typing_extensions.Doc("Total refunded amount.\nFormat: decimal") - ] - ] - status: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - TransactionHistoryStatusInput, - typing_extensions.Doc("Current status of the transaction."), - ] - ] - timestamp: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - datetime.datetime, - typing_extensions.Doc( - "Date and time of the creation of the transaction. Response format expressed according to [ISO8601](https://en.wikipedia.org/wiki/ISO_8601) code." - ), - ] - ] - transaction_code: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "Transaction code returned by the acquirer/processing entity after processing the transaction." - ), - ] - ] - transaction_id: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - TransactionIdInput, typing_extensions.Doc("Unique ID of the transaction.") - ] - ] - type: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - TransactionHistoryTypeInput, - typing_extensions.Doc( - "Type of the transaction for the registered user specified in the `user` property." - ), - ] - ] - user: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - str, - typing_extensions.Doc( - "Email address of the registered user (merchant) to whom the payment is made.\nFormat: email" - ), - ] - ] - - -TransactionHistoryInput = TransactionHistoryDict - - class TransactionsHistoryLink(pydantic.BaseModel): """ Hypermedia link used for transaction history pagination. @@ -8000,22 +4627,9 @@ class TransactionsHistoryLink(pydantic.BaseModel): """ -class TransactionsHistoryLinkDict(typing_extensions.TypedDict, total=False): - href: typing_extensions.Required[ - typing_extensions.Annotated[str, typing_extensions.Doc("Location.")] - ] - rel: typing_extensions.Required[ - typing_extensions.Annotated[str, typing_extensions.Doc("Relation.")] - ] - - -TransactionsHistoryLinkInput = TransactionsHistoryLinkDict - - UnauthorizedErrorsType = typing.Union[ typing.Literal["INVALID_ACCESS_TOKEN", "INVALID_PASSWORD"], str ] -UnauthorizedErrorsTypeInput = UnauthorizedErrorsType class UnauthorizedErrors(pydantic.BaseModel): @@ -8034,35 +4648,9 @@ class UnauthorizedErrors(pydantic.BaseModel): """ -class UnauthorizedErrorsDict(typing_extensions.TypedDict, total=False): - detail: typing_extensions.Required[ - typing_extensions.Annotated[ - str, typing_extensions.Doc("Fuller message giving context to error") - ] - ] - type: typing_extensions.NotRequired[ - typing_extensions.Annotated[ - UnauthorizedErrorsTypeInput, - typing_extensions.Doc( - "Key indicating type of error. Present only for typed 401 responses (e.g. invalid token, invalid password). Absentfor generic unauthorized responses." - ), - ] - ] - - -UnauthorizedErrorsInput = UnauthorizedErrorsDict - - class Unauthorized(pydantic.BaseModel): """ 401 Unauthorized """ errors: UnauthorizedErrors - - -class UnauthorizedDict(typing_extensions.TypedDict, total=False): - errors: typing_extensions.Required[UnauthorizedErrorsInput] - - -UnauthorizedInput = UnauthorizedDict diff --git a/tests/test_request_bodies.py b/tests/test_request_bodies.py index ff12c610..abd6987c 100644 --- a/tests/test_request_bodies.py +++ b/tests/test_request_bodies.py @@ -1,5 +1,6 @@ import datetime import json +import warnings import httpx @@ -81,7 +82,9 @@ def handler(request: httpx.Request) -> httpx.Response: ) sdk = sdk_factory(handler) - response = sdk.subaccounts.update_sub_account(1, nickname=None) + with warnings.catch_warnings(): + warnings.simplefilter("ignore", DeprecationWarning) + response = sdk.subaccounts.update_sub_account(1, nickname=None) assert response.nickname is None assert "request" in captured_request