97 lines
2.0 KiB
TypeScript
97 lines
2.0 KiB
TypeScript
import { NextResponse } from 'next/server';
|
|
import jwt from 'jsonwebtoken';
|
|
import { z } from 'zod';
|
|
|
|
import { enhanceRouteHandler } from '@kit/next/routes';
|
|
import { getLogger } from '@kit/shared/logger';
|
|
|
|
interface MontonioOrderToken {
|
|
uuid: string;
|
|
accessKey: string;
|
|
merchantReference: string;
|
|
merchantReferenceDisplay: string;
|
|
paymentStatus:
|
|
| 'PAID'
|
|
| 'FAILED'
|
|
| 'CANCELLED'
|
|
| 'PENDING'
|
|
| 'EXPIRED'
|
|
| 'REFUNDED';
|
|
paymentMethod: string;
|
|
grandTotal: number;
|
|
currency: string;
|
|
senderIban?: string;
|
|
senderName?: string;
|
|
paymentProviderName?: string;
|
|
paymentLinkUuid: string;
|
|
iat: number;
|
|
exp: number;
|
|
}
|
|
|
|
const BodySchema = z.object({
|
|
token: z.string(),
|
|
});
|
|
|
|
export const POST = enhanceRouteHandler(
|
|
async ({ request }) => {
|
|
const logger = await getLogger();
|
|
const body = await request.json();
|
|
const namespace = 'montonio.verify-token';
|
|
|
|
try {
|
|
const { token } = BodySchema.parse(body);
|
|
|
|
const secretKey = process.env.MONTONIO_SECRET_KEY as string;
|
|
|
|
if (!secretKey) {
|
|
logger.error(
|
|
{
|
|
name: namespace,
|
|
},
|
|
`Missing MONTONIO_SECRET_KEY`,
|
|
);
|
|
|
|
throw new Error('Server misconfiguration.');
|
|
}
|
|
|
|
const decoded = jwt.verify(token, secretKey, {
|
|
algorithms: ['HS256'],
|
|
}) as MontonioOrderToken;
|
|
|
|
logger.info(
|
|
{
|
|
name: namespace,
|
|
status: decoded.paymentStatus,
|
|
orderId: decoded.uuid,
|
|
},
|
|
`Successfully verified Montonio token.`,
|
|
);
|
|
|
|
return NextResponse.json({
|
|
status: decoded.paymentStatus,
|
|
});
|
|
} catch (error) {
|
|
logger.error(
|
|
{
|
|
name: namespace,
|
|
error,
|
|
},
|
|
`Failed to verify Montonio token`,
|
|
);
|
|
|
|
const message = error instanceof Error ? error.message : 'Invalid token';
|
|
|
|
return NextResponse.json(
|
|
{
|
|
error: message,
|
|
},
|
|
{
|
|
status: 400,
|
|
},
|
|
);
|
|
}
|
|
},
|
|
{
|
|
auth: false,
|
|
},
|
|
);
|