PluginProbe
Yatra – Travel Booking & Tour Operator Software / 3.0.14.2
Yatra – Travel Booking & Tour Operator Software v3.0.14.2
3.0.15 3.0.14 3.0.14.1 3.0.14.2 3.0.12 3.0.13 3.0.11 3.0.10 3.0.9 3.0.8 3.0.7 3.0.6 3.0.5 3.0.5.1 3.0.4 3.0.3 3.0.2.9 3.0.2.7 3.0.2.8 3.0.2.6 trunk 1.0.0 2.0.0 2.0.1 2.0.10 All 83 releases
yatra / app / PaymentGateways / PaymentGatewayRegistry.php

PaymentGatewayRegistry.php in Yatra – Travel Booking & Tour Operator Software 3.0.14.2, at app/PaymentGateways/PaymentGatewayRegistry.php

392 lines 13.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 declare(strict_types=1);
4
5 namespace Yatra\PaymentGateways;
6
7 /**
8 * Payment Gateway Registry
9 * Manages registration and retrieval of payment gateways
10 */
11 class PaymentGatewayRegistry
12 {
13 private static ?PaymentGatewayRegistry $instance = null;
14 private array $gateways = [];
15
16 private function __construct()
17 {
18 // Register built-in gateways
19 $this->registerBuiltInGateways();
20
21 // Allow third-party plugins to register their gateways
22 do_action('yatra_register_payment_gateways', $this);
23 }
24
25 public static function getInstance(): self
26 {
27 if (self::$instance === null) {
28 self::$instance = new self();
29 }
30 return self::$instance;
31 }
32
33 /**
34 * Register built-in payment gateways (Free version)
35 * Only PayLater and PayPal are included in free version
36 * Premium gateways are registered by Yatra Pro via 'yatra_register_payment_gateways' hook
37 */
38 private function registerBuiltInGateways(): void
39 {
40 // Free gateways - always available
41 $freeGateways = [
42 Gateways\PayLater\PayLaterGateway::class, // Book Now Pay Later - Free
43 Gateways\PayPal\PayPalGateway::class, // PayPal - Free
44 ];
45
46 foreach ($freeGateways as $gatewayClass) {
47 if (class_exists($gatewayClass)) {
48 $this->register(new $gatewayClass());
49 }
50 }
51
52 // Premium gateways are registered by Yatra Pro plugin
53 // via the 'yatra_register_payment_gateways' action hook
54 }
55
56 /**
57 * Register a payment gateway
58 */
59 public function register(PaymentGatewayInterface $gateway): void
60 {
61 $this->gateways[$gateway->getId()] = $gateway;
62 }
63
64 /**
65 * Get a specific gateway by ID
66 */
67 public function get(string $id): ?PaymentGatewayInterface
68 {
69 return $this->gateways[$id] ?? null;
70 }
71
72 /**
73 * Get all registered gateways
74 */
75 public function getAll(): array
76 {
77 return $this->gateways;
78 }
79
80 /**
81 * Get all enabled/available gateways
82 */
83 public function getAvailable(): array
84 {
85 return array_filter($this->gateways, fn($gateway) => $gateway->isAvailable());
86 }
87
88 /**
89 * Gateways enabled in settings (may still lack API keys). Used for checkout UI.
90 *
91 * @return array<string, PaymentGatewayInterface>
92 */
93 public function getEnabledGateways(): array
94 {
95 return array_filter($this->gateways, fn($gateway) => $gateway->isEnabled());
96 }
97
98 /**
99 * Get list of premium gateway IDs (requires Yatra Pro)
100 */
101 public function getPremiumGatewayIds(): array
102 {
103 return [
104 'stripe',
105 'razorpay',
106 'mollie',
107 'paystack',
108 'square',
109 'authorize_net',
110 'bank_transfer',
111 ];
112 }
113
114 /**
115 * Check if a gateway is premium (requires Pro)
116 */
117 public function isPremiumGateway(string $gatewayId): bool
118 {
119 return in_array($gatewayId, $this->getPremiumGatewayIds(), true);
120 }
121
122 /**
123 * Check if Yatra Pro is active
124 */
125 private function isProActive(): bool
126 {
127 return defined('YATRA_PRO_VERSION') && class_exists('YatraPro\Plugin');
128 }
129
130 /**
131 * Get gateway definitions for admin settings UI
132 * Shows all gateways (registered + premium placeholders) with Pro badges
133 */
134 public function getDefinitions(): array
135 {
136 $definitions = [];
137 $isProActive = $this->isProActive();
138
139 // Add registered gateways
140 foreach ($this->gateways as $id => $gateway) {
141 $config = $gateway->getConfig();
142 $isPremium = $this->isPremiumGateway($id);
143
144 $definitions[$id] = [
145 'id' => $id,
146 'title' => $gateway->getTitle(),
147 'description' => $gateway->getDescription(),
148 'icon' => $gateway->getIcon(),
149 'sandbox_url' => $gateway->getSandboxUrl(),
150 'is_offline' => $gateway->isOffline(),
151 'supports' => $gateway->getSupports(),
152 'fields' => $gateway->getConfigFields(),
153 'config' => $config,
154 'enabled' => !empty($config['enabled']),
155 'is_premium' => $isPremium,
156 'requires_pro' => $isPremium && !$isProActive,
157 ];
158 }
159
160 // Add premium gateway placeholders if Pro is not active
161 if (!$isProActive) {
162 $premiumPlaceholders = $this->getPremiumGatewayPlaceholders();
163 foreach ($premiumPlaceholders as $id => $placeholder) {
164 // Only add if not already registered
165 if (!isset($definitions[$id])) {
166 $definitions[$id] = $placeholder;
167 }
168 }
169 }
170
171 return $definitions;
172 }
173
174 /**
175 * Get premium gateway placeholders for UI when Pro is not active
176 */
177 private function getPremiumGatewayPlaceholders(): array
178 {
179 return [
180 'stripe' => [
181 'id' => 'stripe',
182 'title' => __('Stripe', 'yatra'),
183 'description' => __('Accept credit card payments via Stripe', 'yatra'),
184 'icon' => YATRA_PLUGIN_URL . 'assets/images/payment-gateways/stripe.svg',
185 'sandbox_url' => '',
186 'is_offline' => false,
187 'supports' => ['refunds', 'subscriptions'],
188 'fields' => [],
189 'config' => ['enabled' => false],
190 'enabled' => false,
191 'is_premium' => true,
192 'requires_pro' => true,
193 ],
194 'razorpay' => [
195 'id' => 'razorpay',
196 'title' => __('Razorpay', 'yatra'),
197 'description' => __('Accept payments via Razorpay (India)', 'yatra'),
198 'icon' => YATRA_PLUGIN_URL . 'assets/images/payment-gateways/razorpay.svg',
199 'sandbox_url' => '',
200 'is_offline' => false,
201 'supports' => ['refunds'],
202 'fields' => [],
203 'config' => ['enabled' => false],
204 'enabled' => false,
205 'is_premium' => true,
206 'requires_pro' => true,
207 ],
208 'mollie' => [
209 'id' => 'mollie',
210 'title' => __('Mollie', 'yatra'),
211 'description' => __('Accept payments via Mollie (Europe)', 'yatra'),
212 'icon' => YATRA_PLUGIN_URL . 'assets/images/payment-gateways/mollie.svg',
213 'sandbox_url' => '',
214 'is_offline' => false,
215 'supports' => ['refunds'],
216 'fields' => [],
217 'config' => ['enabled' => false],
218 'enabled' => false,
219 'is_premium' => true,
220 'requires_pro' => true,
221 ],
222 'paystack' => [
223 'id' => 'paystack',
224 'title' => __('Paystack', 'yatra'),
225 'description' => __('Accept payments via Paystack (Africa)', 'yatra'),
226 'icon' => YATRA_PLUGIN_URL . 'assets/images/payment-gateways/paystack.svg',
227 'sandbox_url' => '',
228 'is_offline' => false,
229 'supports' => ['refunds'],
230 'fields' => [],
231 'config' => ['enabled' => false],
232 'enabled' => false,
233 'is_premium' => true,
234 'requires_pro' => true,
235 ],
236 'square' => [
237 'id' => 'square',
238 'title' => __('Square', 'yatra'),
239 'description' => __('Accept payments via Square (US/Canada)', 'yatra'),
240 'icon' => YATRA_PLUGIN_URL . 'assets/images/payment-gateways/square.svg',
241 'sandbox_url' => '',
242 'is_offline' => false,
243 'supports' => ['refunds'],
244 'fields' => [],
245 'config' => ['enabled' => false],
246 'enabled' => false,
247 'is_premium' => true,
248 'requires_pro' => true,
249 ],
250 'authorize_net' => [
251 'id' => 'authorize_net',
252 'title' => __('Authorize.Net', 'yatra'),
253 'description' => __('Accept payments via Authorize.Net (US)', 'yatra'),
254 'icon' => YATRA_PLUGIN_URL . 'assets/images/payment-gateways/authorize-net.svg',
255 'sandbox_url' => '',
256 'is_offline' => false,
257 'supports' => ['refunds'],
258 'fields' => [],
259 'config' => ['enabled' => false],
260 'enabled' => false,
261 'is_premium' => true,
262 'requires_pro' => true,
263 ],
264 'bank_transfer' => [
265 'id' => 'bank_transfer',
266 'title' => __('Bank Transfer', 'yatra'),
267 'description' => __('Accept manual bank transfer payments', 'yatra'),
268 'icon' => YATRA_PLUGIN_URL . 'assets/images/payment-gateways/bank_transfer.svg',
269 'sandbox_url' => '',
270 'is_offline' => true,
271 'supports' => [],
272 'fields' => [],
273 'config' => ['enabled' => false],
274 'enabled' => false,
275 'is_premium' => true,
276 'requires_pro' => true,
277 ],
278 ];
279 }
280
281 /**
282 * Gateways to show on checkout: all enabled in settings.
283 * Configuration is validated when processing payment (see processPayment).
284 */
285 public function getForCheckout(): array
286 {
287 $checkoutGateways = [];
288
289 foreach ($this->getEnabledGateways() as $id => $gateway) {
290 $config = $gateway->getConfig();
291 // Prefer a stored title/description ONLY when the operator actually
292 // customized it. The gateway's default title/description gets
293 // persisted into the config at install time, and using that stored
294 // English string here shadowed the translatable getTitle()/
295 // getDescription() — so the checkout label never translated. When
296 // the stored value equals the gateway's built-in default, fall
297 // through to the translated getter; a genuine custom value (which
298 // is operator free-text, not translatable) is still honored.
299 $storedTitle = isset($config['title']) ? (string) $config['title'] : '';
300 $storedDescription = isset($config['description']) ? (string) $config['description'] : '';
301 $checkoutGateways[] = [
302 'id' => $id,
303 'title' => ($storedTitle !== '' && $storedTitle !== $gateway->getDefaultTitle())
304 ? $storedTitle
305 : $gateway->getTitle(),
306 'description' => ($storedDescription !== '' && $storedDescription !== $gateway->getDefaultDescription())
307 ? $storedDescription
308 : $gateway->getDescription(),
309 'icon' => !empty($config['icon']) ? $config['icon'] : $gateway->getIcon(),
310 'is_offline' => $gateway->isOffline(),
311 'supports' => $gateway->getSupports(),
312 'is_configured' => $gateway->isProperlyConfigured(),
313 ];
314 }
315
316 return $checkoutGateways;
317 }
318
319 /**
320 * Save gateway configuration
321 */
322 public function saveGatewayConfig(string $gatewayId, array $config): bool
323 {
324 $gateway = $this->get($gatewayId);
325 if (!$gateway) {
326 return false;
327 }
328 return $gateway->saveConfig($config);
329 }
330
331 /**
332 * Process payment through a gateway
333 */
334 public function processPayment(string $gatewayId, array $paymentData): array
335 {
336 $gateway = $this->get($gatewayId);
337
338 if (!$gateway) {
339 return [
340 'success' => false,
341 'error' => __('Payment gateway not found', 'yatra'),
342 ];
343 }
344
345 if (!$gateway->isEnabled()) {
346 return [
347 'success' => false,
348 'error' => __('Payment gateway is not available', 'yatra'),
349 ];
350 }
351
352 if (!$gateway->isProperlyConfigured()) {
353 return [
354 'success' => false,
355 'error' => GatewayUserMessages::gatewayNotConfigured($gateway),
356 'code' => 'gateway_not_configured',
357 ];
358 }
359
360 return $gateway->processPayment($paymentData);
361 }
362
363 /**
364 * Enqueue scripts for all available gateways
365 */
366 public function enqueueScripts(): void
367 {
368 foreach ($this->getAvailable() as $gateway) {
369 if (method_exists($gateway, 'enqueueScripts')) {
370 $gateway->enqueueScripts();
371 }
372 }
373 }
374
375 /**
376 * Get frontend data for all available gateways
377 */
378 public function getFrontendData(): array
379 {
380 $data = [];
381
382 foreach ($this->getAvailable() as $id => $gateway) {
383 if (method_exists($gateway, 'getFrontendData')) {
384 $data[$id] = $gateway->getFrontendData();
385 }
386 }
387
388 return $data;
389 }
390 }
391
392