Añadir /send-gift (Enviar regalo) pagado por SumUp

Envía ítems de la tienda por correo al personaje de un amigo, pagado por
SumUp. lib/gift.ts (catálogo por categoría, priceCart con precios reales de
BD, sendGiftByMail vía SOAP .send items troceado a 12/correo + anti-inyección);
servicio send-gift en PAID_SERVICES; ruta dedicada /api/gift/checkout (origen
propio, destino existe, token de seguridad, carrito); SendGiftForm + página con
el diseño; i18n Paid[send-gift]; seed_giftitems.sql (4 cat, 8 ítems).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-14 13:49:56 +00:00
parent 671632a6a0
commit 1a2d40ee9c
8 changed files with 594 additions and 4 deletions
+18
View File
@@ -1,5 +1,6 @@
import { executeSoapCommand } from './soap'
import { creditDPoints } from './dpoints'
import { sendGiftByMail } from './gift'
import { checkFactionChangeEligibility } from './change-faction'
import { checkTransferEligibility } from './transfer-character'
import {
@@ -102,6 +103,23 @@ export const PAID_SERVICES: Record<string, PaidServiceConfig> = {
extraFields: ['destination_account'],
precheck: ({ accountId, email, character, body }) => checkTransferEligibility(accountId, email, character, body),
},
// Enviar regalo: al pagar por SumUp, envía por correo los ítems del carrito al
// personaje destino (a un amigo). `sender` = personaje de origen; `items` = JSON
// [{ i: item_id, q: cantidad }] que guardó el checkout en metadata.
'send-gift': {
price: (m) => Promise.resolve(Number(m.amount)),
productName: (c) => `Regalo para ${c}`,
fulfill: (c, m) => {
let items: { i: number; q: number }[] = []
try {
items = JSON.parse(m.items || '[]')
} catch {
return Promise.resolve(false)
}
return sendGiftByMail(c, m.sender || '', items)
},
extraFields: [],
},
// Compra de PD (Adquirir PD): acredita puntos a la cuenta que hizo el pago.
// El importe lo elige el usuario, por eso `price` lee metadata.amount.
dpoints: {