PluginProbe
SureDonation – Donation Forms, Fundraising Campaigns & Donor Management / 1.1.0
SureDonation – Donation Forms, Fundraising Campaigns & Donor Management v1.1.0
1.6.1 1.6.0 1.5.1 1.5.0 1.4.0 1.3.0 trunk 0.0.1 1.0.0 1.1.0 1.1.1 1.1.2 1.2.0
← All changes | inc/fields/payment-markup.php +37 -169 1.4.0 → 1.1.0 View file →
@@ -171,13 +171,10 @@
171 171 if ( empty( $this->currency ) || 'USD' === $this->currency ) {
172 172 $this->currency = Payment_Helper::get_currency();
173 173 }
174 174
175 - // Get the publishable key for this form's selected account (mode-aware).
176 - $this->stripe_publishable_key = Stripe_Helper::get_stripe_publishable_key(
177 - '',
178 - Stripe_Helper::resolve_account_for_form( $this->form_id )
179 - );
175 + // Get appropriate Stripe publishable key based on mode.
176 + $this->stripe_publishable_key = Stripe_Helper::get_stripe_publishable_key();
180 177
181 178 // Fall back to one-time if subscription is configured but pro is not active.
182 179 $configured_type = $attributes['paymentType'] ?? 'one-time';
183 180 $this->payment_type = 'subscription' === $configured_type && ! defined( 'SUREDONATION_PRO_VER' ) ? 'one-time' : $configured_type;
@@ -240,25 +237,24 @@
240 237 * @return string
241 238 * @since 0.0.1
242 239 */
243 240 public function markup() {
244 - $has_stripe = in_array( 'stripe', $this->payment_methods, true );
241 + $has_stripe = in_array( 'stripe', $this->payment_methods, true );
242 + $has_offline = in_array( 'offline', $this->payment_methods, true );
245 243
246 - // Determine which gateways are actually connected/available for this form.
247 - // get_registered_payment_methods() returns only enabled methods (Stripe when
248 - // connected, Offline when enabled, plus any added by extensions such as
249 - // PayPal), so it is the single gateway-agnostic source of truth.
250 - $methods = $this->get_registered_payment_methods();
244 + // If only Stripe is selected, it must be connected.
245 + if ( $has_stripe && ! $has_offline && ( ! $this->stripe_connected || empty( $this->stripe_publishable_key ) ) ) {
246 + return '';
247 + }
251 248
252 - // No payment gateway is connected/available. Show a clear message instead of
253 - // returning an empty string, which previously left donors with a silently
254 - // broken form and no way to donate. See issue #219.
255 - if ( empty( $methods ) ) {
256 - return $this->render_gateway_unavailable_notice();
249 + // If no gateway is available at all, hide the block.
250 + if ( empty( $this->payment_methods ) ) {
251 + return '';
257 252 }
258 253
259 254 // Validate payment field requirements.
260 - if ( ! $this->validate_payment_requirements() ) {
255 + $is_valid = $this->validate_payment_requirements();
256 + if ( ! $is_valid ) {
261 257 return '';
262 258 }
263 259
264 260 $field_classes = $this->get_field_classes();
@@ -308,18 +304,15 @@
308 304 if ( 'test' === $this->payment_mode && $has_stripe ) {
309 305 echo wp_kses_post( $this->get_test_mode_notice() );
310 306 }
311 307
312 - // Admin-only: the form renders (Offline is enabled) but no real
313 - // gateway is connected.
314 - echo wp_kses_post( $this->get_gateway_setup_notice() );
315 -
316 - // Payment methods accordion ( $methods computed above ).
308 + // Payment methods accordion.
309 + $methods = $this->get_registered_payment_methods();
317 310 echo $this->render_payment_methods_accordion( $methods ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Method builds markup with esc_attr/esc_html on all dynamic values and wp_kses_post on content.
318 311 ?>
319 312
320 - <!-- Payment error display (hidden via CSS; shown by JS on error). -->
321 - <div class="sd-payment-error"></div>
313 + <!-- Payment error display -->
314 + <div class="sd-payment-error" style="display: none;"></div>
322 315 </div>
323 316 </div>
324 317 <?php
325 318 $output = ob_get_clean();
@@ -342,9 +335,9 @@
342 335 'container_id' => 'sd-payment-element-' . $this->block_id,
343 336 ],
344 337 'offline' => [
345 338 'id' => 'offline',
346 - 'label' => __( 'Offline Donation', 'suredonation' ),
339 + 'label' => __( 'Offline Payment', 'suredonation' ),
347 340 'enabled' => Offline_Helper::is_offline_enabled(),
348 341 'container_class' => 'sd-offline-instructions',
349 342 'content' => Offline_Helper::get_offline_instructions( $this->get_campaign_name() ),
350 343 ],
@@ -414,20 +407,15 @@
414 407 <div
415 408 class="sd-accordion-item <?php echo esc_attr( $is_first ? 'sd-payment-active' : '' ); ?>"
416 409 data-method="<?php echo esc_attr( $method['id'] ); ?>"
417 410 >
418 - <?php if ( $is_single_method ) { ?>
419 - <?php // Single method: the header is a static label, not an accordion toggle, so omit the interactive button semantics (keyboard/screen-reader users shouldn't hit an inert "button"). ?>
420 - <div class="sd-accordion-header">
421 - <?php } else { ?>
422 - <div
423 - class="sd-accordion-header"
424 - role="button"
425 - tabindex="0"
426 - aria-expanded="<?php echo esc_attr( $is_first ? 'true' : 'false' ); ?>"
427 - aria-controls="sd-accordion-content-<?php echo esc_attr( $method['id'] ); ?>-<?php echo esc_attr( $this->block_id ); ?>"
428 - >
429 - <?php } ?>
411 + <div
412 + class="sd-accordion-header"
413 + role="button"
414 + tabindex="0"
415 + aria-expanded="<?php echo esc_attr( $is_first ? 'true' : 'false' ); ?>"
416 + aria-controls="sd-accordion-content-<?php echo esc_attr( $method['id'] ); ?>-<?php echo esc_attr( $this->block_id ); ?>"
417 + >
430 418 <div class="sd-payment-input-wrapper">
431 419 <input
432 420 type="radio"
433 421 name="sd-gateway-choice-<?php echo esc_attr( $this->block_id ); ?>"
@@ -443,9 +431,9 @@
443 431 </div>
444 432 </div>
445 433 <div
446 434 id="sd-accordion-content-<?php echo esc_attr( $method['id'] ); ?>-<?php echo esc_attr( $this->block_id ); ?>"
447 - class="sd-accordion-content<?php echo Offline_Helper::is_blank_instructions( $method['content'] ?? '' ) ? ' sd-accordion-content-empty' : ''; ?>"
435 + class="sd-accordion-content"
448 436 role="region"
449 437 >
450 438 <div
451 439 class="sd-payment-method-content"
@@ -616,11 +604,17 @@
616 604 * @return string
617 605 * @since 0.0.1
618 606 */
619 607 private function format_currency( $amount, $currency ) {
620 - // Delegate to the single source of truth so decimal handling and the
621 - // currency sign position stay consistent with every other surface.
622 - return Payment_Helper::format_amount( $amount, $currency );
608 + $symbol = Payment_Helper::get_currency_symbol( $currency );
609 +
610 + // Format based on currency.
611 + if ( in_array( $currency, [ 'JPY', 'KRW' ], true ) ) {
612 + // No decimal places for these currencies.
613 + return $symbol . number_format( $amount, 0 );
614 + }
615 +
616 + return $symbol . number_format( $amount, 2 );
623 617 }
624 618
625 619 /**
626 620 * Get the human-readable label for a payment interval slug.
@@ -653,10 +647,10 @@
653 647 if ( ! current_user_can( 'manage_options' ) ) {
654 648 return '';
655 649 }
656 650
657 - // Build dynamic link to payment settings (shared, hash-routed URL).
658 - $settings_url = Payment_Helper::get_settings_url();
651 + // Build dynamic link to payment settings.
652 + $settings_url = admin_url( 'admin.php?page=suredonation_settings&tab=payments' );
659 653
660 654 ob_start();
661 655 ?>
662 656 <div class="sd-test-mode-notice">
@@ -664,134 +658,8 @@
664 658 <a href="<?php echo esc_url( $settings_url ); ?>" target="_blank" rel="noopener noreferrer">
665 659 <?php esc_html_e( 'Click here to enable live mode and accept payment', 'suredonation' ); ?>
666 660 </a>
667 661 </div>
668 - <?php
669 - $output = ob_get_clean();
670 - return false !== $output ? $output : '';
671 - }
672 -
673 - /**
674 - * Render the notice shown when no payment gateway is connected/available.
675 - *
676 - * Replaces the previous behavior of rendering nothing, which left donors with
677 - * a silently broken form. The `data-payment-available="0"` marker lets the
678 - * frontend script skip gateway init and hide the otherwise-inert submit
679 - * button. See issue #219.
680 - *
681 - * @return string Notice markup.
682 - * @since 1.1.1
683 - */
684 - private function render_gateway_unavailable_notice() {
685 - $field_classes = $this->get_field_classes( [ 'sd-payment-unavailable' ] );
686 -
687 - // The notice text is shown to everyone (admins and donors). Admins
688 - // additionally get an actionable button; donors see the notice without
689 - // it. Mirrors the capability + settings-URL pattern used by
690 - // get_test_mode_notice().
691 - $is_admin = current_user_can( 'manage_options' );
692 - $configure_url = '';
693 - $configure_text = '';
694 -
695 - if ( $is_admin ) {
696 - // Route the admin to the right place. If a gateway is already usable
697 - // on the site, the block simply hasn't selected it — send them to
698 - // this form's editor to fix the payment block. Otherwise no gateway
699 - // is set up at all — send them to global payment settings.
700 - $edit_link = $this->form_id > 0 ? get_edit_post_link( (int) $this->form_id ) : '';
701 -
702 - if ( Payment_Helper::has_usable_gateway() && $edit_link ) {
703 - $configure_url = $edit_link;
704 - $configure_text = __( 'Edit this form’s payment settings', 'suredonation' );
705 - } else {
706 - // No gateway connected — send the admin straight to the gateway
707 - // connect screen (Stripe) rather than the currency/mode page.
708 - $configure_url = Payment_Helper::get_settings_url( 'stripe' );
709 - $configure_text = __( 'Configure payment gateway', 'suredonation' );
710 - }
711 - }
712 -
713 - ob_start();
714 - ?>
715 - <div
716 - data-block-id="<?php echo esc_attr( $this->block_id ); ?>"
717 - data-form-id="<?php echo esc_attr( $this->form_id ); ?>"
718 - data-payment-available="0"
719 - class="<?php echo esc_attr( $field_classes ); ?>"
720 - >
721 - <?php echo wp_kses_post( $this->label_markup ); ?>
722 - <div class="sd-payment-field-wrapper">
723 - <div class="sd-payment-notice" role="status">
724 - <p><?php esc_html_e( 'Payment gateways are not configured. Please contact the site administrator.', 'suredonation' ); ?></p>
725 - <?php echo wp_kses_post( $is_admin ? $this->render_configure_link( $configure_url, $configure_text ) : '' ); ?>
726 - </div>
727 - </div>
728 - </div>
729 - <?php
730 - $output = ob_get_clean();
731 - return false !== $output ? $output : '';
732 - }
733 -
734 - /**
735 - * Render the admin-only notice shown when the payment field renders but no
736 - * real payment gateway is connected.
737 - *
738 - * Enabling Offline Donation makes the field render normally, so the
739 - * donor-facing "gateways are not configured" notice never fires — an admin
740 - * viewing the live form gets no signal that neither Stripe nor PayPal was
741 - * ever connected. Offline is a manual method, not a gateway, so the prompt
742 - * is still warranted. Donors see nothing: the form works for them.
743 - *
744 - * @return string Notice markup, or empty string when a gateway is connected
745 - * or the viewer is not an administrator.
746 - * @since 1.4.0
747 - */
748 - private function get_gateway_setup_notice() {
749 - if ( ! current_user_can( 'manage_options' ) || Payment_Helper::is_any_gateway_connected() ) {
750 - return '';
751 - }
752 -
753 - ob_start();
754 - ?>
755 - <div class="sd-payment-notice sd-payment-notice--admin" role="status">
756 - <p><?php esc_html_e( 'No payment gateway is connected, so donors can only give using the offline method.', 'suredonation' ); ?></p>
757 - <?php
758 - echo wp_kses_post(
759 - $this->render_configure_link(
760 - Payment_Helper::get_settings_url( 'stripe' ),
761 - __( 'Configure payment gateway', 'suredonation' )
762 - )
763 - );
764 - ?>
765 - </div>
766 - <?php
767 - $output = ob_get_clean();
768 - return false !== $output ? $output : '';
769 - }
770 -
771 - /**
772 - * Render the actionable settings link shared by the payment notices.
773 - *
774 - * @param string $url Target URL.
775 - * @param string $text Link text.
776 - * @return string Link markup, or empty string when there is nothing to link to.
777 - * @since 1.4.0
778 - */
779 - private function render_configure_link( $url, $text ) {
780 - if ( '' === $url || '' === $text ) {
781 - return '';
782 - }
783 -
784 - ob_start();
785 - ?>
786 - <a
787 - class="sd-payment-notice__configure"
788 - href="<?php echo esc_url( $url ); ?>"
789 - target="_blank"
790 - rel="noopener noreferrer"
791 - >
792 - <?php echo esc_html( $text ); ?>
793 - </a>
794 662 <?php
795 663 $output = ob_get_clean();
796 664 return false !== $output ? $output : '';
797 665 }