From c85c520df94b73c017529dc35548d9b59ab1bd71 Mon Sep 17 00:00:00 2001 From: ping <1017253325@qq.com> Date: Tue, 23 Sep 2025 14:25:29 +0800 Subject: [PATCH] update --- b/baiduc/baidu_confirm_refund_order.dspy | 308 ++++++++++++++++++----- 1 file changed, 249 insertions(+), 59 deletions(-) diff --git a/b/baiduc/baidu_confirm_refund_order.dspy b/b/baiduc/baidu_confirm_refund_order.dspy index 405df3d..10cf3d7 100644 --- a/b/baiduc/baidu_confirm_refund_order.dspy +++ b/b/baiduc/baidu_confirm_refund_order.dspy @@ -111,14 +111,13 @@ async def affirmbz_order(ns={}): except Exception as error: await sor.rollback() raise error + +async def baidu_new_update_resouce(ns={}): + + # 增加延迟 + import asyncio + await asyncio.sleep(12) -async def get_baidu_orderlist(ns={}): - """ - 百度支付 - 1、获取订单 - 2、算出购买的产品折扣 - 3、比对账号余额 - """ db = DBPools() async with db.sqlorContext('kboss') as sor: baidu_users = await sor.R('baidu_users', {'user_id': ns.get('userid'),'del_flg':'0'}) @@ -139,16 +138,107 @@ async def get_baidu_orderlist(ns={}): headers=header, json=nss) as res: data_ = await res.json() + with open('baidu_new_order_after_confirm.txt', 'a+') as f: + f.write(json.dumps(data_) + '\n') + orders = data_['orders'] + + for item in orders: + order_items = item['orderItems'] + for order_info in order_items: + resourceids = ','.join(order_info['shortIds']) if order_info.get('shortIds') else '' + if not resourceids: + continue + resourcestarttime = await time_convert(order_info.get('resourceStartTime')) if order_info.get( + 'resourceStartTime') else None + resourceendtime = await time_convert(order_info.get('resourceEndTime')) if order_info.get( + 'resourceEndTime') else None + + order_key = order_info['key'] + update_order_goods_sql = """ UPDATE order_goods og + JOIN bz_order o ON og.orderid = o.id + SET + og.resourceids = '%s', + og.resourcestarttime = '%s', + og.resourceendtime = '%s' + WHERE + og.orderkey = '%s' + AND o.provider_orderid = '%s'; """ \ + % (resourceids, resourcestarttime, resourceendtime, order_key, ns.get('order_id')) + await sor.sqlExe(update_order_goods_sql, {}) + update_customer_goods_sql = """ UPDATE customer_goods og + JOIN bz_order o ON og.orderid = o.id + SET + og.resourceid = '%s', + og.start_date = '%s', + og.expire_date = '%s' + WHERE + og.orderkey = '%s' + AND o.provider_orderid = '%s'; """ \ + % (resourceids, resourcestarttime, resourceendtime, order_key, ns.get('order_id')) + await sor.sqlExe(update_customer_goods_sql, {}) + +async def baidu_order_cancel(ns={}): + baidu_id = ns['baidu_id'] + order_id = ns['order_id'] + paydata = {'queryAccountId': baidu_id, 'orderIds': [order_id]} + ns_format = '&'.join(['%s=%s' % (k, v) for k, v in ns.items()]) + url = 'https://billing.baidubce.com/v1/order/cancel?%s' % ns_format + method = 'POST' + header = { + "Host": "billing.baidubce.com" + } + header = await get_auth_header(method=method, url=url, header=header) + async with aiohttp_client.request( + method=method, + url=url, + headers=header, + json=paydata) as res: + await res.json() + return { + 'status': True, + 'msg': 'order cancel success' + } + +async def get_baidu_orderlist(ns={}): + """ + 百度支付 + 1、获取订单 + 2、算出购买的产品折扣 + 3、比对账号余额 + """ + # 增加延迟 + import asyncio + await asyncio.sleep(1) + db = DBPools() + async with db.sqlorContext('kboss') as sor: + baidu_users = await sor.R('baidu_users', {'user_id': ns.get('userid'),'del_flg':'0'}) + user = await sor.R('users', {'id': ns.get('userid')}) + orgid = await sor.R('organization', {'id': user[0]['orgid']}) + nss = {'uuids': [ns.get('order_id')], 'queryAccountId': baidu_users[0]['baidu_id']} + ns_format = '&'.join(['%s=%s' % (k, v) for k, v in ns.items()]) + url = 'https://billing.baidubce.com/v1/order/getByUuid?%s' % ns_format + method = 'POST' + header = { + "Host": "billing.baidubce.com", + "ContentType": "application/json;charset=UTF-8" + } + header = await get_auth_header(method=method, url=url, header=header) + async with aiohttp_client.request( + method=method, + url=url, + headers=header, + json=nss) as res: + data_ = await res.json() + with open('baidu_new_order.txt', 'a+') as f: + f.write(json.dumps(data_) + '\n') orders = data_['orders'] serviceType = orders[0]['orderItems'] # 可能获取得到的是延迟订单 if orders[0]['type'] == 'REFUND' and orders[0]['status'] != 'CREATED': - return { - 'status': False, - 'msg': 'delay_order, 当前状态是: %s' % orders[0]['status'], - 'data': data_ - } + await update_baidu_order_list({'userid': ns.get('userid')}) + res_refund = await baidu_confirm_refund_order({'order_id': ns.get('order_id'), 'baidu_id': baidu_users[0]['baidu_id'], 'user_id': ns.get('userid')}) + return res_refund # 避免重复退订 if orders[0]['type'] == 'REFUND' and orders[0]['status'] == 'CREATED': @@ -167,19 +257,52 @@ async def get_baidu_orderlist(ns={}): (float(orders[0]['price']), orders[0]['status'], updatetime, ns.get('order_id')) await sor.sqlExe(update_refund_sql, {}) + productType = 'prepay' # 判断订单item中productType是否有后付费的产品 for item in orders: order_items = item['orderItems'] for order_info in order_items: postpay_price = order_info['itemFee']['price'] if order_info.get('itemFee') else order_info['catalogPrice'] + if not postpay_price: + # cpt1Price: 固定配置,按分钟计费 + postpay_price = order_info['pricingDetail'].get('cpt1Price') if order_info.get('pricingDetail') else 0 + + # 确定是否是后付费订单 if order_info['productType'] == 'postpay' and postpay_price != 0: - return { - 'status': False, - 'msg': '暂不支持后付费按量购买, 请联系后台开通' - } + productType = 'postpay' + # 获取余额 + user_balance = await getCustomerBalance(sor, orgid[0]['id']) + # 判断余额是否大于50 + if user_balance < 50: + await sor.rollback() + paydata = {'queryAccountId': baidu_users[0]['baidu_id'], 'orderIds': [ns.get('order_id')]} + ns_format = '&'.join(['%s=%s' % (k, v) for k, v in ns.items()]) + url = 'https://billing.baidubce.com/v1/order/cancel?%s' % ns_format + method = 'POST' + header = { + "Host": "billing.baidubce.com" + } + header = await get_auth_header(method=method, url=url, header=header) + async with aiohttp_client.request( + method=method, + url=url, + headers=header, + json=paydata) as res: + await res.json() + ns_record = { + 'orderid': ns.get('order_id'), + 'ordertype': orders[0]['type'], + 'userid': ns.get('userid'), + 'reason': '后付费 该账号余额不足50,无法完成购买' + } + await user_action_record(ns_record) + return { + 'status': False, + 'msg': '您的余额小于该产品的起购金额50元, 目前无法购买立即充值' + } # 实付价格 total_price = 0 - productType = '' + # productType = '' # 买/续/退 字段映射 order_type = orders[0]['type'] @@ -212,7 +335,8 @@ async def get_baidu_orderlist(ns={}): bz_ns['order_date'] = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") bz_ns['thirdparty_order'] = ns.get('order_id') bz_ns['source'] = '百度智能云' - bz_ns['originalprice'] = orders[0]['price'] + # bz_ns['originalprice'] = orders[0]['price'] + bz_ns['originalprice'] = sum(i['catalogPrice'] for i in serviceType) bz_ns['provider_orderid'] = ns.get('order_id') bz_ns['ordertype'] = orders[0]['productType'] bz_ns['servicename'] = orders[0]['serviceType'] @@ -221,23 +345,45 @@ async def get_baidu_orderlist(ns={}): bz_ns['specdataid'] = ns['specdataid'] await sor.C('bz_order', bz_ns) for i in serviceType: - if i['productType'] == 'prepay': - # 预付费 - productType = 'prepay' + # if i['productType'] == 'prepay': + # # 预付费 + # productType = 'prepay' # financePrice = 0 # 获取产品id product = await sor.R('product', {'providerpid': 'baidu_' + i['serviceType'], 'del_flg': '0'}) + if not product: + return { + 'status': False, + 'msg': '未配置该产品, 请联系售后处理' + } # 获取协议 - saleprotocol = await sor.R('saleprotocol', + saleprotocol_to_person = await sor.R('saleprotocol', {'bid_orgid': orgid[0]['id'], 'offer_orgid': orgid[0]['parentid'], 'del_flg': '0'}) - if saleprotocol == []: - # 等于空就代表这个客户没有特殊折扣,就要找到买方为*的协议 - saleprotocol = await sor.R('saleprotocol', {'bid_orgid': '*', 'offer_orgid': orgid[0]['parentid'], - 'del_flg': '0', 'salemode': '0'}) - product_salemode = await sor.R('product_salemode', - {'protocolid': saleprotocol[0]['id'], 'productid': product[0]['id'], - 'del_flg': '0'}) + # 等于空就代表这个客户没有特殊折扣,就要找到买方为*的协议 + saleprotocol_to_all = await sor.R('saleprotocol', {'bid_orgid': '*', 'offer_orgid': orgid[0]['parentid'], + 'del_flg': '0', 'salemode': '0'}) + + if saleprotocol_to_person: + product_salemode = await sor.R('product_salemode', + {'protocolid': saleprotocol_to_person[0]['id'], + 'productid': product[0]['id'], + 'del_flg': '0'}) + if not product_salemode: + product_salemode = await sor.R('product_salemode', + {'protocolid': saleprotocol_to_all[0]['id'], + 'productid': product[0]['id'], + 'del_flg': '0'}) + else: + product_salemode = await sor.R('product_salemode', + {'protocolid': saleprotocol_to_all[0]['id'], + 'productid': product[0]['id'], + 'del_flg': '0'}) + if not product_salemode: + return { + 'status': False, + 'msg': '还未上线这个产品的协议配置' + } supply_price = i['itemFee']['price'] if i.get('itemFee') else i['catalogPrice'] financePrice = abs(supply_price * product_salemode[0]['discount']) total_price += financePrice @@ -263,10 +409,11 @@ async def get_baidu_orderlist(ns={}): nss['chargeduration'] = i.get('time') nss['unit'] = i.get('timeUnit') nss['resourceids'] = ','.join(i['shortIds']) if i.get('shortIds') else '' + nss['orderkey'] = i.get('key') # 如果是续费订单 由于没有返回日期, 重新计算日期 if order_type == 'RENEW': - history_time_sql = "select resourcestarttime, resourceendtime from order_goods where resourceids = '%s' order by resourceendtime desc;" % \ + history_time_sql = "select resourcestarttime, resourceendtime from order_goods where FIND_IN_SET('%s', resourceids) order by resourceendtime desc;" % \ nss['resourceids'] history_time = await sor.sqlExe(history_time_sql, {}) new_end_time = await cal_expire_time(history_time=history_time[0]['resourceendtime'], @@ -275,27 +422,45 @@ async def get_baidu_orderlist(ns={}): nss['resourcestarttime'] = history_time[0]['resourcestarttime'] nss['resourceendtime'] = new_end_time else: - nss['resourcestarttime'] = await time_convert(i.get('resourceStartTime')) if i.get( - 'resourceStartTime') else None - nss['resourceendtime'] = await time_convert(i.get('resourceEndTime')) if i.get( - 'resourceEndTime') else None + if i.get('resourceStartTime'): + nss['resourcestarttime'] = await time_convert(i.get('resourceStartTime')) + else: + nss['resourcestarttime'] = await time_convert(orders[0]['updateTime']) + + if i.get('resourceEndTime'): + nss['resourceendtime'] = await time_convert(i.get('resourceEndTime')) + + # 后付费没有资源结束时间 + if i.get('productType') == 'prepay': + end_time = await time_convert(orders[0]['updateTime']) + nss['resourceendtime'] = await cal_expire_time(history_time=end_time, + chargeduration=nss['chargeduration'], + unit=nss['unit']) + else: + nss['resourceendtime'] = None await sor.C('order_goods', nss) # 循环后更新订单中总价 await sor.U('bz_order', {'id': bz_ns['id'], 'amount': round(total_price, 2)}) except Exception as e: + await baidu_order_cancel({'baidu_id': baidu_users[0]['baidu_id'], 'order_id': ns.get('order_id')}) + import traceback ns_record = { 'orderid': ns.get('order_id'), 'ordertype': orders[0]['type'], 'userid': ns.get('userid'), - 'reason': '发生错误, %s' % str(e)[:100] + 'reason': '发生错误, %s' % str(traceback.format_exc()) } await user_action_record(ns_record) - import traceback with open('baiducloud_err.txt', 'w') as f: - f.write(str(e)+ traceback.format_exc()) + f.write(str(e) + str(traceback.format_exc())) traceback.print_exc() + await sor.rollback() + return { + 'status': False, + 'msg': '产品错误, 请联系售后' + } # 判断用户账户余额是否足够支付 try: @@ -305,7 +470,7 @@ async def get_baidu_orderlist(ns={}): if round(total_price,2) <= count: #判断预付费或者后付费 - if productType == 'prepay': + if productType == 'prepay' or productType == 'postpay': # 调用扣费接口 affirmbz_order_ns = { 'sor': sor, @@ -320,7 +485,7 @@ async def get_baidu_orderlist(ns={}): 'orderid': ns.get('order_id'), 'ordertype': orders[0]['type'], 'userid': ns.get('userid'), - 'reason': '支付错误, 请联系售后' + 'reason': '支付错误, 请联系售后, %s' % affirmbz_order_res.get('msg') } await user_action_record(ns_record) return { @@ -336,22 +501,21 @@ async def get_baidu_orderlist(ns={}): } else: # 调用支付订单接口 - # paydata = {'queryAccountId':baidu_users[0]['baidu_id'],'orderId':ns.get('order_id')} - # ns_format = '&'.join(['%s=%s' % (k, v) for k, v in ns.items()]) - # url = 'https://billing.baidubce.com/v1/order/pay?%s' % ns_format - # method = 'POST' - # header = { - # "Host": "billing.baidubce.com" - # } - # header = await get_auth_header(method=method, url=url, header=header) - # async with aiohttp_client.request( - # method=method, - # url=url, - # headers=header, - # json=paydata) as res: - # data_ = await res.json() - # if data_ == {'success': True}: - if True: + paydata = {'queryAccountId':baidu_users[0]['baidu_id'],'orderId':ns.get('order_id')} + ns_format = '&'.join(['%s=%s' % (k, v) for k, v in ns.items()]) + url = 'https://billing.baidubce.com/v1/order/pay?%s' % ns_format + method = 'POST' + header = { + "Host": "billing.baidubce.com" + } + header = await get_auth_header(method=method, url=url, header=header) + async with aiohttp_client.request( + method=method, + url=url, + headers=header, + json=paydata) as res: + data_ = await res.json() + if data_ == {'success': True}: ns_record = { 'orderid': ns.get('order_id'), 'ordertype': orders[0]['type'], @@ -359,12 +523,23 @@ async def get_baidu_orderlist(ns={}): 'reason': '购买成功' } await user_action_record(ns_record) - return { - 'status': True, - 'orderid': bz_ns['id'] + ns_cron_job = { + 'id': uuid(), + 'source': 'baidu', + 'orderid': ns.get('order_id'), + 'ordertype': orders[0]['type'], + 'userid': ns.get('userid'), + 'reason': 'buy success' } + await sor.C('baidu_cron_job', ns_cron_job) + # return { + # 'status': True, + # 'orderid': bz_ns['id'] + # } else: await sor.rollback() + await baidu_order_cancel( + {'baidu_id': baidu_users[0]['baidu_id'], 'order_id': ns.get('order_id')}) ns_record = { 'orderid': ns.get('order_id'), 'ordertype': orders[0]['type'], @@ -427,10 +602,26 @@ async def get_baidu_orderlist(ns={}): await user_action_record(ns_record) return {'status': False,'msg': '该账号余额不足,无法完成购买'} except Exception as e: + await baidu_order_cancel({'baidu_id': baidu_users[0]['baidu_id'], 'order_id': ns.get('order_id')}) import traceback with open('baiducloud_err.txt', 'w') as f: f.write(str(e)+ traceback.format_exc()) traceback.print_exc() + await sor.rollback() + return { + 'status': False, + 'msg': '产品错误, 请联系售后' + } + # 更新资源时间 资源id + # if order_type == 'NEW': + # await baidu_new_update_resouce(ns) + return { + 'status': True, + 'orderid': bz_ns['id'], + 'originalprice': bz_ns.get('originalprice'), + 'servicename': bz_ns.get('servicename'), + 'amount': total_price + } async def get_order_list_base_page(baidu_id, pageNo=1, pageSize=500): ns = {'queryAccountId': baidu_id, 'pageNo': pageNo, 'pageSize': pageSize} @@ -525,7 +716,6 @@ async def baidu_confirm_refund_order(ns={}): # 'order_id': ["03ee8d08da79458b8f8d3157d3498330", "e711729606024080bf9613d975294616"], # 'userid': 'KsKhCUPizQyGiw3L1WVRy' # } - return {'1': ns} import asyncio # 把 NEED_CONFIRM的订单同步到本地库,用于后续状态更新 await update_baidu_order_list({'userid': ns.get('userid')})