Hey you there… yeah you - thanks for taking the time to read this. I sincerely appreciate you.
I work with a few hundred small businesses whose websites are hosted on a custom legacy PHP platform. One of them has requested that we provide Square support for website payments, and I’m sure we’ll have more.
Most of the sites currently use USAePay, Authorize.net, and similar payment gateways where all of the action happens server-side. Where I’ve run into trouble with Square is that it’s unclear to me what credentials our clients will need to provide to our application.
For development, I have an APPLICATION_ID and a LOCATION_ID that are married together and belong to a single account. These work for now, but it doesn’t seem correct that we’d ask our clients to create an application within their account and provide us with the APPLICATION_ID. They can’t use our APPLICATION_ID though because it won’t work with their LOCATION_ID.
I see other posters that were referred to the OAuth docs, is that our path forward? The problem that creates for us is that it seems we must add a REDIRECT_URL to our account as an application provider. In our case, that REDIRECT_URL would be hosted on the client’s website and thus a different domain name each time. This implementation would send us down a path of creating a standalone service to manage these.
Is there a method we can use where our clients would log into their Square account and copy a key and/or secret and provide them to us one time? Or is OAuth our only path forward for accepting credit card payments for many client websites?
Thanks again for your time and expertise!
OAuth is definitely our recommended path forward. It isn’t ideal to ask each seller to create an application for their account.
Thanks Bryan!
For anyone else who stumbles on this post, one really important detail that took me some digging to find is that you can specify the REDIRECT_URL dynamically when you whisk your user away to the authorization URL in which they agree to your application’s access to their Square account.
This means that if your application exists on many domains, you can redirect each user back to their instance of the application. See here: https://developer.squareup.com/docs/oauth-api/create-urls-for-square-authorization#create-the-authorization-url
It seems I spoke too soon… the “redirect_uri” parameter in the authorization URL must exactly match what’s been specified in your account within the developer dashboard… this essentially makes the parameter useless. It can only give Square the same URL, and the URL must also be set in the account or the OAuth redirect fails.
@Bryan-Square - what purpose does the redirect_uri even serve?
Thanks again for your help @Bryan-Square. Looking at other posts, it seems that the <redirect_uri> parameter was changed to require an exact match within the past year. This seems like a silly choice for Square to have made. That parameter has a distinct purpose - for those who need to redirect their users dynamically (e.g. many websites using the same Square integration).
If Square’s developers determined that this parameter created a security vulnerability, they should have just removed it from existence. Keeping it in the docs but not mentioning that it provides no value is confusing.
Another poster (New OAuth redirect_url requirement for static URI) has solved their “multi-domain multi-tenancy” application problem by sticking their tenant information into the CSRF token, redirecting to one canonical service URL, then redirecting again from their service URL to their tenant based on the information that was shoved into the CSRF token. I suppose I’ll go that same route, but it’d be good to understand the rationale behind Square’s choice in this matter.
And for posterity’s sake, this parameter was likely dishonored because it indeed creates a vulnerability, see here: https://sec.okta.com/articles/2021/02/stealing-oauth-tokens-open-redirects
My recommendation to Square is the following:
- Remove the <redirect_uri> parameter from your documentation altogether and completely disregard it in your implementation (instead of throwing an error during OAuth that it doesn’t match what’s set in the account). Simply redirect to the Redirect URL set within the account, throw an error if it’s not set.
- Provide an additional parameter for multi-tenant applications (perhaps called “tenant_id”) that will also be passed back to the server hosting the Redirect URL so that it can determine which tenant is being authorized. This will prevent future developers from having to concoct their own solution by embedding the tenant information within the CSRF.
- Document for future developers of multi-tenant applications how this process can be made to work… that they must host a service for Redirect URL, and that service should verify the validity of the tenant_id and if necessary, redirect to that tenant’s domain.
We’re constantly working to improve our features based on feedback like this, so I’ll be sure to share your request to the API product team.
Thanks Bryan. Another option that could be helpful would be an encrypted redirect_uri parameter… encrypted via pre-shared key. This should remove the threat of open redirects.
For anyone else who stumbles on this post, one really important detail that took me some digging to find is that you can specify the REDIRECT_URL dynamically when you whisk your user away to the authorization URL in which they agree to your application’s access to their Square account.
For anyone else who stumbles on this post, one really important detail that took me some digging to find is that you can specify the REDIRECT_URL dynamically when you whisk your user away to the authorization URL in which they agree to your application’s access to their Square account.
This is not the case. You can only redirect a user to a registered redirect URL, and you cannot do this dynamically (with Square’s current implementation of OAuth 2.0).
Also, to give more reason why there is a redirect_url
parameter, is that this is part of a standard OAuth 2.0 implementation. Some OAuth implementations support the ability to register multiple redirect URLs, so you would specify in the the query param which registered redirect_url
you would are wanting to send to user to in your flow.
Square currently only supports having one registered OAuth redirect URL per application. So yes, it doesn’t quite seem as useful right now, but it is also expected by a lot of OAuth libraries to be available.