Skip to content

Payment Gateways

The internet_payment_gateways adapter provides integration with Iranian Shaparak payment gateways. Supports both Parsian (SOAP/WSDL) and Saman (REST/JSON) protocols.

Parsian Shaparak

Parsian Shaparak adapter using the SOAP protocol with WSDL service definitions.

Ports

Abstract port interface defining the Parsian Shaparak adapter contract.

archipy.adapters.internet_payment_gateways.ir.parsian.ports.PaymentRequestDTO

Bases: BaseDTO

DTO for initiating a payment request.

Source code in archipy/adapters/internet_payment_gateways/ir/parsian/ports.py
class PaymentRequestDTO(BaseDTO):
    """DTO for initiating a payment request."""

    amount: int = Field(..., gt=0, description="Transaction amount in IRR")
    order_id: int = Field(..., gt=0, description="Unique order identifier")
    callback_url: HttpUrl = Field(..., description="URL to redirect after payment")
    additional_data: str | None = Field(None, description="Additional transaction data")
    originator: str | None = Field(None, description="Transaction originator")

archipy.adapters.internet_payment_gateways.ir.parsian.ports.PaymentRequestDTO.amount class-attribute instance-attribute

amount: int = Field(
    ..., gt=0, description="Transaction amount in IRR"
)

archipy.adapters.internet_payment_gateways.ir.parsian.ports.PaymentRequestDTO.order_id class-attribute instance-attribute

order_id: int = Field(
    ..., gt=0, description="Unique order identifier"
)

archipy.adapters.internet_payment_gateways.ir.parsian.ports.PaymentRequestDTO.callback_url class-attribute instance-attribute

callback_url: HttpUrl = Field(
    ..., description="URL to redirect after payment"
)

archipy.adapters.internet_payment_gateways.ir.parsian.ports.PaymentRequestDTO.additional_data class-attribute instance-attribute

additional_data: str | None = Field(
    None, description="Additional transaction data"
)

archipy.adapters.internet_payment_gateways.ir.parsian.ports.PaymentRequestDTO.originator class-attribute instance-attribute

originator: str | None = Field(
    None, description="Transaction originator"
)

archipy.adapters.internet_payment_gateways.ir.parsian.ports.PaymentRequestDTO.model_config class-attribute instance-attribute

model_config = ConfigDict(
    extra="ignore",
    validate_default=True,
    from_attributes=True,
    frozen=True,
    str_strip_whitespace=True,
    arbitrary_types_allowed=True,
)

archipy.adapters.internet_payment_gateways.ir.parsian.ports.PaymentResponseDTO

Bases: BaseDTO

DTO for payment response.

Source code in archipy/adapters/internet_payment_gateways/ir/parsian/ports.py
class PaymentResponseDTO(BaseDTO):
    """DTO for payment response."""

    token: int | None = Field(None, description="Transaction token")
    status: int | None = Field(None, description="Transaction status code")
    message: str | None = Field(None, description="Status message or error description")

archipy.adapters.internet_payment_gateways.ir.parsian.ports.PaymentResponseDTO.token class-attribute instance-attribute

token: int | None = Field(
    None, description="Transaction token"
)

archipy.adapters.internet_payment_gateways.ir.parsian.ports.PaymentResponseDTO.status class-attribute instance-attribute

status: int | None = Field(
    None, description="Transaction status code"
)

archipy.adapters.internet_payment_gateways.ir.parsian.ports.PaymentResponseDTO.message class-attribute instance-attribute

message: str | None = Field(
    None, description="Status message or error description"
)

archipy.adapters.internet_payment_gateways.ir.parsian.ports.PaymentResponseDTO.model_config class-attribute instance-attribute

model_config = ConfigDict(
    extra="ignore",
    validate_default=True,
    from_attributes=True,
    frozen=True,
    str_strip_whitespace=True,
    arbitrary_types_allowed=True,
)

archipy.adapters.internet_payment_gateways.ir.parsian.ports.ConfirmRequestDTO

Bases: BaseDTO

DTO for confirming a payment.

Source code in archipy/adapters/internet_payment_gateways/ir/parsian/ports.py
class ConfirmRequestDTO(BaseDTO):
    """DTO for confirming a payment."""

    token: int = Field(..., gt=0, description="Transaction token")

archipy.adapters.internet_payment_gateways.ir.parsian.ports.ConfirmRequestDTO.token class-attribute instance-attribute

token: int = Field(
    ..., gt=0, description="Transaction token"
)

archipy.adapters.internet_payment_gateways.ir.parsian.ports.ConfirmRequestDTO.model_config class-attribute instance-attribute

model_config = ConfigDict(
    extra="ignore",
    validate_default=True,
    from_attributes=True,
    frozen=True,
    str_strip_whitespace=True,
    arbitrary_types_allowed=True,
)

archipy.adapters.internet_payment_gateways.ir.parsian.ports.ConfirmResponseDTO

Bases: BaseDTO

DTO for confirm payment response.

Source code in archipy/adapters/internet_payment_gateways/ir/parsian/ports.py
class ConfirmResponseDTO(BaseDTO):
    """DTO for confirm payment response."""

    status: int | None = Field(None, description="Transaction status code")
    rrn: int | None = Field(None, description="Retrieval Reference Number")
    card_number_masked: str | None = Field(None, description="Masked card number")
    token: int | None = Field(None, description="Transaction token")

archipy.adapters.internet_payment_gateways.ir.parsian.ports.ConfirmResponseDTO.status class-attribute instance-attribute

status: int | None = Field(
    None, description="Transaction status code"
)

archipy.adapters.internet_payment_gateways.ir.parsian.ports.ConfirmResponseDTO.rrn class-attribute instance-attribute

rrn: int | None = Field(
    None, description="Retrieval Reference Number"
)

archipy.adapters.internet_payment_gateways.ir.parsian.ports.ConfirmResponseDTO.card_number_masked class-attribute instance-attribute

card_number_masked: str | None = Field(
    None, description="Masked card number"
)

archipy.adapters.internet_payment_gateways.ir.parsian.ports.ConfirmResponseDTO.token class-attribute instance-attribute

token: int | None = Field(
    None, description="Transaction token"
)

archipy.adapters.internet_payment_gateways.ir.parsian.ports.ConfirmResponseDTO.model_config class-attribute instance-attribute

model_config = ConfigDict(
    extra="ignore",
    validate_default=True,
    from_attributes=True,
    frozen=True,
    str_strip_whitespace=True,
    arbitrary_types_allowed=True,
)

archipy.adapters.internet_payment_gateways.ir.parsian.ports.ConfirmWithAmountRequestDTO

Bases: BaseDTO

DTO for confirming a payment with amount and order verification.

Source code in archipy/adapters/internet_payment_gateways/ir/parsian/ports.py
class ConfirmWithAmountRequestDTO(BaseDTO):
    """DTO for confirming a payment with amount and order verification."""

    token: int = Field(..., gt=0, description="Transaction token")
    order_id: int = Field(..., gt=0, description="Unique order identifier")
    amount: int = Field(..., gt=0, description="Transaction amount in IRR")

archipy.adapters.internet_payment_gateways.ir.parsian.ports.ConfirmWithAmountRequestDTO.token class-attribute instance-attribute

token: int = Field(
    ..., gt=0, description="Transaction token"
)

archipy.adapters.internet_payment_gateways.ir.parsian.ports.ConfirmWithAmountRequestDTO.order_id class-attribute instance-attribute

order_id: int = Field(
    ..., gt=0, description="Unique order identifier"
)

archipy.adapters.internet_payment_gateways.ir.parsian.ports.ConfirmWithAmountRequestDTO.amount class-attribute instance-attribute

amount: int = Field(
    ..., gt=0, description="Transaction amount in IRR"
)

archipy.adapters.internet_payment_gateways.ir.parsian.ports.ConfirmWithAmountRequestDTO.model_config class-attribute instance-attribute

model_config = ConfigDict(
    extra="ignore",
    validate_default=True,
    from_attributes=True,
    frozen=True,
    str_strip_whitespace=True,
    arbitrary_types_allowed=True,
)

archipy.adapters.internet_payment_gateways.ir.parsian.ports.ConfirmWithAmountResponseDTO

Bases: BaseDTO

DTO for confirm payment with amount response.

Source code in archipy/adapters/internet_payment_gateways/ir/parsian/ports.py
class ConfirmWithAmountResponseDTO(BaseDTO):
    """DTO for confirm payment with amount response."""

    status: int | None = Field(None, description="Transaction status code")
    rrn: int | None = Field(None, description="Retrieval Reference Number")
    card_number_masked: str | None = Field(None, description="Masked card number")
    token: int | None = Field(None, description="Transaction token")

archipy.adapters.internet_payment_gateways.ir.parsian.ports.ConfirmWithAmountResponseDTO.status class-attribute instance-attribute

status: int | None = Field(
    None, description="Transaction status code"
)

archipy.adapters.internet_payment_gateways.ir.parsian.ports.ConfirmWithAmountResponseDTO.rrn class-attribute instance-attribute

rrn: int | None = Field(
    None, description="Retrieval Reference Number"
)

archipy.adapters.internet_payment_gateways.ir.parsian.ports.ConfirmWithAmountResponseDTO.card_number_masked class-attribute instance-attribute

card_number_masked: str | None = Field(
    None, description="Masked card number"
)

archipy.adapters.internet_payment_gateways.ir.parsian.ports.ConfirmWithAmountResponseDTO.token class-attribute instance-attribute

token: int | None = Field(
    None, description="Transaction token"
)

archipy.adapters.internet_payment_gateways.ir.parsian.ports.ConfirmWithAmountResponseDTO.model_config class-attribute instance-attribute

model_config = ConfigDict(
    extra="ignore",
    validate_default=True,
    from_attributes=True,
    frozen=True,
    str_strip_whitespace=True,
    arbitrary_types_allowed=True,
)

archipy.adapters.internet_payment_gateways.ir.parsian.ports.ReverseRequestDTO

Bases: BaseDTO

DTO for reversing a payment.

Source code in archipy/adapters/internet_payment_gateways/ir/parsian/ports.py
class ReverseRequestDTO(BaseDTO):
    """DTO for reversing a payment."""

    token: int = Field(..., gt=0, description="Transaction token")

archipy.adapters.internet_payment_gateways.ir.parsian.ports.ReverseRequestDTO.token class-attribute instance-attribute

token: int = Field(
    ..., gt=0, description="Transaction token"
)

archipy.adapters.internet_payment_gateways.ir.parsian.ports.ReverseRequestDTO.model_config class-attribute instance-attribute

model_config = ConfigDict(
    extra="ignore",
    validate_default=True,
    from_attributes=True,
    frozen=True,
    str_strip_whitespace=True,
    arbitrary_types_allowed=True,
)

archipy.adapters.internet_payment_gateways.ir.parsian.ports.ReverseResponseDTO

Bases: BaseDTO

DTO for reverse payment response.

Source code in archipy/adapters/internet_payment_gateways/ir/parsian/ports.py
class ReverseResponseDTO(BaseDTO):
    """DTO for reverse payment response."""

    status: int | None = Field(None, description="Transaction status code")
    message: str | None = Field(None, description="Status message or error description")
    token: int | None = Field(None, description="Transaction token")

archipy.adapters.internet_payment_gateways.ir.parsian.ports.ReverseResponseDTO.status class-attribute instance-attribute

status: int | None = Field(
    None, description="Transaction status code"
)

archipy.adapters.internet_payment_gateways.ir.parsian.ports.ReverseResponseDTO.message class-attribute instance-attribute

message: str | None = Field(
    None, description="Status message or error description"
)

archipy.adapters.internet_payment_gateways.ir.parsian.ports.ReverseResponseDTO.token class-attribute instance-attribute

token: int | None = Field(
    None, description="Transaction token"
)

archipy.adapters.internet_payment_gateways.ir.parsian.ports.ReverseResponseDTO.model_config class-attribute instance-attribute

model_config = ConfigDict(
    extra="ignore",
    validate_default=True,
    from_attributes=True,
    frozen=True,
    str_strip_whitespace=True,
    arbitrary_types_allowed=True,
)

archipy.adapters.internet_payment_gateways.ir.parsian.ports.ParsianShaparakPaymentPort

Port interface for Parsian Shaparak payment gateway.

Defines the contract for Parsian IPG adapters implementing payment operations (token request, confirmation, and reversal).

Source code in archipy/adapters/internet_payment_gateways/ir/parsian/ports.py
class ParsianShaparakPaymentPort:
    """Port interface for Parsian Shaparak payment gateway.

    Defines the contract for Parsian IPG adapters implementing payment
    operations (token request, confirmation, and reversal).
    """

    @abstractmethod
    def initiate_payment(self, request: PaymentRequestDTO) -> PaymentResponseDTO:
        """Step 1: Request payment token.

        Args:
            request: Payment request data.

        Returns:
            PaymentResponseDTO: Response containing token, status, and message.

        Raises:
            UnavailableError: If a SOAP fault occurs during the request.
            InternalError: If an unexpected error occurs during the request.
        """
        raise NotImplementedError

    @abstractmethod
    def confirm_payment(self, request: ConfirmRequestDTO) -> ConfirmResponseDTO:
        """Step 3: Confirm transaction.

        Args:
            request: Confirm request data.

        Returns:
            ConfirmResponseDTO: Response containing status, RRN, card number, and token.

        Raises:
            UnavailableError: If a SOAP fault occurs during the request.
            InternalError: If an unexpected error occurs during the request.
        """
        raise NotImplementedError

    @abstractmethod
    def confirm_payment_with_amount(self, request: ConfirmWithAmountRequestDTO) -> ConfirmWithAmountResponseDTO:
        """Confirm transaction with amount and order verification.

        Args:
            request: Confirm with amount request data.

        Returns:
            ConfirmWithAmountResponseDTO: Response containing status, RRN, card number, and token.

        Raises:
            UnavailableError: If a SOAP fault occurs during the request.
            InternalError: If an unexpected error occurs during the request.
        """
        raise NotImplementedError

    @abstractmethod
    def reverse_payment(self, request: ReverseRequestDTO) -> ReverseResponseDTO:
        """Reverse a transaction.

        Args:
            request: Reverse request data.

        Returns:
            ReverseResponseDTO: Response containing status, message, and token.

        Raises:
            UnavailableError: If a SOAP fault occurs during the request.
            InternalError: If an unexpected error occurs during the request.
        """
        raise NotImplementedError

