Coverage for src/integrify/azericard/client.py: 100%

31 statements  

« prev     ^ index     » next       coverage.py v7.9.2, created at 2025-12-29 00:57 +0000

1from datetime import datetime 

2from typing import TYPE_CHECKING, Optional, Union 

3from typing import SupportsFloat as Numeric 

4 

5from integrify.api import APIClient, APIPayloadHandler, APIResponse 

6from integrify.azericard import env 

7from integrify.azericard.handler import ( 

8 AuthAndSavePayloadHandler, 

9 AuthConfirmPayloadHandler, 

10 AuthPayloadHandler, 

11 AuthWithSavedCardPayloadHandler, 

12 GetTransactionStatusPayloadHandler, 

13 TransferConfirmPayloadHandler, 

14 TransferStartPayloadHandler, 

15) 

16from integrify.azericard.schemas.enums import AuthorizationResponseType, AuthorizationType 

17from integrify.azericard.schemas.request.auth import MInfo 

18from integrify.azericard.schemas.response import ( 

19 GetTransactionStatusResponseSchema, 

20 TransferConfirmResponseSchema, 

21 TransferDeclineResponseSchema, 

22) 

23from integrify.schemas import DryResponse 

24from integrify.utils import _UNSET, Unsettable 

25 

26 

27class AzeriCardClientClass(APIClient): 

28 """AzeriCard sorğular üçün baza class""" 

29 

30 def __init__( 

31 self, 

32 name: str = 'AzeriCard', 

33 base_url: Optional[str] = None, 

34 default_handler: Optional[APIPayloadHandler] = None, 

35 sync: bool = True, 

36 dry: bool = False, 

37 ): 

38 super().__init__(name, base_url, default_handler, sync, dry) 

39 

40 self.add_url( 

41 'authorization', 

42 env.MpiAPI.AUTHORIZATION, 

43 'POST', 

44 base_url=env.MpiAPI.BASE_URL, 

45 ) 

46 self.add_handler('authorization', AuthPayloadHandler) 

47 

48 self.add_url( 

49 'finalize', 

50 env.MpiAPI.AUTHORIZATION, 

51 verb='POST', 

52 base_url=env.MpiAPI.BASE_URL, 

53 ) 

54 self.add_handler('finalize', AuthConfirmPayloadHandler) 

55 

56 self.add_url( 

57 'auth_and_save_card', 

58 env.MpiAPI.SAVE_CARD, 

59 verb='POST', 

60 base_url=env.MpiAPI.BASE_URL, 

61 ) 

62 self.add_handler('auth_and_save_card', AuthAndSavePayloadHandler) 

63 

64 self.add_url( 

65 'auth_with_saved_card', 

66 env.MpiAPI.SAVE_CARD, 

67 verb='POST', 

68 base_url=env.MpiAPI.BASE_URL, 

69 ) 

70 self.add_handler('auth_with_saved_card', AuthWithSavedCardPayloadHandler) 

71 

72 self.add_url( 

73 'get_transaction_status', 

74 env.MpiAPI.AUTHORIZATION, 

75 verb='POST', 

76 base_url=env.MpiAPI.BASE_URL, 

77 ) 

78 self.add_handler('get_transaction_status', GetTransactionStatusPayloadHandler) 

79 

80 self.add_url('transfer_start', env.MtAPI.TRANSFER, verb='GET', base_url=env.MtAPI.BASE_URL) 

81 self.add_handler('transfer_start', TransferStartPayloadHandler) 

82 

83 self.add_url( 

84 'transfer_confirm', 

85 env.MtAPI.TRANSFER_CONFIRM, 

86 verb='POST', 

87 base_url=env.MtAPI.BASE_URL, 

88 ) 

89 self.add_handler('transfer_confirm', TransferConfirmPayloadHandler) 

90 

91 self.add_url( 

92 'transfer_decline', 

93 env.MtAPI.TRANSFER_DECLINE, 

94 verb='POST', 

95 base_url=env.MtAPI.BASE_URL, 

96 ) 

97 

98 if TYPE_CHECKING: 

99 

