"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""

from __future__ import annotations
from .airline import Airline, AirlineTypedDict
from .antifrauddecision import AntiFraudDecision
from .avsresponsecode import AVSResponseCode
from .cartitem import CartItem, CartItemTypedDict
from .cvvresponsecode import CVVResponseCode
from .giftcardredemption import GiftCardRedemption, GiftCardRedemptionTypedDict
from .giftcardservice import GiftCardService, GiftCardServiceTypedDict
from .instrumenttype import InstrumentType
from .method import Method
from .recipient import Recipient, RecipientTypedDict
from .shippingdetails import ShippingDetails, ShippingDetailsTypedDict
from .statementdescriptor import StatementDescriptor, StatementDescriptorTypedDict
from .transactionbuyer import TransactionBuyer, TransactionBuyerTypedDict
from .transactionintent import TransactionIntent
from .transactionintentoutcome import TransactionIntentOutcome
from .transactionpaymentmethod import (
    TransactionPaymentMethod,
    TransactionPaymentMethodTypedDict,
)
from .transactionpaymentservice import (
    TransactionPaymentService,
    TransactionPaymentServiceTypedDict,
)
from .transactionpaymentsource import TransactionPaymentSource
from .transactionstatus import TransactionStatus
from .transactionthreedsecuresummary import (
    TransactionThreeDSecureSummary,
    TransactionThreeDSecureSummaryTypedDict,
)
from datetime import datetime
from gr4vy.types import BaseModel, Nullable, OptionalNullable, UNSET, UNSET_SENTINEL
from gr4vy.utils import validate_const, validate_open_enum
import pydantic
from pydantic import model_serializer
from pydantic.functional_validators import AfterValidator, PlainValidator
from typing import Dict, List, Literal, Optional
from typing_extensions import Annotated, NotRequired, TypedDict