archipy.adapters.internet_payment_gateways.ir.parsian.ports.ParsianShaparakPaymentPort.initiate_payment abstractmethod

initiate_payment(
    request: PaymentRequestDTO,
) -> PaymentResponseDTO

Step 1: Request payment token.

Parameters:

Name Type Description Default
request PaymentRequestDTO

Payment request data.

required

Returns:

Name Type Description
PaymentResponseDTO PaymentResponseDTO

Response containing token, status, and message.

Raises:

Type Description
UnavailableError

If a SOAP fault occurs during the request.

InternalError

If an unexpected error occurs during the request.

Source code in archipy/adapters/internet_payment_gateways/ir/parsian/ports.py
@abstractmethod
def initiate_payment(self, request: PaymentRequestDTO) -> PaymentResponseDTO:
    """Step 1: Request payment token.

    Args:
        request: Payment request data.

    Returns:
        PaymentResponseDTO: Response containing token, status, and message.

    Raises:
        UnavailableError: If a SOAP fault occurs during the request.
        InternalError: If an unexpected error occurs during the request.
    """
    raise NotImplementedError

archipy.adapters.internet_payment_gateways.ir.parsian.ports.ParsianShaparakPaymentPort.confirm_payment abstractmethod

confirm_payment(
    request: ConfirmRequestDTO,
) -> ConfirmResponseDTO

Step 3: Confirm transaction.

Parameters:

Name Type Description Default
request ConfirmRequestDTO

Confirm request data.

required

Returns:

Name Type Description
ConfirmResponseDTO ConfirmResponseDTO

Response containing status, RRN, card number, and token.

Raises:

Type Description
UnavailableError

If a SOAP fault occurs during the request.

InternalError

If an unexpected error occurs during the request.

Source code in archipy/adapters/internet_payment_gateways/ir/parsian/ports.py
@abstractmethod
def confirm_payment(self, request: ConfirmRequestDTO) -> ConfirmResponseDTO:
    """Step 3: Confirm transaction.

    Args:
        request: Confirm request data.

    Returns:
        ConfirmResponseDTO: Response containing status, RRN, card number, and token.

    Raises:
        UnavailableError: If a SOAP fault occurs during the request.
        InternalError: If an unexpected error occurs during the request.
    """
    raise NotImplementedError

archipy.adapters.internet_payment_gateways.ir.parsian.ports.ParsianShaparakPaymentPort.confirm_payment_with_amount abstractmethod

confirm_payment_with_amount(
    request: ConfirmWithAmountRequestDTO,
) -> ConfirmWithAmountResponseDTO

Confirm transaction with amount and order verification.

Parameters:

Name Type Description Default
request ConfirmWithAmountRequestDTO

Confirm with amount request data.

required

Returns:

Name Type Description
ConfirmWithAmountResponseDTO ConfirmWithAmountResponseDTO

Response containing status, RRN, card number, and token.

Raises:

Type Description
UnavailableError

If a SOAP fault occurs during the request.

InternalError

If an unexpected error occurs during the request.

Source code in archipy/adapters/internet_payment_gateways/ir/parsian/ports.py
@abstractmethod
def confirm_payment_with_amount(self, request: ConfirmWithAmountRequestDTO) -> ConfirmWithAmountResponseDTO:
    """Confirm transaction with amount and order verification.

    Args:
        request: Confirm with amount request data.

    Returns:
        ConfirmWithAmountResponseDTO: Response containing status, RRN, card number, and token.

    Raises:
        UnavailableError: If a SOAP fault occurs during the request.
        InternalError: If an unexpected error occurs during the request.
    """
    raise NotImplementedError

archipy.adapters.internet_payment_gateways.ir.parsian.ports.ParsianShaparakPaymentPort.reverse_payment abstractmethod

reverse_payment(
    request: ReverseRequestDTO,
) -> ReverseResponseDTO

Reverse a transaction.

Parameters:

Name Type Description Default
request ReverseRequestDTO

Reverse request data.

required

Returns:

Name Type Description
ReverseResponseDTO ReverseResponseDTO

Response containing status, message, and token.

Raises:

Type Description
UnavailableError

If a SOAP fault occurs during the request.

InternalError

If an unexpected error occurs during the request.

Source code in archipy/adapters/internet_payment_gateways/ir/parsian/ports.py
@abstractmethod
def reverse_payment(self, request: ReverseRequestDTO) -> ReverseResponseDTO:
    """Reverse a transaction.

    Args:
        request: Reverse request data.

    Returns:
        ReverseResponseDTO: Response containing status, message, and token.

    Raises:
        UnavailableError: If a SOAP fault occurs during the request.
        InternalError: If an unexpected error occurs during the request.
    """
    raise NotImplementedError

archipy.adapters.internet_payment_gateways.ir.parsian.ports.AsyncParsianShaparakPaymentPort

Async port interface for Parsian Shaparak payment gateway.

Defines the contract for async Parsian IPG adapters implementing payment operations (token request, confirmation, and reversal).

Source code in archipy/adapters/internet_payment_gateways/ir/parsian/ports.py
class AsyncParsianShaparakPaymentPort:
    """Async port interface for Parsian Shaparak payment gateway.

    Defines the contract for async Parsian IPG adapters implementing payment
    operations (token request, confirmation, and reversal).
    """

    @abstractmethod
    async def initiate_payment(self, request: PaymentRequestDTO) -> PaymentResponseDTO:
        """Step 1: Request payment token (async).

        Args:
            request: Payment request data.

        Returns:
            PaymentResponseDTO: Response containing token, status, and message.

        Raises:
            UnavailableError: If a SOAP fault occurs during the request.
            InternalError: If an unexpected error occurs during the request.
        """
        raise NotImplementedError

    @abstractmethod
    async def confirm_payment(self, request: ConfirmRequestDTO) -> ConfirmResponseDTO:
        """Step 3: Confirm transaction (async).

        Args:
            request: Confirm request data.

        Returns:
            ConfirmResponseDTO: Response containing status, RRN, card number, and token.

        Raises:
            UnavailableError: If a SOAP fault occurs during the request.
            InternalError: If an unexpected error occurs during the request.
        """
        raise NotImplementedError

    @abstractmethod
    async def confirm_payment_with_amount(self, request: ConfirmWithAmountRequestDTO) -> ConfirmWithAmountResponseDTO:
        """Confirm transaction with amount and order verification (async).

        Args:
            request: Confirm with amount request data.

        Returns:
            ConfirmWithAmountResponseDTO: Response containing status, RRN, card number, and token.

        Raises:
            UnavailableError: If a SOAP fault occurs during the request.
            InternalError: If an unexpected error occurs during the request.
        """
        raise NotImplementedError

    @abstractmethod
    async def reverse_payment(self, request: ReverseRequestDTO) -> ReverseResponseDTO:
        """Reverse a transaction (async).

        Args:
            request: Reverse request data.

        Returns:
            ReverseResponseDTO: Response containing status, message, and token.

        Raises:
            UnavailableError: If a SOAP fault occurs during the request.
            InternalError: If an unexpected error occurs during the request.
        """
        raise NotImplementedError

archipy.adapters.internet_payment_gateways.ir.parsian.ports.AsyncParsianShaparakPaymentPort.initiate_payment abstractmethod async

initiate_payment(
    request: PaymentRequestDTO,
) -> PaymentResponseDTO

Step 1: Request payment token (async).

Parameters:

Name Type Description Default
request PaymentRequestDTO

Payment request data.

required

Returns:

Name Type Description
PaymentResponseDTO PaymentResponseDTO

Response containing token, status, and message.

Raises:

Type Description
UnavailableError

If a SOAP fault occurs during the request.

InternalError

If an unexpected error occurs during the request.

Source code in archipy/adapters/internet_payment_gateways/ir/parsian/ports.py
@abstractmethod
async def initiate_payment(self, request: PaymentRequestDTO) -> PaymentResponseDTO:
    """Step 1: Request payment token (async).

    Args:
        request: Payment request data.

    Returns:
        PaymentResponseDTO: Response containing token, status, and message.

    Raises:
        UnavailableError: If a SOAP fault occurs during the request.
        InternalError: If an unexpected error occurs during the request.
    """
    raise NotImplementedError

archipy.adapters.internet_payment_gateways.ir.parsian.ports.AsyncParsianShaparakPaymentPort.confirm_payment abstractmethod async

confirm_payment(
    request: ConfirmRequestDTO,
) -> ConfirmResponseDTO

Step 3: Confirm transaction (async).

Parameters:

Name Type Description Default
request ConfirmRequestDTO

Confirm request data.

required

Returns:

Name Type Description
ConfirmResponseDTO ConfirmResponseDTO

Response containing status, RRN, card number, and token.

Raises:

Type Description
UnavailableError

If a SOAP fault occurs during the request.

InternalError

If an unexpected error occurs during the request.

Source code in archipy/adapters/internet_payment_gateways/ir/parsian/ports.py
@abstractmethod
async def confirm_payment(self, request: ConfirmRequestDTO) -> ConfirmResponseDTO:
    """Step 3: Confirm transaction (async).

    Args:
        request: Confirm request data.

    Returns:
        ConfirmResponseDTO: Response containing status, RRN, card number, and token.

    Raises:
        UnavailableError: If a SOAP fault occurs during the request.
        InternalError: If an unexpected error occurs during the request.
    """
    raise NotImplementedError

archipy.adapters.internet_payment_gateways.ir.parsian.ports.AsyncParsianShaparakPaymentPort.confirm_payment_with_amount abstractmethod async

confirm_payment_with_amount(
    request: ConfirmWithAmountRequestDTO,
) -> ConfirmWithAmountResponseDTO

Confirm transaction with amount and order verification (async).

Parameters:

Name Type Description Default
request ConfirmWithAmountRequestDTO

Confirm with amount request data.

required

Returns:

Name Type Description
ConfirmWithAmountResponseDTO ConfirmWithAmountResponseDTO

Response containing status, RRN, card number, and token.

Raises:

Type Description
UnavailableError

If a SOAP fault occurs during the request.

InternalError

If an unexpected error occurs during the request.

Source code in archipy/adapters/internet_payment_gateways/ir/parsian/ports.py
@abstractmethod
async def confirm_payment_with_amount(self, request: ConfirmWithAmountRequestDTO) -> ConfirmWithAmountResponseDTO:
    """Confirm transaction with amount and order verification (async).

    Args:
        request: Confirm with amount request data.

    Returns:
        ConfirmWithAmountResponseDTO: Response containing status, RRN, card number, and token.

    Raises:
        UnavailableError: If a SOAP fault occurs during the request.
        InternalError: If an unexpected error occurs during the request.
    """
    raise NotImplementedError

archipy.adapters.internet_payment_gateways.ir.parsian.ports.AsyncParsianShaparakPaymentPort.reverse_payment abstractmethod async

reverse_payment(
    request: ReverseRequestDTO,
) -> ReverseResponseDTO

Reverse a transaction (async).

Parameters:

Name Type Description Default
request ReverseRequestDTO

Reverse request data.

required

Returns:

Name Type Description
ReverseResponseDTO ReverseResponseDTO

Response containing status, message, and token.

Raises:

Type Description
UnavailableError

If a SOAP fault occurs during the request.

InternalError

If an unexpected error occurs during the request.

Source code in archipy/adapters/internet_payment_gateways/ir/parsian/ports.py
@abstractmethod
async def reverse_payment(self, request: ReverseRequestDTO) -> ReverseResponseDTO:
    """Reverse a transaction (async).

    Args:
        request: Reverse request data.

    Returns:
        ReverseResponseDTO: Response containing status, message, and token.

    Raises:
        UnavailableError: If a SOAP fault occurs during the request.
        InternalError: If an unexpected error occurs during the request.
    """
    raise NotImplementedError

options: show_root_toc_entry: false heading_level: 3

Adapters

archipy.adapters.internet_payment_gateways.ir.parsian.adapters.logger module-attribute

logger = getLogger(__name__)

archipy.adapters.internet_payment_gateways.ir.parsian.adapters.ParsianShaparakPaymentAdapter

Bases: ParsianShaparakPaymentPort

Adapter for interacting with Parsian Shaparak payment gateway services.

Provides methods for initiating payments, confirming transactions, and reversing payments through the Parsian Shaparak payment gateway SOAP services. Supports proxy configuration for environments where direct connections are not possible.

