Search by

kirimi / kirimi-php

yolkmonday

Official PHP client library for the Kirimi WhatsApp API. Send messages, handle OTP verification, and manage WhatsApp communication with ease.

Package info

github.com/kiriminow/kirimi-php

pkg:composer/kirimi/kirimi-php

Statistics

Installs: 35

Dependents: 1

Suggesters: 0

Stars: 2

Open Issues: 0

3.0.0 2026-09-17 17:17 UTC

This package is auto-updated.

Last update: 2026-09-17 17:34:25 UTC


README

Packagist Version Packagist Downloads PHP Version License

Official PHP client library for the Kirimi WhatsApp API. This library provides a simple and efficient way to send WhatsApp messages, handle OTP generation and validation, and manage WhatsApp communication from your PHP applications.

๐Ÿš€ Features

  • โœ… Send WhatsApp messages (text and media)
  • โœ… Broadcast to up to 1000 recipients
  • โœ… WhatsApp Business API (WABA) templates, replies, conversations and OTP
  • โœ… Generate and validate OTP codes (v1 and v2)
  • โœ… Reverse OTP verification
  • โœ… Devices, contacts, packages and deposits
  • โœ… Support for multiple package types (Free, Lite, Basic, Pro)
  • โœ… PSR-4 autoloading support
  • โœ… Comprehensive error handling with HTTP status codes
  • โœ… Type hints and modern PHP features
  • โœ… Service classes for common use cases

๐Ÿ“ฆ Installation

Install via Composer:

composer require kirimi/kirimi-php

๐Ÿ”ง Requirements

  • PHP 8.0 or higher
  • Guzzle HTTP client (installed automatically)
  • ext-json (usually included in PHP)

๐Ÿ”ง Setup

Get your User Code and Secret Key from the Kirimi Dashboard.

<?php

require_once 'vendor/autoload.php';

use Kirimi\KirimiClient;

$client = new KirimiClient('YOUR_USER_CODE', 'YOUR_SECRET_KEY');

๐Ÿ“– API Reference

Constructor

$client = new KirimiClient($userCode, $secret, $endpoint = 'https://api.kirimi.id');

Parameters:

  • $userCode (string): Your unique user code from Kirimi Dashboard
  • $secret (string): Your secret key for authentication
  • $endpoint (string): API endpoint URL (optional)

Send Message

Send WhatsApp messages with optional media support. The recipient is passed as $receiver and sent to the API as receiver (country code, no +).

// Text message only
$result = $client->sendMessage('device_id', '628123456789', 'Hello World!');

// Message with media
$result = $client->sendMessage(
    'device_id',
    '628123456789',
    'Check out this image!',
    'https://example.com/image.jpg'
);

// With advanced options
$result = $client->sendMessage('device_id', '628123456789', 'Hello!', null, [
    'enableTypingEffect' => true,
    'typingSpeedMs'      => 350,       // 100-800
    'quotedMessageId'    => 'MSG_ID',
]);

Parameters:

  • $deviceId (string): Your device ID
  • $receiver (string): Recipient's phone number (with country code)
  • $message (string): Message content
  • $mediaUrl (string|null): URL of media file to send (optional)
  • $options (array): Optional fileName, enableTypingEffect, typingSpeedMs, quotedMessageId

Send Message Fast

Send a message without the typing effect simulation.

$result = $client->sendMessageFast('device_id', '628123456789', 'Hello!');

Send Message File

Send a file/document via multipart upload (max 50MB). The filename is sent both as the multipart filename and as the fileName field.

$result = $client->sendMessageFile(
    'device_id',
    '628123456789',
    '/path/to/document.pdf',
    ['message' => 'Here is your invoice', 'fileName' => 'invoice.pdf']
);

Broadcast Message

Send a message to up to 1000 recipients. $numbers is always sent as a JSON array and $label is required.

$result = $client->broadcastMessage(
    'device_id',
    'promo-juli',                                 // label, max 100 chars
    ['628111111111', '628222222222'],
    'Promo hari ini!',
    ['delay' => 30]                               // seconds, clamped 30-3600
);

WABA โ€” Send Template Message

Send a Meta-approved template via WhatsApp Business API. WABA endpoints use waba_id, never device_id.

$result = $client->sendWabaMessage('waba_id', '628123456789', 'order_update', [
    'variables' => ['Budi', 'ORD-001'],
    'header'    => ['type' => 'text', 'text' => 'Order update'],
]);

WABA โ€” Reply, Conversations & Templates

// Free-form reply (within the 24h customer service window)
$result = $client->wabaReply('waba_id', '628123456789', [
    'type' => 'text',
    'text' => 'Halo, ada yang bisa dibantu?',
]);

// List conversations
$conversations = $client->wabaConversations(50, 1);   // limit, page