100 def authorization( 

101 self, 

102 amount: Numeric, 

103 currency: str, 

104 order: str, 

105 desc: str, 

106 trtype: AuthorizationType, 

107 merch_name: str = env.AZERICARD_MERCHANT_NAME, # type: ignore[assignment] 

108 merch_url: str = env.AZERICARD_MERCHANT_EMAIL, # type: ignore[assignment] 

109 terminal: str = env.AZERICARD_MERCHANT_ID, # type: ignore[assignment] 

110 email: str = env.AZERICARD_MERCHANT_EMAIL, # type: ignore[assignment] 

111 country: Unsettable[str] = _UNSET, 

112 merch_gmt: Unsettable[str] = _UNSET, 

113 backref: str = env.AZERICARD_CALLBACK_URL, # type: ignore[assignment] 

114 timestamp: Union[datetime, str] = datetime.now(), 

115 lang: str = env.AZERICARD_INTERFACE_LANG, # type: ignore[assignment] 

116 name: Unsettable[str] = _UNSET, 

117 m_info: Unsettable[MInfo] = _UNSET, 

118 ) -> DryResponse: 

119 """Ümumi Ödəniş/Pul Dondurma/Dondurulmanı sorğusu 

120 

121 **Endpoint:** *https://{test}mpi.3dsecure.az/cgi-bin/cgi_link* 

122 

123 Example: 

124 ```python 

125 from integrify.azericard import AzeriCardClient 

126 from integrify.azericard.schemas.enums import AuthorizationType 

127 

128 AzeriCardClient.authorization(amount=100, currency='AZN', order='12345678', desc='Ödəniş', trype=AuthorizationType.FREEZE, name='Filankes') 

129 ``` 

130 

131 **Cavab formatı**: Yoxdur. Redirect baş verir, nəticə callback sorğusunda qayıdır. 

132 

133 Args: 

134 amount: Ödəniş miqdarı. Numerik dəyər. 

135 currency: Sifariş valyutası: 3 simvollu valyuta: (AZN) 

136 order: Satıcı sifariş ID-si, rəqəmsal. Son 6 rəqəm sistem izi audit nömrəsi kimi istifadə olunur, terminal id üçün bir gün ərzində unikal olmalıdır 

137 desc: Ödənişin təsviri/açıqlaması 

138 merch_name: Satıcının (merchant) adı (kart istifadəçisinin anladığı formada olmalıdır) 

139 merch_url: Satıcının web site URL-i 

140 terminal: Bank tərəfindən təyin edilmiş Merchant Terminal ID. Mühit dəyişəni kimi təyin olunmayıbsa, burada parametr kimi ötürülməlidir. 

141 trtype: Tranzaksiya növü: 0 (Pre-Avtorizasiya əməliyyatı, pulu bloklamaq/dondurmaq) və ya 1 (Avtorizasiya əməliyyatı, birbaşa ödəniş) 

142 email: Bildirişlər üçün Email ünvan. Qeyd olunmuş sahə doldurulduğu halda Gateway email ünvanı müəyyən etmək üçün əməliyyat nəticəsi haqqında bildiriş göndərə bilər 

143 country: Merchant shop 2 simvollu ölkə kodu. Merchant sistemi Gateway serverin yerləşdiyi ölkədən fərqli ölkədə yerləşirsə qeyd olunmalıdır 

144 merch_gmt: Merchant-ın UTC/GMT vaxt zonası. Merchant sistemi Gateway serverin yerləşdiyi vaxt zonasından fərqli vaxt zonasında yerləşirsə qeyd olunmalıdır 

145 backref: Avtorizasiya nəticəsinin yerləşdirilməsində(post) istifadə olunan Merchant URL 

146 timestamp: Merchant server-lə e-Gateway server arasında zaman fərqi 1 saatı aşmamalıdır, əks halda Gateway tranzaksiyaya imtina verəcək. Dəyər verilmədikdə, `now` avtomatik göndəriləcək 

147 lang: Dil seçimi 

148 name: Müştərinin adı (kartda göstərildiyi kimi) 

149 m_info: Əlavə məlumatlar. Məs: {"browserScreenHeight":"1920","browserScreenWidth":"1080","browserTZ":"0","mobilePhone":{"cc":"994","subscriber":"5077777777"}} 

150 """ # noqa: E501 

