Coverage for packages/azericard/src/integrify/azericard/schemas/response.py: 98%
93 statements
« prev ^ index » next coverage.py v7.16.0, created at 2026-10-19 02:39 +0000
« prev ^ index » next coverage.py v7.16.0, created at 2026-10-19 02:39 +0000
1from datetime import datetime
2from decimal import Decimal
3from hashlib import md5
4from typing import ClassVar
6from integrify.azericard import env
7from integrify.azericard.schemas.enums import (
8 Action,
9 AuthorizationResponseType,
10 AuthorizationType,
11 TransferStatusCode,
12)
13from integrify.azericard.utils import TimeStampIn
14from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator
15from pydantic.alias_generators import to_pascal
16from typing_extensions import Self
19class GetTransactionStatusResponseSchema(BaseModel):
20 action: Action = Field(validation_alias='ACTION')
21 """Sorğu üçün orijinal əməliyyat"""
23 rc: str = Field(validation_alias='Response code')
24 """Sorğu üçün orijinal əməliyyat kodu (ISO-8583 Sahə 39)"""
26 status_message: str = Field(validation_alias='Transaction Status message')
27 """Orijinal əməliyyat statusu mesajı"""
29 terminal: str = Field(validation_alias='TERMINAL')
30 """Orijinal əməliyyat Terminal ID"""
32 card_number: str = Field(validation_alias='Card number')
33 """Orijinal əməliyyat maskalı kart nömrəsi"""
35 amount: Decimal = Field(validation_alias='Transaction amount')
36 """Orijinal əməliyyat məbləği"""
38 currency: str = Field(validation_alias='Transaction currency')
39 """Orijinal əməliyyat valyutası"""
41 date: datetime = Field(validation_alias='Transaction date')
42 """Orijinal əməliyyat tarixi"""
44 state: str = Field(validation_alias='Transaction state')
45 """Orijinal əməliyyat vəziyyəti"""
47 order: str = Field(validation_alias='Merchant order id')
48 """Orijinal əməliyyat ORDER ID-si"""
50 approval: str = Field(validation_alias='Banks approval code')
51 """Orijinal əməliyyatın təsdiq kodu"""
53 rrn: str = Field(validation_alias='Transaction RRN')
54 """Orijinal əməliyyat RRN"""
56 int_ref: str = Field(validation_alias='INT_REF')
57 """Orijinal əməliyyat INT_REF"""
59 trtype: AuthorizationType | AuthorizationResponseType = Field(
60 validation_alias='Original transaction TRTYPE'
61 )
62 """Orijinal əməliyyat TRTYPE"""
64 timestamp: TimeStampIn = Field(validation_alias='Timestamp')
65 """Sorğunun vaxtı"""
67 nonce: str = Field(validation_alias='Nonce')
68 """Orijinal əməliyyat Nonce"""
70 p_sign: str = Field(validation_alias='P_SIGN')
71 """16-lıq formada E-Commerce Gateway MAC (Message Authentication Code).
72 MAC istifadə edilərsə mövcud olacaq."""
74 @field_validator('timestamp', 'date', mode='before')
75 @classmethod
76 def validate_timestamp(cls, val: datetime | str) -> datetime:
77 """İnput string dəyərdirsə, datetime obyektinə çevirən funksiya"""
78 if isinstance(val, datetime): 78 ↛ 79line 78 didn't jump to line 79 because the condition on line 78 was never true
79 return val
81 return datetime.strptime(val, '%Y%m%d%H%M%S')
84class TransferDeclineResponseSchema(BaseModel):
85 SIGNATURE_FIELDS: ClassVar[list[str]] = [
86 'operation_id',
87 'srn',
88 'amount',
89 'cur',
90 'status',
91 'timestamp',
92 'response_code',
93 'message',
94 ]
95 """Signature hesablanılması üçün lazım olan field adları"""
97 model_config = ConfigDict(alias_generator=to_pascal)
99 operation_id: str
100 """Sorğu əməliyyatının ID-si"""
102 srn: str = Field(validation_alias='SRN')
103 """Unikal əməliyyat nömrəsi"""
105 amount: Decimal | None = None
106 """Ödəniş məbləği"""
108 cur: str | None = None
109 """Ödəniş valyutası"""
111 status: str | None = None
112 """Status Mesajı"""
114 timestamp: TimeStampIn | None = None
115 """Sorğunun vaxtı"""
117 response_code: TransferStatusCode | int
118 """Uğur(suz)luq kodu"""
120 message: str
121 """Mesaj"""
123 signature: str
124 """AzeriCard imzası"""
126 @model_validator(mode='after')
127 def validate_signature(self) -> Self:
128 """AzeriCard-dan gələn signature-ni təsdiqləmə funksiyası"""
129 assert self.SIGNATURE_FIELDS
131 source = ''
132 for field in self.SIGNATURE_FIELDS:
133 val = getattr(self, field) or ''
134 source += str(val)
136 with open(env.AZERICARD_KEY_FILE_PATH, encoding='utf-8') as key_file:
137 key = key_file.read().strip().replace('\r\n', '\n')
139 source += key
141 calc_signature = md5(source.encode('utf-8'), usedforsecurity=False).hexdigest()
143 assert calc_signature == self.signature, 'Signature does not match!'
145 return self
148class TransferConfirmResponseSchema(TransferDeclineResponseSchema):
149 SIGNATURE_FIELDS: ClassVar[list[str]] = [
150 'operation_id',
151 'srn',
152 'rrn',
153 'amount',
154 'cur',
155 'receiver_pan',
156 'status',
157 'timestamp',
158 'response_code',
159 'message',
160 ]
161 """Signature hesablanılması üçün lazım olan field adları"""
163 rrn: str = Field(validation_alias='RRN')
164 """Unikal əməliyyat nömrəsi"""
166 receiver_pan: str
167 """Maskalanmış kart nömrəsi"""