/** * 06 — Payment fees (3-mode: included / absorb / surcharge) * * A payment method can carry a processor fee. `feeMode` decides who pays it: * - "included" — the customer pays the goods total (fee not added); the * merchant bears the fee. * - "absorb" — the merchant eats the fee; customer still pays goods. * - "surcharge" — the fee is added ON TOP; the customer pays goods + fee. * * Only "surcharge" changes what the customer is billed. This example shows the * two things a storefront needs: * 1. PREVIEW the surcharge line at method-select time with estimateSurcharge() * — a bit-exact client-side mirror of the server math (no round-trip). * 2. Read the EXACT, authoritative fee off the checkout response payment.fee. * * ⚠️ payment.total is GROSS (goods + surcharge). Never re-add fee.amount to it. * ⚠️ Topups are ALWAYS net — never draw a surcharge line on a top-up. * * Run with: * GAMECORE_API_KEY=gc_live_... bun run examples/06-payment-fees.ts */ import { GameCoreClient, estimateSurcharge } from "@gamecore-api/sdk"; const apiKey = process.env.GAMECORE_API_KEY!; const baseUrl = "https://api.gamecore-api.tech"; const gc = new GameCoreClient({ apiKey, baseUrl }); // --- 1. Preview the surcharge for each method at selection time --- const goodsTotal = 1000; // the cart subtotal the buyer currently sees const methods = await gc.checkout.getPaymentMethods(); for (const m of methods) { const preview = estimateSurcharge({ goods: goodsTotal, feePercent: m.feePercent, feeFixed: m.feeFixed, feeMode: m.feeMode, }); if (preview.applies) { // e.g. "Card — Комиссия платёжной системы: 25 ₽ → к оплате 1025 ₽" console.log( `${m.label} — surcharge ${preview.fee} ₽ → pay ${preview.gross} ₽`, ); } else { console.log(`${m.label} — no surcharge → pay ${goodsTotal} ₽`); } } // --- 2. After checkout.create(), the server fee is authoritative --- // const res = await gc.checkout.create({ ... , paymentMethod: picked.type }); // const fee = res.payment?.fee; // if (fee && fee.mode === "surcharge") { // // Render the real charged breakdown BEFORE redirecting to fee.amount: // // Товары: fee.goodsTotal ₽ · Комиссия: fee.amount ₽ · Итого: res.payment.total ₽ // console.log("charged breakdown", fee, "gross total", res.payment?.total); // }