Source code in archipy/adapters/internet_payment_gateways/ir/parsian/adapters.py
class ParsianShaparakPaymentAdapter(ParsianShaparakPaymentPort):
    """Adapter for interacting with Parsian Shaparak payment gateway services.

    Provides methods for initiating payments, confirming transactions, and reversing
    payments through the Parsian Shaparak payment gateway SOAP services. Supports
    proxy configuration for environments where direct connections are not possible.
    """

    def __init__(self, config: ParsianShaparakConfig | None = None) -> None:
        """Initialize the adapter with Parsian Shaparak configuration.

        Args:
            config (ParsianShaparakConfig | None): Configuration for Parsian Shaparak services.
                If None, uses global config. Includes optional proxy configuration via
                the PROXIES field.

        Raises:
            ValueError: If LOGIN_ACCOUNT is not a valid string.
        """
        configs = BaseConfig.global_config().PARSIAN_SHAPARAK if config is None else config
        if not configs.LOGIN_ACCOUNT or not isinstance(configs.LOGIN_ACCOUNT, str):
            raise ValueError("LOGIN_ACCOUNT must be a non-empty string")

        self.login_account = configs.LOGIN_ACCOUNT
        sync_transport = None
        if configs.PROXIES:
            session = requests.Session()
            session.proxies = configs.PROXIES
            sync_transport = Transport(session=session)

        self.sale_client = zeep.Client(wsdl=configs.PAYMENT_WSDL_URL, transport=sync_transport)
        self.confirm_client = zeep.Client(wsdl=configs.CONFIRM_WSDL_URL, transport=sync_transport)
        self.reversal_client = zeep.Client(wsdl=configs.REVERSAL_WSDL_URL, transport=sync_transport)

    def initiate_payment(self, request: PaymentRequestDTO) -> PaymentResponseDTO:
        """Step 1: Request payment token.

        Args:
            request: Payment request data.

        Returns:
            PaymentResponseDTO: Response containing token, status, and message.

        Raises:
            UnavailableError: If a SOAP fault occurs during the request.
            InternalError: If an unexpected error occurs during the request.
        """
        try:
            request_data = {
                "LoginAccount": self.login_account,
                "Amount": request.amount,
                "OrderId": request.order_id,
                "CallBackUrl": str(request.callback_url),
                "AdditionalData": request.additional_data,
                "Originator": request.originator,
            }

            logger.debug(f"Initiating payment: {request_data}")
            response = self.sale_client.service.SalePaymentRequest(requestData=request_data)
            result = PaymentResponseDTO(
                token=response.Token,
                status=response.Status,
                message=response.Message,
            )
            logger.debug(f"Payment response: {result}")
        except Fault as exception:
            raise UnavailableError(resource_type="Parsian Shaparak Sale Service") from exception
        except Exception as exception:
            raise InternalError() from exception
        else:
            return result

    def confirm_payment(self, request: ConfirmRequestDTO) -> ConfirmResponseDTO:
        """Step 3: Confirm transaction.

        Args:
            request: Confirm request data.

        Returns:
            ConfirmResponseDTO: Response containing status, RRN, card number, and token.

        Raises:
            UnavailableError: If a SOAP fault occurs during the request.
            InternalError: If an unexpected error occurs during the request.
        """
        try:
            request_data = {"LoginAccount": self.login_account, "Token": request.token}

            logger.debug(f"Confirming payment: {request_data}")
            response = self.confirm_client.service.ConfirmPayment(requestData=request_data)
            result = ConfirmResponseDTO(
                status=response.Status,
                rrn=response.RRN,
                card_number_masked=response.CardNumberMasked,
                token=response.Token,
            )
            logger.debug(f"Confirm response: {result}")
        except Fault as exception:
            raise UnavailableError(resource_type="Parsian Shaparak Confirm Service") from exception
        except Exception as exception:
            raise InternalError() from exception
        else:
            return result

    def confirm_payment_with_amount(self, request: ConfirmWithAmountRequestDTO) -> ConfirmWithAmountResponseDTO:
        """Confirm transaction with amount and order verification.

        Args:
            request: Confirm with amount request data.

        Returns:
            ConfirmWithAmountResponseDTO: Response containing status, RRN, card number, and token.

        Raises:
            UnavailableError: If a SOAP fault occurs during the request.
            InternalError: If an unexpected error occurs during the request.
        """
        try:
            request_data = {
                "LoginAccount": self.login_account,
                "Token": request.token,
                "OrderId": request.order_id,
                "Amount": request.amount,
            }

            logger.debug(f"Confirming payment with amount: {request_data}")
            response = self.confirm_client.service.ConfirmPaymentWithAmount(requestData=request_data)
            result = ConfirmWithAmountResponseDTO(
                status=response.Status,
                rrn=response.RRN,
                card_number_masked=response.CardNumberMasked,
                token=response.Token,
            )
            logger.debug(f"Confirm with amount response: {result}")
        except Fault as exception:
            raise UnavailableError(resource_type="Parsian Shaparak Confirm Service") from exception
        except Exception as exception:
            raise InternalError() from exception
        else:
            return result

    def reverse_payment(self, request: ReverseRequestDTO) -> ReverseResponseDTO:
        """Reverse a transaction.

        Args:
            request: Reverse request data.

        Returns:
            ReverseResponseDTO: Response containing status, message, and token.

        Raises:
            UnavailableError: If a SOAP fault occurs during the request.
            InternalError: If an unexpected error occurs during the request.
        """
        try:
            request_data = {"LoginAccount": self.login_account, "Token": request.token}

            logger.debug(f"Reversing payment: {request_data}")
            response = self.reversal_client.service.ReversalRequest(requestData=request_data)
            result = ReverseResponseDTO(
                status=response.Status,
                message=response.Message,
                token=response.Token,
            )
            logger.debug(f"Reversal response: {result}")
        except Fault as exception:
            raise UnavailableError(resource_type="Parsian Shaparak Reversal Service") from exception
        except Exception as exception:
            raise InternalError() from exception
        else:
            return result

archipy.adapters.internet_payment_gateways.ir.parsian.adapters.ParsianShaparakPaymentAdapter.login_account instance-attribute

login_account = LOGIN_ACCOUNT

archipy.adapters.internet_payment_gateways.ir.parsian.adapters.ParsianShaparakPaymentAdapter.sale_client instance-attribute

sale_client = Client(
    wsdl=PAYMENT_WSDL_URL, transport=sync_transport
)

archipy.adapters.internet_payment_gateways.ir.parsian.adapters.ParsianShaparakPaymentAdapter.confirm_client instance-attribute

confirm_client = Client(
    wsdl=CONFIRM_WSDL_URL, transport=sync_transport
)

archipy.adapters.internet_payment_gateways.ir.parsian.adapters.ParsianShaparakPaymentAdapter.reversal_client instance-attribute

reversal_client = Client(
    wsdl=REVERSAL_WSDL_URL, transport=sync_transport
)

archipy.adapters.internet_payment_gateways.ir.parsian.adapters.ParsianShaparakPaymentAdapter.initiate_payment

initiate_payment(
    request: PaymentRequestDTO,
) -> PaymentResponseDTO

Step 1: Request payment token.

Parameters:

Name Type Description Default
request PaymentRequestDTO

Payment request data.

required

Returns:

Name Type Description
PaymentResponseDTO PaymentResponseDTO

Response containing token, status, and message.

Raises:

Type Description
UnavailableError

If a SOAP fault occurs during the request.

InternalError

If an unexpected error occurs during the request.

Source code in archipy/adapters/internet_payment_gateways/ir/parsian/adapters.py
def initiate_payment(self, request: PaymentRequestDTO) -> PaymentResponseDTO:
    """Step 1: Request payment token.

    Args:
        request: Payment request data.

    Returns:
        PaymentResponseDTO: Response containing token, status, and message.

    Raises:
        UnavailableError: If a SOAP fault occurs during the request.
        InternalError: If an unexpected error occurs during the request.
    """
    try:
        request_data = {
            "LoginAccount": self.login_account,
            "Amount": request.amount,
            "OrderId": request.order_id,
            "CallBackUrl": str(request.callback_url),
            "AdditionalData": request.additional_data,
            "Originator": request.originator,
        }

        logger.debug(f"Initiating payment: {request_data}")
        response = self.sale_client.service.SalePaymentRequest(requestData=request_data)
        result = PaymentResponseDTO(
            token=response.Token,
            status=response.Status,
            message=response.Message,
        )
        logger.debug(f"Payment response: {result}")
    except Fault as exception:
        raise UnavailableError(resource_type="Parsian Shaparak Sale Service") from exception
    except Exception as exception:
        raise InternalError() from exception
    else:
        return result

archipy.adapters.internet_payment_gateways.ir.parsian.adapters.ParsianShaparakPaymentAdapter.confirm_payment

confirm_payment(
    request: ConfirmRequestDTO,
) -> ConfirmResponseDTO

Step 3: Confirm transaction.

Parameters:

Name Type Description Default
request ConfirmRequestDTO

Confirm request data.

required

Returns:

Name Type Description
ConfirmResponseDTO ConfirmResponseDTO

Response containing status, RRN, card number, and token.

Raises:

Type Description
UnavailableError

If a SOAP fault occurs during the request.

InternalError

If an unexpected error occurs during the request.

Source code in archipy/adapters/internet_payment_gateways/ir/parsian/adapters.py
def confirm_payment(self, request: ConfirmRequestDTO) -> ConfirmResponseDTO:
    """Step 3: Confirm transaction.

    Args:
        request: Confirm request data.

    Returns:
        ConfirmResponseDTO: Response containing status, RRN, card number, and token.

    Raises:
        UnavailableError: If a SOAP fault occurs during the request.
        InternalError: If an unexpected error occurs during the request.
    """
    try:
        request_data = {"LoginAccount": self.login_account, "Token": request.token}

        logger.debug(f"Confirming payment: {request_data}")
        response = self.confirm_client.service.ConfirmPayment(requestData=request_data)
        result = ConfirmResponseDTO(
            status=response.Status,
            rrn=response.RRN,
            card_number_masked=response.CardNumberMasked,
            token=response.Token,
        )
        logger.debug(f"Confirm response: {result}")
    except Fault as exception:
        raise UnavailableError(resource_type="Parsian Shaparak Confirm Service") from exception
    except Exception as exception:
        raise InternalError() from exception
    else:
        return result

archipy.adapters.internet_payment_gateways.ir.parsian.adapters.ParsianShaparakPaymentAdapter.confirm_payment_with_amount

confirm_payment_with_amount(
    request: ConfirmWithAmountRequestDTO,
) -> ConfirmWithAmountResponseDTO

Confirm transaction with amount and order verification.

Parameters:

Name Type Description Default
request ConfirmWithAmountRequestDTO

Confirm with amount request data.

required

Returns:

Name Type Description
ConfirmWithAmountResponseDTO ConfirmWithAmountResponseDTO

Response containing status, RRN, card number, and token.

Raises:

Type Description
UnavailableError

If a SOAP fault occurs during the request.

InternalError

If an unexpected error occurs during the request.

Source code in archipy/adapters/internet_payment_gateways/ir/parsian/adapters.py
def confirm_payment_with_amount(self, request: ConfirmWithAmountRequestDTO) -> ConfirmWithAmountResponseDTO:
    """Confirm transaction with amount and order verification.

    Args:
        request: Confirm with amount request data.

    Returns:
        ConfirmWithAmountResponseDTO: Response containing status, RRN, card number, and token.

    Raises:
        UnavailableError: If a SOAP fault occurs during the request.
        InternalError: If an unexpected error occurs during the request.
    """
    try:
        request_data = {
            "LoginAccount": self.login_account,
            "Token": request.token,
            "OrderId": request.order_id,
            "Amount": request.amount,
        }

        logger.debug(f"Confirming payment with amount: {request_data}")
        response = self.confirm_client.service.ConfirmPaymentWithAmount(requestData=request_data)
        result = ConfirmWithAmountResponseDTO(
            status=response.Status,
            rrn=response.RRN,
            card_number_masked=response.CardNumberMasked,
            token=response.Token,
        )
        logger.debug(f"Confirm with amount response: {result}")
    except Fault as exception:
        raise UnavailableError(resource_type="Parsian Shaparak Confirm Service") from exception
    except Exception as exception:
        raise InternalError() from exception
    else:
        return result

archipy.adapters.internet_payment_gateways.ir.parsian.adapters.ParsianShaparakPaymentAdapter.reverse_payment

reverse_payment(
    request: ReverseRequestDTO,
) -> ReverseResponseDTO

Reverse a transaction.

Parameters:

Name Type Description Default
request ReverseRequestDTO

Reverse request data.

required

Returns:

Name Type Description
ReverseResponseDTO ReverseResponseDTO

Response containing status, message, and token.

Raises:

Type Description
UnavailableError

If a SOAP fault occurs during the request.

InternalError

If an unexpected error occurs during the request.

Source code in archipy/adapters/internet_payment_gateways/ir/parsian/adapters.py
def reverse_payment(self, request: ReverseRequestDTO) -> ReverseResponseDTO:
    """Reverse a transaction.

    Args:
        request: Reverse request data.

    Returns:
        ReverseResponseDTO: Response containing status, message, and token.

    Raises:
        UnavailableError: If a SOAP fault occurs during the request.
        InternalError: If an unexpected error occurs during the request.
    """
    try:
        request_data = {"LoginAccount": self.login_account, "Token": request.token}

        logger.debug(f"Reversing payment: {request_data}")
        response = self.reversal_client.service.ReversalRequest(requestData=request_data)
        result = ReverseResponseDTO(
            status=response.Status,
            message=response.Message,
            token=response.Token,
        )
        logger.debug(f"Reversal response: {result}")
    except Fault as exception:
        raise UnavailableError(resource_type="Parsian Shaparak Reversal Service") from exception
    except Exception as exception:
        raise InternalError() from exception
    else:
        return result

archipy.adapters.internet_payment_gateways.ir.parsian.adapters.AsyncParsianShaparakPaymentAdapter

Bases: AsyncParsianShaparakPaymentPort

Async adapter for interacting with Parsian Shaparak payment gateway services.

Provides async methods for initiating payments, confirming transactions, and reversing payments through the Parsian Shaparak payment gateway SOAP services. Supports proxy configuration for environments where direct connections are not possible.

