PluginProbe
SureDonation – Donation Forms, Fundraising Campaigns & Donor Management / 1.1.0
SureDonation – Donation Forms, Fundraising Campaigns & Donor Management v1.1.0
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 -173 1.5.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,138 +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 - // Both audiences are told the gateways are not configured, but only donors
688 - // are told to contact the administrator — an admin *is* that person and
689 - // gets the actionable button below, so the sentence would send them in a
690 - // circle. Mirrors the capability + settings-URL pattern used by
691 - // get_test_mode_notice().
692 - $is_admin = current_user_can( 'manage_options' );
693 - $configure_url = '';
694 - $configure_text = '';
695 - $notice_text = $is_admin
696 - ? __( 'Payment gateways are not configured.', 'suredonation' )
697 - : __( 'Payment gateways are not configured. Please contact the site administrator.', 'suredonation' );
698 -
699 - if ( $is_admin ) {
700 - // Route the admin to the right place. If a gateway is already usable
701 - // on the site, the block simply hasn't selected it — send them to
702 - // this form's editor to fix the payment block. Otherwise no gateway
703 - // is set up at all — send them to global payment settings.
704 - $edit_link = $this->form_id > 0 ? get_edit_post_link( (int) $this->form_id ) : '';
705 -
706 - if ( Payment_Helper::has_usable_gateway() && $edit_link ) {
707 - $configure_url = $edit_link;
708 - $configure_text = __( 'Edit this form’s payment settings', 'suredonation' );
709 - } else {
710 - // No gateway connected — send the admin straight to the gateway
711 - // connect screen (Stripe) rather than the currency/mode page.
712 - $configure_url = Payment_Helper::get_settings_url( 'stripe' );
713 - $configure_text = __( 'Configure payment gateway', 'suredonation' );
714 - }
715 - }
716 -
717 - ob_start();
718 - ?>
719 - <div
720 - data-block-id="<?php echo esc_attr( $this->block_id ); ?>"
721 - data-form-id="<?php echo esc_attr( $this->form_id ); ?>"
722 - data-payment-available="0"
723 - class="<?php echo esc_attr( $field_classes ); ?>"
724 - >
725 - <?php echo wp_kses_post( $this->label_markup ); ?>
726 - <div class="sd-payment-field-wrapper">
727 - <div class="sd-payment-notice" role="status">
728 - <p><?php echo esc_html( $notice_text ); ?></p>
729 - <?php echo wp_kses_post( $is_admin ? $this->render_configure_link( $configure_url, $configure_text ) : '' ); ?>
730 - </div>
731 - </div>
732 - </div>
733 - <?php
734 - $output = ob_get_clean();
735 - return false !== $output ? $output : '';
736 - }
737 -
738 - /**
739 - * Render the admin-only notice shown when the payment field renders but no
740 - * real payment gateway is connected.
741 - *
742 - * Enabling Offline Donation makes the field render normally, so the
743 - * donor-facing "gateways are not configured" notice never fires — an admin
744 - * viewing the live form gets no signal that neither Stripe nor PayPal was
745 - * ever connected. Offline is a manual method, not a gateway, so the prompt
746 - * is still warranted. Donors see nothing: the form works for them.
747 - *
748 - * @return string Notice markup, or empty string when a gateway is connected
749 - * or the viewer is not an administrator.
750 - * @since 1.4.0
751 - */
752 - private function get_gateway_setup_notice() {
753 - if ( ! current_user_can( 'manage_options' ) || Payment_Helper::is_any_gateway_connected() ) {
754 - return '';
755 - }
756 -
757 - ob_start();
758 - ?>
759 - <div class="sd-payment-notice sd-payment-notice--admin" role="status">
760 - <p><?php esc_html_e( 'No payment gateway is connected, so donors can only give using the offline method.', 'suredonation' ); ?></p>
761 - <?php
762 - echo wp_kses_post(
763 - $this->render_configure_link(
764 - Payment_Helper::get_settings_url( 'stripe' ),
765 - __( 'Configure payment gateway', 'suredonation' )
766 - )
767 - );
768 - ?>
769 - </div>
770 - <?php
771 - $output = ob_get_clean();
772 - return false !== $output ? $output : '';
773 - }
774 -
775 - /**
776 - * Render the actionable settings link shared by the payment notices.
777 - *
778 - * @param string $url Target URL.
779 - * @param string $text Link text.
780 - * @return string Link markup, or empty string when there is nothing to link to.
781 - * @since 1.4.0
782 - */
783 - private function render_configure_link( $url, $text ) {
784 - if ( '' === $url || '' === $text ) {
785 - return '';
786 - }
787 -
788 - ob_start();
789 - ?>
790 - <a
791 - class="sd-payment-notice__configure"
792 - href="<?php echo esc_url( $url ); ?>"
793 - target="_blank"
794 - rel="noopener noreferrer"
795 - >
796 - <?php echo esc_html( $text ); ?>
797 - </a>
798 662 <?php
799 663 $output = ob_get_clean();
800 664 return false !== $output ? $output : '';
801 665 }