"""
YenePay PDT model.
"""
import re
from pprint import pformat
from requests import codes
from yenepay.api import ApiRequest
from yenepay.exceptions import CheckoutError
[docs]class PDT:
"""A class to checks the latest status of a payment order"""
def __init__(
self,
client,
merchant_order_id: str,
transaction_id: str,
use_sandbox=False,
) -> None:
"""
:param client: yenepay client account
:type client: :class:`yenepay.models.client.Client`
:param transaction_id: a unique identifier id of the payment
transaction that is set on YenePay’s platform. This id can
be obtained from your SuccessUrl or IPNUrl endpoints.
:type transaction_id: :func:`str`
:param merchant_order_id: the order id for this transaction that is
set on your platform.
:type merchant_order_id: :func:`str`
:param use_sandbox: Use sandbox environment. Default is False.
:type use_sandbox: Optional :func:`bool`
:rtype: :obj:`None`
"""
self._client = client
self.merchantOrderId = merchant_order_id
self.transactionId = transaction_id
self.use_sandbox = use_sandbox
@property
def requestType(self) -> str:
"""
:return: PDT request type. always `PDT`
:rtype: :func:`str`
"""
return "PDT"
@property
def request_type(self) -> str:
"""
:return: PDT request type. alway `PDT`
:rtype: :func:`str`
"""
return self.requestType
@property
def token(self) -> str:
"""
:return: client pdt token.
:rtype: :func:`str`
"""
return self._client.pdtToken
@property
def pdtToken(self) -> str:
"""
:return: client pdt token.
:rtype: :func:`str`
"""
return self._client.pdtToken
@property
def transaction_id(self) -> str:
"""
:return: checkout transaction id.
:rtype: :func:`str`
"""
return self.transactionId
@transaction_id.setter
def transaction_id(self, value: str) -> None:
"""set transaction id."""
self.transactionId = value
@property
def merchant_order_id(self) -> str:
"""
:return: checkout merchant order id.
:rtype: :func:`str`
"""
return self.merchantOrderId
@merchant_order_id.setter
def merchant_order_id(self, value: str) -> None:
"""set merchant order id."""
self.merchantOrderId = value
@property
def is_sandbox(self) -> bool:
"""
check client running sandbox environment.
:rtype: :func:`bool`
"""
return self.use_sandbox
[docs] def to_dict(self) -> dict:
"""
Convert PDT properties into dictionary object.
:return: dictionary of PDT properties
:rtype: :func:`dict`
"""
return {
"requestType": self.requestType,
"pdtToken": self.pdtToken,
"transactionId": self.transactionId,
"merchantOrderId": self.merchantOrderId,
}
[docs] def check_status(self):
"""
Check the latest status of a given payment order.
:return: PDT Status
:rtype: :class:`yenepay.models.pdt.PDTResponse`
"""
status_code, response = ApiRequest.pdt(self.to_dict(), self.is_sandbox)
if status_code == codes.ok:
return PDTResponse(response, self)
else:
raise CheckoutError(pformat(response))
def __repr__(self) -> str:
"""return pdt representation."""
return "<PDT {}>".format(self.pdtToken)
def __str__(self) -> str:
"""return pdt string representation."""
return self.__repr__()
[docs]class PDTResponse:
"""PDT status resposen class."""
def __init__(self, response: str, pdt: PDT) -> None:
"""
:param response: Actutal response from api endpoint.
:type response: :func:`str`
:param pdt: a PDT instance that reqest in sent from.
:type pdt: :class:`yenepay.models.pdt.PDT`
:rtype: :obj:`None`
"""
self._response = response
self.pdt = pdt
pattern = r"(?:(\w+)=(\w+))"
matches = re.findall(pattern, self._response)
for attr, value in matches:
setattr(self, self._to_python_attr(attr), value)
def _to_python_attr(self, attr: str) -> str:
"""return a given attribute name into snake case.
>>> response = PDTResponse("status=success", None)
>>> response._to_python_attr("TotalAmount")
'total_amount'
>>> response._to_python_attr("Status")
'status'
>>> response._to_python_attr("BuyerID")
'buyer_id'
"""
pattern = r"(?:[A-Z])[a-z0-9_]*"
attr = attr.replace("ID", "Id")
matches = re.findall(pattern, attr)
return "_".join((match.lower() for match in matches))