hexters/coinpayment
Laravel CoinPayments integration by Hexters. Provides simple setup and helpers to create transactions, generate checkout URLs, handle IPN callbacks, track payment status, and process confirmations for crypto payments via the CoinPayments API.
Installation
composer require hexters/coinpayment
Publish the config file:
php artisan vendor:publish --provider="Hexters\CoinPayment\CoinPaymentServiceProvider" --tag="config"
Configuration
Edit config/coinpayment.php with your CoinPayment API credentials:
'api_key' => env('COINPAYMENT_API_KEY'),
'secret_key' => env('COINPAYMENT_SECRET_KEY'),
'default_currency' => 'BTC',
'default_callback_url' => env('COINPAYMENT_CALLBACK_URL'),
First Use Case: Create a Payment
use Hexters\CoinPayment\Facades\CoinPayment;
$payment = CoinPayment::createPayment([
'price' => 0.01, // in BTC
'currency1' => 'BTC',
'currency2' => 'USD',
'price2' => 500, // equivalent in USD
'item_name' => 'Premium Subscription',
'item_number' => 'SUB-12345',
'buyer_email' => 'user@example.com',
'buyer_name' => 'John Doe',
'ipn_url' => route('coinpayment.callback'),
'cancel_url' => route('payment.cancel'),
'variable' => 'custom_data',
]);
return redirect()->to($payment->getPaymentUrl());
Callback Handling
Add a route in routes/web.php:
Route::post('/coinpayment/callback', [PaymentController::class, 'handleCallback'])->name('coinpayment.callback');
Verify the callback in your controller:
public function handleCallback(Request $request)
{
$response = CoinPayment::verifyCallback($request->all());
if ($response->success) {
// Process successful payment
}
return response()->json(['status' => 'success']);
}
Recurring Payments
Use the createSubscription method for recurring billing:
$subscription = CoinPayment::createSubscription([
'price' => 0.005, // BTC
'currency1' => 'BTC',
'currency2' => 'USD',
'price2' => 250,
'period' => 1, // months
'period1' => 'month',
'item_name' => 'Monthly Membership',
'item_number' => 'MEM-67890',
'buyer_email' => 'user@example.com',
'ipn_url' => route('coinpayment.subscription.callback'),
'cancel_url' => route('subscription.cancel'),
]);
Multi-Currency Support Dynamically switch currencies based on user preference:
$userCurrency = $user->preferred_currency;
$paymentData = [
'price' => $amountInBTC,
'currency1' => 'BTC',
'currency2' => $userCurrency,
'price2' => $amountInUserCurrency,
// ... other fields
];
Webhook Integration Extend the callback logic to trigger events:
event(new PaymentReceived($response->data));
Refund Handling Process refunds via the API:
$refund = CoinPayment::createRefund([
'txn_id' => $transactionId,
'amount' => 0.002, // BTC
'currency' => 'BTC',
'reason' => 'Customer requested refund',
]);
Laravel Cashier Compatibility
Extend Cashier’s PostWebhook handler to include CoinPayment logic:
public function handleCoinPaymentWebhook($payload)
{
$response = CoinPayment::verifyCallback($payload);
if ($response->success) {
$this->handleSuccessfulPayment($response->data);
}
}
Middleware for Authenticated Payments Protect payment routes:
Route::middleware(['auth'])->group(function () {
Route::post('/create-payment', [PaymentController::class, 'create'])->name('create.payment');
});
Logging and Auditing Log all payment events for compliance:
\Log::channel('payment')->info('Payment created', $paymentData);
Callback Verification
verifyCallback(). Never trust the IPN data directly.signature field in the request to validate:
$response = CoinPayment::verifyCallback($request->all());
if (!$response->success) {
abort(403, 'Invalid callback signature');
}
Currency Conversion Delays
$rate = CoinPayment::getRate(['currency1' => 'BTC', 'currency2' => 'USD']);
$price2 = $price * $rate['rate'];
Transaction Timeouts
getTransactionStatus:
$status = CoinPayment::getTransactionStatus($txnId);
if ($status->status === 'pending') {
return back()->with('error', 'Payment processing...');
}
API Rate Limits
$rate = Cache::remember("coinpayment_rate_{$currency1}_{$currency2}", 300, function () use ($currency1, $currency2) {
return CoinPayment::getRate(['currency1' => $currency1, 'currency2' => $currency2]);
});
Enable Debug Mode
Set debug to true in config/coinpayment.php to log raw API responses:
'debug' => env('APP_DEBUG'),
Test Mode
Use the test_mode flag to simulate payments:
$payment = CoinPayment::createPayment([...], ['test_mode' => true]);
Common Errors
Invalid API Key: Double-check config/coinpayment.php and .env.IPN Signature Mismatch: Ensure the secret_key is correct and the request data is unaltered.Insufficient Funds: Verify price2 (fiat) matches the user’s expected cost.Custom Payment Methods Extend the base class to add support for additional cryptocurrencies:
namespace App\Services;
use Hexters\CoinPayment\CoinPayment;
class ExtendedCoinPayment extends CoinPayment
{
public function createDogecoinPayment(array $data)
{
$data['currency1'] = 'DOGE';
return $this->createPayment($data);
}
}
Webhook Events Dispatch Laravel events for specific actions:
// In CoinPaymentServiceProvider's boot method
event(new PaymentCreated($paymentData));
Localization Override default messages (e.g., success/failure notifications):
'messages' => [
'payment_success' => trans('coinpayment.payment_success_custom'),
],
Database Models
Create a Payment model to persist transactions:
// Migration
Schema::create('coinpayments', function (Blueprint $table) {
$table->id();
$table->string('txn_id');
$table->decimal('amount', 20, 8);
$table->string('currency');
$table->string('status');
$table->json('metadata');
$table->timestamps();
});
How can I help you explore Laravel packages today?