Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Square Connect API #400

Open
philippefutureboy opened this issue May 14, 2018 · 5 comments
Open

Square Connect API #400

philippefutureboy opened this issue May 14, 2018 · 5 comments

Comments

@philippefutureboy
Copy link

Have a request for a new sample?
================================
Great, we love hearing how we can improve our samples! Remove the template below and
provide an explanation of your sample request. Be as detailed as possible.
Note that it should cover a use case that isn't similar to our existing samples and
likely to be of broad use (i.e. not just a copy/paste solution to your specialized problem).

Hi!

First of all, thanks for the looooovely suite of function samples. This is a programmer's dream! 🎉 🚀 ✨

I was wondering, do you think you could integrate the Square Connect API to your function samples? That could open up a whole slew of Point-Of-Sale applications w/ inventory and catalog management.

Let me know!

Have a wonderful day ✨

Cheers,

Philippe

@danielpowell4
Copy link

@philippefutureboy wondering how far you got along this path.

I've found this post, which seems to at least be a starting point.

If there is a more boilerplate starting point/tutorial out there in the wild, though, that's obviously better!

@philippefutureboy
Copy link
Author

@danielpowell4 We ended up reevaluating our options and go for a faster, more out-of-the-box product. Namely, used webflow and we integrated the Paypal button. While the solution did not provide the inventory management we would have liked to have, it did satisfy our need for a payment gateway on our website.

Thanks for the link :)

@danielpowell4
Copy link

danielpowell4 commented Sep 5, 2018

This is a preliminary sample for those who come next:

const functions = require("firebase-functions");
const crypto = require("crypto");
const axios = require("axios"); // be sure to add to package.json via npm install axios

exports.authorize = functions.https.onRequest((request, response) => {
  const squareAuthURL = "https://connect.squareup.com/oauth2/authorize?";
  const state = crypto.randomBytes(32).toString("hex");
  response.set("Set-Cookie", `__session=${state}; Secure`);

  response.redirect(
    squareAuthURL +
      `client_id=${functions.config().square.app_id}&` +
      `response_type=code&` +
      `scope=MERCHANT_PROFILE_READ ITEMS_READ ORDERS_READ PAYMENTS_READ&` +
      `session=false&` +
      `locale=en-US&` +
      `state=${state}`
  );
});

const getSessionCookie = cookie => {
  let name = "__session=";
  let decodedCookie = decodeURIComponent(cookie);
  let ca = decodedCookie.split(";");
  for (let c of ca) {
    while (c.charAt(0) === " ") {
      c = c.substring(1);
    }
    if (c.indexOf(name) === 0) {
      return c.substring(name.length, c.length);
    }
  }
  return "";
};

// TODO: Implement me as needed for use case!
const createOrUpdateFirebaseAccount = (userData, tokenData) => ({
  userData,
  tokenData
});

exports.callback = functions.https.onRequest((request, response) => {
  const tokenURL = "https://connect.squareup.com/oauth2/token";
  const redirectURI =
    "https://us-central1-YOUR_APP_NAME.cloudfunctions.net/callback";
  const cookieState = getSessionCookie(request.get("cookie"));

  const { code, state } = request.query;

  if (cookieState === state) {
    const { app_id, secret } = functions.config().square;
    let access_token, id, email, name;
    return axios
      .post(tokenURL, {
        client_id: app_id,
        client_secret: secret,
        code: decodeURIComponent(code),
        redirect_uri: redirectURI
      })
      .then(token => {
        ({ access_token } = token.data);
        return (
          axios
            .get("https://connect.squareup.com/v1/me", {
              headers: {
                Authorization: `Bearer ${access_token}`
              }
            })
            .then(user => {
              //  return createOrUpdateFirebaseAccount(user.data, token.data);
              return response.json({
                tokenData: token.data,
                userData: user.data
              });
            })
            // .then(firebaseToken => {
            //   return response.json({
            //     email: email,
            //     token: firebaseToken
            //   });
            // })
            .catch(error => {
              console.log(error);
              return response.send(error);
            })
        );
      });
  } else {
    console.log(`INVALID STATE: ${cookieState} === ${state}`);
    return response.send(`INVALID STATE: ${cookieState} === ${state}`);
  }
});

Be sure to set ENV configs as appropriate:

https://firebase.google.com/docs/functions/config-env

You will also need to set up the Oauth callback url inside of square

It is also best practice to encode the tokens rather than saving them directly.

This is best done via something like:

const encryptToken = accessToken => {
  const cipher = crypto.createCipher("aes192", ENCRYPT_KEY);

  let encrypted = cipher.update(accessToken, "utf8", "hex");
  encrypted += cipher.final("hex");
  return encrypted;
};

const decryptToken = accessToken => {
  const decipher = crypto.createDecipher("aes192", ENCRYPT_KEY);

  let decrypted = decipher.update(accessToken, "hex", "utf8");
  decrypted += decipher.final("utf8");
  return decrypted;
};

Beyond this be sure to checkout the pre-built postman test api suite, likely using a sandbox access_token credential in your environment

@ugenlik
Copy link

ugenlik commented Feb 24, 2020

@danielpowell4 could you share your full code, where is functions.config().square coming from?

@Klieger
Copy link

Klieger commented May 22, 2020

@danielpowell4 could you share your full code, where is functions.config().square coming from?

https://firebase.google.com/docs/functions/config-env

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
4 participants