-
Notifications
You must be signed in to change notification settings - Fork 3.8k
Expand file tree
/
Copy pathindex.js
More file actions
130 lines (125 loc) · 4.71 KB
/
index.js
File metadata and controls
130 lines (125 loc) · 4.71 KB
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
/**
* Copyright 2016 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
'use strict';
const functions = require('firebase-functions/v1');
const {onInit} = require('firebase-functions/v1/init');
const {defineSecret} = require('firebase-functions/params');
const paypal = require('paypal-rest-sdk');
// firebase-admin SDK init
const admin = require('firebase-admin');
admin.initializeApp();
const paypalClientId = defineSecret('PAYPAL_CLIENT_ID');
const paypalClientSecret = defineSecret('PAYPAL_CLIENT_SECRET');
onInit(() => {
paypal.configure({
mode: 'sandbox', // sandbox or live
client_id: paypalClientId.value(),
client_secret: paypalClientSecret.value(),
});
});
/**
* Expected in the body the amount
* Set up the payment information object
* Initialize the payment and redirect the user to the PayPal payment page
*/
exports.pay = functions.runWith({secrets: [paypalClientId, paypalClientSecret]}).https.onRequest((req, res) => {
// 1.Set up a payment information object, Build PayPal payment request
const payReq = JSON.stringify({
intent: 'sale',
payer: {
payment_method: 'paypal'
},
redirect_urls: {
return_url: `${req.protocol}://${req.get('host')}/process`,
cancel_url: `${req.protocol}://${req.get('host')}/cancel`
},
transactions: [{
amount: {
total: req.body.price,
currency: 'USD'
},
// This is the payment transaction description. Maximum length: 127
description: req.body.uid, // req.body.id
// reference_id string .Optional. The merchant-provided ID for the purchase unit. Maximum length: 256.
// reference_id: req.body.uid,
custom: req.body.uid,
// soft_descriptor: req.body.uid
// "invoice_number": req.body.uid,A
}]
});
// 2.Initialize the payment and redirect the user.
paypal.payment.create(payReq, (error, payment) => {
const links = {};
if (error) {
functions.logger.error(error);
res.status(500).end();
} else {
// Capture HATEOAS links
payment.links.forEach((linkObj) => {
links[linkObj.rel] = {
href: linkObj.href,
method: linkObj.method
};
});
// If redirect url present, redirect user
if ( Object.prototype.hasOwnProperty.call(links, 'approval_url')) {
// REDIRECT USER TO links['approval_url'].href
functions.logger.info(links.approval_url.href);
// res.json({"approval_url":links.approval_url.href});
res.redirect(302, links.approval_url.href);
} else {
functions.logger.error('no redirect URI present');
res.status(500).end();
}
}
});
});
// 3.Complete the payment. Use the payer and payment IDs provided in the query string following the redirect.
exports.process = functions.runWith({secrets: [paypalClientId, paypalClientSecret]}).https.onRequest(async (req, res) => {
const paymentId = req.query.paymentId;
const payerId = {
payer_id: req.query.PayerID
};
const r = await paypal.payment.execute(paymentId, payerId, (error, payment) => {
if (error) {
functions.logger.error(error);
res.redirect(`${req.protocol}://${req.get('host')}/error`); // replace with your url page error
} else {
if (payment.state === 'approved') {
functions.logger.info(
'payment completed successfully, description: ',
payment.transactions[0].description
);
// functions.logger.info('req.custom: : ', payment.transactions[0].custom);
// set paid status to True in RealTime Database
const date = Date.now();
const uid = payment.transactions[0].description;
const ref = admin.database().ref('users/' + uid + '/');
ref.push({
paid: true,
// 'description': description,
date: date,
});
res.redirect(`${req.protocol}://${req.get('host')}/success`); // replace with your url, page success
} else {
functions.logger.warn('payment.state: not approved ?');
// replace debug url
res.redirect(`https://console.firebase.google.com/project/${process.env.GCLOUD_PROJECT}/functions/logs?search=&severity=DEBUG`);
}
}
});
functions.logger.info('promise: ', r);
});