Created stripe webhook
parent
557bda246d
commit
7e72507d6b
|
@ -2,6 +2,7 @@ import os
|
|||
|
||||
from flask import Flask
|
||||
|
||||
from public_api.endpoints.stripe_webhook import StripeWebHookEndpoint
|
||||
from selene.api import SeleneResponse, selene_api
|
||||
from selene.api.base_config import get_base_config
|
||||
from selene.api.public_endpoint import check_oauth_token
|
||||
|
@ -146,6 +147,12 @@ public.add_url_rule(
|
|||
methods=['GET']
|
||||
)
|
||||
|
||||
public.add_url_rule(
|
||||
'/v1/user/stripe/webhook',
|
||||
view_func=StripeWebHookEndpoint.as_view('stripe_webhook_api'),
|
||||
methods=['POST']
|
||||
)
|
||||
|
||||
"""
|
||||
This is a workaround to allow the API return 401 when we call a non existent path. Use case:
|
||||
GET /device/{uuid} with empty uuid. Core today uses the 401 to validate if it needs to perform a pairing process
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
import json
|
||||
from http import HTTPStatus
|
||||
|
||||
from selene.api import PublicEndpoint
|
||||
from selene.data.account import AccountRepository
|
||||
|
||||
|
||||
class StripeWebHookEndpoint(PublicEndpoint):
|
||||
|
||||
def __init__(self):
|
||||
super(StripeWebHookEndpoint, self).__init__()
|
||||
|
||||
def post(self):
|
||||
event = json.loads(self.request.data)
|
||||
type = event.get('type')
|
||||
if type == 'customer.subscription.deleted':
|
||||
customer = event['data']['object']['customer']
|
||||
AccountRepository(self.db).end_active_membership(customer)
|
||||
return '', HTTPStatus.OK
|
|
@ -22,7 +22,8 @@ ONE_DAY = 86400
|
|||
|
||||
def check_oauth_token():
|
||||
global_context.url = request.url
|
||||
exclude_paths = ['/v1/device/code', '/v1/device/activate', '/api/account', '/v1/auth/token', '/v1/auth/callback']
|
||||
exclude_paths = ['/v1/device/code', '/v1/device/activate', '/api/account', '/v1/auth/token', '/v1/auth/callback',
|
||||
'/v1/user/stripe/webhook']
|
||||
exclude = any(request.path.startswith(path) for path in exclude_paths)
|
||||
if not exclude:
|
||||
headers = request.headers
|
||||
|
|
|
@ -300,6 +300,17 @@ class AccountRepository(RepositoryBase):
|
|||
)
|
||||
self.cursor.update(db_request)
|
||||
|
||||
def end_active_membership(self, customer_id):
|
||||
db_request = self._build_db_request(
|
||||
sql_file_name='get_active_membership_by_payment_account_id.sql',
|
||||
args=dict(payment_account_id=customer_id)
|
||||
)
|
||||
db_result = self.cursor.select_one(db_request)
|
||||
if db_result is not None:
|
||||
account_membership = AccountMembership(**db_result)
|
||||
account_membership.end_date = datetime.utcnow()
|
||||
self.end_membership(account_membership)
|
||||
|
||||
def get_active_account_membership(self, account_id) -> AccountMembership:
|
||||
account_membership = None
|
||||
db_request = self._build_db_request(
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
SELECT
|
||||
acc_mem.id,
|
||||
mem.type,
|
||||
LOWER(acc_mem.membership_ts_range)::date start_date,
|
||||
acc_mem.payment_method,
|
||||
payment_account_id,
|
||||
payment_id
|
||||
FROM
|
||||
account.account_membership acc_mem
|
||||
INNER JOIN
|
||||
account.membership mem ON acc_mem.membership_id = mem.id
|
||||
WHERE
|
||||
acc_mem.payment_account_id = %(payment_account_id)s AND UPPER(acc_mem.membership_ts_range) IS NULL
|
Loading…
Reference in New Issue