diff --git a/apps/builder/components/shared/Graph/Nodes/StepNode/SettingsPopoverContent/bodies/PaymentSettings/PaymentSettings.tsx b/apps/builder/components/shared/Graph/Nodes/StepNode/SettingsPopoverContent/bodies/PaymentSettings/PaymentSettings.tsx index 2f313a0d0..b2975fe99 100644 --- a/apps/builder/components/shared/Graph/Nodes/StepNode/SettingsPopoverContent/bodies/PaymentSettings/PaymentSettings.tsx +++ b/apps/builder/components/shared/Graph/Nodes/StepNode/SettingsPopoverContent/bodies/PaymentSettings/PaymentSettings.tsx @@ -75,7 +75,13 @@ export const PaymentSettings = ({ options, onOptionsChange }: Props) => { const handleButtonLabelChange = (button: string) => onOptionsChange({ ...options, - labels: { button }, + labels: { ...options.labels, button }, + }) + + const handleSuccessLabelChange = (success: string) => + onOptionsChange({ + ...options, + labels: { ...options.labels, success }, }) return ( @@ -130,6 +136,14 @@ export const PaymentSettings = ({ options, onOptionsChange }: Props) => { placeholder="Pay" /> + + Success message: + + diff --git a/apps/builder/playwright/tests/customDomains.spec.ts b/apps/builder/playwright/tests/customDomains.spec.ts index 62dfbbd23..07725d6a8 100644 --- a/apps/builder/playwright/tests/customDomains.spec.ts +++ b/apps/builder/playwright/tests/customDomains.spec.ts @@ -61,6 +61,7 @@ test.describe('Free workspace', () => { }, ]) await page.goto(`/typebots/${typebotId}/share`) + await expect(page.locator('text=Pro')).toBeVisible() await page.click('text=Add my domain') await expect(page.locator('text=For solo creator')).toBeVisible() }) diff --git a/apps/builder/playwright/tests/templates.spec.ts b/apps/builder/playwright/tests/templates.spec.ts index 90465163a..b504a3c06 100644 --- a/apps/builder/playwright/tests/templates.spec.ts +++ b/apps/builder/playwright/tests/templates.spec.ts @@ -11,6 +11,7 @@ test.describe.parallel('Templates page', () => { test('From file should import correctly', async ({ page }) => { await page.goto('/typebots/create') + await page.waitForTimeout(1000) await page.setInputFiles( 'input[type="file"]', path.join(__dirname, '../fixtures/typebots/singleChoiceTarget.json') diff --git a/apps/viewer/pages/api/integrations/stripe/createPaymentIntent.ts b/apps/viewer/pages/api/integrations/stripe/createPaymentIntent.ts index 9386947a0..c1df0d606 100644 --- a/apps/viewer/pages/api/integrations/stripe/createPaymentIntent.ts +++ b/apps/viewer/pages/api/integrations/stripe/createPaymentIntent.ts @@ -61,25 +61,39 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => { const receiptEmail = parseVariables(variables)( inputOptions.additionalInformation?.email ) - const paymentIntent = await stripe.paymentIntents.create({ - amount, - currency: inputOptions.currency, - receipt_email: receiptEmail === '' ? undefined : receiptEmail, - automatic_payment_methods: { - enabled: true, - }, - }) + try { + const paymentIntent = await stripe.paymentIntents.create({ + amount, + currency: inputOptions.currency, + receipt_email: receiptEmail === '' ? undefined : receiptEmail, + automatic_payment_methods: { + enabled: true, + }, + }) - return res.send({ - clientSecret: paymentIntent.client_secret, - publicKey: - isPreview && stripeKeys.test?.publicKey - ? stripeKeys.test.publicKey - : stripeKeys.live.publicKey, - amountLabel: `${amount / 100}${ - currencySymbols[inputOptions.currency] ?? inputOptions.currency - }`, - }) + return res.send({ + clientSecret: paymentIntent.client_secret, + publicKey: + isPreview && stripeKeys.test?.publicKey + ? stripeKeys.test.publicKey + : stripeKeys.live.publicKey, + amountLabel: `${amount / 100}${ + currencySymbols[inputOptions.currency] ?? ` ${inputOptions.currency}` + }`, + }) + } catch (err) { + const error = err as any + return 'raw' in error + ? res.status(error.raw.statusCode).send({ + error: { + name: `${error.raw.type} ${error.raw.param}`, + message: error.raw.message, + }, + }) + : res.status(500).send({ + error, + }) + } } return methodNotAllowed(res) } diff --git a/packages/bot-engine/src/components/ChatBlock/ChatStep/InputChatStep.tsx b/packages/bot-engine/src/components/ChatBlock/ChatStep/InputChatStep.tsx index b9d19ee90..19f8a7ab9 100644 --- a/packages/bot-engine/src/components/ChatBlock/ChatStep/InputChatStep.tsx +++ b/packages/bot-engine/src/components/ChatBlock/ChatStep/InputChatStep.tsx @@ -112,7 +112,7 @@ const Input = ({ return ( onSubmit('Success')} + onSuccess={() => onSubmit(step.options.labels.success ?? 'Success')} /> ) } diff --git a/packages/bot-engine/src/components/ChatBlock/ChatStep/inputs/PaymentForm/StripePaymentForm.tsx b/packages/bot-engine/src/components/ChatBlock/ChatStep/inputs/PaymentForm/StripePaymentForm.tsx index 2d7fb2ce8..607d38db0 100644 --- a/packages/bot-engine/src/components/ChatBlock/ChatStep/inputs/PaymentForm/StripePaymentForm.tsx +++ b/packages/bot-engine/src/components/ChatBlock/ChatStep/inputs/PaymentForm/StripePaymentForm.tsx @@ -19,6 +19,7 @@ export const StripePaymentForm = ({ options, onSuccess }: Props) => { apiHost, isPreview, typebot: { variables }, + onNewLog, } = useTypebot() const { window: frameWindow, document: frameDocument } = useFrame() // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -34,7 +35,13 @@ export const StripePaymentForm = ({ options, onSuccess }: Props) => { variables, inputOptions: options, }) - if (error || !data) return console.error(error) + if (error) + return onNewLog({ + status: 'error', + description: error.name + ' ' + error.message, + details: error.message, + }) + if (!data) return await initStripe(frameDocument) setStripe(frameWindow.Stripe(data.publicKey)) setClientSecret(data.clientSecret) @@ -82,6 +89,8 @@ const CheckoutForm = ({ const [message, setMessage] = useState() const [isLoading, setIsLoading] = useState(false) + const [isPayButtonVisible, setIsPayButtonVisible] = useState(false) + useEffect(() => { if (!stripe || !clientSecret) return @@ -145,20 +154,28 @@ const CheckoutForm = ({ setMessage('An unexpected error occured.') } + const showPayButton = () => setIsPayButtonVisible(true) + return (
- - + {isPayButtonVisible && ( + + )} {message && (
( ? JSON.stringify(params.body) : undefined, }) - if (!response.ok) throw new Error(response.statusText) const data = await response.json() + if (!response.ok) throw 'error' in data ? data.error : data return { data } } catch (e) { console.error(e)