diff --git a/templates/zilencer/billing.html b/templates/zilencer/billing.html
index 8c69cbd3e9..2596b7ff10 100644
--- a/templates/zilencer/billing.html
+++ b/templates/zilencer/billing.html
@@ -12,23 +12,27 @@
 
     
         
{{ _("Billing") }}
-        Plan
-        {{ plan_name }}
-        
-        You are paying for {{ seat_count }} users.
-        Your plan will renew on {{ renewal_date }} for ${{ renewal_amount }}.
-        {% if prorated_charges %}
-        You have ${{ prorated_charges }} in prorated charges that will be
-        added to your next bill.
-        {% elif prorated_credits %}
-        You have ${{ prorated_credits }} in prorated credits that will be
-        automatically applied to your next bill.
+        {% if admin_access %}
+            Plan
+            {{ plan_name }}
+            
+            You are paying for {{ seat_count }} users.
+            Your plan will renew on {{ renewal_date }} for ${{ renewal_amount }}.
+            {% if prorated_charges %}
+            You have ${{ prorated_charges }} in prorated charges that will be
+            added to your next bill.
+            {% elif prorated_credits %}
+            You have ${{ prorated_credits }} in prorated credits that will be
+            automatically applied to your next bill.
+            {% endif %}
+            
+            
+            Payment method: {{ payment_method }}.
+            
+            Contact support@zulipchat.com for billing history or to make changes to your subscription.
+        {% else %}
+            You must be an organization administrator or a billing administrator to view this page.
         {% endif %}
-        
-        
-        Payment method: {{ payment_method }}.
-        
-        Contact support@zulipchat.com for billing history or to make changes to your subscription.
     
 
 {% endblock %}
diff --git a/zilencer/tests/test_stripe.py b/zilencer/tests/test_stripe.py
index d3b896fbac..f2d35ff554 100644
--- a/zilencer/tests/test_stripe.py
+++ b/zilencer/tests/test_stripe.py
@@ -129,6 +129,37 @@ class StripeTest(ZulipTestCase):
         self.assertEqual(response.status_code, 302)
         self.assertEqual('/billing/', response.url)
 
+    @mock.patch("zilencer.lib.stripe.STRIPE_PUBLISHABLE_KEY", "stripe_publishable_key")
+    @mock.patch("zilencer.views.STRIPE_PUBLISHABLE_KEY", "stripe_publishable_key")
+    @mock.patch("stripe.Invoice.upcoming", side_effect=mock_upcoming_invoice)
+    @mock.patch("stripe.Customer.retrieve", side_effect=mock_retrieve_customer)
+    @mock.patch("stripe.Customer.create", side_effect=mock_create_customer)
+    @mock.patch("stripe.Subscription.create", side_effect=mock_create_subscription)
+    def test_billing_page_permissions(self, mock_create_subscription: mock.Mock,
+                                      mock_create_customer: mock.Mock,
+                                      mock_retrieve_customer: mock.Mock,
+                                      mock_upcoming_invoice: mock.Mock) -> None:
+        # Check that non-admins can access /upgrade via /billing, when there is no Customer object
+        self.login(self.example_email('hamlet'))
+        response = self.client_get("/billing/")
+        self.assertEqual(response.status_code, 302)
+        self.assertEqual('/upgrade/', response.url)
+        # Check that non-admins can sign up and pay
+        self.client_post("/upgrade/", {'stripeToken': self.token,
+                                       'seat_count': self.quantity,
+                                       'plan': Plan.CLOUD_ANNUAL})
+        # Check that the non-admin hamlet can still access /billing
+        response = self.client_get("/billing/")
+        self.assert_in_success_response(["Contact support@zulipchat.com for billing"], response)
+        # Check admins can access billing, even though they are not the billing_user
+        self.login(self.example_email('iago'))
+        response = self.client_get("/billing/")
+        self.assert_in_success_response(["Contact support@zulipchat.com for billing"], response)
+        # Check that non-admin, non-billing_user does not have access
+        self.login(self.example_email("cordelia"))
+        response = self.client_get("/billing/")
+        self.assert_in_success_response(["You must be an organization administrator"], response)
+
     @mock.patch("zilencer.lib.stripe.STRIPE_PUBLISHABLE_KEY", "stripe_publishable_key")
     @mock.patch("zilencer.views.STRIPE_PUBLISHABLE_KEY", "stripe_publishable_key")
     @mock.patch("stripe.Customer.create", side_effect=mock_create_customer)
diff --git a/zilencer/views.py b/zilencer/views.py
index fe0cf97039..49c1d52962 100644
--- a/zilencer/views.py
+++ b/zilencer/views.py
@@ -199,10 +199,10 @@ def billing_home(request: HttpRequest) -> HttpResponse:
     if customer is None:
         return HttpResponseRedirect(reverse('zilencer.views.initial_upgrade'))
 
-    # TODO
-    # if not user.is_realm_admin and not user == customer.billing_user:
-        # context['error_message'] = _("You must be an administrator to view this page.")
-        # return render(request, 'zilencer/billing.html', context=context)
+    if not user.is_realm_admin and not user == customer.billing_user:
+        context = {'admin_access': False}  # type: Dict[str, Any]
+        return render(request, 'zilencer/billing.html', context=context)
+    context = {'admin_access': True}
 
     stripe_customer = get_stripe_customer(customer.stripe_customer_id)
 
@@ -230,7 +230,7 @@ def billing_home(request: HttpRequest) -> HttpResponse:
     if source is not None:
         payment_method = "Card ending in %(last4)s" % {'last4': source.last4}
 
-    context = {
+    context.update({
         'plan_name': plan_name,
         'seat_count': seat_count,
         'renewal_date': renewal_date,
@@ -238,6 +238,6 @@ def billing_home(request: HttpRequest) -> HttpResponse:
         'payment_method': payment_method,
         'prorated_charges': '{:,.2f}'.format(prorated_charges),
         'prorated_credits': '{:,.2f}'.format(prorated_credits),
-    }  # type: Dict[str, Any]
+    })
 
     return render(request, 'zilencer/billing.html', context=context)