Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added typescript webhook example #764

Merged
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions examples/webhook-signing/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Stripe keys
STRIPE_SECRET_KEY=
STRIPE_WEBHOOK_SECRET=
2 changes: 2 additions & 0 deletions examples/webhook-signing/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.env
express-ts.js
48 changes: 48 additions & 0 deletions examples/webhook-signing/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Checking webhook signatures

Verify the events that Stripe sends to your webhook endpoints. Additional docs: https://stripe.com/docs/webhooks/signatures.

Additional Node TypeScript server implementation sample: https://github.com/stripe-samples/accept-a-card-payment/tree/master/using-webhooks/server/node-typescript.
thorsten-stripe marked this conversation as resolved.
Show resolved Hide resolved

### Requirements

You’ll need the following:

- [Node.js](http://nodejs.org) >=10.0.0
- Stripe account to accept payments ([sign up](https://dashboard.stripe.com/register) for free).
- [Stripe CLI](https://github.com/stripe/stripe-cli) or [ngrok](https://ngrok.com/) to tunnel requests to your local server.
thorsten-stripe marked this conversation as resolved.
Show resolved Hide resolved

### Setup

Copy the environment variables file from the root of the repository:

cp .env.example .env

Update `.env` with your own [Stripe API keys](https://dashboard.stripe.com/account/apikeys).

### Install and run

Install dependencies using npm:
thorsten-stripe marked this conversation as resolved.
Show resolved Hide resolved

npm install

Next, follow [these installation steps](https://github.com/stripe/stripe-cli#installation) to install the Stripe CLI which we'll use for webhook forwarding.

After the installation has finished, authenticate the CLI with your Stripe account:

stripe login

To start the webhook forwarding run:

stripe listen --forward-to localhost:3000/webhook

The Stripe CLI will let you know that webhook forwarding is ready and output your webhook signing secret:

> Ready! Your webhook signing secret is whsec_xxx

Copy the webhook signing secret (`whsec_xxx`) to your `.env` file.
thorsten-stripe marked this conversation as resolved.
Show resolved Hide resolved

In a separate terminal window, start the local server:

npm run vanilla # Runs the vanilla JavaScript example.
npm run typescript # Compiles and runs the TypeScript example.
67 changes: 67 additions & 0 deletions examples/webhook-signing/express-ts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import Stripe from 'stripe';
import express from 'express';
import bodyParser from 'body-parser';
import env from 'dotenv';

env.config();

const stripe: Stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, {
apiVersion: '2019-12-03',
typescript: true,
});

const webhookSecret: string = process.env.STRIPE_WEBHOOK_SECRET!;

const app: express.Application = express();

// Only use the raw body parser for webhooks.
app.use(
(
req: express.Request,
res: express.Response,
next: express.NextFunction
): void => {
if (req.originalUrl === '/webhook') {
next();
} else {
bodyParser.json()(req, res, next);
}
}
);

// Stripe requires the raw body to construct the event
app.post(
'/webhook',
bodyParser.raw({type: 'application/json'}),
(req: express.Request, res: express.Response): void => {
const sig: string | string[] = req.headers['stripe-signature']!;

let event: Stripe.Event;

try {
event = stripe.webhooks.constructEvent(req.body, sig, webhookSecret);
} catch (err) {
// On error, return the error message
res.status(400).send(`Webhook Error: ${err.message}`);
return;
}

// Do something with event
console.log('Success:', event.id);

// Cast event data to Stripe object
switch (event.type) {
case 'payment_intent.succeeded':
const pi = event.data.object as Stripe.PaymentIntent;
console.log(`PaymentIntent status: ${pi.status}`);
break;
}

// Return a response to acknowledge receipt of the event
res.json({received: true});
}
);

app.listen(3000, (): void => {
console.log('Example app listening on port 3000!');
});
59 changes: 29 additions & 30 deletions examples/webhook-signing/express.js
Original file line number Diff line number Diff line change
@@ -1,41 +1,40 @@
const stripe = require('stripe')(process.env.STRIPE_API_KEY);
require('dotenv').config();
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
const express = require('express');
const bodyParser = require('body-parser');

/**
* You'll need to make sure this is externally accessible. ngrok (https://ngrok.com/)
* makes this really easy.
*
* To run this file, just provide your Secret API Key and Webhook Secret, like so:
* STRIPE_API_KEY=sk_test_XXX WEBHOOK_SECRET=whsec_XXX node express.js
*/
const webhookSecret = process.env.STRIPE_WEBHOOK_SECRET;

const webhookSecret = process.env.WEBHOOK_SECRET;
const app = express();

// Only use the raw body parser for webhooks.
app.use((req, res, next) => {
if (req.originalUrl === '/webhook') {
next();
} else {
bodyParser.json()(req, res, next);
}
});

// Stripe requires the raw body to construct the event
app.post(
'/webhooks',
bodyParser.raw({type: 'application/json'}),
(req, res) => {
const sig = req.headers['stripe-signature'];

let event;

try {
event = stripe.webhooks.constructEvent(req.body, sig, webhookSecret);
} catch (err) {
// On error, return the error message
return res.status(400).send(`Webhook Error: ${err.message}`);
}

// Do something with event
console.log('Success:', event.id);

// Return a response to acknowledge receipt of the event
res.json({received: true});
app.post('/webhook', bodyParser.raw({type: 'application/json'}), (req, res) => {
const sig = req.headers['stripe-signature'];

let event;

try {
event = stripe.webhooks.constructEvent(req.body, sig, webhookSecret);
} catch (err) {
// On error, return the error message
return res.status(400).send(`Webhook Error: ${err.message}`);
}
);

// Do something with event
console.log('Success:', event.id);

// Return a response to acknowledge receipt of the event
res.json({received: true});
});

app.listen(3000, () => {
console.log('Example app listening on port 3000!');
Expand Down
Loading