You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
flyapps/fir_ser/api/utils/pay/wx.py

85 lines
3.6 KiB

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# project: 3月
# author: NinEveN
# date: 2021/3/18
from api.utils.wxpay import WeChatPay, WeChatPayType
from datetime import datetime, timedelta
from api.utils.storage.caches import update_order_info, update_order_status
import json
import logging
logger = logging.getLogger(__file__)
class Weixinpay(object):
def __init__(self, name, p_type, auth):
self.p_type = p_type
self.wx_config = auth
self.name = name
self.wxpay = self.__get_wx_pay()
def __get_wx_pay(self):
return WeChatPay(wechatpay_type=WeChatPayType.NATIVE,
mchid=self.wx_config.get('MCH_ID'),
parivate_key=self.wx_config.get('APP_PRIVATE_KEY'),
cert_serial_no=self.wx_config.get('SERIAL_NO'),
appid=self.wx_config.get('APP_ID'),
notify_url="%s/%s" % (self.wx_config.get('APP_NOTIFY_URL'), self.name),
apiv3_key=self.wx_config.get('API_V3_KEY')
)
def get_pay_pc_url(self, out_trade_no, total_amount, passback_params):
passback_params.update({'name': self.name})
time_expire = (datetime.now() + timedelta(days=1)).strftime("%Y-%m-%dT%H:%M:%S+08:00")
code, data = self.wxpay.pay(
description=self.wx_config.get('SUBJECT'),
out_trade_no=out_trade_no,
amount={
'total': total_amount, # 订单总金额,单位为分。示例值:100
'currency': 'CNY'
},
time_expire=time_expire,
attach=json.dumps(passback_params),
)
return {'type': self.p_type, 'url': json.loads(data).get('code_url', ''), 'out_trade_no': out_trade_no}
def valid_order(self, request):
headers = {
'Wechatpay-Signature': request.META.get('HTTP_WECHATPAY_SIGNATURE'),
'Wechatpay-Timestamp': request.META.get('HTTP_WECHATPAY_TIMESTAMP'),
'Wechatpay-Nonce': request.META.get('HTTP_WECHATPAY_NONCE'),
'Wechatpay-Serial': request.META.get('HTTP_WECHATPAY_SERIAL'),
}
result = self.wxpay.decrypt_callback(headers, request.body.decode('utf-8'))
if result:
logger.info("付款成功,等待下一步验证 %s" % result)
data = json.loads(result)
passback_params = data.get("attach", "")
out_trade_no = data.get("out_trade_no", "")
if passback_params:
ext_parms = json.loads(passback_params)
user_id = ext_parms.get("user_id")
transaction_id = data.get("transaction_id", "")
return update_order_info(user_id, out_trade_no, transaction_id, 0)
else:
logger.error("passback_params %s user_id not exists" % passback_params)
else:
logger.error("消息解密失败")
return False
def update_order_status(self, out_trade_no):
code, data = self.wxpay.query(out_trade_no=out_trade_no)
# (0, '交易成功'), (1, '待支付'), (2, '订单已创建'), (3, '退费申请中'), (4, '已退费'), (5, '主动取消'), (6, '超时取消')
data = json.loads(data)
logger.info("out_trade_no: %s info:%s" % (out_trade_no, data))
if code == 200:
trade_status = data.get("trade_state", '')
if trade_status in ['SUCCESS']:
update_order_status(out_trade_no, 0)
elif trade_status in ['NOTPAY']:
update_order_status(out_trade_no, 2)
elif code == 404:
update_order_status(out_trade_no, 1)