Quick Pay Checkout works with Sandbox Credentials... But Not Production Credentials

I’m using the Quick Pay Checkout API, and it works from start to finish when using my Sandbox Access token and Sandbox Location ID. The payment link opens the “Checkout API Sandbox Testing Panel” as follows…

(1) Overview: I then click Next
(2) Test Payment: I then click Test Payment
(3) Checkout Complete: it says “your test payment was successful.

I can then see these test transactions in my Sandbox test account under “Transactions”. Also, if I click “Preview Checkout”, the card details payment page appears as it should do.

Screenshots available if you think that could help? I’m also happy for you to log in to my account to see what you can find.

At this stage I’m feeling pretty excited, ready to go live, and so in my code I replaced the Sandbox Access token with the Production Access token, and I replaced the Sandbox Location ID with the Production Location ID, but I then get the following…

{ "errors": [ { "category": "AUTHENTICATION_ERROR", "code": "UNAUTHORIZED", "detail": "This request could not be authorized." } ] }

Please can you advise what I can try? Needless to say when I change my Access token and Location ID back to Sandbox, it works perfectly again.

Is it just the changing of the Access token and Location ID that’s required? Or am I missing something?

Here’s my code but I suspect that’s probably not the cause…

include 'basket_class_definition.php';

session_start();

$access_token="Production_Access_Token"; // Production Token
//$access_token="Sandbox_Access_Token"; // Sandbox Token

$curl = curl_init();

curl_setopt($curl, CURLOPT_URL, "https://connect.squareupsandbox.com/v2/online-checkout/payment-links");
curl_setopt($curl, CURLOPT_POST, "true");
curl_setopt($curl, CURLOPT_HTTPHEADER, array('authorization: Bearer ' . $access_token, 'content-type: application/json', 'Square-Version: 2025-06-18'));
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);

$payment_as_integer = (int)($_SESSION['checkout_costs']->grand_total * 100);

$unique_value = uniqid();

$body = array(
  "idempotency_key" => $unique_value,
  "quick_pay" => array(
  "name" => "Test Order", "price_money" => array(
  "amount" => $payment_as_integer, "currency" => "GBP"),
  "location_id" => "Production_Location_ID")
);
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($body));

$response = curl_exec($curl);
curl_close($curl);
echo "$response";

Thank you, Gary.

:waving_hand: I’m Square Dev AI, here to help answer your question!
Based on the information you’ve provided, the following documentation will help answer your question:

Additional Documentation

Test Authorization with Web Server
Sandbox Payments
Square Sandbox

If this documentation helped you find a solution, please check the box indicating that this reply solves the problem.
Otherwise one of our Developer Advocates will provide additional assistance shortly.

The issue you’re encountering is likely due to the use of the incorrect base URL for production requests. When switching from the Sandbox to the Production environment, you need to change the base URL from https://connect.squareupsandbox.com to https://connect.squareup.com.

Here are the steps you should follow to resolve the issue:

  1. Update the Base URL: Change the base URL in your cURL request from https://connect.squareupsandbox.com/v2/online-checkout/payment-links to https://connect.squareup.com/v2/online-checkout/payment-links.

  2. Use Production Credentials: Ensure that you are using the correct Production Access Token and Production Location ID. Double-check these values in your Square Developer Dashboard under the production settings for your application.

  3. Verify Permissions: Make sure that your production application has the necessary permissions enabled to perform the actions you’re trying to execute. This can be checked in the OAuth permissions section of your application settings.

  4. Check API Version: Ensure that the Square-Version header is set to a valid API version that is supported in production.

By making these adjustments, your requests should be properly authenticated in the production environment. If you continue to experience issues, double-check that all credentials and settings are correctly configured for production use.

This answer was reviewed by @Bryan-Square.

Square-Dev-AI you are correct! I.e. the base URL I was using is incorrect.

It’s now working for production via curl functions, so thank you, even though you’re a bot :star_struck:

For anyone interested in using -X POST bash code like shown in Square Explorer, but you don’t have shell_exec() enabled, see post 9 just here: HTTPS via curl_init() versus HTTPS via -X POST - Questions - Square Developer Forums