webapp/src/components/Discours/Donate.tsx

197 lines
7.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { clsx } from 'clsx'
import { createSignal, onMount } from 'solid-js'
import { useLocalize } from '../../context/localize'
import { useSnackbar } from '../../context/snackbar'
import { showModal } from '../../stores/ui'
import styles from './Donate.module.scss'
export const Donate = () => {
const { t } = useLocalize()
const once = ''
const monthly = 'Monthly'
const cpOptions = {
publicId: 'pk_0a37bab30ffc6b77b2f93d65f2aed',
description: t('Help discours to grow'),
currency: 'RUB',
}
let amountSwitchElement: HTMLDivElement | undefined
let customAmountElement: HTMLInputElement | undefined
const [widget, setWidget] = createSignal()
const [customerReciept, setCustomerReciept] = createSignal({})
const [showingPayment, setShowingPayment] = createSignal<boolean>()
const [period, setPeriod] = createSignal(monthly)
const [amount, setAmount] = createSignal(0)
const {
actions: { showSnackbar },
} = useSnackbar()
const initiated = () => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const {
cp: { CloudPayments },
} = window as any // Checkout(cpOptions)
setWidget(new CloudPayments())
console.log('[donate] payments initiated')
setCustomerReciept({
Items: [
//товарные позиции
{
label: cpOptions.description, //наименование товара
price: amount() || 0, //цена
quantity: 1, //количество
amount: amount() || 0, //сумма
vat: 20, //ставка НДС
method: 0, // тег-1214 признак способа расчета - признак способа расчета
object: 0, // тег-1212 признак предмета расчета - признак предмета товара, работы, услуги, платежа, выплаты, иного предмета расчета
},
],
// taxationSystem: 0, //система налогообложения; необязательный, если у вас одна система налогообложения
// email: 'user@example.com', //e-mail покупателя, если нужно отправить письмо с чеком
// phone: '', //телефон покупателя в любом формате, если нужно отправить сообщение со ссылкой на чек
isBso: false, //чек является бланком строгой отчетности
amounts: {
electronic: amount(), // Сумма оплаты электронными деньгами
advancePayment: 0, // Сумма из предоплаты (зачетом аванса) (2 знака после запятой)
credit: 0, // Сумма постоплатой(в кредит) (2 знака после запятой)
provision: 0, // Сумма оплаты встречным предоставлением (сертификаты, др. мат.ценности) (2 знака после запятой)
},
})
}
onMount(() => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const script = document.createElement('script')
script.type = 'text/javascript'
script.src = 'https://widget.cloudpayments.ru/bundles/cloudpayments.js'
script.async = true
script.addEventListener('load', initiated)
document.head.appendChild(script)
})
const show = () => {
// $openModal = 'donate'
setShowingPayment(true)
console.log('[donate] clicked')
const choice: HTMLInputElement | undefined | null =
amountSwitchElement?.querySelector('input[type=radio]:checked')
setAmount(Number.parseInt(customAmountElement?.value || choice?.value || '0'))
console.log('[donate] input amount ' + amount)
// eslint-disable-next-line @typescript-eslint/no-explicit-any
;(widget() as any).charge(
{
// options
...cpOptions,
amount: amount(),
skin: 'classic',
requireEmail: true,
retryPayment: true,
// invoiceId: '1234567', //номер заказа (необязательно)
// accountId: 'user@example.com', //идентификатор плательщика (обязательно для создания подписки)
data: {
CloudPayments: {
CustomerReciept: customerReciept(),
recurrent: {
interval: period(), // local solid's signal
period: 1, // internal widget's
CustomerReciept: customerReciept(), // чек для регулярных платежей
},
},
},
},
(opts) => {
// success
// действие при успешной оплате
console.debug('[donate] options', opts)
showModal('thank')
},
function (reason: string, options) {
// fail
// действие при неуспешной оплате
console.debug('[donate] options', options)
showSnackbar({
type: 'error',
body: reason,
})
},
)
}
return (
<form class={styles.donateForm} action="" method="post">
<input type="hidden" name="shopId" value="156465" />
<input value="148805" name="scid" type="hidden" />
<input value="0" name="customerNumber" type="hidden" />
<div class={styles.formGroup}>
<div class={styles.donateButtonsContainer} ref={amountSwitchElement}>
<input type="radio" name="amount" id="fix250" value="250" />
<label for="fix250" class={styles.btn}>
250&thinsp;
</label>
<input type="radio" name="amount" id="fix500" value="500" checked />
<label for="fix500" class={styles.btn}>
500&thinsp;
</label>
<input type="radio" name="amount" id="fix1000" value="1000" />
<label for="fix1000" class={styles.btn}>
1000&thinsp;
</label>
<input
class={styles.donateInput}
required
ref={customAmountElement}
type="number"
name="sum"
placeholder={t('Another amount')}
/>
</div>
</div>
<div class={styles.formGroup} id="payment-type" classList={{ showing: showingPayment() }}>
<div class={clsx(styles.btnGroup, styles.paymentChoose)} data-toggle="buttons">
<input
type="radio"
autocomplete="off"
id="once"
name="once"
onClick={() => setPeriod(once)}
checked={period() === once}
/>
<label
for="once"
class={clsx(styles.btn, styles.paymentType)}
classList={{ active: period() === once }}
>
{t('One time')}
</label>
<input
type="radio"
autocomplete="off"
id="monthly"
name="monthly"
onClick={() => setPeriod(monthly)}
checked={period() === monthly}
/>
<label
for="monthly"
class={clsx(styles.btn, styles.paymentType)}
classList={{ active: period() === monthly }}
>
{t('Every month')}
</label>
</div>
</div>
<div class={styles.formGroup}>
<button type="button" class={clsx(styles.btn, styles.sendBtn)} onClick={show}>
{t('Help discours to grow')}
</button>
</div>
</form>
)
}