201 lines
6.0 KiB
Python
201 lines
6.0 KiB
Python
# init.py
|
||
import os
|
||
from appPublic.log import debug,exception
|
||
from ahserver.configuredServer import add_startup
|
||
from ahserver.serverenv import ServerEnv
|
||
from .notify import get_provider, get_provider_channel
|
||
from .paylog import PaymentLog, unipay_accounting
|
||
from .payfee import get_pay_fee, sor_get_pay_fee, get_paychannels, get_pay_feerate
|
||
|
||
# 从 env 或配置载入 provider conf(这里只示例)
|
||
CONF = {
|
||
"transfer":{
|
||
"pop3server": os.getenv("POP3SERVER", ""),
|
||
"mail": os.getenv("MAIL", ""),
|
||
"password": os.getenv("PASSWORD", ""),
|
||
"from_mail": os.getenv("FROM_MAIL", ""),
|
||
"account_no": os.getenv("ACCOUNT_NO", "")
|
||
},
|
||
"wechat": {
|
||
"mchid": os.getenv("WXP_MCHID",""),
|
||
"appid": os.getenv("WXP_APPID", ""),
|
||
"cert_serial_no": os.getenv("WXP_SERIAL",""),
|
||
"private_key_pem": open(os.getenv("WXP_PRIVKEY","./merchant_private_key.pem"),"rb").read(),
|
||
"api_v3_key": os.getenv("WXP_API_V3_KEY","")
|
||
},
|
||
"paypal": {
|
||
"client_id": os.getenv("PP_ID",""),
|
||
"client_secret": os.getenv("PP_SECRET",""),
|
||
"sandbox": True
|
||
},
|
||
"alipay": {
|
||
"app_id": os.getenv("ALIPAY_APPID",""),
|
||
"app_private_key_pem": open(os.getenv("ALIPAY_PRIV","./alipay_priv.pem"),"rb").read(),
|
||
"alipay_public_key_pem": open(os.getenv("ALIPAY_PUB",""),"rb").read()
|
||
},
|
||
"stripe": {
|
||
"api_key": os.getenv("STRIPE_KEY","")
|
||
}
|
||
}
|
||
|
||
PROVIDERS = {}
|
||
|
||
|
||
# 下单接口(统一)
|
||
async def create_payment(request, params_kw=None):
|
||
env = request._run_ns
|
||
if params_kw is None:
|
||
params_kw = request.params_kw
|
||
data = params_kw
|
||
data.request = request
|
||
provider = data.get("provider")
|
||
if provider not in PROVIDERS:
|
||
debug(f'{provider=} is not a valid payment channel')
|
||
return {"error":"unknown provider"}
|
||
try:
|
||
if PROVIDERS[provider] is None:
|
||
e = Exception(f'{provider} cannot pay')
|
||
exception(f'{e}')
|
||
raise e
|
||
notify_url = env.entire_url(f'providers/{provider}')
|
||
pl = PaymentLog(request._run_ns)
|
||
fee = await get_pay_fee(provider, data.amount)
|
||
channel = get_provider_channel(provider)
|
||
userid = await env.get_user()
|
||
orgid = await env.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
|
||
plog = await pl.new_log(userid, orgid, provider,
|
||
payment_name, amount,
|
||
fee, client_ip, currency=currency)
|
||
if plog:
|
||
data.out_trade_no = plog.id
|
||
data.customerid = orgid
|
||
data.userid = userid
|
||
data.payment_name = payment_name
|
||
data.notify_url = notify_url
|
||
data.client_ip = client_ip
|
||
res = await PROVIDERS[provider].create_payment(data)
|
||
debug(f'{provider=} instance return {res}')
|
||
return res
|
||
raise Exception('write payment_log error')
|
||
except Exception as e:
|
||
exception(f'create_payment():{params_kw=}, {e}')
|
||
raise e
|
||
|
||
# 查询
|
||
async def query_payment(request, params_kw=None):
|
||
if params_kw is None:
|
||
params_kw = request.params_kw
|
||
data = params_kw
|
||
provider = data.get("provider")
|
||
if provider not in PROVIDERS:
|
||
return {"error":"unknown provider"}
|
||
try:
|
||
if PROVIDERS[provider] is None:
|
||
e = Exception(f'{provider} cannot pay')
|
||
exception(f'{e}')
|
||
raise e
|
||
res = await PROVIDERS[provider].query(data)
|
||
return res
|
||
except Exception as e:
|
||
exception(f'query_payment():{params_kw}, {e}')
|
||
raise e
|
||
|
||
# 退款
|
||
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")
|
||
if provider not in PROVIDERS:
|
||
return {"error":"unknown provider"}
|
||
try:
|
||
if PROVIDERS[provider] is None:
|
||
e = Exception(f'{provider} cannot pay')
|
||
exception(f'{e}')
|
||
raise e
|
||
res = await PROVIDERS[provider].refund(data)
|
||
return res
|
||
except Exception as e:
|
||
exception(f'query_payment():{params_kw}, {e}')
|
||
raise e
|
||
|
||
# 回调入口:你可把厂商回调用各自 endpoint 再转发到这里,或在厂商控制台按各自 URL 配置
|
||
async def payment_notify_handle(request, data):
|
||
logid = data.params.out_trade_no
|
||
pl = PaymentLog(request._run_ns)
|
||
plog = await pl.payed_log(logid)
|
||
await unipay_accounting(request, data)
|
||
if provider == "wechat":
|
||
return {"code":"SUCCESS", "message":"OK"}
|
||
else:
|
||
return "OK"
|
||
|
||
async def wechat_notify(request):
|
||
debug("wechat notify called .......")
|
||
provider = 'wechat'
|
||
if PROVIDERS[provider] is None:
|
||
e = Exception(f'{provider} cannot pay')
|
||
exception(f'{e}')
|
||
return
|
||
try:
|
||
data = await PROVIDERS[provider].handle_notify(request)
|
||
except Exception as e:
|
||
e = Exception(f'{provider} cannot pay')
|
||
exception(f'{e}')
|
||
return
|
||
try:
|
||
await unipay_accounting(request, data)
|
||
except Exception as e:
|
||
exception(f'{e}')
|
||
return {"code":"SUCCESS", "message":"OK"}
|
||
|
||
async def alipay_notify(request):
|
||
debug("alipay notify called .......")
|
||
provider = 'alipay'
|
||
if PROVIDERS[provider] is None:
|
||
e = Exception(f'{provider} cannot pay')
|
||
exception(f'{e}')
|
||
return
|
||
try:
|
||
data = await PROVIDERS[provider].handle_notify(request)
|
||
except Exception as e:
|
||
e = Exception(f'{provider} cannot pay')
|
||
exception(f'{e}')
|
||
return
|
||
try:
|
||
await unipay_accounting(request, data)
|
||
except Exception as e:
|
||
exception(f'{e}')
|
||
return {"code":"SUCCESS", "message":"OK"}
|
||
|
||
async def setup_callback_path(app):
|
||
app.router.add_post('/unipay/notify/wechat', wechat_notify)
|
||
app.router.add_post('/unipay/notify/alipay', wechat_notify)
|
||
|
||
# callback url= "/unipay/notify/{provider}"
|
||
|
||
def load_unipay():
|
||
PROVIDERS["transfer"] = get_provider("transfer", CONF["transfer"])
|
||
PROVIDERS["wechat"] = get_provider("wechat", CONF["wechat"])
|
||
PROVIDERS["paypal"] = get_provider("paypal", CONF["paypal"])
|
||
PROVIDERS["alipay"] = get_provider("alipay", CONF["alipay"])
|
||
PROVIDERS["stripe"] = get_provider("stripe", CONF["stripe"])
|
||
env = ServerEnv()
|
||
env.get_paychannels = get_paychannels
|
||
env.get_pay_feerate = get_pay_feerate
|
||
env.payment_notify = payment_notify
|
||
env.create_payment = create_payment
|
||
env.query_payment = query_payment
|
||
env.refund_payment = refund_payment
|
||
env.get_pay_fee = get_pay_fee
|
||
env.sor_get_pay_fee = sor_get_pay_fee
|
||
env.PaymentLog = PaymentLog
|
||
add_startup(setup_callback_path)
|
||
|
||
|