Skip to content

Commit d9ad483

Browse files
committed
Added publishable keys and /config endpoint to get it
1 parent 558b34a commit d9ad483

File tree

3 files changed

+50
-7
lines changed

3 files changed

+50
-7
lines changed

donation-api/src/donation_api/constants.py

+17-5
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,14 @@
77
@dataclass
88
class Constants:
99
stripe_on_prod: bool = bool(os.getenv("STRIPE_USE_LIVE") == "1")
10-
stripe_test_key: str = os.getenv("STRIPE_TEST_KEY") or "notset"
11-
stripe_live_key: str = os.getenv("STRIPE_LIVE_KEY") or "notset"
10+
stripe_test_secret_key: str = os.getenv("STRIPE_TEST_SECRET_KEY") or "notset"
11+
stripe_live_secret_key: str = os.getenv("STRIPE_LIVE_SECRET_KEY") or "notset"
12+
stripe_test_publishable_key: str = (
13+
os.getenv("STRIPE_TEST_PUBLISHABLE_KEY") or "notset"
14+
)
15+
stripe_live_publishable_key: str = (
16+
os.getenv("STRIPE_LIVE_PUBLISHABLE_KEY") or "notset"
17+
)
1218
stripe_webhook_secret: str = os.getenv("STRIPE_WEBHOOK_SECRET") or ""
1319
stripe_webhook_sender_ips: list[str] = field(default_factory=list)
1420
stripe_webhook_testing_ips: list[str] = field(default_factory=list)
@@ -36,10 +42,16 @@ def __post_init__(self):
3642
raise OSError("No Stripe Webhook IPs!")
3743

3844
@property
39-
def stripe_api_key(self) -> str:
45+
def stripe_secret_api_key(self) -> str:
46+
if self.stripe_on_prod:
47+
return self.stripe_live_secret_key
48+
return self.stripe_test_secret_key
49+
50+
@property
51+
def stripe_publishable_api_key(self) -> str:
4052
if self.stripe_on_prod:
41-
return self.stripe_live_key
42-
return self.stripe_test_key
53+
return self.stripe_live_publishable_key
54+
return self.stripe_test_publishable_key
4355

4456

4557
conf = Constants()

donation-api/src/donation_api/stripe.py

+30-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from donation_api.constants import conf
1212

1313
logger = logging.getLogger("uvicorn.error")
14-
stripe.api_key = conf.stripe_api_key
14+
stripe.api_key = conf.stripe_secret_api_key
1515

1616
router = APIRouter(
1717
prefix="/stripe",
@@ -32,6 +32,10 @@ class PaymentIntent(BaseModel):
3232
secret: str
3333

3434

35+
class PublicConfigResponse(BaseModel):
36+
publishable_key: str
37+
38+
3539
class StripeWebhookPayload(BaseModel):
3640
"""Stripe-sent payload during the webhook call
3741
https://stripe.com/docs/webhooks"""
@@ -72,6 +76,20 @@ def can_send_webhook(ip_addr: str) -> bool:
7276
return ip_addr in conf.stripe_webhook_sender_ips
7377

7478

79+
@router.get(
80+
"/config",
81+
status_code=HTTPStatus.OK,
82+
responses={
83+
HTTPStatus.OK: {
84+
"model": PublicConfigResponse,
85+
"description": "Health Check passed",
86+
},
87+
},
88+
)
89+
async def get_config():
90+
return {"publishable_key": conf.stripe_publishable_api_key}
91+
92+
7593
@router.get(
7694
"/health-check",
7795
status_code=HTTPStatus.OK,
@@ -87,12 +105,23 @@ def can_send_webhook(ip_addr: str) -> bool:
87105
)
88106
async def check_config():
89107
errors: list[str] = []
108+
90109
if conf.stripe_on_prod and not str(stripe.api_key).startswith("sk_live_"):
91110
errors.append("Missing Live API Key")
92111

93112
if not conf.stripe_on_prod and not str(stripe.api_key).startswith("sk_test_"):
94113
errors.append("Missing Test API Key")
95114

115+
if conf.stripe_on_prod and not conf.stripe_publishable_api_key.startswith(
116+
"pk_live_"
117+
):
118+
errors.append("Missing Live Publishable API Key")
119+
120+
if not conf.stripe_on_prod and not conf.stripe_publishable_api_key.startswith(
121+
"pk_test_"
122+
):
123+
errors.append("Missing Test Publishable API Key")
124+
96125
if not conf.stripe_webhook_sender_ips:
97126
errors.append("Missing Stripe IPs")
98127

donation-api/tests/test_stripe.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,6 @@ def test_default_to_test():
1212
def test_check_config(client: TestClient):
1313
resp = client.get("/v1/stripe/health-check")
1414
assert resp.status_code == HTTPStatus.INTERNAL_SERVER_ERROR
15-
assert resp.json().get("detail") == "Missing Test API Key"
15+
reason = resp.json().get("detail")
16+
assert "Missing Test API Key" in reason
17+
assert "Missing Test Publishable API Key" in reason

0 commit comments

Comments
 (0)