def admin_refund(order_identify): voucher = Voucher.query.filter( Voucher.order_identify == order_identify).first() if voucher.is_send: flash("您已发货,无法退款!") elif voucher.is_refund == 2: flash("该订单已退款,无需再退款!") else: if voucher.is_refund == 0: flash("您已取消该订单,将向相应顾客退款!") app_private_key_string = open( r"app/subject/app_private_2048.txt").read() alipay_public_key_string = open( r"app/subject/alipay_public_2048.txt").read() myalipay = AliPay( appid="2016093000629449", app_notify_url=None, # 默认回调url app_private_key_string=app_private_key_string, # 支付宝的公钥,验证支付宝回传消息使用,不是你自己的公钥, alipay_public_key_string=alipay_public_key_string, sign_type="RSA2", # RSA 或者 RSA2 debug=True # 默认False ) result = myalipay.api_alipay_trade_refund( out_trade_no=order_identify, refund_amount=voucher.total_money) if result["code"] == "10000": voucher.is_refund = 2 db.session.commit() flash("退款成功") else: flash("退款失败") if voucher.multiply_commodities: current_items = [] movie_count = [] ids = list(map(lambda x: int(x), voucher.name.split())) for id in ids: item = Trolley.query.filter(Trolley.id == id).first() current_items.append(item.movie) movie_count.append(item.movie_count) return render_template('trolley/commodities.html', current_items=current_items, voucher=voucher, movie_count=movie_count, len=len, range=range) else: return render_template('subject/commodity.html', voucher=voucher)
def get(self, request, order_id): try: shop = Shop.objects.get(user_id=request.user.id) except Shop.DoesNotExist: return render(request, 'login.html', {'errmsg': '用户登录信息已失效,请重新登录!'}) # 校验参数 if not order_id: return redirect(reverse('ordermanage:sj_order', kwargs={'page': 1})) try: order = OrderInfo.objects.get(order_id=order_id, order_status=2) except OrderInfo.DoesNotExist: return redirect(reverse('ordermanage:sj_order', kwargs={'page': 1})) # 初始化 alipay = AliPay( appid=settings.ALIPAY_APPID, # 应用id app_notify_url=None, # 默认回调url app_private_key_path=os.path.join(settings.BASE_DIR, 'apps/order/app_private_key.pem'), # 支付宝的公钥,验证支付宝回传消息 alipay_public_key_path=os.path.join(settings.BASE_DIR, 'apps/order/alipay_public_key.pem'), sign_type="RSA2", # RSA 或者 RSA2 debug=True # 默认False ) order_string = alipay.api_alipay_trade_refund( trade_no=order.trade_no, refund_amount=str(order.total_price + order.transit_price), notify_url=None ) code = order_string.get('code') if code == '10000' and order_string.get('msg') == 'Success': # 改变订单状态,轨迹表生成一条数据 order.order_status = 0 order_track = OrderTrack.objects.create(order=order, status=0) order.save() else: sub_msg = order_string.get('sub_msg') return render(request, 'sj_order.html', {'errmsg': sub_msg}) return redirect(reverse('ordermanage:sj_order', kwargs={'page': 1}))
class AlipayBase(object): def __init__(self, isVip=None): # print(AliPay_alipay_private_key) # # # print(AliPay_alipay_public_key) # # print(AliPay_Appid) self.alipay = AliPay( appid=AliPay_Appid, app_notify_url=Alipay_callbackUrl if not isVip else Alipay_callbackUrlForVip, app_private_key_string=AliPay_app_private_key, alipay_public_key_string=AliPay_alipay_public_key, sign_type="RSA2", debug=False, # 上线则改为False , 沙箱True ) def query(self, orderid): response = self.alipay.api_alipay_trade_query(out_trade_no=orderid) return response def create(self, order_id, amount, subject=None): order_string = self.alipay.api_alipay_trade_app_pay( out_trade_no=order_id, total_amount=str(amount.quantize(Decimal('0.00'))), subject='支付订单:%s' % order_id if not subject else subject, return_url=None, notify_url=None, ) logger.info(order_string) return order_string def refund(self, order, orderid, refund_amount): response = self.alipay.api_alipay_trade_refund(refund_amount=str( refund_amount.quantize(Decimal('0.00'))), out_trade_no=orderid) logger.info("退款信息->{}".format(response)) if response['code'] != '10000': raise PubErrorCustom(response['msg']) try: for item in OrderGoodsLink.objects.filter( linkid__in=json.loads(order.linkid)['linkids']): try: glObj = GoodsLinkSku.objects.select_for_update().get( id=item.skugoodslinkid) glObj.stock += item.gdnum glObj.number -= item.gdnum glObj.save() except GoodsLinkSku.DoesNotExist: pass except Exception as e: print(str(e)) def callback_vip(self, data): iData = dict() for item in data: iData[item] = data[item] sign = iData.pop("sign", None) if not self.alipay.verify(iData, sign): print(iData) raise PubErrorCustom("验签失败!") if iData.get("trade_status", None) != 'TRADE_SUCCESS': print(iData) raise PubErrorCustom("交易状态异常!") try: orderObj = OrderVip.objects.select_for_update().get( orderid=iData.get("out_trade_no", "")) if orderObj.status == '1': logger.info("订单{}已处理".format(orderObj.orderid)) raise PubErrorCustom("订单{}已处理".format(orderObj.orderid)) except Order.DoesNotExist: raise PubErrorCustom("订单不存在!") orderObj.status = '1' user = Users.objects.select_for_update().get(userid=orderObj.userid) if user.isvip == '1': user.exprise = viphandler(user.exprise, orderObj.unit, orderObj.term) orderObj.exprise = user.exprise else: user.isvip = '1' user.term = orderObj.term user.unit = orderObj.unit user.exprise = orderObj.exprise orderObj.save() user.save() def callback(self, data): iData = dict() for item in data: iData[item] = data[item] sign = iData.pop("sign", None) if not self.alipay.verify(iData, sign): print(iData) raise PubErrorCustom("验签失败!") if iData.get("trade_status", None) != 'TRADE_SUCCESS': print(iData) raise PubErrorCustom("交易状态异常!") try: orderObj = Order.objects.select_for_update().get( orderid=iData.get("out_trade_no", "")) if orderObj.status == '1': logger.info("订单{}已处理".format(orderObj.orderid)) raise PubErrorCustom("订单{}已处理".format(orderObj.orderid)) except Order.DoesNotExist: raise PubErrorCustom("订单不存在!") orderObj.status = '1' orderObj.trade_no = iData['trade_no'] orderObj.trade_info = json.dumps(iData, ensure_ascii=False) orderObj.save() user = Users.objects.select_for_update().get(userid=orderObj.userid) logger.info("用户{}积分余额{}使用积分{}获得积分{}".format(user.mobile, user.jf, orderObj.use_jf, orderObj.get_jf)) user.jf -= orderObj.use_jf user.jf += orderObj.get_jf user.save() logger.info("支付宝回调订单处理成功!=>{}".format(iData))
def delete(self, request, order_id): result = ResultResponse(code.ARIES_200_SUCCESS, 'success') request_data = request.data logger_info.info(request_data) # Request data parsing try: open_id = request.META['HTTP_OPEN_ID'] payment = Payment.objects.get(open_id=open_id, order_id=order_id) except Exception as e: logger_error.info(str(e)) result = ResultResponse(code.ARIES_400_BAD_REQUEST, 'Request data invalid') return Response(result.get_response(), result.get_code()) payment_type = payment.payment_type # Refund business logic if payment_type == 0 or payment_type == 2: alipay_transaction = AlipayPaymentTransaction.objects.get( out_trade_no=order_id) # Check debug state value if settings.STAGE or settings.DEBUG: debug = True else: debug = False alipay = AliPay( appid=resources.get_alipay_app_id(), app_notify_url=resources.get_alipay_notify_url(), app_private_key_path=resources.get_viastelle_pri_key(), alipay_public_key_path=resources.get_viastelle_pub_key(), sign_type='RSA2', debug=debug) refund_result = alipay.api_alipay_trade_refund( out_trade_no=alipay_transaction.out_trade_no, trade_no=alipay_transaction.trade_no, refund_amount=alipay_transaction.total_amount, refund_reason='Customer asked') if refund_result['code'] == '10000': refund_status = 0 payment_status = 5 else: refund_status = 1 payment_status = 6 try: logger_info.info(refund_result) refund_result['order_id'] = order_id refund_result['status'] = refund_status refund_result['alipay_refund_validation'] = True serializer = AlipayRefundSerializer(data=refund_result) if serializer.is_valid(): serializer.save() else: logger_info.info(serializer.errors) payment.payment_status = payment_status payment.save() except Exception as e: logger_info.error(str(e)) result = ResultResponse( code.ARIES_500_INTERNAL_SERVER_ERROR, get_msg(code.ERROR_4002_PAYMENT_IS_NOT_FOUND)) result.set_error(code.ERROR_4002_PAYMENT_IS_NOT_FOUND) return Response(result.get_response(), result.get_code()) elif payment_type == 1 or payment_type == 3: if payment_type == 1: wechat_app_id = 'viastelle' merchant_id = 'viastelle' else: wechat_app_id = 'viastelle' merchant_id = 'viastelle' transaction = WechatQueryTransaction.objects.get(order_id=order_id) total_fee = transaction.total_fee refund_data = { 'appid': wechat_app_id, 'mch_id': merchant_id, 'nonce_str': payment_util.wechat_payment_str(transaction.order_id), 'transaction_id': transaction.transaction_id, 'out_trade_no': order_id, 'out_refund_no': transaction.transaction_id, 'total_fee': total_fee, 'refund_fee': total_fee } if payment_type == 1: refund_data_xml = payment_util.get_payment_wechat_dict_to_xml( refund_data) else: refund_data_xml = payment_util.get_payment_wechat_public_dict_to_xml( refund_data) logger_info.info(refund_data_xml) # refund_data_signed = utils.calculate_signature(prepaid_object, api_key) # prepaid_data = utils.dict_to_xml(prepaid_object, prepaid_signature) api_cert_dir = '/home/nexttf/workspace/project_aries/config/keys' if payment_type == 1: api_cert = 'app_pay_apiclient_cert.pem' api_key = 'app_pay_apiclient_key.pem' else: api_cert = 'public_pay_apiclient_cert.pem' api_key = 'public_pay_apiclient_key.pem' api_cert_file = os.path.join(api_cert_dir, api_cert) api_key_file = os.path.join(api_cert_dir, api_key) """ verify=True, cert=(self.cert_file, self.key_file)) """ headers = {'Content-Type': 'application/xml'} response = requests.post(url=get_wechat_refund_url(), headers=headers, data=refund_data_xml, verify=True, cert=(api_cert_file, api_key_file)) logger_info.info(response.text) try: refund_result = xmltodict.parse(response.text)['xml'] logger_info.info(refund_result) if refund_result['return_code'] == 'SUCCESS': refund_status = 0 payment_status = 5 else: refund_status = 1 payment_status = 6 validation = payment_util.get_payment_wechat_sign_validation( refund_result) refund_result['status'] = refund_status refund_result['order_id'] = order_id refund_result['wechat_refund_validation'] = validation serializer = WechatRefundSerializer(data=refund_result) if serializer.is_valid(): serializer.save() else: logger_info.info(serializer.errors) payment.payment_status = payment_status payment.save() if refund_status == 1: logger_error.error(code.ERROR_4003_PAYMENT_REFUND_FAIL) result = ResultResponse( code.ARIES_500_INTERNAL_SERVER_ERROR, get_msg(code.ERROR_4003_PAYMENT_REFUND_FAIL)) result.set_error(code.ERROR_4003_PAYMENT_REFUND_FAIL) return Response(result.get_response(), result.get_code()) except Exception as e: logger_error.error(str(e)) result = ResultResponse( code.ARIES_500_INTERNAL_SERVER_ERROR, get_msg(code.ERROR_4002_PAYMENT_IS_NOT_FOUND)) result.set_error(code.ERROR_4002_PAYMENT_IS_NOT_FOUND) return Response(result.get_response(), result.get_code()) return Response(result.get_response(), result.get_code())
class PayGateWay(AbstractPayFactory): config = { "__sandbox": False, "__app_id": "支付宝开发者应用ID", "__private_key": "商户私钥", "__public_key": "支付宝公钥", "#说明": "去掉 __ 启用对应的选项,#号为备注字典" } alipay = None def __init__(self, data: dict): super(PayGateWay, self).__init__(data) if self.config['sandbox']: self.url = "https://openapi.alipaydev.com/gateway.do?" else: self.url = "https://openapi.alipay.com/gateway.do?" self.alipay = AliPay( appid=self.config["app_id"], app_notify_url=None, # 默认回调url app_private_key_string=self.config["private_key"], # 支付宝的公钥,验证支付宝回传消息使用,不是你自己的公钥, alipay_public_key_string=self.config["public_key"], sign_type="RSA2", # RSA 或者 RSA2 debug=False, # 默认False ) def create_order(self, data: BaseTransactionSlip, *args, **kwargs) -> BaseCreateOrderResult: if not isinstance(data, BaseTransactionSlip): raise RuntimeError("请传入一个 BaseTransactionSlip 实例") params = { "out_trade_no": data.sid, "subject": data.name, "total_amount": data.price, "return_url": data.sync_url } if data.async_url: params['notify_url'] = data.async_url if data.device_type == data.COMPUTER_DEVICE: order_string = self.alipay.api_alipay_trade_page_pay(**params) else: order_string = self.alipay.api_alipay_trade_wap_pay(**params) return BaseCreateOrderResult(self.url + order_string) def notify_order(self, request, *args, **kwargs) -> BaseTransactionResult: data = request.data print("=========收到异步通知数据=========") print(json.dumps(data)) if not isinstance(data, dict): data = dict(request.data.dict()) data = self.__deal_dict(data) print(json.dumps(data)) print("=========收到异步通知数据=========") signature = data.pop("sign") success = self.alipay.verify(data, signature) sid = data["out_trade_no"] pid = data["trade_no"] status = BaseTransactionResult.SIGN_VERIFICATION_FAILED if success and data["trade_status"] in ("TRADE_SUCCESS", "TRADE_FINISHED"): status = BaseTransactionResult.SUCCESSFULLY_VERIFIED result = BaseTransactionResult(sid, pid, status) return result def return_order(self, data: dict, *args, **kwargs) -> BaseTransactionResult: print("=========收到同步通知数据=========") print(json.dumps(data)) data = self.__deal_dict(data) print(json.dumps(data)) print("=========收到同步通知数据=========") # verification signature = data.pop("sign") success = self.alipay.verify(data, signature) sid = data["out_trade_no"] pid = data["trade_no"] status = BaseTransactionResult.SIGN_VERIFICATION_FAILED if success: status = BaseTransactionResult.UNKNOWN_PAYMENT_STATUS result = BaseTransactionResult(sid, pid, status) return result def query_order(self, data: BaseOrderId) -> dict: res = self.alipay.api_alipay_trade_query(out_trade_no=data.sid) return res def cancel_order(self, data: BaseOrderId) -> BaseCancelOrder: res = self.alipay.api_alipay_trade_close(out_trade_no=data.sid) res_status = False if '10000' in res and 'Success' in res: res_status = True return BaseCancelOrder(res_status, res) def request_refund(self, data: BaseRequestRefund) -> bool: result = self.alipay.api_alipay_trade_refund( out_trade_no=data.sid, refund_amount=f"{data.price}") if result["code"] == "10000": return True else: return False @staticmethod def __deal_dict(data: dict): _data = {} for i in data: if isinstance(data[i], list): _data[i] = data[i][0] else: _data[i] = data[i] return _data @staticmethod def gateway_config() -> dict: return PayGateWay.config @staticmethod def success_http() -> HttpResponse: return HttpResponse('success') @staticmethod def failed_http() -> HttpResponse: return HttpResponse('验签出错') @staticmethod def gateway_name(): return "AliPay" @staticmethod def gateway_description(): return "支持手机、PC支付,该接口仅限于中国大陆用户"
class Alipay(): def __init__(self): if alipay_debug is True: self._appid = alipay_div_id self._gateway = alipay_dev_url else: self._appid = alipay_id self._gateway = alipay_url self._alipay = AliPay( appid=self._appid, app_notify_url=None, # 默认回调url app_private_key_path=app_private_key_path, alipay_public_key_path=app_public_key_path, sign_type="RSA2", # RSA 或者 RSA2 debug=alipay_debug # 默认False ) def getpaycheckurl(self, sessionkey, out_trade_no, subject, total_amount, retcontent): returnurl = '%s/%s' % (app_return_url, sessionkey) notify_url = '%s/%s' % (app_notify_url, retcontent) order_string = self._alipay.api_alipay_trade_page_pay( out_trade_no=out_trade_no, total_amount=total_amount, subject=subject, return_url=returnurl, notify_url=notify_url # 可选, 不填则使用默认notify url ) alipay_request = '%s?%s' % (self._gateway, order_string) return alipay_request def getpaydeepurl(self, out_trade_no, subject, total_amount, userid, code): bodyhash = crypto_helper.get_key(str(total_amount), userid, str(code), out_trade_no) returnurl = '%s%s/%s/%s/%s' % (app_return_url, 'deep', userid, code, bodyhash) notify_url = '%s%s/%s/%s/%s' % (app_notify_url, 'deep', userid, code, bodyhash) order_string = self._alipay.api_alipay_trade_page_pay( out_trade_no=out_trade_no, total_amount=total_amount, subject=subject, return_url=returnurl, notify_url=notify_url # 可选, 不填则使用默认notify url ) alipay_request = '%s?%s' % (self._gateway, order_string) return alipay_request def verifyurl(self, data): signature = data.pop("sign") success = self._alipay.verify(data, signature) return success def query(self, out_trade_no): result = self._alipay.api_alipay_trade_query(out_trade_no=out_trade_no) if result.get("trade_status", "") == "TRADE_SUCCESS": return True return False def refund(self, refund_amount, out_trade_no): result = self._alipay.api_alipay_trade_refund( refund_amount=refund_amount, out_trade_no=out_trade_no, trade_no=None, out_request_no=out_trade_no) if result["code"] == "10000": return True return False def refundquery(self, out_trade_no): result = self._alipay.api_alipay_trade_fastpay_refund_query( out_request_no=out_trade_no, out_trade_no=out_trade_no) if result["code"] == "10000" and 'refund_amount' in result: return True return False def refundallquery(self, out_trade_no): result = self._alipay.api_alipay_trade_fastpay_refund_query( out_request_no=out_trade_no, out_trade_no=out_trade_no) if result["code"] == "10000" and 'refund_amount' in result and result[ "refund_amount"] == result["total_amount"]: return True return False def tradecancel(self, out_trade_no): result = self._alipay.api_alipay_trade_cancel( out_trade_no=out_trade_no) if result["code"] == "10000": return True return False