bugfix
This commit is contained in:
commit
74aa5b87b9
@ -11,6 +11,36 @@
|
||||
},
|
||||
"editexclouded": [
|
||||
"id"
|
||||
],
|
||||
"toolbar":{
|
||||
"tools":[
|
||||
{
|
||||
"name":"refund",
|
||||
"label":"退费",
|
||||
"url":"{{entire_url('../refund.ui')}}"
|
||||
}
|
||||
]
|
||||
},
|
||||
"binds":[
|
||||
"wid":"self",
|
||||
"event":"refund",
|
||||
"actiontype":"urlwidget",
|
||||
"target":"PopupWindow",
|
||||
"popup_options":{
|
||||
{% if params_kw._is_mobile %}
|
||||
"width":"100%",
|
||||
"height":"90%",
|
||||
{% else %}
|
||||
"width": "40%",
|
||||
"height":"80%",
|
||||
{% endif %}
|
||||
"archor": "cc"
|
||||
},
|
||||
"options":{
|
||||
"url":"{{entire_url('../refund.ui')}}",
|
||||
"params": {
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@ -69,7 +69,7 @@ async def create_payment(request, params_kw=None):
|
||||
amount = data.amount
|
||||
currency = data.currency
|
||||
plog = await pl.new_log(userid, orgid, provider,
|
||||
payment_name, amount,
|
||||
amount,
|
||||
fee, client_ip, currency=currency)
|
||||
if plog:
|
||||
data.out_trade_no = plog.id
|
||||
@ -109,16 +109,26 @@ async def query_payment(request, params_kw=None):
|
||||
async def refund_payment(request, params_kw=None):
|
||||
if params_kw is None:
|
||||
params_kw = request.params_kw
|
||||
data = params_kw
|
||||
provider = data.get("provider")
|
||||
data = await get_refundable_plog(request, params_kw.id)
|
||||
if data is None:
|
||||
return None
|
||||
if params_kw.amount >= data.total_amount:
|
||||
return None
|
||||
provider = data.channelid
|
||||
if provider not in PROVIDERS:
|
||||
return {"error":"unknown provider"}
|
||||
try:
|
||||
plog = await new_refund_log(request, data.amount, data.id)
|
||||
if PROVIDERS[provider] is None:
|
||||
e = Exception(f'{provider} cannot pay')
|
||||
exception(f'{e}')
|
||||
raise e
|
||||
res = await PROVIDERS[provider].refund(data)
|
||||
plog.out_trade_no = plog.origin_id
|
||||
plog.out_request_no = plog.id
|
||||
plog.total_amount = params_kw.amount
|
||||
plog.refund_amount = plog.total_amount
|
||||
plog.notify_url = request.env.entire_url(f'notify/{provider}')
|
||||
res = await PROVIDERS[provider].refund(plog)
|
||||
return res
|
||||
except Exception as e:
|
||||
exception(f'query_payment():{params_kw}, {e}')
|
||||
|
||||
@ -1,9 +1,16 @@
|
||||
from sqlor.dbpools import DBPools
|
||||
from sqlor.dbpools import DBPools, get_sor_context
|
||||
from appPublic.timeUtils import timestampstr
|
||||
from appPublic.log import debug, exception
|
||||
from appPublic.dictObject import DictObject
|
||||
from ahserver.serverenv import ServerEnv
|
||||
|
||||
RECHARGE="充值"
|
||||
REFUND ="退费"
|
||||
|
||||
payment_names = [
|
||||
RECHARGE,
|
||||
REFUND
|
||||
]
|
||||
class PaymentLog:
|
||||
def __init__(self, env):
|
||||
self.db = DBPools()
|
||||
@ -11,14 +18,15 @@ class PaymentLog:
|
||||
|
||||
async def new_log(self,
|
||||
userid, customerid, channel,
|
||||
payment_name, amount, feerate,
|
||||
amount, feerate,
|
||||
client_ip, currency='CNY'):
|
||||
dbname = self.env.get_module_dbname('unipay')
|
||||
async with self.db.sqlorContext(dbname) as sor:
|
||||
return await self.sor_new_log(sor, userid, customerid, channel,
|
||||
payment_name, amount, feerate,
|
||||
amount, feerate,
|
||||
client_ip, currency=currency)
|
||||
return None
|
||||
|
||||
async def sor_new_log(self, sor,
|
||||
userid, customerid, channel,
|
||||
payment_name, amount, feerate,
|
||||
@ -28,7 +36,7 @@ class PaymentLog:
|
||||
"id": self.env.uuid(),
|
||||
"customerid": customerid,
|
||||
"channelid": channel,
|
||||
"payment_name": payment_name,
|
||||
"payment_name": RECHARGE,
|
||||
"payer_client_ip": client_ip,
|
||||
"amount_total": amount,
|
||||
"pay_feerate": feerate,
|
||||
@ -72,6 +80,64 @@ class PaymentLog:
|
||||
return None
|
||||
return None
|
||||
|
||||
async def get_refundable_plog(request, id):
|
||||
db = DBPools()
|
||||
env = request._run_ns
|
||||
orgid = await get_userorgid()
|
||||
dbname = env.get_module_dbname('unipay')
|
||||
async with db.sqlorContext(dbname) as sor:
|
||||
recs = await sor.R('payment_log', {'id':id,
|
||||
'customerid': orgid,
|
||||
'payment_status'
|
||||
})
|
||||
if len(recs) < 1:
|
||||
debug(f'id({id}) not exists in payment_log or not belong you')
|
||||
return None
|
||||
origin_plog = recs[0]
|
||||
if origin_plog.payment_status == '0':
|
||||
debug(f'id({id}) payment status 0')
|
||||
return None
|
||||
if origin_plog.origin_id:
|
||||
debug(f'id({id}) is a refund plog')
|
||||
return None
|
||||
recs = await sor.R('payment_log', {'origin_id': id})
|
||||
amt = origin_plog.total_amount
|
||||
for l in recs:
|
||||
amt -= l.total_amount
|
||||
if amt <= 0:
|
||||
return None
|
||||
origin_plog.total_amount = amt
|
||||
return origin_plog
|
||||
exception(f'{db.except}')
|
||||
return None
|
||||
|
||||
async def new_refund_log(request, amount, origin_id):
|
||||
env = ServerEnv()
|
||||
async with get_sor_context(env, 'unipay') as sor:
|
||||
recs = await sor.R('payment_log', {'id': origin_id})
|
||||
if len(recs) < 1:
|
||||
raise Exception(f'{origin_id} not a payment_log')
|
||||
ol = recs[0]
|
||||
ns = {
|
||||
"id": env.uuid(),
|
||||
"customerid": ol.customerid,
|
||||
"channelid": ol.channel,
|
||||
"payment_name": REFUND,
|
||||
"payer_client_ip": ol.client_ip,
|
||||
"amount_total": amount,
|
||||
"pay_feerate": 0.0,
|
||||
"pay_fee": 0.0,
|
||||
"currency": ol.currency,
|
||||
"payment_status": '0',
|
||||
"init_timestamp": timestampstr(),
|
||||
"payed_timestamp": "2000-01-01 00:00:00.001",
|
||||
"cancel_timestamp": "2000-01-01 00:00:00.001",
|
||||
"userid": userid,
|
||||
"origin_id": origin_id
|
||||
}
|
||||
await sor.C('payment_log', ns.copy())
|
||||
return DictObject(**ns)
|
||||
|
||||
async def unipay_accounting(request, data):
|
||||
logid = data.out_trade_no
|
||||
trade_id = data.trade_no
|
||||
|
||||
20
wwwroot/refund.dspy
Normal file
20
wwwroot/refund.dspy
Normal file
@ -0,0 +1,20 @@
|
||||
# refund.dspy
|
||||
debug(f'refund.dspy: {params_kw=}')
|
||||
params_kw.amount = float(params_kw.amount)
|
||||
plog = await get_refundable_plog(request, parmas_kw.id)
|
||||
if plog is None:
|
||||
return {
|
||||
"widgettype": "Text",
|
||||
"options":{
|
||||
"i18n":true,
|
||||
"width":"100%",
|
||||
"wrap":true,
|
||||
"otext":"不可退费"
|
||||
}
|
||||
}
|
||||
if params_kw.amount > plog.total_amount:
|
||||
return {
|
||||
}
|
||||
|
||||
plog.total_amount = params_kw.amount
|
||||
|
||||
55
wwwroot/refund.ui
Normal file
55
wwwroot/refund.ui
Normal file
@ -0,0 +1,55 @@
|
||||
{% if params_kw.id %}
|
||||
{% set plog = get_refundable_plog(request, params_kw.id) %}
|
||||
{% if plog %}
|
||||
{
|
||||
"widgettype":"Form",
|
||||
"options":{
|
||||
"description":"输入退费金额,缺省为本最多可退金额",
|
||||
"width": "100%",
|
||||
"fields":[
|
||||
{
|
||||
"name":"id",
|
||||
"uitype":"hide",
|
||||
"value":"{{plog.id}}"
|
||||
},
|
||||
{
|
||||
"name": "amount",
|
||||
"label": "退费金额",
|
||||
"uitype":"float",
|
||||
"defaultvalue": {{plog.amount}}
|
||||
}
|
||||
]
|
||||
},
|
||||
"binds":[
|
||||
{
|
||||
"wid":"self",
|
||||
"event":"submit",
|
||||
"actiontype":"urlwidget",
|
||||
"target": "self",
|
||||
"options":{
|
||||
"url":"{{entire_url('refund.dspy')}}"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
{% else %}
|
||||
{
|
||||
"widgettype":"Text",
|
||||
"options":{
|
||||
"i18n":true,
|
||||
"width":"100%",
|
||||
"otext":"本地充值已退费",
|
||||
"wrap": true
|
||||
}
|
||||
}
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{
|
||||
"widgettype": "Text",
|
||||
"options":{
|
||||
"i18n": true
|
||||
"width": "100%",
|
||||
"otext": "需要选定一条记录"
|
||||
}
|
||||
}
|
||||
{% endif %}
|
||||
Loading…
x
Reference in New Issue
Block a user