Source code in archipy/adapters/internet_payment_gateways/ir/parsian/adapters.py
class AsyncParsianShaparakPaymentAdapter(AsyncParsianShaparakPaymentPort):
    """Async adapter for interacting with Parsian Shaparak payment gateway services.

    Provides async methods for initiating payments, confirming transactions, and
    reversing payments through the Parsian Shaparak payment gateway SOAP services.
    Supports proxy configuration for environments where direct connections are
    not possible.
    """

    def __init__(self, config: ParsianShaparakConfig | None = None) -> None:
        """Initialize the async adapter with Parsian Shaparak configuration.

        Args:
            config (ParsianShaparakConfig | None): Configuration for Parsian Shaparak services.
                If None, uses global config. Includes optional proxy configuration via
                the PROXIES field.

        Raises:
            ValueError: If LOGIN_ACCOUNT is not a valid string.
        """
        configs = BaseConfig.global_config().PARSIAN_SHAPARAK if config is None else config
        if not configs.LOGIN_ACCOUNT or not isinstance(configs.LOGIN_ACCOUNT, str):
            raise ValueError("LOGIN_ACCOUNT must be a non-empty string")

        self.login_account = configs.LOGIN_ACCOUNT
        proxy = self._get_proxy(configs.PROXIES)
        async_transport = None
        if proxy:
            httpx_client = httpx.AsyncClient(proxy=proxy)
            async_transport = AsyncTransport(client=httpx_client)

        self.sale_client = AsyncClient(wsdl=configs.PAYMENT_WSDL_URL, transport=async_transport)
        self.confirm_client = AsyncClient(wsdl=configs.CONFIRM_WSDL_URL, transport=async_transport)
        self.reversal_client = AsyncClient(wsdl=configs.REVERSAL_WSDL_URL, transport=async_transport)

    @staticmethod
    def _get_proxy(proxies: dict[str, str] | None) -> str | None:
        if proxies is None:
            return None
        return proxies.get("https") or proxies.get("http") or proxies.get("socks5") or proxies.get("socks5h")

    async def initiate_payment(self, request: PaymentRequestDTO) -> PaymentResponseDTO:
        """Step 1: Request payment token (async).

        Args:
            request: Payment request data.

        Returns:
            PaymentResponseDTO: Response containing token, status, and message.

        Raises:
            UnavailableError: If a SOAP fault occurs during the request.
            InternalError: If an unexpected error occurs during the request.
        """
        try:
            request_data = {
                "LoginAccount": self.login_account,
                "Amount": request.amount,
                "OrderId": request.order_id,
                "CallBackUrl": str(request.callback_url),
                "AdditionalData": request.additional_data,
                "Originator": request.originator,
            }

            logger.debug(f"Initiating payment: {request_data}")
            response = await self.sale_client.service.SalePaymentRequest(requestData=request_data)
            result = PaymentResponseDTO(
                token=response.Token,
                status=response.Status,
                message=response.Message,
            )
            logger.debug(f"Payment response: {result}")
        except Fault as exception:
            raise UnavailableError(resource_type="Parsian Shaparak Sale Service") from exception
        except Exception as exception:
            raise InternalError() from exception
        else:
            return result

    async def confirm_payment(self, request: ConfirmRequestDTO) -> ConfirmResponseDTO:
        """Step 3: Confirm transaction (async).

        Args:
            request: Confirm request data.

        Returns:
            ConfirmResponseDTO: Response containing status, RRN, card number, and token.

        Raises:
            UnavailableError: If a SOAP fault occurs during the request.
            InternalError: If an unexpected error occurs during the request.
        """
        try:
            request_data = {"LoginAccount": self.login_account, "Token": request.token}

            logger.debug(f"Confirming payment: {request_data}")
            response = await self.confirm_client.service.ConfirmPayment(requestData=request_data)
            result = ConfirmResponseDTO(
                status=response.Status,
                rrn=response.RRN,
                card_number_masked=response.CardNumberMasked,
                token=response.Token,
            )
            logger.debug(f"Confirm response: {result}")
        except Fault as exception:
            raise UnavailableError(resource_type="Parsian Shaparak Confirm Service") from exception
        except Exception as exception:
            raise InternalError() from exception
        else:
            return result

    async def confirm_payment_with_amount(self, request: ConfirmWithAmountRequestDTO) -> ConfirmWithAmountResponseDTO:
        """Confirm transaction with amount and order verification (async).

        Args:
            request: Confirm with amount request data.

        Returns:
            ConfirmWithAmountResponseDTO: Response containing status, RRN, card number, and token.

        Raises:
            UnavailableError: If a SOAP fault occurs during the request.
            InternalError: If an unexpected error occurs during the request.
        """
        try:
            request_data = {
                "LoginAccount": self.login_account,
                "Token": request.token,
                "OrderId": request.order_id,
                "Amount": request.amount,
            }

            logger.debug(f"Confirming payment with amount: {request_data}")
            response = await self.confirm_client.service.ConfirmPaymentWithAmount(requestData=request_data)
            result = ConfirmWithAmountResponseDTO(
                status=response.Status,
                rrn=response.RRN,
                card_number_masked=response.CardNumberMasked,
                token=response.Token,
            )
            logger.debug(f"Confirm with amount response: {result}")
        except Fault as exception:
            raise UnavailableError(resource_type="Parsian Shaparak Confirm Service") from exception
        except Exception as exception:
            raise InternalError() from exception
        else:
            return result

    async def reverse_payment(self, request: ReverseRequestDTO) -> ReverseResponseDTO:
        """Reverse a transaction (async).

        Args:
            request: Reverse request data.

        Returns:
            ReverseResponseDTO: Response containing status, message, and token.

        Raises:
            UnavailableError: If a SOAP fault occurs during the request.
            InternalError: If an unexpected error occurs during the request.
        """
        try:
            request_data = {"LoginAccount": self.login_account, "Token": request.token}

            logger.debug(f"Reversing payment: {request_data}")
            response = await self.reversal_client.service.ReversalRequest(requestData=request_data)
            result = ReverseResponseDTO(
                status=response.Status,
                message=response.Message,
                token=response.Token,
            )
            logger.debug(f"Reversal response: {result}")
        except Fault as exception:
            raise UnavailableError(resource_type="Parsian Shaparak Reversal Service") from exception
        except Exception as exception:
            raise InternalError() from exception
        else:
            return result

archipy.adapters.internet_payment_gateways.ir.parsian.adapters.AsyncParsianShaparakPaymentAdapter.login_account instance-attribute

login_account = LOGIN_ACCOUNT

archipy.adapters.internet_payment_gateways.ir.parsian.adapters.AsyncParsianShaparakPaymentAdapter.sale_client instance-attribute

sale_client = AsyncClient(
    wsdl=PAYMENT_WSDL_URL, transport=async_transport
)

archipy.adapters.internet_payment_gateways.ir.parsian.adapters.AsyncParsianShaparakPaymentAdapter.confirm_client instance-attribute

confirm_client = AsyncClient(
    wsdl=CONFIRM_WSDL_URL, transport=async_transport
)

archipy.adapters.internet_payment_gateways.ir.parsian.adapters.AsyncParsianShaparakPaymentAdapter.reversal_client instance-attribute

reversal_client = AsyncClient(
    wsdl=REVERSAL_WSDL_URL, transport=async_transport
)

archipy.adapters.internet_payment_gateways.ir.parsian.adapters.AsyncParsianShaparakPaymentAdapter.initiate_payment async

initiate_payment(
    request: PaymentRequestDTO,
) -> PaymentResponseDTO

Step 1: Request payment token (async).

Parameters:

Name Type Description Default
request PaymentRequestDTO

Payment request data.

required

Returns:

Name Type Description
PaymentResponseDTO PaymentResponseDTO

Response containing token, status, and message.

Raises:

Type Description
UnavailableError

If a SOAP fault occurs during the request.

InternalError

If an unexpected error occurs during the request.

Source code in archipy/adapters/internet_payment_gateways/ir/parsian/adapters.py
async def initiate_payment(self, request: PaymentRequestDTO) -> PaymentResponseDTO:
    """Step 1: Request payment token (async).

    Args:
        request: Payment request data.

    Returns:
        PaymentResponseDTO: Response containing token, status, and message.

    Raises:
        UnavailableError: If a SOAP fault occurs during the request.
        InternalError: If an unexpected error occurs during the request.
    """
    try:
        request_data = {
            "LoginAccount": self.login_account,
            "Amount": request.amount,
            "OrderId": request.order_id,
            "CallBackUrl": str(request.callback_url),
            "AdditionalData": request.additional_data,
            "Originator": request.originator,
        }

        logger.debug(f"Initiating payment: {request_data}")
        response = await self.sale_client.service.SalePaymentRequest(requestData=request_data)
        result = PaymentResponseDTO(
            token=response.Token,
            status=response.Status,
            message=response.Message,
        )
        logger.debug(f"Payment response: {result}")
    except Fault as exception:
        raise UnavailableError(resource_type="Parsian Shaparak Sale Service") from exception
    except Exception as exception:
        raise InternalError() from exception
    else:
        return result

archipy.adapters.internet_payment_gateways.ir.parsian.adapters.AsyncParsianShaparakPaymentAdapter.confirm_payment async

confirm_payment(
    request: ConfirmRequestDTO,
) -> ConfirmResponseDTO

Step 3: Confirm transaction (async).

Parameters:

Name Type Description Default
request ConfirmRequestDTO

Confirm request data.

required

Returns:

Name Type Description
ConfirmResponseDTO ConfirmResponseDTO

Response containing status, RRN, card number, and token.

Raises:

Type Description
UnavailableError

If a SOAP fault occurs during the request.

InternalError

If an unexpected error occurs during the request.

Source code in archipy/adapters/internet_payment_gateways/ir/parsian/adapters.py
async def confirm_payment(self, request: ConfirmRequestDTO) -> ConfirmResponseDTO:
    """Step 3: Confirm transaction (async).

    Args:
        request: Confirm request data.

    Returns:
        ConfirmResponseDTO: Response containing status, RRN, card number, and token.

    Raises:
        UnavailableError: If a SOAP fault occurs during the request.
        InternalError: If an unexpected error occurs during the request.
    """
    try:
        request_data = {"LoginAccount": self.login_account, "Token": request.token}

        logger.debug(f"Confirming payment: {request_data}")
        response = await self.confirm_client.service.ConfirmPayment(requestData=request_data)
        result = ConfirmResponseDTO(
            status=response.Status,
            rrn=response.RRN,
            card_number_masked=response.CardNumberMasked,
            token=response.Token,
        )
        logger.debug(f"Confirm response: {result}")
    except Fault as exception:
        raise UnavailableError(resource_type="Parsian Shaparak Confirm Service") from exception
    except Exception as exception:
        raise InternalError() from exception
    else:
        return result

archipy.adapters.internet_payment_gateways.ir.parsian.adapters.AsyncParsianShaparakPaymentAdapter.confirm_payment_with_amount async

confirm_payment_with_amount(
    request: ConfirmWithAmountRequestDTO,
) -> ConfirmWithAmountResponseDTO

Confirm transaction with amount and order verification (async).

Parameters:

Name Type Description Default
request ConfirmWithAmountRequestDTO

Confirm with amount request data.

required

Returns:

Name Type Description
ConfirmWithAmountResponseDTO ConfirmWithAmountResponseDTO

Response containing status, RRN, card number, and token.

Raises:

Type Description
UnavailableError

If a SOAP fault occurs during the request.

InternalError

If an unexpected error occurs during the request.

Source code in archipy/adapters/internet_payment_gateways/ir/parsian/adapters.py
async def confirm_payment_with_amount(self, request: ConfirmWithAmountRequestDTO) -> ConfirmWithAmountResponseDTO:
    """Confirm transaction with amount and order verification (async).

    Args:
        request: Confirm with amount request data.

    Returns:
        ConfirmWithAmountResponseDTO: Response containing status, RRN, card number, and token.

    Raises:
        UnavailableError: If a SOAP fault occurs during the request.
        InternalError: If an unexpected error occurs during the request.
    """
    try:
        request_data = {
            "LoginAccount": self.login_account,
            "Token": request.token,
            "OrderId": request.order_id,
            "Amount": request.amount,
        }

        logger.debug(f"Confirming payment with amount: {request_data}")
        response = await self.confirm_client.service.ConfirmPaymentWithAmount(requestData=request_data)
        result = ConfirmWithAmountResponseDTO(
            status=response.Status,
            rrn=response.RRN,
            card_number_masked=response.CardNumberMasked,
            token=response.Token,
        )
        logger.debug(f"Confirm with amount response: {result}")
    except Fault as exception:
        raise UnavailableError(resource_type="Parsian Shaparak Confirm Service") from exception
    except Exception as exception:
        raise InternalError() from exception
    else:
        return result

archipy.adapters.internet_payment_gateways.ir.parsian.adapters.AsyncParsianShaparakPaymentAdapter.reverse_payment async

reverse_payment(
    request: ReverseRequestDTO,
) -> ReverseResponseDTO

Reverse a transaction (async).

Parameters:

Name Type Description Default
request ReverseRequestDTO

Reverse request data.

required

Returns:

Name Type Description
ReverseResponseDTO ReverseResponseDTO

Response containing status, message, and token.

Raises:

Type Description
UnavailableError

If a SOAP fault occurs during the request.

InternalError

If an unexpected error occurs during the request.

Source code in archipy/adapters/internet_payment_gateways/ir/parsian/adapters.py
async def reverse_payment(self, request: ReverseRequestDTO) -> ReverseResponseDTO:
    """Reverse a transaction (async).

    Args:
        request: Reverse request data.

    Returns:
        ReverseResponseDTO: Response containing status, message, and token.

    Raises:
        UnavailableError: If a SOAP fault occurs during the request.
        InternalError: If an unexpected error occurs during the request.
    """
    try:
        request_data = {"LoginAccount": self.login_account, "Token": request.token}

        logger.debug(f"Reversing payment: {request_data}")
        response = await self.reversal_client.service.ReversalRequest(requestData=request_data)
        result = ReverseResponseDTO(
            status=response.Status,
            message=response.Message,
            token=response.Token,
        )
        logger.debug(f"Reversal response: {result}")
    except Fault as exception:
        raise UnavailableError(resource_type="Parsian Shaparak Reversal Service") from exception
    except Exception as exception:
        raise InternalError() from exception
    else:
        return result

options: show_root_toc_entry: false heading_level: 3

Saman Shaparak

Saman Shaparak adapters using the REST/JSON protocol. Includes four variants:

  • SamanShaparakPaymentAdapter — Classic SEP adapter, redirects to fixed payment URL
  • SamanNeoPgShaparakPaymentAdapter — Neo-PG adapter, receives dynamic payment URL from X-IPG-Url response header
  • AsyncSamanShaparakPaymentAdapter — Async version of classic SEP adapter
  • AsyncSamanNeoPgShaparakPaymentAdapter — Async version of Neo-PG adapter

Ports

Abstract port interfaces defining the Saman Shaparak adapter contract.

archipy.adapters.internet_payment_gateways.ir.saman.ports.PaymentRequestDTO

Bases: BaseDTO

Request for getting payment token.

Source code in archipy/adapters/internet_payment_gateways/ir/saman/ports.py
class PaymentRequestDTO(BaseDTO):
    """Request for getting payment token."""

    amount: int = Field(..., gt=0, description="مبلغ به ریال")
    res_num: str = Field(..., description="شماره سفارش یکتا (ResNum)")
    redirect_url: HttpUrl = Field(..., description="آدرس صفحه بازگشت")
    cell_number: str | None = Field(None, description="شماره موبایل خریدار")
    wage: int | None = Field(None, description="مبلغ کارمزد")
    token_expiry_in_min: int = Field(20, ge=20, le=3600, description="مدت اعتبار توکن به دقیقه")
    hashed_card_number: str | None = Field(None, description="شماره کارت هش شده")

