├── .gitignore ├── LICENSE ├── README.md ├── index.js ├── package.json └── tests └── index.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | coverage 3 | .DS_STORE -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) Nijiko Yonskai (nijikokun.com) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Stripe Mock Webhooks 2 | 3 | Quickly test Stripe Webhooks against your application without hitting Stripe or requiring internet connectivity. 4 | 5 | ## Features & Data 6 | 7 | - Customize Webhook response 8 | - Generate Webhook response object without triggering it against your application 9 | - Offline mocking 10 | - [Supports multiple versions of the Stripe API](https://github.com/Nijikokun/stripe-mock-data#features--data) 11 | - Promises! 12 | 13 | ## Install 14 | 15 | ```bash 16 | $ npm install stripe-mock-webhooks --save-dev 17 | ``` 18 | 19 | ## Usage 20 | 21 | ```js 22 | // Require 23 | var StripeMockWebhooks = require('stripe-mock-webhooks') 24 | 25 | // Tell the server where it should send events 26 | var webhooks = new StripeMockWebhooks({ 27 | version: '2015-10-01', // Default is latest Stripe API version 28 | url: 'http://localhost:3001/stripe/events' 29 | }) 30 | ``` 31 | 32 | Send a webhook: 33 | 34 | ```js 35 | webhooks.trigger('invoice.created').then(function (response) { 36 | // success 37 | }).catch(function (err) { 38 | // error 39 | }) 40 | ``` 41 | 42 | Or overwrite values in the response: 43 | 44 | ```js 45 | webhooks.trigger('invoice.created', { 46 | data: { 47 | object: { 48 | plan: { 49 | id: 'PLAN_IDENTIFIER' 50 | } 51 | } 52 | } 53 | }) 54 | ``` 55 | 56 | Additional options can be turned on / off: 57 | 58 | ```js 59 | webhooks.trigger('invoice.created', undefined, { 60 | now: false 61 | }) 62 | ``` 63 | 64 | Build `JSON` response without triggering an event: 65 | 66 | ```js 67 | var response = webhooks.build('invoice.created', { 68 | data: { 69 | object: { 70 | plan: { 71 | id: 'PLAN_IDENTIFIER' 72 | } 73 | } 74 | } 75 | }) 76 | ``` 77 | 78 | Supports the same arguments as `webhooks.trigger` 79 | 80 | ## Trigger Options 81 | 82 | - `now` - Updates event `created` timestamp to `Date.now()`, defaults to `true` 83 | 84 | ## Examples 85 | 86 | Look in [tests](tests/) to see example usage. 87 | 88 | ## License 89 | 90 | MIT © [Nijiko Yonskai](http://nijikokun.com) 91 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | var StripeData = require('stripe-mock-data') 4 | var Promise = require('promise') 5 | var assign = require('assign-deep') 6 | var needle = require('needle') 7 | 8 | /** 9 | * Stripe Mock Webhook Constructor 10 | * 11 | * @param {Object} options Mocking options 12 | * @param {String} options.url URL to be pinged when an event is triggered 13 | * @param {String} options.version Stripe API version to be used 14 | */ 15 | module.exports = exports = function StripeMockWebhooks (options) { 16 | options = options || {} 17 | 18 | if (!options.url) { 19 | throw new Error('StripeMockWebhooks: missing required option [url]') 20 | } 21 | 22 | this.version = options.version || StripeMockWebhooks.LATEST_STRIPE_VERSION 23 | this.stripeData = StripeData(this.version) 24 | this.url = options.url 25 | } 26 | 27 | /** 28 | * Latest Stripe API version 29 | * @type {String} 30 | */ 31 | exports.LATEST_STRIPE_VERSION = '2015-10-01' 32 | 33 | /** 34 | * Build Stripe Event Response 35 | * 36 | * @param {String} event Stripe webhook event name 37 | * @param {Object} properties Properties to be added or replaced in the response 38 | * @param {Object} options Flags and options for the triggered event 39 | * @param {Boolean} options.now Change event created timestamp to now, defaults to true 40 | */ 41 | exports.prototype.build = function stripeEvent (event, properties, options) { 42 | properties = properties || {} 43 | options = options || { 44 | now: true 45 | } 46 | 47 | var response = this.stripeData.webhooks[event] 48 | 49 | if (!response) { 50 | throw new Error('StripeMockWebhooks: no such webhook [' + event + '] for version [' + this.version + ']') 51 | } else { 52 | response = response[0] || response 53 | } 54 | 55 | if (options.now) { 56 | response.created = Date.now() 57 | } 58 | 59 | response = assign(response, properties) 60 | 61 | return response 62 | } 63 | 64 | /** 65 | * Trigger Stripe Webhook Event 66 | * 67 | * @param {String} event Stripe webhook event name 68 | * @param {Object} properties Properties to be added or replaced in the response 69 | * @param {Object} options Flags and options for the triggered event 70 | * @param {Boolean} options.now Change event created timestamp to now, defaults to true 71 | */ 72 | exports.prototype.trigger = function triggerStripeEvent (event, properties, options) { 73 | return new Promise(function (resolve, reject) { 74 | needle.post(this.url, this.build(event, properties, options), { 75 | json: true 76 | }, function (err, res) { 77 | return err ? reject(err) : resolve(res) 78 | }) 79 | }.bind(this)) 80 | } 81 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "stripe-mock-webhooks", 3 | "version": "1.1.0", 4 | "description": "Test Stripe Webhooks, no internet required", 5 | "repository": "Nijikokun/stripe-mock-webhooks", 6 | "main": "index.js", 7 | "scripts": { 8 | "test": "node tests/index.js" 9 | }, 10 | "keywords": [ 11 | "stripe", 12 | "test", 13 | "mock", 14 | "data", 15 | "api", 16 | "server", 17 | "webhook", 18 | "json", 19 | "offline", 20 | "tester" 21 | ], 22 | "author": "Nijiko Yonskai (nijikokun.com)", 23 | "license": "MIT", 24 | "dependencies": { 25 | "assign-deep": "^0.4.2", 26 | "needle": "^0.11.0", 27 | "promise": "^7.0.4", 28 | "stripe-mock-data": "^1.0.0" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /tests/index.js: -------------------------------------------------------------------------------- 1 | var StripeMockWebhooks = require('../') 2 | var assert = require('assert') 3 | var http = require('http') 4 | 5 | // Check latest stripe version 6 | assert(StripeMockWebhooks.LATEST_STRIPE_VERSION === '2015-10-01') 7 | 8 | // Build webhooks object 9 | var webhooks = new StripeMockWebhooks({ 10 | version: '2015-04-07', 11 | url: 'http://localhost:3001/stripe/events' 12 | }) 13 | 14 | // Check correct version was used 15 | assert(webhooks.version === '2015-04-07') 16 | 17 | // Check webhook url was set 18 | assert(webhooks.url === 'http://localhost:3001/stripe/events') 19 | 20 | // Invoke a webhook with invalid event 21 | webhooks.trigger('invoice_create').catch(function (err) { 22 | assert.equal(err.message, 'StripeMockWebhooks: no such webhook [invoice.create] for version [2015-04-07]') 23 | }) 24 | 25 | // Initialize a server to send a response 26 | var server = http.createServer(function (req, res) { 27 | var body = '' 28 | 29 | assert.equal(req.method, 'POST') 30 | assert.equal(req.url, '/stripe/events') 31 | 32 | req.on('data', function (chunk) { 33 | body += chunk 34 | }) 35 | 36 | req.on('end', function () { 37 | res.writeHead(200, { 'Content-Type': 'application/json' }) 38 | res.end(body) 39 | }) 40 | }) 41 | 42 | // Listen on 3001 43 | server.listen(3001) 44 | 45 | // Invoke a webhook 46 | webhooks.trigger('invoice.created').then(function (response) { 47 | assert.equal(response.statusCode, 200) 48 | assert.equal(response.body.type, 'invoice.created') 49 | }).catch(function (err) { 50 | console.trace(err) 51 | process.exit(1) 52 | }) 53 | 54 | // Invoke a webhook with properties 55 | webhooks.trigger('invoice.created', { livemode: true }).then(function (response) { 56 | assert.equal(response.statusCode, 200) 57 | assert.equal(response.body.type, 'invoice.created') 58 | assert.equal(response.body.livemode, true) 59 | server.close() 60 | }).catch(function (err) { 61 | console.trace(err) 62 | process.exit(1) 63 | }) --------------------------------------------------------------------------------