tingee-sdk 0.4.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
tingee_sdk/__init__.py ADDED
@@ -0,0 +1,53 @@
1
+ """
2
+ Tingee SDK for Python
3
+
4
+ Official SDK for Tingee Open API. DTO types are in ``tingee_sdk.models``.
5
+ """
6
+
7
+ from .bank_constants import (
8
+ BANKS,
9
+ BANKS_OBJECT,
10
+ BankAccountTypeEnum,
11
+ BankBinEnum,
12
+ BankNameEnum,
13
+ get_bank_bin,
14
+ get_bank_code,
15
+ get_bank_short_name,
16
+ )
17
+ from .client import ENVIRONMENT_URLS, TingeeClient, TingeeEnvironment
18
+ from .http import TingeeHttpError
19
+ from .response import TingeeApiResponse, is_error_response, is_success_response
20
+ from .signature import (
21
+ URL_VALIDATION_EVENT,
22
+ create_url_validation_response,
23
+ format_timestamp,
24
+ generate_signature,
25
+ verify_webhook_signature,
26
+ )
27
+ from .version import SDK_VERSION
28
+
29
+ __version__ = SDK_VERSION
30
+
31
+ __all__ = [
32
+ "TingeeClient",
33
+ "TingeeEnvironment",
34
+ "ENVIRONMENT_URLS",
35
+ "TingeeHttpError",
36
+ "TingeeApiResponse",
37
+ "is_success_response",
38
+ "is_error_response",
39
+ "generate_signature",
40
+ "format_timestamp",
41
+ "verify_webhook_signature",
42
+ "create_url_validation_response",
43
+ "URL_VALIDATION_EVENT",
44
+ "BankNameEnum",
45
+ "BankBinEnum",
46
+ "BankAccountTypeEnum",
47
+ "BANKS",
48
+ "BANKS_OBJECT",
49
+ "get_bank_code",
50
+ "get_bank_short_name",
51
+ "get_bank_bin",
52
+ "SDK_VERSION",
53
+ ]
@@ -0,0 +1,92 @@
1
+ """Bank constants (same as the other SDKs)."""
2
+
3
+ from enum import Enum
4
+ from typing import Dict, List, Optional, TypedDict
5
+
6
+ __all__ = [
7
+ "BankNameEnum",
8
+ "BankBinEnum",
9
+ "BankAccountTypeEnum",
10
+ "BankInfo",
11
+ "BANKS_OBJECT",
12
+ "BANKS",
13
+ "get_bank_code",
14
+ "get_bank_short_name",
15
+ "get_bank_bin",
16
+ ]
17
+
18
+
19
+ class BankNameEnum(str, Enum):
20
+ OCB = "OCB"
21
+ BIDV = "BIDV"
22
+ MBB = "MBB"
23
+ ACB = "ACB"
24
+ VPB = "VPB"
25
+ PGB = "PGB"
26
+ VIB = "VIB"
27
+ STB = "STB"
28
+ CTG = "CTG"
29
+ VCB = "VCB"
30
+ AGRIBANK = "AGRIBANK"
31
+ SHINHAN = "SHINHAN"
32
+ COB = "COB"
33
+
34
+
35
+ class BankBinEnum(str, Enum):
36
+ OCB = "970448"
37
+ BIDV = "970418"
38
+ MBB = "970422"
39
+ ACB = "970416"
40
+ VPB = "970432"
41
+ PGB = "970430"
42
+ VIB = "970441"
43
+ STB = "970403"
44
+ CTG = "970415"
45
+ VCB = "970436"
46
+ AGRIBANK = "970405"
47
+ SHINHAN = "970424"
48
+ COB = "970446"
49
+
50
+
51
+ class BankAccountTypeEnum(str, Enum):
52
+ PersonalAccount = "personal-account"
53
+ BusinessAccount = "business-account"
54
+ BusinessHouseHoldAccount = "business-household-account"
55
+
56
+
57
+ class BankInfo(TypedDict):
58
+ code: BankNameEnum
59
+ name: str
60
+ shortName: str
61
+ bin: str
62
+
63
+
64
+ BANKS_OBJECT: Dict[BankNameEnum, BankInfo] = {
65
+ BankNameEnum.VCB: {"code": BankNameEnum.VCB, "name": "Ngân hàng TMCP Ngoại Thương Việt Nam", "bin": "970436", "shortName": "Vietcombank"},
66
+ BankNameEnum.CTG: {"code": BankNameEnum.CTG, "name": "Ngân hàng TMCP Công thương Việt Nam", "bin": "970415", "shortName": "VietinBank"},
67
+ BankNameEnum.BIDV: {"code": BankNameEnum.BIDV, "name": "Ngân hàng TMCP Đầu tư và Phát triển Việt Nam", "bin": "970418", "shortName": "BIDV"},
68
+ BankNameEnum.AGRIBANK: {"code": BankNameEnum.AGRIBANK, "name": "Ngân hàng Nông nghiệp và Phát triển Nông thôn Việt Nam", "bin": "970405", "shortName": "Agribank"},
69
+ BankNameEnum.MBB: {"code": BankNameEnum.MBB, "name": "Ngân hàng TMCP Quân đội", "bin": "970422", "shortName": "MB Bank"},
70
+ BankNameEnum.ACB: {"code": BankNameEnum.ACB, "name": "Ngân hàng TMCP Á Châu", "bin": "970416", "shortName": "ACB"},
71
+ BankNameEnum.OCB: {"code": BankNameEnum.OCB, "name": "Ngân hàng TMCP Phương Đông", "bin": "970448", "shortName": "OCB Bank"},
72
+ BankNameEnum.VPB: {"code": BankNameEnum.VPB, "name": "Ngân hàng TMCP Việt Nam Thịnh Vượng", "bin": "970432", "shortName": "VPBank"},
73
+ BankNameEnum.STB: {"code": BankNameEnum.STB, "name": "Ngân hàng TMCP Sài Gòn Thương Tín", "bin": "970403", "shortName": "Sacombank"},
74
+ BankNameEnum.VIB: {"code": BankNameEnum.VIB, "name": "Ngân hàng TMCP Quốc tế Việt Nam", "bin": "970441", "shortName": "VIB"},
75
+ BankNameEnum.PGB: {"code": BankNameEnum.PGB, "name": "Ngân Hàng TMCP Thịnh vượng và Phát triển", "bin": "970430", "shortName": "PGBank"},
76
+ BankNameEnum.SHINHAN: {"code": BankNameEnum.SHINHAN, "name": "Ngân hàng TNHH MTV Shinhan Việt Nam", "bin": "970424", "shortName": "Shinhan Bank"},
77
+ BankNameEnum.COB: {"code": BankNameEnum.COB, "name": "Ngân hàng Hợp tác Xã Việt Nam", "bin": "970446", "shortName": "Co-opBank"},
78
+ }
79
+
80
+ BANKS: List[BankInfo] = list(BANKS_OBJECT.values())
81
+
82
+
83
+ def get_bank_code(bank_bin: str) -> Optional[BankNameEnum]:
84
+ return next((x["code"] for x in BANKS if x["bin"] == bank_bin), None)
85
+
86
+
87
+ def get_bank_short_name(bank_bin: str) -> Optional[str]:
88
+ return next((x["shortName"] for x in BANKS if x["bin"] == bank_bin), None)
89
+
90
+
91
+ def get_bank_bin(bank_name: BankNameEnum) -> Optional[str]:
92
+ return next((x["bin"] for x in BANKS if x["code"] == bank_name), None)
tingee_sdk/client.py ADDED
@@ -0,0 +1,76 @@
1
+ from typing import Any, Dict, Literal, Optional, Union
2
+
3
+ from .generated_methods import GeneratedMethods
4
+ from .http import TingeeHttpClient
5
+ from .signature import create_url_validation_response, verify_webhook_signature
6
+
7
+ __all__ = ["TingeeClient", "TingeeEnvironment", "ENVIRONMENT_URLS"]
8
+
9
+ TingeeEnvironment = Literal["production", "uat"]
10
+
11
+ ENVIRONMENT_URLS: Dict[str, str] = {
12
+ "production": "https://open-api.tingee.vn",
13
+ "uat": "https://uat-open-api.tingee.vn",
14
+ }
15
+
16
+
17
+ class TingeeClient(GeneratedMethods):
18
+ """
19
+ Tingee Open API client.
20
+
21
+ Example::
22
+
23
+ client = TingeeClient(secret_key="...", client_id="...", environment="uat")
24
+ result = client.bank.get_banks()
25
+ if result["code"] == "00":
26
+ print(result["data"])
27
+ """
28
+
29
+ def __init__(
30
+ self,
31
+ secret_key: str,
32
+ client_id: str,
33
+ environment: TingeeEnvironment = "production",
34
+ timeout: float = 90,
35
+ base_url: Optional[str] = None,
36
+ ) -> None:
37
+ """
38
+ :param secret_key: Secret key for generating request signature
39
+ :param client_id: Client ID for API authentication
40
+ :param environment: ``production`` (default) or ``uat``
41
+ :param timeout: Request timeout in seconds (default 90)
42
+ :param base_url: Custom base URL (overrides environment)
43
+ """
44
+ if not secret_key:
45
+ raise ValueError("secret_key is required")
46
+ if not client_id:
47
+ raise ValueError("client_id is required")
48
+ if environment not in ENVIRONMENT_URLS and not base_url:
49
+ raise ValueError("environment must be one of: {0}".format(", ".join(ENVIRONMENT_URLS)))
50
+
51
+ self._secret_key = secret_key
52
+ self._base_url = base_url or ENVIRONMENT_URLS[environment]
53
+ super().__init__(TingeeHttpClient(self._base_url, secret_key, client_id, timeout))
54
+
55
+ def get_base_url(self) -> str:
56
+ return self._base_url
57
+
58
+ def verify_webhook_signature(
59
+ self,
60
+ signature: Optional[str],
61
+ timestamp: Optional[str],
62
+ body: Union[Dict[str, Any], str, bytes, None],
63
+ ) -> Dict[str, str]:
64
+ """Verify an incoming Tingee webhook signature using this client's secret_key."""
65
+ return verify_webhook_signature(self._secret_key, signature, timestamp, body)
66
+
67
+ def create_url_validation_response(
68
+ self,
69
+ body: Union[Dict[str, Any], str, bytes, None],
70
+ secret_token: Optional[str] = None,
71
+ ) -> Optional[Dict[str, str]]:
72
+ """
73
+ Build the response for a webhook URL validation request, ``None`` if body is not one.
74
+ Pass ``secret_token`` when your "Webhook verification" credential differs from this client's.
75
+ """
76
+ return create_url_validation_response(secret_token or self._secret_key, body)