151 

152 def finalize( 

153 self, 

154 amount: Numeric, 

155 currency: str, 

156 order: str, 

157 rrn: str, 

158 int_ref: str, 

159 trtype: AuthorizationResponseType, 

160 terminal: str = env.AZERICARD_MERCHANT_ID, # type: ignore[assignment] 

161 timestamp: Union[datetime, str] = datetime.now(), 

162 ) -> DryResponse: 

163 """PreAuthorization (pulu bloklama) sorğusuna cavab və ya direkt ödənişi refund sorğusu 

164 

165 **Endpoint:** *https://{test}mpi.3dsecure.az/cgi-bin/cgi_link* 

166 

167 Example: 

168 ```python 

169 from integrify.azericard import AzeriCardClient 

170 from integrify.azericard.schemas.enums import AuthorizationResponseType 

171 

172 AzeriCardClient.finalize(amount=100, currency='AZN', order='12345678', rrn='payment_rrn', int_ref='int_ref', trtype=AuthorizationResponseType.ACCEPT_PAYMENT) 

173 ``` 

174 

175 **Cavab formatı**: 

176 

177 Args: 

178 amount: Ödəniş miqdarı. Numerik dəyər. 

179 currency: Sifariş valyutası: 3 simvollu valyuta: (AZN) 

180 order: Satıcı sifariş ID-si, rəqəmsal. Son 6 rəqəm sistem izi audit nömrəsi kimi istifadə olunur, terminal id üçün bir gün ərzində unikal olmalıdır 

181 rrn: Ödənişin RRN-i, Authorization sorğusuna response-da gəlir 

182 int_ref: Ödənişin referansı, Authorization sorğusuna response-da gəlir 

183 trtype: Tranzaksiya növü: 21 (Təsdiq), 22 (Geri qaytarma), 24 (Ləğv etmə, spesifik banklar üçün istifadə olunur) 

184 timestamp: Merchant server-lə e-Gateway server arasında zaman fərqi 1 saatı aşmamalıdır, əks halda Gateway tranzaksiyaya imtina verəcək. Dəyər verilmədikdə, `now` avtomatik göndəriləcək 

185 """ # noqa: E501 

186 

187 def auth_and_save_card( 

188 self, 

189 amount: Numeric, 

190 currency: str, 

191 order: str, 

192 desc: str, 

193 trtype: AuthorizationType, 

194 merch_name: str = env.AZERICARD_MERCHANT_NAME, # type: ignore[assignment] 

195 merch_url: str = env.AZERICARD_MERCHANT_EMAIL, # type: ignore[assignment] 

196 terminal: str = env.AZERICARD_MERCHANT_ID, # type: ignore[assignment] 

197 email: str = env.AZERICARD_MERCHANT_EMAIL, # type: ignore[assignment] 

198 country: Unsettable[str] = _UNSET, 

199 merch_gmt: Unsettable[str] = _UNSET, 

200 backref: str = env.AZERICARD_CALLBACK_URL, # type: ignore[assignment] 

201 timestamp: Union[datetime, str] = datetime.now(), 

202 lang: str = env.AZERICARD_INTERFACE_LANG, # type: ignore[assignment] 

203 name: Unsettable[str] = _UNSET, 

204 m_info: Unsettable[MInfo] = _UNSET, 

205 ) -> DryResponse: 

