Square up checkout integration with laravel

Hello, i am new to square up and i need help on how to integrate square up checkout in a laravel project. I’ve tried to run composer require square/connect as it is in one the github accounts but seems the package has been retired, how can i go about it to integrate square up checkout in a laravel project.

:wave: At this time we don’t have an example in Laravel. 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. What issues are you running into when trying to integrate the Web Payments SDK? :slightly_smiling_face:

1 Like

OK thanks…

what about integrating it with php ?

I’ve tried but i kept on getting these error

https://pci-connect.squareupsandbox.com/payments/mtx/v2
[HTTP/2 204 No Content 305ms]

JSON.parse: unexpected character at line 1 column 1 of the JSON data

codes:

card.php

<!DOCTYPE html>
<html>
  <head>
    <link href="css/app.css" rel="stylesheet" />
    <script
      type="text/javascript"
      src="https://sandbox.web.squarecdn.com/v1/square.js"
    ></script>
    <script>
      const appId = 'sandbox-sq0idb-HYFzDWQRnqfkLWj2o-h-GA';
      const locationId = 'L131SXP8EWFDE';

      async function initializeCard(payments) {
        const card = await payments.card();
        await card.attach('#card-container');

        return card;
      }

      async function createPayment(token) {
        const body = JSON.stringify({
          locationId,
          sourceId: token,
        });

        const paymentResponse = await fetch('payment-process.php', {
          method: 'POST',
          headers: {
            // 'Accept': 'application/json',
            'Content-Type': 'application/json',
          },
          body,
        });

        if (paymentResponse.ok) {
          return paymentResponse.json();
        }

        const errorBody = await paymentResponse.text();
        throw new Error(errorBody);
      }

      async function tokenize(paymentMethod) {
        const tokenResult = await paymentMethod.tokenize();
        if (tokenResult.status === 'OK') {
          return tokenResult.token;
        } else {
          let errorMessage = `Tokenization failed with status: ${tokenResult.status}`;
          if (tokenResult.errors) {
            errorMessage += ` and errors: ${JSON.stringify(
              tokenResult.errors
            )}`;
          }

          throw new Error(errorMessage);
        }
      }

      // status is either SUCCESS or FAILURE;
      function displayPaymentResults(status) {
        const statusContainer = document.getElementById(
          'payment-status-container'
        );
        if (status === 'SUCCESS') {
          statusContainer.classList.remove('is-failure');
          statusContainer.classList.add('is-success');
        } else {
          statusContainer.classList.remove('is-success');
          statusContainer.classList.add('is-failure');
        }

        statusContainer.style.visibility = 'visible';
      }

      document.addEventListener('DOMContentLoaded', async function () {
        if (!window.Square) {
          throw new Error('Square.js failed to load properly');
        }

        let payments;
        try {
          payments = window.Square.payments(appId, locationId);
        } catch {
          const statusContainer = document.getElementById(
            'payment-status-container'
          );
          statusContainer.className = 'missing-credentials';
          statusContainer.style.visibility = 'visible';
          return;
        }

        let card;
        try {
          card = await initializeCard(payments);
        } catch (e) {
          console.error('Initializing Card failed', e);
          return;
        }

        // Checkpoint 2.
        async function handlePaymentMethodSubmission(event, paymentMethod) {
          event.preventDefault();

          try {
            // disable the submit button as we await tokenization and make a payment request.
            cardButton.disabled = true;
            const token = await tokenize(paymentMethod);
            const paymentResults = await createPayment(token);
            displayPaymentResults('SUCCESS');

            console.debug('Payment Success', paymentResults);
          } catch (e) {
            cardButton.disabled = false;
            displayPaymentResults('FAILURE');
            console.error(e.message);
          }
        }

        const cardButton = document.getElementById('card-button');
        cardButton.addEventListener('click', async function (event) {
          await handlePaymentMethodSubmission(event, card);
        });
      });
    </script>
  </head>
  <body>
    <form id="payment-form">
      <div id="card-container"></div>
      <button id="card-button" type="button">Pay $1.00</button>
    </form>
    <div id="payment-status-container"></div>
  </body>
</html>

payment-process.php

<?php

require 'square/square-php-sdk/example-autoload.php';

use Square\SquareClient;
use Square\LocationsApi;
use Square\Exceptions\ApiException;
use Square\Http\ApiResponse;
use Square\Models\ListLocationsResponse;
use Square\Models\Money;
use Square\Models\CreatePaymentRequest;
use Square\Models\createPayment;
use Square\Environment;

$data = json_decode(file_get_contents('php://input'), true);

$square_client = new SquareClient([
    'accesstToken' => 'ACCESS_TOKEN',
    'environment' => Environment::SANDBOX,
]);

$payments_api = $square_client->getPaymentsApi();

$money = new Money();
$money->setAmount(100);
// Set currency to the currency for the location
$money->setCurrency("USD");

// 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.

$orderId = rand(9000, 1000);
$create_payment_request = new CreatePaymentRequest($data['sourceId'], $orderId, $money);

$response = $payments_api->createPayment($create_payment_request);

