第一次提交
This commit is contained in:
201
app/utils/alipay.py
Normal file
201
app/utils/alipay.py
Normal file
@@ -0,0 +1,201 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
支付宝支付工具类
|
||||
"""
|
||||
|
||||
from alipay import AliPay
|
||||
from flask import current_app
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
class AlipayHelper:
|
||||
"""支付宝支付助手类"""
|
||||
|
||||
def __init__(self, app=None):
|
||||
"""
|
||||
初始化支付宝客户端
|
||||
:param app: Flask应用实例
|
||||
"""
|
||||
self.alipay = None
|
||||
if app:
|
||||
self.init_app(app)
|
||||
|
||||
def init_app(self, app):
|
||||
"""
|
||||
初始化支付宝配置
|
||||
:param app: Flask应用实例
|
||||
"""
|
||||
config = app.config
|
||||
|
||||
# 检查必要的配置
|
||||
required_configs = [
|
||||
'ALIPAY_APP_ID',
|
||||
'ALIPAY_PRIVATE_KEY',
|
||||
'ALIPAY_PUBLIC_KEY',
|
||||
'ALIPAY_ALIPAY_PUBLIC_KEY'
|
||||
]
|
||||
|
||||
missing_configs = [cfg for cfg in required_configs if not config.get(cfg)]
|
||||
if missing_configs:
|
||||
raise ValueError(f"缺少必要的支付宝配置: {', '.join(missing_configs)}")
|
||||
|
||||
# 初始化支付宝客户端
|
||||
self.alipay = AliPay(
|
||||
appid=config['ALIPAY_APP_ID'],
|
||||
app_private_key=config['ALIPAY_PRIVATE_KEY'],
|
||||
alipay_public_key=config['ALIPAY_ALIPAY_PUBLIC_KEY'],
|
||||
sign_type=config.get('ALIPAY_SIGN_TYPE', 'RSA2'),
|
||||
charset=config.get('ALIPAY_CHARSET', 'utf-8'),
|
||||
gateway=config.get('ALIPAY_GATEWAY', 'https://openapi.alipay.com/gateway.do')
|
||||
)
|
||||
|
||||
def create_payment_url(self, order_number, amount, subject, notify_url, return_url):
|
||||
"""
|
||||
创建支付宝支付链接
|
||||
:param order_number: 订单号
|
||||
:param amount: 支付金额
|
||||
:param subject: 支付主题
|
||||
:param notify_url: 异步通知URL
|
||||
:param return_url: 同步返回URL
|
||||
:return: 支付链接
|
||||
"""
|
||||
if not self.alipay:
|
||||
raise ValueError("支付宝客户端未初始化")
|
||||
|
||||
# 构建订单参数
|
||||
order_params = {
|
||||
'out_trade_no': order_number, # 商户订单号
|
||||
'total_amount': str(amount), # 订单总金额
|
||||
'subject': subject, # 订单标题
|
||||
'body': f'订单{order_number}的支付', # 订单描述
|
||||
'product_code': 'FAST_INSTANT_TRADE_PAY', # 产品代码
|
||||
}
|
||||
|
||||
# 生成支付链接
|
||||
payment_url = self.alipay.trade_page_pay(
|
||||
total_amount=str(amount),
|
||||
subject=subject,
|
||||
out_trade_no=order_number,
|
||||
return_url=return_url,
|
||||
notify_url=notify_url
|
||||
)
|
||||
|
||||
# 构建完整的支付URL
|
||||
gateway = self.alipay.gateway
|
||||
full_payment_url = f"{gateway}?{payment_url}"
|
||||
|
||||
return full_payment_url
|
||||
|
||||
def create_wap_payment_url(self, order_number, amount, subject, notify_url, return_url):
|
||||
"""
|
||||
创建手机网站支付链接
|
||||
:param order_number: 订单号
|
||||
:param amount: 支付金额
|
||||
:param subject: 支付主题
|
||||
:param notify_url: 异步通知URL
|
||||
:param return_url: 同步返回URL
|
||||
:return: 支付链接
|
||||
"""
|
||||
if not self.alipay:
|
||||
raise ValueError("支付宝客户端未初始化")
|
||||
|
||||
# 生成支付链接
|
||||
payment_url = self.alipay.trade_wap_pay(
|
||||
total_amount=str(amount),
|
||||
subject=subject,
|
||||
out_trade_no=order_number,
|
||||
return_url=return_url,
|
||||
notify_url=notify_url
|
||||
)
|
||||
|
||||
# 构建完整的支付URL
|
||||
gateway = self.alipay.gateway
|
||||
full_payment_url = f"{gateway}?{payment_url}"
|
||||
|
||||
return full_payment_url
|
||||
|
||||
def query_order_status(self, order_number):
|
||||
"""
|
||||
查询订单支付状态
|
||||
:param order_number: 订单号
|
||||
:return: 订单状态信息
|
||||
"""
|
||||
if not self.alipay:
|
||||
raise ValueError("支付宝客户端未初始化")
|
||||
|
||||
try:
|
||||
result = self.alipay.alipay_trade_query(
|
||||
out_trade_no=order_number
|
||||
)
|
||||
return result
|
||||
except Exception as e:
|
||||
current_app.logger.error(f"查询支付宝订单状态失败: {str(e)}")
|
||||
return None
|
||||
|
||||
def verify_notification(self, data, signature):
|
||||
"""
|
||||
验证支付宝异步通知签名
|
||||
:param data: 通知数据
|
||||
:param signature: 签名
|
||||
:return: 验证结果
|
||||
"""
|
||||
if not self.alipay:
|
||||
raise ValueError("支付宝客户端未初始化")
|
||||
|
||||
try:
|
||||
# 验证签名
|
||||
return self.alipay.verify(data, signature)
|
||||
except Exception as e:
|
||||
current_app.logger.error(f"验证支付宝通知签名失败: {str(e)}")
|
||||
return False
|
||||
|
||||
def verify_trade_status(self, notify_data):
|
||||
"""
|
||||
验证交易状态
|
||||
:param notify_data: 通知数据
|
||||
:return: 验证结果和交易状态
|
||||
"""
|
||||
if not self.alipay:
|
||||
raise ValueError("支付宝客户端未初始化")
|
||||
|
||||
try:
|
||||
# 验证签名
|
||||
if not self.alipay.verify(notify_data, notify_data.get('sign')):
|
||||
return False, None
|
||||
|
||||
# 检查交易状态
|
||||
trade_status = notify_data.get('trade_status')
|
||||
if trade_status in ['TRADE_SUCCESS', 'TRADE_FINISHED']:
|
||||
return True, trade_status
|
||||
else:
|
||||
return False, trade_status
|
||||
except Exception as e:
|
||||
current_app.logger.error(f"验证支付宝交易状态失败: {str(e)}")
|
||||
return False, None
|
||||
|
||||
def get_trade_state(self, order_number):
|
||||
"""
|
||||
获取交易状态
|
||||
:param order_number: 订单号
|
||||
:return: 交易状态
|
||||
"""
|
||||
result = self.query_order_status(order_number)
|
||||
if not result:
|
||||
return None
|
||||
|
||||
# 根据支付宝返回的状态码判断
|
||||
code = result.get('code')
|
||||
if code == '10000': # 接口调用成功
|
||||
trade_status = result.get('trade_status')
|
||||
if trade_status == 'TRADE_SUCCESS':
|
||||
return 'SUCCESS'
|
||||
elif trade_status == 'TRADE_FINISHED':
|
||||
return 'FINISHED'
|
||||
elif trade_status == 'TRADE_CLOSED':
|
||||
return 'CLOSED'
|
||||
elif trade_status == 'WAIT_BUYER_PAY':
|
||||
return 'WAIT_PAY'
|
||||
elif code == '40004': # 业务处理失败
|
||||
return 'NOT_EXIST'
|
||||
|
||||
return None
|
||||
Reference in New Issue
Block a user