给所有支付接口加上了支付宝

This commit is contained in:
TermiNexus committed 2026-07-09 22:06:46 +08:00
1 parent 8bd4bc740a
commit f8df7a751a
11 files changed
+611 -127

No files matched your search

+47 -3
View File
@@ -40,11 +40,42 @@ def get_alipay_config(club_id=None):
'ALIPAY_PUBLIC_KEY': cfg.get('ALIPAY_PUBLIC_KEY', ''),
'GATEWAY': cfg.get('GATEWAY', 'https://openapi.alipay.com/gateway.do'),
'NOTIFY_URL': cfg.get('NOTIFY_URL', ''),
'NOTIFY_URL_CZJILU': cfg.get('NOTIFY_URL_CZJILU', '') or cfg.get('NOTIFY_URL', ''),
'RETURN_URL': cfg.get('RETURN_URL', ''),
'sandbox': sandbox,
}
def get_czjilu_notify_url(club_id=None):
"""获取 Czjilu 类充值(押金/积分/会员/商家/考核/罚款)的支付宝异步回调地址。"""
return get_alipay_config(club_id)['NOTIFY_URL_CZJILU']
def generate_alipay_czjilu_pay_params(dingdanid, jine, subject, club_id=None, expire_minutes=30):
"""生成 Czjilu 类充值的支付宝 wap.pay 二维码参数。
返回 {qr_code, qr_image, pay_method},并在 cache 标记该订单为支付宝订单
(轮询接口据此跳过微信查单,直接等异步回调更新本地状态)。
"""
from django.core.cache import cache
notify_url = get_czjilu_notify_url(club_id)
pay_url = build_wap_pay_url(
out_trade_no=dingdanid,
amount=jine,
subject=subject or '充值支付',
club_id=club_id,
expire_minutes=expire_minutes,
notify_url=notify_url,
)
qr_image = qr_link_to_base64(pay_url)
cache.set(f'alipay_pay_url_{dingdanid}', pay_url, 60 * 30)
return {
'qr_code': pay_url,
'qr_image': qr_image,
'pay_method': 'alipay',
}
# ==================== 密钥加载 ====================
def _load_private_key(key_str):
@@ -196,17 +227,18 @@ def verify_notify_params(params, club_id=None):
# ==================== wap.pay 跳转 URL ====================
def build_wap_pay_url(out_trade_no, amount, subject, body='', club_id=None, expire_minutes=30):
def build_wap_pay_url(out_trade_no, amount, subject, body='', club_id=None, expire_minutes=30, notify_url=None):
"""
生成 alipay.trade.wap.pay 跳转 URL(GET 方式)。
参数:
out_trade_no: 商户订单号(对应 Order.OrderID)
out_trade_no: 商户订单号(对应 Order.OrderID 或 Czjilu.dingdan_id)
amount: 订单金额(Decimal 或字符串,单位元)
subject: 订单标题
body: 订单描述(可选)
club_id: 预留多 club(暂未使用)
expire_minutes: 超时关闭时间(分钟)
notify_url: 自定义异步回调地址(可选,默认用 cfg['NOTIFY_URL'])
返回:
完整的支付宝跳转 URL,前端 web-view 直接加载即可。
@@ -230,7 +262,7 @@ def build_wap_pay_url(out_trade_no, amount, subject, body='', club_id=None, expi
'timestamp': time.strftime('%Y-%m-%d %H:%M:%S'),
'version': '1.0',
'biz_content': json.dumps(biz_content, separators=(',', ':'), ensure_ascii=False),
'notify_url': cfg['NOTIFY_URL'],
'notify_url': notify_url or cfg['NOTIFY_URL'],
'return_url': cfg['RETURN_URL'],
}
@@ -343,3 +375,15 @@ def club_id_from_order(order_id):
except Exception:
pass
return CLUB_ID_DEFAULT
def club_id_from_czjilu(dingdan_id):
"""从 Czjilu 充值单反查 club_id(支付宝 czjilu 回调用)。"""
from products.models import Czjilu
try:
row = Czjilu.query.filter(dingdan_id=dingdan_id).first()
if row and getattr(row, 'club_id', None):
return row.club_id
except Exception:
pass
return CLUB_ID_DEFAULT
+200 -2
View File
@@ -167,9 +167,191 @@ def fulfill_jifen_recharge(dingdan_id, paid_amount_yuan=None):
return {'already_done': False, 'dingdan_id': dingdan_id, 'zhuangtai': 3, 'jifen': dashou.jifen}
@transaction.atomic
def fulfill_fakuan(dingdan_id, paid_amount_yuan=None):
"""罚款支付幂等履约:仅 zhuangtai==9 时入账。"""
import re
from orders.models import Penalty
from users.fadan_fenhong_utils import process_fadan_fenhong
order = Czjilu.query.filter(dingdan_id=dingdan_id).select_for_update().first()
if not order:
raise CzjiluFulfillError('订单不存在', 'not_found')
if order.leixing != 6:
raise CzjiluFulfillError('订单类型不是罚款', 'type_error')
if order.zhuangtai != 9:
try:
from jituan.services.szjilu_accounting import repair_wechat_income_if_missing
repair_wechat_income_if_missing(
Decimal(str(order.jine)),
getattr(order, 'club_id', None) or CLUB_ID_DEFAULT,
biz_ref=f'cz:{dingdan_id}',
)
except Exception as exc:
logger.error('罚款补记收支失败 dingdan=%s: %s', dingdan_id, exc, exc_info=True)
return {'already_done': True, 'dingdan_id': dingdan_id, 'zhuangtai': order.zhuangtai}
amount = Decimal(str(order.jine))
if paid_amount_yuan is not None:
paid = Decimal(str(paid_amount_yuan))
if abs(paid - amount) > Decimal('0.01'):
raise CzjiluFulfillError(f'支付金额{paid}与订单{amount}不一致', 'amount_mismatch')
order.zhuangtai = 3
order.save(update_fields=['zhuangtai'])
# 更新罚单状态为已缴纳(2)并触发分红
try:
fadan = None
m = re.search(r'#fadan:(\d+)', order.shuoming or '')
if m:
fadan = Penalty.query.filter(
id=int(m.group(1)),
PenalizedUserID=order.yonghuid,
Status__in=[1, 3],
).first()
if not fadan:
fadan = Penalty.query.filter(
PenalizedUserID=order.yonghuid,
FineAmount=order.jine,
Status__in=[1, 3],
).order_by('-CreateTime').first()
if fadan:
fadan.Status = 2
fadan.save(update_fields=['Status'])
success, msg = process_fadan_fenhong(fadan.id)
if not success:
logger.error('罚单 %s 分红处理失败: %s', fadan.id, msg)
else:
logger.info('罚单 %s 分红处理完成: %s', fadan.id, msg)
except Exception as exc:
logger.error('罚款罚单状态更新失败 dingdan=%s: %s', dingdan_id, exc, exc_info=True)
try:
from jituan.services.szjilu_accounting import repair_wechat_income_if_missing
repair_wechat_income_if_missing(amount, getattr(order, 'club_id', None) or CLUB_ID_DEFAULT, biz_ref=f'cz:{dingdan_id}')
except Exception as exc:
logger.error('罚款收支统计失败 dingdan=%s: %s', dingdan_id, exc, exc_info=True)
logger.info('罚款履约完成 dingdan=%s amount=%s', dingdan_id, amount)
return {'already_done': False, 'dingdan_id': dingdan_id, 'zhuangtai': 3}
@transaction.atomic
def fulfill_kaohe(dingdan_id, paid_amount_yuan=None):
"""考核支付幂等履约:仅 zhuangtai==9 时入账。"""
from rank.models import KaohePayTemp
from rank.utils import create_shenhe_jilu_from_temp
from users.business_models import User
order = Czjilu.query.filter(dingdan_id=dingdan_id).select_for_update().first()
if not order:
raise CzjiluFulfillError('订单不存在', 'not_found')
if order.leixing != 5:
raise CzjiluFulfillError('订单类型不是考核', 'type_error')
if order.zhuangtai != 9:
try:
from jituan.services.szjilu_accounting import repair_wechat_income_if_missing
repair_wechat_income_if_missing(
Decimal(str(order.jine)),
getattr(order, 'club_id', None) or CLUB_ID_DEFAULT,
biz_ref=f'cz:{dingdan_id}',
)
except Exception as exc:
logger.error('考核补记收支失败 dingdan=%s: %s', dingdan_id, exc, exc_info=True)
return {'already_done': True, 'dingdan_id': dingdan_id, 'zhuangtai': order.zhuangtai}
amount = Decimal(str(order.jine))
if paid_amount_yuan is not None:
paid = Decimal(str(paid_amount_yuan))
if abs(paid - amount) > Decimal('0.01'):
raise CzjiluFulfillError(f'支付金额{paid}与订单{amount}不一致', 'amount_mismatch')
order.zhuangtai = 3
order.save(update_fields=['zhuangtai'])
# 从临时表取业务参数并创建审核记录
try:
temp = KaohePayTemp.query.get(dingdan_id=dingdan_id, yonghuid=order.yonghuid)
user = User.query.get(UserUID=order.yonghuid)
success, msg, record = create_shenhe_jilu_from_temp(user, temp)
if not success:
logger.error('创建审核记录失败 dingdan=%s: %s', dingdan_id, msg)
order.zhuangtai = 10 # 支付成功但业务处理失败
order.save(update_fields=['zhuangtai'])
else:
logger.info('考核审核记录创建成功 dingdan=%s jilu_id=%s', dingdan_id, getattr(record, 'jilu_id', None))
except KaohePayTemp.DoesNotExist:
logger.error('考核临时表无记录 dingdan=%s', dingdan_id)
order.zhuangtai = 10
order.save(update_fields=['zhuangtai'])
except Exception as exc:
logger.error('考核审核记录创建异常 dingdan=%s: %s', dingdan_id, exc, exc_info=True)
order.zhuangtai = 10
order.save(update_fields=['zhuangtai'])
try:
from jituan.services.szjilu_accounting import repair_wechat_income_if_missing
repair_wechat_income_if_missing(amount, getattr(order, 'club_id', None) or CLUB_ID_DEFAULT, biz_ref=f'cz:{dingdan_id}')
except Exception as exc:
logger.error('考核收支统计失败 dingdan=%s: %s', dingdan_id, exc, exc_info=True)
logger.info('考核履约完成 dingdan=%s amount=%s', dingdan_id, amount)
return {'already_done': False, 'dingdan_id': dingdan_id, 'zhuangtai': order.zhuangtai}
@transaction.atomic
def fulfill_shangjia(dingdan_id, paid_amount_yuan=None):
"""商家充值幂等履约:仅 zhuangtai==9 时入账。"""
from users.models import UserShangjia
order = Czjilu.query.filter(dingdan_id=dingdan_id).select_for_update().first()
if not order:
raise CzjiluFulfillError('订单不存在', 'not_found')
if order.leixing != 4:
raise CzjiluFulfillError('订单类型不是商家充值', 'type_error')
if order.zhuangtai != 9:
try:
from jituan.services.szjilu_accounting import repair_wechat_income_if_missing
repair_wechat_income_if_missing(
Decimal(str(order.jine)),
getattr(order, 'club_id', None) or CLUB_ID_DEFAULT,
biz_ref=f'cz:{dingdan_id}',
)
except Exception as exc:
logger.error('商家充值补记收支失败 dingdan=%s: %s', dingdan_id, exc, exc_info=True)
return {'already_done': True, 'dingdan_id': dingdan_id, 'zhuangtai': order.zhuangtai}
amount = Decimal(str(order.jine))
if paid_amount_yuan is not None:
paid = Decimal(str(paid_amount_yuan))
if abs(paid - amount) > Decimal('0.01'):
raise CzjiluFulfillError(f'支付金额{paid}与订单{amount}不一致', 'amount_mismatch')
try:
shangjia = UserShangjia.objects.select_for_update().get(user__UserUID=order.yonghuid)
except UserShangjia.DoesNotExist:
raise CzjiluFulfillError('商家不存在,无法充值', 'shangjia_not_found')
shangjia.yue += amount
shangjia.save(update_fields=['yue'])
order.zhuangtai = 3
order.save(update_fields=['zhuangtai'])
try:
from jituan.services.szjilu_accounting import repair_wechat_income_if_missing
repair_wechat_income_if_missing(amount, getattr(order, 'club_id', None) or CLUB_ID_DEFAULT, biz_ref=f'cz:{dingdan_id}')
except Exception as exc:
logger.error('商家充值收支统计失败 dingdan=%s: %s', dingdan_id, exc, exc_info=True)
logger.info('商家充值履约完成 dingdan=%s amount=%s yue=%s', dingdan_id, amount, shangjia.yue)
return {'already_done': False, 'dingdan_id': dingdan_id, 'zhuangtai': 3, 'yue': shangjia.yue}
def confirm_czjilu_paid(dingdan_id, yonghuid, expected_leixing):
"""轮询确认:查微信 SUCCESS 后幂等履约。"""
from jituan.services.member_recharge import query_wechat_v2_trade_state
"""轮询确认:支付宝订单直接看本地状态,微信订单查微信 SUCCESS 后幂等履约。"""
from django.core.cache import cache
try:
order = Czjilu.query.get(dingdan_id=dingdan_id, yonghuid=yonghuid)
@@ -194,13 +376,29 @@ def confirm_czjilu_paid(dingdan_id, yonghuid, expected_leixing):
if order.zhuangtai != 9:
raise CzjiluFulfillError(f'订单状态异常: {order.zhuangtai}', 'status_error')
# 支付宝订单:异步回调会更新状态,轮询时只看本地状态,未支付则提示稍后重试
is_alipay = cache.get(f'alipay_pay_url_{dingdan_id}') is not None
if is_alipay:
raise CzjiluFulfillError('支付宝支付结果尚未同步,请稍后再试', 'not_paid')
# 微信订单:主动查单
from jituan.services.member_recharge import query_wechat_v2_trade_state
trade_state, _ = query_wechat_v2_trade_state(dingdan_id, getattr(order, 'club_id', None))
if trade_state != 'SUCCESS':
raise CzjiluFulfillError('微信侧尚未支付成功,请稍后再试', 'not_paid')
paid = Decimal(str(order.jine))
if expected_leixing == 1:
from jituan.services.member_recharge import fulfill_member_recharge
return fulfill_member_recharge(dingdan_id, paid_amount_yuan=paid, source='confirm')
if expected_leixing == 2:
return fulfill_yajin_recharge(dingdan_id, paid_amount_yuan=paid)
if expected_leixing == 3:
return fulfill_jifen_recharge(dingdan_id, paid_amount_yuan=paid)
if expected_leixing == 4:
return fulfill_shangjia(dingdan_id, paid_amount_yuan=paid)
if expected_leixing == 5:
return fulfill_kaohe(dingdan_id, paid_amount_yuan=paid)
if expected_leixing == 6:
return fulfill_fakuan(dingdan_id, paid_amount_yuan=paid)
raise CzjiluFulfillError('不支持的充值类型', 'type_error')
+5
View File
@@ -1088,6 +1088,11 @@ def confirm_member_recharge_paid(dingdan_id, yonghuid):
if order.zhuangtai != MEMBER_PENDING_STATUS:
raise MemberRechargeError(f'订单状态异常: {order.zhuangtai}', 'status_error')
# 支付宝订单:异步回调会更新状态,轮询时只看本地状态,未支付则提示稍后重试
from django.core.cache import cache
if cache.get(f'alipay_pay_url_{dingdan_id}') is not None:
raise MemberRechargeError('支付宝支付结果尚未同步,请稍后再试', 'not_paid')
trade_state, _ = query_wechat_v2_trade_state(
dingdan_id, getattr(order, 'club_id', None),
)
+4 -1
View File
@@ -8,7 +8,8 @@ from .views import ShangpinHuoquView, ShangpinXiangqingHuoquView, DashouHuiyuanL
ShangpinZhuanquFabuView, ShangpinFabuView, GuizeTupianShangchuanView, AdHuiyuanHqView, HuiyuanXiugaiView, \
AdHuiyuanFbView, AdShangpinHuQu, AdLeixingXiuGai, AdLunboXiuGai, AdZhuanquXiuGai, AdGonggaoXiuGai, \
AdShangpinGuizeXiuGai, AdShangpinXiuGai, AdShangpinNeiRongHuoQu,\
HuiyuanTypeListView, HuiyuanRecordListView, ZuzhangFenhongView, CzhqdyView, DsqrgmdhView
HuiyuanTypeListView, HuiyuanRecordListView, ZuzhangFenhongView, CzhqdyView, DsqrgmdhView, \
AlipayCzjiluNotifyView
urlpatterns = [
#path('shangpinhuoqu/', ShangpinHuoquView.as_view(), name='获取商品数据商品类型和专区'),
@@ -34,6 +35,8 @@ urlpatterns = [
path('huiyuanlx', HuiyuanLunxun.as_view(), name='会员支付轮询'),
path('sjcz', ShangjiaChongzhi.as_view(), name='商家充值支付参数获取'), # 商家充值支付参数
path('sjhuitiao', csrf_exempt(ShangjiaHuitiao.as_view()), name='商家支付官方回调'),
# 支付宝 Czjilu 充值统一回调(押金/积分/会员/商家/考核/罚款)
path('alipay-czjilu-notify/', csrf_exempt(AlipayCzjiluNotifyView.as_view()), name='支付宝Czjilu充值统一回调'),
#path('sjhuitiao', ShangjiaHuitiao.as_view(), name='商家支付官方回调'), # 商家支付回调
path('sjshibai', ShangjiaShibai.as_view(), name='商家支付失败'), # 商家支付失败处理
path('sjcg', ShangjiaChenggong.as_view(), name='商家支付成功'), # 商家支付成功轮询
+3
View File
@@ -56,6 +56,7 @@ from .chongzhi_payment import (
MAX_INTEGRAL,
IDENTITY_CONFIG,
)
from .alipay_czjilu_notify import AlipayCzjiluNotifyView
from .shangpin_admin import (
ShangpinLeixingFabuView,
ShangpinZhuanquFabuView,
@@ -96,6 +97,8 @@ __all__ = [
'ShangjiaChongzhi', 'ShangjiaHuitiao', 'ShangjiaShibai', 'ShangjiaChenggong',
'CzhqdyView', 'DsqrgmdhView',
'INTEGRAL_PRICE', 'INTEGRAL_INCREMENT', 'MAX_INTEGRAL', 'IDENTITY_CONFIG',
# alipay_czjilu_notify
'AlipayCzjiluNotifyView',
# shangpin_admin
'ShangpinLeixingFabuView', 'ShangpinZhuanquFabuView', 'ShangpinFabuView',
'GuizeTupianShangchuanView',
+117
View File
@@ -0,0 +1,117 @@
"""支付宝 Czjilu 类充值统一异步回调视图。
所有基于 Czjilu 表的支付宝支付(押金/积分/会员/商家充值/考核/罚款)
共用一个回调入口,按 Czjilu.leixing 路由到对应履约函数。
"""
import logging
import traceback
from django.http import HttpResponse
from django.views import View
from products.models import Czjilu
from products.czjilu_types import (
CZJILU_LEIXING_HUIYUAN, CZJILU_LEIXING_YAJIN, CZJILU_LEIXING_JIFEN,
CZJILU_LEIXING_SHANGJIA, CZJILU_LEIXING_KAOHE, CZJILU_LEIXING_FAKUAN,
)
logger = logging.getLogger(__name__)
class AlipayCzjiluNotifyView(View):
"""支付宝 Czjilu 充值统一回调:验签 + 按 leixing 路由履约。
路径:/shangpin/alipay-czjilu-notify/
不需要 JWT 认证,由支付宝服务器调用。
"""
def post(self, request):
try:
# 注意:必须用 .dict() 而不是 dict()
# dict(request.POST) 返回 {key: [value_list]}(值是列表)
# request.POST.dict() 返回 {key: value}(值是字符串),符合验签需求
params = request.POST.dict() if request.POST else {}
if not params:
logger.warning('[ALIPAY_CZJILU_NOTIFY] 收到空数据')
return HttpResponse('fail', content_type='text/plain')
out_trade_no = params.get('out_trade_no', '')
trade_no = params.get('trade_no', '')
trade_status = params.get('trade_status', '')
total_amount = params.get('total_amount', '')
logger.info(
'[ALIPAY_CZJILU_NOTIFY] out_trade_no=%s, trade_no=%s, trade_status=%s, total_amount=%s',
out_trade_no, trade_no, trade_status, total_amount,
)
# 验签
from jituan.services.alipay_pay import verify_notify_params, club_id_from_czjilu
notify_club_id = club_id_from_czjilu(out_trade_no)
if not verify_notify_params(params, notify_club_id):
logger.warning('[ALIPAY_CZJILU_NOTIFY] 验签失败: out_trade_no=%s', out_trade_no)
return HttpResponse('fail', content_type='text/plain')
# 仅处理交易成功状态
if trade_status not in ('TRADE_SUCCESS', 'TRADE_FINISHED'):
logger.info('[ALIPAY_CZJILU_NOTIFY] 非成功状态 %s: %s', trade_status, out_trade_no)
return HttpResponse('success', content_type='text/plain')
# 查询充值单
order = Czjilu.query.filter(dingdan_id=out_trade_no).first()
if not order:
logger.error('[ALIPAY_CZJILU_NOTIFY] 充值单不存在: %s', out_trade_no)
return HttpResponse('fail', content_type='text/plain')
# 已支付:补记收支后直接返回成功(幂等)
if order.zhuangtai == 3:
logger.info('[ALIPAY_CZJILU_NOTIFY] 订单已支付,幂等返回: %s', out_trade_no)
return HttpResponse('success', content_type='text/plain')
if order.zhuangtai != 9:
logger.warning(
'[ALIPAY_CZJILU_NOTIFY] 订单状态异常: %s, zhuangtai=%s',
out_trade_no, order.zhuangtai,
)
return HttpResponse('success', content_type='text/plain')
# 按 leixing 路由到对应履约函数
paid_amount = total_amount or order.jine
leixing = order.leixing
try:
if leixing == CZJILU_LEIXING_HUIYUAN:
from jituan.services.member_recharge import fulfill_member_recharge
fulfill_member_recharge(out_trade_no, paid_amount_yuan=paid_amount, source='callback')
elif leixing == CZJILU_LEIXING_YAJIN:
from jituan.services.czjilu_fulfill import fulfill_yajin_recharge
fulfill_yajin_recharge(out_trade_no, paid_amount_yuan=paid_amount)
elif leixing == CZJILU_LEIXING_JIFEN:
from jituan.services.czjilu_fulfill import fulfill_jifen_recharge
fulfill_jifen_recharge(out_trade_no, paid_amount_yuan=paid_amount)
elif leixing == CZJILU_LEIXING_SHANGJIA:
from jituan.services.czjilu_fulfill import fulfill_shangjia
fulfill_shangjia(out_trade_no, paid_amount_yuan=paid_amount)
elif leixing == CZJILU_LEIXING_KAOHE:
from jituan.services.czjilu_fulfill import fulfill_kaohe
fulfill_kaohe(out_trade_no, paid_amount_yuan=paid_amount)
elif leixing == CZJILU_LEIXING_FAKUAN:
from jituan.services.czjilu_fulfill import fulfill_fakuan
fulfill_fakuan(out_trade_no, paid_amount_yuan=paid_amount)
else:
logger.error('[ALIPAY_CZJILU_NOTIFY] 未知 leixing=%s: %s', leixing, out_trade_no)
return HttpResponse('fail', content_type='text/plain')
except Exception as fulfill_exc:
logger.error(
'[ALIPAY_CZJILU_NOTIFY] 履约异常 out_trade_no=%s leixing=%s: %s',
out_trade_no, leixing, fulfill_exc, exc_info=True,
)
# 履约异常返回 fail,让支付宝重试
return HttpResponse('fail', content_type='text/plain')
logger.info('[ALIPAY_CZJILU_NOTIFY] 履约完成: %s, leixing=%s', out_trade_no, leixing)
return HttpResponse('success', content_type='text/plain')
except Exception as e:
logger.error('[ALIPAY_CZJILU_NOTIFY] 回调处理异常: %s', str(e))
logger.error(traceback.format_exc())
return HttpResponse('fail', content_type='text/plain')
+37 -19
View File
@@ -156,26 +156,44 @@ class ShangjiaChongzhi(APIView):
'message': '订单创建失败,请重试'
}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
# 5. 生成微信支付参数
try:
pay_openid, _ = get_payment_openid(request)
if not pay_openid:
# 5. 生成支付参数(支持支付宝/微信)
pay_method = (request.data.get('pay_method') or request.data.get('payMethod') or 'wechat').lower()
if pay_method == 'alipay':
try:
from jituan.services.alipay_pay import generate_alipay_czjilu_pay_params
pay_params = generate_alipay_czjilu_pay_params(
dingdanid=dingdanid,
jine=jine,
subject=settings.SHANGJIA_CZ_PAY_DESCRIPTION,
club_id=resolve_club_id_for_write(request, request.user),
)
except Exception as e:
chongzhi_jilu.delete()
return Response({'code': 400, 'message': '用户openid不存在'}, status=status.HTTP_400_BAD_REQUEST)
pay_params = self.generate_wechat_pay_params(
dingdanid=dingdanid,
jine=jine,
openid=pay_openid,
pay_type='shangjia'
)
except Exception as e:
# 支付参数生成失败,删除订单记录
chongzhi_jilu.delete()
logger.error(f"生成微信支付参数失败: {str(e)}")
return Response({
'code': 500,
'message': f'支付参数生成失败: {str(e)}'
}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
logger.error(f"生成支付宝支付参数失败: {str(e)}")
return Response({
'code': 500,
'message': f'支付参数生成失败: {str(e)}'
}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
else:
try:
pay_openid, _ = get_payment_openid(request)
if not pay_openid:
chongzhi_jilu.delete()
return Response({'code': 400, 'message': '用户openid不存在'}, status=status.HTTP_400_BAD_REQUEST)
pay_params = self.generate_wechat_pay_params(
dingdanid=dingdanid,
jine=jine,
openid=pay_openid,
pay_type='shangjia'
)
except Exception as e:
# 支付参数生成失败,删除订单记录
chongzhi_jilu.delete()
logger.error(f"生成微信支付参数失败: {str(e)}")
return Response({
'code': 500,
'message': f'支付参数生成失败: {str(e)}'
}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
# 6. 返回支付参数和订单ID
logger.info(f"商家{shangjia.nicheng}支付参数生成成功: {dingdanid}")
+46 -25
View File
@@ -164,35 +164,56 @@ class HuiyuanGoumai(APIView):
f"会员{huiyuanid}, 俱乐部{club_id}, 体验={is_trial}, "
f"金额{jine}元, 天数{purchase_days}")
# 7. 生成微信支付参数
try:
pay_openid, _ = get_payment_openid(request)
if not pay_openid:
# 7. 生成支付参数(支持支付宝/微信)
pay_method = (request.data.get('pay_method') or request.data.get('payMethod') or 'wechat').lower()
if pay_method == 'alipay':
try:
from jituan.services.alipay_pay import generate_alipay_czjilu_pay_params
pay_params = generate_alipay_czjilu_pay_params(
dingdanid=dingdanid,
jine=jine,
subject=settings.HUIYUAN_PAY_DESCRIPTION,
club_id=club_id,
)
except Exception as e:
from jituan.services.member_recharge import MEMBER_CANCELLED_STATUS
chongzhi_jilu.zhuangtai = MEMBER_CANCELLED_STATUS
chongzhi_jilu.shuoming = f"{shuoming} | 下单失败:openid不存在"[:100]
chongzhi_jilu.shuoming = f"{shuoming} | 下单失败:{str(e)[:40]}"[:100]
chongzhi_jilu.save(update_fields=['zhuangtai', 'shuoming'])
logger.error(f"生成会员支付宝参数失败: {str(e)}")
return Response({
'code': 400,
'message': '用户openid不存在',
'dingdanid': dingdanid,
}, status=status.HTTP_400_BAD_REQUEST)
pay_params = self.generate_wechat_pay_params(
dingdanid=dingdanid,
jine=jine,
openid=pay_openid,
pay_type='huiyuan'
)
except Exception as e:
from jituan.services.member_recharge import MEMBER_CANCELLED_STATUS
chongzhi_jilu.zhuangtai = MEMBER_CANCELLED_STATUS
chongzhi_jilu.shuoming = f"{shuoming} | 下单失败:{str(e)[:40]}"[:100]
chongzhi_jilu.save(update_fields=['zhuangtai', 'shuoming'])
logger.error(f"生成会员支付参数失败: {str(e)}")
return Response({
'code': 500,
'message': f'支付参数生成失败: {str(e)}'
}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
'code': 500,
'message': f'支付参数生成失败: {str(e)}'
}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
else:
try:
pay_openid, _ = get_payment_openid(request)
if not pay_openid:
from jituan.services.member_recharge import MEMBER_CANCELLED_STATUS
chongzhi_jilu.zhuangtai = MEMBER_CANCELLED_STATUS
chongzhi_jilu.shuoming = f"{shuoming} | 下单失败:openid不存在"[:100]
chongzhi_jilu.save(update_fields=['zhuangtai', 'shuoming'])
return Response({
'code': 400,
'message': '用户openid不存在',
'dingdanid': dingdanid,
}, status=status.HTTP_400_BAD_REQUEST)
pay_params = self.generate_wechat_pay_params(
dingdanid=dingdanid,
jine=jine,
openid=pay_openid,
pay_type='huiyuan'
)
except Exception as e:
from jituan.services.member_recharge import MEMBER_CANCELLED_STATUS
chongzhi_jilu.zhuangtai = MEMBER_CANCELLED_STATUS
chongzhi_jilu.shuoming = f"{shuoming} | 下单失败:{str(e)[:40]}"[:100]
chongzhi_jilu.save(update_fields=['zhuangtai', 'shuoming'])
logger.error(f"生成会员支付参数失败: {str(e)}")
return Response({
'code': 500,
'message': f'支付参数生成失败: {str(e)}'
}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
# 8. 返回支付参数和订单ID
return Response({
+37 -19
View File
@@ -132,26 +132,44 @@ class JifenBuchong(APIView):
logger.info(f"创建积分充值订单: 用户{request.user.UserUID}, 订单{dingdanid}, 金额{jine}元")
# 6. 生成微信支付参数(完整版)
try:
pay_openid, _ = get_payment_openid(request)
if not pay_openid:
# 6. 生成支付参数(支持支付宝/微信)
pay_method = (request.data.get('pay_method') or request.data.get('payMethod') or 'wechat').lower()
if pay_method == 'alipay':
try:
from jituan.services.alipay_pay import generate_alipay_czjilu_pay_params
pay_params = generate_alipay_czjilu_pay_params(
dingdanid=dingdanid,
jine=jine,
subject=settings.JIFEN_PAY_DESCRIPTION,
club_id=resolve_club_id_for_write(request, request.user),
)
except Exception as e:
chongzhi_jilu.delete()
return Response({'code': 400, 'message': '用户openid不存在'}, status=status.HTTP_400_BAD_REQUEST)
pay_params = self.generate_wechat_pay_params(
dingdanid=dingdanid,
jine=jine,
openid=pay_openid,
pay_type='jifen'
)
except Exception as e:
# 支付参数生成失败,删除订单记录
chongzhi_jilu.delete()
logger.error(f"生成积分支付参数失败: {str(e)}")
return Response({
'code': 500,
'message': f'支付参数生成失败: {str(e)}'
}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
logger.error(f"生成支付宝支付参数失败: {str(e)}")
return Response({
'code': 500,
'message': f'支付参数生成失败: {str(e)}'
}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
else:
try:
pay_openid, _ = get_payment_openid(request)
if not pay_openid:
chongzhi_jilu.delete()
return Response({'code': 400, 'message': '用户openid不存在'}, status=status.HTTP_400_BAD_REQUEST)
pay_params = self.generate_wechat_pay_params(
dingdanid=dingdanid,
jine=jine,
openid=pay_openid,
pay_type='jifen'
)
except Exception as e:
# 支付参数生成失败,删除订单记录
chongzhi_jilu.delete()
logger.error(f"生成积分支付参数失败: {str(e)}")
return Response({
'code': 500,
'message': f'支付参数生成失败: {str(e)}'
}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
# 7. 返回支付参数和订单ID
return Response({
+37 -19
View File
@@ -146,26 +146,44 @@ class YajinGoumai(APIView):
logger.info(f"创建押金充值订单: 用户{request.user.UserUID}, 订单{dingdanid}, 金额{jine}元")
# 5. 生成微信支付参数
try:
pay_openid, _ = get_payment_openid(request)
if not pay_openid:
# 5. 生成支付参数(支持支付宝/微信)
pay_method = (request.data.get('pay_method') or request.data.get('payMethod') or 'wechat').lower()
if pay_method == 'alipay':
try:
from jituan.services.alipay_pay import generate_alipay_czjilu_pay_params
pay_params = generate_alipay_czjilu_pay_params(
dingdanid=dingdanid,
jine=jine,
subject=settings.YAJIN_PAY_DESCRIPTION,
club_id=resolve_club_id_for_write(request, request.user),
)
except Exception as e:
chongzhi_jilu.delete()
return Response({'code': 400, 'message': '用户openid不存在'}, status=status.HTTP_400_BAD_REQUEST)
pay_params = self.generate_wechat_pay_params(
dingdanid=dingdanid,
jine=jine,
openid=pay_openid,
pay_type='yajin'
)
except Exception as e:
# 支付参数生成失败,删除订单记录
chongzhi_jilu.delete()
logger.error(f"生成微信支付参数失败: {str(e)}")
return Response({
'code': 500,
'message': f'支付参数生成失败: {str(e)}'
}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
logger.error(f"生成支付宝支付参数失败: {str(e)}")
return Response({
'code': 500,
'message': f'支付参数生成失败: {str(e)}'
}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
else:
try:
pay_openid, _ = get_payment_openid(request)
if not pay_openid:
chongzhi_jilu.delete()
return Response({'code': 400, 'message': '用户openid不存在'}, status=status.HTTP_400_BAD_REQUEST)
pay_params = self.generate_wechat_pay_params(
dingdanid=dingdanid,
jine=jine,
openid=pay_openid,
pay_type='yajin'
)
except Exception as e:
# 支付参数生成失败,删除订单记录
chongzhi_jilu.delete()
logger.error(f"生成微信支付参数失败: {str(e)}")
return Response({
'code': 500,
'message': f'支付参数生成失败: {str(e)}'
}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
# 6. 返回支付参数和订单ID
return Response({
+78 -39
View File
@@ -131,13 +131,6 @@ class FaKuanPayView(APIView):
from jituan.services.club_user import get_payment_openid
from products.czjilu_types import CZJILU_LEIXING_FAKUAN, penalty_cz_shuoming
pay_openid, _ = get_payment_openid(request)
if not pay_openid:
return Response({
'code': 400,
'message': '用户openid不存在,无法发起微信支付',
}, status=status.HTTP_400_BAD_REQUEST)
chongzhi_jilu = Czjilu.query.create(
dingdan_id=dingdanid,
zhuangtai=9,
@@ -148,20 +141,46 @@ class FaKuanPayView(APIView):
club_id=penalty_cz_club_id(fadan),
)
try:
pay_params = self.generate_wechat_pay_params(
dingdanid=dingdanid,
jine=jine,
openid=pay_openid,
pay_type='fakuan'
)
except Exception as e:
chongzhi_jilu.delete()
logger.error(f"生成微信支付参数失败: {str(e)}")
return Response({
'code': 500,
'message': f'支付参数生成失败: {str(e)}'
}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
# 生成支付参数(支持支付宝/微信)
pay_method = (request.data.get('pay_method') or request.data.get('payMethod') or 'wechat').lower()
if pay_method == 'alipay':
try:
from jituan.services.alipay_pay import generate_alipay_czjilu_pay_params
pay_params = generate_alipay_czjilu_pay_params(
dingdanid=dingdanid,
jine=jine,
subject=settings.FAKUAN_PAY_DESCRIPTION,
club_id=penalty_cz_club_id(fadan),
)
except Exception as e:
chongzhi_jilu.delete()
logger.error(f"生成支付宝支付参数失败: {str(e)}")
return Response({
'code': 500,
'message': f'支付参数生成失败: {str(e)}'
}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
else:
pay_openid, _ = get_payment_openid(request)
if not pay_openid:
chongzhi_jilu.delete()
return Response({
'code': 400,
'message': '用户openid不存在,无法发起微信支付',
}, status=status.HTTP_400_BAD_REQUEST)
try:
pay_params = self.generate_wechat_pay_params(
dingdanid=dingdanid,
jine=jine,
openid=pay_openid,
pay_type='fakuan'
)
except Exception as e:
chongzhi_jilu.delete()
logger.error(f"生成微信支付参数失败: {str(e)}")
return Response({
'code': 500,
'message': f'支付参数生成失败: {str(e)}'
}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
return Response({
'code': 200,
@@ -670,25 +689,45 @@ class KaohePayView(APIView):
attach_str = json.dumps({'oid': dingdanid}, ensure_ascii=False)
logger.info(f"attach内容: {attach_str},长度: {len(attach_str.encode('utf-8'))}字节")
# 11. 生成微信支付参数
try:
pay_params = self.generate_wechat_pay_params(
dingdanid=dingdanid,
jine=float(fee),
openid=user.OpenID,
attach=attach_str,
pay_type='kaohe'
)
logger.info(f"微信支付参数生成成功: {dingdanid}")
except Exception as e:
order.delete() # 下单失败,删除订单记录
# 同时删除临时表记录
# 11. 生成支付参数(支持支付宝/微信)
pay_method = (request.data.get('pay_method') or request.data.get('payMethod') or 'wechat').lower()
if pay_method == 'alipay':
try:
KaohePayTemp.query.filter(dingdan_id=dingdanid).delete()
except Exception as del_e:
logger.error(f"删除临时表记录失败: {str(del_e)}")
logger.error(f"生成微信支付参数失败: {str(e)}", exc_info=True)
return Response({'code': 500, 'message': f'支付参数生成失败: {str(e)}'})
from jituan.services.alipay_pay import generate_alipay_czjilu_pay_params
pay_params = generate_alipay_czjilu_pay_params(
dingdanid=dingdanid,
jine=float(fee),
subject=settings.KAOHE_PAY_DESCRIPTION,
club_id=resolve_club_id_for_write(request, user),
)
logger.info(f"支付宝支付参数生成成功: {dingdanid}")
except Exception as e:
order.delete()
try:
KaohePayTemp.query.filter(dingdan_id=dingdanid).delete()
except Exception as del_e:
logger.error(f"删除临时表记录失败: {str(del_e)}")
logger.error(f"生成支付宝支付参数失败: {str(e)}", exc_info=True)
return Response({'code': 500, 'message': f'支付参数生成失败: {str(e)}'})
else:
try:
pay_params = self.generate_wechat_pay_params(
dingdanid=dingdanid,
jine=float(fee),
openid=user.OpenID,
attach=attach_str,
pay_type='kaohe'
)
logger.info(f"微信支付参数生成成功: {dingdanid}")
except Exception as e:
order.delete() # 下单失败,删除订单记录
# 同时删除临时表记录
try:
KaohePayTemp.query.filter(dingdan_id=dingdanid).delete()
except Exception as del_e:
logger.error(f"删除临时表记录失败: {str(del_e)}")
logger.error(f"生成微信支付参数失败: {str(e)}", exc_info=True)
return Response({'code': 500, 'message': f'支付参数生成失败: {str(e)}'})
return Response({
'code': 200,