Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add getLodgePrices endpoint to fetch lodge prices #774

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions client/src/models/__generated__/schema.d.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 21 additions & 0 deletions server/src/business-layer/services/StripeService.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {
LODGE_PRICING_TYPE_KEY,
MEMBERSHIP_PRODUCT_TYPE_KEY,
ProductTypeValues,
USER_FIREBASE_EMAIL_KEY,
Expand Down Expand Up @@ -377,6 +378,26 @@ export default class StripeService {
}
}

/** Fetch all active products from Stripe
* @returns lodgeProducts - An array of active lodge products from Stripe
*/
public async getActiveLodgeProducts() {
try {
const products = await stripe.products.list({
active: true,
expand: ["data.default_price"]
})
// Filter products with the required metadata
const lodgeProducts = products.data.filter((product) =>
Object.keys(product.metadata).includes(LODGE_PRICING_TYPE_KEY)
)
return lodgeProducts
} catch (error) {
console.error("Error fetching Stripe products:", error)
throw error
}
}

/**
* Promotes a user from guest to member status.
* @param uid The user ID to promote to a member.
Expand Down
44 changes: 44 additions & 0 deletions server/src/middleware/__generated__/routes.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

71 changes: 71 additions & 0 deletions server/src/middleware/__generated__/swagger.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

56 changes: 55 additions & 1 deletion server/src/service-layer/controllers/PaymentController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import {
import {
MembershipTypeValues,
MEMBERSHIP_TYPE_KEY,
LODGE_PRICING_TYPE_KEY
LODGE_PRICING_TYPE_KEY,
LodgePricingTypeValues
} from "business-layer/utils/StripeProductMetadata"
import {
UTCDateToDdMmYyyy,
Expand All @@ -27,6 +28,7 @@ import {
} from "service-layer/request-models/UserRequests"
import {
BookingPaymentResponse,
LodgeStripeProductResponse,
MembershipPaymentResponse,
MembershipStripeProductResponse
} from "service-layer/response-models/PaymentResponse"
Expand Down Expand Up @@ -107,6 +109,58 @@ export class PaymentController extends Controller {
}
}

/**
* Fetches the prices of the lodge products from Stripe.
* @returns The prices of the lodge products.
*/
@Get("lodge_prices")
public async getLodgePrices(): Promise<LodgeStripeProductResponse> {
const stripeService = new StripeService()
try {
const lodgeProducts = await stripeService.getActiveLodgeProducts()
// Maps the products to the required response type MembershipStripeProductResponse in PaymentResponse

const productsValues = lodgeProducts.map((product) => {
// Checks the membership type of the product
const lodgeType = product.metadata[
LODGE_PRICING_TYPE_KEY
] as LodgePricingTypeValues

let name: LodgePricingTypeValues

switch (lodgeType) {
case LodgePricingTypeValues.SingleFridayOrSaturday: {
name = LodgePricingTypeValues.SingleFridayOrSaturday
break
}
case LodgePricingTypeValues.Normal: {
name = LodgePricingTypeValues.Normal
break
}
}
jeffplays2005 marked this conversation as resolved.
Show resolved Hide resolved

return {
productId: product.id,
name,
description: product.description,
discount: product.metadata.discount === "true",
displayPrice: (
Number(
(product.default_price as Stripe.Price).unit_amount_decimal
) / 100
).toString(),
originalPrice: product.metadata.original_price
}
})
this.setStatus(200)
return { data: productsValues }
} catch (error) {
console.error(error)
this.setStatus(500)
return { error: "Error fetching active Stripe products" }
}
}

/**
* Fetches the details of a checkout session based on a stripe checkout session id.
* @param sessionId The id of the stripe checkout session to fetch.
Expand Down
17 changes: 16 additions & 1 deletion server/src/service-layer/response-models/PaymentResponse.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import { MembershipTypeValues } from "business-layer/utils/StripeProductMetadata"
import {
LodgePricingTypeValues,
MembershipTypeValues
} from "business-layer/utils/StripeProductMetadata"
import { CommonResponse } from "./CommonResponse"
import { Timestamp } from "firebase-admin/firestore"

Expand Down Expand Up @@ -31,6 +34,18 @@ export interface MembershipStripeProductResponse extends CommonResponse {
}[]
}

// Make a data shape matching to the expected response from Stripe API
export interface LodgeStripeProductResponse extends CommonResponse {
data?: {
productId: string
name: LodgePricingTypeValues
description?: string
discount: boolean
displayPrice: string
originalPrice?: string
}[]
}
jeffplays2005 marked this conversation as resolved.
Show resolved Hide resolved

export interface AvailableDatesResponse extends CommonResponse {
data?: AvailableDates[]
}
Loading