This SDK provides a simple and easy-to-use interface for integrating with our payment processing system.
You can find the full API documentation here.
Install via Composer:
composer require arnipay/sdk-phpThe easiest way to use the SDK is via the fluent interface.
require 'vendor/autoload.php';
use Arnipay\Arnipay;
// 1. Setup
// The third argument 'true' enables Sandbox mode automatically.
$arni = new Arnipay('CLIENT_ID', 'PRIVATE_KEY', true);
// 2. Create Payment Link
try {
$url = $arni->payment()
->title('Pizza Order')
->amount(50000)
->reference('ORDER-123')
->description('Two large pizzas')
->redirect('https://site.com/thanks', 'https://site.com/oops')
->createUrl();
echo "Pay here: " . $url;
} catch (Exception $e) {
echo "Error: " . $e->getMessage();
}
// 3. Get Payment Methods
try {
$methods = $arni->getPaymentMethods();
// Returns array: [['code' => 'qr', 'name' => 'Código QR'], ...]
print_r($methods);
} catch (Exception $e) {
echo "Error: " . $e->getMessage();
}
// 4. Webhook Handling (webhook.php)
try {
$arni->webhook('WEBHOOK_SECRET')->handle(function($event) {
if ($event->isPaid()) {
// $event->reference corresponds to the reference you set above
Order::complete($event->reference);
}
});
http_response_code(200);
} catch (Exception $e) {
http_response_code(400);
}By default, payment links show every method enabled for your account. You can optionally restrict methods with ->allow(['qr', 'card']) on the builder; omit it unless you need a fixed list, so new Arnipay methods appear without a code change.
For more control, you can use the underlying services directly.
use Arnipay\Gateway\Client;
use Arnipay\Gateway\PaymentLink;
use Arnipay\Gateway\Webhook;
use Arnipay\Gateway\Transaction;
// Initialize the client
$client = new Client(
'your-client-id',
'your-private-key'
);
// For sandbox:
// $client->setBaseUrl('https://sandbox.arnipay.com.py/api/v1', false);
// For local development:
// $client->setBaseUrl('http://arnipay.local/api/v1', false);$paymentLink = new PaymentLink($client);
try {
$link = $paymentLink->create(
150000, // price
'Premium Subscription', // title
'1 year access to all premium content', // description
[
'reference' => 'SUB-' . date('Y'),
'approved_redirection_url' => 'https://example.com/success',
'failed_redirection_url' => 'https://example.com/failed'
]
);
echo "Payment link created with ID: " . $link['id'] . "\n";
echo "Payment URL: " . $link['url'] . "\n";
} catch (Arnipay\Exception\GatewayException $e) {
echo "Error: " . $e->getMessage() . "\n";
if ($errors = $e->getErrors()) {
print_r($errors);
}
}You can pass 'payment_methods' => ['qr', 'tigo'] in the options array to limit which methods are offered; leave it out to expose all enabled methods (recommended).
$paymentLink = new PaymentLink($client);
try {
$link = $paymentLink->get('payment-link-uuid');
echo "Payment link details:\n";
echo "Title: " . $link['title'] . "\n";
echo "Price: " . $link['price'] . "\n";
echo "Is Paid: " . ($link['is_paid'] ? 'Yes' : 'No') . "\n";
} catch (Arnipay\Exception\GatewayException $e) {
echo "Error: " . $e->getMessage() . "\n";
}You can inspect specific transactions and perform actions on them, such as reversals.
// List transactions for a specific payment link
try {
$transactions = $arni->transaction()->list(['link_payment_id' => 123]);
foreach ($transactions as $tx) {
echo "Transaction ID: " . $tx['id'] . "\n";
}
} catch (Exception $e) {
echo "Error listing transactions: " . $e->getMessage();
}
// Get a single transaction
try {
$tx = $arni->transaction()->get('transaction-uuid');
print_r($tx);
} catch (Exception $e) {
echo "Error getting transaction: " . $e->getMessage();
}
// Reverse a transaction (Refund)
try {
$result = $arni->transaction()->reverse('transaction-uuid', 'Customer requested refund');
echo "Reversal initiated. Status: " . $result['status'];
} catch (Arnipay\Exception\GatewayException $e) {
echo "Reversal failed: " . $e->getMessage();
// Check if it was because the payment method doesn't support it
if (isset($e->getErrors()['payment_method'])) {
echo "Payment method not supported for auto-reversal";
}
}The SDK exposes helpers so you do not have to wire superglobals manually:
$webhook = new Webhook('your-webhook-secret');
try {
// Automatically captures method, URI, headers and body, then validates the signature.
$event = $webhook->handleRequest();
if ($event->isPaid()) {
// $event->get('reference') or $event['data']['payment_id']
$paymentId = $event->get('payment_id');
$amount = $event->get('amount');
// Update your database or take appropriate action
}
switch ($event->getType()) {
case 'payment.failed':
// Handle failed payment
break;
case 'payment.pending':
// Handle pending payment
break;
case 'pending_refund':
// Handle out-of-stock condition detected
break;
case 'auto_refunded':
// Handle successful automatic refund
break;
}
http_response_code(200);
echo json_encode(['status' => 'success']);
} catch (Arnipay\Exception\GatewayException $e) {
http_response_code($e->getStatusCode() ?: 400);
echo json_encode(['status' => 'error', 'message' => $e->getMessage()]);
}The SDK throws Arnipay\Exception\GatewayException when an error occurs. This exception provides:
- Error message
- HTTP status code
- Validation errors (if available)
try {
// SDK operation
} catch (Arnipay\Exception\GatewayException $e) {
echo "Error: " . $e->getMessage() . "\n";
echo "Status Code: " . $e->getStatusCode() . "\n";
if ($errors = $e->getErrors()) {
echo "Validation Errors:\n";
print_r($errors);
}
}The project defines separate PHPUnit test suites for unit and integration tests.
- Unit tests (no external services required):
vendor/bin/phpunit --testsuite Unit- Integration tests (require environment variables; see
tests/Integration/README.md):
vendor/bin/phpunit --testsuite IntegrationNote: Using --testsuite is the recommended way to exclude integration tests. If you previously used --exclude-group=integration and still saw integration tests run, switch to the --testsuite commands above.