PluginProbe
SureForms – Contact Form Builder, AI Forms, Payment Form, Survey & Quiz / 2.12.8
SureForms – Contact Form Builder, AI Forms, Payment Form, Survey & Quiz v2.12.8
2.12.8 2.12.7 2.12.6 2.12.5 2.12.4 2.12.3 2.12.2 2.12.1 2.12.0 2.11.1 2.11.0 2.10.1 2.10.0 2.9.1 2.9.0 2.8.2 2.8.1 2.7.0 2.7.1 2.8.0 trunk 0.0.10 0.0.11 0.0.12 0.0.13 All 98 releases
← All changes | inc/payments/stripe/admin-stripe-handler.php +35 -54 2.9.1 → 2.12.8 View file →
@@ -102,64 +102,43 @@
102 102 if ( empty( $payment['subscription_id'] ) ) {
103 103 wp_send_json_error( [ 'message' => esc_html__( 'Subscription ID not found.', 'sureforms' ) ] );
104 104 }
105 105
106 - // Cancel the subscription.
107 - $cancel_result = $this->cancel_subscription( $payment['subscription_id'] );
108 - if ( ! $cancel_result ) {
109 - wp_send_json_error( [ 'message' => esc_html__( 'Subscription cancellation failed.', 'sureforms' ) ] );
106 + // Cancel via the gateway-agnostic filter so the payment's OWN gateway (Stripe or
107 + // PayPal) performs the cancellation. Previously this called the Stripe API directly,
108 + // which failed for PayPal subscriptions cancelled from the admin screen. Both gateways
109 + // hook 'srfm_process_subscription_cancellation' (Stripe + PayPal), matching the
110 + // frontend cancellation path.
111 + $cancel_result = apply_filters(
112 + 'srfm_process_subscription_cancellation',
113 + [
114 + 'success' => false,
115 + 'message' => __( 'Cancellation is not supported for this payment gateway.', 'sureforms' ),
116 + ],
117 + $payment
118 + );
119 +
120 + if ( empty( $cancel_result['success'] ) ) {
121 + wp_send_json_error(
122 + [
123 + 'message' => ! empty( $cancel_result['message'] ) && is_string( $cancel_result['message'] )
124 + ? esc_html( $cancel_result['message'] )
125 + : esc_html__( 'Subscription cancellation failed.', 'sureforms' ),
126 + ]
127 + );
110 128 }
111 129
112 - // Get current logs and add cancel log entry.
113 - $current_logs = Helper::get_array_value( $payment['log'] );
114 -
115 - // Build log messages array.
116 - $log_messages = [
117 - sprintf(
118 - /* translators: %s: Stripe subscription ID */
119 - __( 'Subscription ID: %s', 'sureforms' ),
120 - $payment['subscription_id']
121 - ),
122 - sprintf(
123 - /* translators: %s: payment gateway name */
124 - __( 'Payment Gateway: %s', 'sureforms' ),
125 - 'Stripe'
126 - ),
127 - sprintf(
128 - /* translators: %s: subscription status */
129 - __( 'Subscription Status: %s', 'sureforms' ),
130 - __( 'Canceled', 'sureforms' )
131 - ),
132 - sprintf(
133 - /* translators: %s: user display name */
134 - __( 'Canceled by: %s', 'sureforms' ),
135 - wp_get_current_user()->display_name
136 - ),
137 - __( 'Note: The subscription has been permanently canceled. The customer will no longer be charged and will lose access to subscription benefits.', 'sureforms' ),
138 - ];
139 -
140 - // Create new log entry.
141 - $new_log = [
142 - 'title' => __( 'Subscription Canceled', 'sureforms' ),
143 - 'created_at' => current_time( 'mysql' ),
144 - 'messages' => $log_messages,
145 - ];
146 - $current_logs[] = $new_log;
147 -
148 - // Preserve the transaction `status` (e.g. 'succeeded') so the Refund option
149 - // remains available; lifecycle is tracked via `subscription_status`.
150 - $updated = Payments::update(
151 - $payment_id,
130 + // The gateway callback (Stripe/PayPal) is the single source of truth: it has already
131 + // cancelled at the gateway AND persisted subscription_status + the "Subscription Canceled"
132 + // activity log. Just report success here — mirroring the frontend cancel path — so we don't
133 + // write the DB a second time or append a duplicate log entry.
134 + wp_send_json_success(
152 135 [
153 - 'subscription_status' => 'canceled',
154 - 'log' => $current_logs,
136 + 'message' => ! empty( $cancel_result['message'] ) && is_string( $cancel_result['message'] )
137 + ? esc_html( $cancel_result['message'] )
138 + : esc_html__( 'Subscription cancelled successfully.', 'sureforms' ),
155 139 ]
156 140 );
157 - if ( ! $updated ) {
158 - wp_send_json_error( [ 'message' => esc_html__( 'Failed to update subscription status in database.', 'sureforms' ) ] );
159 - }
160 -
161 - wp_send_json_success( [ 'message' => esc_html__( 'Subscription canceled successfully!', 'sureforms' ) ] );
162 141 }
163 142
164 143 /**
165 144 * Process Stripe subscription cancellation via filter system.
@@ -172,10 +151,12 @@
172 151 * @param array<string,mixed> $payment Payment record from database.
173 152 * @return array<string,mixed> Result with success status and message.
174 153 */
175 154 public function process_stripe_subscription_cancellation( $result, $payment ) {
176 - // Only process Stripe payments.
177 - if ( empty( $payment['gateway'] ) || 'stripe' !== $payment['gateway'] ) {
155 + // Process Stripe payments. Stripe is the only gateway in the free plugin, and the
156 + // `gateway` column defaults to '' for legacy/imported rows — so an empty gateway is
157 + // treated as Stripe. Only an explicitly different gateway (e.g. 'paypal') is skipped.
158 + if ( ! empty( $payment['gateway'] ) && 'stripe' !== $payment['gateway'] ) {
178 159 return $result;
179 160 }
180 161
181 162 if ( empty( $payment['subscription_id'] ) || ! is_string( $payment['subscription_id'] ) ) {
@@ -1034,9 +1015,9 @@
1034 1015 if ( is_string( $charge_id ) && '' !== $charge_id ) {
1035 1016 return $this->create_refund_by_charge( $payment, $charge_id, $refund_amount, $refund_notes );
1036 1017 }
1037 1018
1038 - throw new \Exception( __( 'Unable to determine the appropriate refund method for this subscription payment.', 'sureforms' ) );
1019 + throw new \Exception( esc_html__( 'Unable to determine the appropriate refund method for this subscription payment.', 'sureforms' ) );
1039 1020 }
1040 1021
1041 1022 /**
1042 1023 * Create refund using charge ID