feat(SW-245): Delete credit card
This commit is contained in:
committed by
Michael Zetterberg
parent
2af17ef4d8
commit
e9a6499086
@@ -1,5 +1,6 @@
|
||||
import { mergeRouters } from "@/server/trpc"
|
||||
|
||||
import { userMutationRouter } from "./mutation"
|
||||
import { userQueryRouter } from "./query"
|
||||
|
||||
export const userRouter = mergeRouters(userQueryRouter)
|
||||
export const userRouter = mergeRouters(userQueryRouter, userMutationRouter)
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { z } from "zod"
|
||||
|
||||
import { Lang } from "@/constants/languages"
|
||||
|
||||
export const getUserInputSchema = z
|
||||
.object({
|
||||
mask: z.boolean().default(true),
|
||||
@@ -19,11 +21,15 @@ export const soonestUpcomingStaysInput = z
|
||||
})
|
||||
.default({ limit: 3 })
|
||||
|
||||
export const initiateSaveCardInput = z.object({
|
||||
export const addCreditCardInput = z.object({
|
||||
language: z.string(),
|
||||
})
|
||||
|
||||
export const saveCardInput = z.object({
|
||||
export const deleteCreditCardInput = z.object({
|
||||
creditCardId: z.string(),
|
||||
})
|
||||
|
||||
export const saveCreditCardInput = z.object({
|
||||
transactionId: z.string(),
|
||||
merchantId: z.string().optional(),
|
||||
})
|
||||
|
||||
85
server/routers/user/mutation.ts
Normal file
85
server/routers/user/mutation.ts
Normal file
@@ -0,0 +1,85 @@
|
||||
import * as api from "@/lib/api"
|
||||
import { initiateSaveCardSchema } from "@/server/routers/user/output"
|
||||
import { protectedProcedure, router } from "@/server/trpc"
|
||||
|
||||
import {
|
||||
addCreditCardInput,
|
||||
deleteCreditCardInput,
|
||||
saveCreditCardInput,
|
||||
} from "./input"
|
||||
|
||||
export const userMutationRouter = router({
|
||||
creditCard: router({
|
||||
add: protectedProcedure.input(addCreditCardInput).mutation(async function ({
|
||||
ctx,
|
||||
input,
|
||||
}) {
|
||||
const apiResponse = await api.post(api.endpoints.v1.intiateSaveCard, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${ctx.session.token.access_token}`,
|
||||
},
|
||||
body: {
|
||||
language: input.language,
|
||||
mobileToken: false,
|
||||
redirectUrl: `api/web/add-card-callback/${input.language}`,
|
||||
},
|
||||
})
|
||||
|
||||
if (!apiResponse.ok) {
|
||||
console.info(`API Response Failed - Initiating add Creadit Card flow`)
|
||||
console.error(apiResponse)
|
||||
return null
|
||||
}
|
||||
|
||||
const apiJson = await apiResponse.json()
|
||||
const verifiedData = initiateSaveCardSchema.safeParse(apiJson)
|
||||
if (!verifiedData.success) {
|
||||
console.error(`Failed to initiate save card data`)
|
||||
console.error(verifiedData.error)
|
||||
return null
|
||||
}
|
||||
|
||||
return verifiedData.data.data
|
||||
}),
|
||||
save: protectedProcedure
|
||||
.input(saveCreditCardInput)
|
||||
.mutation(async function ({ ctx, input }) {
|
||||
const apiResponse = await api.post(
|
||||
`${api.endpoints.v1.creditCards}/${input.transactionId}`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${ctx.session.token.access_token}`,
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
if (!apiResponse.ok) {
|
||||
console.error(`API Response Failed - Save card`)
|
||||
console.error(apiResponse)
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}),
|
||||
delete: protectedProcedure
|
||||
.input(deleteCreditCardInput)
|
||||
.mutation(async function ({ ctx, input }) {
|
||||
const apiResponse = await api.remove(
|
||||
`${api.endpoints.v1.creditCards}/${input.creditCardId}`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${ctx.session.token.access_token}`,
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
if (!apiResponse.ok) {
|
||||
console.error(`API Response Failed - Delete credit card`)
|
||||
console.error(apiResponse)
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}),
|
||||
}),
|
||||
})
|
||||
@@ -176,20 +176,28 @@ type GetFriendTransactionsData = z.infer<typeof getFriendTransactionsSchema>
|
||||
|
||||
export type FriendTransaction = GetFriendTransactionsData["data"][number]
|
||||
|
||||
export const getCreditCardsSchema = z.object({
|
||||
data: z.array(
|
||||
z.object({
|
||||
attribute: z.object({
|
||||
cardName: z.string().optional(),
|
||||
alias: z.string(),
|
||||
truncatedNumber: z.string(),
|
||||
expirationDate: z.string(),
|
||||
cardType: z.string(),
|
||||
}),
|
||||
id: z.string(),
|
||||
type: z.string(),
|
||||
})
|
||||
),
|
||||
export const creditCardSchema = z
|
||||
.object({
|
||||
attribute: z.object({
|
||||
cardName: z.string().optional(),
|
||||
alias: z.string(),
|
||||
truncatedNumber: z.string(),
|
||||
expirationDate: z.string(),
|
||||
cardType: z.string(),
|
||||
}),
|
||||
id: z.string(),
|
||||
type: z.string(),
|
||||
})
|
||||
.transform((apiResponse) => {
|
||||
return {
|
||||
id: apiResponse.id,
|
||||
type: apiResponse.attribute.cardType,
|
||||
truncatedNumber: apiResponse.attribute.truncatedNumber,
|
||||
}
|
||||
})
|
||||
|
||||
export const creditCardsSchema = z.object({
|
||||
data: z.array(creditCardSchema),
|
||||
})
|
||||
|
||||
export const getMembershipCardsSchema = z.array(
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
import { Lang } from "@/constants/languages"
|
||||
import { env } from "@/env/server"
|
||||
import * as api from "@/lib/api"
|
||||
import { internalServerError } from "@/server/errors/next"
|
||||
import {
|
||||
badRequestError,
|
||||
forbiddenError,
|
||||
unauthorizedError,
|
||||
} from "@/server/errors/trpc"
|
||||
import {
|
||||
protectedProcedure,
|
||||
router,
|
||||
@@ -21,18 +15,15 @@ import encryptValue from "../utils/encryptValue"
|
||||
import {
|
||||
friendTransactionsInput,
|
||||
getUserInputSchema,
|
||||
initiateSaveCardInput,
|
||||
saveCardInput,
|
||||
staysInput,
|
||||
} from "./input"
|
||||
import {
|
||||
creditCardsSchema,
|
||||
FriendTransaction,
|
||||
getCreditCardsSchema,
|
||||
getFriendTransactionsSchema,
|
||||
getMembershipCardsSchema,
|
||||
getStaysSchema,
|
||||
getUserSchema,
|
||||
initiateSaveCardSchema,
|
||||
Stay,
|
||||
} from "./output"
|
||||
import { benefits, extendedUser, nextLevelPerks } from "./temp"
|
||||
@@ -566,7 +557,7 @@ export const userQueryRouter = router({
|
||||
}
|
||||
|
||||
const apiJson = await apiResponse.json()
|
||||
const verifiedData = getCreditCardsSchema.safeParse(apiJson)
|
||||
const verifiedData = creditCardsSchema.safeParse(apiJson)
|
||||
if (!verifiedData.success) {
|
||||
console.error(`Failed to validate Credit Cards Data`)
|
||||
console.error(`User: (${JSON.stringify(ctx.session.user)})`)
|
||||
@@ -577,69 +568,6 @@ export const userQueryRouter = router({
|
||||
return verifiedData.data.data
|
||||
}),
|
||||
|
||||
initiateSaveCard: protectedProcedure
|
||||
.input(initiateSaveCardInput)
|
||||
.mutation(async function ({ ctx, input }) {
|
||||
const apiResponse = await api.post(api.endpoints.v1.initiateSaveCard, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${ctx.session.token.access_token}`,
|
||||
},
|
||||
body: {
|
||||
language: input.language,
|
||||
mobileToken: false,
|
||||
redirectUrl: `api/web/add-card-callback/${input.language}`,
|
||||
},
|
||||
})
|
||||
|
||||
if (!apiResponse.ok) {
|
||||
switch (apiResponse.status) {
|
||||
case 400:
|
||||
throw badRequestError(apiResponse)
|
||||
case 401:
|
||||
throw unauthorizedError(apiResponse)
|
||||
case 403:
|
||||
throw forbiddenError(apiResponse)
|
||||
default:
|
||||
throw internalServerError(apiResponse)
|
||||
}
|
||||
}
|
||||
|
||||
const apiJson = await apiResponse.json()
|
||||
const verifiedData = initiateSaveCardSchema.safeParse(apiJson)
|
||||
if (!verifiedData.success) {
|
||||
console.error(`Failed to initiate save card data`)
|
||||
console.error(`User: (${JSON.stringify(ctx.session.user)})`)
|
||||
console.error(verifiedData.error)
|
||||
return null
|
||||
}
|
||||
|
||||
return verifiedData.data.data
|
||||
}),
|
||||
|
||||
saveCard: protectedProcedure.input(saveCardInput).mutation(async function ({
|
||||
ctx,
|
||||
input,
|
||||
}) {
|
||||
const apiResponse = await api.post(
|
||||
`${api.endpoints.v1.creditCards}/${input.transactionId}`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${ctx.session.token.access_token}`,
|
||||
},
|
||||
body: {},
|
||||
}
|
||||
)
|
||||
|
||||
if (!apiResponse.ok) {
|
||||
console.error(`API Response Failed - Save card`)
|
||||
console.error(`User: (${JSON.stringify(ctx.session.user)})`)
|
||||
console.error(apiResponse)
|
||||
return null
|
||||
}
|
||||
|
||||
return true
|
||||
}),
|
||||
|
||||
membershipCards: protectedProcedure.query(async function ({ ctx }) {
|
||||
const apiResponse = await api.get(api.endpoints.v1.profile, {
|
||||
cache: "no-store",
|
||||
|
||||
Reference in New Issue
Block a user