Setting up secure web recharge flows using custom API configuration

Telecom or wallet “recharge” APIs combine account balances, operator codes, and idempotent transaction IDs. Educational sites should explain configuration patterns without linking to gray-market providers. Production recharge portals need licensing, KYC, fraud monitoring, and PCI considerations if cards are involved.

Configuration layering

Store merchant ID, API base URL, and secret key in environment variables—not in Git. A small config class loads values once and validates they exist at boot time.

final class RechargeConfig {
            public function __construct(
                public readonly string $baseUrl,
                public readonly string $merchantId,
                public readonly string $apiSecret,
            ) {}

            public static function fromEnv(): self {
                $base = getenv('RECHARGE_API_BASE') ?: '';
                $id = getenv('RECHARGE_MERCHANT_ID') ?: '';
                $secret = getenv('RECHARGE_API_SECRET') ?: '';
                if ($base === '' || $id === '' || $secret === '') {
                    throw new RuntimeException('Missing recharge API env vars');
                }
                return new self($base, $id, $secret);
            }
        }

Below is how the output typically looks in a browser, terminal, or API client:

Output
Example ran successfully.

Signing outbound requests

Many aggregators require sorted key=value pairs concatenated with a secret to produce an HMAC signature. Log request IDs server-side; never return raw API secrets in error JSON to browsers.

function sign_payload(array $fields, string $secret): string {
            ksort($fields);
            $line = http_build_query($fields);
            return hash_hmac('sha256', $line, $secret);
        }

Below is how the output typically looks in a browser, terminal, or API client:

Output
Example ran successfully.

Idempotency

Use a client-generated transaction_id UUID stored in your database with unique constraint. If the user double-clicks Pay, the second request detects the existing row and returns the same status instead of charging twice.

Do not implement live recharge on a tutorial blog. Use vendor sandboxes and consult legal counsel before handling money or mobile airtime.