1. Go to this page and download the library: Download kosovopay/php-sdk library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
kosovopay / php-sdk example snippets
use KosovoPay\KosovoPay;
$kp = new KosovoPay('sk_test_…');
$kp = new KosovoPay(
apiKey: 'sk_live_…',
baseUrl: 'https://api.kosovo.sh', // override for a private/staging gateway
apiVersion: '2026-06-01', // pinned via the Kosovopay-Version header
connectTimeout: 10, // seconds to establish the TCP/TLS connection
requestTimeout: 30, // seconds for the full request/response
maxRetries: 3, // total attempts for retryable failures
);
> $kp = new KosovoPay($_ENV['KOSOVOPAY_SECRET_KEY']);
>
use KosovoPay\KosovoPay;
use KosovoPay\Enums\CurrencyCode;
use KosovoPay\Params\CreatePaymentParams;
$kp = new KosovoPay($_ENV['KOSOVOPAY_SECRET_KEY']);
$payment = $kp->payments->create(new CreatePaymentParams(
amount: 4990, // €49.90 in minor units
currency: CurrencyCode::EUR,
successUrl: 'https://shop.test/thank-you',
cancelUrl: 'https://shop.test/cart',
description: 'Order #1024',
metadata: ['order_id' => '1024'],
));
header('Location: ' . $payment->hostedUrl);
exit;
$payment = $kp->payments->create($params, idempotencyKey: 'order-1024');
// Re-running this exact call returns the original payment instead of creating a second.
use KosovoPay\Enums\CurrencyCode;
use KosovoPay\Enums\CheckoutMode;
use KosovoPay\Params\CreatePaymentParams;
use KosovoPay\Params\LineItem;
$payment = $kp->payments->create(new CreatePaymentParams(
amount: 4990,
currency: CurrencyCode::EUR,
successUrl: 'https://shop.test/thank-you',
mode: CheckoutMode::Hosted, // default — can be omitted
cancelUrl: 'https://shop.test/cart',
failUrl: 'https://shop.test/payment-failed',
description: 'Order #1024',
merchantReference: 'ORDER-1024',
expiresAt: time() + 1800, // optional: link expires in 30 min
lineItems: [
new LineItem(name: 'Wireless mouse', quantity: 1, unitAmountCents: 2990, sku: 'WM-01'),
new LineItem(name: 'USB-C cable', quantity: 2, unitAmountCents: 1000),
],
metadata: ['order_id' => '1024', 'customer_tier' => 'gold'],
));
echo $payment->id; // "pi_…"
echo $payment->hostedUrl; // redirect the buyer here
use KosovoPay\Enums\RefundReason;
use KosovoPay\Params\CreateRefundParams;
// Full refund
$refund = $kp->refunds->create(new CreateRefundParams(payment: 'pi_1024'));
// Partial refund with a reason
$refund = $kp->refunds->create(new CreateRefundParams(
payment: 'pi_1024',
amount: 1000, // €10.00
reason: RefundReason::RequestedByCustomer,
), idempotencyKey: 'refund-order-1024-partial-1');
echo $refund->status->value; // "succeeded" | "pending" | "failed"
$refund = $kp->refunds->retrieve('re_77');
use KosovoPay\Params\ListRefundsParams;
foreach ($kp->refunds->all(new ListRefundsParams(payment: 'pi_1024')) as $refund) {
echo $refund->id, PHP_EOL;
}
use KosovoPay\Enums\BankCode;
// All banks enabled for your account, as a Collection<Bank>
$banks = $kp->banks->all();
foreach ($banks as $bank) {
printf(
"%-10s min %d step %d partial-refunds: %s\n",
$bank->code->value,
$bank->capabilities->minAmount,
$bank->capabilities->amountStep,
$bank->capabilities->refunds->partial ? 'yes' : 'no',
);
}
// A single bank
$onefor = $kp->banks->retrieve(BankCode::Onefor);
$onefor->capabilities->currencies; // list<CurrencyCode> the bank accepts
$onefor->capabilities->minAmount; // smallest accepted amount, minor units
$onefor->capabilities->amountStep; // amount must be a multiple of this
$onefor->capabilities->refunds->supported;
$onefor->capabilities->refunds->partial;
use KosovoPay\Enums\CurrencyCode;
// Supported settlement currencies
foreach ($kp->currencies->all() as $currency) {
printf("%s (%s) — %d decimals%s\n",
$currency->code->value, $currency->symbol, $currency->decimals,
$currency->isDefault ? ' [default]' : '');
}
// A live FX rate
$rate = $kp->rates->retrieve(CurrencyCode::EUR, CurrencyCode::USD);
echo $rate->rate; // "1.0850" — a decimal string, never a lossy float
echo $rate->syncedAt; // ISO-8601 timestamp of the last sync
var_dump($rate->stale); // true if the upstream feed is behind
use KosovoPay\Webhook;
use KosovoPay\Enums\WebhookEventType;
use KosovoPay\Exceptions\WebhookSignatureException;
$payload = file_get_contents('php://input'); // the RAW body — do not decode first
$signature = $_SERVER['HTTP_KOSOVOPAY_SIGNATURE'] ?? '';
$secret = $_ENV['KOSOVOPAY_WEBHOOK_SECRET']; // whsec_… from the endpoint
try {
$event = Webhook::constructEvent($payload, $signature, $secret);
} catch (WebhookSignatureException $e) {
http_response_code(400);
exit;
}
match ($event->type) {
WebhookEventType::PaymentCaptured => fulfilOrder($event->asPayment()),
WebhookEventType::PaymentFailed => notifyFailure($event->asPayment()),
WebhookEventType::RefundSucceeded => recordRefund($event->asRefund()),
default => null, // ignore everything else, stay forward-compatible
};
http_response_code(200);
use Illuminate\Http\Request;
use KosovoPay\Webhook;
use KosovoPay\Exceptions\WebhookSignatureException;
Route::post('/webhooks/kosovopay', function (Request $request) {
try {
$event = Webhook::constructEvent(
payload: $request->getContent(),
signatureHeader: $request->header(Webhook::SIGNATURE_HEADER, ''),
secret: config('services.kosovopay.webhook_secret'),
);
} catch (WebhookSignatureException) {
abort(400);
}
ProcessKosovoPayEvent::dispatch($event->id, $event->type->value);
return response()->noContent();
});
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use KosovoPay\Webhook;
use KosovoPay\Exceptions\WebhookSignatureException;
#[Route('/webhooks/kosovopay', methods: ['POST'])]
public function handle(Request $request): Response
{
try {
$event = Webhook::constructEvent(
$request->getContent(),
$request->headers->get(Webhook::SIGNATURE_HEADER, ''),
$this->webhookSecret,
);
} catch (WebhookSignatureException) {
return new Response('', 400);
}
// … handle $event …
return new Response('', 200);
}
use KosovoPay\Enums\WebhookEventType;
use KosovoPay\Params\CreateWebhookEndpointParams;
// Create — the secret is returned exactly ONCE, on creation. Store it now.
$endpoint = $kp->webhookEndpoints->create(new CreateWebhookEndpointParams(
url: 'https://shop.test/webhooks/kosovopay',
enabledEvents: [WebhookEventType::PaymentCaptured, WebhookEventType::RefundSucceeded],
description: 'Production fulfilment hook',
));
$secret = $endpoint->secret; // "whsec_…" — persist this; it is never shown again
// List
foreach ($kp->webhookEndpoints->all() as $e) {
printf("%s → %s [%s]\n", $e->id, $e->url, $e->status);
}
// Rotate the signing secret (returns the new secret once)
$rotated = $kp->webhookEndpoints->rotateSecret('we_1');
$newSecret = $rotated->secret;
// Delete
$deleted = $kp->webhookEndpoints->delete('we_1');
assert($deleted->deleted === true);
use KosovoPay\Money;
// Minor units → display string
Money::format(4990, decimals: 2, symbol: '€'); // "€49.90"
Money::formatCurrency(4990, $currencyDto); // uses the Currency DTO's symbol + decimals
// Exact FX conversion (uses bcmath when available, rounds half-up to minor units)
$usd = Money::convert(4990, $rate->rate); // 4990 EUR-cents × "1.0850" → 5414
use KosovoPay\Enums\CurrencyCode;
use KosovoPay\Enums\BankCode;
$check = $kp->validateAmount(125, CurrencyCode::EUR, BankCode::Onefor);
if (! $check->valid) {
echo $check->code; // "amount_below_minimum"
echo $check->message; // human-readable explanation
print_r($check->nearestValid); // suggested valid amount(s), when applicable
}
use KosovoPay\Exceptions\KosovoPayException;
use KosovoPay\Exceptions\ValidationException;
use KosovoPay\Exceptions\RateLimitException;
use KosovoPay\Exceptions\AuthenticationException;
use KosovoPay\Exceptions\Payment\AmountBelowMinimumException;
try {
$payment = $kp->payments->create($params);
} catch (AmountBelowMinimumException $e) {
// a precise, recoverable payment error
return back()->withErrors(['amount' => $e->getMessage()]);
} catch (ValidationException $e) {
// $e->param tells you which field was rejected
return back()->withErrors([$e->param ?? 'request' => $e->getMessage()]);
} catch (RateLimitException $e) {
sleep($e->retryAfter ?? 1);
// … retry …
} catch (AuthenticationException $e) {
Log::critical('KosovoPay key rejected', ['request_id' => $e->requestId]);
throw $e;
} catch (KosovoPayException $e) {
// catch-all — always log the request id for support
Log::error($e->getMessage(), [
'code' => $e->errorCode,
'type' => $e->errorType,
'status' => $e->statusCode,
'request_id' => $e->requestId,
'doc_url' => $e->docUrl,
]);
throw $e;
}
use KosovoPay\KosovoPay;
use KosovoPay\Requests\Payments\CreatePayment;
use Saloon\Http\Faking\MockClient;
use Saloon\Http\Faking\MockResponse;
use Saloon\Http\Request;
$mock = new MockClient([
CreatePayment::class => MockResponse::make([
'object' => 'payment', 'id' => 'pi_test', 'status' => 'pending', 'mode' => 'test',
'amount' => 4990, 'amount_captured' => 0, 'amount_refunded' => 0, 'currency' => 'EUR',
'created' => 1749600000, 'refunds' => [],
], 201),
]);
$kp = new KosovoPay('sk_test_x');
$kp->connector()->withMockClient($mock);
$payment = $kp->payments->create($params);
$mock->assertSent(fn (Request $r) => $r->headers()->get('Idempotency-Key') !== null);
bash
composer
Loading please wait ...
Before you can download the PHP files, the dependencies should be resolved. This can take some minutes. Please be patient.