206 """Ümumi kartı saxlayaraq ödəniş sorğusu 

207 

208 **Endpoint:** *https://{test}mpi.3dsecure.az/token/cgi_link* 

209 

210 Example: 

211 ```python 

212 from integrify.azericard import AzeriCardClient 

213 from integrify.azericard.schemas.enums import AuthorizationType 

214 

215 AzeriCardClient.auth_and_save_card(amount=100, currency='AZN', order='12345678', desc='Ödəniş', trype=AuthorizationType.DIRECT, name='Filankes') 

216 ``` 

217 

218 **Cavab formatı**: Callback sorğu baş verir 

219 

220 Args: 

221 amount: Ödəniş miqdarı. Numerik dəyər. 

222 currency: Sifariş valyutası: 3 simvollu valyuta: (AZN) 

223 order: Satıcı sifariş ID-si, rəqəmsal. Son 6 rəqəm sistem izi audit nömrəsi kimi istifadə olunur, terminal id üçün bir gün ərzində unikal olmalıdır 

224 desc: Ödənişin təsviri/açıqlaması 

225 merch_name: Satıcının (merchant) adı (kart istifadəçisinin anladığı formada olmalıdır) 

226 merch_url: Satıcının web site URL-i 

227 trtype: Tranzaksiya növü = 0 (Pre-Avtorizasiya əməliyyatı, pulu bloklamaq/dondurmaq),Tranzaksiya növü = 1 (Avtorizasiya əməliyyatı) 

228 backref: Avtorizasiya nəticəsinin yerləşdirilməsində(post) istifadə olunan Merchant URL 

229 email: Bildirişlər üçün Email ünvan. Qeyd olunmuş sahə doldurulduğu halda Gateway email ünvanı müəyyən etmək üçün əməliyyat nəticəsi haqqında bildiriş göndərə bilər 

230 country: Merchant shop 2 simvollu ölkə kodu. Merchant sistemi Gateway serverin yerləşdiyi ölkədən fərqli ölkədə yerləşirsə qeyd olunmalıdır 

231 merch_gmt: Merchant-ın UTC/GMT vaxt zonası. Merchant sistemi Gateway serverin yerləşdiyi vaxt zonasından fərqli vaxt zonasında yerləşirsə qeyd olunmalıdır 

232 timestamp: Merchant server-lə e-Gateway server arasında zaman fərqi 1 saatı aşmamalıdır, əks halda Gateway tranzaksiyaya imtina verəcək. Dəyər verilmədikdə, `now` avtomatik göndəriləcək 

233 lang: Dil seçimi 

234 name: Müştərinin adı (kartda göstərildiyi kimi) 

235 m_info: Əlavə məlumatlar. Məs: {"browserScreenHeight":"1920","browserScreenWidth":"1080","browserTZ":"0","mobilePhone":{"cc":"994","subscriber":"5077777777"}} 

236 """ # noqa: E501 

237 

238 def auth_with_saved_card( 

239 self, 

240 amount: Numeric, 

241 currency: str, 

242 order: str, 

243 desc: str, 

244 trtype: AuthorizationType, 

245 token: str, 

246 merch_name: str = env.AZERICARD_MERCHANT_NAME, # type: ignore[assignment] 

247 merch_url: str = env.AZERICARD_MERCHANT_EMAIL, # type: ignore[assignment] 

248 terminal: str = env.AZERICARD_MERCHANT_ID, # type: ignore[assignment] 

249 email: str = env.AZERICARD_MERCHANT_EMAIL, # type: ignore[assignment] 

250 country: Unsettable[str] = _UNSET, 

251 merch_gmt: Unsettable[str] = _UNSET, 

252 backref: str = env.AZERICARD_CALLBACK_URL, # type: ignore[assignment] 

253 timestamp: Union[datetime, str] = datetime.now(), 

254 lang: str = env.AZERICARD_INTERFACE_LANG, # type: ignore[assignment] 

255 name: Unsettable[str] = _UNSET, 

256 m_info: Unsettable[MInfo] = _UNSET, 

257 ) -> DryResponse: 

