Added checkout backend function
This commit is contained in:
		@@ -11,7 +11,8 @@
 | 
			
		||||
  "main": "lib/index.js",
 | 
			
		||||
  "dependencies": {
 | 
			
		||||
    "firebase-admin": "~5.12.1",
 | 
			
		||||
    "firebase-functions": "^1.0.3"
 | 
			
		||||
    "firebase-functions": "^1.0.3",
 | 
			
		||||
    "paypal-rest-sdk": "^1.8.1"
 | 
			
		||||
  },
 | 
			
		||||
  "devDependencies": {
 | 
			
		||||
    "typescript": "^2.5.3"
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,114 @@
 | 
			
		||||
import * as admin from 'firebase-admin';
 | 
			
		||||
import * as functions from 'firebase-functions';
 | 
			
		||||
import * as paypal from 'paypal-rest-sdk';
 | 
			
		||||
import {resolve} from 'path';
 | 
			
		||||
 | 
			
		||||
export const helloWorld = functions.https.onRequest((request, response) => {
 | 
			
		||||
  response.send('Hello from Firebase!');
 | 
			
		||||
paypal.configure({
 | 
			
		||||
  mode: 'sandbox',
 | 
			
		||||
  client_id: 'AaU8tQfmz1_MFDTKuf84yYERXvdDt2ZFJVrxhNW_49DazF4A_F0VBuKyV5_nntyEdZqUa5Oq9ZBj65GV',
 | 
			
		||||
  client_secret: 'EAZ8aFDU4lHHLy1bQqULYWqznf3dBknXZW3AH__zFC0bUs8AGUyR6RNbm-jHvqtikX7PsSqMO5vxuvKm'
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
export const checkout = functions.https.onRequest(async (request, response) => {
 | 
			
		||||
  // Create base request
 | 
			
		||||
  let req = {
 | 
			
		||||
    intent: 'sale',
 | 
			
		||||
    payer: {
 | 
			
		||||
      payment_method: 'paypal'
 | 
			
		||||
    },
 | 
			
		||||
    redirect_urls: {
 | 
			
		||||
      return_url: 'https://fhsons.zakscode.com/success',
 | 
			
		||||
      cancel_url: 'https://fhsons.zakscode.com/cart'
 | 
			
		||||
    },
 | 
			
		||||
    transactions: [
 | 
			
		||||
      {
 | 
			
		||||
        item_list: {
 | 
			
		||||
          items: []
 | 
			
		||||
        },
 | 
			
		||||
        amount: {
 | 
			
		||||
          total: 0,
 | 
			
		||||
          currency: 'CAD'
 | 
			
		||||
        },
 | 
			
		||||
        description: 'Purchase of equipment and suplies from FH & Sons'
 | 
			
		||||
      }
 | 
			
		||||
    ]
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  // Fill in information from DB
 | 
			
		||||
  let promises = [];
 | 
			
		||||
  let cart = request.body.cart.filter(row => row.quantity > 0);
 | 
			
		||||
  cart.forEach(async row =>
 | 
			
		||||
    promises.push(
 | 
			
		||||
      admin
 | 
			
		||||
        .firestore()
 | 
			
		||||
        .doc(`product/${row.id}`)
 | 
			
		||||
        .get()
 | 
			
		||||
    )
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  let products = await Promise.all(promises);
 | 
			
		||||
  req.transactions[0].item_list.items = products.map((row, i) => {
 | 
			
		||||
    return {name: row.name, sku: row.name, price: row.price, currency: 'CAD', quantity: cart[i].quantity};
 | 
			
		||||
  });
 | 
			
		||||
  req.transactions[0].amount.total = products.reduce((acc, row, i) => acc + row.price * cart[i].quantity, 0);
 | 
			
		||||
 | 
			
		||||
  // Send request to PayPal
 | 
			
		||||
  let create = new Promise((res, rej) => {
 | 
			
		||||
    paypal.payment.create(req, (error, payment) => {
 | 
			
		||||
      if (error) rej(error);
 | 
			
		||||
 | 
			
		||||
      let link = payment.links.filter(row => row.rel == 'approval_url').map(row => row.href)[0];
 | 
			
		||||
 | 
			
		||||
      if (link) {
 | 
			
		||||
        res(link);
 | 
			
		||||
      } else {
 | 
			
		||||
        rej('no redirect URI present');
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  try {
 | 
			
		||||
    response.send(await create);
 | 
			
		||||
  } catch (err) {
 | 
			
		||||
    console.error(err);
 | 
			
		||||
    response.status(500);
 | 
			
		||||
  }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
exports.process = functions.https.onRequest((req, res) => {
 | 
			
		||||
  const paymentId = req.query.paymentId;
 | 
			
		||||
  const payerId = {
 | 
			
		||||
    payer_id: req.query.PayerID
 | 
			
		||||
  };
 | 
			
		||||
  return paypal.payment
 | 
			
		||||
    .execute(paymentId, payerId, (error, payment) => {
 | 
			
		||||
      if (error) {
 | 
			
		||||
        console.error(error);
 | 
			
		||||
        res.redirect(`${req.protocol}://${req.get('host')}/error`); // replace with your url page error
 | 
			
		||||
      } else {
 | 
			
		||||
        if (payment.state === 'approved') {
 | 
			
		||||
          console.info('payment completed successfully, description: ', payment.transactions[0].description);
 | 
			
		||||
          // console.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 {
 | 
			
		||||
          console.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`
 | 
			
		||||
          );
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    })
 | 
			
		||||
    .then(r => console.info('promise: ', r));
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -484,6 +484,10 @@ braces@^2.3.1:
 | 
			
		||||
    split-string "^3.0.2"
 | 
			
		||||
    to-regex "^3.0.1"
 | 
			
		||||
 | 
			
		||||
buffer-crc32@^0.2.3:
 | 
			
		||||
  version "0.2.13"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242"
 | 
			
		||||
 | 
			
		||||
buffer-equal-constant-time@1.0.1:
 | 
			
		||||
  version "1.0.1"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819"
 | 
			
		||||
@@ -1936,6 +1940,13 @@ path-type@^3.0.0:
 | 
			
		||||
  dependencies:
 | 
			
		||||
    pify "^3.0.0"
 | 
			
		||||
 | 
			
		||||
paypal-rest-sdk@^1.8.1:
 | 
			
		||||
  version "1.8.1"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/paypal-rest-sdk/-/paypal-rest-sdk-1.8.1.tgz#5023fd42f43da628d18cc00d6bd566eacba74528"
 | 
			
		||||
  dependencies:
 | 
			
		||||
    buffer-crc32 "^0.2.3"
 | 
			
		||||
    semver "^5.0.3"
 | 
			
		||||
 | 
			
		||||
performance-now@^2.1.0:
 | 
			
		||||
  version "2.1.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
 | 
			
		||||
@@ -2235,7 +2246,7 @@ sax@^1.2.4:
 | 
			
		||||
  version "1.2.4"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
 | 
			
		||||
 | 
			
		||||
semver@^5.3.0:
 | 
			
		||||
semver@^5.0.3, semver@^5.3.0:
 | 
			
		||||
  version "5.5.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab"
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user