archipy.adapters.internet_payment_gateways.ir.saman.ports.PaymentRequestDTO.amount class-attribute instance-attribute

amount: int = Field(..., gt=0, description='مبلغ به ریال')

archipy.adapters.internet_payment_gateways.ir.saman.ports.PaymentRequestDTO.res_num class-attribute instance-attribute

res_num: str = Field(
    ..., description="شماره سفارش یکتا (ResNum)"
)

archipy.adapters.internet_payment_gateways.ir.saman.ports.PaymentRequestDTO.redirect_url class-attribute instance-attribute

redirect_url: HttpUrl = Field(
    ..., description="آدرس صفحه بازگشت"
)

archipy.adapters.internet_payment_gateways.ir.saman.ports.PaymentRequestDTO.cell_number class-attribute instance-attribute

cell_number: str | None = Field(
    None, description="شماره موبایل خریدار"
)

archipy.adapters.internet_payment_gateways.ir.saman.ports.PaymentRequestDTO.wage class-attribute instance-attribute

wage: int | None = Field(None, description='مبلغ کارمزد')

archipy.adapters.internet_payment_gateways.ir.saman.ports.PaymentRequestDTO.token_expiry_in_min class-attribute instance-attribute

token_expiry_in_min: int = Field(
    20,
    ge=20,
    le=3600,
    description="مدت اعتبار توکن به دقیقه",
)

archipy.adapters.internet_payment_gateways.ir.saman.ports.PaymentRequestDTO.hashed_card_number class-attribute instance-attribute

hashed_card_number: str | None = Field(
    None, description="شماره کارت هش شده"
)

archipy.adapters.internet_payment_gateways.ir.saman.ports.PaymentRequestDTO.model_config class-attribute instance-attribute

model_config = ConfigDict(
    extra="ignore",
    validate_default=True,
    from_attributes=True,
    frozen=True,
    str_strip_whitespace=True,
    arbitrary_types_allowed=True,
)

archipy.adapters.internet_payment_gateways.ir.saman.ports.PaymentResponseDTO

Bases: BaseDTO

Response from token request.

Source code in archipy/adapters/internet_payment_gateways/ir/saman/ports.py
class PaymentResponseDTO(BaseDTO):
    """Response from token request."""

    status: int
    token: str | None = None
    error_code: str | None = None
    error_desc: str | None = None
    ipg_url: str | None = Field(None, description="Dynamic payment page URL from X-IPG-Url header (Neo-PG only)")

    @model_validator(mode="after")
    def validate_status(self) -> Self:
        """Validate TLS-related settings to ensure compatibility."""
        if (self.status == 1 and self.token is None) or (self.status == -1 and self.error_code is None):
            raise FailedPreconditionError()
        return self

archipy.adapters.internet_payment_gateways.ir.saman.ports.PaymentResponseDTO.status instance-attribute

status: int

archipy.adapters.internet_payment_gateways.ir.saman.ports.PaymentResponseDTO.token class-attribute instance-attribute

token: str | None = None

archipy.adapters.internet_payment_gateways.ir.saman.ports.PaymentResponseDTO.error_code class-attribute instance-attribute

error_code: str | None = None

archipy.adapters.internet_payment_gateways.ir.saman.ports.PaymentResponseDTO.error_desc class-attribute instance-attribute

error_desc: str | None = None

archipy.adapters.internet_payment_gateways.ir.saman.ports.PaymentResponseDTO.ipg_url class-attribute instance-attribute

ipg_url: str | None = Field(
    None,
    description="Dynamic payment page URL from X-IPG-Url header (Neo-PG only)",
)

archipy.adapters.internet_payment_gateways.ir.saman.ports.PaymentResponseDTO.model_config class-attribute instance-attribute

model_config = ConfigDict(
    extra="ignore",
    validate_default=True,
    from_attributes=True,
    frozen=True,
    str_strip_whitespace=True,
    arbitrary_types_allowed=True,
)

archipy.adapters.internet_payment_gateways.ir.saman.ports.PaymentResponseDTO.validate_status

validate_status() -> Self

Validate TLS-related settings to ensure compatibility.

Source code in archipy/adapters/internet_payment_gateways/ir/saman/ports.py
@model_validator(mode="after")
def validate_status(self) -> Self:
    """Validate TLS-related settings to ensure compatibility."""
    if (self.status == 1 and self.token is None) or (self.status == -1 and self.error_code is None):
        raise FailedPreconditionError()
    return self

archipy.adapters.internet_payment_gateways.ir.saman.ports.VerifyRequestDTO

Bases: BaseDTO

Request for verifying a payment.

Source code in archipy/adapters/internet_payment_gateways/ir/saman/ports.py
class VerifyRequestDTO(BaseDTO):
    """Request for verifying a payment."""

    reference_number: str = Field(..., description="رسید دیجیتالی (RefNum)")

archipy.adapters.internet_payment_gateways.ir.saman.ports.VerifyRequestDTO.reference_number class-attribute instance-attribute

reference_number: str = Field(
    ..., description="رسید دیجیتالی (RefNum)"
)

archipy.adapters.internet_payment_gateways.ir.saman.ports.VerifyRequestDTO.model_config class-attribute instance-attribute

model_config = ConfigDict(
    extra="ignore",
    validate_default=True,
    from_attributes=True,
    frozen=True,
    str_strip_whitespace=True,
    arbitrary_types_allowed=True,
)

archipy.adapters.internet_payment_gateways.ir.saman.ports.VerifyResponseDTO

Bases: BaseDTO

Response from payment verification.

Source code in archipy/adapters/internet_payment_gateways/ir/saman/ports.py
class VerifyResponseDTO(BaseDTO):
    """Response from payment verification."""

    success: bool
    result_code: int
    result_description: str
    rrn: str | None = None
    reference_number: str | None = None
    masked_pan: str | None = None
    hashed_pan: str | None = None
    original_amount: int | None = None
    affective_amount: int | None = None
    trace_no: str | None = None

archipy.adapters.internet_payment_gateways.ir.saman.ports.VerifyResponseDTO.success instance-attribute

success: bool

archipy.adapters.internet_payment_gateways.ir.saman.ports.VerifyResponseDTO.result_code instance-attribute

result_code: int

archipy.adapters.internet_payment_gateways.ir.saman.ports.VerifyResponseDTO.result_description instance-attribute

result_description: str

archipy.adapters.internet_payment_gateways.ir.saman.ports.VerifyResponseDTO.rrn class-attribute instance-attribute

rrn: str | None = None

archipy.adapters.internet_payment_gateways.ir.saman.ports.VerifyResponseDTO.reference_number class-attribute instance-attribute

reference_number: str | None = None

archipy.adapters.internet_payment_gateways.ir.saman.ports.VerifyResponseDTO.masked_pan class-attribute instance-attribute

masked_pan: str | None = None

archipy.adapters.internet_payment_gateways.ir.saman.ports.VerifyResponseDTO.hashed_pan class-attribute instance-attribute

hashed_pan: str | None = None

archipy.adapters.internet_payment_gateways.ir.saman.ports.VerifyResponseDTO.original_amount class-attribute instance-attribute

original_amount: int | None = None

archipy.adapters.internet_payment_gateways.ir.saman.ports.VerifyResponseDTO.affective_amount class-attribute instance-attribute

affective_amount: int | None = None

archipy.adapters.internet_payment_gateways.ir.saman.ports.VerifyResponseDTO.trace_no class-attribute instance-attribute

trace_no: str | None = None

archipy.adapters.internet_payment_gateways.ir.saman.ports.VerifyResponseDTO.model_config class-attribute instance-attribute

model_config = ConfigDict(
    extra="ignore",
    validate_default=True,
    from_attributes=True,
    frozen=True,
    str_strip_whitespace=True,
    arbitrary_types_allowed=True,
)

archipy.adapters.internet_payment_gateways.ir.saman.ports.ReverseRequestDTO

Bases: BaseDTO

Request for reversing a payment.

Source code in archipy/adapters/internet_payment_gateways/ir/saman/ports.py
class ReverseRequestDTO(BaseDTO):
    """Request for reversing a payment."""

    reference_number: str = Field(...)

archipy.adapters.internet_payment_gateways.ir.saman.ports.ReverseRequestDTO.reference_number class-attribute instance-attribute

reference_number: str = Field(...)

archipy.adapters.internet_payment_gateways.ir.saman.ports.ReverseRequestDTO.model_config class-attribute instance-attribute

model_config = ConfigDict(
    extra="ignore",
    validate_default=True,
    from_attributes=True,
    frozen=True,
    str_strip_whitespace=True,
    arbitrary_types_allowed=True,
)

archipy.adapters.internet_payment_gateways.ir.saman.ports.ReverseResponseDTO

Bases: BaseDTO

Response from payment reversal.

Source code in archipy/adapters/internet_payment_gateways/ir/saman/ports.py
class ReverseResponseDTO(BaseDTO):
    """Response from payment reversal."""

    success: bool
    result_code: int
    result_description: str

archipy.adapters.internet_payment_gateways.ir.saman.ports.ReverseResponseDTO.success instance-attribute

success: bool

archipy.adapters.internet_payment_gateways.ir.saman.ports.ReverseResponseDTO.result_code instance-attribute

result_code: int

archipy.adapters.internet_payment_gateways.ir.saman.ports.ReverseResponseDTO.result_description instance-attribute

result_description: str

archipy.adapters.internet_payment_gateways.ir.saman.ports.ReverseResponseDTO.model_config class-attribute instance-attribute

model_config = ConfigDict(
    extra="ignore",
    validate_default=True,
    from_attributes=True,
    frozen=True,
    str_strip_whitespace=True,
    arbitrary_types_allowed=True,
)

archipy.adapters.internet_payment_gateways.ir.saman.ports.SamanShaparakPaymentPort

Port interface for Saman Shaparak payment gateway.

Defines the contract for Saman IPG adapters implementing payment operations (token request, verification, and reversal).

Source code in archipy/adapters/internet_payment_gateways/ir/saman/ports.py
class SamanShaparakPaymentPort:
    """Port interface for Saman Shaparak payment gateway.

    Defines the contract for Saman IPG adapters implementing payment
    operations (token request, verification, and reversal).
    """

    @abstractmethod
    def initiate_payment(self, request: PaymentRequestDTO) -> PaymentResponseDTO:
        """Step 1: Request payment token."""
        raise NotImplementedError

    @abstractmethod
    def verify_payment(self, request: VerifyRequestDTO) -> VerifyResponseDTO:
        """Step 3: Verify transaction."""
        raise NotImplementedError

    @abstractmethod
    def reverse_payment(self, request: ReverseRequestDTO) -> ReverseResponseDTO:
        """Reverse a transaction."""
        raise NotImplementedError

archipy.adapters.internet_payment_gateways.ir.saman.ports.SamanShaparakPaymentPort.initiate_payment abstractmethod

initiate_payment(
    request: PaymentRequestDTO,
) -> PaymentResponseDTO

Step 1: Request payment token.

Source code in archipy/adapters/internet_payment_gateways/ir/saman/ports.py
@abstractmethod
def initiate_payment(self, request: PaymentRequestDTO) -> PaymentResponseDTO:
    """Step 1: Request payment token."""
    raise NotImplementedError

archipy.adapters.internet_payment_gateways.ir.saman.ports.SamanShaparakPaymentPort.verify_payment abstractmethod

verify_payment(
    request: VerifyRequestDTO,
) -> VerifyResponseDTO

Step 3: Verify transaction.

Source code in archipy/adapters/internet_payment_gateways/ir/saman/ports.py
@abstractmethod
def verify_payment(self, request: VerifyRequestDTO) -> VerifyResponseDTO:
    """Step 3: Verify transaction."""
    raise NotImplementedError

archipy.adapters.internet_payment_gateways.ir.saman.ports.SamanShaparakPaymentPort.reverse_payment abstractmethod

reverse_payment(
    request: ReverseRequestDTO,
) -> ReverseResponseDTO

Reverse a transaction.

Source code in archipy/adapters/internet_payment_gateways/ir/saman/ports.py
@abstractmethod
def reverse_payment(self, request: ReverseRequestDTO) -> ReverseResponseDTO:
    """Reverse a transaction."""
    raise NotImplementedError

archipy.adapters.internet_payment_gateways.ir.saman.ports.AsyncSamanShaparakPaymentPort

Async port interface for Saman Shaparak payment gateway.

Defines the contract for async Saman IPG adapters implementing payment operations (token request, verification, and reversal).

Source code in archipy/adapters/internet_payment_gateways/ir/saman/ports.py
class AsyncSamanShaparakPaymentPort:
    """Async port interface for Saman Shaparak payment gateway.

    Defines the contract for async Saman IPG adapters implementing payment
    operations (token request, verification, and reversal).
    """

    @abstractmethod
    async def initiate_payment(self, request: PaymentRequestDTO) -> PaymentResponseDTO:
        """Step 1: Request payment token (async)."""
        raise NotImplementedError

    @abstractmethod
    async def verify_payment(self, request: VerifyRequestDTO) -> VerifyResponseDTO:
        """Step 3: Verify transaction (async)."""
        raise NotImplementedError

    @abstractmethod
    async def reverse_payment(self, request: ReverseRequestDTO) -> ReverseResponseDTO:
        """Reverse a transaction (async)."""
        raise NotImplementedError

archipy.adapters.internet_payment_gateways.ir.saman.ports.AsyncSamanShaparakPaymentPort.initiate_payment abstractmethod async

initiate_payment(
    request: PaymentRequestDTO,
) -> PaymentResponseDTO

Step 1: Request payment token (async).

Source code in archipy/adapters/internet_payment_gateways/ir/saman/ports.py
@abstractmethod
async def initiate_payment(self, request: PaymentRequestDTO) -> PaymentResponseDTO:
    """Step 1: Request payment token (async)."""
    raise NotImplementedError

archipy.adapters.internet_payment_gateways.ir.saman.ports.AsyncSamanShaparakPaymentPort.verify_payment abstractmethod async

verify_payment(
    request: VerifyRequestDTO,
) -> VerifyResponseDTO

Step 3: Verify transaction (async).

