add multi-crypto payment buttons to cart

This commit is contained in:
2026-09-05 18:55:58 +02:00
parent 3b6323658e
commit 302c3729c4
5 changed files with 41 additions and 17 deletions
+6
View File
@@ -0,0 +1,6 @@
import { PaymentMethod } from '../modules/payment/types/PaymentMethod';
export const paymentMethodLabel: Record<PaymentMethod, string> = {
[PaymentMethod.Xmr]: 'XMR',
[PaymentMethod.Btc]: 'BTC'
};
@@ -3,14 +3,13 @@ import { DiscountCodesModule } from '../discountCode/DiscountCodesModule';
import { ProductsModule } from '../product/ProductsModule'; import { ProductsModule } from '../product/ProductsModule';
import { StorefrontCoreModule } from '../storefrontCore/StorefrontCoreModule'; import { StorefrontCoreModule } from '../storefrontCore/StorefrontCoreModule';
import { StorefrontProductModule } from '../storefrontProduct/StorefrontProductModule'; import { StorefrontProductModule } from '../storefrontProduct/StorefrontProductModule';
import { ExchangeRateModule } from '../exchangeRate/ExchangeRateModule';
import { StorefrontCartController } from './controllers/StorefrontCartController'; import { StorefrontCartController } from './controllers/StorefrontCartController';
import { StorefrontCartDiscountResolver } from './services/StorefrontCartDiscountResolver'; import { StorefrontCartDiscountResolver } from './services/StorefrontCartDiscountResolver';
import { StorefrontCartService } from './services/StorefrontCartService'; import { StorefrontCartService } from './services/StorefrontCartService';
import { StorefrontDiscountService } from './services/StorefrontDiscountService'; import { StorefrontDiscountService } from './services/StorefrontDiscountService';
@Module({ @Module({
imports: [StorefrontCoreModule, StorefrontProductModule, ProductsModule, DiscountCodesModule, ExchangeRateModule], imports: [StorefrontCoreModule, StorefrontProductModule, ProductsModule, DiscountCodesModule],
controllers: [StorefrontCartController], controllers: [StorefrontCartController],
providers: [StorefrontCartService, StorefrontDiscountService, StorefrontCartDiscountResolver], providers: [StorefrontCartService, StorefrontDiscountService, StorefrontCartDiscountResolver],
exports: [StorefrontCartService] exports: [StorefrontCartService]
@@ -1,7 +1,10 @@
import { Body, Controller, Get, HttpStatus, Post, Req, Res, UseFilters } from '@nestjs/common'; import { Body, Controller, Get, HttpStatus, Post, Req, Res, UseFilters } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { Throttle } from '@nestjs/throttler'; import { Throttle } from '@nestjs/throttler';
import type { Request, Response } from 'express'; import type { Request, Response } from 'express';
import { throttleProfiles } from '../../../config/throttleProfiles'; import { throttleProfiles } from '../../../config/throttleProfiles';
import type { Config } from '../../../types/Config';
import { paymentMethodLabel } from '../../../consts/paymentMethodLabel';
import { StorefrontExceptionFilter } from '../../storefrontCore/filters/StorefrontExceptionFilter'; import { StorefrontExceptionFilter } from '../../storefrontCore/filters/StorefrontExceptionFilter';
import { StorefrontCartCookieService } from '../../storefrontCore/services/StorefrontCartCookieService'; import { StorefrontCartCookieService } from '../../storefrontCore/services/StorefrontCartCookieService';
import { StorefrontCheckoutSessionCookieService } from '../../storefrontCore/services/StorefrontCheckoutSessionCookieService'; import { StorefrontCheckoutSessionCookieService } from '../../storefrontCore/services/StorefrontCheckoutSessionCookieService';
@@ -33,7 +36,8 @@ export class StorefrontCartController {
private readonly feedbackCookieService: StorefrontFeedbackCookieService, private readonly feedbackCookieService: StorefrontFeedbackCookieService,
private readonly checkoutSessionCookieService: StorefrontCheckoutSessionCookieService, private readonly checkoutSessionCookieService: StorefrontCheckoutSessionCookieService,
private readonly captchaService: StorefrontCaptchaService, private readonly captchaService: StorefrontCaptchaService,
private readonly captchaCookieService: StorefrontCaptchaCookieService private readonly captchaCookieService: StorefrontCaptchaCookieService,
private readonly configService: ConfigService
) {} ) {}
@Get('shop/cart') @Get('shop/cart')
@@ -62,9 +66,17 @@ export class StorefrontCartController {
this.captchaCookieService.setAnswer(req, res, encryptedAnswer); this.captchaCookieService.setAnswer(req, res, encryptedAnswer);
const { enabledPaymentMethods } = this.configService.get('shopSettings') as Config['shopSettings'];
const paymentMethods = enabledPaymentMethods.map(paymentMethod => ({
paymentMethod,
paymentMethodLabel: paymentMethodLabel[paymentMethod]
}));
return res.render('cart-summary', { return res.render('cart-summary', {
...summary, ...summary,
...shopLocals, ...shopLocals,
paymentMethods,
captchaSvg captchaSvg
}); });
} }
@@ -4,8 +4,6 @@ import type { CookieCartExtended } from './CookieCartExtended';
export type CookieCartSummary = { export type CookieCartSummary = {
cartExtended: CookieCartExtended; cartExtended: CookieCartExtended;
cartSubtotal: number; cartSubtotal: number;
cartTotalXmr: string | null;
fiatPerXmr: number | null;
hasManualLines: boolean; hasManualLines: boolean;
hasAutoLines: boolean; hasAutoLines: boolean;
cartTotalIssueMessage: string | null; cartTotalIssueMessage: string | null;
@@ -66,18 +66,27 @@
{{/if}} {{/if}}
<div class='sf-stack sf-mt-4'> <div class='sf-stack sf-mt-4'>
{{#unless hasIssues}} {{#unless hasIssues}}
<form class='sf-form-col' method='post' action='/shop/checkout/pay'> <form class='sf-form-col' method='post' action='/shop/checkout/pay'>
<div>{{{captchaSvg}}}</div> <div>{{{captchaSvg}}}</div>
<label class='sf-field'> <label class='sf-field'>
<span class='sf-field__label'>Enter the code above</span> <span class='sf-field__label'>Enter the code above</span>
<input class='sf-input' type='text' name='captcha' autocomplete='off' required /> <input class='sf-input' type='text' name='captcha' autocomplete='off' required />
</label> </label>
<button type='submit' class='sf-btn sf-btn--primary'>Pay with XMR</button>
</form> <div class='sf-stack'>
{{else}} {{#each paymentMethods}}
<button type='button' class='sf-btn sf-btn--primary' disabled title='Resolve cart issues before paying'>Pay with XMR</button> <button
{{/unless}} type='submit'
name='paymentMethod'
value='{{paymentMethod}}'
class='sf-btn sf-btn--primary'
>
Pay with {{paymentMethodLabel}}
</button>
{{/each}}
</div>
</form>
{{else}} {{else}}
<button type='button' class='sf-btn sf-btn--primary' disabled title='Resolve cart issues before paying'>Continue to payment</button> <button type='button' class='sf-btn sf-btn--primary' disabled title='Resolve cart issues before paying'>Continue to payment</button>
{{/unless}} {{/unless}}