258 """Ümumi saxlanmış kart ilə Authurization sorğusu 

259 

260 **Endpoint:** *https://{test}mpi.3dsecure.az/token/cgi_link* 

261 

262 Example: 

263 ```python 

264 from integrify.azericard import AzeriCardClient 

265 from integrify.azericard.schemas.enums import AuthorizationType 

266 

267 AzeriCardClient.auth_with_saved_card(amount=100, currency='AZN', order='12345678', desc='Ödəniş', trype=AuthorizationType.DIRECT, name='Filankes', token='card-token') 

268 ``` 

269 

270 **Cavab formatı**: Callback sorğu baş verir 

271 

272 Args: 

273 amount: Ödəniş miqdarı. Numerik dəyər. 

274 currency: Sifariş valyutası: 3 simvollu valyuta: (AZN) 

275 order: Satıcı sifariş ID-si, rəqəmsal. Son 6 rəqəm sistem izi audit nömrəsi kimi istifadə olunur, terminal id üçün bir gün ərzində unikal olmalıdır 

276 desc: Ödənişin təsviri/açıqlaması 

277 merch_name: Satıcının (merchant) adı (kart istifadəçisinin anladığı formada olmalıdır) 

278 merch_url: Satıcının web site URL-i 

279 trtype: Tranzaksiya növü = 0 (Pre-Avtorizasiya əməliyyatı, pulu bloklamaq/dondurmaq),Tranzaksiya növü = 1 (Avtorizasiya əməliyyatı) 

280 backref: Avtorizasiya nəticəsinin yerləşdirilməsində(post) istifadə olunan Merchant URL 

281 token: Yadda saxlanılmış kartın ID-si 

282 email: Bildirişlər üçün Email ünvan. Qeyd olunmuş sahə doldurulduğu halda Gateway email ünvanı müəyyən etmək üçün əməliyyat nəticəsi haqqında bildiriş göndərə bilər 

283 country: Merchant shop 2 simvollu ölkə kodu. Merchant sistemi Gateway serverin yerləşdiyi ölkədən fərqli ölkədə yerləşirsə qeyd olunmalıdır 

284 merch_gmt: Merchant-ın UTC/GMT vaxt zonası. Merchant sistemi Gateway serverin yerləşdiyi vaxt zonasından fərqli vaxt zonasında yerləşirsə qeyd olunmalıdır 

285 timestamp: Merchant server-lə e-Gateway server arasında zaman fərqi 1 saatı aşmamalıdır, əks halda Gateway tranzaksiyaya imtina verəcək. Dəyər verilmədikdə, `now` avtomatik göndəriləcək 

286 lang: Dil seçimi 

287 name: Müştərinin adı (kartda göstərildiyi kimi) 

288 m_info: Əlavə məlumatlar. Məs: {"browserScreenHeight":"1920","browserScreenWidth":"1080","browserTZ":"0","mobilePhone":{"cc":"994","subscriber":"5077777777"}} 

289 """ # noqa: E501 

290 

291 def get_transaction_status( 

292 self, 

293 tran_trtype: Union[AuthorizationType, AuthorizationResponseType], 

294 order: str, 

295 terminal: str = env.AZERICARD_MERCHANT_ID, # type: ignore[assignment] 

296 timestamp: Union[datetime, str] = datetime.now(), 

297 ) -> APIResponse[GetTransactionStatusResponseSchema]: 

298 """Bitmiş tranzaksiyanın statusunu alma sorğusu 

299 

300 **Endpoint:** *https://{test}mpi.3dsecure.az/cgi-bin/cgi_link* 

301 

302 Example: 

303 ```python 

304 from integrify.azericard import AzeriCardClient 

305 from integrify.azericard.schemas.enums import AuthorizationType 

306 

307 AzeriCardClient.get_transaction_status(tran_trtype=AuthorizationType.DIRECT, order='12345678') 

308 ``` 

309 

310 **Cavab formatı**: [`GetTransactionStatusResponseSchema`][integrify.azericard.schemas.response.GetTransactionStatusResponseSchema] 

311 

312 Args: 

313 tran_trtype: Sorğu üçün orijinal əməliyyat növü, TRTYPE (Məsələn: 0, 1, 22, 24 və s.) 

314 order: Satıcı sifariş ID-si, rəqəmsal. Son 6 rəqəm sistem izi audit nömrəsi kimi istifadə olunur, terminal id üçün bir gün ərzində unikal olmalıdır 

315 terminal: Bank tərəfindən təyin edilmiş Merchant Terminal ID. Mühit dəyişəni kimi təyin olunmayıbsa, burada parametr kimi ötürülməlidir. 

316 timestamp: Merchant server-lə e-Gateway server arasında zaman fərqi 1 saatı aşmamalıdır, əks halda Gateway tranzaksiyaya imtina verəcək. Dəyər verilmədikdə, `now` avtomatik göndəriləcək 

317 """ # noqa: E501 