if ($response->isSuccess()) {
  echo json_encode($response->getResult());
} else {
  echo json_encode($response->getErrors());
}

?>

i await your response. thanks

If you remove $orderId from the payment request does it work as expected? It looks like you’re generating a random order_id instead of using the one that we generate when calling CreateOrder. :slightly_smiling_face:

Still showing the same error…

i think the response should be 200 OK, why is it giving 204 no content ?

i would appreciate it, if you can give or recommend an example of how to integrate it with HTML and JavaScript not Node.Js or with HTML and PHP.

Did you succeed in implementing using Laravel? I have been trying to do it from couple of weeks and I feel lost and no progress.

No, not yet.

I’ve went through the documentation many times still the same result. Maybe there is no solution to it for now.

Is the 204 error a Square error that you’re getting back? :slightly_smiling_face:

Yes and think the response should be 200 OK

So the payment was successful? :slightly_smiling_face:

No.

i would appreciate it, if you can give or recommend an example of how to integrate it with HTML and JavaScript not Node.Js or with HTML and PHP.

We have examples in other supported languages like PHP. :slightly_smiling_face:

The ones I’ve tried kept on giving the same error, if you don’t mind, can you recommend another PHP examples

Hi @Psimon, we don’t have any other example projects that implement payments for PHP at this time.

Hello @Psimon ,
Did you manage to solve it?
If so, can you please help me. I feel so confused on how to integrate as it does not have straight methods as we do in paypal/stripe integration.

@Brandt7658 did you manage to integrate this?
My code is given below. I am facing issue in integration, am i doing something wrong?
Can you please help me out. The square.js does not load and form also does not show any fields such as Card, CVV and expiry date.

@extends('frontend.layouts.master')

@section('title')
<title>
    {{ env('APP_NAME') }} | Checkout
</title>
@endsection

@section('content')
<form id="payment-form">
    <div id="card-container"></div>
    <button id="card-button" type="button">Pay $1.00</button>
</form>
<div id="payment-status-container"></div>
<script type="text/javascript" src="https://web.squarecdn.com/v1/square.js"></script>
<script>
    const appId = '{{ env("SANDBOX_APP_ID") }}';
    const locationId = '{{ env("LOCATION_ID") }}';

    async function initializeCard(payments) {
        const card = await payments.card();
        await card.attach('#card-container');

        return card;
    }

    async function createPayment(token) {
        const body = JSON.stringify({
            locationId,
            sourceId: token,
        });

        const paymentResponse = await fetch(
            "{{ route('square.store') }}", {
                method: 'POST',
                headers: {
                    // 'Accept': 'application/json',
                    'Content-Type': 'application/json',
                },
                body,
            });

        if (paymentResponse.ok) {
            return paymentResponse.json();
        }

        const errorBody = await paymentResponse.text();
        throw new Error(errorBody);
    }

    async function tokenize(paymentMethod) {
        const tokenResult = await paymentMethod.tokenize();
        if (tokenResult.status === 'OK') {
            return tokenResult.token;
        } else {
            let errorMessage = `Tokenization failed with status: ${tokenResult.status}`;
            if (tokenResult.errors) {
                errorMessage += ` and errors: ${JSON.stringify(
              tokenResult.errors
            )}`;
            }

            throw new Error(errorMessage);
        }
    }

    // status is either SUCCESS or FAILURE;
    function displayPaymentResults(status) {
        const statusContainer = document.getElementById(
            'payment-status-container'
        );
        if (status === 'SUCCESS') {
            statusContainer.classList.remove('is-failure');
            statusContainer.classList.add('is-success');
        } else {
            statusContainer.classList.remove('is-success');
            statusContainer.classList.add('is-failure');
        }

        statusContainer.style.visibility = 'visible';
    }

    document.addEventListener('DOMContentLoaded', async function() {
        if (!window.Square) {
            throw new Error('Square.js failed to load properly');
        }

        let payments;
        try {
            payments = window.Square.payments(appId, locationId);
        } catch {
            const statusContainer = document.getElementById(
                'payment-status-container'
            );
            statusContainer.className = 'missing-credentials';
            statusContainer.style.visibility = 'visible';
            return;
        }

        let card;
        try {
            card = await initializeCard(payments);
        } catch (e) {
            console.error('Initializing Card failed', e);
            return;
        }

        // Checkpoint 2.
        async function handlePaymentMethodSubmission(event, paymentMethod) {
            event.preventDefault();

            try {
                // disable the submit button as we await tokenization and make a payment request.
                cardButton.disabled = true;
                const token = await tokenize(paymentMethod);
                const paymentResults = await createPayment(token);
                displayPaymentResults('SUCCESS');

                console.debug('Payment Success', paymentResults);
            } catch (e) {
                cardButton.disabled = false;
                displayPaymentResults('FAILURE');
                console.error(e.message);
            }
        }

        const cardButton = document.getElementById('card-button');
        cardButton.addEventListener('click', async function(event) {
            await handlePaymentMethodSubmission(event, card);
        });
    });
</script>
@endsection

Are you using localhost or HTTPS when trying to load the form? :slightly_smiling_face: