PluginProbe
Timetics – Appointment Booking Calendar & Scheduling / 1.0.38
Timetics – Appointment Booking Calendar & Scheduling v1.0.38
1.0.62 1.0.63 1.0.61 1.0.60 1.0.59 1.0.58 1.0.57 1.0.56 trunk 1.0.0 1.0.1 1.0.10 1.0.11 1.0.12 1.0.13 1.0.14 1.0.15 1.0.16 1.0.17 1.0.18 1.0.19 1.0.2 1.0.20 1.0.21 1.0.22 All 64 releases
← All changes | core/integrations/stripe/stripe-payment.php +5 -190 1.0.63 → 1.0.38 View file →
@@ -5,10 +5,8 @@
5 5 * @package Timetics
6 6 */
7 7 namespace Timetics\Core\Integrations\Stripe;
8 8
9 -defined( 'ABSPATH' ) || exit;
10 -
11 9 /**
12 10 * Class StripePayment
13 11 */
14 12 class StripePayment {
@@ -27,35 +25,23 @@
27 25 * @return array
28 26 */
29 27 public function create_payment( $args = [] ) {
30 28 $defaults = [
31 - 'amount' => '',
32 - 'currency' => '',
33 - 'metadata' => [],
29 + 'amount' => '',
30 + 'currency' => '',
34 31 ];
35 32
36 - $args = wp_parse_args( $args, $defaults );
33 + $args = wp_parse_args( $args, $defaults );
37 34
38 - $metadata = is_array( $args['metadata'] ) ? $args['metadata'] : [];
39 - unset( $args['metadata'] );
40 -
41 35 $url = $this->payment_intent_url;
42 36 $secret = timetics_get_option( 'stripe_secret_key' );
43 - $body = build_query( $args ) . '&automatic_payment_methods[enabled]=true';
44 -
45 - foreach ( $metadata as $meta_key => $meta_value ) {
46 - if ( $meta_value === '' || $meta_value === null ) {
47 - continue;
48 - }
49 - $body .= '&metadata[' . rawurlencode( (string) $meta_key ) . ']=' . rawurlencode( (string) $meta_value );
50 - }
51 -
37 + $args = build_query( $args ) . '&automatic_payment_methods[enabled]=true';
52 38 $params = [
53 39 'headers' => [
54 40 'Authorization' => 'Bearer ' . $secret,
55 41 'Content-Type' => 'application/x-www-form-urlencoded;charset=UTF-8',
56 42 ],
57 - 'body' => $body,
43 + 'body' => $args,
58 44 ];
59 45
60 46 $response = wp_remote_post( $url, $params );
61 47
@@ -68,177 +54,6 @@
68 54 */
69 55 do_action( 'timetics/integrations/stripe/create_payment', $response );
70 56
71 57 return $response;
72 - }
73 -
74 - /**
75 - * Update an existing Stripe PaymentIntent's metadata server-side.
76 - * Used to bind a PaymentIntent to a booking after the booking is created
77 - * but before the customer confirms the payment.
78 - *
79 - * @param string $intent_id PaymentIntent id (pi_...).
80 - * @param array $metadata Key/value pairs to set on the intent.
81 - *
82 - * @return array|\WP_Error Decoded Stripe response, or WP_Error on failure.
83 - */
84 - public function update_payment_intent( $intent_id, $metadata = [] ) {
85 - $intent_id = is_string( $intent_id ) ? trim( $intent_id ) : '';
86 -
87 - if ( '' === $intent_id || strpos( $intent_id, 'pi_' ) !== 0 ) {
88 - return new \WP_Error( 'timetics_stripe_invalid_intent', __( 'Invalid Stripe payment intent id.', 'timetics' ) );
89 - }
90 -
91 - $secret = timetics_get_option( 'stripe_secret_key' );
92 -
93 - if ( empty( $secret ) ) {
94 - return new \WP_Error( 'timetics_stripe_missing_secret', __( 'Stripe secret key is not configured.', 'timetics' ) );
95 - }
96 -
97 - $body_parts = [];
98 - foreach ( (array) $metadata as $meta_key => $meta_value ) {
99 - if ( $meta_value === '' || $meta_value === null ) {
100 - continue;
101 - }
102 - $body_parts[] = 'metadata[' . rawurlencode( (string) $meta_key ) . ']=' . rawurlencode( (string) $meta_value );
103 - }
104 -
105 - if ( empty( $body_parts ) ) {
106 - return new \WP_Error( 'timetics_stripe_empty_metadata', __( 'No metadata provided.', 'timetics' ) );
107 - }
108 -
109 - $response = wp_remote_post(
110 - $this->payment_intent_url . '/' . rawurlencode( $intent_id ),
111 - [
112 - 'headers' => [
113 - 'Authorization' => 'Bearer ' . $secret,
114 - 'Content-Type' => 'application/x-www-form-urlencoded;charset=UTF-8',
115 - ],
116 - 'body' => implode( '&', $body_parts ),
117 - 'timeout' => 15,
118 - ]
119 - );
120 -
121 - if ( is_wp_error( $response ) ) {
122 - return $response;
123 - }
124 -
125 - $code = (int) wp_remote_retrieve_response_code( $response );
126 - $body = json_decode( wp_remote_retrieve_body( $response ), true );
127 -
128 - if ( $code < 200 || $code >= 300 ) {
129 - $message = is_array( $body ) && ! empty( $body['error']['message'] )
130 - ? $body['error']['message']
131 - : __( 'Stripe payment intent update failed.', 'timetics' );
132 - return new \WP_Error( 'timetics_stripe_update_failed', $message, [ 'status' => $code ] );
133 - }
134 -
135 - if ( ! is_array( $body ) ) {
136 - return new \WP_Error( 'timetics_stripe_invalid_response', __( 'Unexpected Stripe response.', 'timetics' ) );
137 - }
138 -
139 - return $body;
140 - }
141 -
142 - /**
143 - * Retrieve a Stripe PaymentIntent server-side for verification.
144 - *
145 - * @param string $intent_id PaymentIntent id (pi_...).
146 - *
147 - * @return array|\WP_Error Decoded Stripe response, or WP_Error on transport / API failure.
148 - */
149 - public function retrieve_payment_intent( $intent_id ) {
150 - $intent_id = is_string( $intent_id ) ? trim( $intent_id ) : '';
151 -
152 - if ( '' === $intent_id || strpos( $intent_id, 'pi_' ) !== 0 ) {
153 - return new \WP_Error( 'timetics_stripe_invalid_intent', __( 'Invalid Stripe payment intent id.', 'timetics' ) );
154 - }
155 -
156 - $secret = timetics_get_option( 'stripe_secret_key' );
157 -
158 - if ( empty( $secret ) ) {
159 - return new \WP_Error( 'timetics_stripe_missing_secret', __( 'Stripe secret key is not configured.', 'timetics' ) );
160 - }
161 -
162 - $url = $this->payment_intent_url . '/' . rawurlencode( $intent_id );
163 -
164 - $response = wp_remote_get(
165 - $url,
166 - [
167 - 'headers' => [
168 - 'Authorization' => 'Bearer ' . $secret,
169 - ],
170 - 'timeout' => 15,
171 - ]
172 - );
173 -
174 - if ( is_wp_error( $response ) ) {
175 - return $response;
176 - }
177 -
178 - $code = (int) wp_remote_retrieve_response_code( $response );
179 - $body = json_decode( wp_remote_retrieve_body( $response ), true );
180 -
181 - if ( $code < 200 || $code >= 300 ) {
182 - $message = is_array( $body ) && ! empty( $body['error']['message'] )
183 - ? $body['error']['message']
184 - : __( 'Stripe payment intent retrieval failed.', 'timetics' );
185 - return new \WP_Error( 'timetics_stripe_retrieve_failed', $message, [ 'status' => $code ] );
186 - }
187 -
188 - if ( ! is_array( $body ) ) {
189 - return new \WP_Error( 'timetics_stripe_invalid_response', __( 'Unexpected Stripe response.', 'timetics' ) );
190 - }
191 -
192 - return $body;
193 - }
194 -
195 - /**
196 - * Cancel a Stripe PaymentIntent. Used by the unpaid-booking cleanup sweep
197 - * so a card can't be charged after we've already released the slot.
198 - * Stripe refuses this if the intent already succeeded — that failure is
199 - * the caller's signal to leave the booking alone instead of cancelling it.
200 - *
201 - * @param string $intent_id PaymentIntent id (pi_...).
202 - *
203 - * @return array|\WP_Error Decoded Stripe response, or WP_Error on failure.
204 - */
205 - public function cancel_payment_intent( $intent_id ) {
206 - $intent_id = is_string( $intent_id ) ? trim( $intent_id ) : '';
207 -
208 - if ( '' === $intent_id || strpos( $intent_id, 'pi_' ) !== 0 ) {
209 - return new \WP_Error( 'timetics_stripe_invalid_intent', __( 'Invalid Stripe payment intent id.', 'timetics' ) );
210 - }
211 -
212 - $secret = timetics_get_option( 'stripe_secret_key' );
213 -
214 - if ( empty( $secret ) ) {
215 - return new \WP_Error( 'timetics_stripe_missing_secret', __( 'Stripe secret key is not configured.', 'timetics' ) );
216 - }
217 -
218 - $response = wp_remote_post(
219 - $this->payment_intent_url . '/' . rawurlencode( $intent_id ) . '/cancel',
220 - [
221 - 'headers' => [
222 - 'Authorization' => 'Bearer ' . $secret,
223 - ],
224 - 'timeout' => 15,
225 - ]
226 - );
227 -
228 - if ( is_wp_error( $response ) ) {
229 - return $response;
230 - }
231 -
232 - $code = (int) wp_remote_retrieve_response_code( $response );
233 - $body = json_decode( wp_remote_retrieve_body( $response ), true );
234 -
235 - if ( $code < 200 || $code >= 300 ) {
236 - $message = is_array( $body ) && ! empty( $body['error']['message'] )
237 - ? $body['error']['message']
238 - : __( 'Stripe payment intent cancellation failed.', 'timetics' );
239 - return new \WP_Error( 'timetics_stripe_cancel_failed', $message, [ 'status' => $code ] );
240 - }
241 -
242 - return is_array( $body ) ? $body : [];
243 58 }
244 59 }