This repository has been archived by the owner on Mar 15, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathpayPledge.js
158 lines (146 loc) · 4.68 KB
/
payPledge.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
const logger = require('../../../lib/logger')
const sendPendingPledgeConfirmations = require('../../../lib/sendPendingPledgeConfirmations')
const generateMemberships = require('../../../lib/generateMemberships')
const payPledgePaymentslip = require('../../../lib/payments/paymentslip/payPledge')
const payPledgePaypal = require('../../../lib/payments/paypal/payPledge')
const payPledgePostfinance = require('../../../lib/payments/postfinance/payPledge')
const payPledgeStripe = require('../../../lib/payments/stripe/payPledge')
const updateUserOnMailchimp = require('../../../lib/updateUserOnMailchimp')
module.exports = async (_, args, {pgdb, req, t}) => {
const transaction = await pgdb.transactionBegin()
try {
const { pledgePayment } = args
// load pledge
// FOR UPDATE to wait on other transactions
const pledge = (await transaction.query(`
SELECT *
FROM pledges
WHERE id = :pledgeId
FOR UPDATE
`, {
pledgeId: pledgePayment.pledgeId
}))[0]
if (!pledge) {
logger.error(`pledge (${pledgePayment.pledgeId}) not found`, { req: req._log(), args, pledge })
throw new Error(t('api/unexpected'))
}
if (pledge.status === 'SUCCESSFUL') {
// check if the pledge was paid with the same paypal transaction
// happens if the webhook is faster than redirect
const payment = (await transaction.query(`
SELECT
pay.*
FROM
"pledgePayments" pp
JOIN
payments pay
ON pp."paymentId" = pay.id
WHERE
pp."pledgeId" = :pledgeId
`, {
pledgeId: pledge.id
}))[0]
let pspPayload
try {
pspPayload = JSON.parse(pledgePayment.pspPayload)
} catch (e) { }
if (
payment && payment.pspPayload && pspPayload &&
payment.pspPayload.TRANSACTIONID === pspPayload.tx) {
await transaction.transactionCommit()
return {
pledgeId: pledge.id
}
}
logger.error('pledge is already paid', { req: req._log(), args, pledge, pledgePayment })
throw new Error(t('api/pledge/alreadyPaid'))
}
// load user
const user = await transaction.public.users.findOne({id: pledge.userId})
// check/charge payment
let pledgeStatus
if (pledgePayment.method === 'PAYMENTSLIP') {
pledgeStatus = await payPledgePaymentslip({
pledgeId: pledge.id,
total: pledge.total,
address: pledgePayment.address,
paperInvoice: pledgePayment.paperInvoice,
userId: user.id,
transaction,
t,
logger
})
} else if (pledgePayment.method === 'STRIPE') {
pledgeStatus = await payPledgeStripe({
pledgeId: pledge.id,
total: pledge.total,
sourceId: pledgePayment.sourceId,
userId: user.id,
transaction,
t,
logger
})
} else if (pledgePayment.method === 'POSTFINANCECARD') {
pledgeStatus = await payPledgePostfinance({
pledgeId: pledge.id,
total: pledge.total,
pspPayloadRaw: pledgePayment.pspPayload,
userId: user.id,
transaction,
t,
logger
})
} else if (pledgePayment.method === 'PAYPAL') {
pledgeStatus = await payPledgePaypal({
pledgeId: pledge.id,
total: pledge.total,
pspPayloadRaw: pledgePayment.pspPayload,
transaction,
t,
logger
})
} else {
logger.error('unsupported paymentMethod', { req: req._log(), args, pledge, pledgePayment })
throw new Error(t('api/unexpected'))
}
if (!pledgeStatus) {
logger.error('pledgeStatus undefined', { req: req._log(), args, pledge, pledgeStatus })
throw new Error(t('api/unexpected'))
}
if (pledge.status !== pledgeStatus) {
// generate Memberships
if (pledgeStatus === 'SUCCESSFUL') {
await generateMemberships(pledge.id, transaction, t, logger)
}
// update pledge status
await transaction.public.pledges.updateOne({
id: pledge.id
}, {
status: pledgeStatus
})
}
// send a confirmation email for this pledge
await transaction.public.pledges.updateOne({
id: pledge.id
}, {
sendConfirmMail: true
})
// commit transaction
await transaction.transactionCommit()
// if the user is signed in, send mail immediately
if (req.user) {
await sendPendingPledgeConfirmations(pledge.userId, pgdb, t)
}
updateUserOnMailchimp({
userId: pledge.userId,
pgdb
})
return {
pledgeId: pledge.id
}
} catch (e) {
await transaction.transactionRollback()
logger.info('transaction rollback', { req: req._log(), error: e })
throw e
}
}