PluginProbe
Yatra – Travel Booking & Tour Operator Software / 3.0.9
Yatra – Travel Booking & Tour Operator Software v3.0.9
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 2.0.11 All 82 releases
yatra / app / Controllers / PaymentController.php

PaymentController.php in Yatra – Travel Booking & Tour Operator Software 3.0.9, at app/Controllers/PaymentController.php

235 lines 7.3 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\Controllers;
6
7 use WP_REST_Request;
8 use WP_REST_Response;
9 use WP_Error;
10 use Yatra\Services\PaymentService;
11
12 /**
13 * Payment REST API Controller
14 *
15 * Handles payment record operations (listing, viewing, managing payments)
16 */
17 class PaymentController extends BaseController
18 {
19 /**
20 * REST API namespace
21 */
22 protected string $namespace = 'yatra/v1';
23
24 /**
25 * Payment service instance
26 */
27 private PaymentService $paymentService;
28
29 /**
30 * Constructor - Initialize services
31 */
32 public function __construct()
33 {
34 $this->paymentService = new PaymentService();
35 }
36
37 /**
38 * Register REST API routes
39 */
40 public function register_routes(): void
41 {
42 // Payment stats — view cap (read-only aggregates).
43 register_rest_route($this->namespace, '/payments/stats', [
44 [
45 'methods' => 'GET',
46 'callback' => [$this, 'getPaymentStats'],
47 'permission_callback' => [$this, 'checkCanView'],
48 ],
49 ]);
50
51 // List + create payments. Create needs the edit-bookings cap
52 // because adding a payment mutates the booking's payment state.
53 register_rest_route($this->namespace, '/payments', [
54 [
55 'methods' => 'GET',
56 'callback' => [$this, 'getPayments'],
57 'permission_callback' => [$this, 'checkCanView'],
58 ],
59 [
60 'methods' => 'POST',
61 'callback' => [$this, 'createPayment'],
62 'permission_callback' => [$this, 'checkCanEdit'],
63 ]
64 ]);
65
66 // Single-payment read / update / delete. Update + delete are
67 // refund-equivalent operations from the customer's perspective
68 // (changing the amount or removing a recorded payment can
69 // affect what the customer owes), so we gate them on the
70 // dedicated refund cap. Accountant role holds refund without
71 // holding edit-bookings, so they can issue refunds without
72 // also being able to edit the underlying booking.
73 register_rest_route($this->namespace, '/payments/(?P<id>\d+)', [
74 [
75 'methods' => 'GET',
76 'callback' => [$this, 'getPayment'],
77 'permission_callback' => [$this, 'checkCanView'],
78 ],
79 [
80 'methods' => 'PUT',
81 'callback' => [$this, 'updatePayment'],
82 'permission_callback' => [$this, 'checkCanRefund'],
83 ],
84 [
85 'methods' => 'DELETE',
86 'callback' => [$this, 'deletePayment'],
87 'permission_callback' => [$this, 'checkCanRefund'],
88 ]
89 ]);
90 }
91
92 /**
93 * Granular permission checks. WP administrators pass every cap
94 * via the Team module's admin-fallback filter, so an explicit
95 * `manage_options` check isn't needed at this layer.
96 */
97 public function checkCanView(): bool
98 {
99 return current_user_can('yatra_view_bookings');
100 }
101
102 public function checkCanEdit(): bool
103 {
104 return current_user_can('yatra_edit_bookings');
105 }
106
107 public function checkCanRefund(): bool
108 {
109 // Refund cap is high-sensitivity. Held by Owner + Manager +
110 // Accountant by default. Sales Agent / Front Desk / Guide
111 // can record payments via the create endpoint above but
112 // cannot modify or delete existing ones.
113 return current_user_can('yatra_refund_bookings');
114 }
115
116 /**
117 * @deprecated Kept for any external code referencing the old
118 * method name. Routes to view — safer than the old "view OR
119 * manage_options" shorthand, and admin users still pass via
120 * the admin-fallback layer.
121 */
122 public function checkAdminPermission(): bool
123 {
124 return $this->checkCanView();
125 }
126
127 /**
128 * GET /payments/stats - Counts per status for admin toolbar
129 */
130 public function getPaymentStats(WP_REST_Request $request): WP_REST_Response
131 {
132 $counts = $this->paymentService->getAdminStatusCounts();
133
134 return new WP_REST_Response($counts, 200);
135 }
136
137 /**
138 * GET /payments - List all payments
139 */
140 public function getPayments(WP_REST_Request $request): WP_REST_Response
141 {
142 $filters = [
143 'page' => (int) ($request->get_param('page') ?: 1),
144 'per_page' => (int) ($request->get_param('per_page') ?: 20),
145 'booking_id' => (int) $request->get_param('booking_id'),
146 'status' => $request->get_param('status') ?: '',
147 'gateway' => $request->get_param('gateway') ?: '',
148 'search' => $request->get_param('search') ?: '',
149 'date_from' => $request->get_param('date_from') ?: '',
150 'date_to' => $request->get_param('date_to') ?: '',
151 ];
152
153 $result = $this->paymentService->getPayments($filters);
154
155 return new WP_REST_Response([
156 'data' => $result['data'],
157 'total' => $result['total'],
158 'page' => $filters['page'],
159 'per_page' => $filters['per_page'],
160 'total_pages' => ceil($result['total'] / $filters['per_page']),
161 ], 200);
162 }
163
164 /**
165 * GET /payments/{id} - Get single payment
166 */
167 public function getPayment(WP_REST_Request $request)
168 {
169 $id = (int) $request->get_param('id');
170 $payment = $this->paymentService->getPayment($id);
171
172 if (!$payment) {
173 return new WP_Error('payment_not_found', 'Payment not found', ['status' => 404]);
174 }
175
176 return new WP_REST_Response($payment, 200);
177 }
178
179 /**
180 * POST /payments - Create payment
181 */
182 public function createPayment(WP_REST_Request $request)
183 {
184 $data = $request->get_json_params();
185
186 try {
187 $payment = $this->paymentService->createPayment($data);
188 return new WP_REST_Response($payment, 201);
189 } catch (\Exception $e) {
190 return new WP_Error('payment_creation_failed', $e->getMessage(), ['status' => 400]);
191 }
192 }
193
194 /**
195 * PUT /payments/{id} - Update payment
196 */
197 public function updatePayment(WP_REST_Request $request)
198 {
199 $id = (int) $request->get_param('id');
200 $data = $request->get_json_params();
201
202 try {
203 $payment = $this->paymentService->updatePayment($id, $data);
204
205 if (!$payment) {
206 return new WP_Error('payment_not_found', 'Payment not found', ['status' => 404]);
207 }
208
209 return new WP_REST_Response($payment, 200);
210 } catch (\Exception $e) {
211 return new WP_Error('payment_update_failed', $e->getMessage(), ['status' => 400]);
212 }
213 }
214
215 /**
216 * DELETE /payments/{id} - Delete payment
217 */
218 public function deletePayment(WP_REST_Request $request)
219 {
220 $id = (int) $request->get_param('id');
221
222 try {
223 $result = $this->paymentService->deletePayment($id);
224
225 if (!$result) {
226 return new WP_Error('payment_not_found', 'Payment not found', ['status' => 404]);
227 }
228
229 return new WP_REST_Response(['success' => true], 200);
230 } catch (\Exception $e) {
231 return new WP_Error('payment_deletion_failed', $e->getMessage(), ['status' => 400]);
232 }
233 }
234 }
235