(20241216) Payment auth bug fix.
This commit is contained in:
@@ -6,11 +6,11 @@
|
||||
|
||||
DATE:
|
||||
|
||||
Friday, 13th Dec., 2024.
|
||||
Monday, 16th Dec., 2024.
|
||||
|
||||
OBJECTIVE:
|
||||
|
||||
To provide a structure to receive auth details of various software.
|
||||
To provide a structure to receive payment request details.
|
||||
|
||||
REFERENCES:
|
||||
|
||||
@@ -43,9 +43,18 @@ from typing import Optional, Literal, Union
|
||||
from utils_v2.string import regex
|
||||
from utils_v2.date_time import date_time
|
||||
|
||||
# Models:
|
||||
from models.core.payment import CorePaymentModel
|
||||
|
||||
# To work with date and time:
|
||||
import datetime
|
||||
|
||||
# To work with MongoDB:
|
||||
from bson.objectid import ObjectId
|
||||
|
||||
# To work with currencies:
|
||||
import pycountry
|
||||
|
||||
|
||||
# *****************************************************************************************************************
|
||||
# ***** ****
|
||||
@@ -75,41 +84,7 @@ REGEX_SESSION_TOKEN = r"^[a-f0-9]{8}-[a-f0-9]{4}-[1-5][a-f0-9]{3}-[89ab][a-f0-9]
|
||||
# *****************************************************************************************************************
|
||||
|
||||
|
||||
class SafaricomMPesaExpressAuth(BaseModel):
|
||||
|
||||
consumerKey: str = Field(
|
||||
description = "the app's consumer key given by safaricom; found in 'my apps'",
|
||||
frozen = True
|
||||
)
|
||||
|
||||
consumerSecret: str = Field(
|
||||
description = "the app's consumer secret given by safaricom; found in 'my apps'",
|
||||
frozen = True
|
||||
)
|
||||
|
||||
businessShortCode: str = Field(
|
||||
description = "your app's business short code; found in 'my apps'",
|
||||
frozen = True
|
||||
)
|
||||
|
||||
appPasskey: str = Field(
|
||||
description = "your app's passkey; taken from human representative",
|
||||
frozen = True
|
||||
)
|
||||
|
||||
# ┏┓ ┏•
|
||||
# ┃ ┏┓┏┓╋┓┏┓
|
||||
# ┗┛┗┛┛┗┛┗┗┫
|
||||
# ┛
|
||||
|
||||
class Config:
|
||||
extra = "forbid"
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
class PGAuthRequestHeaders(BaseModel):
|
||||
class PGPaymentRequestHeaders(BaseModel):
|
||||
|
||||
sessionToken: str = Field(
|
||||
description = "the session token of the user who is requesting the service",
|
||||
@@ -133,10 +108,112 @@ class PGAuthRequestHeaders(BaseModel):
|
||||
# ---------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
class PGAuthRequestData(BaseModel):
|
||||
class PGPaymentRequestData(BaseModel):
|
||||
|
||||
client: Literal["safaricomMPesaExpress"] = Field(alias = "client")
|
||||
auth: Union[SafaricomMPesaExpressAuth]
|
||||
# {
|
||||
# "customerMobileNumber": "",
|
||||
# "tokenId": "",
|
||||
# "description": "",
|
||||
# "payerNumber": "",
|
||||
# "amount": "",
|
||||
# "currency": "",
|
||||
# "emailAddress": "",
|
||||
# "reference": "",
|
||||
# }
|
||||
|
||||
tokenKey: ObjectId = Field(
|
||||
description = "the auth token to use to send this message",
|
||||
frozen = True,
|
||||
)
|
||||
|
||||
customerName: str | None = Field(
|
||||
description = "the name of the registered customer who must make the payment",
|
||||
frozen = True,
|
||||
default = None
|
||||
)
|
||||
|
||||
customerNo: str = Field(
|
||||
description = "the contact no. of the registered customer who must make the payment",
|
||||
frozen = True
|
||||
)
|
||||
|
||||
payerNo: str | None = Field(
|
||||
description = (
|
||||
"the phone no. to which the payment request will go;"
|
||||
"if not specified, the value of 'customerNo' should be used"
|
||||
),
|
||||
frozen = True,
|
||||
default = None
|
||||
)
|
||||
|
||||
email: str | None = Field(
|
||||
description = "the e-mail id of the registered customer",
|
||||
pattern = regex.REGEX_EMAIL_ID,
|
||||
frozen = True,
|
||||
default = None
|
||||
)
|
||||
|
||||
amount: float | int = Field(
|
||||
description = "the amount of money to be requested",
|
||||
frozen = True
|
||||
)
|
||||
|
||||
currencyCode: str = Field(
|
||||
description = "the three-letter iso 4217 code to identify the currency",
|
||||
frozen = True,
|
||||
examples = ["INR", "USD", "KES"]
|
||||
)
|
||||
|
||||
metadata: dict = Field(
|
||||
description = "any extra information about this payment",
|
||||
frozen = True
|
||||
)
|
||||
|
||||
# ┏┓ ┏•
|
||||
# ┃ ┏┓┏┓╋┓┏┓
|
||||
# ┗┛┗┛┛┗┛┗┗┫
|
||||
# ┛
|
||||
|
||||
class Config:
|
||||
extra = "forbid"
|
||||
arbitrary_types_allowed = True
|
||||
|
||||
# ┓┏ ┓• ┓ •
|
||||
# ┃┃┏┓┃┓┏┫┏┓╋┓┏┓┏┓
|
||||
# ┗┛┗┻┗┗┗┻┗┻┗┗┗┛┛┗
|
||||
|
||||
@field_validator("tokenKey", mode = "before")
|
||||
def parse_oid(cls, value):
|
||||
try: value = ObjectId(value)
|
||||
except: pass
|
||||
return value
|
||||
|
||||
@field_validator("currencyCode", mode = "before")
|
||||
def validate_currency(cls, value):
|
||||
currency = pycountry.currencies.get(alpha_3 = value)
|
||||
if currency is None: raise ValueError("invalid currency code, please use iso 4217 standard")
|
||||
return value
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
class PaymentRequestOneResult(BaseModel):
|
||||
|
||||
success: bool = Field(
|
||||
description = "whether, or not, the sms was successfully sent",
|
||||
default = False
|
||||
)
|
||||
|
||||
message: str | None = Field(
|
||||
description = "a brief message to summarize the result of the process",
|
||||
default = None
|
||||
)
|
||||
|
||||
paymentDetails: CorePaymentModel = Field(
|
||||
description = "the actual data of the payment",
|
||||
default = None
|
||||
)
|
||||
|
||||
# ┏┓ ┏•
|
||||
# ┃ ┏┓┏┓╋┓┏┓
|
||||
|
||||
Reference in New Issue
Block a user