unipay/unipay/providers/transfer.py
2025-12-16 18:29:59 +08:00

115 lines
3.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import re
from random import randint
import poplib
from appPublic.log import debug
from appPublic.dictObject import DictObject
from appPublic.timeUtils import curDateString, timestampstr
from email.parser import Parser
from email.header import decode_header
from email.utils import parseaddr
from ..core import Gateway
def guess_charset(msg):
charset = msg.get_charset()
if charset is None:
content_type = msg.get('Content-Type', '').lower()
pos = content_type.find('charset=')
if pos >= 0:
charset = content_type[pos + 8:].strip()
return charset
class EmailClient:
def __init__(self, pop3_server, emailaddress, password):
self.client = poplib.POP3(pop3_server)
self.client.user(emailaddress)
self.client.pass_(password)
def stat(self):
return self.client.stat()
def mail_list(self):
resp, mails, octets = self.client.list()
def get_mail(self, index):
resp, lines, octets = self.client.retr(index)
debug(f'{resp=}, {octets=}')
msg_content = b'\r\n'.join(lines).decode('utf-8')
msg = Parser().parsestr(msg_content)
mail = {
"mailfrom": msg.get('From'),
"mailto": msg.get('To'),
"subject": msg.get('Subject'),
"body": self.get_body(msg)
}
return DictObject(**mail)
def get_body(self, msg):
if msg.is_multipart():
parts = msg.get_payload()
content = ''
for part in parts:
content += self.get_body(part)
return content
else:
content_type = msg.get_content_type()
content = msg.get_payload(decode=True)
charset = guess_charset(msg)
if charset:
content = content.decode(charset)
else:
content = content.decode('utf-8')
return content
class TransferPay(Gateway):
def __init__(self, from_mail="", pop3server="", email="", password=""):
self.from_email = from_email
self.pop3server = pop3server
self.email = email
self.password = password
self.running = False
async def create_payment(self, payload: Dict[str, Any]) -> str:
"""
返回一个可以在 H5 里直接重定向的支付宝支付 URL
"""
ns = {
"id": payload["out_trade_no"],
"customerid": payload['customerid'],
"amount": payload["amount"],
"tcode": self.gen_mailcode(),
"curdate": curDateString(),
"curtime": timestampstr(),
"status": '0'
}
return
def get_transfer_data(self, mail):
assert mail.mailfrom == '95555@message.cmbchina.com'
assert mail.mailto == self.email
assert mail.body.startswith('动账业务通知')
ns = DictObject()
match = re.search(r'交易金额\s*[:]?\s*(\d+(?:\.\d+)?)', mail.body)
if match:
ns.amount = float(match.group(1))
p = r'摘要[:]\s*(\d{7})(?!\d)'
match = re.search(r'摘要[:]\s*(\d{7})(?!\d)', mail.body)
if match:
ns.code = match.group(1)
assert ns.amount
assert ns.code
return ns
def gen_mailcode(self):
c = '1'
for range(6):
c += randint(0,9)
return c
def run(self):
self.running = True
while self.running:
ec = EmailClient(self.pop3server, self.email, self.password)
mail = ec.get_mail(1)