Download the PHP package scanandpay/php without Composer

On this page you can find all versions of the php package scanandpay/php. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package php

scanandpay/php

Official PHP SDK for Scan & Pay — generate PayTo PayID QR codes and payment links from any PHP backend (Laravel, Symfony, Magento, plain PHP, …), then react to our signed webhook when a payment is confirmed. No WordPress or framework required.

Your backend mints a session, we run the payment surface, our webhook confirms back to you.

How the pieces fit

You never handle funds, banking credentials, or PayID resolution — the SDK generates the link, the customer pays on our hosted surface, and you receive a verified webhook telling you the order is paid.

Install

Requires PHP 8.1+ with the curl, json, and hash extensions.

Quickstart

Amount format

amount is always float dollars (e.g. 19.90 for $19.90). This matches the Scan & Pay API directly — no multiplication or division needed.

For display, use $session->amount directly:

Metadata

Attach a free-form key/value bag to any session. We echo it back unchanged in the webhook payload + getStatus response, so you can correlate the payment with your own order/customer/cart records.

Limits: max 50 keys, max 500 chars per key + value (validated client-side before any network call). Don't put secrets here — metadata isn't encrypted at rest in any special way.

API versioning

The SDK pins itself to a date-stamped API contract via the Scanpay-Version header (e.g. 2026-05-07). When we evolve the wire format, your already-installed SDK keeps running against the contract it was built for. Upgrade at your own pace.

Idempotency

Every createSession call sends an Idempotency-Key header. The SDK generates a UUIDv7 by default; pass your own to make retries safe across process restarts.

Retries

Transient failures (5xx, network) are retried 3× with exponential backoff and full-half jitter (≈250 → 500 → 1000ms). 4xx responses surface immediately. POSTs retry only when an Idempotency-Key header is present — the SDK auto-sends one for createSession so this is transparent for the standard path.

Tune by injecting a configured HttpClient:

Webhook secret rotation

Rotate the merchant webhook secret in the dashboard; the SDK accepts both the new and old values during the 30-day grace window:

WebhookVerifier::verify() tries current first, falls back to previous, then throws WebhookSignatureException.

Errors

All thrown errors extend ScanAndPay\Exceptions\ScanAndPayException. HTTP-status-mapped subclasses extend ApiException:

Class HTTP Surfaces when
ValidationException Bad input rejected before any HTTP call
AuthenticationException 401 API rejected X-Scanpay-Key
AuthorizationException 403 Key valid, action not permitted
NotFoundException 404 Session/merchant doesn't exist
IdempotencyConflictException 409 Key in flight or reused with different body
RateLimitException 429 Exhausted rate limit (no retry on 4xx)
ApiException other 4xx 400, 405, 422, … (no retry)
ServerException 5xx After retries exhausted
NetworkException Transport failure after retries exhausted
WebhookSignatureException Webhook signature/timestamp/replay check failed

Credentials

Sign in to the merchant dashboard at business.scanandpay.com.au, open Settings → Integrations, and copy:

Store them in environment variables — never commit them to source control.

Production integration checklist

Use the SDK from your backend only. Your frontend can display the returned payment URL or QR widget, but it must never receive the API Secret or Webhook Secret.

  1. Create your local order first. Store the cart, customer, amount, currency, and a durable platformOrderId in your own database with a pending payment status.
  2. Create one Scan & Pay session for that order. Call $client->createSession() from your backend using the same platformOrderId. Pass an idempotency key based on your order id if the request may be retried by a queue worker, PHP-FPM retry, or browser refresh.
  3. Render the payment step as pending. Show the returned payment session to the customer with scanandpay_checkout(), your own QR renderer, or a redirect to the returned pay URL. Do not send the customer to a success page yet.
  4. Expose a small status endpoint. If you use scanandpay_checkout(), point pollUrl at your own backend endpoint. That endpoint should fetch status with the SDK and return only the public status fields your UI needs.
  5. Verify the webhook on raw request bytes. Use $client->webhooks()->verify($signature, $rawBody) before trusting any webhook payload. A parsed or re-serialized body will fail signature verification.
  6. React to our payment confirmation webhook. Treat $event->isPaid() as the signal to mark your order paid in your own database. The Place Order click and QR render only mean payment has started — money has not moved until the webhook arrives.
  7. Keep test and live credentials separate. Use environment variables or your secret manager, and never commit merchant credentials into source control, frontend bundles, mobile apps, logs, screenshots, or support tickets.

Safe to share publicly: package install commands, SDK method names, request/response fields, webhook verification rules, idempotency guidance, test-mode behaviour, and error handling. Keep your database schema, internal routes, cloud project names, merchant secrets, and admin tooling private.

Integration pitfalls

Things that bite first-time integrators (we've hit each one ourselves):

  1. Create the order BEFORE minting the session. The session binds to your platformOrderId and the webhook references the same id when the payment is confirmed. Persist the order in your DB (status pending) first, then call $client->createSession([...]).
  2. Don't finalise the order on Place Order. A common pattern in checkout code (WooCommerce included) is a hardcoded list — "if this gateway is stripe / paypal / etc. defer; otherwise finalise immediately". If that list is missing scanandpay, the checkout flashes a success screen and the QR widget never renders. Always treat Scan & Pay as a deferred / async-confirmation gateway, just like Stripe Checkout or PayPal — the customer needs to see the QR and complete the scan-and-pay in their banking app before the order can be considered paid.
  3. Webhook is the source of truth. Mark the order paid only when the verified webhook arrives with $event->isPaid() (or event.status === 'confirmed' if you're inspecting the raw payload). The Place Order click on your site does NOT mean money has moved.

Documentation

Local development

Versioning

SemVer. Pre-1.0 — expect minor breaking changes between versions until 1.0.

Licence

Apache-2.0.


All versions of php with dependencies

PHP Build Version
Package Version
Requires php Version ^8.1
ext-curl Version *
ext-json Version *
ext-hash Version *
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package scanandpay/php contains the following files

Loading the files please wait ...