Plugin Directory

Changeset 3471417


Ignore:
Timestamp:
02/28/2026 12:10:00 AM (4 weeks ago)
Author:
taiflywire
Message:

Updating trunk with GitLab release 1.0.11

Location:
flywire-payment-gateway/trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • flywire-payment-gateway/trunk/CHANGELOG

    r3227922 r3471417  
    22All notable changes to this project will be documented in this file.
    33 
     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
    414## [1.0.10] - 2023-08-02
    515
  • flywire-payment-gateway/trunk/flywire-payment-gateway.php

    r3227922 r3471417  
    66 * Author: Flywire
    77 * Author URI: http://www.flywire.com/
    8  * Version: 1.0.10
     8 * Version: 1.0.11
    99 * Text Domain: flywire-payment-gateway
    1010 * Domain Path: /i18n/languages/
     
    160160
    161161        /**
    162          * Flywire 3-letter portal code
    163         *
    164         * @var string
    165         */
     162             * Flywire portal code (5-character alphanumeric)
     163            *
     164            * @var string
     165            */
    166166        public $portal;
    167167
     
    277277         */
    278278        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;
    279300
    280301        /**
     
    304325            $this->complete_order                 = 'yes' === $this->get_option( 'complete_order' );
    305326            $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' ) ) );
    307329            $this->instructions                   = $this->get_option( 'instructions' );
    308330            $this->field_mapping                  = $this->get_option( 'field_mapping' );
     
    312334            $this->enable_proxy                   = 'yes' === $this->get_option( 'enable_proxy' );
    313335            $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' );
    314340            $this->subunits_demo                  = $this->get_option( 'subunits_demo' );
    315341            $this->subunits_prod                  = $this->get_option( 'subunits_prod' );
     
    400426                    'type'        => 'textarea',
    401427                    '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\"student_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}",
    403429                    'desc_tip'    => true,
    404430                ),
     
    429455                ),
    430456
     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
    431484                'payer_info' => array(
    432485                    'title'       => __( 'Payer Information Screen', 'flywire-payment-gateway' ),
     
    458511                    'title'       => __( 'Demo Portal Code', 'flywire-payment-gateway' ),
    459512                    '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' ),
    461514                    'default'     => '',
    462515                    'desc_tip'    => true,
     
    466519                    'title'       => __( 'Production Portal Code', 'flywire-payment-gateway' ),
    467520                    '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' ),
    469522                    'default'     => '',
    470523                    'desc_tip'    => true,
     
    608661        protected function validate_testmode( string $key, string $value, array $fields ): string {
    609662            $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 ) {
    612667                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 ) {
    614669                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'] ) );
    615670            }
     
    636691
    637692        /**
    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.
    639738         *
    640739         * @param string $key The new setting key
     
    644743         * @return string
    645744         */
    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.' ) );
    652751            }
    653752
     
    656755
    657756        /**
    658          * Validate prod_portal. Enforce 3-letter alphabetic code.
     757         * Validate enable_proxy. If enabled, require a value for proxy_url.
    659758         *
    660759         * @param string $key The new setting key
     
    664763         * @return string
    665764         */
    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 key
    681          * @param string $value The new setting value
    682          * @param array $fields All form fields
    683          *
    684          * @return string
    685          */
    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 key
    701          * @param string $value The new setting value
    702          * @param array $fields All form fields
    703          *
    704          * @return string
    705          */
    706765        protected function validate_enable_proxy( string $key, string $value, array $fields ): string {
    707766            $post_data = $this->get_post_data();
     
    709768            if ( 'yes' === $value && empty( $this->get_field_value( 'proxy_url', $fields['proxy_url'], $post_data ) ) ) {
    710769                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' ) );
    711780            }
    712781
     
    773842         *
    774843         */
    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            }
    776850            $method = $order->get_payment_method();
    777851            if ( $method !== 'flywire' ) {
     
    810884            $portal_info = array(
    811885                "demo" => array(
    812                     "code"     => $this->get_option( 'demo_portal' ),
     886                    "code"     => strtoupper( trim( $this->get_option( 'demo_portal' ) ) ),
    813887                    "subunits" => null,
    814888                    "currency" => null
    815889                ),
    816890                "prod" => array(
    817                     "code"     => $this->get_option( 'prod_portal' ),
     891                    "code"     => strtoupper( trim( $this->get_option( 'prod_portal' ) ) ),
    818892                    "subunits" => null,
    819893                    "currency" => null
  • flywire-payment-gateway/trunk/includes/flywire-payment-gateway-request.php

    r3227922 r3471417  
    3333
    3434    /**
    35      * Flywire 3-letter portal code
     35     * Flywire portal code (5-character alphanumeric)
    3636     *
    3737     * @var string
     
    9494     */
    9595    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;
    96117
    97118    /**
     
    137158     * @param string $order_id WC order ID
    138159     */
    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        }
    158183
    159184    /**
     
    195220        if ($this->display_payer_info && isset($this->hidden_payer_fields))
    196221            $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        );
    197227        foreach ( $this->mapping as $key => $value ) {
    198228            $settings[ $key ] = $this->expand_template( $value, $this->order );
     
    206236            'sender_address1',
    207237            'sender_city',
    208             'sender_zip',
    209238            'sender_email'
    210239        );
     
    283312                    $value = $obj->get_meta( ltrim($key, '_') ); // try without underscore
    284313            } 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] ) ) {
    286318                    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] ) );
    287322                }
    288                 $value = call_user_func( array( $obj, 'get_' . $matches[0][2] ) );
    289323            }
    290324            $template = str_replace( $matches[0][0], $value, $template );
  • flywire-payment-gateway/trunk/readme.txt

    r3227922 r3471417  
    33Tags: woocommerce, credit card, bank transfer, pay, payment gateway
    44Requires at least: 5.7
    5 Tested up to: 6.2
    6 Stable tag: 1.0.10
     5Tested up to: 6.9.1
     6Stable tag: 1.0.11
    77Requires PHP: 8.0
    88License: GPLv2 or later
     
    2727
    2828== 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.
    2935
    3036= 1.0.10 =
Note: See TracChangeset for help on using the changeset viewer.