You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This tutorial shows how you can build a more secure payment form using Turnstile. You can learn how to block bot access on the checkout page and trigger additional authentication flows by integrating Turnstile with Stripe
25
-
23
+
This tutorial shows how you can build a more secure payment form using Turnstile. You can learn how to block bot access on the checkout page and trigger additional authentication flows by integrating Turnstile with Stripe.
26
24
27
25
## Before you begin
28
26
29
-
- You must have a Cloudflare account
30
-
- You must have a Stripe account
27
+
<Renderfile="prereqs"product="workers" />
28
+
3. Sign up for a [Stripe](https://stripe.com) account.
31
29
30
+
## 1. Get Your Turnstile sitekey and secret key
32
31
33
-
## Get Your Turnstile sitekey and secret key
32
+
First, you will need to prepare a Cloudflare Turnstile widget to use for this application.
34
33
35
34
1. Log in to the [Cloudflare dashboard](https://dash.cloudflare.com/) and select your account.
36
35
2. Go to **Turnstile** and [create a new Turnstile widget](/turnstile/get-started/).
37
36
3. Copy the sitekey and the secret key to use in the next step.
38
37
39
-
## 1. Create a new Worker project
38
+
## 2. Create a new Worker project
40
39
41
-
42
-
First, let's create a Cloudflare Workers project.
40
+
Now that your Turnstile widget it ready to use, you can create your Worker application.
43
41
44
42
<Renderfile="c3-definition"product="workers" />
45
43
46
44
To efficiently create and manage multiple APIs, let's use [`Hono`](https://hono.dev). Hono is an open-source application framework released by a Cloudflare Developer Advocate. It is lightweight and allows for the creation of multiple API paths, as well as efficient request and response handling.
45
+
47
46
Open your command line interface (CLI) and run the following command:
During the setup, you will be asked if you want to manage your project source code with `Git`. It is recommended to answer `Yes` as it helps in recording your work and rolling back changes. You can also choose `No`, which will not affect the tutorial progress.
87
85
88
86
```sh
@@ -150,21 +148,19 @@ curl http://localhost:8787
150
148
Hello Hono!
151
149
```
152
150
153
-
So far, we've covered how to create a Cloudflare Worker project and introduced tools and open-source projects like the `C3` command and the `Hono` framework that streamline development with Cloudflare. Leveraging these features will help you develop applications on Cloudflare Workers more smoothly.
154
-
155
-
## 2. Preparation for the building web application
151
+
So far, we've covered how to create a Worker project using `C3` and introduced the open source `Hono` framework that streamlines web-application development with Workers.
156
152
157
-
By the default, we need to update the Hono project for supporting to web application.
153
+
At the next step, we need to update the Hono project for supporting to web application.
158
154
159
-
### Change the file extension to support JSX
155
+
##3. Change index script file extension to .JSX
160
156
161
-
Since we'll use JSX to dynamically create HTML, let's change `src/index.ts` to `src/index.tsx`.
157
+
Since we will use JSX to dynamically create HTML, you will need to change `src/index.ts` to `src/index.tsx`.
162
158
163
159
```
164
160
mv src/index.ts src/index.tsx
165
161
```
166
162
167
-
At the same time, let's change the filename specified in the `wrangler.toml`.
163
+
At the same time, change the filename specified in the `wrangler.toml`.
168
164
169
165
```diff
170
166
#:schema node_modules/wrangler/config-schema.json
@@ -174,19 +170,15 @@ name = "secure-payment-form"
174
170
compatibility_date = "2024-10-22"
175
171
```
176
172
177
-
### Register Stripe API key and Turnstile key as environment variables
178
-
179
-
Let's register API keys as environment variables to use both Stripe and Cloudflare Turnstile.
173
+
## 4. Add the Stripe API key and Turnstile key as environment variables
180
174
181
-
You can obtain test site keys and secret keys for Cloudflare Turnstile from the documentation.
175
+
To connect your web application to both Stripe and Turnstile, you must register the necessary API keys for Stripe and Turnstile as environment variables within your application.
In local development using Hono and Wrangler, you can retrieve values set in `.dev.vars` like this:
213
206
214
207
```ts
215
-
app.get('/hello', asyncc=> {
216
-
console.log(c.env.TURNSTILE_SITE_KEY);
217
-
returnc.json({ message: 'test' });
218
-
})
208
+
app.get("/hello", async(c)=> {
209
+
console.log(c.env.TURNSTILE_SITE_KEY);
210
+
returnc.json({ message: "test" });
211
+
});
219
212
```
220
213
221
-
Now we're ready for application development. In the next steps, we'll develop a payment form using Turnstile and Stripe.
214
+
Now we are ready for application development. In the next steps, we will develop a payment form using Turnstile and Stripe.
222
215
223
-
## 3. Implementing Bot Detection with Turnstile
216
+
## 5. Implement Bot Detection with Turnstile
224
217
225
-
Let's start by creating a form that uses Turnstile to detect bot access. Add the following code to `src/index.tsx` to create a simple form:
218
+
Start by creating a form that uses Turnstile to detect bot access. Add the following code to `src/index.tsx` to create a simple form:
226
219
227
220
```ts
228
221
import { Hono } from"hono";
@@ -247,8 +240,8 @@ export default app;
247
240
248
241
```
249
242
250
-
Let's add JavaScript code to our application to implement bot detection using Turnstile.
251
-
By adding this implementation, the order form submission process will be disabled until the Turnstile bot detection process is completed and it is confirmed that the access is not from a bot.
243
+
Add JavaScript code to our application to implement bot detection using Turnstile.
244
+
By adding this implementation, the order form submission process will be disabled until the Turnstile bot detection process is completed and it is confirmed that the access request is not from a bot.
252
245
253
246
```diff
254
247
import { Hono } from "hono";
@@ -297,15 +290,15 @@ export default app;
297
290
298
291
```
299
292
300
-
Here, we're loading the Turnstile script file with a `script` tag. The `_turnstileCB` function is executed when the script file loading is complete, triggered by the `onload=_turnstileCB` in the query string.
293
+
This will load the Turnstile script file with a `script` tag. The `_turnstileCB` function is executed when the script file loading is complete, triggered by the `onload=_turnstileCB` in the query string.
301
294
302
295
In the `_turnstileCB` function, `turnstile.render()` is executed. The `callback` set here removes the `disabled` attribute from the submit `button` of the `form`.
303
296
304
-
This simple implementation prevents order operations for accesses that Cloudflare identifies as bots.
297
+
This implementation blocks order operations for any requests that Cloudflare identifies as being made by a bots.
305
298
306
-
## 4. Integrating Turnstile with a Stripe Payment Form
299
+
## 6. Integrate Turnstile with a Stripe payment form
307
300
308
-
For a more practical example, let's integrate Turnstile with a Stripe payment form. First, install the Stripe SDK:
301
+
To integrate Turnstile with a Stripe payment form, first you will need to install the Stripe SDK:
309
302
310
303
<Tabs> <TabItemlabel="npm">
311
304
@@ -327,8 +320,7 @@ pnpm add stripe
327
320
328
321
</TabItem> </Tabs>
329
322
330
-
Next, let's implement the code to create a payment form in `src/index.tsx`.
331
-
First, create a [Payment Intent](https://docs.stripe.com/api/payment_intents) on the server side:
323
+
Next, implement the code to create a payment form in `src/index.tsx`. The following code creates a [Payment Intent](https://docs.stripe.com/api/payment_intents) on the server side:
332
324
333
325
```diff
334
326
import { Hono } from "hono";
@@ -358,7 +350,7 @@ app.get("/", async (c) => {
358
350
359
351
```
360
352
361
-
And adding JavaScript code to display the payment form. Edit `src/index.tsx`:
353
+
Then, add the following code to display the payment form. Edit `src/index.tsx`:
362
354
363
355
```diff
364
356
{html`
@@ -431,98 +423,102 @@ The payment form is now ready. To experience how it behaves when a bot is detect
431
423
+TURNSTILE_SITE_KEY = '2x00000000000000000000AB'
432
424
```
433
425
434
-
If you restart the application now, you'll notice that you can't submit the payment form.
426
+
If you restart the application now, you will notice that you cannot submit the payment form.
This way, you can block requests trying to manipulate the payment form using bots, such as card testing attacks.
430
+
This way, you can block requests that use bots to try and manipulate the payment form, such as card testing attacks.
439
431
By verifying whether the `turnstileToken` is set by the `callback` of `turnstile.render()`, you can use Turnstile's result when processing the `form`'s `submit` event.
440
432
441
-
Note: After completing the tests, let's make sure to revert the Turnstile SITE_KEY back to its original value.
433
+
:::note
434
+
After completing the tests, make sure to revert the Turnstile `SITE_KEY` back to its original value.
435
+
442
436
```diff
443
437
+TURNSTILE_SITE_KEY = '1x00000000000000000000AA'
444
438
-TURNSTILE_SITE_KEY = '2x00000000000000000000AB'
445
439
```
446
440
447
-
## 5. Adding Server-Side Validation
441
+
:::
442
+
443
+
## 7. Add Server-Side Validation
448
444
449
-
Let's add a step to verify that the token generated by the Turnstile widget is valid and not forged.
445
+
Next, add a step to verify that the token generated by the Turnstile widget is valid and not forged.
450
446
In this case, we'll add an API that performs additional validation and server-side processing based on the result of `turnstile.render`.
451
447
452
-
First, for easier testing, let's remove the `disabled` attribute from the `button` tag:
448
+
For easier testing, remove the `disabled` attribute from the `button` tag:
453
449
454
450
```diff
455
451
- <button type="submit" disabled>Order</button>
456
452
+ <button type="submit" >Order</button>
457
453
```
458
454
459
-
Next, let's add an API for server-side verification. Please add the following code to `src/index.tsx`.
455
+
Next, add an API for server-side verification. Please add the following code to `src/index.tsx`.
460
456
This API validates the Turnstile token generated by the client application and incorporates the result into Stripe's Payment Intent.
By executing this before calling Stripe's JavaScript SDK in the form's submit event, we can decide whether to proceed with the payment based on the server-side validation result:
By adding this step, we now perform a two-stage check using Turnstile before the payment process.
575
-
Since we're saving the Turnstile authentication result in the Stripe data, it's also easier to investigate if a user reports a payment failure.
571
+
572
+
Since we're saving the Turnstile authentication result in the Stripe data, it is also easier to investigate if a user reports a payment failure.
576
573
577
574
If you want more strict control, you could add a process to invalidate the Stripe Payment Intent if authentication fails in the `POST /pre-confirm` API.
578
575
579
576
## Conclusion
580
577
581
-
In online payments, it's necessary to protect applications from bot attacks such as card testing and DDoS.
582
-
While payment services like Stripe are increasingly implementing bot prevention measures, adding Turnstile can provide an extra layer of security for your payment forms.
578
+
In online payments, it ss necessary to protect applications from bot attacks such as card testing and DDoS attacks.
579
+
580
+
While payment services like Stripe are increasingly implementing bot prevention measures, adding Turnstile can provide an extra layer of security for your payment forms.
0 commit comments