Source code in archipy/adapters/internet_payment_gateways/ir/saman/ports.py
@abstractmethod
async def verify_payment(self, request: VerifyRequestDTO) -> VerifyResponseDTO:
    """Step 3: Verify transaction (async)."""
    raise NotImplementedError

archipy.adapters.internet_payment_gateways.ir.saman.ports.AsyncSamanShaparakPaymentPort.reverse_payment abstractmethod async

reverse_payment(
    request: ReverseRequestDTO,
) -> ReverseResponseDTO

Reverse a transaction (async).

Source code in archipy/adapters/internet_payment_gateways/ir/saman/ports.py
@abstractmethod
async def reverse_payment(self, request: ReverseRequestDTO) -> ReverseResponseDTO:
    """Reverse a transaction (async)."""
    raise NotImplementedError

options: show_root_toc_entry: false heading_level: 3

Adapters

archipy.adapters.internet_payment_gateways.ir.saman.adapters.logger module-attribute

logger = getLogger(__name__)

archipy.adapters.internet_payment_gateways.ir.saman.adapters.SamanShaparakPaymentAdapter

Bases: SamanShaparakPaymentPort

Saman Shaparak (SEP) Classic Adapter - Full v3/.5 Protocol.

Implements the SamanShaparakPaymentPort interface using httpx for HTTP operations. Provides methods for initiating payments, verifying transactions, and reversing payments.

Source code in archipy/adapters/internet_payment_gateways/ir/saman/adapters.py
class SamanShaparakPaymentAdapter(SamanShaparakPaymentPort):
    """Saman Shaparak (SEP) Classic Adapter - Full v3/.5 Protocol.

    Implements the SamanShaparakPaymentPort interface using httpx for HTTP operations.
    Provides methods for initiating payments, verifying transactions, and reversing payments.
    """

    def __init__(self, config: SamanShaparakConfig | None = None) -> None:
        configs = BaseConfig.global_config().SAMAN_SHAPARAK if config is None else config

        if not configs.TERMINAL_ID:
            raise ValueError("TERMINAL_ID must be provided in SamanShaparakConfig")

        self.terminal_id = configs.TERMINAL_ID
        self.payment_url = str(configs.PAYMENT_URL)
        self.verify_url = str(configs.VERIFY_URL)
        self.reverse_url = str(configs.REVERSE_URL)

        proxy = self._get_proxy(configs.PROXIES)
        self.client = httpx.Client(proxy=proxy, timeout=30)

        logger.info(f"SamanShaparakPaymentAdapter initialized with terminal {self.terminal_id}")

    @staticmethod
    def _get_proxy(proxies: dict[str, str] | None) -> str | None:
        if proxies is None:
            return None
        return proxies.get("https") or proxies.get("http") or proxies.get("socks5") or proxies.get("socks5h")

    def initiate_payment(self, request: PaymentRequestDTO) -> PaymentResponseDTO:
        """Step 1: Request payment token.

        Args:
            request: Payment request data.

        Returns:
            PaymentResponseDTO: Response containing token, status, etc.

        Raises:
            UnavailableError: If the payment service is unavailable.
            InternalError: If an unexpected error occurs.
        """
        try:
            payload = {
                "action": "token",
                "TerminalId": self.terminal_id,
                "Amount": request.amount,
                "ResNum": request.res_num,
                "RedirectUrl": str(request.redirect_url),
                "CellNumber": request.cell_number,
                "Wage": request.wage,
                "TokenExpiryInMin": request.token_expiry_in_min,
                "HashedCardNumber": request.hashed_card_number,
            }
            payload = {k: v for k, v in payload.items() if v is not None}

            logger.debug(f"Saman initiate payment payload: {payload}")
            resp = self.client.post(self.payment_url, json=payload)
            resp.raise_for_status()
            data = resp.json()

            return PaymentResponseDTO(
                status=data.get("status"),
                token=data.get("token"),
                error_code=data.get("errorCode"),
                error_desc=data.get("errorDesc"),
            )
        except httpx.RequestError as e:
            raise UnavailableError(resource_type="Saman Token Service") from e
        except Exception as e:
            raise InternalError() from e

    def verify_payment(self, request: VerifyRequestDTO) -> VerifyResponseDTO:
        """Step 3: Verify transaction (strongly recommended).

        Args:
            request: Verify request with reference number.

        Returns:
            VerifyResponseDTO: Response containing transaction details.

        Raises:
            UnavailableError: If the verify service is unavailable.
            InternalError: If an unexpected error occurs.
        """
        try:
            payload = {"RefNum": request.reference_number, "TerminalNumber": int(self.terminal_id)}

            resp = self.client.post(self.verify_url, json=payload)
            resp.raise_for_status()
            data = resp.json()

            transaction_detail = data.get("TransactionDetail", {})
            return VerifyResponseDTO(
                success=data.get("Success", False),
                result_code=data.get("ResultCode", -1),
                result_description=data.get("ResultDescription", "Unknown"),
                rrn=transaction_detail.get("RRN"),
                reference_number=transaction_detail.get("RefNum"),
                masked_pan=transaction_detail.get("MaskedPan"),
                hashed_pan=transaction_detail.get("HashedPan"),
                original_amount=transaction_detail.get("OrginalAmount"),
                affective_amount=transaction_detail.get("AffectiveAmount"),
                trace_no=transaction_detail.get("StraceNo"),
            )
        except httpx.RequestError as e:
            raise UnavailableError(resource_type="Saman Verify Service") from e
        except Exception as e:
            raise InternalError() from e

    def reverse_payment(self, request: ReverseRequestDTO) -> ReverseResponseDTO:
        """Reverse a transaction.

        Args:
            request: Reverse request with reference number.

        Returns:
            ReverseResponseDTO: Response containing reversal result.

        Raises:
            UnavailableError: If the reverse service is unavailable.
            InternalError: If an unexpected error occurs.
        """
        try:
            payload = {"RefNum": request.reference_number, "TerminalNumber": int(self.terminal_id)}
            resp = self.client.post(self.reverse_url, json=payload)
            resp.raise_for_status()
            data = resp.json()

            return ReverseResponseDTO(
                success=data.get("Success", False),
                result_code=data.get("ResultCode", -1),
                result_description=data.get("ResultDescription", "Unknown"),
            )
        except httpx.RequestError as e:
            raise UnavailableError(resource_type="Saman Reverse Service") from e
        except Exception as e:
            raise InternalError() from e

archipy.adapters.internet_payment_gateways.ir.saman.adapters.SamanShaparakPaymentAdapter.terminal_id instance-attribute

terminal_id = TERMINAL_ID

archipy.adapters.internet_payment_gateways.ir.saman.adapters.SamanShaparakPaymentAdapter.payment_url instance-attribute

payment_url = str(PAYMENT_URL)

archipy.adapters.internet_payment_gateways.ir.saman.adapters.SamanShaparakPaymentAdapter.verify_url instance-attribute

verify_url = str(VERIFY_URL)

archipy.adapters.internet_payment_gateways.ir.saman.adapters.SamanShaparakPaymentAdapter.reverse_url instance-attribute

reverse_url = str(REVERSE_URL)

archipy.adapters.internet_payment_gateways.ir.saman.adapters.SamanShaparakPaymentAdapter.client instance-attribute

client = Client(proxy=proxy, timeout=30)

archipy.adapters.internet_payment_gateways.ir.saman.adapters.SamanShaparakPaymentAdapter.initiate_payment

initiate_payment(
    request: PaymentRequestDTO,
) -> PaymentResponseDTO

Step 1: Request payment token.

Parameters:

Name Type Description Default
request PaymentRequestDTO

Payment request data.

required

Returns:

Name Type Description
PaymentResponseDTO PaymentResponseDTO

Response containing token, status, etc.

Raises:

Type Description
UnavailableError

If the payment service is unavailable.

InternalError

If an unexpected error occurs.

Source code in archipy/adapters/internet_payment_gateways/ir/saman/adapters.py
def initiate_payment(self, request: PaymentRequestDTO) -> PaymentResponseDTO:
    """Step 1: Request payment token.

    Args:
        request: Payment request data.

    Returns:
        PaymentResponseDTO: Response containing token, status, etc.

    Raises:
        UnavailableError: If the payment service is unavailable.
        InternalError: If an unexpected error occurs.
    """
    try:
        payload = {
            "action": "token",
            "TerminalId": self.terminal_id,
            "Amount": request.amount,
            "ResNum": request.res_num,
            "RedirectUrl": str(request.redirect_url),
            "CellNumber": request.cell_number,
            "Wage": request.wage,
            "TokenExpiryInMin": request.token_expiry_in_min,
            "HashedCardNumber": request.hashed_card_number,
        }
        payload = {k: v for k, v in payload.items() if v is not None}

        logger.debug(f"Saman initiate payment payload: {payload}")
        resp = self.client.post(self.payment_url, json=payload)
        resp.raise_for_status()
        data = resp.json()

        return PaymentResponseDTO(
            status=data.get("status"),
            token=data.get("token"),
            error_code=data.get("errorCode"),
            error_desc=data.get("errorDesc"),
        )
    except httpx.RequestError as e:
        raise UnavailableError(resource_type="Saman Token Service") from e
    except Exception as e:
        raise InternalError() from e

archipy.adapters.internet_payment_gateways.ir.saman.adapters.SamanShaparakPaymentAdapter.verify_payment

verify_payment(
    request: VerifyRequestDTO,
) -> VerifyResponseDTO

Step 3: Verify transaction (strongly recommended).

Parameters:

Name Type Description Default
request VerifyRequestDTO

Verify request with reference number.

required

Returns:

Name Type Description
VerifyResponseDTO VerifyResponseDTO

Response containing transaction details.

Raises:

Type Description
UnavailableError

If the verify service is unavailable.

InternalError

If an unexpected error occurs.

Source code in archipy/adapters/internet_payment_gateways/ir/saman/adapters.py
def verify_payment(self, request: VerifyRequestDTO) -> VerifyResponseDTO:
    """Step 3: Verify transaction (strongly recommended).

    Args:
        request: Verify request with reference number.

    Returns:
        VerifyResponseDTO: Response containing transaction details.

    Raises:
        UnavailableError: If the verify service is unavailable.
        InternalError: If an unexpected error occurs.
    """
    try:
        payload = {"RefNum": request.reference_number, "TerminalNumber": int(self.terminal_id)}

        resp = self.client.post(self.verify_url, json=payload)
        resp.raise_for_status()
        data = resp.json()

        transaction_detail = data.get("TransactionDetail", {})
        return VerifyResponseDTO(
            success=data.get("Success", False),
            result_code=data.get("ResultCode", -1),
            result_description=data.get("ResultDescription", "Unknown"),
            rrn=transaction_detail.get("RRN"),
            reference_number=transaction_detail.get("RefNum"),
            masked_pan=transaction_detail.get("MaskedPan"),
            hashed_pan=transaction_detail.get("HashedPan"),
            original_amount=transaction_detail.get("OrginalAmount"),
            affective_amount=transaction_detail.get("AffectiveAmount"),
            trace_no=transaction_detail.get("StraceNo"),
        )
    except httpx.RequestError as e:
        raise UnavailableError(resource_type="Saman Verify Service") from e
    except Exception as e:
        raise InternalError() from e

archipy.adapters.internet_payment_gateways.ir.saman.adapters.SamanShaparakPaymentAdapter.reverse_payment

reverse_payment(
    request: ReverseRequestDTO,
) -> ReverseResponseDTO

Reverse a transaction.

Parameters:

Name Type Description Default
request ReverseRequestDTO

Reverse request with reference number.

required

Returns:

Name Type Description
ReverseResponseDTO ReverseResponseDTO

Response containing reversal result.

Raises:

Type Description
UnavailableError

If the reverse service is unavailable.

InternalError

If an unexpected error occurs.

Source code in archipy/adapters/internet_payment_gateways/ir/saman/adapters.py
def reverse_payment(self, request: ReverseRequestDTO) -> ReverseResponseDTO:
    """Reverse a transaction.

    Args:
        request: Reverse request with reference number.

    Returns:
        ReverseResponseDTO: Response containing reversal result.

    Raises:
        UnavailableError: If the reverse service is unavailable.
        InternalError: If an unexpected error occurs.
    """
    try:
        payload = {"RefNum": request.reference_number, "TerminalNumber": int(self.terminal_id)}
        resp = self.client.post(self.reverse_url, json=payload)
        resp.raise_for_status()
        data = resp.json()

        return ReverseResponseDTO(
            success=data.get("Success", False),
            result_code=data.get("ResultCode", -1),
            result_description=data.get("ResultDescription", "Unknown"),
        )
    except httpx.RequestError as e:
        raise UnavailableError(resource_type="Saman Reverse Service") from e
    except Exception as e:
        raise InternalError() from e

archipy.adapters.internet_payment_gateways.ir.saman.adapters.SamanNeoPgShaparakPaymentAdapter

Bases: SamanShaparakPaymentAdapter

Saman Neo-PG (New Generation) Adapter - Uses dynamic X-IPG-Url.

Extends SamanShaparakPaymentAdapter to capture the dynamic payment page URL from the X-IPG-Url header in the token response.

Source code in archipy/adapters/internet_payment_gateways/ir/saman/adapters.py
class SamanNeoPgShaparakPaymentAdapter(SamanShaparakPaymentAdapter):
    """Saman Neo-PG (New Generation) Adapter - Uses dynamic X-IPG-Url.

    Extends SamanShaparakPaymentAdapter to capture the dynamic payment page URL
    from the X-IPG-Url header in the token response.
    """

    def initiate_payment(self, request: PaymentRequestDTO) -> PaymentResponseDTO:
        """Override to capture dynamic neo-pg URL from header.

        Args:
            request: Payment request data.

        Returns:
            PaymentResponseDTO: Response containing token, status, and IPG URL.

        Raises:
            UnavailableError: If the payment service is unavailable.
            InternalError: If an unexpected error occurs.
        """
        try:
            payload = {
                "action": "token",
                "TerminalId": self.terminal_id,
                "Amount": request.amount,
                "ResNum": request.res_num,
                "RedirectUrl": str(request.redirect_url),
                "CellNumber": request.cell_number,
                "Wage": request.wage,
                "TokenExpiryInMin": request.token_expiry_in_min,
                "HashedCardNumber": request.hashed_card_number,
            }
            payload = {k: v for k, v in payload.items() if v is not None}

            resp = self.client.post(self.payment_url, json=payload)
            resp.raise_for_status()
            data = resp.json()

            ipg_url = resp.headers.get("X-IPG-Url")

            return PaymentResponseDTO(
                status=data.get("status"),
                token=data.get("token"),
                error_code=data.get("errorCode"),
                error_desc=data.get("errorDesc"),
                ipg_url=ipg_url,
            )
        except httpx.RequestError as e:
            raise UnavailableError(resource_type="Saman Neo-PG Token Service") from e
        except Exception as e:
            raise InternalError() from e

