From 5b7e7a4606fe7406cafcae965094f1e9cae1c66e Mon Sep 17 00:00:00 2001 From: PCoder Date: Fri, 13 Sep 2019 23:38:48 +0530 Subject: [PATCH] Add UserRegisterPayment + check_otp --- ucloud-pay.py | 106 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 101 insertions(+), 5 deletions(-) diff --git a/ucloud-pay.py b/ucloud-pay.py index 601a8ee..da6896d 100644 --- a/ucloud-pay.py +++ b/ucloud-pay.py @@ -1,12 +1,42 @@ +import binascii import json + +import requests +from decouple import config from flask import Flask, request from flask_restful import Resource, Api +from pyotp import TOTP + from config import etcd_client as client, logging, APP_PORT +from stripe_utils import StripeUtils app = Flask(__name__) api = Api(app) +def check_otp(name, realm, token): + try: + data = { + "auth_name": config("AUTH_NAME", ""), + "auth_token": TOTP(config("AUTH_SEED", "")).now(), + "auth_realm": config("AUTH_REALM", ""), + "name": name, + "realm": realm, + "token": token, + } + except binascii.Error: + return 400 + + response = requests.post( + "{OTP_SERVER}{OTP_VERIFY_ENDPOINT}".format( + OTP_SERVER=config("OTP_SERVER", ""), + OTP_VERIFY_ENDPOINT=config("OTP_VERIFY_ENDPOINT", "verify/"), + ), + data=data, + ) + return response.status_code + + class ListProducts(Resource): @staticmethod def get(): @@ -14,14 +44,15 @@ class ListProducts(Resource): prod_dict = {} for p in products: prod_dict[p.key] = json.loads(p.value) - logging.debug(f"Products = {prod_dict}") + logging.debug("Products = {}".format(prod_dict)) return prod_dict, 200 + class AddProduct(Resource): @staticmethod def post(): data = request.json - logging.debug(f"Got data: {str(data)}") + logging.debug("Got data: {}".format(str(data))) # TODO: Add validation product_key = "/v1/products/" @@ -31,11 +62,76 @@ class AddProduct(Resource): "type": data["product_type"], "price": data["product_price"], "recurring_duration": data["product_recurring_duration"], - "recurring_duration_units": data["product_recurring_duration_units"] + "recurring_duration_units": + data["product_recurring_duration_units"] } - logging.debug(f"Adding product data: {str(product_value)}") + logging.debug("Adding product data: {}".format(str(product_value))) client.put(product_key, product_value, value_in_json=True) - return {"message": f"Product {data['product_name']} created"}, 200 + return {"message": + "Product {} created".format(data['product_name'])}, 200 + + +class UserRegisterPayment(Resource): + @staticmethod + def post(): + try: + data = request.json + logging.debug("Got data: {}".format(str(data))) + otp_response = check_otp(data["name"], data["realm"], + data["token"]) + if otp_response != 200: + return {"message": "Wrong Credentials"}, 403 + + stripe_utils = StripeUtils() + stripe_customer = stripe_utils.get_stripe_customer_from_email( + data["email"]) + if stripe_customer is None: + token_response = stripe_utils.get_token_from_card( + data["number"], data["cvc"], data["expiry_month"], + data["expiry_year"] + ) + if token_response["response"]: + stripe_customer_resp = stripe_utils.create_customer( + token_response["response"].id + ) + if stripe_customer_resp: + stripe_customer = stripe_customer_resp["response"] + else: + logging.error("Could not get/create stripe_customer " + "for {}".format(data["email"])) + return {"message": + "Error with card. Contact support"}, 400 + else: + logging.error("Could not get token for the card") + return {"message": "Error with card. Contact support"}, 400 + + user_key = "/v1/users/{}/stripe_customer/".format(data["email"]) + user_value = stripe_customer.id + client.put(user_key, user_value, value_in_json=False) + + user_key = "/v1/users/{}/cards/".format(data["email"]) + user_value = [token_response["response"].card.id] + client.put(user_key, user_value, value_in_json=False) + resp = stripe_utils.associate_customer_card(stripe_customer.id, + token_response["response"].id) + if resp["response"]: + return {"message": + "Card ending in {} registered as your payment " + "soruce".format(data['card'].strip()[-4:]) + }, 200 + else: + logging.error( + "Unable to associate card " + "{} with customer {}".format( + token_response["response"].card.id, data["email"] + ) + ) + return {"message": "Error with card. Contact support"}, 400 + + except KeyError as key_error: + logging.error(str(key_error)) + return {"message": "Missing parameters"}, 400 + api.add_resource(ListProducts, "/product/list") api.add_resource(AddProduct, "/product/add")