class TransactionTypedDict(TypedDict):
    r"""A full transaction resource."""

    id: str
    r"""The ID for the transaction."""
    reconciliation_id: str
    r"""The base62 encoded transaction ID. This represents a shorter version of this transaction's `id` which is sent to payment services, anti-fraud services, and other connectors. You can use this ID to reconcile a payment service's transaction against our system. This ID is sent instead of the transaction ID because not all services support 36 digit identifiers."""
    merchant_account_id: str
    r"""The ID of the merchant account this transaction belongs to."""
    currency: str
    r"""The currency code for this transaction."""
    amount: int
    r"""The total amount for this transaction across all funding sources including gift cards."""
    status: TransactionStatus
    authorized_amount: int
    r"""The amount for this transaction that has been authorized for the `payment_method`. This can be less than the `amount` if gift cards were used."""
    captured_amount: int
    r"""The total amount captured for this transaction, in the smallest currency unit (for example, cents or pence). This can be the full value of the `authorized_amount` or less."""
    refunded_amount: int
    r"""The total amount refunded for this transaction, in the smallest currency unit (for example, cents or pence). This can be the full value of the `captured_amount` or less."""
    settled_amount: int
    r"""The net amount settled for this transaction, in the smallest currency unit (for example, cents or pence)."""
    settled: bool
    r"""Indicates whether this transaction has been settled."""
    intent: TransactionIntent
    gift_card_redemptions: List[GiftCardRedemptionTypedDict]
    r"""The gift cards redeemed for this transaction."""
    created_at: datetime
    r"""The date and time when the transaction was created, in ISO 8601 format."""
    updated_at: datetime
    r"""The date and time when the transaction was last updated, in ISO 8601 format."""
    disputed: bool
    r"""Indicates whether this transaction has been disputed."""
    payment_source: TransactionPaymentSource
    r"""The way payment method information made it to this transaction."""
    merchant_initiated: bool
    r"""Indicates whether the transaction was initiated by the merchant or the customer."""
    is_subsequent_payment: bool
    r"""Indicates whether the transaction represents a subsequent payment or an initial one."""
    intent_outcome: TransactionIntentOutcome
    multi_tender: bool
    r"""The outcome of the original intent of a transaction. This allows you to understand if the intent of the transaction (e.g. `capture` or `authorize`) has been achieved when dealing with multiple payment instruments."""
    account_funding_transaction: bool
    r"""Marks the transaction as an AFT. Requires the payment service to support this feature, and might `recipient` and `buyer` data"""
    type: Literal["transaction"]
    r"""Always `transaction`."""
    settled_currency: NotRequired[Nullable[str]]
    r"""The ISO 4217 currency code of this transaction's settlement."""
    country: NotRequired[Nullable[str]]
    r"""The 2-letter ISO 3166-1 alpha-2 country code for the transaction. Used to filter payment services for processing."""
    external_identifier: NotRequired[Nullable[str]]
    r"""An external identifier that can be used to match the transaction against your own records."""
    payment_method: NotRequired[Nullable[TransactionPaymentMethodTypedDict]]
    r"""The payment method used for this transaction."""
    method: NotRequired[Nullable[Method]]
    r"""The method used for the transaction."""
    instrument_type: NotRequired[Nullable[InstrumentType]]
    r"""The name of the instrument used to process the transaction."""
    error_code: NotRequired[Nullable[str]]
    r"""The standardized error code set by Gr4vy."""
    payment_service: NotRequired[Nullable[TransactionPaymentServiceTypedDict]]
    r"""The payment service used for this transaction."""
    pending_review: NotRequired[bool]
    r"""Whether a manual anti fraud review is pending with an anti fraud service."""
    buyer: NotRequired[Nullable[TransactionBuyerTypedDict]]
    r"""The buyer used for this transaction."""
    raw_response_code: NotRequired[Nullable[str]]
    r"""This is the response code received from the payment service. This can be set to any value and is not standardized across different payment services."""
    raw_response_description: NotRequired[Nullable[str]]
    r"""This is the response description received from the payment service. This can be set to any value and is not standardized across different payment services."""
    shipping_details: NotRequired[Nullable[ShippingDetailsTypedDict]]
    r"""The shipping details associated with the transaction."""
    checkout_session_id: NotRequired[Nullable[str]]
    r"""The identifier for the checkout session this transaction is associated with."""
    gift_card_service: NotRequired[Nullable[GiftCardServiceTypedDict]]
    r"""The gift card service used for this transaction."""
    airline: NotRequired[Nullable[AirlineTypedDict]]
    r"""Contains information about an airline travel, if applicable."""
    auth_response_code: NotRequired[Nullable[str]]
    r"""This is the response description received from the processor."""
    avs_response_code: NotRequired[Nullable[AVSResponseCode]]
    r"""The response code received from the payment service for the Address Verification Check (AVS). This code is mapped to a standardized Gr4vy AVS response code."""
    cvv_response_code: NotRequired[Nullable[CVVResponseCode]]
    r"""The response code received from the payment service for the Card Verification Value (CVV). This code is mapped to a standardized Gr4vy CVV response code."""
    anti_fraud_decision: NotRequired[Nullable[AntiFraudDecision]]
    r"""The mapped decision received from the anti-fraud service. In case of a review decision this field is not updated once the review is resolved."""
    cart_items: NotRequired[Nullable[List[CartItemTypedDict]]]
    r"""An array of cart items that represents the line items of a transaction."""
    statement_descriptor: NotRequired[Nullable[StatementDescriptorTypedDict]]
    r"""The statement descriptor is the text to be shown on the buyer's statements."""
    scheme_transaction_id: NotRequired[Nullable[str]]
    r"""An identifier for the transaction used by the scheme itself, when available."""
    three_d_secure: NotRequired[Nullable[TransactionThreeDSecureSummaryTypedDict]]
    r"""The 3-D Secure data that was sent to the payment service for the transaction."""
    payment_service_transaction_id: NotRequired[Nullable[str]]
    r"""The payment service's unique ID for the transaction."""
    additional_identifiers: NotRequired[Dict[str, Nullable[str]]]
    r"""A list of additional identifiers that we may keep track of to manage this transaction. This may include the authorization ID, capture ID, and processor ID, as well as an undefined list of additional identifiers."""
    metadata: NotRequired[Nullable[Dict[str, str]]]
    r"""Additional information about the transaction stored as key-value pairs."""
    authorized_at: NotRequired[Nullable[datetime]]
    r"""The date this transaction was authorized at."""
    captured_at: NotRequired[Nullable[datetime]]
    r"""The date this transaction was captured at."""
    voided_at: NotRequired[Nullable[datetime]]
    r"""The date this transaction was voided at."""
    canceled_at: NotRequired[Nullable[datetime]]
    r"""The date this transaction was canceled at."""
    approval_expires_at: NotRequired[Nullable[datetime]]
    r"""The date this transaction's approval URL will expire at."""
    buyer_approval_timedout_at: NotRequired[Nullable[datetime]]
    r"""The date this transaction's approval timed out at."""
    recipient: NotRequired[Nullable[RecipientTypedDict]]
    r"""The recipient of any account to account funding. For use with AFTs."""
    merchant_advice_code: NotRequired[Nullable[str]]
    r"""An optional merchant advice code which provides insight into the type of transaction or reason why the payment failed."""
    installment_count: NotRequired[Nullable[int]]
    r"""The number of installments for this transaction, if applicable."""
    tax_amount: NotRequired[Nullable[int]]
    r"""The sales tax amount for this transaction, represented as a monetary amount in the smallest currency unit for the given currency, for example `1299` cents to create an authorization for `$12.99`"""
    merchant_tax_id: NotRequired[Nullable[str]]
    r"""Merchant tax ID (for example, EIN or VAT number)."""
    customer_reference_number: NotRequired[Nullable[str]]
    r"""Customer code or reference."""
    amount_includes_tax: NotRequired[Nullable[bool]]
    r"""Whether the tax is included in the amount."""
    supplier_order_number: NotRequired[Nullable[str]]
    r"""The merchant's unique identifier for the sales order or invoice."""
    duty_amount: NotRequired[Nullable[int]]
    r"""Total charges for import/export duties."""
    shipping_amount: NotRequired[Nullable[int]]
    r"""Total shipping amount."""