archipy.adapters.internet_payment_gateways.ir.saman.adapters.SamanNeoPgShaparakPaymentAdapter.terminal_id instance-attribute

terminal_id = TERMINAL_ID

archipy.adapters.internet_payment_gateways.ir.saman.adapters.SamanNeoPgShaparakPaymentAdapter.payment_url instance-attribute

payment_url = str(PAYMENT_URL)

archipy.adapters.internet_payment_gateways.ir.saman.adapters.SamanNeoPgShaparakPaymentAdapter.verify_url instance-attribute

verify_url = str(VERIFY_URL)

archipy.adapters.internet_payment_gateways.ir.saman.adapters.SamanNeoPgShaparakPaymentAdapter.reverse_url instance-attribute

reverse_url = str(REVERSE_URL)

archipy.adapters.internet_payment_gateways.ir.saman.adapters.SamanNeoPgShaparakPaymentAdapter.client instance-attribute

client = Client(proxy=proxy, timeout=30)

archipy.adapters.internet_payment_gateways.ir.saman.adapters.SamanNeoPgShaparakPaymentAdapter.initiate_payment

initiate_payment(
    request: PaymentRequestDTO,
) -> PaymentResponseDTO

Override to capture dynamic neo-pg URL from header.

Parameters:

Name Type Description Default
request PaymentRequestDTO

Payment request data.

required

Returns:

Name Type Description
PaymentResponseDTO PaymentResponseDTO

Response containing token, status, and IPG URL.

Raises:

Type Description
UnavailableError

If the payment service is unavailable.

InternalError

If an unexpected error occurs.

Source code in archipy/adapters/internet_payment_gateways/ir/saman/adapters.py
def initiate_payment(self, request: PaymentRequestDTO) -> PaymentResponseDTO:
    """Override to capture dynamic neo-pg URL from header.

    Args:
        request: Payment request data.

    Returns:
        PaymentResponseDTO: Response containing token, status, and IPG URL.

    Raises:
        UnavailableError: If the payment service is unavailable.
        InternalError: If an unexpected error occurs.
    """
    try:
        payload = {
            "action": "token",
            "TerminalId": self.terminal_id,
            "Amount": request.amount,
            "ResNum": request.res_num,
            "RedirectUrl": str(request.redirect_url),
            "CellNumber": request.cell_number,
            "Wage": request.wage,
            "TokenExpiryInMin": request.token_expiry_in_min,
            "HashedCardNumber": request.hashed_card_number,
        }
        payload = {k: v for k, v in payload.items() if v is not None}

        resp = self.client.post(self.payment_url, json=payload)
        resp.raise_for_status()
        data = resp.json()

        ipg_url = resp.headers.get("X-IPG-Url")

        return PaymentResponseDTO(
            status=data.get("status"),
            token=data.get("token"),
            error_code=data.get("errorCode"),
            error_desc=data.get("errorDesc"),
            ipg_url=ipg_url,
        )
    except httpx.RequestError as e:
        raise UnavailableError(resource_type="Saman Neo-PG Token Service") from e
    except Exception as e:
        raise InternalError() from e

archipy.adapters.internet_payment_gateways.ir.saman.adapters.SamanNeoPgShaparakPaymentAdapter.verify_payment

verify_payment(
    request: VerifyRequestDTO,
) -> VerifyResponseDTO

Step 3: Verify transaction (strongly recommended).

Parameters:

Name Type Description Default
request VerifyRequestDTO

Verify request with reference number.

required

Returns:

Name Type Description
VerifyResponseDTO VerifyResponseDTO

Response containing transaction details.

Raises:

Type Description
UnavailableError

If the verify service is unavailable.

InternalError

If an unexpected error occurs.

Source code in archipy/adapters/internet_payment_gateways/ir/saman/adapters.py
def verify_payment(self, request: VerifyRequestDTO) -> VerifyResponseDTO:
    """Step 3: Verify transaction (strongly recommended).

    Args:
        request: Verify request with reference number.

    Returns:
        VerifyResponseDTO: Response containing transaction details.

    Raises:
        UnavailableError: If the verify service is unavailable.
        InternalError: If an unexpected error occurs.
    """
    try:
        payload = {"RefNum": request.reference_number, "TerminalNumber": int(self.terminal_id)}

        resp = self.client.post(self.verify_url, json=payload)
        resp.raise_for_status()
        data = resp.json()

        transaction_detail = data.get("TransactionDetail", {})
        return VerifyResponseDTO(
            success=data.get("Success", False),
            result_code=data.get("ResultCode", -1),
            result_description=data.get("ResultDescription", "Unknown"),
            rrn=transaction_detail.get("RRN"),
            reference_number=transaction_detail.get("RefNum"),
            masked_pan=transaction_detail.get("MaskedPan"),
            hashed_pan=transaction_detail.get("HashedPan"),
            original_amount=transaction_detail.get("OrginalAmount"),
            affective_amount=transaction_detail.get("AffectiveAmount"),
            trace_no=transaction_detail.get("StraceNo"),
        )
    except httpx.RequestError as e:
        raise UnavailableError(resource_type="Saman Verify Service") from e
    except Exception as e:
        raise InternalError() from e

archipy.adapters.internet_payment_gateways.ir.saman.adapters.SamanNeoPgShaparakPaymentAdapter.reverse_payment

reverse_payment(
    request: ReverseRequestDTO,
) -> ReverseResponseDTO

Reverse a transaction.

Parameters:

Name Type Description Default
request ReverseRequestDTO

Reverse request with reference number.

required

Returns:

Name Type Description
ReverseResponseDTO ReverseResponseDTO

Response containing reversal result.

Raises:

Type Description
UnavailableError

If the reverse service is unavailable.

InternalError

If an unexpected error occurs.

Source code in archipy/adapters/internet_payment_gateways/ir/saman/adapters.py
def reverse_payment(self, request: ReverseRequestDTO) -> ReverseResponseDTO:
    """Reverse a transaction.

    Args:
        request: Reverse request with reference number.

    Returns:
        ReverseResponseDTO: Response containing reversal result.

    Raises:
        UnavailableError: If the reverse service is unavailable.
        InternalError: If an unexpected error occurs.
    """
    try:
        payload = {"RefNum": request.reference_number, "TerminalNumber": int(self.terminal_id)}
        resp = self.client.post(self.reverse_url, json=payload)
        resp.raise_for_status()
        data = resp.json()

        return ReverseResponseDTO(
            success=data.get("Success", False),
            result_code=data.get("ResultCode", -1),
            result_description=data.get("ResultDescription", "Unknown"),
        )
    except httpx.RequestError as e:
        raise UnavailableError(resource_type="Saman Reverse Service") from e
    except Exception as e:
        raise InternalError() from e

archipy.adapters.internet_payment_gateways.ir.saman.adapters.AsyncSamanShaparakPaymentAdapter

Bases: AsyncSamanShaparakPaymentPort

Async Saman Shaparak (SEP) Classic Adapter - Full v3/.5 Protocol.

Async implementation of SamanShaparakPaymentPort using httpx.AsyncClient. Provides async methods for initiating payments, verifying transactions, and reversing payments.

Source code in archipy/adapters/internet_payment_gateways/ir/saman/adapters.py
class AsyncSamanShaparakPaymentAdapter(AsyncSamanShaparakPaymentPort):
    """Async Saman Shaparak (SEP) Classic Adapter - Full v3/.5 Protocol.

    Async implementation of SamanShaparakPaymentPort using httpx.AsyncClient.
    Provides async methods for initiating payments, verifying transactions,
    and reversing payments.
    """

    def __init__(self, config: SamanShaparakConfig | None = None) -> None:
        configs = BaseConfig.global_config().SAMAN_SHAPARAK if config is None else config

        if not configs.TERMINAL_ID:
            raise ValueError("TERMINAL_ID must be provided in SamanShaparakConfig")

        self.terminal_id = configs.TERMINAL_ID
        self.payment_url = str(configs.PAYMENT_URL)
        self.verify_url = str(configs.VERIFY_URL)
        self.reverse_url = str(configs.REVERSE_URL)

        proxy = self._get_proxy(configs.PROXIES)
        self.client = httpx.AsyncClient(proxy=proxy, timeout=30)

        logger.info(f"AsyncSamanShaparakPaymentAdapter initialized with terminal {self.terminal_id}")

    @staticmethod
    def _get_proxy(proxies: dict[str, str] | None) -> str | None:
        if proxies is None:
            return None
        return proxies.get("https") or proxies.get("http") or proxies.get("socks5") or proxies.get("socks5h")

    async def initiate_payment(self, request: PaymentRequestDTO) -> PaymentResponseDTO:
        """Step 1: Request payment token (async).

        Args:
            request: Payment request data.

        Returns:
            PaymentResponseDTO: Response containing token, status, etc.

        Raises:
            UnavailableError: If the payment service is unavailable.
            InternalError: If an unexpected error occurs.
        """
        try:
            payload = {
                "action": "token",
                "TerminalId": self.terminal_id,
                "Amount": request.amount,
                "ResNum": request.res_num,
                "RedirectUrl": str(request.redirect_url),
                "CellNumber": request.cell_number,
                "Wage": request.wage,
                "TokenExpiryInMin": request.token_expiry_in_min,
                "HashedCardNumber": request.hashed_card_number,
            }
            payload = {k: v for k, v in payload.items() if v is not None}

            logger.debug(f"Saman async initiate payment payload: {payload}")
            resp = await self.client.post(self.payment_url, json=payload)
            resp.raise_for_status()
            data = resp.json()

            return PaymentResponseDTO(
                status=data.get("status"),
                token=data.get("token"),
                error_code=data.get("errorCode"),
                error_desc=data.get("errorDesc"),
            )
        except httpx.RequestError as e:
            raise UnavailableError(resource_type="Saman Token Service") from e
        except Exception as e:
            raise InternalError() from e

    async def verify_payment(self, request: VerifyRequestDTO) -> VerifyResponseDTO:
        """Step 3: Verify transaction (async, strongly recommended).

        Args:
            request: Verify request with reference number.

        Returns:
            VerifyResponseDTO: Response containing transaction details.

        Raises:
            UnavailableError: If the verify service is unavailable.
            InternalError: If an unexpected error occurs.
        """
        try:
            payload = {"RefNum": request.reference_number, "TerminalNumber": int(self.terminal_id)}

            resp = await self.client.post(self.verify_url, json=payload)
            resp.raise_for_status()
            data = resp.json()

            transaction_detail = data.get("TransactionDetail", {})
            return VerifyResponseDTO(
                success=data.get("Success", False),
                result_code=data.get("ResultCode", -1),
                result_description=data.get("ResultDescription", "Unknown"),
                rrn=transaction_detail.get("RRN"),
                reference_number=transaction_detail.get("RefNum"),
                masked_pan=transaction_detail.get("MaskedPan"),
                hashed_pan=transaction_detail.get("HashedPan"),
                original_amount=transaction_detail.get("OrginalAmount"),
                affective_amount=transaction_detail.get("AffectiveAmount"),
                trace_no=transaction_detail.get("StraceNo"),
            )
        except httpx.RequestError as e:
            raise UnavailableError(resource_type="Saman Verify Service") from e
        except Exception as e:
            raise InternalError() from e

    async def reverse_payment(self, request: ReverseRequestDTO) -> ReverseResponseDTO:
        """Reverse a transaction (async).

        Args:
            request: Reverse request with reference number.

        Returns:
            ReverseResponseDTO: Response containing reversal result.

        Raises:
            UnavailableError: If the reverse service is unavailable.
            InternalError: If an unexpected error occurs.
        """
        try:
            payload = {"RefNum": request.reference_number, "TerminalNumber": int(self.terminal_id)}
            resp = await self.client.post(self.reverse_url, json=payload)
            resp.raise_for_status()
            data = resp.json()

            return ReverseResponseDTO(
                success=data.get("Success", False),
                result_code=data.get("ResultCode", -1),
                result_description=data.get("ResultDescription", "Unknown"),
            )
        except httpx.RequestError as e:
            raise UnavailableError(resource_type="Saman Reverse Service") from e
        except Exception as e:
            raise InternalError() from e

archipy.adapters.internet_payment_gateways.ir.saman.adapters.AsyncSamanShaparakPaymentAdapter.terminal_id instance-attribute

terminal_id = TERMINAL_ID

archipy.adapters.internet_payment_gateways.ir.saman.adapters.AsyncSamanShaparakPaymentAdapter.payment_url instance-attribute

payment_url = str(PAYMENT_URL)

archipy.adapters.internet_payment_gateways.ir.saman.adapters.AsyncSamanShaparakPaymentAdapter.verify_url instance-attribute

verify_url = str(VERIFY_URL)

archipy.adapters.internet_payment_gateways.ir.saman.adapters.AsyncSamanShaparakPaymentAdapter.reverse_url instance-attribute

reverse_url = str(REVERSE_URL)

archipy.adapters.internet_payment_gateways.ir.saman.adapters.AsyncSamanShaparakPaymentAdapter.client instance-attribute

client = AsyncClient(proxy=proxy, timeout=30)

archipy.adapters.internet_payment_gateways.ir.saman.adapters.AsyncSamanShaparakPaymentAdapter.initiate_payment async

initiate_payment(
    request: PaymentRequestDTO,
) -> PaymentResponseDTO

Step 1: Request payment token (async).

Parameters:

Name Type Description Default
request PaymentRequestDTO

Payment request data.

required

Returns:

Name Type Description
PaymentResponseDTO PaymentResponseDTO

Response containing token, status, etc.

Raises:

Type Description
UnavailableError

