rename-guild: permitir pagar con PD, Stripe o SumUp
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>
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
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 })
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
import { getSession } from '@/lib/session'
|
||||
import { renameGuild } from '@/lib/guild'
|
||||
|
||||
/** Renombra una hermandad de la que la cuenta en sesión es Maestro (cuesta 1000 PD). */
|
||||
export async function POST(request: Request) {
|
||||
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 result = await renameGuild({
|
||||
accountId: session.accountId,
|
||||
guildId: Number(body.guildId),
|
||||
newName: String(body.newName ?? ''),
|
||||
token: String(body.token ?? '').trim(),
|
||||
})
|
||||
return Response.json(result)
|
||||
}
|
||||
Reference in New Issue
Block a user