Skip to content

Commit

Permalink
feat(input): ⚡️ Better payment accessibility
Browse files Browse the repository at this point in the history
  • Loading branch information
baptisteArno committed Jun 1, 2022
1 parent 89d17a9 commit c1461f0
Show file tree
Hide file tree
Showing 8 changed files with 78 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
Expand Down Expand Up @@ -130,6 +136,14 @@ export const PaymentSettings = ({ options, onOptionsChange }: Props) => {
placeholder="Pay"
/>
</Stack>
<Stack>
<Text>Success message:</Text>
<Input
onChange={handleSuccessLabelChange}
defaultValue={options.labels.success ?? 'Success'}
placeholder="Success"
/>
</Stack>
<Accordion allowToggle>
<AccordionItem>
<AccordionButton justifyContent="space-between">
Expand Down
1 change: 1 addition & 0 deletions apps/builder/playwright/tests/customDomains.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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()
})
Expand Down
1 change: 1 addition & 0 deletions apps/builder/playwright/tests/templates.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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')
Expand Down
50 changes: 32 additions & 18 deletions apps/viewer/pages/api/integrations/stripe/createPaymentIntent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ const Input = ({
return (
<PaymentForm
options={step.options}
onSuccess={() => onSubmit('Success')}
onSuccess={() => onSubmit(step.options.labels.success ?? 'Success')}
/>
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
Expand Down Expand Up @@ -82,6 +89,8 @@ const CheckoutForm = ({
const [message, setMessage] = useState<string>()
const [isLoading, setIsLoading] = useState(false)

const [isPayButtonVisible, setIsPayButtonVisible] = useState(false)

useEffect(() => {
if (!stripe || !clientSecret) return

Expand Down Expand Up @@ -145,20 +154,28 @@ const CheckoutForm = ({
setMessage('An unexpected error occured.')
}

const showPayButton = () => setIsPayButtonVisible(true)

return (
<form
id="payment-form"
onSubmit={handleSubmit}
className="flex flex-col rounded-lg p-4 typebot-input w-full items-center"
>
<PaymentElement id="payment-element" className="w-full" />
<SendButton
label={`${options.labels.button} ${amountLabel}`}
isDisabled={isLoading || !stripe || !elements}
isLoading={isLoading}
className="mt-4 w-full max-w-lg"
disableIcon
<PaymentElement
id="payment-element"
className="w-full"
onReady={showPayButton}
/>
{isPayButtonVisible && (
<SendButton
label={`${options.labels.button} ${amountLabel}`}
isDisabled={isLoading || !stripe || !elements}
isLoading={isLoading}
className="mt-4 w-full max-w-lg"
disableIcon
/>
)}

{message && (
<div
Expand Down
4 changes: 2 additions & 2 deletions packages/models/src/typebot/steps/inputs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ export type PaymentInputOptions = OptionBase & {
email?: string
phoneNumber?: string
}
labels: { button: string }
labels: { button: string; success?: string }
}

const defaultButtonLabel = 'Send'
Expand Down Expand Up @@ -198,6 +198,6 @@ export const defaultChoiceInputOptions: ChoiceInputOptions = {

export const defaultPaymentInputOptions: PaymentInputOptions = {
provider: PaymentProvider.STRIPE,
labels: { button: 'Pay' },
labels: { button: 'Pay', success: 'Success' },
currency: 'USD',
}
2 changes: 1 addition & 1 deletion packages/utils/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ export const sendRequest = async <ResponseData>(
? 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)
Expand Down

4 comments on commit c1461f0

@vercel
Copy link

@vercel vercel bot commented on c1461f0 Jun 1, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vercel
Copy link

@vercel vercel bot commented on c1461f0 Jun 1, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

builder-v2 – ./apps/builder

builder-v2-git-main-typebot-io.vercel.app
app.typebot.io
builder-v2-typebot-io.vercel.app

@vercel
Copy link

@vercel vercel bot commented on c1461f0 Jun 1, 2022

@vercel
Copy link

@vercel vercel bot commented on c1461f0 Jun 1, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.