AppID sandbox-sq0idb-fPhWF8SVrMcRSyoVuTHMmQ
The process-card.php script fails and it seems the first error is here:
$currency = $client->getLocationsApi()->retrieveLocation(env(‘SQUARE_LOCATION_ID’))->getResult()->getLocation()->getCurrency();
(locationID is being successfully retrieved from the .env file).
I have no idea what the following errors in plesk logs mean and would appreciate your assistance, please.
<?php
require 'vendor/autoload.php';
use Square\SquareClient;
use Square\Environment;
use function Prinx\Dotenv\env;
// use the loadEnv function
use function Prinx\Dotenv\loadEnv;
// Load the specific env file
$env_path = __DIR__ . '/.env';
loadEnv($env_path);
$db_host = env('DB_HOST');
$db_user = env('DB_USER');
$db_name = env('DB_NAME');
$db_password = env('DB_PASS');
$square_application_id = env('SQUARE_APPLICATION_ID');
$square_access_token = env('SQUARE_ACCESS_TOKEN');
$square_location_id = env('SQUARE_LOCATION_ID');
$environment = env('ENVIRONMENT');
// Pulled from the .env file and upper cased e.g. SANDBOX, PRODUCTION.
$upper_case_environment = strtoupper($environment);
$full_environment_string = "Environment::$upper_case_environment";
$client = new SquareClient([
'accessToken' => '$square_access_token',
'environment' => '$upper_case_environment'
]);
?>
<html>
<head>
<title>My Payment Form</title>
<!-- link to the SqPaymentForm library -->
<script type="text/javascript" src=
<?php
echo "\"";
echo ( $environment === 'PRODUCTION' ) ? "https://js.squareup.com/v2/paymentform"
: "https://js.squareupsandbox.com/v2/paymentform";
echo "\"";
?>
></script>
<script type="text/javascript">
window.applicationId =
<?php
echo "\"";
echo env('SQUARE_APPLICATION_ID');
echo "\"";
?>;
window.locationId =
<?php
echo "\"";
echo env('SQUARE_LOCATION_ID');
echo "\"";
?>;
</script>
<!-- link to the local SqPaymentForm initialization -->
<script type="text/javascript" src="https://cdn.jsdelivr.net/gh/square/connect-api-examples/templates/web-ui/payment-form/custom/sq-payment-form.js"></script>
<!-- link to the custom styles for SqPaymentForm -->
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/square/connect-api-examples/templates/web-ui/payment-form/custom/sq-payment-form.css">
</head>
<body>
<!-- Begin Payment Form -->
<div class="sq-payment-form">
<!--
Square's JS will automatically hide these buttons if they are unsupported
by the current device.
-->
<div id="sq-walletbox">
<button id="sq-google-pay" class="button-google-pay"></button>
<button id="sq-apple-pay" class="sq-apple-pay"></button>
<button id="sq-masterpass" class="sq-masterpass"></button>
<div class="sq-wallet-divider">
<span class="sq-wallet-divider__text">Or</span>
</div>
</div>
<div id="sq-ccbox">
<!--
You should replace the action attribute of the form with the path of
the URL you want to POST the nonce to (for example, "/process-card").
You need to then make a "Charge" request to Square's Payments API with
this nonce to securely charge the customer.
Learn more about how to setup the server component of the payment form here:
https://developer.squareup.com/docs/payments-api/overview
-->
<!-- The 109 on the form path is for testing an orderId
We know an orderId that is valid and we want to test with it.
Later, we'll add a query to get the orderId or insert this form in a page which knows the orderId. -->
<form id="nonce-form" novalidate action="/square-payment-gateway/phpsdk-integration/process-card.php/109" method="post">
<div class="sq-field">
<label class="sq-label">Card Number</label>
<div id="sq-card-number"></div>
</div>
<div class="sq-field-wrapper">
<div class="sq-field sq-field--in-wrapper">
<label class="sq-label">CVV</label>
<div id="sq-cvv"></div>
</div>
<div class="sq-field sq-field--in-wrapper">
<label class="sq-label">Expiration</label>
<div id="sq-expiration-date"></div>
</div>
<div class="sq-field sq-field--in-wrapper">
<label class="sq-label">Postal</label>
<div id="sq-postal-code"></div>
</div>
</div>
<div class="sq-field">
<button id="sq-creditcard" class="sq-button" onclick="onGetCardNonce(event)">
Make Payment
</button>
</div>
<!--
After a nonce is generated it will be assigned to this hidden input field.
-->
<div id="error"></div>
<input type="hidden" id="card-nonce" name="nonce">
</form>
</div>
</div>
<!-- End Payment Form -->
</body>
</html>
It looks like you aren’t passing the variables, and you’re passing literal strings. The line it references is attempting to pull the server_url for the environment, but given that’s an invalid environment you’re passing, it will fail and return null. I imagine you want to do this instead:
Are you seeing a different error, now? I won’t be able to see anything on Square’s end based on the above errors; those are all client-side before it hits Square’s servers. My suggestion should’ve resolved your original error, but it sounds like you’re seeing a different error, now? Can you clarify what you mean by the nonce is not being sent?
That’s why I think the nonce is not being passed from index.php.
This is the process-payment.php script.
<?php
require 'vendor/autoload.php';
use Square\Models\Money;
use Square\Models\CreatePaymentRequest;
use Square\Exceptions\ApiException;
use Square\SquareClient;
use function Prinx\Dotenv\env;
// use the loadEnv function
use function Prinx\Dotenv\loadEnv;
// Load the specific env file
$env_path = __DIR__ . '/.env';
loadEnv($env_path);
echo "<pre>dumping=";
var_dump($_POST);
echo "</pre>";
// The access token to use in all Connect API requests.
// Set your environment as *sandbox* if you're just testing things out.
$access_token = env('SQUARE_ACCESS_TOKEN');
$environment = env('ENVIRONMENT');
$square_location_id = env('SQUARE_LOCATION_ID');
$upper_case_environment = strtoupper($environment);
// Initialize the Square client.
$client = new SquareClient([
'accessToken' => $access_token,
'environment' => $upper_case_environment
]);
// Helps ensure this code has been reached via form submission
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
error_log('Received a non-POST request');
echo 'Request not allowed';
http_response_code(405);
return;
}
// Fail if the card form didn't send a value for `nonce` to the server
$nonce = $_POST['nonce'];
if (is_null($nonce)) {
echo 'Invalid card data';
http_response_code(422);
return;
}
$payments_api = $client->getPaymentsApi();
// To learn more about splitting payments with additional recipients,
// see the Payments API documentation on our [developer site]
// (https://developer.squareup.com/docs/payments-api/overview).
$money = new Money();
// Monetary amounts are specified in the smallest unit of the applicable currency.
// This amount is in cents. It's also hard-coded for $1.00, which isn't very useful.
echo "<pre>
here 1
nonce = $nonce</pre>";
$money->setAmount(100);
// Set currency to the currency for the location
$currency = $client->getLocationsApi()->retrieveLocation(env('SQUARE_LOCATION_ID'))->getResult()->getLocation()->getCurrency();
//$currency = 'GBP';
echo "here2";
$money->setCurrency($currency);
// Every payment you process with the SDK must have a unique idempotency key.
// If you're unsure whether a particular payment succeeded, you can reattempt
// it with the same idempotency key without worrying about double charging
// the buyer.
$create_payment_request = new CreatePaymentRequest($nonce, uniqid(), $money);
// The SDK throws an exception if a Connect endpoint responds with anything besides
// a 200-level HTTP code. This block catches any exceptions that occur from the request.
try {
$response = $payments_api->createPayment($create_payment_request);
// If there was an error with the request we will
// print them to the browser screen here
if ($response->isError()) {
echo 'Api response has Errors';
$errors = $response->getErrors();
echo '<ul>';
foreach ($errors as $error) {
echo '<li>❌ ' . $error->getDetail() . '</li>';
}
echo '</ul>';
exit();
}
echo '<pre>';
print_r($response);
echo '</pre>';
} catch (ApiException $e) {
echo 'Caught exception!<br/>';
echo('<strong>Response body:</strong><br/>');
echo '<pre>'; var_dump($e->getResponseBody()); echo '</pre>';
echo '<br/><strong>Context:</strong><br/>';
echo '<pre>'; var_dump($e->getContext()); echo '</pre>';
exit();
}
I took a look at our logs for your application (sandbox-sq0idb-fPhWF8SVrMcRSyoVuTHMmQ) and haven’t seen a successful call to Square to create a nonce, so it sounds like you’re not even requesting a card nonce at all, or something is breaking before that point, so it shouldn’t even be going to process-payment.php yet. How are you handling the nonce generation in your Javascript currently?
The only place in the docs I can find with a get card nonce request, is in the payment form - in the walkthrough doc. Of course, that only works with 4111 1111 1111 1111 cvv 111 etc and not the card details the SDK requires.
Here is the nonce JS i used.
function onGetCardNonce(event) {
// Don't submit the form until SqPaymentForm returns with a nonce
event.preventDefault();
// Request a nonce from the SqPaymentForm object
paymentForm.requestCardNonce();
}
Please link me to the docs which properly set out what is necessary. I have spent over a week on this because the docs are rubbish. I have integrated successfully for a different client of mine, with Stripe in less than half a day. This client wants to stay with Square but my time costs may affect that decision.
Correct, you can only generate a nonce using either the Square Payment Form (web) or In-App Payments SDK (which is basically a mobile payment form). Since my last comment, I do see that you were able to generate three nonces successfully, so it sounds like progress was made. However, I do not see a follow up CreatePayment call, so something went wrong prior to this call.
Can you confirm what happened after generating the nonces? If anything is preventing the CreatePayment call, it would be happening on your side since I am not seeing any server logs, so I do not know what went wrong.
I’m having similar issues concerning SDK implementation. So far, I’m running it all on localhost host. Everything is setup and running, but here is the error:
Notice : Undefined offset: 0 in C:\xampp\htdocs\perzsi.com\dashboard\payment\vendor\square\square\src\SquareClient.php on line 176
Notice : Trying to access array offset on value of type null in C:\xampp\htdocs\perzsi.com\dashboard\payment\vendor\square\square\src\SquareClient.php on line 176
Fatal error : Uncaught TypeError: Argument 1 passed to Square\ApiHelper::appendUrlWithTemplateParameters() must be of the type string, null given, called in C:\xampp\htdocs\perzsi.com\dashboard\payment\vendor\square\square\src\SquareClient.php on line 180 and defined in C:\xampp\htdocs\perzsi.com\dashboard\payment\vendor\square\square\src\ApiHelper.php:25 Stack trace: #0 C:\xampp\htdocs\perzsi.com\dashboard\payment\vendor\square\square\src\SquareClient.php(180): Square\ApiHelper::appendUrlWithTemplateParameters(NULL, Array, false) #1 C:\xampp\htdocs\perzsi.com\dashboard\payment\vendor\square\square\src\Apis\LocationsApi.php(184): Square\SquareClient->getBaseUri() #2 C:\xampp\htdocs\perzsi.com\dashboard\payment\utils\location-info.php(31): Square\Apis\LocationsApi->retrieveLocation(‘’) #3 C:\xampp\htdocs\perzsi.com\dashboard\payment\utils\location-info.php(50): LocationInfo->__construct() #4 C:\xampp\htdocs\perzsi.com\dashboard\payment\process-card.php(6): include(‘C:\xampp\htdocs…’) #5 {main} thrown in C:\xampp\htdocs\perzsi.com\dashboard\payment\vendor\square\square\src\ApiHelper.php on line 25