127 lines
4.1 KiB
Python
127 lines
4.1 KiB
Python
# init.py
|
||
import os
|
||
from unipay.notify import get_provider, get_provider_channel
|
||
from ahserver.serverenv import ServerEnv
|
||
from paylog import PaymentLog
|
||
|
||
# 从 env 或配置载入 provider conf(这里只示例)
|
||
CONF = {
|
||
"wechat": {
|
||
"mchid": os.getenv("WXP_MCHID",""),
|
||
"serial_no": os.getenv("WXP_SERIAL",""),
|
||
"privkey_pem": open(os.getenv("WXP_PRIVKEY","./merchant_private_key.pem"),"rb").read(),
|
||
"platform_pub_pem": open(os.getenv("WXP_PLATFORM_PUB","./platform_pub.pem"),"rb").read(),
|
||
"api_v3_key": os.getenv("WXP_API_V3_KEY","").encode()
|
||
},
|
||
"paypal": {
|
||
"client_id": os.getenv("PP_ID",""),
|
||
"client_secret": os.getenv("PP_SECRET",""),
|
||
"sandbox": True
|
||
},
|
||
"alipay": {
|
||
"app_id": os.getenv("ALIPAY_APPID",""),
|
||
"privkey_pem": open(os.getenv("ALIPAY_PRIV","./alipay_priv.pem"),"rb").read(),
|
||
"alipay_pub_pem": open(os.getenv("ALIPAY_PUB","./alipay_pub.pem"),"rb").read(),
|
||
"sandbox": True
|
||
},
|
||
"stripe": {
|
||
"api_key": os.getenv("STRIPE_KEY","")
|
||
}
|
||
}
|
||
|
||
PROVIDERS = {}
|
||
|
||
|
||
# 下单接口(统一)
|
||
async def create_payment(request, params_kw=None):
|
||
if params_kw is None:
|
||
params_kw = request.paams_kw
|
||
data = params_kw
|
||
provider = data.get("provider")
|
||
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)}
|
||
|
||
# 查询
|
||
async def query_payment(request, params_kw=None):
|
||
if params_kw is None:
|
||
params_kw = request.paams_kw
|
||
data = params_kw
|
||
provider = data.get("provider")
|
||
if provider not in PROVIDERS:
|
||
return {"error":"unknown provider"}
|
||
try:
|
||
res = await PROVIDERS[provider].query(data)
|
||
return res
|
||
except Exception as e:
|
||
return {"error": str(e)}
|
||
|
||
# 退款
|
||
async def refund_payment(request, params_kw=None):
|
||
if params_kw is None:
|
||
params_kw = request.paams_kw
|
||
data = params_kw
|
||
provider = data.get("provider")
|
||
if provider not in PROVIDERS:
|
||
return {"error":"unknown provider"}
|
||
try:
|
||
res = await PROVIDERS[provider].refund(data)
|
||
return res
|
||
except Exception as e:
|
||
return {"error": str(e)}
|
||
|
||
# 回调入口:你可把厂商回调用各自 endpoint 再转发到这里,或在厂商控制台按各自 URL 配置
|
||
async def payment_notify(request, callback, params_kw=None):
|
||
if params_kw is None:
|
||
params_kw = request.paams_kw
|
||
data = params_kw
|
||
provider = params_kw.provider
|
||
headers = dict(request.headers)
|
||
body = await request.text()
|
||
try:
|
||
data = await PROVIDERS[provider].handle_notify(headers, body)
|
||
# 这里 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"}
|
||
else:
|
||
return "OK"
|
||
except Exception as e:
|
||
return web.Response(status=500, text=str(e))
|
||
|
||
# callback url= "/unipay/notify/{provider}"
|
||
|
||
def load_unipay():
|
||
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.payment_notify = payment_notify
|
||
env.create_payment = create_payment
|
||
env.query_payment = query_payment
|
||
env.refund_payment = refund_payment
|
||
|