PHPackages                             mbmjertan/keksphp - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Payment Processing](/categories/payments)
4. /
5. mbmjertan/keksphp

ActiveLibrary[Payment Processing](/categories/payments)

mbmjertan/keksphp
=================

KEKS Pay - PHP implementacija

v1.0(5y ago)17MITPHP

Since May 3Pushed 5y ago1 watchersCompare

[ Source](https://github.com/mbmjertan/keksphp)[ Packagist](https://packagist.org/packages/mbmjertan/keksphp)[ RSS](/packages/mbmjertan-keksphp/feed)WikiDiscussions master Synced 6d ago

READMEChangelog (1)Dependencies (1)Versions (2)Used By (0)

KeksPHP
=======

[](#keksphp)

KeksPHP is an implementation of the KEKS Pay API webshop backend integrations in PHP. You can use it as a reference when building your own custom implementation and it's available as a library on Composer/Packagist as well.

It's free and open source, and published under the MIT license. However, it's not built or supported by the KEKS Pay team and I can't provide any warranties for it. Use it as you wish, but your usage is your resposibility entirely.

KeksPHP only handles *the communication* with KEKS Pay. You'll still need to integrate it with your own order management, you'll still need to implement some kind of transaction logging (which KeksPHP does make easy-ish) and you'll still need to build a frontend for KEKS Pay payments.

To start integrating with KEKS Pay, you'll need to contact the KEKS Pay team first. You can find their contact info, as well as their official documentation on [the KEKS Pay website](https://kekspay.hr).

Usage
-----

[](#usage)

### Installing and autoloading

[](#installing-and-autoloading)

Install KeksPHP with Composer (or another tool of your choice). If you're using Composer, all KeksPHP classes will be available under the `KeksPHP` namespace after including autoload.php.

If you're new to Composer, please look into how to use it and come back here. You can also just download this code and integrate it into your project (but making sure you handle *this project's* dependencies as well), but Composer will make all of this easier.

If you'd really like to avoid using Composer, make sure that you autoload the classes in the `src\` folder using PSR-4 under the namespace `KeksPHP`.

### Requirements

[](#requirements)

KeksPHP is tested under PHP 8. While it may work under previous PHP versions, I can't support older versions.

You'll need the PHP JSON and OpenSSL extensions. If you're using the `KeksRefund::sumbitRefund` method, you'll also need to make sure you're able to use Guzzle. If you're using Composer, Guzzle will be automatically installed as well.

### Setting KeksSeller

[](#setting-keksseller)

All other KeksPHP classes require `KeksSeller` as a member.

KeksSeller contains your KEKS Pay configuration (CID, TID, API Base and Deep Link Base, which you'll get from the KEKS Pay team) and lets you provide functions that define how to validate the `advice` you recieve from KEKS Pay and how to build success/failure URLs for customers.

To set the CID and TID, set the cid and tid members of the class instance respectively. To set the hashKey, use the setHashKey method.

```
$KeksSeller = new \KeksPHP\KeksSeller;
$KeksSeller->cid = "C00111";
$KeksSeller->tid = "P00222";
$KeksSeller->setHashKey("SOMEHASHKEYPROVIDEDBYKEKS");
```

In production enviroments, you'll also need to change the API base and deep link base to values given by the KEKS Pay team.

If your success and failure URLs are fixed for *every* transaction, you can set the successRedirect and failRedirect members of the class instance respectively, like so:

```
$KeksSeller->successRedirect = 'https://google.com';
$KeksSeller->failRedirect = 'https://bing.com';
```

If they can change depending on transaction data, provide a closure for them like so:

```
$KeksSeller->provideSuccessRedirectFunction(function($KeksTransaction){
	// your code here
	return $successURL;
});

$KeksSeller->provideFailRedirectFunction(function($KeksTransaction){
	// your code here
	return $failURL;
});
```

The closures will be called with the corresponding KeksTransaction class instance.

You'll also need to validate the recieved advice with a function. At the very least, you need to check if the cart amount on your store matches with the amount paid via KEKS Pay. To let KeksPHP know what function to call, set a closure like so, which will be called with an instance of `\stdClass` (a generic object) built from the JSON recieved from KEKS Pay:

```
$KeksSeller->provideValidateAdviceFunction(function($KeksAdvice){
	// your code here, with a very very simple example as well
	// if the JSON has a someField object, you can access it using $KeksAdvice->someField
	if($KeksAdvice->amount != $YourShopOrder->amount) return false;
	return true;
});
```

If a transaction should be accepted, return `true`. Otherwise, return `false`.

### KeksTransaction: Initiating a transaction

[](#kekstransaction-initiating-a-transaction)

To initiate a transaction, you'll need to serve a QR code to customers on the desktop and a deep link to customers on phones.

To make generating these QR codes and deep links easier, KeksPHP provides a method to build the QR codes and deep links for you.

To do so, create an instance of the `KeksTransaction` class by calling the constructor with your `KeksSeller` instance as its argument.

Set the `bill_id` member of the `KeksTransaction` instance to a unique order identifier in your stores backend (order ID, UUID, whatever - KeksPHP doesn't care, but you'll need to be able to identify an *order* based on its `bill_id`).

Set the `amount` member of the `KeksTransaction` instance to the amount you want to charge using KEKS Pay. `amount` is an int or a float, and will be appropriately formatted by KeksPHP. For instance, to charge 20 HRK, set `amount` to equal `20`, and to charge 20.05 HRK, set `amount` to equal `20.05` -- do not set `amount` to a formatted string.

Then, call the `buildDeepLinkAndQR` method of the `KeksTransaction` instance. This will return a `\stdClass` instance with two members: `qr` and `deeplink`.

```
$KeksTransaction = new \KeksPHP\KeksTransaction($KeksSeller); // create a new KeksTransaction
$KeksTransaction->bill_id = 20;
$KeksTransaction->amount = 500;
var_dump($KeksTransaction->buildDeepLinkAndQR()); // use $KeksTransaction->buildDeepLinkAndQR()->deeplink to get the deeplink
```

You can then generate a QR code containing **the value** of the `qr` member of the class or a link to **the value** of the `deeplink` member of the class and display it to the user. How you'll handle that: that's up to you.

I'd advise you to find a library for your language (or a JavaScript library or an API) to generate the QR code and to toggle QR code/deep link visibility with media queries.

### KeksTransaction: Interpreting recieved advice

[](#kekstransaction-interpreting-recieved-advice)

#### Requirements

[](#requirements-1)

You'll need to build an endpoint where KEKS Pay will send POST requests to send the `advice`. You'll also need to implement some authentification there - KeksPHP **will not** do this for you.

There are two ways you can do this: using token autentification and [PHP Basic Auth](https://www.php.net/manual/en/features.http-auth.php).

If you're going to be catching the KEKS Pay request yourself, store it in a variable and pass it as a parameter to the `buildFromAdvice` method of the `KeksTransaction` class. If you don't to this, KeksPHP will try to catch the request itself.

#### Interpreting advice

[](#interpreting-advice)

If you've caught the advice content from php://input yourself:

```
$KeksTransaction = new \KeksPHP\KeksTransaction($KeksSeller);

$Response = $KeksTransaction->buildFromAdvice($YourAdvice);

echo json_encode($Response);
```

If you want KeksPHP to catch the advice for you:

```
$KeksTransaction = new \KeksPHP\KeksTransaction($KeksSeller);

$Response = $KeksTransaction->buildFromAdvice();

echo json_encode($Response);
```

KeksPHP will now:

- check if your TID in KeksSeller matches the TID in the advice recieved
- check if the transaction has cleared (status == 0)
- call your validation closure with the advice recieved

If any of these checks fail, KeksPHP will throw a `KeksIntegrationException`, handle it and log it into the `handledExceptions` member array of the KeksTransactions instance, which you can access with the `getExceptions` method to check what went wrong.

Furthermore, the `buildFromAdvice` method will return a response with status of -1 and message equalling the exception messages.

If these checks pass, KeksPHP will return a response with status of 0 and message = 'Accepted'.

#### Responding to KEKS Pay

[](#responding-to-keks-pay)

To respond to KEKS Pay after handling the transaction, encode the `buildFromAdvice` output at JSON (using `json_encode`) and return it.

#### Logging transactions

[](#logging-transactions)

How you'll do this is up to you, but you can simply serialize or json\_encode the KeksTransaction instance.

### Refunding

[](#refunding)

To refund a transaction, create a `KeksRefund` by calling its constructor with the corresponding KeksSeller and KeksTransaction instances.

```
$KeksRefund = new \KeksPHP\KeksRefund($KeksSeller, $KeksTransaction);
```

Then, you can choose a path.

#### Just generate the refund request, but don't send it

[](#just-generate-the-refund-request-but-dont-send-it)

If you'd like to send the refund request yourself, you can just ask KeksPHP to create the Refund, but not to send it - using the `createRefund` method, setting its only parameter to **the amount to be refunded**. You can then access it using the `RefundRequest` member of the KeksRefund instance.

```
$KeksRefund->createRefund($Amount);

your_function_to_send_refund_request($KeksRefund->RefundRequest)
```

This will not validate the KEKS Pay response, so if you need to do that, call the `validateKeksResponse` method with the KEKS Pay API reponse body as its only parameter

```
$KeksRefund->validateKeksResponse($KeksReponse);
```

This will change the `RefundSuccessful` member of the class to either true or false. (It defaults to false)

#### Do everything for me

[](#do-everything-for-me)

If you'd like KeksPHP to send the refund request for you, first generate it using the `createRefund` method, setting its only parameter to **the amount to be refunded**.

Then call the `submitRefund` method to send the refund to KEKS Pay and check the `RefundSuccessful` member to see if the refund was successful.

```
$KeksRefund->createRefund($Amount);

$KeksRefund->submitRefund();

if($KeksRefund->RefundSuccessful){
	echo 'yay, successfull refund!';
}
else{
	echo 'oh no, I could not refund!';
}
```

#### Possible pitfalls

[](#possible-pitfalls)

If the amount **to be refunded** is higher than the **original transaction amount**, you'll get a `KeksIntegrationException`.

### Exceptions

[](#exceptions)

If an exception occurs in KeksPHP's `KeksTransaction` methods, it'll try to handle it and store it in the `handledExceptions` member of itself, which you can access using the `getExceptions` method of the class.

If an exception occurs in `KeksRefund`, you'll get it thrown your way as there's no chance to recover.

All exceptions thrown by KeksPHP are of the type `KeksIntegrationException` which extends PHP's generic exceptions to provide you with the applicable `KeksSeller`, `KeksTransaction` and `KeksRefund` transactions whereever possible to make debugging easier.

You can access these by accessing the `KeksSeller`, `KeksTransaction` and `KeksRefund` members of the exception respectively.

Support and bugs
----------------

[](#support-and-bugs)

For questions and issues regarding this project, open an issue here. (Croatian is fine here, as well!)

For questions regarding KEKS Pay, contact the KEKS Pay team.

###  Health Score

23

—

LowBetter than 27% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity6

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity52

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

1840d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/1742806?v=4)[Mario Borna Mjertan](/maintainers/mbmjertan)[@mbmjertan](https://github.com/mbmjertan)

---

Top Contributors

[![mbmjertan](https://avatars.githubusercontent.com/u/1742806?v=4)](https://github.com/mbmjertan "mbmjertan (7 commits)")

### Embed Badge

![Health badge](/badges/mbmjertan-keksphp/health.svg)

```
[![Health](https://phpackages.com/badges/mbmjertan-keksphp/health.svg)](https://phpackages.com/packages/mbmjertan-keksphp)
```

###  Alternatives

[chargebee/chargebee-php

ChargeBee API client implementation for PHP

768.0M9](/packages/chargebee-chargebee-php)[imdhemy/google-play-billing

Google Play Billing

491.3M5](/packages/imdhemy-google-play-billing)[bitpay/sdk

Complete version of the PHP library for the new cryptographically secure BitPay API

42337.5k4](/packages/bitpay-sdk)[buckaroo/sdk

Buckaroo payment SDK

12189.1k9](/packages/buckaroo-sdk)[contica/facturador-electronico-cr

Un facturador de código libre para integrar facturación electrónica en Costa Rica a un proyecto PHP

2128.8k](/packages/contica-facturador-electronico-cr)[karson/mpesa-php-sdk

172.2k](/packages/karson-mpesa-php-sdk)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
