PHPackages                             danipa/sdk - 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. [API Development](/categories/api)
4. /
5. danipa/sdk

ActiveLibrary[API Development](/categories/api)

danipa/sdk
==========

Official PHP SDK for the Danipa fintech API

v0.1.0(1mo ago)01MITPHPPHP ^8.1

Since May 2Pushed 1mo agoCompare

[ Source](https://github.com/Danipa/php-sdk)[ Packagist](https://packagist.org/packages/danipa/sdk)[ Docs](https://docs.danipa.com)[ RSS](/packages/danipa-sdk/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependencies (7)Versions (2)Used By (0)

danipa/sdk
==========

[](#danipasdk)

Official PHP SDK for the Danipa payments API.

```
composer require danipa/sdk
```

Requires PHP 8.1+. Runtime dependencies: [Guzzle 7](https://github.com/guzzle/guzzle) (default transport) and `psr/http-message` / `psr/http-client` / `psr/http-factory`. Bring your own PSR-18 client to swap Guzzle out — see [Pluggable HTTP transport](#pluggable-http-transport).

> **Source of truth:** this package is developed in the `paboagye/danipa-digital-platform` monorepo (private) and published to Packagist via the public mirror `danipa/php-sdk` on every `sdk-php-v*` tag — `git subtree split` keeps the mirror's tree in lockstep with `sdks/php/` in the monorepo.

Quick start
-----------

[](#quick-start)

```
use Danipa\Sdk\Danipa;
use Danipa\Sdk\RequestOptions;
use Danipa\Sdk\Model\CreateCollectionRequest;
use Danipa\Sdk\Model\Payer;

// API key prefix decides sandbox vs production:
//   dk_test_… → https://api.sandbox.danipa.com/ms
//   dk_live_… → https://api.danipa.com/ms
$danipa = Danipa::builder()
    ->apiKey(getenv('DANIPA_API_KEY'))
    ->build();

$collection = $danipa->collections()->create(
    new CreateCollectionRequest(
        amount: '125.00',
        currency: 'GHS',
        payer: Payer::phone('+233244112233', 'Ama K.'),
    ),
    RequestOptions::withIdempotencyKey('order-1234'),
);

echo $collection->status->value; // "PENDING"
```

Resources
---------

[](#resources)

ResourceMethods`$danipa->collections()``create`, `get``$danipa->disbursements()``create`, `get``$danipa->wallets()``getBalance`, `getBalance($currency)``$danipa->paymentLinks()``create``$danipa->invoices()``create``Danipa\Sdk\DanipaWebhook``verify`, `computeSignature` (static)Idempotency
-----------

[](#idempotency)

Pass an idempotency key on every mutating call via `RequestOptions::withIdempotencyKey(...)`. The backend dedupes on `(merchantId, key)` for 24 hours, so retrying a failed request with the same key is safe.

```
use Danipa\Sdk\Model\CreateDisbursementRequest;
use Danipa\Sdk\Model\Recipient;

$danipa->disbursements()->create(
    new CreateDisbursementRequest(
        amount: '500.00',
        currency: 'GHS',
        recipient: Recipient::phone('+233244998877', 'Kojo'),
    ),
    RequestOptions::withIdempotencyKey('payout-' . $order->id),
);
```

The header is sent on `POST` requests only — `GET` calls ignore the option, matching Node + Java.

Retry &amp; timeout
-------------------

[](#retry--timeout)

- Auto-retries 5xx and network errors. Default 3 attempts with exponential backoff (200 ms → 400 ms → 800 ms, capped at 2 s, +0–50 ms jitter).
- 4xx never retries — fix the request and re-call.
- 30 s per-request timeout. Override via the builder.

```
$danipa = Danipa::builder()
    ->apiKey(getenv('DANIPA_API_KEY'))
    ->maxRetries(5)
    ->timeoutMs(60000)
    ->build();
```

Verifying webhooks
------------------

[](#verifying-webhooks)

The verifier is namespaced as `Danipa\Sdk\DanipaWebhook` and works in plain PHP, Symfony, Laravel, or any framework that exposes the raw request body and headers.

### Plain PHP

[](#plain-php)

```
use Danipa\Sdk\DanipaWebhook;

$payload   = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_DANIPA_SIGNATURE'] ?? '';
$timestamp = $_SERVER['HTTP_X_DANIPA_TIMESTAMP'] ?? '';
$secret    = getenv('DANIPA_WEBHOOK_SECRET');

if (!DanipaWebhook::verify($payload, $signature, $timestamp, $secret)) {
    http_response_code(401);
    echo json_encode(['error' => 'Invalid signature']);
    exit;
}

$event = json_decode($payload, true);
// … dispatch event …
http_response_code(200);
```

### Symfony

[](#symfony)

```
use Danipa\Sdk\DanipaWebhook;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;

#[Route('/webhooks/danipa', methods: ['POST'])]
public function __invoke(Request $request): Response
{
    $ok = DanipaWebhook::verify(
        $request->getContent(),
        $request->headers->get('X-Danipa-Signature', ''),
        $request->headers->get('X-Danipa-Timestamp', ''),
        $_ENV['DANIPA_WEBHOOK_SECRET'],
    );
    if (!$ok) {
        return new Response('', 401);
    }
    // … decode + dispatch …
    return new Response('', 200);
}
```

### Laravel

[](#laravel)

```
use Danipa\Sdk\DanipaWebhook;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;

Route::post('/webhooks/danipa', function (Request $request) {
    $ok = DanipaWebhook::verify(
        $request->getContent(),                            // raw body — NOT $request->all()
        $request->header('X-Danipa-Signature', ''),
        $request->header('X-Danipa-Timestamp', ''),
        env('DANIPA_WEBHOOK_SECRET'),
    );
    abort_if(!$ok, 401);
    // … dispatch …
    return response()->noContent();
});
```

The 5-minute replay window is enforced server-side. Always pass the **raw request body** — re-serializing through `json_encode(json_decode(...))` rewrites the bytes and breaks the signature.

Error handling
--------------

[](#error-handling)

```
use Danipa\Sdk\Errors\DanipaApiError;
use Danipa\Sdk\Errors\DanipaNetworkError;

try {
    $danipa->collections()->create($req);
} catch (DanipaApiError $e) {
    // Backend rejected the request — 4xx or exhausted-retry 5xx.
    fwrite(STDERR, sprintf(
        "[%d] %s: %s (correlationId: %s)\n",
        $e->status,
        $e->errorCode,
        $e->getMessage(),
        $e->correlationId ?? '-',
    ));
} catch (DanipaNetworkError $e) {
    // Never reached the backend (DNS, TLS, timeout, connection reset).
    fwrite(STDERR, 'Network failure: ' . ($e->getPrevious()?->getMessage() ?? $e->getMessage()) . "\n");
}
```

Both classes extend `Danipa\Sdk\Errors\DanipaError`, which itself extends `RuntimeException` — catch the base to handle anything from the SDK.

Pluggable HTTP transport
------------------------

[](#pluggable-http-transport)

The default transport is Guzzle 7. Pass any [PSR-18](https://www.php-fig.org/psr/psr-18/) `ClientInterface` to swap it — useful when your app already runs Symfony HttpClient, Buzz, or a managed Guzzle pool with custom middleware:

```
use Symfony\Component\HttpClient\Psr18Client;

$danipa = Danipa::builder()
    ->apiKey(getenv('DANIPA_API_KEY'))
    ->transport(new Psr18Client())
    ->build();
```

Optional PSR-17 factories (`requestFactory`, `streamFactory`) can be injected the same way; both default to Guzzle's `HttpFactory`.

Event reference
---------------

[](#event-reference)

Full webhook event catalog with payload schemas: [developer.sandbox.danipa.com/webhooks/events](https://developer.sandbox.danipa.com/webhooks/events).

License
-------

[](#license)

MIT.

###  Health Score

34

—

LowBetter than 75% of packages

Maintenance92

Actively maintained with recent releases

Popularity1

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity32

Early-stage or recently created project

 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

38d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/ba3aa49c7cbc082a3d600c236502e9ee454d52a88fe96a15d3a67b205e612700?d=identicon)[paboagye](/maintainers/paboagye)

---

Top Contributors

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

---

Tags

sdkpaymentsfintechafricamomodanipa

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP\_CodeSniffer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/danipa-sdk/health.svg)

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

###  Alternatives

[tempest/framework

The PHP framework that gets out of your way.

2.2k31.1k11](/packages/tempest-framework)[aws/aws-sdk-php

AWS SDK for PHP - Use Amazon Web Services in your PHP project

6.3k532.1M2.5k](/packages/aws-aws-sdk-php)[telnyx/telnyx-php

Official Telnyx PHP SDK — APIs for Voice, SMS, MMS, WhatsApp, Fax, SIP Trunking, Wireless IoT, Call Control, and more. Build global communications on Telnyx's private carrier-grade network.

35729.6k2](/packages/telnyx-telnyx-php)[mollie/mollie-api-php

Mollie API client library for PHP. Mollie is a European Payment Service provider and offers international payment methods such as Mastercard, VISA, American Express and PayPal, and local payment methods such as iDEAL, Bancontact, SOFORT Banking, SEPA direct debit, Belfius Direct Net, KBC Payment Button and various gift cards such as Podiumcadeaukaart and fashioncheque.

61315.4M74](/packages/mollie-mollie-api-php)[neuron-core/neuron-ai

The PHP Agentic Framework.

1.9k496.1k32](/packages/neuron-core-neuron-ai)[getbrevo/brevo-php

Official Brevo provided RESTFul API V3 php library

1003.6M46](/packages/getbrevo-brevo-php)

PHPackages © 2026

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