Beispiel #1
0
def create_new_platform(user_id):
    # 成为平台属主
    user = User.get(user_id=user_id)
    assert user
    account = Account.get(user_id=user.user_id,
                          platform_id=user.bind_platform_id)
    assert account
    platform = Platform.get(owner_user_id=user.user_id)
    if not platform:
        # SELECT `AUTO_INCREMENT` FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'trade' AND table_name = 'platform';
        # ALTER TABLE `platform` AUTO_INCREMENT = 3;
        platform = Platform.create(owner_user_id=user.user_id)
    platform.platform_id = platform.id
    qrcode_info = WeClient.create_qrcode(scene_str=str(platform.platform_id),
                                         is_permanent=True)
    log.d(f'qrcode_info: {qrcode_info}')
    qrcode_content = qrcode_info['url']
    log.i(
        f'create qrcode, platform_id: {platform.platform_id}, qrcode_content: {qrcode_content}'
    )
    platform.update(qrcode_content=qrcode_content,
                    platform_id=platform.id,
                    ssid=f'WIFI-{platform.platform_id}')
    user.update(bind_platform_id=platform.platform_id)
    account.update(role=Account.Role.PLATFORM_OWNER.value,
                   platform_id=user.bind_platform_id)
    return platform
Beispiel #2
0
    def handle_order_unpaid(cls, order):
        # 查询订单API文档: https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_2
        # 关闭订单API文档: https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_3
        # 下载对账单API文档: https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_6
        out_trade_no = order.out_trade_no  # 商户订单号
        attach = order.attach
        total_fee = order.total_fee

        # 1. 查询订单API, 获取查询结果
        ret_json = WePay.query_order(out_trade_no)
        # OrderedDict([
        #  ('return_code', 'SUCCESS'), ('return_msg', 'OK'), ('appid', 'wx54d296959ee50c0b'), ('mch_id', '1517154171'),
        #  ('nonce_str', 'LQ36VyPkbS7tK7Nk'), ('sign', '5182234EB26EBFB718D5FDD1189E6056'), ('result_code', 'SUCCESS'),
        #  ('out_trade_no', '1540519817110XiX6jCKAmXb348V3e'), ('trade_state', 'NOTPAY'),
        #  ('trade_state_desc', '订单未支付')
        # ])
        log.d(f'order query from weixin: {ret_json}')
        #
        if ret_json['return_code'] != 'SUCCESS':
            log.e('order query not success')
            return

        # 2. 检查签名
        if not WePay.is_right_sign(ret_json):
            log.e('sign illegal, sign:{}', ret_json['sign'])
            return

        if ret_json['result_code'] != 'SUCCESS':
            log.e('check signature not success')
            return

        # 3. 交易状态分支处理
        trade_state = ret_json['trade_state']

        if trade_state == 'SUCCESS':

            wx_total_fee = int(ret_json['total_fee'])
            transaction_id = ret_json['transaction_id']

            # 支付成功, 先检查total_fee是否一致, 然后把charge记录状态从0改为1, transaction_id更新为微信返回值
            if wx_total_fee != total_fee:
                log.e(
                    f'total_fee: {wx_total_fee} != order.total_fee:{total_fee}'
                )
                return

            # 增加用户免费资源
            increase_user_resource(total_fee, out_trade_no, transaction_id,
                                   attach)

        elif trade_state in ['NOTPAY', 'CLOSED', 'PAYERROR']:

            # 超时还未支付或订单已经关闭, 需把charge记录状态从0改为-1
            status = Order.Status.EXPIRED.value
            Order.objects.filter(out_trade_no=out_trade_no).update(
                status=status)
            log.i(
                f"UPDATE orders SET status = '{status}' WHERE out_trade_no = '{out_trade_no}'"
            )
Beispiel #3
0
 def release_lock(self):
     if self.is_released:
         return
     self.is_released = True
     key = self.get_key(process_name=self.process_name,
                        worker_id=self.worker_id)
     is_success = self.get_and_delete(keys=[key], args=[self.pod_uid])
     if not is_success:
         if not self.worker_id:
             log.d(
                 f'no need release because not get lock, worker_id: {self.worker_id}'
             )
             return -1
         sentry_sdk.capture_message(f'release lock fail. key: {key}')
     return is_success
Beispiel #4
0
 def doing(cls, start_time, end_time):
     # 明天到期的用户
     log.d(
         f'select expire account where start_time > {start_time} and end_time <= {end_time}'
     )
     #
     accounts = Account.objects.filter(
         expired_at__gt=start_time,
         expired_at__lte=end_time,
     )
     for account in accounts:
         user = User.get(user_id=account.user_id)
         log.i(
             f'send wechat template message, openid: {user.openid}, expired_at: {account.expired_at}'
         )
         WePush.notify_account_expire(openid=user.openid,
                                      username=account.username,
                                      expired_at=account.expired_at)
