bugfix
This commit is contained in:
parent
dcf7a239d4
commit
1cbe37d4a3
13
README.md
Normal file
13
README.md
Normal file
@ -0,0 +1,13 @@
|
||||
# 统一支付
|
||||
|
||||
支持微信,支付宝,paypal支持
|
||||
|
||||
## 支付重要信息
|
||||
支付重要信息都通过环境变量设置
|
||||
|
||||
### 微信支付
|
||||
|
||||
### 支付宝
|
||||
|
||||
### paypal
|
||||
|
||||
16
json/payment_log.json
Normal file
16
json/payment_log.json
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
"tblname": "payment_log",
|
||||
"title": "充值记录",
|
||||
"params": {
|
||||
"sortby": "init_timestamp desc",
|
||||
"browserfields": {
|
||||
"exclouded": ["id"],
|
||||
"logined_userorgid":"customerid",
|
||||
"alters": {
|
||||
}
|
||||
},
|
||||
"editexclouded": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
}
|
||||
BIN
models/payment_log.xlsx
Normal file
BIN
models/payment_log.xlsx
Normal file
Binary file not shown.
4
pyproject.toml
Normal file
4
pyproject.toml
Normal file
@ -0,0 +1,4 @@
|
||||
[build-system]
|
||||
requires = ["setuptools>=61", "wheel"]
|
||||
build-backend = "setuptools.build_meta"
|
||||
|
||||
15
setup.cfg
Normal file
15
setup.cfg
Normal file
@ -0,0 +1,15 @@
|
||||
[metadata]
|
||||
name=pricing
|
||||
version = 0.0.1
|
||||
description = A pricing module for online store
|
||||
author = "yu moqing"
|
||||
author_email = "yumoqing@gmail.com"
|
||||
readme = "README.md"
|
||||
license = "MIT"
|
||||
[options]
|
||||
packages = find:
|
||||
requires_python = ">=3.8"
|
||||
install_requires =
|
||||
apppublic
|
||||
ahserver
|
||||
sqlor
|
||||
Binary file not shown.
@ -1,7 +1,8 @@
|
||||
# init.py
|
||||
import os
|
||||
from unipay.notify import get_provider
|
||||
from unipay.notify import get_provider, get_provider_channel
|
||||
from ahserver.serverenv import ServerEnv
|
||||
from paylog import PaymentLog
|
||||
|
||||
# 从 env 或配置载入 provider conf(这里只示例)
|
||||
CONF = {
|
||||
@ -40,8 +41,21 @@ async def create_payment(request, params_kw=None):
|
||||
if provider not in PROVIDERS:
|
||||
return {"error":"unknown provider"}
|
||||
try:
|
||||
pl = PaymentLog(request._run_ns)
|
||||
channel = get_provider_channel(provider)
|
||||
userid = await get_suer()
|
||||
orgid = await get_userorgid()
|
||||
client_ip = request['client_ip']
|
||||
# userid, customerid, channel, payment_name, amount, client_ip, currency='CNY'
|
||||
payment_name = data.payment_name or "充值",
|
||||
amount = data.amount
|
||||
currency = data.currency
|
||||
id = await pl.new_log(userid, orgid, payment_name, amount, client_ip, currency=currency)
|
||||
if id:
|
||||
data.out_trade_no = id
|
||||
res = await PROVIDERS[provider].create_payment(data)
|
||||
return res
|
||||
raise Exception('write payment_log error')
|
||||
except Exception as e:
|
||||
return {"error": str(e)}
|
||||
|
||||
@ -86,6 +100,9 @@ async def payment_notify(request, callback, params_kw=None):
|
||||
# 这里 data 应包含标准化字段:out_trade_no/status/attach 等
|
||||
# TODO: 业务幂等处理
|
||||
# 返回厂商要求的固定成功响应
|
||||
logid = data['out_trade_no']
|
||||
pl = PaymentLog(request._run_ns)
|
||||
await pl.payed_log(logid)
|
||||
await callback(request, data)
|
||||
if provider == "wechat":
|
||||
return {"code":"SUCCESS", "message":"OK"}
|
||||
|
||||
@ -6,6 +6,16 @@ from .providers.alipay import AlipayGateway
|
||||
from .providers.stripe import StripeGateway
|
||||
|
||||
# 简单工厂:你可以按需扩展配置注入
|
||||
|
||||
def get_provider_channel(name:str):
|
||||
channels = {
|
||||
"wechat":"0",
|
||||
"paypal":"1",
|
||||
"alipay":"2",
|
||||
"stripe":"3"
|
||||
}
|
||||
return channels.get(name, '9')
|
||||
|
||||
def get_provider(name: str, conf: Dict):
|
||||
if name == "wechat":
|
||||
return WechatGateway(**conf)
|
||||
|
||||
48
unipay/paylog.py
Normal file
48
unipay/paylog.py
Normal file
@ -0,0 +1,48 @@
|
||||
from sqlor.dbpools import DBPools
|
||||
|
||||
class PaymentLog:
|
||||
def __init__(self, env):
|
||||
self.db = DBPools()
|
||||
self.env = env
|
||||
|
||||
async def new_log(self, userid, customerid, channel, payment_name, amount, client_ip, currency='CNY'):
|
||||
dbname = await self.env.get_module_dbname('unipay')
|
||||
async with self.db.sqlorContext(dbname) as sor:
|
||||
ns = {
|
||||
"id": self.env.uuid(),
|
||||
"customerid": customerid,
|
||||
"payment_channel": channel,
|
||||
"payment_name": payment_name,
|
||||
"payer_client_ip": client_ip,
|
||||
"currency": currency,
|
||||
"payment_status": '0',
|
||||
"init_timestamp": timestampstr(),
|
||||
"userid": userid
|
||||
}
|
||||
await sor.C('payment_log', ns)
|
||||
return True
|
||||
return False
|
||||
|
||||
async def cancel_log(self, logid):
|
||||
dbname = await self.env.get_module_dbname('unipay')
|
||||
async with self.db.sqlorContext(dbname) as sor:
|
||||
ns = {
|
||||
"id": logid,
|
||||
"cancel_timestamp": timestampstr()
|
||||
}
|
||||
await sor.U('payment_log', ns)
|
||||
return True
|
||||
return False
|
||||
|
||||
async def payed_log(self, logid):
|
||||
dbname = await self.env.get_module_dbname('unipay')
|
||||
async with self.db.sqlorContext(dbname) as sor:
|
||||
ns = {
|
||||
"id": logid,
|
||||
"payed_timestamp": timestampstr()
|
||||
}
|
||||
await sor.U('payment_log', ns)
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
15
wwwroot/menu.ui
Normal file
15
wwwroot/menu.ui
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"widgettype":"Menu",
|
||||
"items":[
|
||||
{
|
||||
"name":"recharge",
|
||||
"label":"充值",
|
||||
"url":"{{entire_url('recharge.ui')}}"
|
||||
},
|
||||
{
|
||||
"name":"payment_log",
|
||||
"label":"充值历史",
|
||||
"url":"{{entire_url('payment_log')}}"
|
||||
}
|
||||
]
|
||||
}
|
||||
9
wwwroot/recharge.dspy
Normal file
9
wwwroot/recharge.dspy
Normal file
@ -0,0 +1,9 @@
|
||||
url = await create_payment(request)
|
||||
return {
|
||||
"widgettype":"Iframe",
|
||||
"options":{
|
||||
"url": url,
|
||||
"height": "100%",
|
||||
"width":"100%"
|
||||
}
|
||||
}
|
||||
74
wwwroot/recharge.ui
Normal file
74
wwwroot/recharge.ui
Normal file
@ -0,0 +1,74 @@
|
||||
{
|
||||
"widgettype":"Form",
|
||||
"options":{
|
||||
"width": "100%",
|
||||
"height": "100%",
|
||||
"fields":[
|
||||
{
|
||||
"name":"provider",
|
||||
"uitype":"code",
|
||||
"required":true,
|
||||
"defautvalue":"wechat",
|
||||
"label":"充值渠道",
|
||||
"data":[
|
||||
{
|
||||
"value":"wechat",
|
||||
"text":"微信支付"
|
||||
},
|
||||
{
|
||||
"value":"alipay",
|
||||
"text":"支付宝"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name":"amount",
|
||||
"label":"充值金额",
|
||||
"required":true,
|
||||
"uitype":"float",
|
||||
"lenght":18,
|
||||
"dec":2
|
||||
},
|
||||
{
|
||||
"name":"currency",
|
||||
"label":"币种",
|
||||
"uitype":"code",
|
||||
"defaultvalue":"CNY",
|
||||
"data":[
|
||||
{
|
||||
"value":"CNY",
|
||||
"text":"人民币"
|
||||
},
|
||||
{
|
||||
"value":"USD",
|
||||
"text": "美元"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
]
|
||||
},
|
||||
"binds":[
|
||||
{
|
||||
"wid": "self",
|
||||
"evnet":"submit",
|
||||
"actiontype":"urlwidget",
|
||||
"target":"PopupWindow",
|
||||
"popup_options":{
|
||||
{% if params_kw._is_mobile %}
|
||||
"width": "95%",
|
||||
"height": "95%",
|
||||
{% else %}
|
||||
"width": "50%",
|
||||
"height": "50%",
|
||||
{% endif %}
|
||||
"archor":"cc"
|
||||
},
|
||||
"options":{
|
||||
"url":"{{entire_url('recharge.dspy')}}",
|
||||
"method":"POST",
|
||||
"params":{}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user