20ee5a83c8
Renombrar hermandad ya no es solo PD: ahora ofrece el mismo selector de forma de pago que el resto de servicios (saldo PD / tarjeta Stripe / tarjeta SumUp). El coste es equivalente: 1000 PD = 10 €. - lib/guild: se separa la validación (checkGuildRenameEligibility) del renombrado por SOAP (renameGuildBySoap); nuevo GUILD_RENAME_EUR (10 €). - paid-services: entrada 'rename-guild' para que la reconciliación/webhook entregue el servicio tras el pago con tarjeta. - nueva ruta /api/guild/rename/checkout con las 3 pasarelas (valida elegibilidad antes de cobrar); se elimina la antigua /api/guild/rename. - RenameGuildForm usa PaymentMethodSelect y redirige a service-success. - i18n: Paid.rename-guild (title/success) para la página de éxito. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
94 lines
3.6 KiB
TypeScript
94 lines
3.6 KiB
TypeScript
import { randomUUID } from 'crypto'
|
|
import { getSession } from '@/lib/session'
|
|
import { createCheckoutSession } from '@/lib/stripe'
|
|
import { createSumUpCheckout, sumupConfigured } from '@/lib/sumup'
|
|
import { getPaidService } from '@/lib/paid-services'
|
|
import { payServiceWithDPoints } from '@/lib/pay-with-dpoints'
|
|
import { checkGuildRenameEligibility, GUILD_RENAME_EUR } from '@/lib/guild'
|
|
|
|
function safeLocale(v: unknown): string {
|
|
return v === 'en' ? 'en' : 'es'
|
|
}
|
|
|
|
/**
|
|
* Inicia el renombrado de hermandad con la forma de pago elegida (PD / Stripe /
|
|
* SumUp). Valida la elegibilidad (Maestro, token, nombre libre) antes de cobrar.
|
|
* Con PD, ejecuta el renombrado al momento; con Stripe/SumUp, lo hace la
|
|
* reconciliación/webhook vía PAID_SERVICES['rename-guild'].
|
|
*/
|
|
export async function POST(request: Request) {
|
|
const cfg = getPaidService('rename-guild')!
|
|
|
|
const session = await getSession()
|
|
if (!session.accountId || !session.username) {
|
|
return Response.json({ success: false, error: 'notAuthenticated' }, { status: 401 })
|
|
}
|
|
|
|
let body: Record<string, unknown> = {}
|
|
try {
|
|
body = await request.json()
|
|
} catch {
|
|
return Response.json({ success: false, error: 'invalidRequest' }, { status: 400 })
|
|
}
|
|
|
|
const guildId = Number(body.guildId)
|
|
const newName = String(body.newName ?? '').trim()
|
|
const token = String(body.token ?? '').trim()
|
|
|
|
const elig = await checkGuildRenameEligibility({ accountId: session.accountId, guildId, newName, token })
|
|
if (!elig.ok) return Response.json({ success: false, error: elig.error })
|
|
|
|
const metadata: Record<string, string> = { service: 'rename-guild', guildId: String(guildId), newName }
|
|
const price = GUILD_RENAME_EUR
|
|
const site = process.env.SITE_URL || ''
|
|
const ip = (request.headers.get('x-forwarded-for') || '').split(',')[0].trim() || '0.0.0.0'
|
|
const productName = cfg.productName(newName, metadata)
|
|
|
|
// Pago con saldo PD: descuenta el saldo y renombra al momento.
|
|
if (String(body.provider) === 'pd') {
|
|
const r = await payServiceWithDPoints(session.accountId, price, () => cfg.fulfill(newName, metadata))
|
|
if (!r.success) return Response.json({ success: false, error: r.error })
|
|
const locale = safeLocale(body.locale)
|
|
return Response.json({
|
|
success: true,
|
|
url: `${site}/${locale}/service-success?service=rename-guild&provider=pd&name=${encodeURIComponent(newName)}`,
|
|
})
|
|
}
|
|
|
|
if (String(body.provider) === 'sumup') {
|
|
if (!sumupConfigured()) return Response.json({ success: false, error: 'notConfigured' })
|
|
const reference = randomUUID()
|
|
const r = await createSumUpCheckout({
|
|
accountId: session.accountId,
|
|
username: session.username || '',
|
|
email: session.bnetEmail || '',
|
|
acoreIp: ip,
|
|
amount: price,
|
|
points: 0,
|
|
reference,
|
|
description: productName,
|
|
returnUrl: `${site}/service-success?service=rename-guild&provider=sumup&ref=${reference}`,
|
|
service: 'rename-guild',
|
|
characterName: newName,
|
|
metadata,
|
|
})
|
|
if (!r.success || !r.url) return Response.json({ success: false, error: r.error || 'sumupError' })
|
|
return Response.json({ success: true, url: r.url })
|
|
}
|
|
|
|
const r = await createCheckoutSession({
|
|
accountId: session.accountId,
|
|
username: session.username || '',
|
|
email: session.bnetEmail || '',
|
|
acoreIp: ip,
|
|
amount: price,
|
|
characterName: newName,
|
|
productName,
|
|
successUrl: `${site}/service-success?service=rename-guild`,
|
|
cancelUrl: `${site}/rename-guild`,
|
|
metadata,
|
|
})
|
|
if (!r.success || !r.url) return Response.json({ success: false, error: 'stripeError' })
|
|
return Response.json({ success: true, url: r.url })
|
|
}
|