bugfix
This commit is contained in:
parent
08f1939601
commit
0b8d9f4bd6
15
json/transfercode.json
Normal file
15
json/transfercode.json
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"tblname": "transfercode",
|
||||||
|
"title": "转账码",
|
||||||
|
"params": {
|
||||||
|
"sortby": "id",
|
||||||
|
"browserfields": {
|
||||||
|
"exclouded": ["id"],
|
||||||
|
"alters": {
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"editexclouded": [
|
||||||
|
"id"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
models/transfercode.xlsx
Normal file
BIN
models/transfercode.xlsx
Normal file
Binary file not shown.
@ -8,6 +8,12 @@ from .payfee import get_pay_fee, sor_get_pay_fee, get_paychannels, get_pay_feera
|
|||||||
|
|
||||||
# 从 env 或配置载入 provider conf(这里只示例)
|
# 从 env 或配置载入 provider conf(这里只示例)
|
||||||
CONF = {
|
CONF = {
|
||||||
|
"transfer":{
|
||||||
|
"pop3server": os.getenv("POP3SERVER", ""),
|
||||||
|
"mail": os.getenv("MAIL", ""),
|
||||||
|
"password": os.getenv("PASSWORD", "")
|
||||||
|
"from_mail": os.getenv("FROM_MAIL", "")
|
||||||
|
}
|
||||||
"wechat": {
|
"wechat": {
|
||||||
"mchid": os.getenv("WXP_MCHID",""),
|
"mchid": os.getenv("WXP_MCHID",""),
|
||||||
"appid": os.getenv("WXP_APPID", ""),
|
"appid": os.getenv("WXP_APPID", ""),
|
||||||
@ -132,6 +138,7 @@ async def payment_notify(request, callback, params_kw=None):
|
|||||||
# callback url= "/unipay/notify/{provider}"
|
# callback url= "/unipay/notify/{provider}"
|
||||||
|
|
||||||
def load_unipay():
|
def load_unipay():
|
||||||
|
PROVIDERS["transfer"] = get_provider("transfer", CONF["transfer"]),
|
||||||
PROVIDERS["wechat"] = get_provider("wechat", CONF["wechat"]),
|
PROVIDERS["wechat"] = get_provider("wechat", CONF["wechat"]),
|
||||||
PROVIDERS["paypal"] = get_provider("paypal", CONF["paypal"]),
|
PROVIDERS["paypal"] = get_provider("paypal", CONF["paypal"]),
|
||||||
PROVIDERS["alipay"] = get_provider("alipay", CONF["alipay"]),
|
PROVIDERS["alipay"] = get_provider("alipay", CONF["alipay"]),
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
# unipay/notify.py
|
# unipay/notify.py
|
||||||
from typing import Dict
|
from typing import Dict
|
||||||
|
from appPublic.log import exception
|
||||||
|
from .providers.transfer import TransferGateway
|
||||||
from .providers.wechat import WechatGateway
|
from .providers.wechat import WechatGateway
|
||||||
from .providers.paypal import PaypalGateway
|
from .providers.paypal import PaypalGateway
|
||||||
from .providers.alipay import AlipayGateway
|
from .providers.alipay import AlipayGateway
|
||||||
@ -12,12 +14,15 @@ def get_provider_channel(name:str):
|
|||||||
"wechat":"0",
|
"wechat":"0",
|
||||||
"paypal":"1",
|
"paypal":"1",
|
||||||
"alipay":"2",
|
"alipay":"2",
|
||||||
"stripe":"3"
|
"stripe":"3",
|
||||||
|
"transfer":"4"
|
||||||
}
|
}
|
||||||
return channels.get(name, '9')
|
return channels.get(name, '9')
|
||||||
|
|
||||||
def get_provider(name: str, conf: Dict):
|
def get_provider(name: str, conf: Dict):
|
||||||
try:
|
try:
|
||||||
|
if name == "transfer":
|
||||||
|
return TransferGateway(**conf)
|
||||||
if name == "wechat":
|
if name == "wechat":
|
||||||
return WechatGateway(**conf)
|
return WechatGateway(**conf)
|
||||||
if name == "paypal":
|
if name == "paypal":
|
||||||
@ -26,7 +31,8 @@ def get_provider(name: str, conf: Dict):
|
|||||||
return AlipayGateway(**conf)
|
return AlipayGateway(**conf)
|
||||||
if name == "stripe":
|
if name == "stripe":
|
||||||
return StripeGateway(**conf)
|
return StripeGateway(**conf)
|
||||||
except:
|
except Exception as e:
|
||||||
|
exception(f'get_proveder() error {name=}, {conf=}, {e}')
|
||||||
return None
|
return None
|
||||||
raise ValueError("unknown provider")
|
raise ValueError("unknown provider")
|
||||||
|
|
||||||
|
|||||||
114
unipay/providers/transfer.py
Normal file
114
unipay/providers/transfer.py
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
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)
|
||||||
|
|
||||||
Loading…
x
Reference in New Issue
Block a user