PHP code example of kkxdev / laravel-phonepe-autopay

1. Go to this page and download the library: Download kkxdev/laravel-phonepe-autopay library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

kkxdev / laravel-phonepe-autopay example snippets


use Kkxdev\PhonePe\Facades\PhonePe;
use Kkxdev\PhonePe\DTO\Subscription\SubscriptionSetupRequest;

$request = SubscriptionSetupRequest::fromArray([
    'merchantOrderId' => 'ORDER_' . time(),
    'amount' => 100000, // Amount in paisa (1000 INR)
    'merchantSubscriptionId' => 'SUB_' . time(),
    'subscriptionType' => 'RECURRING',
    'authWorkflowType' => 'TRANSACTION',
    'amountType' => 'FIXED',
    'maxAmount' => 100000,
    'frequency' => 'MONTHLY', // DAILY, WEEKLY, MONTHLY, QUARTERLY, HALFYEARLY, YEARLY
    'productType' => 'UPI_MANDATE',
    'redirectUrl' => 'https://yourdomain.com/payment/success',
    'cancelRedirectUrl' => 'https://yourdomain.com/payment/cancel',
    'message' => 'Monthly subscription payment',
    'metaInfo' => [
        'udf1' => 'custom_data_1',
        'udf2' => 'custom_data_2',
    ],
]);

try {
    $response = PhonePe::subscription()->setup($request);

    // Redirect user to PhonePe authorization page
    return redirect($response['redirectUrl']);

} catch (\Kkxdev\PhonePe\Exceptions\ValidationException $e) {
    // Handle validation errors
    $errors = $e->getErrors();
} catch (\Kkxdev\PhonePe\Exceptions\ApiException $e) {
    // Handle API errors
    $statusCode = $e->getStatusCode();
    $responseBody = $e->getResponseBody();
}

use Kkxdev\PhonePe\Facades\PhonePe;

$status = PhonePe::subscription()->getStatus('SUB_123456');

if ($status->isActive()) {
    // Subscription is active
    echo "Subscription ID: {$status->subscriptionId}\n";
    echo "State: {$status->state}\n";
    echo "Frequency: {$status->frequency}\n";
    echo "Max Amount: {$status->maxAmount}\n";
} elseif ($status->isCancelled()) {
    // Subscription was cancelled/revoked
} elseif ($status->isPaused()) {
    // Subscription is paused
}

use Kkxdev\PhonePe\Facades\PhonePe;

$orderStatus = PhonePe::subscription()->getOrderStatus('ORDER_123456');

if ($orderStatus->isCompleted()) {
    // Payment completed successfully
    $transactionId = $orderStatus->paymentDetails[0]['transactionId'] ?? null;
} elseif ($orderStatus->isFailed()) {
    // Payment failed
} elseif ($orderStatus->isPending()) {
    // Payment still pending
}

use Kkxdev\PhonePe\Facades\PhonePe;
use Kkxdev\PhonePe\DTO\Redemption\RedemptionNotifyRequest;

$request = RedemptionNotifyRequest::fromArray([
    'merchantOrderId' => 'REDEMPTION_' . time(),
    'amount' => 100000, // Amount in paisa
    'merchantSubscriptionId' => 'SUB_123456',
    'redemptionRetryStrategy' => 'STANDARD', // STANDARD or CUSTOM
]);

$response = PhonePe::redemption()->notify($request);

// Store orderId for later execution
$orderId = $response['orderId'];
$state = $response['state']; // NOTIFIED

use Kkxdev\PhonePe\Facades\PhonePe;
use Kkxdev\PhonePe\DTO\Redemption\RedemptionExecuteRequest;

$request = RedemptionExecuteRequest::fromArray([
    'merchantOrderId' => 'REDEMPTION_123456',
    'idempotencyKey' => 'IDEMPOTENT_KEY_' . time(), // Optional but recommended
]);

