forked from stripe/stripe-connect-rocketrides
-
Notifications
You must be signed in to change notification settings - Fork 1
/
stripe.js
172 lines (157 loc) · 5.38 KB
/
stripe.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
'use strict';
const config = require('../../config');
const stripe = require('stripe')(config.stripe.secretKey, {
apiVersion: config.stripe.apiVersion || '2022-08-01'
});
const request = require('request-promise-native');
const querystring = require('querystring');
const express = require('express');
const router = express.Router();
// Middleware that requires a logged-in pilot
function pilotRequired(req, res, next) {
if (!req.isAuthenticated()) {
return res.redirect('/pilots/login');
}
next();
}
/**
* GET /pilots/stripe/authorize
*
* Redirect to Stripe to set up payments.
*/
router.get('/authorize', pilotRequired, async (req, res, next) => {
// Generate a random string as `state` to protect from CSRF and include it in the session
req.session.state = Math.random()
.toString(36)
.slice(2);
try {
let accountId = req.user.stripeAccountId;
// Create a Stripe account for this user if one does not exist already
if (accountId == undefined) {
// Define the parameters to create a new Stripe account with
let accountParams = {
type: 'express',
country: req.user.country || undefined,
email: req.user.email || undefined,
business_type: req.user.type || 'individual',
}
// Companies and invididuals require different parameters
if (accountParams.business_type === 'company') {
accountParams = Object.assign(accountParams, {
company: {
name: req.user.businessName || undefined
}
});
} else {
accountParams = Object.assign(accountParams, {
individual: {
first_name: req.user.firstName || undefined,
last_name: req.user.lastName || undefined,
email: req.user.email || undefined
}
});
}
const account = await stripe.accounts.create(accountParams);
accountId = account.id;
// Update the model and store the Stripe account ID in the datastore:
// this Stripe account ID will be used to issue payouts to the pilot
req.user.stripeAccountId = accountId;
await req.user.save();
}
// Create an account link for the user's Stripe account
const accountLink = await stripe.accountLinks.create({
account: accountId,
refresh_url: config.publicDomain + '/pilots/stripe/authorize',
return_url: config.publicDomain + '/pilots/stripe/onboarded',
type: 'account_onboarding'
});
// Redirect to Stripe to start the Express onboarding flow
res.redirect(accountLink.url);
} catch (err) {
console.log('Failed to create a Stripe account.');
console.log(err);
next(err);
}
});
/**
* GET /pilots/stripe/onboarded
*
* Return endpoint from Stripe onboarding, checks if onboarding has been completed
*/
router.get('/onboarded', pilotRequired, async (req, res, next) => {
try {
// Retrieve the user's Stripe account and check if they have finished onboarding
const account = await stripe.account.retrieve(req.user.stripeAccountId);
if (account.details_submitted) {
req.user.onboardingComplete = true;
await req.user.save();
// Redirect to the Rocket Rides dashboard
req.flash('showBanner', 'true');
res.redirect('/pilots/dashboard');
} else {
console.log('The onboarding process was not completed.');
res.redirect('/pilots/signup');
}
} catch (err) {
console.log('Failed to retrieve Stripe account information.');
console.log(err);
next(err);
}
})
/**
* GET /pilots/stripe/dashboard
*
* Redirect to the pilots' Stripe Express dashboard to view payouts and edit account details.
*/
router.get('/dashboard', pilotRequired, async (req, res) => {
const pilot = req.user;
// Make sure the logged-in pilot completed the Express onboarding
if (!pilot.onboardingComplete) {
return res.redirect('/pilots/signup');
}
try {
// Generate a unique login link for the associated Stripe account to access their Express dashboard
const loginLink = await stripe.accounts.createLoginLink(
pilot.stripeAccountId, {
redirect_url: config.publicDomain + '/pilots/dashboard'
}
);
// Directly link to the account tab
if (req.query.account) {
loginLink.url = loginLink.url + '#/account';
}
// Retrieve the URL from the response and redirect the user to Stripe
return res.redirect(loginLink.url);
} catch (err) {
console.log(err);
console.log('Failed to create a Stripe login link.');
return res.redirect('/pilots/signup');
}
});
/**
* POST /pilots/stripe/payout
*
* Generate a payout with Stripe for the available balance.
*/
router.post('/payout', pilotRequired, async (req, res) => {
const pilot = req.user;
try {
// Fetch the account balance to determine the available funds
const balance = await stripe.balance.retrieve({
stripe_account: pilot.stripeAccountId,
});
// This demo app only uses USD so we'll just use the first available balance
// (Note: there is one balance for each currency used in your application)
const {amount, currency} = balance.available[0];
// Create a payout
const payout = await stripe.payouts.create({
amount: amount,
currency: currency,
statement_descriptor: config.appName,
}, {stripe_account: pilot.stripeAccountId });
} catch (err) {
console.log(err);
}
res.redirect('/pilots/dashboard');
});
module.exports = router;