Installation
composer require bledniy/mentor-payment
Publish the bundle’s configuration:
php artisan vendor:publish --provider="MentorPay\Bundle\MentorPayBundle" --tag="config"
Environment Configuration
Add to .env:
MENTOR_PAY_API_KEY=your_api_key_here
MENTOR_PAY_SECRET_KEY=your_secret_key_here
MENTOR_PAY_BASE_URL=https://api.mentorpay.example
First Use Case: Creating a Payment Inject the client into a controller/service:
use MentorPay\Bundle\Client;
class PaymentController extends Controller
{
public function __construct(private Client $client) {}
public function createPayment()
{
$payment = $this->client->createPayment([
'amount' => 100.00,
'currency' => 'USD',
'description' => 'Mentorship fee',
'metadata' => ['user_id' => 123],
]);
return response()->json($payment);
}
}
Key Files to Review
config/mentor_pay.php (default config)src/Client.php (core API interactions)src/Exception/ (error handling)Create & Confirm Payments
Use Client::createPayment() for one-time payments or Client::createSubscription() for recurring.
$payment = $this->client->createPayment($data);
$confirmed = $this->client->confirmPayment($payment->id);
Webhook Handling
Validate webhooks via Client::validateWebhook():
public function handleWebhook(Request $request)
{
if ($this->client->validateWebhook($request->getContent(), $request->headers->get('X-Signature'))) {
$event = $this->client->parseWebhook($request->getContent());
// Process event (e.g., payment.succeeded)
}
}
Create/Update Subscriptions
$subscription = $this->client->createSubscription([
'plan_id' => 'premium_monthly',
'customer_id' => 'cus_123',
]);
Cancel/Resume Subscriptions
$this->client->cancelSubscription($subscription->id);
$this->client->resumeSubscription($subscription->id);
$customer = $this->client->createCustomer([
'name' => 'John Doe',
'email' => 'john@example.com',
]);
Service Provider Binding
Bind the Client to the container in AppServiceProvider:
$this->app->bind(MentorPay\Bundle\Client::class, function ($app) {
return new MentorPay\Bundle\Client($app['config']['mentor_pay']);
});
Middleware for Authenticated Requests Create middleware to attach API keys to requests:
public function handle($request, Closure $next)
{
$request->headers->set('Authorization', 'Bearer ' . config('mentor_pay.api_key'));
return $next($request);
}
Mock the Client
Use Laravel’s Mockery to stub API calls:
$mock = Mockery::mock(MentorPay\Bundle\Client::class);
$mock->shouldReceive('createPayment')->andReturn((object)['id' => 'pay_123']);
$this->app->instance(MentorPay\Bundle\Client::class, $mock);
Test Webhooks Locally
Use php artisan mentor-pay:webhook-test (if the bundle includes a test command) or manually trigger events via Client::simulateWebhook().
.env or a secrets manager.MENTOR_PAY_SECRET_KEY and regenerate webhook signatures.idempotency_key for critical operations (e.g., payments) to avoid duplicate charges:
$this->client->createPayment([
'amount' => 100.00,
'idempotency_key' => 'unique_key_here',
]);
if (!$this->client->validateWebhook($rawBody, $signature)) {
abort(403, 'Invalid webhook signature');
}
try {
$this->client->createPayment($data);
} catch (RateLimitExceededException $e) {
sleep(2 ** $e->getRetryAfter());
retry();
}
Configure Monolog in config/mentor_pay.php:
'logging' => [
'enabled' => true,
'channel' => 'single',
],
Logs will appear in storage/logs/laravel.log.
| Error | Cause | Solution |
|---|---|---|
Invalid API Key |
Wrong MENTOR_PAY_API_KEY |
Verify .env and regenerate keys. |
Webhook signature mismatch |
Incorrect MENTOR_PAY_SECRET_KEY |
Update key and regenerate webhook secrets. |
Plan not found |
Invalid plan_id |
Check API docs for valid plan IDs. |
Customer already exists |
Duplicate customer_id |
Use updateCustomer() instead. |
curl -X POST -H "X-Signature: $SIGNATURE" -d '{"type":"payment.succeeded"}' http://localhost/webhook
Extend the Client to transform responses:
class CustomClient extends MentorPay\Bundle\Client
{
public function createPayment(array $data)
{
$response = parent::createPayment($data);
return (object) [
'id' => $response->id,
'formatted_amount' => '$' . $response->amount,
];
}
}
Listen for MentorPay events via Laravel’s event system:
// In EventServiceProvider
protected $listen = [
MentorPay\Bundle\Events\PaymentSucceeded::class => [
HandleSuccessfulPayment::class,
],
];
Override the default handler:
public function handleWebhook(Request $request)
{
$event = $this->client->parseWebhook($request->getContent());
match ($event->type) {
'payment.succeeded' => $this->handlePaymentSuccess($event),
'subscription.canceled' => $this->handleSubscriptionCancel($event),
default => null,
};
}
If the bundle supports multiple API versions, specify in config:
'api_version' => '2023-10', // Check MentorPay docs for latest
How can I help you explore Laravel packages today?