// Refresh template status from Meta
$templates = $client->wabaTemplatesSync('waba_id');

WABA โ€” OTP

$result = $client->wabaSendOtp('waba_id', '628123456789', 'otp_auth');
$verify = $client->wabaVerifyOtp('waba_id', '628123456789', '123456');

Devices

$device  = $client->createDevice(3, 'VOUCHER10');       // package_id, voucher_code
$connect = $client->connectDevice('device_id');          // returns QR/session state
$renew   = $client->renewDevice('device_id', 4, 'VOUCHER10');

$devices  = $client->listDevices(1, 10);                 // page, limit
$status   = $client->deviceStatus('device_id');
$detailed = $client->deviceStatusEnhanced('device_id');

User Info

$info = $client->userInfo();

Contacts

Existing numbers are skipped, not overwritten.

$result = $client->saveContact('John Doe', '628123456789', 'device_id');

$bulk = $client->saveContactsBulk([
    ['nama' => 'John Doe', 'nomor' => '628123456789'],
    ['nama' => 'Jane Doe', 'nomor' => '628987654321'],
], 'device_id');   // max 1000 contacts

Generate OTP

Generate and send OTP via device WhatsApp.

// Basic
$result = $client->generateOTP('device_id', '628123456789');

// With options
$result = $client->generateOTP('device_id', '628123456789', [
    'otp_length'       => 6,           // 4-20, default 8
    'otp_type'         => 'numeric',   // numeric | alphabetic | alphanumeric
    'customOtpText'    => 'Your code',
    'customOtpMessage' => 'Your OTP is {otp}. Valid for 5 minutes.',
]);

Validate OTP

$result = $client->validateOTP('device_id', '628123456789', '123456');

Send OTP V2

Send an OTP through the Kirimi provider, your own device, or your own WABA.

// Kirimi provider (Rp 595 per delivered OTP)
$result = $client->sendOtpV2('628123456789', [
    'method'   => 'whatsapp',
    'app_name' => 'MyApp',
]);

// Your own connected device (free)
$result = $client->sendOtpV2('628123456789', [
    'method'         => 'device',
    'device_id'      => 'device_id',
    'custom_message' => 'Your OTP is {{otp}}',
]);

// Your own WABA + AUTHENTICATION template (free)
$result = $client->sendOtpV2('628123456789', [
    'method'        => 'waba_user',
    'waba_id'       => 'waba_id',
    'template_name' => 'otp_auth',
]);

Verify OTP V2

$result = $client->verifyOtpV2('628123456789', '123456');

Reverse OTP

The customer sends a token back to your device, which verifies automatically.

$create = $client->otpReverseCreate('628123456789', 'device_id', [
    'app_name'        => 'MyApp',
    'callback_url'    => 'https://example.com/callback',
    'custom_message'  => 'Send {{token}} from {{phone}} to verify.',
    'success_message' => 'Verified!',
    'failure_message' => 'Verification failed.',
]);

$status = $client->otpReverseStatus($create['token']);   // pending|verified|phone_mismatch|expired

Deposits & Packages

$packages = $client->listPackages();

$deposit = $client->createDeposit(50000);        // min 100
$status  = $client->depositStatus($ref);
$cancel  = $client->cancelDeposit($ref);         // must be unpaid

$all  = $client->listDeposits();
$paid = $client->listDeposits(['status' => 'paid', 'page' => 1, 'limit' => 10]);

Package Support:

  • Free: Text only (with watermark)
  • Lite/Basic/Pro: Text + Media support

Health Check

Check the API service status.

$status = $client->healthCheck();
print_r($status);

๐ŸŽฏ Quick Start

Check out the examples/demo.php file for a complete demonstration of all features:

# Set your credentials as environment variables
export KIRIMI_USER_CODE="your_user_code"
export KIRIMI_SECRET_KEY="your_secret_key"
export KIRIMI_DEVICE_ID="your_device_id"
export TEST_PHONE="628123456789"

# Run the example
composer run example
# or
php examples/demo.php

๐Ÿ’ก Usage Examples

Basic WhatsApp Messaging

<?php

require_once 'vendor/autoload.php';

use Kirimi\KirimiClient;
use Kirimi\KirimiException;

$client = new KirimiClient('your_user_code', 'your_secret');

try {
    $result = $client->sendMessage(
        'your_device_id',
        '628123456789',
        'Welcome to our service! ๐ŸŽ‰'
    );
    echo "Message sent successfully: " . json_encode($result) . PHP_EOL;
} catch (KirimiException $e) {
    echo "Failed to send message: " . $e->getMessage() . PHP_EOL;
}

OTP Verification Flow

<?php

require_once 'vendor/autoload.php';

use Kirimi\Services\OTPService;

$otpService = new OTPService('your_user_code', 'your_secret', 'your_device_id');

