web-next: rename-character/customize-character por SumUp + renombrado de rutas
- /rename-character y /customize-character: renombrar/personalizar pagados por SumUp (getRenamePrice/getCustomizePrice). SumUp ahora es service-aware: columna home_stripelog.service; createSumUpCheckout guarda service+character; fulfillSumUpCheckout despacha a la acción del servicio (.char rename/customi) o, sin service, acredita PD. [service]/checkout acepta provider:'sumup'; PaidServiceForm acepta provider+confirmText; service-success maneja el return SumUp. Se eliminan las antiguas /rename y /customize (Stripe). - /revive-character (comparte ReviveServiceContent); se elimina /revive. - Renombres de ruta + todos sus enlaces: /account -> /my-account, /recruit -> /recruit-a-friend, /unstuck -> /unstuck-character. (/select-account y /api/account/* intactos.) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
+21
-5
@@ -1,6 +1,7 @@
|
||||
import type { RowDataPacket, ResultSetHeader } from 'mysql2'
|
||||
import { db, DB } from './db'
|
||||
import { creditDPoints, PD_PER_UNIT } from './dpoints'
|
||||
import { getPaidService } from './paid-services'
|
||||
|
||||
const API = 'https://api.sumup.com/v0.1'
|
||||
|
||||
@@ -26,6 +27,10 @@ interface CreateParams {
|
||||
reference: string
|
||||
description: string
|
||||
returnUrl: string
|
||||
// Para pagos de servicio (renombrar, etc.): al pagar se ejecuta la acción del
|
||||
// servicio sobre `characterName` en vez de acreditar PD. Sin `service` = compra de PD.
|
||||
service?: string
|
||||
characterName?: string
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -55,9 +60,9 @@ export async function createSumUpCheckout(p: CreateParams): Promise<{ success: b
|
||||
if (!url) return { success: false, error: 'noHostedUrl' }
|
||||
|
||||
await db(DB.default).query(
|
||||
'INSERT INTO home_stripelog (account_id, username, email, acore_ip, stripe_ip, product_name, amount, session_id, mode, character_name, timestamp, fulfilled) ' +
|
||||
'VALUES (?, ?, ?, ?, NULL, ?, ?, ?, ?, ?, NOW(), 0)',
|
||||
[p.accountId, p.username, p.email, p.acoreIp, p.description, p.amount, p.reference, 'sumup', p.username],
|
||||
'INSERT INTO home_stripelog (account_id, username, email, acore_ip, stripe_ip, product_name, amount, session_id, mode, character_name, service, timestamp, fulfilled) ' +
|
||||
'VALUES (?, ?, ?, ?, NULL, ?, ?, ?, ?, ?, ?, NOW(), 0)',
|
||||
[p.accountId, p.username, p.email, p.acoreIp, p.description, p.amount, p.reference, 'sumup', p.characterName ?? p.username, p.service ?? null],
|
||||
)
|
||||
return { success: true, url }
|
||||
} catch (e) {
|
||||
@@ -83,13 +88,15 @@ async function isReferencePaid(reference: string): Promise<boolean> {
|
||||
* Entrega un checkout SumUp pagado: verifica el estado, reclama de forma atómica
|
||||
* (fulfilled 0->1) y acredita los PD. Idempotente. Devuelve true si acreditó ahora.
|
||||
*/
|
||||
export async function fulfillSumUpCheckout(reference: string): Promise<{ ok: boolean; paid: boolean }> {
|
||||
export async function fulfillSumUpCheckout(
|
||||
reference: string,
|
||||
): Promise<{ ok: boolean; paid: boolean; service?: string; character?: string }> {
|
||||
if (!reference) return { ok: false, paid: false }
|
||||
const paid = await isReferencePaid(reference)
|
||||
if (!paid) return { ok: false, paid: false }
|
||||
|
||||
const [rows] = await db(DB.default).query<RowDataPacket[]>(
|
||||
'SELECT id, account_id, amount FROM home_stripelog WHERE session_id = ? AND mode = ?',
|
||||
'SELECT id, account_id, amount, service, character_name FROM home_stripelog WHERE session_id = ? AND mode = ?',
|
||||
[reference, 'sumup'],
|
||||
)
|
||||
const log = rows[0]
|
||||
@@ -102,6 +109,15 @@ export async function fulfillSumUpCheckout(reference: string): Promise<{ ok: boo
|
||||
)
|
||||
if (res.affectedRows === 0) return { ok: false, paid: true }
|
||||
|
||||
// Pago de servicio (renombrar…): ejecuta la acción sobre el personaje.
|
||||
const service = log.service ? String(log.service) : ''
|
||||
const cfg = service ? getPaidService(service) : null
|
||||
if (cfg) {
|
||||
const ok = await cfg.fulfill(String(log.character_name), { service })
|
||||
return { ok, paid: true, service, character: String(log.character_name) }
|
||||
}
|
||||
|
||||
// Sin servicio: compra de PD (comportamiento por defecto).
|
||||
const points = Math.round(Number(log.amount) * PD_PER_UNIT)
|
||||
const ok = await creditDPoints(Number(log.account_id), points)
|
||||
return { ok, paid: true }
|
||||
|
||||
Reference in New Issue
Block a user