class Transaction(BaseModel):
    r"""A full transaction resource."""

    id: str
    r"""The ID for the transaction."""

    reconciliation_id: str
    r"""The base62 encoded transaction ID. This represents a shorter version of this transaction's `id` which is sent to payment services, anti-fraud services, and other connectors. You can use this ID to reconcile a payment service's transaction against our system. This ID is sent instead of the transaction ID because not all services support 36 digit identifiers."""

    merchant_account_id: str
    r"""The ID of the merchant account this transaction belongs to."""

    currency: str
    r"""The currency code for this transaction."""

    amount: int
    r"""The total amount for this transaction across all funding sources including gift cards."""

    status: Annotated[TransactionStatus, PlainValidator(validate_open_enum(False))]

    authorized_amount: int
    r"""The amount for this transaction that has been authorized for the `payment_method`. This can be less than the `amount` if gift cards were used."""

    captured_amount: int
    r"""The total amount captured for this transaction, in the smallest currency unit (for example, cents or pence). This can be the full value of the `authorized_amount` or less."""

    refunded_amount: int
    r"""The total amount refunded for this transaction, in the smallest currency unit (for example, cents or pence). This can be the full value of the `captured_amount` or less."""

    settled_amount: int
    r"""The net amount settled for this transaction, in the smallest currency unit (for example, cents or pence)."""

    settled: bool
    r"""Indicates whether this transaction has been settled."""

    intent: Annotated[TransactionIntent, PlainValidator(validate_open_enum(False))]

    gift_card_redemptions: List[GiftCardRedemption]
    r"""The gift cards redeemed for this transaction."""

    created_at: datetime
    r"""The date and time when the transaction was created, in ISO 8601 format."""

    updated_at: datetime
    r"""The date and time when the transaction was last updated, in ISO 8601 format."""

    disputed: bool
    r"""Indicates whether this transaction has been disputed."""

    payment_source: Annotated[
        TransactionPaymentSource, PlainValidator(validate_open_enum(False))
    ]
    r"""The way payment method information made it to this transaction."""

    merchant_initiated: bool
    r"""Indicates whether the transaction was initiated by the merchant or the customer."""

    is_subsequent_payment: bool
    r"""Indicates whether the transaction represents a subsequent payment or an initial one."""

    intent_outcome: Annotated[
        TransactionIntentOutcome, PlainValidator(validate_open_enum(False))
    ]

    multi_tender: bool
    r"""The outcome of the original intent of a transaction. This allows you to understand if the intent of the transaction (e.g. `capture` or `authorize`) has been achieved when dealing with multiple payment instruments."""

    account_funding_transaction: bool
    r"""Marks the transaction as an AFT. Requires the payment service to support this feature, and might `recipient` and `buyer` data"""

    TYPE: Annotated[
        Annotated[
            Optional[Literal["transaction"]],
            AfterValidator(validate_const("transaction")),
        ],
        pydantic.Field(alias="type"),
    ] = "transaction"
    r"""Always `transaction`."""

    settled_currency: OptionalNullable[str] = UNSET
    r"""The ISO 4217 currency code of this transaction's settlement."""

    country: OptionalNullable[str] = UNSET
    r"""The 2-letter ISO 3166-1 alpha-2 country code for the transaction. Used to filter payment services for processing."""

    external_identifier: OptionalNullable[str] = UNSET
    r"""An external identifier that can be used to match the transaction against your own records."""

    payment_method: OptionalNullable[TransactionPaymentMethod] = UNSET
    r"""The payment method used for this transaction."""

    method: Annotated[
        OptionalNullable[Method], PlainValidator(validate_open_enum(False))
    ] = UNSET
    r"""The method used for the transaction."""

    instrument_type: Annotated[
        OptionalNullable[InstrumentType], PlainValidator(validate_open_enum(False))
    ] = UNSET
    r"""The name of the instrument used to process the transaction."""

    error_code: OptionalNullable[str] = UNSET
    r"""The standardized error code set by Gr4vy."""

    payment_service: OptionalNullable[TransactionPaymentService] = UNSET
    r"""The payment service used for this transaction."""

    pending_review: Optional[bool] = False
    r"""Whether a manual anti fraud review is pending with an anti fraud service."""

    buyer: OptionalNullable[TransactionBuyer] = UNSET
    r"""The buyer used for this transaction."""

    raw_response_code: OptionalNullable[str] = UNSET
    r"""This is the response code received from the payment service. This can be set to any value and is not standardized across different payment services."""

    raw_response_description: OptionalNullable[str] = UNSET
    r"""This is the response description received from the payment service. This can be set to any value and is not standardized across different payment services."""

    shipping_details: OptionalNullable[ShippingDetails] = UNSET
    r"""The shipping details associated with the transaction."""

    checkout_session_id: OptionalNullable[str] = UNSET
    r"""The identifier for the checkout session this transaction is associated with."""

    gift_card_service: OptionalNullable[GiftCardService] = UNSET
    r"""The gift card service used for this transaction."""

    airline: OptionalNullable[Airline] = UNSET
    r"""Contains information about an airline travel, if applicable."""

    auth_response_code: OptionalNullable[str] = UNSET
    r"""This is the response description received from the processor."""

    avs_response_code: Annotated[
        OptionalNullable[AVSResponseCode], PlainValidator(validate_open_enum(False))
    ] = UNSET
    r"""The response code received from the payment service for the Address Verification Check (AVS). This code is mapped to a standardized Gr4vy AVS response code."""

    cvv_response_code: Annotated[
        OptionalNullable[CVVResponseCode], PlainValidator(validate_open_enum(False))
    ] = UNSET
    r"""The response code received from the payment service for the Card Verification Value (CVV). This code is mapped to a standardized Gr4vy CVV response code."""

    anti_fraud_decision: Annotated[
        OptionalNullable[AntiFraudDecision], PlainValidator(validate_open_enum(False))
    ] = UNSET
    r"""The mapped decision received from the anti-fraud service. In case of a review decision this field is not updated once the review is resolved."""

    cart_items: OptionalNullable[List[CartItem]] = UNSET
    r"""An array of cart items that represents the line items of a transaction."""

    statement_descriptor: OptionalNullable[StatementDescriptor] = UNSET
    r"""The statement descriptor is the text to be shown on the buyer's statements."""

    scheme_transaction_id: OptionalNullable[str] = UNSET
    r"""An identifier for the transaction used by the scheme itself, when available."""

    three_d_secure: OptionalNullable[TransactionThreeDSecureSummary] = UNSET
    r"""The 3-D Secure data that was sent to the payment service for the transaction."""

    payment_service_transaction_id: OptionalNullable[str] = UNSET
    r"""The payment service's unique ID for the transaction."""

    additional_identifiers: Optional[Dict[str, Nullable[str]]] = None
    r"""A list of additional identifiers that we may keep track of to manage this transaction. This may include the authorization ID, capture ID, and processor ID, as well as an undefined list of additional identifiers."""

    metadata: OptionalNullable[Dict[str, str]] = UNSET
    r"""Additional information about the transaction stored as key-value pairs."""

    authorized_at: OptionalNullable[datetime] = UNSET
    r"""The date this transaction was authorized at."""

    captured_at: OptionalNullable[datetime] = UNSET
    r"""The date this transaction was captured at."""

    voided_at: OptionalNullable[datetime] = UNSET
    r"""The date this transaction was voided at."""

    canceled_at: OptionalNullable[datetime] = UNSET
    r"""The date this transaction was canceled at."""

    approval_expires_at: OptionalNullable[datetime] = UNSET
    r"""The date this transaction's approval URL will expire at."""

    buyer_approval_timedout_at: OptionalNullable[datetime] = UNSET
    r"""The date this transaction's approval timed out at."""

    recipient: OptionalNullable[Recipient] = UNSET
    r"""The recipient of any account to account funding. For use with AFTs."""

    merchant_advice_code: OptionalNullable[str] = UNSET
    r"""An optional merchant advice code which provides insight into the type of transaction or reason why the payment failed."""

    installment_count: OptionalNullable[int] = UNSET
    r"""The number of installments for this transaction, if applicable."""

    tax_amount: OptionalNullable[int] = UNSET
    r"""The sales tax amount for this transaction, represented as a monetary amount in the smallest currency unit for the given currency, for example `1299` cents to create an authorization for `$12.99`"""

    merchant_tax_id: OptionalNullable[str] = UNSET
    r"""Merchant tax ID (for example, EIN or VAT number)."""

    customer_reference_number: OptionalNullable[str] = UNSET
    r"""Customer code or reference."""

    amount_includes_tax: OptionalNullable[bool] = UNSET
    r"""Whether the tax is included in the amount."""

    supplier_order_number: OptionalNullable[str] = UNSET
    r"""The merchant's unique identifier for the sales order or invoice."""

    duty_amount: OptionalNullable[int] = UNSET
    r"""Total charges for import/export duties."""

    shipping_amount: OptionalNullable[int] = UNSET
    r"""Total shipping amount."""

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = [
            "type",
            "settled_currency",
            "country",
            "external_identifier",
            "payment_method",
            "method",
            "instrument_type",
            "error_code",
            "payment_service",
            "pending_review",
            "buyer",
            "raw_response_code",
            "raw_response_description",
            "shipping_details",
            "checkout_session_id",
            "gift_card_service",
            "airline",
            "auth_response_code",
            "avs_response_code",
            "cvv_response_code",
            "anti_fraud_decision",
            "cart_items",
            "statement_descriptor",
            "scheme_transaction_id",
            "three_d_secure",
            "payment_service_transaction_id",
            "additional_identifiers",
            "metadata",
            "authorized_at",
            "captured_at",
            "voided_at",
            "canceled_at",
            "approval_expires_at",
            "buyer_approval_timedout_at",
            "recipient",
            "merchant_advice_code",
            "installment_count",
            "tax_amount",
            "merchant_tax_id",
            "customer_reference_number",
            "amount_includes_tax",
            "supplier_order_number",
            "duty_amount",
            "shipping_amount",
        ]
        nullable_fields = [
            "settled_currency",
            "country",
            "external_identifier",
            "payment_method",
            "method",
            "instrument_type",
            "error_code",
            "payment_service",
            "buyer",
            "raw_response_code",
            "raw_response_description",
            "shipping_details",
            "checkout_session_id",
            "gift_card_service",
            "airline",
            "auth_response_code",
            "avs_response_code",
            "cvv_response_code",
            "anti_fraud_decision",
            "cart_items",
            "statement_descriptor",
            "scheme_transaction_id",
            "three_d_secure",
            "payment_service_transaction_id",
            "metadata",
            "authorized_at",
            "captured_at",
            "voided_at",
            "canceled_at",
            "approval_expires_at",
            "buyer_approval_timedout_at",
            "recipient",
            "merchant_advice_code",
            "installment_count",
            "tax_amount",
            "merchant_tax_id",
            "customer_reference_number",
            "amount_includes_tax",
            "supplier_order_number",
            "duty_amount",
            "shipping_amount",
        ]
        null_default_fields = []

        serialized = handler(self)

        m = {}

        for n, f in type(self).model_fields.items():
            k = f.alias or n
            val = serialized.get(k)
            serialized.pop(k, None)

            optional_nullable = k in optional_fields and k in nullable_fields
            is_set = (
                self.__pydantic_fields_set__.intersection({n})
                or k in null_default_fields
            )  # pylint: disable=no-member

            if val is not None and val != UNSET_SENTINEL:
                m[k] = val
            elif val != UNSET_SENTINEL and (
                not k in optional_fields or (optional_nullable and is_set)
            ):
                m[k] = val

        return m
