Files
carmanagement/apps/api/src/services/amanpayService.ts
T
2026-05-10 19:55:57 -04:00

98 lines
3.0 KiB
TypeScript

import crypto from 'crypto'
const BASE_URL = process.env.AMANPAY_BASE_URL ?? 'https://api.amanpay.net'
const MERCHANT_ID = process.env.AMANPAY_MERCHANT_ID ?? ''
const SECRET_KEY = process.env.AMANPAY_SECRET_KEY ?? ''
const WEBHOOK_SECRET = process.env.AMANPAY_WEBHOOK_SECRET ?? ''
export interface AmanPayCreateParams {
amount: number
currency: string
orderId: string
description: string
customerEmail?: string
customerName?: string
successUrl: string
failureUrl: string
webhookUrl: string
}
export interface AmanPayCheckoutResult {
transactionId: string
checkoutUrl: string
status: string
}
async function getAuthHeaders() {
return {
'Content-Type': 'application/json',
'x-merchant-id': MERCHANT_ID,
'x-api-key': SECRET_KEY,
}
}
export async function createCheckout(params: AmanPayCreateParams): Promise<AmanPayCheckoutResult> {
const res = await fetch(`${BASE_URL}/v1/payments`, {
method: 'POST',
headers: await getAuthHeaders(),
body: JSON.stringify({
merchant_id: MERCHANT_ID,
amount: params.amount,
currency: params.currency,
order_id: params.orderId,
description: params.description,
customer_email: params.customerEmail,
customer_name: params.customerName,
success_url: params.successUrl,
failure_url: params.failureUrl,
webhook_url: params.webhookUrl,
}),
})
if (!res.ok) {
const err = await res.json().catch(() => ({})) as Record<string, unknown>
throw new Error(`AmanPay checkout failed: ${(err?.message as string) ?? res.statusText}`)
}
const json = await res.json() as Record<string, unknown>
return {
transactionId: (json.transaction_id ?? json.id) as string,
checkoutUrl: (json.checkout_url ?? json.payment_url) as string,
status: (json.status ?? 'PENDING') as string,
}
}
export async function getTransaction(transactionId: string) {
const res = await fetch(`${BASE_URL}/v1/payments/${transactionId}`, {
headers: await getAuthHeaders(),
})
if (!res.ok) throw new Error('AmanPay: failed to fetch transaction')
return res.json()
}
export async function refundTransaction(transactionId: string, amount: number, reason?: string) {
const res = await fetch(`${BASE_URL}/v1/payments/${transactionId}/refund`, {
method: 'POST',
headers: await getAuthHeaders(),
body: JSON.stringify({ amount, reason }),
})
if (!res.ok) {
const err = await res.json().catch(() => ({})) as Record<string, unknown>
throw new Error(`AmanPay refund failed: ${(err?.message as string) ?? res.statusText}`)
}
return res.json()
}
export function verifyWebhookSignature(rawBody: string, signature: string): boolean {
if (!WEBHOOK_SECRET) return false
const expected = crypto
.createHmac('sha256', WEBHOOK_SECRET)
.update(rawBody)
.digest('hex')
return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected))
}
export function isConfigured(): boolean {
return !!(MERCHANT_ID && SECRET_KEY && MERCHANT_ID !== 'your-amanpay-merchant-id')
}