diff --git a/frontends/web/src/components/terms/btcdirect-otc-terms.tsx b/frontends/web/src/components/terms/btcdirect-otc-terms.tsx index 1e879d7fdf..abcfde0bc5 100644 --- a/frontends/web/src/components/terms/btcdirect-otc-terms.tsx +++ b/frontends/web/src/components/terms/btcdirect-otc-terms.tsx @@ -26,26 +26,27 @@ type TProps = { onContinue: () => void; } +export const getBTCDirectPrivacyLink = () => { + switch (i18n.resolvedLanguage) { + case 'de': + return 'https://btcdirect.eu/de-at/datenschutzenklaerung?BitBox'; + case 'nl': + return 'https://btcdirect.eu/nl-nl/privacy-policy?BitBox'; + case 'es': + return 'https://btcdirect.eu/es-es/privacy-policy?BitBox'; + case 'fr': + return 'https://btcdirect.eu/fr-fr/privacy-policy?BitBox'; + default: + return 'https://btcdirect.eu/en-eu/privacy-policy?BitBox'; + } +}; + +const handleSkipDisclaimer = (e: ChangeEvent) => { + setConfig({ frontend: { skipBTCDirectOTCDisclaimer: e.target.checked } }); +}; + export const BTCDirectOTCTerms = ({ onContinue }: TProps) => { const { t } = useTranslation(); - const handleSkipDisclaimer = (e: ChangeEvent) => { - setConfig({ frontend: { skipBTCDirectOTCDisclaimer: e.target.checked } }); - }; - - const getPrivacyLink = () => { - switch (i18n.resolvedLanguage) { - case 'de': - return 'https://btcdirect.eu/de-at/datenschutzenklaerung?BitBox'; - case 'nl': - return 'https://btcdirect.eu/nl-nl/privacy-policy?BitBox'; - case 'es': - return 'https://btcdirect.eu/es-es/privacy-policy?BitBox'; - case 'fr': - return 'https://btcdirect.eu/fr-fr/privacy-policy?BitBox'; - default: - return 'https://btcdirect.eu/en-eu/privacy-policy?BitBox'; - } - }; return (
@@ -84,7 +85,7 @@ export const BTCDirectOTCTerms = ({ onContinue }: TProps) => {

{t('buy.exchange.infoContent.btcdirect.disclaimer.dataProtection.title')}

{t('buy.exchange.infoContent.btcdirect.disclaimer.dataProtection.text')}

- + {t('buy.exchange.infoContent.btcdirect.disclaimer.dataProtection.link')}

diff --git a/frontends/web/src/components/terms/btcdirect-terms.tsx b/frontends/web/src/components/terms/btcdirect-terms.tsx index 00e5a0a94d..171c2daa00 100644 --- a/frontends/web/src/components/terms/btcdirect-terms.tsx +++ b/frontends/web/src/components/terms/btcdirect-terms.tsx @@ -21,6 +21,8 @@ import { Button, Checkbox } from '@/components/forms'; import { setConfig } from '@/utils/config'; import { IAccount } from '@/api/account'; import { A } from '@/components/anchor/anchor'; +import { getBTCDirectAboutUsLink } from '@/routes/exchange/components/infocontent'; +import { getBTCDirectPrivacyLink } from './btcdirect-otc-terms'; import style from './terms.module.css'; type TProps = { @@ -28,85 +30,52 @@ type TProps = { onAgreedTerms: () => void; } +const handleSkipDisclaimer = (e: ChangeEvent) => { + setConfig({ frontend: { skipBTCDirectWidgetDisclaimer: e.target.checked } }); +}; + export const BTCDirectTerms = ({ account, onAgreedTerms }: TProps) => { const { t } = useTranslation(); - const handleSkipDisclaimer = (e: ChangeEvent) => { - setConfig({ frontend: { skipBTCDirectDisclaimer: e.target.checked } }); - }; - - const coinCode = account.coinCode.toUpperCase(); const isBitcoin = isBitcoinOnly(account.coinCode); - // TODO: change the copy of MoonPay terms to BTCDirect return (
- BTC Direct

- {t('buy.info.disclaimer.title', { + {t('buy.exchange.infoContent.btcdirectWidget.disclaimer.title', { context: isBitcoin ? 'bitcoin' : 'crypto' })}

-

{t('buy.info.disclaimer.intro.0', { coinCode })}

-

{t('buy.info.disclaimer.intro.1', { coinCode })}

+

{t('buy.exchange.infoContent.btcdirectWidget.disclaimer.description')}

- {t('buy.info.disclaimer.payment.title')} + {t('buy.exchange.infoContent.btcdirectWidget.disclaimer.paymentMethods.title')}

-

{t('buy.info.disclaimer.payment.details', { coinCode })}

-
- - - - - - - - - - - - - - - - - - - - - - - - - -
{t('buy.info.disclaimer.payment.table.method')}{t('buy.info.disclaimer.payment.table.fee')}{t('buy.info.disclaimer.payment.table.description')}
{t('buy.info.disclaimer.payment.table.1_method')}1.9 %{t('buy.info.disclaimer.payment.table.1_description')}
{t('buy.info.disclaimer.payment.table.2_method')}4.9 %{t('buy.info.disclaimer.payment.table.2_description')}
-
-

{t('buy.info.disclaimer.payment.footnote')}

-

- {t('buy.info.disclaimer.security.title')} -

-

- {t('buy.info.disclaimer.security.descriptionGeneric', { - context: isBitcoin ? 'bitcoin' : 'crypto' - })} -

+
    +
  • +

    {t('buy.exchange.infoContent.btcdirectWidget.disclaimer.paymentMethods.buy')}

    +
  • +
+

{t('buy.exchange.infoContent.btcdirectWidget.disclaimer.paymentMethods.note')}

- - {t('buy.info.disclaimer.security.link')} + + {t('buy.exchange.infoContent.btcdirectWidget.learnmore')}

- {t('buy.info.disclaimer.protection.title')} + {t('buy.exchange.infoContent.btcdirectWidget.disclaimer.security.title')}

+

{t('buy.exchange.infoContent.btcdirectWidget.disclaimer.security.description')}

- {t('buy.info.disclaimer.protection.descriptionGeneric', { - context: isBitcoin ? 'bitcoin' : 'crypto' - })} + + {t('buy.exchange.infoContent.btcdirectWidget.disclaimer.security.link')} +

+

{t('buy.exchange.infoContent.btcdirect.disclaimer.dataProtection.title')}

+

{t('buy.exchange.infoContent.btcdirect.disclaimer.dataProtection.text')}

- - {t('buy.info.disclaimer.privacyPolicy')} + + {t('buy.exchange.infoContent.btcdirect.disclaimer.dataProtection.link')}

diff --git a/frontends/web/src/locales/en/app.json b/frontends/web/src/locales/en/app.json index 39f5e6901f..e33e881ab6 100644 --- a/frontends/web/src/locales/en/app.json +++ b/frontends/web/src/locales/en/app.json @@ -453,6 +453,25 @@ "title": "Buying or selling over €50,000?" }, "btcdirectWidget": { + "disclaimer": { + "description": "We work with BTC Direct, a trusted European broker, to make buying cryptocurrencies easy within the BitBoxApp. This service is available across Europe using bank transfers, credit cards and many local payment methods.", + "kyc": { + "description": "Customer identity verification is required for all trades. You’ll need to take a selfie and take a picture of an official document.", + "title": "Identity verification" + }, + "paymentMethods": { + "buy": "Buying: Pay in EUR to get the coins delivered directly to your BitBox. You can choose between one-time and recurring buys. For bank transfers, the exchange rate is fixed when BTC Direct receives the money. Instant methods use a fixed conversion rate for a limited time.", + "note": "Note: BTC Direct exchange rates may differ slightly from the BitBoxApp rates.", + "title": "Payment Methods and Fees" + }, + "security": { + "description": "BTC Direct is an external service not covered by the BitBox02 security threat model. We closely work with BTC Direct to enhance overall security.", + "link": "BitBox02 security threat model", + "title": "Security" + }, + "title_bitcoin": "Buy bitcoin with BTC Direct", + "title_crypto": "Buy crypto with BTC Direct" + }, "infobox": { "feesBuying": { "bancontact": "Bancontact: {{fee}}%", @@ -462,7 +481,6 @@ "title": "Fees for Buying" }, "intro": "European buying of cryptocurrencies with EUR.", - "learnmore": "Learn more about BTC Direct", "payment": { "bancontact": "Bancontact", "bankTransfer": "Bank transfer, SEPA Instant, iDEAL", @@ -470,7 +488,8 @@ "sofort": "Sofort", "title": "Payment methods" } - } + }, + "learnmore": "Learn more about BTC Direct" }, "moonpay": { "fees": { diff --git a/frontends/web/src/routes/exchange/btcdirect-otc.tsx b/frontends/web/src/routes/exchange/btcdirect-otc.tsx index 8730889e0c..203ed69277 100644 --- a/frontends/web/src/routes/exchange/btcdirect-otc.tsx +++ b/frontends/web/src/routes/exchange/btcdirect-otc.tsx @@ -17,7 +17,7 @@ import { useTranslation } from 'react-i18next'; import { useNavigate } from 'react-router-dom'; import { BTCDirectOTCTerms } from '@/components/terms/btcdirect-otc-terms'; -import { getBTCDirectLink } from './components/infocontent'; +import { getBTCDirectAboutUsLink } from './components/infocontent'; import { Header } from '@/components/layout'; import { open } from '@/api/system'; import style from './iframe.module.css'; @@ -27,7 +27,7 @@ export const BTCDirectOTC = () => { const navigate = useNavigate(); const openBTCDirect = () => { - open(getBTCDirectLink()); + open(getBTCDirectAboutUsLink()); navigate(-1); }; diff --git a/frontends/web/src/routes/exchange/btcdirect.tsx b/frontends/web/src/routes/exchange/btcdirect.tsx index f3a9a4f63b..958b3e795d 100644 --- a/frontends/web/src/routes/exchange/btcdirect.tsx +++ b/frontends/web/src/routes/exchange/btcdirect.tsx @@ -72,7 +72,7 @@ export const BTCDirect = ({ accounts, code }: TProps) => { useEffect(() => { if (config) { - setAgreedTerms(config.frontend.skipBTCDirectDisclaimer); + setAgreedTerms(config.frontend.skipBTCDirectWidgetDisclaimer); } }, [config]); diff --git a/frontends/web/src/routes/exchange/components/buysell.tsx b/frontends/web/src/routes/exchange/components/buysell.tsx index f940e0be7a..09babb809a 100644 --- a/frontends/web/src/routes/exchange/components/buysell.tsx +++ b/frontends/web/src/routes/exchange/components/buysell.tsx @@ -21,7 +21,7 @@ import { useLoad } from '@/hooks/api'; import * as exchangesAPI from '@/api/exchanges'; import { Button } from '@/components/forms/button'; import { AppContext } from '@/contexts/AppContext'; -import { getBTCDirectLink, TInfoContentProps } from './infocontent'; +import { getBTCDirectAboutUsLink, TInfoContentProps } from './infocontent'; import { Skeleton } from '@/components/skeleton/skeleton'; import { hasPaymentRequest } from '@/api/account'; import { Message } from '@/components/message/message'; @@ -158,7 +158,7 @@ export const BuySell = ({ {t('buy.exchange.infoContent.btcdirect.link')} ) : ( - + {t('buy.exchange.infoContent.btcdirect.link')} )} diff --git a/frontends/web/src/routes/exchange/components/infocontent.tsx b/frontends/web/src/routes/exchange/components/infocontent.tsx index a9f2afe924..f31eb306b3 100644 --- a/frontends/web/src/routes/exchange/components/infocontent.tsx +++ b/frontends/web/src/routes/exchange/components/infocontent.tsx @@ -37,7 +37,7 @@ export const getBTCDirectOTCLink = () => { } }; -export const getBTCDirectLink = () => { +export const getBTCDirectAboutUsLink = () => { switch (i18n.resolvedLanguage) { case 'de': return 'https://btcdirect.eu/de-at/uber-uns?BitBox'; @@ -228,8 +228,8 @@ const BTCDirectInfo = ({

- - {t('buy.exchange.infoContent.btcdirectWidget.infobox.learnmore')} + + {t('buy.exchange.infoContent.btcdirectWidget.learnmore')}

diff --git a/frontends/web/src/routes/exchange/guide.tsx b/frontends/web/src/routes/exchange/guide.tsx index a6c3fb8ae3..df62f4e4f0 100644 --- a/frontends/web/src/routes/exchange/guide.tsx +++ b/frontends/web/src/routes/exchange/guide.tsx @@ -1,5 +1,5 @@ /** - * Copyright 2022-2024 Shift Crypto AG + * Copyright 2022-2025 Shift Crypto AG * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,31 +18,42 @@ import { useTranslation } from 'react-i18next'; import type { TExchangeName } from '@/api/exchanges'; import { Entry } from '@/components/guide/entry'; import { Guide } from '@/components/guide/guide'; +import { getBTCDirectPrivacyLink } from '@/components/terms/btcdirect-otc-terms'; -interface BuyGuideProps { +type BuyGuideProps = { exchange?: TExchangeName; translationContext: 'bitcoin' | 'crypto'; } -export const ExchangeGuide = ({ exchange, translationContext }: BuyGuideProps) => { +const usePrivacyLink = (exchange?: TExchangeName) => { const { t } = useTranslation(); + switch (exchange) { + case 'btcdirect': + return ({ + text: t('buy.exchange.infoContent.btcdirect.disclaimer.dataProtection.link'), + url: getBTCDirectPrivacyLink(), + }); + case 'moonpay': + return ({ + text: t('buy.info.disclaimer.privacyPolicy'), + url: 'https://www.moonpay.com/privacy_policy', + }); + case 'pocket': + return ({ + text: t('exchange.pocket.terms.dataprotection.link'), + url: 'https://pocketbitcoin.com/policy/privacy', + }); + } +}; - const pocketLink = { - text: t('exchange.pocket.terms.dataprotection.link'), - url: 'https://pocketbitcoin.com/policy/privacy', - }; - - const moonpayLink = { - text: t('buy.info.disclaimer.privacyPolicy'), - url: 'https://www.moonpay.com/privacy_policy', - }; - - const privacyLink = exchange === 'pocket' ? pocketLink : moonpayLink; +export const ExchangeGuide = ({ exchange, translationContext }: BuyGuideProps) => { + const { t } = useTranslation(); + const link = usePrivacyLink(exchange); return (