def advantage_shop_view(): account = previous_purchase_id = None is_test_backend = flask.request.args.get("test_backend", False) stripe_publishable_key = os.getenv("STRIPE_LIVE_PUBLISHABLE_KEY", "pk_live_68aXqowUeX574aGsVck8eiIE") api_url = flask.current_app.config["CONTRACTS_LIVE_API_URL"] if is_test_backend: stripe_publishable_key = os.getenv( "STRIPE_TEST_PUBLISHABLE_KEY", "pk_test_yndN9H0GcJffPe0W58Nm64cM00riYG4N46", ) api_url = flask.current_app.config["CONTRACTS_TEST_API_URL"] if user_info(flask.session): advantage = AdvantageContracts( session, flask.session["authentication_token"], api_url=api_url, ) if flask.session.get("guest_authentication_token"): flask.session.pop("guest_authentication_token") try: account = advantage.get_purchase_account() except HTTPError as err: code = err.response.status_code if code == 401: # We got an unauthorized request, so we likely # need to re-login to refresh the macaroon flask.current_app.extensions["sentry"].captureException( extra={ "session_keys": flask.session.keys(), "request_url": err.request.url, "request_headers": err.request.headers, "response_headers": err.response.headers, "response_body": err.response.json(), "response_code": err.response.json()["code"], "response_message": err.response.json()["message"], }) empty_session(flask.session) return flask.render_template( "advantage/subscribe/index.html", account=None, previous_purchase_id=None, product_listings=[], stripe_publishable_key=stripe_publishable_key, is_test_backend=is_test_backend, ) if code != 404: raise # There is no purchase account yet for this user. # One will need to be created later, but this is an expected # condition. else: advantage = AdvantageContracts(session, None, api_url=api_url) if account is not None: resp = advantage.get_account_subscriptions_for_marketplace( account["id"], "canonical-ua") subs = resp.get("subscriptions") if subs: previous_purchase_id = subs[0].get("lastPurchaseID") listings_response = advantage.get_marketplace_product_listings( "canonical-ua") product_listings = listings_response.get("productListings") if not product_listings: # For the time being, no product listings means the shop has not been # activated, so fallback to shopify. This should become an error later. return flask.redirect("https://buy.ubuntu.com/") products = {pr["id"]: pr for pr in listings_response["products"]} listings = [] for listing in product_listings: if "price" not in listing: continue listing["product"] = products[listing["productID"]] listings.append(listing) return flask.render_template( "advantage/subscribe/index.html", account=account, previous_purchase_id=previous_purchase_id, product_listings=listings, stripe_publishable_key=stripe_publishable_key, is_test_backend=is_test_backend, )
def post_advantage_subscriptions(preview): is_test_backend = flask.request.args.get("test_backend", False) api_url = flask.current_app.config["CONTRACTS_LIVE_API_URL"] if is_test_backend: api_url = flask.current_app.config["CONTRACTS_TEST_API_URL"] user_token = flask.session.get("authentication_token") guest_token = flask.session.get("guest_authentication_token") if user_info(flask.session) or guest_token: advantage = AdvantageContracts( session, user_token or guest_token, token_type=("Macaroon" if user_token else "Bearer"), api_url=api_url, ) else: return flask.jsonify({"error": "authentication required"}), 401 payload = flask.request.json if not payload: return flask.jsonify({}), 400 account_id = payload.get("account_id") previous_purchase_id = payload.get("previous_purchase_id") last_subscription = {} if not guest_token: try: subscriptions = ( advantage.get_account_subscriptions_for_marketplace( account_id=account_id, marketplace="canonical-ua")) except HTTPError: flask.current_app.extensions["sentry"].captureException( extra={"payload": payload}) return ( flask.jsonify( {"error": "could not retrieve account subscriptions"}), 500, ) if subscriptions: last_subscription = subscriptions["subscriptions"][0] # If there is a subscription we get the current metric # value for each product listing so we can generate a # purchase request with updated quantities later. subscribed_quantities = {} if "purchasedProductListings" in last_subscription: for item in last_subscription["purchasedProductListings"]: product_listing_id = item["productListing"]["id"] subscribed_quantities[product_listing_id] = item["value"] purchase_items = [] for product in payload.get("products"): product_listing_id = product["product_listing_id"] metric_value = product["quantity"] + subscribed_quantities.get( product_listing_id, 0) purchase_items.append({ "productListingID": product_listing_id, "metric": "active-machines", "value": metric_value, }) purchase_request = { "accountID": account_id, "purchaseItems": purchase_items, "previousPurchaseID": previous_purchase_id, } try: if not preview: purchase = advantage.purchase_from_marketplace( marketplace="canonical-ua", purchase_request=purchase_request) else: purchase = advantage.preview_purchase_from_marketplace( marketplace="canonical-ua", purchase_request=purchase_request) except HTTPError as http_error: flask.current_app.extensions["sentry"].captureException( extra={ "purchase_request": purchase_request, "api_response": http_error.response.json(), }) return ( flask.jsonify({"error": "could not complete this purchase"}), 500, ) return flask.jsonify(purchase), 200