Beispiel #5
0
 def doing(cls):
     if not cls.start_time:
         cls.start_time = cls.load_start_time()
     cls.end_time = cls.calculate_end_time()
     if cls.end_time < cls.start_time:
         log.w(f'end_time({cls.end_time}) < start_time({cls.start_time})')
         return
     log.d(
         f'select unpaid order where start_time > {cls.start_time} and end_time <= {cls.end_time}'
     )
     #
     orders = Order.objects.filter(created_at__gt=cls.start_time,
                                   created_at__lte=cls.end_time,
                                   status=Order.Status.UNPAID.value)
     for order in orders:
         cls.handle_order_unpaid(order)
     # 保存标签
     cls.start_time = cls.end_time
     cls.save_start_time(start_time=cls.start_time)
Beispiel #6
0
 def post(self, request):
     log.d(f'we_pay notify. data: {request.body}')
     try:
         # request.data: OrderedDict([(u'appid', u'wx7f843ee17bc2a7b7'), (u'attach', u'{"btype": 0}'), (u'bank_type', u'CFT'), (u'cash_fee', 1), (u'fee_type', u'CNY'), (u'is_subscribe', u'Y'), (u'mch_id', u'1480215992'), (u'nonce_str', u'bZhA1HTmIqBFCluKpai32Yj97tvk4DzV'), (u'openid', u'ovj3E0l9vffwBuqz_PNu25yL_is4'), (u'out_trade_no', u'15021710481087kJMqd36CBz9OqFnK'), (u'result_code', u'SUCCESS'), (u'return_code', u'SUCCESS'), (u'time_end', u'20170808134526'), (u'total_fee', 1), (u'trade_type', u'JSAPI'), (u'transaction_id', u'4005762001201708085135613047'), (u'sign', u'F59843FFFAE5E70A9F1B67D755A372E0')])
         # (Pdb) request.body
         # b'<xml><appid><![CDATA[wx54d296959ee50c0b]]></appid>\n<attach><![CDATA[{"tariff_name": "month1"}]]></attach>\n<bank_type><![CDATA[CFT]]></bank_type>\n<cash_fee><![CDATA[1]]></cash_fee>\n<fee_type><![CDATA[CNY]]></fee_type>\n<is_subscribe><![CDATA[Y]]></is_subscribe>\n<mch_id><![CDATA[1517154171]]></mch_id>\n<nonce_str><![CDATA[dJ1t73xXmCrOjn8z5DP6BKyNqgI0cwvS]]></nonce_str>\n<openid><![CDATA[o0FSR0Zh3rotbOog_b2lytxzKrYo]]></openid>\n<out_trade_no><![CDATA[1540483879395x3Oko4Ta9RWamsQCW]]></out_trade_no>\n<result_code><![CDATA[SUCCESS]]></result_code>\n<return_code><![CDATA[SUCCESS]]></return_code>\n<sign><![CDATA[22BE162C29D8558541F04475C379E18B]]></sign>\n<time_end><![CDATA[20181026001122]]></time_end>\n<total_fee>1</total_fee>\n<trade_type><![CDATA[JSAPI]]></trade_type>\n<transaction_id><![CDATA[4200000206201810263667544938]]></transaction_id>\n</xml>'
         data = WePay.parse_payment_result(request.body)
         out_trade_no = data['out_trade_no']
         attach = data['attach']
         return_code = data['return_code']
         assert return_code == 'SUCCESS'
         transaction_id = data['transaction_id']
         total_fee = data['total_fee']
         # 增加用户免费资源
         increase_user_resource(total_fee, out_trade_no, transaction_id,
                                attach)
         return self.SUCCESS_RESPONSE
     except (InvalidSignatureException, Exception) as e:
         log.e(f'we_pay notify error, body: {request.body}')
         sentry_sdk.capture_exception(e)
         return self.SUCCESS_RESPONSE
Beispiel #7
0
 def refresh_lock(self):
     last = 0
     while 1:
         if SigTerm.is_term or self.is_process_exit:
             result = self.release_lock()
             log.d(f'release lock. result: {result}')
             raise SystemExit()
         now = int(time.time())
         if now - last < (self.expire_time / 2):
             continue
         else:
             last = now
         key = self.get_key(process_name=self.process_name,
                            worker_id=self.worker_id)
         is_success = self.get_and_expire(
             keys=[key], args=[self.pod_uid, self.expire_time])
         if not is_success:
             sentry_sdk.capture_message(
                 f'refresh lock fail. key: {key}, pod_uid: {self.pod_uid}')
         log.t(f'success refresh lock. key: {key}')
         time.sleep(1)
Beispiel #8
0
 def start(self):
     # 需支持高可用, 多进程互斥, 只有1个进程在处理
     log.set_header('timer_processor')
     lock = RedisLock(max_worker_id=1,
                      expire_time=30,
                      process_name='timer_processor')
     try:
         lock.start()
         log.d(f'jobs: {MetaClass.jobs}')
         while True:
             # FIXME SigTerm, PidFile
             close_old_connections(
             )  # workaround:   https://zhaojames0707.github.io/post/django_mysql_gone_away/
             for job_class in MetaClass.jobs:
                 job_class.start()
             time.sleep(self.sleep_seconds)
     except Exception as e:
         log.e(traceback.format_exc())
         if not isinstance(e, SystemExit):
             sentry_sdk.capture_exception(e)
     finally:
         lock.stop()