// Send OTP
$result = $otpService->sendVerificationCode('628123456789');
if ($result['success']) {
    echo "OTP sent successfully!" . PHP_EOL;
} else {
    echo "Failed to send OTP: " . $result['error'] . PHP_EOL;
}

// Verify OTP (user provides the code)
$verifyResult = $otpService->verifyCode('628123456789', '123456');
if ($verifyResult['success'] && $verifyResult['verified']) {
    echo "OTP verified successfully!" . PHP_EOL;
} else {
    echo "OTP verification failed!" . PHP_EOL;
}

Notification Service

<?php

require_once 'vendor/autoload.php';

use Kirimi\Services\NotificationService;

$notificationService = new NotificationService('your_user_code', 'your_secret', 'your_device_id');

// Send welcome message
$result = $notificationService->sendWelcomeMessage('628123456789', 'John Doe');

// Send order confirmation
$result = $notificationService->sendOrderConfirmation(
    '628123456789',
    'ORD-001',
    ['Product A', 'Product B', 'Product C']
);

// Send invoice with document
$result = $notificationService->sendInvoiceWithDocument(
    '628123456789',
    'INV-001',
    'https://example.com/invoice.pdf'
);

// Send appointment reminder
$result = $notificationService->sendAppointmentReminder(
    '628123456789',
    '2024-01-15',
    '10:00 AM',
    'Main Office'
);

Laravel Integration

<?php

// In your Laravel service provider or controller
use Kirimi\KirimiClient;

class WhatsAppService
{
    private KirimiClient $kirimi;

    public function __construct()
    {
        $this->kirimi = new KirimiClient(
            config('services.kirimi.user_code'),
            config('services.kirimi.secret')
        );
    }

    public function sendNotification(string $phone, string $message): bool
    {
        try {
            $this->kirimi->sendMessage(
                config('services.kirimi.device_id'),
                $phone,
                $message
            );
            return true;
        } catch (KirimiException $e) {
            Log::error('WhatsApp notification failed: ' . $e->getMessage());
            return false;
        }
    }
}

// In config/services.php
return [
    'kirimi' => [
        'user_code' => env('KIRIMI_USER_CODE'),
        'secret' => env('KIRIMI_SECRET_KEY'),
        'device_id' => env('KIRIMI_DEVICE_ID'),
    ],
];

๐Ÿ“‹ Package Types & Features

Package ID Features OTP Support
Free 1 Text only (with watermark) โŒ
Lite 2, 6, 9 Text + Media โŒ
Basic 3, 7, 10 Text + Media + OTP โœ…
Pro 4, 8, 11 Text + Media + OTP โœ…

โš ๏ธ Error Handling

The library provides comprehensive error handling using KirimiException. Use getStatusCode() to distinguish failures; it returns the HTTP status code from the response (null for network errors).

Code Meaning
400 Invalid params
401 Wrong secret
402 Insufficient balance (/v2/otp/send whatsapp)
403 Feature not in package / subscription inactive
404 Not found
429 Rate limited
500 Server error
502 Number undeliverable
503 Provider outage
use Kirimi\KirimiException;

try {
    $client->sendMessage('device_id', '628123456789', 'Hello');
} catch (KirimiException $e) {
    switch ($e->getStatusCode()) {
        case 401:
            echo 'Invalid credentials';
            break;
        case 402:
            echo 'Insufficient balance';
            break;
        case 429:
            echo 'Rate limited, retry later';
            break;
        default:
            echo 'Request failed: ' . $e->getMessage();
    }
}

๐Ÿ”’ Security Notes

  • Always keep your secret key secure and never expose it in client-side code
  • Use environment variables to store credentials
  • Validate phone numbers before sending messages
  • Implement rate limiting in your application
// Good practice: use environment variables
$client = new KirimiClient(
    $_ENV['KIRIMI_USER_CODE'],
    $_ENV['KIRIMI_SECRET_KEY']
);

๐Ÿšฆ Rate Limits & Quotas

  • Each message sent reduces your device quota (unless unlimited)
  • OTP codes expire after 5 minutes
  • Device must be in 'connected' status to send messages
  • Check your dashboard for current quota and usage statistics

๐Ÿงช Testing

Run the test suite:

composer test

Run tests with coverage:

composer test-coverage

Check code style:

composer cs-check

Fix code style:

composer cs-fix

๐Ÿค Contributing

Contributions are welcome! Please follow these steps:

  1. Fork the repository
  2. Create a feature branch
  3. Follow PSR-12 coding standards
  4. Add tests for new features
  5. Submit a pull request

๐Ÿ“„ License

MIT

๐Ÿ‘จโ€๐Ÿ’ป Author

Ari Padrian - yolkmonday@gmail.com

๐Ÿ“š Additional Resources

Made with โค๏ธ for the PHP and WhatsApp automation community