-
Notifications
You must be signed in to change notification settings - Fork 61
/
app.js
120 lines (102 loc) · 3.54 KB
/
app.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
// API usage Dependencies
const recurly = require('recurly')
const express = require('express');
const bodyParser = require('body-parser');
// We'll use uuids to generate account_code values
const uuid = require('node-uuid');
// Set up express
const app = express();
app.use(bodyParser());
// These are the various configuration values used in this example. They are
// pulled from the ENV for ease of use, but can be defined directly or stored
// elsewhere
const {
RECURLY_SUBDOMAIN,
RECURLY_API_KEY,
RECURLY_PUBLIC_KEY,
SUCCESS_URL,
ERROR_URL,
PUBLIC_DIR_PATH
} = process.env;
// Instantiate a configured recurly client
const client = new recurly.Client(RECURLY_API_KEY)
// POST route to handle a new subscription form
app.post('/api/subscriptions/new', async function (req, res) {
// Build our billing info hash
const tokenId = req.body['recurly-token'];
const code = req.body['recurly-account-code'] || uuid.v1();
const billingInfo = { token_id: tokenId };
// Optionally add a 3D Secure token if one is present. You only need to do this
// if you are integrating with Recurly's 3D Secure support
if (req.body['three-d-secure-token']) {
billingInfo.three_d_secure_action_result_token_id = req.body['three-d-secure-token']
}
// Create the purchase using minimal
// information: planCode, currency, account.code, and
// the token we generated on the frontend
const purchaseReq = {
subscriptions: [{ planCode: 'basic' }],
currency: 'USD',
account: { code, billingInfo }
}
try {
await client.createPurchase(purchaseReq);
res.redirect(SUCCESS_URL);
}
catch (err) {
// Here we handle a 3D Secure required error by redirecting to an authentication page
if (err && err.transactionError && err.transactionError.code === 'three_d_secure_action_required') {
const { threeDSecureActionTokenId } = err.transactionError;
const url = `/3d-secure/authenticate.html#token_id=${tokenId}&action_token_id=${threeDSecureActionTokenId}&account_code=${code}`
return res.redirect(url);
}
// If any other error occurs, redirect to an error page with the error as a query param
const { message } = err;
return res.redirect(`${ERROR_URL}?error=${message}`);
}
});
// POST route to handle a new account form
app.post('/api/accounts/new', async function (req, res) {
try {
const accountCreate = {
code: uuid.v1(),
billing_info: {
token_id: req.body['recurly-token']
}
}
await client.createAccount(accountCreate);
res.redirect(SUCCESS_URL);
}
catch (err) {
const { message } = err;
return res.redirect(`${ERROR_URL}?error=${message}`);
}
});
// PUT route to handle an account update form
app.put('/api/accounts/:account_code', async function (req, res) {
try {
const accountUpdate = {
billing_info: {
token_id: req.body['recurly-token']
}
}
await client.updateAccount(req.params.account_code, accountUpdate);
res.redirect(SUCCESS_URL);
}
catch (err) {
const { message } = err;
return res.redirect(`${ERROR_URL}?error=${message}`);
}
});
// This endpoint provides configuration to recurly.js
app.get('/config', function (req, res) {
res.setHeader('Content-Type', 'application/javascript');
res.send(`window.recurlyConfig = { publicKey: '${RECURLY_PUBLIC_KEY}' }`);
});
// Mounts express.static to render example forms
const pubDirPath = PUBLIC_DIR_PATH || '/../../public';
app.use(express.static(pubDirPath));
// Start the server
app.listen(9001, function () {
console.log('Listening on port 9001');
});