Validate a discount code (promotion code or coupon ID) before checkout. Returns discount details if valid.
(
*,
request: Request,
org_id: str,
body: ValidateDiscountCodeBody,
orm: Session = Depends(get_orm_session),
)
| 1088 | |
| 1089 | |
| 1090 | async def validate_discount_code( |
| 1091 | *, |
| 1092 | request: Request, |
| 1093 | org_id: str, |
| 1094 | body: ValidateDiscountCodeBody, |
| 1095 | orm: Session = Depends(get_orm_session), |
| 1096 | ) -> ValidateDiscountCodeResponse: |
| 1097 | """ |
| 1098 | Validate a discount code (promotion code or coupon ID) before checkout. |
| 1099 | Returns discount details if valid. |
| 1100 | """ |
| 1101 | stripe.api_key = STRIPE_SECRET_KEY |
| 1102 | |
| 1103 | if not STRIPE_SECRET_KEY: |
| 1104 | raise HTTPException(status_code=500, detail="Stripe secret key not configured.") |
| 1105 | |
| 1106 | # Verify user has permission |
| 1107 | org: Optional[OrgModel] = OrgModel.get_by_id(orm, org_id) |
| 1108 | if not org: |
| 1109 | raise HTTPException(status_code=404, detail="Organization not found") |
| 1110 | |
| 1111 | if not org.is_user_admin_or_owner(request.state.session.user_id): |
| 1112 | raise HTTPException( |
| 1113 | status_code=403, detail="User does not have permission to manage this organization." |
| 1114 | ) |
| 1115 | |
| 1116 | # Try as promotion code first (most common) |
| 1117 | try: |
| 1118 | promotion_codes = stripe.PromotionCode.list(code=body.discount_code, active=True, limit=1) |
| 1119 | if promotion_codes.data: |
| 1120 | promo_code = promotion_codes.data[0] |
| 1121 | coupon = promo_code.coupon |
| 1122 | |
| 1123 | # Build discount description |
| 1124 | if coupon.percent_off: |
| 1125 | discount_description = f"{coupon.percent_off}% off" |
| 1126 | discount_type = "percent_off" |
| 1127 | discount_value = coupon.percent_off |
| 1128 | currency = None |
| 1129 | else: |
| 1130 | # For amount_off, we need to handle currency |
| 1131 | amount_in_dollars = coupon.amount_off / 100 # Convert cents to dollars |
| 1132 | currency_symbol = "$" if coupon.currency.upper() == "USD" else coupon.currency.upper() |
| 1133 | discount_description = f"{currency_symbol}{amount_in_dollars:.2f} off" |
| 1134 | discount_type = "amount_off" |
| 1135 | discount_value = coupon.amount_off |
| 1136 | currency = coupon.currency.upper() |
| 1137 | |
| 1138 | # Add duration info to description |
| 1139 | if coupon.duration == "once": |
| 1140 | discount_description += " for the first month" |
| 1141 | elif coupon.duration == "repeating": |
| 1142 | discount_description += f" for {coupon.duration_in_months} months" |
| 1143 | elif coupon.duration == "forever": |
| 1144 | discount_description += " forever" |
| 1145 | |
| 1146 | return ValidateDiscountCodeResponse( |
| 1147 | valid=True, |
nothing calls this directly
no test coverage detected
searching dependent graphs…