$response = PhonePe::redemption()->execute($request);

if ($response['state'] === 'COMPLETED') {
    $transactionId = $response['transactionId'];
    // Payment successful
} elseif ($response['state'] === 'FAILED') {
    // Payment failed
}

use Kkxdev\PhonePe\Facades\PhonePe;

$status = PhonePe::redemption()->getStatus('REDEMPTION_123456');

if ($status->isCompleted()) {
    echo "Transaction ID: {$status->transactionId}\n";
} elseif ($status->isFailed()) {
    echo "Error Code: {$status->errorCode}\n";
}

use Kkxdev\PhonePe\Facades\PhonePe;

PhonePe::subscription()->cancel('SUB_123456');
// Returns void on success (204 No Content)

use Kkxdev\PhonePe\Facades\PhonePe;
use Kkxdev\PhonePe\DTO\Refund\RefundRequest;

$request = RefundRequest::fromArray([
    'merchantRefundId' => 'REFUND_' . time(),
    'originalMerchantOrderId' => 'ORDER_123456',
    'amount' => 50000, // Amount to refund in paisa
]);

$response = PhonePe::refund()->create($request);

$refundId = $response['refundId'];
$state = $response['state']; // PENDING, CONFIRMED, COMPLETED, FAILED

use Kkxdev\PhonePe\Facades\PhonePe;

$status = PhonePe::refund()->getStatus('REFUND_123456');

if ($status->isCompleted()) {
    echo "Refund completed successfully\n";
    echo "Amount: {$status->amount}\n";
} elseif ($status->isFailed()) {
    echo "Refund failed: {$status->errorCode}\n";
}

use Kkxdev\PhonePe\Facades\PhonePe;
use Illuminate\Http\Request;

public function handleWebhook(Request $request)
{
    try {
        $authHeader = $request->header('Authorization');
        $payload = $request->all();

        // Verify and parse webhook
        $event = PhonePe::verifyWebhook($authHeader, $payload);

        // Handle different event types
        if ($event->isSubscriptionPaused()) {
            $subscriptionId = $event->getMerchantSubscriptionId();
            // Handle pause event

        } elseif ($event->isSubscriptionUnpaused()) {
            $subscriptionId = $event->getMerchantSubscriptionId();
            // Handle unpause event

        } elseif ($event->isSubscriptionRevoked()) {
            $subscriptionId = $event->getMerchantSubscriptionId();
            // Handle revocation (user-initiated cancellation)

        } elseif ($event->isRedemptionCompleted()) {
            // Handle successful redemption

        } elseif ($event->isRedemptionFailed()) {
            // Handle failed redemption
        }

        return response()->json(['status' => 'success'], 200);

    } catch (\Kkxdev\PhonePe\Exceptions\WebhookVerificationException $e) {
        // Signature verification failed
        return response()->json(['error' => 'Invalid signature'], 403);
    }
}

// Configured in config/phonepe.php
'retry' => [
    'enabled' => true,
    'max_attempts' => 3,
    'base_delay_ms' => 1000,
    'max_delay_ms' => 10000,
    'jitter' => true, // Prevents thundering herd
],

'circuit_breaker' => [
    'enabled' => true,
    'failure_threshold' => 5, // Open after 5 consecutive failures
    'success_threshold' => 2, // Close after 2 successes in half-open
    'cooldown_seconds' => 60, // Wait 60s before testing recovery
],

use Kkxdev\PhonePe\Contracts\HttpClientInterface;

// In your tests
$mockClient = Mockery::mock(HttpClientInterface::class);
$mockClient->shouldReceive('send')
    ->andReturn([
        'orderId' => 'PG_ORDER_123',
        'state' => 'PENDING',
        'redirectUrl' => 'https://phonepe.com/...',
    ]);

$this->app->instance(HttpClientInterface::class, $mockClient);
bash
php artisan vendor:publish --tag=phonepe-config