318 

319 def transfer_start( 

320 self, 

321 merchant: str, 

322 srn: str, 

323 amount: Numeric, 

324 cur: str, 

325 receiver_credentials: str, 

326 redirect_link: str, 

327 ) -> DryResponse: 

328 """User-ə ödəniş etmək sorğusu 

329 

330 **Endpoint:** *https://{test}mt.3dsecure.az/payment/view* 

331 

332 Example: 

333 ```python 

334 from integrify.azericard import AzeriCardClient 

335 

336 AzeriCardClient.transfer_start(merchant='MyMerchant', srn='12345678', amount=100, cur='944', receiver_credentials='Filankəsov Filankəs', redirect_link='my-redirect-api-for-user') 

337 ``` 

338 

339 **Cavab formatı**: Callback sorğu baş verir 

340 

341 Args: 

342 merchant: Şirkət adı 

343 srn: Unikal əməliyyat nömrəsi 

344 amount: Ödəniş məbləği 

345 cur: Ödəniş valyutasının 3 rəqəmli kodu (944 - AZN) 

346 receiver_credentials: İstifadəçinin tam adı 

347 redirect_link: Əməliyyatın sonunda müştərini yönləndirmək istədiyiniz keçid linki 

348 """ # noqa: E501 

349 

350 def transfer_confirm( 

351 self, 

352 merchant: str, 

353 srn: str, 

354 amount: Numeric, 

355 cur: str, 

356 timestamp: Union[datetime, str] = datetime.now(), 

357 ) -> APIResponse[TransferConfirmResponseSchema]: 

358 """User-ə ödənişi təsdiqləmək sorğusu 

359 

360 **Endpoint:** *https://{test}mt.3dsecure.az/api/confirm* 

361 

362 Example: 

363 ```python 

364 from integrify.azericard import AzeriCardClient 

365 

366 AzeriCardClient.transfer_confirm(merchant='MyMerchant', srn='12345678', amount=100, cur='944') 

367 ``` 

368 

369 **Cavab formatı**: [TransferConfirmResponseSchema][integrify.azericard.schemas.response.TransferConfirmResponseSchema] 

370 

371 Args: 

372 merchant: Şirkət adı 

373 srn: Unikal əməliyyat nömrəsi 

374 amount: Ödəniş məbləği 

375 cur: Ödəniş valyutasının 3 rəqəmli kodu (944 - AZN) 

376 timestamp: Dəyər verilmədikdə, `now` avtomatik göndəriləcək 

377 """ # noqa: E501 

378 

379 def transfer_decline( 

380 self, 

381 merchant: str, 

382 srn: str, 

383 amount: Numeric, 

384 cur: str, 

385 timestamp: Union[datetime, str] = datetime.now(), 

386 ) -> APIResponse[TransferDeclineResponseSchema]: 

387 """User-ə ödənişi imtina etmək sorğusu 

388 

389 **Endpoint:** *https://{test}mt.3dsecure.az/api/decline* 

390 

391 Example: 

392 ```python 

393 from integrify.azericard import AzeriCardClient 

394 

395 AzeriCardClient.transfer_decline(merchant='MyMerchant', srn='12345678', amount=100, cur='944') 

396 ``` 

397 

398 **Cavab formatı**: [TransferDeclineResponseSchema][integrify.azericard.schemas.response.TransferDeclineResponseSchema] 

399 

400 Args: 

401 merchant: Şirkət adı 

402 srn: Unikal əməliyyat nömrəsi 

403 amount: Ödəniş məbləği 

404 cur: Ödəniş valyutasının 3 rəqəmli kodu (944 - AZN) 

405 timestamp: Dəyər verilmədikdə, `now` avtomatik göndəriləcək 

406 """ # noqa: E501 

407 

408 

409AzeriCardClient = AzeriCardClientClass(sync=True) 

410AzeriCardAsyncClient = AzeriCardClientClass(sync=False)