If the payment service is unavailable.

InternalError

If an unexpected error occurs.

Source code in archipy/adapters/internet_payment_gateways/ir/saman/adapters.py
async def initiate_payment(self, request: PaymentRequestDTO) -> PaymentResponseDTO:
    """Step 1: Request payment token (async).

    Args:
        request: Payment request data.

    Returns:
        PaymentResponseDTO: Response containing token, status, etc.

    Raises:
        UnavailableError: If the payment service is unavailable.
        InternalError: If an unexpected error occurs.
    """
    try:
        payload = {
            "action": "token",
            "TerminalId": self.terminal_id,
            "Amount": request.amount,
            "ResNum": request.res_num,
            "RedirectUrl": str(request.redirect_url),
            "CellNumber": request.cell_number,
            "Wage": request.wage,
            "TokenExpiryInMin": request.token_expiry_in_min,
            "HashedCardNumber": request.hashed_card_number,
        }
        payload = {k: v for k, v in payload.items() if v is not None}

        logger.debug(f"Saman async initiate payment payload: {payload}")
        resp = await self.client.post(self.payment_url, json=payload)
        resp.raise_for_status()
        data = resp.json()

        return PaymentResponseDTO(
            status=data.get("status"),
            token=data.get("token"),
            error_code=data.get("errorCode"),
            error_desc=data.get("errorDesc"),
        )
    except httpx.RequestError as e:
        raise UnavailableError(resource_type="Saman Token Service") from e
    except Exception as e:
        raise InternalError() from e

archipy.adapters.internet_payment_gateways.ir.saman.adapters.AsyncSamanShaparakPaymentAdapter.verify_payment async

verify_payment(
    request: VerifyRequestDTO,
) -> VerifyResponseDTO

Step 3: Verify transaction (async, strongly recommended).

Parameters:

Name Type Description Default
request VerifyRequestDTO

Verify request with reference number.

required

Returns:

Name Type Description
VerifyResponseDTO VerifyResponseDTO

Response containing transaction details.

Raises:

Type Description
UnavailableError

If the verify service is unavailable.

InternalError

If an unexpected error occurs.

Source code in archipy/adapters/internet_payment_gateways/ir/saman/adapters.py
async def verify_payment(self, request: VerifyRequestDTO) -> VerifyResponseDTO:
    """Step 3: Verify transaction (async, strongly recommended).

    Args:
        request: Verify request with reference number.

    Returns:
        VerifyResponseDTO: Response containing transaction details.

    Raises:
        UnavailableError: If the verify service is unavailable.
        InternalError: If an unexpected error occurs.
    """
    try:
        payload = {"RefNum": request.reference_number, "TerminalNumber": int(self.terminal_id)}

        resp = await self.client.post(self.verify_url, json=payload)
        resp.raise_for_status()
        data = resp.json()

        transaction_detail = data.get("TransactionDetail", {})
        return VerifyResponseDTO(
            success=data.get("Success", False),
            result_code=data.get("ResultCode", -1),
            result_description=data.get("ResultDescription", "Unknown"),
            rrn=transaction_detail.get("RRN"),
            reference_number=transaction_detail.get("RefNum"),
            masked_pan=transaction_detail.get("MaskedPan"),
            hashed_pan=transaction_detail.get("HashedPan"),
            original_amount=transaction_detail.get("OrginalAmount"),
            affective_amount=transaction_detail.get("AffectiveAmount"),
            trace_no=transaction_detail.get("StraceNo"),
        )
    except httpx.RequestError as e:
        raise UnavailableError(resource_type="Saman Verify Service") from e
    except Exception as e:
        raise InternalError() from e

archipy.adapters.internet_payment_gateways.ir.saman.adapters.AsyncSamanShaparakPaymentAdapter.reverse_payment async

reverse_payment(
    request: ReverseRequestDTO,
) -> ReverseResponseDTO

Reverse a transaction (async).

Parameters:

Name Type Description Default
request ReverseRequestDTO

Reverse request with reference number.

required

Returns:

Name Type Description
ReverseResponseDTO ReverseResponseDTO

Response containing reversal result.

Raises:

Type Description
UnavailableError

If the reverse service is unavailable.

InternalError

If an unexpected error occurs.

Source code in archipy/adapters/internet_payment_gateways/ir/saman/adapters.py
async def reverse_payment(self, request: ReverseRequestDTO) -> ReverseResponseDTO:
    """Reverse a transaction (async).

    Args:
        request: Reverse request with reference number.

    Returns:
        ReverseResponseDTO: Response containing reversal result.

    Raises:
        UnavailableError: If the reverse service is unavailable.
        InternalError: If an unexpected error occurs.
    """
    try:
        payload = {"RefNum": request.reference_number, "TerminalNumber": int(self.terminal_id)}
        resp = await self.client.post(self.reverse_url, json=payload)
        resp.raise_for_status()
        data = resp.json()

        return ReverseResponseDTO(
            success=data.get("Success", False),
            result_code=data.get("ResultCode", -1),
            result_description=data.get("ResultDescription", "Unknown"),
        )
    except httpx.RequestError as e:
        raise UnavailableError(resource_type="Saman Reverse Service") from e
    except Exception as e:
        raise InternalError() from e

archipy.adapters.internet_payment_gateways.ir.saman.adapters.AsyncSamanNeoPgShaparakPaymentAdapter

Bases: AsyncSamanShaparakPaymentAdapter

Async Saman Neo-PG (New Generation) Adapter - Uses dynamic X-IPG-Url.

Async implementation extending AsyncSamanShaparakPaymentAdapter to capture the dynamic payment page URL from the X-IPG-Url header in the token response.

Source code in archipy/adapters/internet_payment_gateways/ir/saman/adapters.py
class AsyncSamanNeoPgShaparakPaymentAdapter(AsyncSamanShaparakPaymentAdapter):
    """Async Saman Neo-PG (New Generation) Adapter - Uses dynamic X-IPG-Url.

    Async implementation extending AsyncSamanShaparakPaymentAdapter to capture
    the dynamic payment page URL from the X-IPG-Url header in the token response.
    """

    async def initiate_payment(self, request: PaymentRequestDTO) -> PaymentResponseDTO:
        """Override to capture dynamic neo-pg URL from header (async).

        Args:
            request: Payment request data.

        Returns:
            PaymentResponseDTO: Response containing token, status, and IPG URL.

        Raises:
            UnavailableError: If the payment service is unavailable.
            InternalError: If an unexpected error occurs.
        """
        try:
            payload = {
                "action": "token",
                "TerminalId": self.terminal_id,
                "Amount": request.amount,
                "ResNum": request.res_num,
                "RedirectUrl": str(request.redirect_url),
                "CellNumber": request.cell_number,
                "Wage": request.wage,
                "TokenExpiryInMin": request.token_expiry_in_min,
                "HashedCardNumber": request.hashed_card_number,
            }
            payload = {k: v for k, v in payload.items() if v is not None}

            resp = await self.client.post(self.payment_url, json=payload)
            resp.raise_for_status()
            data = resp.json()

            ipg_url = resp.headers.get("X-IPG-Url")

            return PaymentResponseDTO(
                status=data.get("status"),
                token=data.get("token"),
                error_code=data.get("errorCode"),
                error_desc=data.get("errorDesc"),
                ipg_url=ipg_url,
            )
        except httpx.RequestError as e:
            raise UnavailableError(resource_type="Saman Neo-PG Token Service") from e
        except Exception as e:
            raise InternalError() from e

archipy.adapters.internet_payment_gateways.ir.saman.adapters.AsyncSamanNeoPgShaparakPaymentAdapter.terminal_id instance-attribute

terminal_id = TERMINAL_ID

archipy.adapters.internet_payment_gateways.ir.saman.adapters.AsyncSamanNeoPgShaparakPaymentAdapter.payment_url instance-attribute

payment_url = str(PAYMENT_URL)

archipy.adapters.internet_payment_gateways.ir.saman.adapters.AsyncSamanNeoPgShaparakPaymentAdapter.verify_url instance-attribute

verify_url = str(VERIFY_URL)

archipy.adapters.internet_payment_gateways.ir.saman.adapters.AsyncSamanNeoPgShaparakPaymentAdapter.reverse_url instance-attribute

reverse_url = str(REVERSE_URL)

archipy.adapters.internet_payment_gateways.ir.saman.adapters.AsyncSamanNeoPgShaparakPaymentAdapter.client instance-attribute

client = AsyncClient(proxy=proxy, timeout=30)

archipy.adapters.internet_payment_gateways.ir.saman.adapters.AsyncSamanNeoPgShaparakPaymentAdapter.initiate_payment async

initiate_payment(
    request: PaymentRequestDTO,
) -> PaymentResponseDTO

Override to capture dynamic neo-pg URL from header (async).

Parameters:

Name Type Description Default
request PaymentRequestDTO

Payment request data.

required

Returns:

Name Type Description
PaymentResponseDTO PaymentResponseDTO

Response containing token, status, and IPG URL.

Raises:

Type Description
UnavailableError

If the payment service is unavailable.

InternalError

If an unexpected error occurs.

Source code in archipy/adapters/internet_payment_gateways/ir/saman/adapters.py
async def initiate_payment(self, request: PaymentRequestDTO) -> PaymentResponseDTO:
    """Override to capture dynamic neo-pg URL from header (async).

    Args:
        request: Payment request data.

    Returns:
        PaymentResponseDTO: Response containing token, status, and IPG URL.

    Raises:
        UnavailableError: If the payment service is unavailable.
        InternalError: If an unexpected error occurs.
    """
    try:
        payload = {
            "action": "token",
            "TerminalId": self.terminal_id,
            "Amount": request.amount,
            "ResNum": request.res_num,
            "RedirectUrl": str(request.redirect_url),
            "CellNumber": request.cell_number,
            "Wage": request.wage,
            "TokenExpiryInMin": request.token_expiry_in_min,
            "HashedCardNumber": request.hashed_card_number,
        }
        payload = {k: v for k, v in payload.items() if v is not None}

        resp = await self.client.post(self.payment_url, json=payload)
        resp.raise_for_status()
        data = resp.json()

        ipg_url = resp.headers.get("X-IPG-Url")

        return PaymentResponseDTO(
            status=data.get("status"),
            token=data.get("token"),
            error_code=data.get("errorCode"),
            error_desc=data.get("errorDesc"),
            ipg_url=ipg_url,
        )
    except httpx.RequestError as e:
        raise UnavailableError(resource_type="Saman Neo-PG Token Service") from e
    except Exception as e:
        raise InternalError() from e

archipy.adapters.internet_payment_gateways.ir.saman.adapters.AsyncSamanNeoPgShaparakPaymentAdapter.verify_payment async

verify_payment(
    request: VerifyRequestDTO,
) -> VerifyResponseDTO

Step 3: Verify transaction (async, strongly recommended).

Parameters:

Name Type Description Default
request VerifyRequestDTO

Verify request with reference number.

required

Returns:

Name Type Description
VerifyResponseDTO VerifyResponseDTO

Response containing transaction details.

Raises:

Type Description
UnavailableError

If the verify service is unavailable.

InternalError

If an unexpected error occurs.

Source code in archipy/adapters/internet_payment_gateways/ir/saman/adapters.py
async def verify_payment(self, request: VerifyRequestDTO) -> VerifyResponseDTO:
    """Step 3: Verify transaction (async, strongly recommended).

    Args:
        request: Verify request with reference number.

    Returns:
        VerifyResponseDTO: Response containing transaction details.

    Raises:
        UnavailableError: If the verify service is unavailable.
        InternalError: If an unexpected error occurs.
    """
    try:
        payload = {"RefNum": request.reference_number, "TerminalNumber": int(self.terminal_id)}

        resp = await self.client.post(self.verify_url, json=payload)
        resp.raise_for_status()
        data = resp.json()

        transaction_detail = data.get("TransactionDetail", {})
        return VerifyResponseDTO(
            success=data.get("Success", False),
            result_code=data.get("ResultCode", -1),
            result_description=data.get("ResultDescription", "Unknown"),
            rrn=transaction_detail.get("RRN"),
            reference_number=transaction_detail.get("RefNum"),
            masked_pan=transaction_detail.get("MaskedPan"),
            hashed_pan=transaction_detail.get("HashedPan"),
            original_amount=transaction_detail.get("OrginalAmount"),
            affective_amount=transaction_detail.get("AffectiveAmount"),
            trace_no=transaction_detail.get("StraceNo"),
        )
    except httpx.RequestError as e:
        raise UnavailableError(resource_type="Saman Verify Service") from e
    except Exception as e:
        raise InternalError() from e

archipy.adapters.internet_payment_gateways.ir.saman.adapters.AsyncSamanNeoPgShaparakPaymentAdapter.reverse_payment async

reverse_payment(
    request: ReverseRequestDTO,
) -> ReverseResponseDTO

Reverse a transaction (async).

Parameters:

Name Type Description Default
request ReverseRequestDTO

Reverse request with reference number.

required

Returns:

Name Type Description
ReverseResponseDTO ReverseResponseDTO

Response containing reversal result.

Raises:

Type Description
UnavailableError

If the reverse service is unavailable.

InternalError

If an unexpected error occurs.

Source code in archipy/adapters/internet_payment_gateways/ir/saman/adapters.py
async def reverse_payment(self, request: ReverseRequestDTO) -> ReverseResponseDTO:
    """Reverse a transaction (async).

    Args:
        request: Reverse request with reference number.

    Returns:
        ReverseResponseDTO: Response containing reversal result.

    Raises:
        UnavailableError: If the reverse service is unavailable.
        InternalError: If an unexpected error occurs.
    """
    try:
        payload = {"RefNum": request.reference_number, "TerminalNumber": int(self.terminal_id)}
        resp = await self.client.post(self.reverse_url, json=payload)
        resp.raise_for_status()
        data = resp.json()

        return ReverseResponseDTO(
            success=data.get("Success", False),
            result_code=data.get("ResultCode", -1),
            result_description=data.get("ResultDescription", "Unknown"),
        )
    except httpx.RequestError as e:
        raise UnavailableError(resource_type="Saman Reverse Service") from e
    except Exception as e:
        raise InternalError() from e

options: show_root_toc_entry: false heading_level: 3