Changeset 3471417
- Timestamp:
- 02/28/2026 12:10:00 AM (4 weeks ago)
- Location:
- flywire-payment-gateway/trunk
- Files:
-
- 4 edited
-
CHANGELOG (modified) (1 diff)
-
flywire-payment-gateway.php (modified) (17 diffs)
-
includes/flywire-payment-gateway-request.php (modified) (6 diffs)
-
readme.txt (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
flywire-payment-gateway/trunk/CHANGELOG
r3227922 r3471417 2 2 All notable changes to this project will be documented in this file. 3 3 4 ## [1.0.11] - 2026-02-28 5 6 ### Added 7 - Implemented support for 5-char portal codes 8 - Implemented support for embed2.0 theme options. 9 10 ### Changed 11 - Fixed bug where 'pass_url" setting wasn't being saved properly, preventing ngrok use. 12 - Added order_id and sender_state into the default Field Mapping. 13 4 14 ## [1.0.10] - 2023-08-02 5 15 -
flywire-payment-gateway/trunk/flywire-payment-gateway.php
r3227922 r3471417 6 6 * Author: Flywire 7 7 * Author URI: http://www.flywire.com/ 8 * Version: 1.0.1 08 * Version: 1.0.11 9 9 * Text Domain: flywire-payment-gateway 10 10 * Domain Path: /i18n/languages/ … … 160 160 161 161 /** 162 * Flywire 3-letter portal code163 *164 * @var string165 */162 * Flywire portal code (5-character alphanumeric) 163 * 164 * @var string 165 */ 166 166 public $portal; 167 167 … … 277 277 */ 278 278 public $pass_url; 279 280 /** 281 * Enable the modal header with client logo and name 282 * 283 * @var bool 284 */ 285 public $enable_header; 286 287 /** 288 * Enable the modal footer with Flywire logo, language selector and Live Help link 289 * 290 * @var bool 291 */ 292 public $enable_footer; 293 294 /** 295 * Enable Live Help to Flywire Support 296 * 297 * @var bool 298 */ 299 public $enable_chat; 279 300 280 301 /** … … 304 325 $this->complete_order = 'yes' === $this->get_option( 'complete_order' ); 305 326 $this->on_guaranteed = 'yes' === $this->get_option( 'complete_on_guaranteed' ); 306 $this->portal = $this->testmode ? $this->get_option( 'demo_portal' ) : $this->get_option( 'prod_portal' ); 327 // Normalize portal codes to upper-case for consistency. 328 $this->portal = strtoupper( trim( $this->testmode ? $this->get_option( 'demo_portal' ) : $this->get_option( 'prod_portal' ) ) ); 307 329 $this->instructions = $this->get_option( 'instructions' ); 308 330 $this->field_mapping = $this->get_option( 'field_mapping' ); … … 312 334 $this->enable_proxy = 'yes' === $this->get_option( 'enable_proxy' ); 313 335 $this->proxy_url = $this->get_option( 'proxy_url' ); 336 $this->pass_url = 'yes' === $this->get_option( 'pass_url' ); 337 $this->enable_header = 'yes' === $this->get_option( 'enable_header' ); 338 $this->enable_footer = 'yes' === $this->get_option( 'enable_footer' ); 339 $this->enable_chat = 'yes' === $this->get_option( 'enable_chat' ); 314 340 $this->subunits_demo = $this->get_option( 'subunits_demo' ); 315 341 $this->subunits_prod = $this->get_option( 'subunits_prod' ); … … 400 426 'type' => 'textarea', 401 427 'description' => __( 'JSON configuration to define how WooCommerce fields will map to Flywire fields. Should be supplied by your Flywire Relationship Manager or Solutions Consultant.', 'flywire-payment-gateway' ), 402 'default' => "{\r\n\t\"sender_country\":\"{{billing_country}}\",\r\n\t\"sender_first_name\":\"{{billing_first_name}}\",\r\n\t\"sender_last_name\":\"{{billing_last_name}}\",\r\n\t\"sender_address1\":\"{{billing_address_1}}\",\r\n\t\"sender_phone\":\"{{billing_phone}}\",\r\n\t\"sender_city\":\"{{billing_city}}\",\r\n\t\"sender_zip\":\"{{billing_postcode}}\",\r\n\t\"sender_email\":\"{{billing_email}}\",\r\n\t\"s tudent_first_name\":\"{{billing_first_name}}\",\r\n\t\"student_last_name\":\"{{billing_last_name}}\",\r\n\t\"student_email\":\"{{billing_email}}\"\r\n}",428 'default' => "{\r\n\t\"sender_country\":\"{{billing_country}}\",\r\n\t\"sender_first_name\":\"{{billing_first_name}}\",\r\n\t\"sender_last_name\":\"{{billing_last_name}}\",\r\n\t\"sender_address1\":\"{{billing_address_1}}\",\r\n\t\"sender_phone\":\"{{billing_phone}}\",\r\n\t\"sender_city\":\"{{billing_city}}\",\r\n\t\"sender_zip\":\"{{billing_postcode}}\",\r\n\t\"sender_email\":\"{{billing_email}}\",\r\n\t\"sender_state\":\"{{billing_state}}\",\r\n\t\"student_first_name\":\"{{billing_first_name}}\",\r\n\t\"student_last_name\":\"{{billing_last_name}}\",\r\n\t\"student_email\":\"{{billing_email}}\",\r\n\t\"order_id\":\"{{order_number}}\"\r\n}", 403 429 'desc_tip' => true, 404 430 ), … … 429 455 ), 430 456 457 'theme_options' => array( 458 'title' => __( 'Theme Options', 'flywire-payment-gateway' ), 459 'type' => 'title', 460 'description' => __( 'Customize the appearance of the Flywire payment modal.', 'flywire-payment-gateway' ), 461 ), 462 463 'enable_header' => array( 464 'title' => __( 'Enable Header', 'flywire-payment-gateway' ), 465 'type' => 'checkbox', 466 'label' => __( 'Shows the modal header with client logo and name', 'flywire-payment-gateway' ), 467 'default' => 'yes', 468 ), 469 470 'enable_footer' => array( 471 'title' => __( 'Enable Footer', 'flywire-payment-gateway' ), 472 'type' => 'checkbox', 473 'label' => __( 'Shows the modal footer with Flywire logo, language selector and Live Help link', 'flywire-payment-gateway' ), 474 'default' => 'yes', 475 ), 476 477 'enable_chat' => array( 478 'title' => __( 'Enable Chat', 'flywire-payment-gateway' ), 479 'type' => 'checkbox', 480 'label' => __( 'Enable Live Help to Flywire Support (Enable Footer must be selected to enable)', 'flywire-payment-gateway' ), 481 'default' => 'yes', 482 ), 483 431 484 'payer_info' => array( 432 485 'title' => __( 'Payer Information Screen', 'flywire-payment-gateway' ), … … 458 511 'title' => __( 'Demo Portal Code', 'flywire-payment-gateway' ), 459 512 'type' => 'text', 460 'description' => __( 'The Demo portal code for your institution. A 3-letter code (e.g. FLC)', 'flywire-payment-gateway' ),513 'description' => __( 'The Demo portal code for your institution. A 5-character alphanumeric code (e.g. A1B2C)', 'flywire-payment-gateway' ), 461 514 'default' => '', 462 515 'desc_tip' => true, … … 466 519 'title' => __( 'Production Portal Code', 'flywire-payment-gateway' ), 467 520 'type' => 'text', 468 'description' => __( 'The production portal code for your institution. A 3-letter code (e.g. FLC)', 'flywire-payment-gateway' ),521 'description' => __( 'The production portal code for your institution. A 5-character alphanumeric code (e.g. A1B2C)', 'flywire-payment-gateway' ), 469 522 'default' => '', 470 523 'desc_tip' => true, … … 608 661 protected function validate_testmode( string $key, string $value, array $fields ): string { 609 662 $post_data = $this->get_post_data(); 610 611 if ( 'yes' === $value && empty( $this->get_field_value( 'demo_portal', $fields['demo_portal'], $post_data ) ) ) { 663 $demo_portal = trim( (string) $this->get_field_value( 'demo_portal', $fields['demo_portal'], $post_data ) ); 664 $prod_portal = trim( (string) $this->get_field_value( 'prod_portal', $fields['prod_portal'], $post_data ) ); 665 666 if ( 'yes' === $value && '' === $demo_portal ) { 612 667 throw new Exception( sprintf( __( 'If <strong>%s</strong> is enabled, <strong>%s</strong> is required.', 'flywire-payment-gateway' ), $fields[ $key ]['title'], $fields['demo_portal']['title'] ) ); 613 } elseif ( 'no' === $value && empty( $this->get_field_value( 'prod_portal', $fields['prod_portal'], $post_data ) )) {668 } elseif ( 'no' === $value && '' === $prod_portal ) { 614 669 throw new Exception( sprintf( __( 'If <strong>%s</strong> is enabled, <strong>%s</strong> is required.', 'flywire-payment-gateway' ), $fields[ $key ]['title'], $fields['prod_portal']['title'] ) ); 615 670 } … … 636 691 637 692 /** 638 * Validate demo_portal. Enforce 3-letter alphabetic code. 693 * Validate demo_portal. Enforce 5-character alphanumeric code (A-Z, 0-9). 694 * 695 * @param string $key The new setting key 696 * @param string $value The new setting value 697 * @param array $fields All form fields 698 * 699 * @return string 700 */ 701 protected function validate_demo_portal( string $key, string $value, array $fields ): string { 702 $value = strtoupper( trim( $value ) ); 703 704 $re = '/^[A-Z0-9]{5}$/'; 705 $valid = preg_match( $re, $value ); 706 707 if ( '' !== $value && ! $valid ) { 708 throw new Exception( __( $fields[ $key ]['title'] . ' must be a 5-character alphanumeric code (A-Z, 0-9), e.g. A1B2C.' ) ); 709 } 710 711 return $value; 712 } 713 714 /** 715 * Validate prod_portal. Enforce 5-character alphanumeric code (A-Z, 0-9). 716 * 717 * @param string $key The new setting key 718 * @param string $value The new setting value 719 * @param array $fields All form fields 720 * 721 * @return string 722 */ 723 protected function validate_prod_portal( string $key, string $value, array $fields ): string { 724 $value = strtoupper( trim( $value ) ); 725 726 $re = '/^[A-Z0-9]{5}$/'; 727 $valid = preg_match( $re, $value ); 728 729 if ( '' !== $value && ! $valid ) { 730 throw new Exception( __( $fields[ $key ]['title'] . ' must be a 5-character alphanumeric code (A-Z, 0-9), e.g. A1B2C.' ) ); 731 } 732 733 return $value; 734 } 735 736 /** 737 * Validate hidden_payer_fields. Enforce comma-separated list of strings that must be lowercase letters, numbers and underscores only. 639 738 * 640 739 * @param string $key The new setting key … … 644 743 * @return string 645 744 */ 646 protected function validate_ demo_portal( string $key, string $value, array $fields ): string {647 $re = '/^[a-zA-Z]{3}$/';648 $valid = preg_match_all( $re, $value, $matches, PREG_SET_ORDER);649 650 if ( ! empty( $value ) && !$valid ) {651 throw new Exception( __( $fields[ $key ]['title'] . ' must be a 3-letter code (e.g. FLY).' ) );745 protected function validate_hidden_payer_fields( string $key, string $value, array $fields ): string { 746 $re = '/^([a-z1-2_]+)(,\s*[a-z1-2_]+)*$/'; 747 $valid = preg_match_all($re, $value, $matches, PREG_SET_ORDER); 748 749 if ( $value !== '' && !$valid ) { 750 throw new Exception( __( 'Please provide a comma-delimited list of valid internal field names.' ) ); 652 751 } 653 752 … … 656 755 657 756 /** 658 * Validate prod_portal. Enforce 3-letter alphabetic code.757 * Validate enable_proxy. If enabled, require a value for proxy_url. 659 758 * 660 759 * @param string $key The new setting key … … 664 763 * @return string 665 764 */ 666 protected function validate_prod_portal( string $key, string $value, array $fields ): string {667 $re = '/^[a-zA-Z]{3}$/';668 $valid = preg_match_all( $re, $value, $matches, PREG_SET_ORDER );669 670 if ( ! empty( $value ) && ! $valid ) {671 throw new Exception( __( $fields[ $key ]['title'] . ' must be a 3-letter code (e.g. FLY).' ) );672 }673 674 return $value;675 }676 677 /**678 * Validate hidden_payer_fields. Enforce comma-separated list of strings that must be lowercase letters, numbers and underscores only.679 *680 * @param string $key The new setting key681 * @param string $value The new setting value682 * @param array $fields All form fields683 *684 * @return string685 */686 protected function validate_hidden_payer_fields( string $key, string $value, array $fields ): string {687 $re = '/^([a-z1-2_]+)(,\s*[a-z1-2_]+)*$/';688 $valid = preg_match_all($re, $value, $matches, PREG_SET_ORDER);689 690 if ( $value !== '' && !$valid ) {691 throw new Exception( __( 'Please provide a comma-delimited list of valid internal field names.' ) );692 }693 694 return $value;695 }696 697 /**698 * Validate enable_proxy. If enabled, require a value for proxy_url.699 *700 * @param string $key The new setting key701 * @param string $value The new setting value702 * @param array $fields All form fields703 *704 * @return string705 */706 765 protected function validate_enable_proxy( string $key, string $value, array $fields ): string { 707 766 $post_data = $this->get_post_data(); … … 709 768 if ( 'yes' === $value && empty( $this->get_field_value( 'proxy_url', $fields['proxy_url'], $post_data ) ) ) { 710 769 throw new Exception( sprintf( __( 'If <strong>%s</strong> is enabled, <strong>%s</strong> is required.', 'flywire-payment-gateway' ), $fields[ $key ]['title'], $fields['proxy_url']['title'] ) ); 770 } 771 772 return $value; 773 } 774 775 protected function validate_enable_chat( string $key, string $value, array $fields ): string { 776 $post_data = $this->get_post_data(); 777 778 if ( 'yes' === $value && 'yes' !== $this->get_field_value( 'enable_footer', $fields['enable_footer'], $post_data ) ) { 779 throw new Exception( __( 'Enable Footer must be selected to enable Live Help', 'flywire-payment-gateway' ) ); 711 780 } 712 781 … … 773 842 * 774 843 */ 775 public function flywire_thankyou_order_received_text( string $text, WC_Order $order ): string { 844 public function flywire_thankyou_order_received_text( string $text, $order ): string { 845 global $wp; 846 self::log( 'Entering flywire_thankyou_order_received_text. Order object type: ' . gettype( $order ) . '. Query vars: ' . json_encode($wp->query_vars) ); 847 if ( ! is_a( $order, 'WC_Order' ) ) { 848 return $text; 849 } 776 850 $method = $order->get_payment_method(); 777 851 if ( $method !== 'flywire' ) { … … 810 884 $portal_info = array( 811 885 "demo" => array( 812 "code" => $this->get_option( 'demo_portal'),886 "code" => strtoupper( trim( $this->get_option( 'demo_portal' ) ) ), 813 887 "subunits" => null, 814 888 "currency" => null 815 889 ), 816 890 "prod" => array( 817 "code" => $this->get_option( 'prod_portal'),891 "code" => strtoupper( trim( $this->get_option( 'prod_portal' ) ) ), 818 892 "subunits" => null, 819 893 "currency" => null -
flywire-payment-gateway/trunk/includes/flywire-payment-gateway-request.php
r3227922 r3471417 33 33 34 34 /** 35 * Flywire 3-letter portal code35 * Flywire portal code (5-character alphanumeric) 36 36 * 37 37 * @var string … … 94 94 */ 95 95 public $pass_url; 96 97 /** 98 * Enable the modal header with client logo and name 99 * 100 * @var bool 101 */ 102 public $enable_header; 103 104 /** 105 * Enable the modal footer with Flywire logo, language selector and Live Help link 106 * 107 * @var bool 108 */ 109 public $enable_footer; 110 111 /** 112 * Enable Live Help to Flywire Support 113 * 114 * @var bool 115 */ 116 public $enable_chat; 96 117 97 118 /** … … 137 158 * @param string $order_id WC order ID 138 159 */ 139 public function __construct( WC_Gateway_Flywire $gateway, string $order_id ) { 140 $this->order = wc_get_order( $order_id ); 141 $this->testmode = $gateway->testmode; 142 $this->mapping = json_decode( $gateway->field_mapping ); 143 $this->portal = apply_filters( 'flywpg_portal_code', $gateway->portal, $this->order, $gateway->testmode ); 144 $this->subunits_demo = $gateway->subunits_demo; 145 $this->subunits_prod = $gateway->subunits_prod; 146 $this->currency_demo = $gateway->currency_demo; 147 $this->currency_prod = $gateway->currency_prod; 148 $this->currency = apply_filters( 'flywpg_portal_currency', $this->get_currency(), $this->portal ); 149 $this->number_of_subunits_in_currency = apply_filters( 'flywpg_portal_subunits', $this->get_subunits(), $this->order->get_currency() ); 150 $this->display_payer_info = $gateway->display_payer_info; 151 $this->hidden_payer_fields = $gateway->hidden_payer_fields; 152 $this->api_url = $gateway->api_url; 153 $this->return_url = $gateway->get_return_url( $this->order ); 154 $this->enable_proxy = $gateway->enable_proxy; 155 $this->proxy_url = $gateway->proxy_url; 156 $this->pass_url = $gateway->pass_url; 157 } 160 public function __construct( WC_Gateway_Flywire $gateway, string $order_id ) { 161 $this->order = wc_get_order( $order_id ); 162 $this->testmode = $gateway->testmode; 163 $this->mapping = json_decode( $gateway->field_mapping ); 164 // Ensure consistent formatting even if a filter overrides the code. 165 $this->portal = strtoupper( trim( (string) apply_filters( 'flywpg_portal_code', $gateway->portal, $this->order, $gateway->testmode ) ) ); 166 $this->subunits_demo = $gateway->subunits_demo; 167 $this->subunits_prod = $gateway->subunits_prod; 168 $this->currency_demo = $gateway->currency_demo; 169 $this->currency_prod = $gateway->currency_prod; 170 $this->currency = apply_filters( 'flywpg_portal_currency', $this->get_currency(), $this->portal ); 171 $this->number_of_subunits_in_currency = apply_filters( 'flywpg_portal_subunits', $this->get_subunits(), $this->order->get_currency() ); 172 $this->display_payer_info = $gateway->display_payer_info; 173 $this->hidden_payer_fields = $gateway->hidden_payer_fields; 174 $this->api_url = $gateway->api_url; 175 $this->return_url = $gateway->get_return_url( $this->order ); 176 $this->enable_proxy = $gateway->enable_proxy; 177 $this->proxy_url = $gateway->proxy_url; 178 $this->pass_url = $gateway->pass_url; 179 $this->enable_header = $gateway->enable_header; 180 $this->enable_footer = $gateway->enable_footer; 181 $this->enable_chat = $gateway->enable_chat; 182 } 158 183 159 184 /** … … 195 220 if ($this->display_payer_info && isset($this->hidden_payer_fields)) 196 221 $settings['hidden'] = $this->hidden_payer_fields; 222 $settings['theme'] = array( 223 'header' => $this->enable_header, 224 'footer' => $this->enable_footer, 225 'chat' => $this->enable_chat 226 ); 197 227 foreach ( $this->mapping as $key => $value ) { 198 228 $settings[ $key ] = $this->expand_template( $value, $this->order ); … … 206 236 'sender_address1', 207 237 'sender_city', 208 'sender_zip',209 238 'sender_email' 210 239 ); … … 283 312 $value = $obj->get_meta( ltrim($key, '_') ); // try without underscore 284 313 } else { // native WC Order field 285 if ( ! method_exists( $obj, 'get_' . $matches[0][2] ) ) { 314 if ( $matches[0][2] === 'order_number' ) { 315 // For order number, use get_order_number() method which exists on WC_Order 316 $value = $obj->get_order_number(); 317 } elseif ( ! method_exists( $obj, 'get_' . $matches[0][2] ) ) { 286 318 wc_add_notice( __( 'Field mapping failed: Method get_' . $matches[0][2] . '() not found.' ) ); 319 $value = ''; 320 } else { 321 $value = call_user_func( array( $obj, 'get_' . $matches[0][2] ) ); 287 322 } 288 $value = call_user_func( array( $obj, 'get_' . $matches[0][2] ) );289 323 } 290 324 $template = str_replace( $matches[0][0], $value, $template ); -
flywire-payment-gateway/trunk/readme.txt
r3227922 r3471417 3 3 Tags: woocommerce, credit card, bank transfer, pay, payment gateway 4 4 Requires at least: 5.7 5 Tested up to: 6. 26 Stable tag: 1.0.1 05 Tested up to: 6.9.1 6 Stable tag: 1.0.11 7 7 Requires PHP: 8.0 8 8 License: GPLv2 or later … … 27 27 28 28 == Changelog == 29 30 = 1.0.11 = 31 * Implemented support for 5-char portal codes 32 * Fixed bug where 'pass_url" setting wasn't being saved properly, preventing ngrok use. 33 * Added order_id and sender_state into the default Field Mapping. 34 * Implemented support for embed2.0 theme options. 29 35 30 36 = 1.0.10 =
Note: See TracChangeset
for help on using the changeset viewer.