Commit 6c9ffb86 by Aeolus

nfc卡功能开发

parent 8c4a363c
......@@ -12,16 +12,6 @@ SK_CONFIG = {
"app_secret": os.getenv("SK_MINI_PROGRAM_APPSECRET"),
}
SSW_PAY_CONFIG = {
"mch_id": os.getenv("SSW_MCHID"),
"pay_key": os.getenv("SSW_PAY_KEY"),
"cert_path": os.getenv("SSW_PAY_SSL_CERT_PATH"),
"key_path": os.getenv("SSW_PAY_SSL_KEY_PATH"),
'callback_url': '/rent/wx_pay_callback',
'refund_callback_url': '/rent/refund_callback',
'domain': 'https://sukang.ssw-htzn.com/sukang/'
}
XX_PAY_CONFIG = {
"mch_id": os.getenv("XX_MCHID"),
"pay_key": os.getenv("XX_PAY_KEY"),
......@@ -29,7 +19,7 @@ XX_PAY_CONFIG = {
"key_path": os.getenv("XX_PAY_SSL_KEY_PATH"),
'callback_url': '/rent/wx_pay_callback',
'refund_callback_url': '/rent/refund_callback',
'domain': 'https://sukang.ssw-htzn.com/sukang'
'domain': 'https://autemat.ssw-htzn.com/sukang'
}
pay_config_list = ["", "xx"]
......@@ -53,3 +43,5 @@ platform_appid_config_dict = {
"sukang24h": SK_CONFIG["app_id"],
}
NFC_PAY_CALLBCK_URL = "'/nfc_card/wx_pay_callback'"
......@@ -64,7 +64,7 @@ class Machine(Base):
short_address = Column(VARCHAR(45))
address = Column(String(191, 'utf8mb4_unicode_ci'), comment='机柜位置')
place_id = Column(INTEGER(10), nullable=False)
mch_platform = Column(INTEGER(11), nullable=False, server_default=text("'1'"), comment='1随身玩 2晓见文旅')
mch_platform = Column(INTEGER(11), nullable=False, server_default=text("'1'"), comment='1咻咻')
position = Column(String(20, 'utf8mb4_unicode_ci'), comment='机柜位置坐标')
hatch_number = Column(TINYINT(3), nullable=False, server_default=text("'0'"), comment='机柜的仓口数量')
type = Column(TINYINT(3), nullable=False, server_default=text("'1'"), comment='机柜类型1正常')
......@@ -85,6 +85,39 @@ class MachineProduction(Base):
updated_at = Column(TIMESTAMP, server_default=text("CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP"))
class NfcCard(Base):
__tablename__ = 'nfc_card'
__table_args__ = {'comment': 'nfc卡片表'}
id = Column(INTEGER(10), primary_key=True)
card_no = Column(String(40, 'utf8mb4_unicode_ci'), comment='卡片编号')
user_name = Column(String(40, 'utf8mb4_unicode_ci'), comment='学生名称')
phone = Column(String(40, 'utf8mb4_unicode_ci'), index=True, comment='手机号')
language = Column(String(40, 'utf8mb4_unicode_ci'), comment='语种')
nick_name = Column(String(40, 'utf8mb4_unicode_ci'), comment='昵称')
money = Column(INTEGER(10), nullable=False)
mch_platform = Column(INTEGER(11), nullable=False, server_default=text("'1'"), comment='1咻咻')
status = Column(TINYINT(4), nullable=False, comment='状态0停用1正常')
created_at = Column(TIMESTAMP, server_default=text("CURRENT_TIMESTAMP"))
updated_at = Column(TIMESTAMP, server_default=text("CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP"))
class NfcCardPayRecord(Base):
__tablename__ = 'nfc_card_pay_record'
__table_args__ = {'comment': 'nfc卡片充值表'}
id = Column(INTEGER(10), primary_key=True)
card_no = Column(String(40, 'utf8mb4_unicode_ci'), index=True, comment='卡片编号')
rent_no = Column(VARCHAR(40), nullable=False, comment='租借单号')
is_pay = Column(TINYINT(3), nullable=False, server_default=text("'0'"), comment='是否支付')
pay_money = Column(INTEGER(10), nullable=False, comment='充值金额')
prepay_id = Column(VARCHAR(191), comment='微信支付prepay_id')
refund_no = Column(VARCHAR(191), comment='退款单号')
status = Column(TINYINT(4), nullable=False, comment='状态-1停用1正常')
created_at = Column(TIMESTAMP, server_default=text("CURRENT_TIMESTAMP"))
updated_at = Column(TIMESTAMP, server_default=text("CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP"))
class Place(Base):
__tablename__ = 'place'
......
#!usr/bin/env python
# -*- coding:utf-8 _*-
"""
@version:
author:Aeolus
@file: nfc_card_portal.py
"""
import json
import logging
import re
import time
from flask import Blueprint, request, jsonify, g
from config.commen_config import USER_RENT_PREPAY_ID
from config.wechat_config import platform_appid_config_list, pay_config_list
from models.base_model import db
from models.models import NfcCard, NfcCardPayRecord
from service.rent_service import RentService
from service.wechat_service import WeChatPayService
from utils.error_code import NFC_CARD_NOT_EXIST, NFC_CARD_ACTIVATED_ERROR, WE_MINIAPP_PAY_FAIL
from utils.my_redis_cache import redis_client
from utils.my_response import BaseResponse
logger = logging.getLogger(__name__)
nfc_card_route = Blueprint('nfc_card', __name__)
@nfc_card_route.route("activate")
def run_nfc_card_activate():
json_data = request.get_json()
card_no = json_data["card_no"]
user_name = json_data["user_name"]
phone = json_data.get("phone", None)
card = NfcCard.query.filter_by(card_no=card_no).first()
if not card:
return jsonify(NFC_CARD_NOT_EXIST)
if card.status != 0:
return jsonify(NFC_CARD_ACTIVATED_ERROR)
card.status = 1
db.session.add(card)
db.session.commit()
return BaseResponse()
@nfc_card_route.route("pay")
def run_nfc_card_activate():
json_data = request.get_json()
card_no = json_data["card_no"]
money = json_data["money"]
user = g.user
# 验证机柜是否存在
card = NfcCard.query.filter_by(card_no=card_no, status=1).first()
if not card:
return jsonify(NFC_CARD_NOT_EXIST)
# 生成订单编号
rent_no = RentService.create_order_no()
# 配置微信订单数据
wechat_service = WeChatPayService(app_id=platform_appid_config_list[user.platform],
config_name=pay_config_list[card.mch_platform])
pay_data = {
'body': '灰兔智能租借押金', # 商品描述
'out_trade_no': rent_no, # 商户订单号
'total_fee': money, # 总价
'trade_type': "JSAPI",
'openid': user.openid,
'timeStamp': str(int(time.time())),
'attach': {
"card_no": card_no,
"user_id": user.id,
"platform": card.mch_platform,
}
}
# 微信下单接口
pay_info = wechat_service.unifiedorder(pay_data, callback_url=)
if not pay_info:
return BaseResponse(**WE_MINIAPP_PAY_FAIL)
# 微信下单成功,redis存prepay_id 5分钟失效
redis_client.set(USER_RENT_PREPAY_ID + str(user.id) + rent_no, pay_info["prepay_id"], 300)
return BaseResponse(data=pay_info)
@nfc_card_route.route('/wx_pay_callback', methods=['GET', 'POST'])
def run_nfc_card_wx_pay_callback():
"""
支付回调接口
:return:
"""
response_data = {
'return_code': 'SUCCESS',
'return_msg': 'SUCCESS'
}
error_data = {
'return_code': 'FAIL',
'return_msg': 'FAIL'
}
header = {'Content-Type': 'application/xml'}
# 进行签名认证
xml_data = request.data
import xmltodict
callback_data = dict(xmltodict.parse(xml_data)['xml'])
attach = re.sub('\'', '\"', callback_data["attach"])
rent_data = json.loads(attach)
platform = rent_data["platform"]
card_no = rent_data["card_no"]
user_id = rent_data["user_id"]
platform = pay_config_list[platform]
wechat_service = WeChatPayService(app_id=callback_data["appid"], config_name=platform)
verify_result = wechat_service.verify_pay_callbak_sign(callback_data)
if not verify_result:
return xmltodict.unparse({'xml': response_data}, pretty=True), header
# 判断订单是否已经存在过
rent_no = callback_data['out_trade_no']
rent = NfcCardPayRecord.query.filter_by(rent_no=rent_no).first()
if rent:
return xmltodict.unparse({'xml': response_data}, pretty=True), header
try:
rent = NfcCardPayRecord()
rent.rent_no = rent_no
rent.card_no = card_no
rent.user_id = user_id
rent.pay_money = int(callback_data["total_fee"])
rent.is_pay = 1
rent.mch_platform = platform
prepay_id = redis_client.get(USER_RENT_PREPAY_ID + str(user_id) + rent_no)
if prepay_id:
rent.prepay_id = prepay_id
db.session.add(rent)
db.session.commit()
except Exception as e:
return xmltodict.unparse({'xml': error_data}, pretty=True), header
return xmltodict.unparse({'xml': response_data}, pretty=True), header
......@@ -26,14 +26,18 @@ class WeChatPayService(WeChatPay):
key_path = self.config["key_path"]
super(WeChatPayService, self).__init__(app_id, pay_key, mch_id, mch_cert=cert_path, mch_key=key_path)
def unifiedorder(self, pay_data):
def unifiedorder(self, pay_data, callback_url=None):
"""
:param pay_data:
:param callback_url:
:return:
"""
if callback_url:
notify_url = self.config["domain"] + callback_url
else:
notify_url = self.config["domain"] + self.config["callback_url"]
logger.debug(notify_url)
pay_data["nonce_str"] = self.get_nonce_str()
result = self.order.create(notify_url=notify_url, **pay_data)
prepay_id = result.get('prepay_id')
......@@ -58,7 +62,8 @@ class WeChatPayService(WeChatPay):
def do_refund(self, refund_data):
"""
:param refund_data:
:param
refund_data:
:return:
"""
for i in range(3):
......@@ -100,7 +105,8 @@ class WeChatPayService(WeChatPay):
def verify_pay_callbak_sign(self, callback_data):
"""
验证签名方法
:param callback_data: 微信回调的xml解析后的数据
:param
callback_data: 微信回调的xml解析后的数据
:return:
"""
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment