Integrate with the PHP Checkout SDK
Learn how to integrate ICEPAY Checkout in a PHP application using the official Checkout SDK.
The ICEPAY Checkout SDK provides a PHP interface around the Checkout API. It handles HTTP communication, maps API responses to PHP models, provides consistent exception handling, and includes a postback handler for verifying payment status notifications.
This guide walks through a complete integration, from installing the SDK and creating a payment to handling postbacks, retrieving payments, issuing refunds, and forwarding funds.
How the SDK fits into your integration
Section titled “How the SDK fits into your integration”The SDK runs in your backend application and communicates with the ICEPAY Checkout API for you.
-
Create a checkout request
Build the payment using the SDK’s request and amount models.
-
Send the payment to ICEPAY
Call
createCheckout()on theCheckoutClient. -
Redirect the customer
ICEPAY returns a checkout URL through the response model. Redirect the customer to that URL.
-
Handle payment updates
Use the SDK’s
PostbackHandlerto verify incoming ICEPAY postbacks and parse the updated payment. -
Retrieve or manage the payment when needed
Use the same client to retrieve a payment, issue a refund, forward funds, or retrieve available payment methods.
Requirements
Section titled “Requirements”The Checkout SDK requires:
- PHP 8.1 or newer;
- Composer;
- compatible PSR HTTP client, message, and factory implementations;
- your ICEPAY Merchant ID and Merchant Secret.
The SDK does not force one specific HTTP client implementation. This means it can work with different HTTP stacks depending on your application.
Install the SDK
Section titled “Install the SDK”Install the SDK with Composer:
composer require icepay/checkout-sdkThe SDK requires implementations for the PSR HTTP interfaces it uses. If your project does not already provide compatible implementations, you can install the SDK together with Nyholm PSR-7 and Symfony HTTP Client:
composer require icepay/checkout-sdk nyholm/psr7 symfony/http-clientConfigure your credentials
Section titled “Configure your credentials”Keep your credentials outside your source code, for example as environment variables:
ICEPAY_MERCHANT_ID=your_merchant_idICEPAY_MERCHANT_SECRET=your_merchant_secretCreate the CheckoutClient and configure the credentials:
<?php
require_once 'vendor/autoload.php';
use ICEPAY\Checkout\CheckoutClient;
$merchantId = getenv('ICEPAY_MERCHANT_ID');$merchantSecret = getenv('ICEPAY_MERCHANT_SECRET');
if ($merchantId === false || $merchantSecret === false) { throw new RuntimeException('Missing ICEPAY credentials.');}
$checkoutClient = (new CheckoutClient())->withAuthorization( merchantId: $merchantId, merchantSecret: $merchantSecret,);The client uses these credentials when communicating with the ICEPAY Checkout API.
Create your first payment
Section titled “Create your first payment”A payment starts with a Checkout request model.
<?php
use ICEPAY\Checkout\Models\Amount;use ICEPAY\Checkout\Models\Request\Checkout as CheckoutRequest;
$checkoutRequest = new CheckoutRequest( reference: 'ORD-16307', description: 'Ice cream dipped in sprinkles', amount: new Amount( value: 299, currency: Amount::CURRENCY_EUR, ), redirectUrl: 'https://merchant.example.com/payment-complete', webhookUrl: 'https://merchant.example.com/payment-webhook',);
$response = $checkoutClient->createCheckout($checkoutRequest);The response is mapped to an SDK response model, so you can access the returned values as PHP properties instead of manually decoding JSON.
For example:
$paymentKey = $response->key;$checkoutUrl = $response->links->checkout;$status = $response->status->toString();Redirect the customer
Section titled “Redirect the customer”After creating the payment, redirect the customer to the returned checkout URL:
header('Location: ' . $response->links->checkout, true, 303);exit;The customer can then complete the payment on the hosted ICEPAY Checkout Page.
Understanding the amount
Section titled “Understanding the amount”The Amount model takes the amount as an integer.
For currencies with two decimal places:
| Customer-facing amount | SDK value |
|---|---|
| €0.01 | 1 |
| €2.99 | 299 |
| €10.00 | 1000 |
| €149.95 | 14995 |
For example:
$amount = new Amount( value: 299, currency: Amount::CURRENCY_EUR,);Configure the checkout request
Section titled “Configure the checkout request”The SDK’s CheckoutRequest model supports the following properties:
| Property | Type | Purpose |
|---|---|---|
reference |
string |
Your payment or order reference. |
description |
string |
Description of the payment. |
amount |
Amount |
Payment amount and currency. |
redirectUrl |
string |
URL to which the customer returns after checkout. |
webhookUrl |
string |
URL to which ICEPAY sends payment status updates. |
paymentMethod |
PaymentMethod or string |
Optionally preselect a payment method. |
metadata |
Metadata |
Additional metadata sent with the payment. |
expireAfter |
?int |
Optional payment expiration period. |
You can supply these values in the constructor or use the helper methods provided by the request model.
For example:
$checkoutRequest = new CheckoutRequest( reference: 'ORD-16307', description: 'Ice cream dipped in sprinkles', amount: new Amount(299, Amount::CURRENCY_EUR),);
$checkoutRequest ->withRedirectUrl('https://merchant.example.com/payment-complete') ->withWebhookUrl('https://merchant.example.com/payment-webhook') ->withCustomerEmail('johndoe@example.com');Add customer information
Section titled “Add customer information”For a customer email address, use:
$checkoutRequest->withCustomerEmail('johndoe@example.com');You can also provide a customer array:
$checkoutRequest->withCustomer([ 'email' => 'johndoe@example.com', 'firstName' => 'John', 'lastName' => 'Doe',]);The SDK stores this information in the request metadata before serializing the payment request.
Let the customer choose a payment method
Section titled “Let the customer choose a payment method”If you do not set paymentMethod, redirect the customer to:
$response->links->checkoutThe hosted Checkout Page can then present the available payment methods to the customer.
Preselect a payment method
Section titled “Preselect a payment method”If the customer already selected a payment method in your own checkout, include it in the request.
You can pass the payment method as a string:
$checkoutRequest = new CheckoutRequest( reference: 'ORD-16307', description: 'Ice cream dipped in sprinkles', amount: new Amount(299, Amount::CURRENCY_EUR), paymentMethod: 'ideal',);Or use the SDK’s PaymentMethod model:
use ICEPAY\Checkout\Models\PaymentMethod;
$checkoutRequest = new CheckoutRequest( reference: 'ORD-16307', description: 'Ice cream dipped in sprinkles', amount: new Amount(299, Amount::CURRENCY_EUR), paymentMethod: new PaymentMethod( type: PaymentMethod::TYPE_IDEAL, ),);When a direct payment-method URL is returned, it is available through:
$response->links->directBecause the direct link is optional, check that it is available before using it:
if ($response->links->direct !== null) { header('Location: ' . $response->links->direct, true, 303); exit;}Retrieve available payment methods
Section titled “Retrieve available payment methods”Use getPaymentMethods() to retrieve the payment methods available to the authenticated merchant:
$paymentMethods = $checkoutClient->getPaymentMethods();
foreach ($paymentMethods as $paymentMethod) { echo $paymentMethod->id; echo $paymentMethod->description;}Each item is returned as an SDK response model with properties such as:
$paymentMethod->id;$paymentMethod->description;$paymentMethod->logo;Handle payment postbacks
Section titled “Handle payment postbacks”After a payment status changes, ICEPAY sends a request to the webhookUrl supplied when you created the payment.
The SDK includes PostbackHandler, which:
- verifies the
ICEPAY-Signature; - uses your Merchant Secret for signature validation;
- parses the JSON body;
- returns the payment as an SDK
Checkoutresponse model.
This means you do not have to implement the HMAC verification yourself.
Basic PHP example
Section titled “Basic PHP example”<?php
use ICEPAY\Checkout\Exceptions\InvalidSignature;use ICEPAY\Checkout\PostbackHandler;
$merchantSecret = getenv('ICEPAY_MERCHANT_SECRET');
if ($merchantSecret === false) { throw new RuntimeException('Missing ICEPAY Merchant Secret.');}
$handler = new PostbackHandler( merchantSecret: $merchantSecret,);
$body = file_get_contents('php://input');$signature = $_SERVER['HTTP_ICEPAY_SIGNATURE'] ?? '';
try { $payment = $handler->handle($body, $signature);} catch (InvalidSignature) { http_response_code(400); return;}
$paymentKey = $payment->key;$status = $payment->status->toString();$financialStatus = $payment->financialStatus->toString();
// Update the payment in your application.Verify without parsing
Section titled “Verify without parsing”If you only need to check the authenticity of a postback:
if (!$handler->verify($body, $signature)) { http_response_code(400); return;}Using a PSR-7 request
Section titled “Using a PSR-7 request”If your framework already gives you a PSR-7 MessageInterface, the handler can read the body and signature header directly:
use ICEPAY\Checkout\Exceptions\InvalidSignature;use Psr\Http\Message\MessageInterface;
/** @var MessageInterface $request */
try { $payment = $handler->handleRequest($request);} catch (InvalidSignature) { http_response_code(400); return;}You can also use:
$handler->verifyRequest($request);when you only want to verify the request.
Retrieve a payment
Section titled “Retrieve a payment”Store the ICEPAY payment key returned when the payment is created:
$paymentKey = $response->key;You can retrieve the current payment later with:
$payment = $checkoutClient->getCheckout($paymentKey);The returned model exposes the payment state:
$payment->key;$payment->reference;$payment->amount;$payment->paymentMethod;$payment->links;
$payment->status->toString();$payment->financialStatus->toString();Payment statuses
Section titled “Payment statuses”The SDK maps the payment status to the Status enum.
Possible values handled by the SDK are:
startedpendingcompletedexpiredcancelledunknownThe separate financial status is represented by the FinancialStatus enum:
unclearedclearedunknownRefund a payment
Section titled “Refund a payment”Create a refund request using ICEPAY\Checkout\Models\Request\Refund.
use ICEPAY\Checkout\Models\Request\Refund as RefundRequest;
$refundRequest = new RefundRequest( reference: 'RFD-00069', amount: 299, description: 'Received chocolate dip instead of sprinkles',);
$refund = $checkoutClient->refund( refund: $refundRequest, checkoutId: $paymentKey,);The refund amount can be supplied as either an integer or an Amount object.
When an integer is supplied, the SDK serializes it as the request’s amount.value:
$refundRequest = new RefundRequest( reference: 'RFD-00069', amount: 299, description: null,);Forward payment funds
Section titled “Forward payment funds”The SDK exposes payment forwarding through the Forward request model.
use ICEPAY\Checkout\Models\Request\Forward as ForwardRequest;
$forwardRequest = new ForwardRequest( reference: 'FWD-00042', amount: 299, recipient: '1001', description: 'Forwarding to merchant 1001',);
$forward = $checkoutClient->forward( forward: $forwardRequest, checkoutId: $paymentKey,);The SDK accepts either a recipient ID string or a Recipient model.
When a string is supplied:
recipient: '1001'the SDK serializes it as:
{ "recipient": { "id": "1001" }}Handle SDK errors
Section titled “Handle SDK errors”All CheckoutClient operations use the same base exception:
ICEPAY\Checkout\Exceptions\ApiExceptionThis includes:
- API errors returned by ICEPAY;
- typed API exceptions;
- transport failures such as timeouts, DNS errors, or refused connections.
A general error handler can therefore catch ApiException:
use ICEPAY\Checkout\Exceptions\ApiException;
try { $response = $checkoutClient->createCheckout($checkoutRequest);} catch (ApiException $exception) { $message = $exception->getMessage(); $httpStatus = $exception->getCode(); $type = $exception->type; $errors = $exception->errors;
// Log or handle the failure.}For transport failures, the status code can be 0.
The SDK also provides more specific exception classes for particular API problems. You can catch those when your application needs different behavior for a specific error, while keeping ApiException as the general fallback.
For example:
use ICEPAY\Checkout\Exceptions\ApiException;use ICEPAY\Checkout\Exceptions\Payment\NotFound;
try { $payment = $checkoutClient->getCheckout($paymentKey);} catch (NotFound $exception) { // Handle a payment that does not exist.} catch (ApiException $exception) { // Handle any other ICEPAY or connection error.}Add integration information
Section titled “Add integration information”For platform integrations or reusable modules, the checkout request can include integration information:
$checkoutRequest->withIntegrationInformation( type: 'custom', version: '1.0.0', developer: 'Example Developer',);The SDK stores this information in the payment metadata.
This can be useful when the same ICEPAY account receives payments from different integration types or versions.
Use a custom HTTP client
Section titled “Use a custom HTTP client”For most integrations, automatic PSR implementation discovery is enough.
Advanced integrations can provide their own PSR-18 client by constructing the SDK’s HttpClient:
use ICEPAY\Checkout\CheckoutClient;use ICEPAY\Checkout\HttpClient;use Psr\Http\Client\ClientInterface;
/** @var ClientInterface $psrHttpClient */
$httpClient = new HttpClient( client: $psrHttpClient,);
$checkoutClient = (new CheckoutClient($httpClient))->withAuthorization( merchantId: $merchantId, merchantSecret: $merchantSecret,);This is useful when your application or framework already has its own HTTP transport layer.
Available client operations
Section titled “Available client operations”The main CheckoutClient operations are:
| SDK method | Purpose |
|---|---|
createCheckout($checkoutRequest) |
Create a payment. |
getCheckout($paymentKey) |
Retrieve a payment. |
getPaymentMethods() |
Retrieve available payment methods. |
refund($refundRequest, $paymentKey) |
Refund a payment. |
forward($forwardRequest, $paymentKey) |
Forward payment funds. |
These methods correspond to the Checkout API operations while keeping request creation, response mapping, and exception handling inside the SDK.
Recommended integration flow
Section titled “Recommended integration flow”For a normal PHP checkout integration:
-
Install and configure the SDK
Configure the
CheckoutClientwith your Merchant ID and Merchant Secret. -
Create the payment
Build a
CheckoutRequestwith your reference, amount, redirect URL, and webhook URL. -
Store the payment key
Save
$response->keytogether with your own order or payment record. -
Redirect the customer
Send the customer to
$response->links->checkout, or use the direct link when you deliberately preselect a supported payment method. -
Process postbacks
Use
PostbackHandler::handle()to verify and parse status updates. -
Update your own payment record
Store the returned
statusandfinancialStatusseparately. -
Use additional operations when needed
Retrieve the payment, refund it, forward funds, or retrieve available payment methods through the same
CheckoutClient.
Explore the API
Section titled “Explore the API”The SDK handles the HTTP requests and response mapping for you, but the underlying Checkout API is still useful when you need to understand the exact endpoint behavior or payload structure.

