Plugin Directory

Changeset 3385037


Ignore:
Timestamp:
10/27/2025 08:28:24 AM (4 months ago)
Author:
versionnext
Message:

Prepare 1.1.3: fixes/changes

Location:
formpays-pro
Files:
5 added
7 edited

Legend:

Unmodified
Added
Removed
  • formpays-pro/trunk/CHANGELOG.md

    r3379943 r3385037  
    11# FormPays Pro - Changelog
     2---
     3
     4## [1.1.3] - 2024-12-19
     5
     6### Email Notifications & Payment Gateway Enhancements
     7**Comprehensive Email System & Razorpay Integration Improvements**
     8
     9#### New Features
     10- **Email Notifications System**:
     11  - Added "Email Notifications & Confirmations" admin menu
     12  - 4 customizable email templates (Payment Success/Failed for Customer/Admin)
     13  - Automatic email sending on payment events
     14  - Test email functionality to verify settings
     15  - Dynamic placeholders: `{transaction_id}`, `{amount}`, `{customer_name}`, `{customer_email}`, `{payment_date}`, `{payment_method}`, `{form_title}`, `{site_name}`
     16- **Smart Phone Number Formatting**:
     17  - Automatically adds country code for Razorpay compatibility
     18  - Formats numbers in `+{country code}{phone number}` format
     19  - Handles various input formats (with/without country code)
     20
     21#### Bug Fixes
     22- **Fixed Deprecated Property Warning**: Declared `$email_handler` property to fix PHP 8.2+ deprecation warning
     23- **Payment Method Selection**: Payment method selected on form now properly passed to Razorpay gateway
     24- **Phone Number Prefilling**: Customer phone number now correctly prefilled in Razorpay checkout page
     25- **Transaction Time Display**: Success page now shows correct transaction completion time
     26- **Success Page Enhancement**: Improved success page with more transaction details and better styling
     27
     28#### Code Quality
     29- **WordPress Coding Standards**: Fixed placeholder ordering in translatable strings
     30- **Nonce Verification**: Added proper phpcs:ignore comments for email settings save
     31- **External Assets**: Moved email notifications JavaScript and CSS to external files (`assets/js/email-notifications.js`, `assets/css/email-notifications.css`)
     32
    233---
    334
  • formpays-pro/trunk/README.txt

    r3379943 r3385037  
    66Requires PHP: 5.6
    77Requires PHP: 7.4
    8 Stable tag: 1.1.2
     8Stable tag: 1.1.3
    99Plugin URI: https://version-next.com/formpays-pro/
    1010Author URI: https://version-next.com/
     
    2727* **Transaction Management**: Complete payment tracking and management
    2828* **Email Notifications**: Automatic notifications for payments and failures
     29* **Email Templates**: Customize notification emails for customers and admins
    2930
    3031= Payment Gateways =
     
    14114211. Analytics Dashboard
    14214312. Drag and Drop Form Field
     14413. Notification Email Template
    143145
    144146== External Services ==
     
    380382= Available Notifications =
    381383
    382 * **Transaction Created**: Sent to customer and admin
    383 * **Payment Success**: Sent to customer and admin
    384 * **Payment Failure**: Sent to customer with retry information
     384* **Payment Success - Customer**: Confirmation email to customer with transaction details
     385* **Payment Success - Admin**: Notification to admin about successful payment
     386* **Payment Failed - Customer**: Failure notification with retry information
     387* **Payment Failed - Admin**: Alert to admin about failed payment
     388
     389= Email Template Customization =
     390
     3911. Go to **FormPays Pro → Email Notifications**
     3922. Customize email templates with dynamic placeholders:
     393   - `{transaction_id}` - Transaction ID
     394   - `{amount}` - Payment amount
     395   - `{customer_name}` - Customer name
     396   - `{customer_email}` - Customer email
     397   - `{payment_date}` - Payment date and time
     398   - `{payment_method}` - Selected payment method
     399   - `{form_title}` - Form title
     400   - `{site_name}` - Your site name
     4013. Enable/disable individual email notifications
     4024. Test email functionality to verify settings
    385403
    386404= Customization =
     
    449467
    450468== Changelog ==
     469
     470= 1.1.3 =
     471* **Features**: Added Email Notifications & Confirmations menu with customizable email templates
     472* **Features**: Automatic email notifications for payment success and failure to customers and admins
     473* **Features**: Test email functionality to verify email settings
     474* **Features**: Smart phone number formatting with country code for Razorpay integration
     475* **Bug Fix**: Fixed deprecated dynamic property warning for email_handler
     476* **Bug Fix**: Resolved payment method selection not being passed to Razorpay gateway
     477* **Bug Fix**: Fixed customer phone number not being prefilled in Razorpay checkout
     478* **Bug Fix**: Corrected transaction time display on success page
     479* **Enhancement**: Enhanced success page with more detailed transaction information
     480* **Code Quality**: Fixed placeholder ordering in translatable strings
     481* **Code Quality**: Added WordPress Coding Standards compliance for email notifications
    451482
    452483= 1.1.2 =
  • formpays-pro/trunk/admin/class-formpays-pro-admin.php

    r3379943 r3385037  
    3030        add_action( 'wp_ajax_formpays_pro_bulk_delete_transactions', array( $this, 'ajax_bulk_delete_transactions' ) );
    3131        add_action( 'wp_ajax_formpays_pro_bulk_approve_transactions', array( $this, 'ajax_bulk_approve_transactions' ) );
     32        add_action( 'wp_ajax_formpays_pro_send_test_email', array( $this, 'ajax_send_test_email' ) );
    3233    }
    3334    /**
     
    9394            'formpays-pro-analytics',
    9495            array( $this, 'analytics_page' )
     96        );
     97        add_submenu_page(
     98            'formpays-pro',
     99            __( 'Email Notifications', 'formpays-pro' ),
     100            __( 'Email Notifications', 'formpays-pro' ),
     101            'manage_options',
     102            'formpays-pro-email-notifications',
     103            array( $this, 'email_notifications_page' )
    95104        );
    96105        add_submenu_page(
     
    216225                    'export_nonce' => wp_create_nonce( 'formpays_pro_export_transactions' ),
    217226                    'debug'        => defined( 'WP_DEBUG' ) && WP_DEBUG,
     227                )
     228            );
     229        }
     230
     231        // Enqueue email notifications-specific styles and scripts
     232        if ( strpos( $hook, 'formpays-pro-email-notifications' ) !== false ) {
     233            wp_enqueue_style(
     234                'formpays-pro-email-notifications',
     235                FORMPAYS_PRO_PLUGIN_URL . 'assets/css/email-notifications.css',
     236                array( 'formpays-pro-admin' ),
     237                FORMPAYS_PRO_VERSION
     238            );
     239
     240            wp_enqueue_script(
     241                'formpays-pro-email-notifications',
     242                FORMPAYS_PRO_PLUGIN_URL . 'assets/js/email-notifications.js',
     243                array( 'jquery', 'formpays-pro-admin' ),
     244                FORMPAYS_PRO_VERSION,
     245                true
     246            );
     247
     248            // Localize email notifications script
     249            wp_localize_script(
     250                'formpays-pro-email-notifications',
     251                'formpays_pro_email_notifications',
     252                array(
     253                    'ajax_url'           => admin_url( 'admin-ajax.php' ),
     254                    'nonce'              => wp_create_nonce( 'formpays_pro_test_email' ),
     255                    'please_enter_email' => esc_html__( 'Please enter a test email address.', 'formpays-pro' ),
     256                    'sending'            => esc_html__( 'Sending...', 'formpays-pro' ),
     257                    'test_email_sent'    => esc_html__( 'Test email sent successfully!', 'formpays-pro' ),
     258                    'failed_to_send'     => esc_html__( 'Failed to send test email: ', 'formpays-pro' ),
     259                    'unknown_error'      => esc_html__( 'Unknown error', 'formpays-pro' ),
     260                    'failed_to_send_error' => esc_html__( 'Failed to send test email. Please try again.', 'formpays-pro' ),
    218261                )
    219262            );
     
    11321175        include FORMPAYS_PRO_PLUGIN_DIR . 'admin/views/analytics.php';
    11331176    }
     1177
     1178    /**
     1179     * Email notifications page
     1180     */
     1181    public function email_notifications_page() {
     1182        // Handle form submission for email settings
     1183        if ( isset( $_POST['formpays_pro_email_nonce'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['formpays_pro_email_nonce'] ) ), 'formpays_pro_email_settings' ) ) {
     1184            $this->handle_email_settings_save();
     1185        }
     1186
     1187        // Get current email settings
     1188        $email_settings = get_option( 'formpays_pro_email_settings', array() );
     1189       
     1190        // Default email templates
     1191        $default_templates = array(
     1192            'payment_success_customer' => array(
     1193                'subject' => __( 'Payment Confirmation - Transaction #{transaction_id}', 'formpays-pro' ),
     1194                'message' => __( 'Dear {customer_name},
     1195
     1196Thank you for your payment! Your transaction has been completed successfully.
     1197
     1198Transaction Details:
     1199- Transaction ID: {transaction_id}
     1200- Amount: {amount}
     1201- Payment Date: {payment_date}
     1202- Payment Method: {payment_method}
     1203
     1204If you have any questions, please contact us.
     1205
     1206Best regards,
     1207{site_name}', 'formpays-pro' ),
     1208                'enabled' => true,
     1209            ),
     1210            'payment_success_admin' => array(
     1211                'subject' => __( 'New Payment Received - Transaction #{transaction_id}', 'formpays-pro' ),
     1212                'message' => __( 'A new payment has been received:
     1213
     1214Transaction Details:
     1215- Transaction ID: {transaction_id}
     1216- Amount: {amount}
     1217- Customer Name: {customer_name}
     1218- Customer Email: {customer_email}
     1219- Payment Date: {payment_date}
     1220- Payment Method: {payment_method}
     1221- Form: {form_title}
     1222
     1223Please check your admin panel for more details.', 'formpays-pro' ),
     1224                'enabled' => true,
     1225            ),
     1226            'payment_failed_customer' => array(
     1227                'subject' => __( 'Payment Failed - Transaction #{transaction_id}', 'formpays-pro' ),
     1228                'message' => __( 'Dear {customer_name},
     1229
     1230We were unable to process your payment for transaction #{transaction_id}.
     1231
     1232Amount: {amount}
     1233Payment Date: {payment_date}
     1234
     1235Please try again or contact us for assistance.
     1236
     1237Best regards,
     1238{site_name}', 'formpays-pro' ),
     1239                'enabled' => true,
     1240            ),
     1241            'payment_failed_admin' => array(
     1242                'subject' => __( 'Payment Failed - Transaction #{transaction_id}', 'formpays-pro' ),
     1243                'message' => __( 'A payment has failed:
     1244
     1245Transaction Details:
     1246- Transaction ID: {transaction_id}
     1247- Amount: {amount}
     1248- Customer Name: {customer_name}
     1249- Customer Email: {customer_email}
     1250- Payment Date: {payment_date}
     1251- Form: {form_title}
     1252
     1253Please check the transaction details in your admin panel.', 'formpays-pro' ),
     1254                'enabled' => true,
     1255            ),
     1256        );
     1257
     1258        // Merge with defaults
     1259        $email_templates = array();
     1260        foreach ( $default_templates as $key => $default ) {
     1261            $email_templates[ $key ] = isset( $email_settings[ $key ] ) ? wp_parse_args( $email_settings[ $key ], $default ) : $default;
     1262        }
     1263
     1264        // Get admin email settings
     1265        $admin_email = isset( $email_settings['admin_email'] ) ? $email_settings['admin_email'] : get_option( 'admin_email' );
     1266        $from_name = isset( $email_settings['from_name'] ) ? $email_settings['from_name'] : get_bloginfo( 'name' );
     1267        $from_email = isset( $email_settings['from_email'] ) ? $email_settings['from_email'] : get_option( 'admin_email' );
     1268
     1269        // Include the email notifications view
     1270        include FORMPAYS_PRO_PLUGIN_DIR . 'admin/views/email-notifications.php';
     1271    }
     1272
     1273    /**
     1274     * Handle email settings save
     1275     */
     1276    private function handle_email_settings_save() {
     1277        if ( ! current_user_can( 'manage_options' ) ) {
     1278            wp_die( esc_html__( 'You do not have permission to perform this action.', 'formpays-pro' ) );
     1279        }
     1280
     1281        $email_settings = array();
     1282
     1283        // Save admin email settings
     1284        // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Nonce verification handled in email_notifications_page()
     1285        $email_settings['admin_email'] = sanitize_email( wp_unslash( $_POST['admin_email'] ?? '' ) );
     1286        // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Nonce verification handled in email_notifications_page()
     1287        $email_settings['from_name'] = sanitize_text_field( wp_unslash( $_POST['from_name'] ?? '' ) );
     1288        // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Nonce verification handled in email_notifications_page()
     1289        $email_settings['from_email'] = sanitize_email( wp_unslash( $_POST['from_email'] ?? '' ) );
     1290
     1291        // Save email templates
     1292        $template_keys = array( 'payment_success_customer', 'payment_success_admin', 'payment_failed_customer', 'payment_failed_admin' );
     1293       
     1294        foreach ( $template_keys as $key ) {
     1295            // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Nonce verification handled in email_notifications_page()
     1296            $email_settings[ $key ] = array(
     1297                // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Nonce verification handled in email_notifications_page()
     1298                'subject' => sanitize_text_field( wp_unslash( $_POST[ $key . '_subject' ] ?? '' ) ),
     1299                // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Nonce verification handled in email_notifications_page()
     1300                'message' => wp_kses_post( wp_unslash( $_POST[ $key . '_message' ] ?? '' ) ),
     1301                // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Nonce verification handled in email_notifications_page()
     1302                'enabled' => isset( $_POST[ $key . '_enabled' ] ),
     1303            );
     1304        }
     1305
     1306        // Save settings
     1307        update_option( 'formpays_pro_email_settings', $email_settings );
     1308
     1309        // Add success notice
     1310        add_action( 'admin_notices', function() {
     1311            echo '<div class="notice notice-success is-dismissible"><p>' . esc_html__( 'Email settings saved successfully!', 'formpays-pro' ) . '</p></div>';
     1312        });
     1313    }
    11341314    /**
    11351315     * AJAX: Save form
     
    23532533        }
    23542534    }
     2535
     2536    /**
     2537     * AJAX: Send test email
     2538     */
     2539    public function ajax_send_test_email() {
     2540        // Verify nonce
     2541        if ( ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ?? '' ) ), 'formpays_pro_test_email' ) ) {
     2542            wp_send_json_error( esc_html__( 'Security check failed.', 'formpays-pro' ) );
     2543        }
     2544
     2545        // Check permissions
     2546        if ( ! current_user_can( 'manage_options' ) ) {
     2547            wp_send_json_error( esc_html__( 'You do not have permission to perform this action.', 'formpays-pro' ) );
     2548        }
     2549
     2550        $test_email = isset( $_POST['test_email'] ) ? sanitize_email( wp_unslash( $_POST['test_email'] ) ) : '';
     2551        if ( empty( $test_email ) ) {
     2552            wp_send_json_error( esc_html__( 'Please provide a valid email address.', 'formpays-pro' ) );
     2553        }
     2554
     2555        // Get email settings
     2556        $email_settings = get_option( 'formpays_pro_email_settings', array() );
     2557        $from_name = isset( $email_settings['from_name'] ) ? $email_settings['from_name'] : get_bloginfo( 'name' );
     2558        $from_email = isset( $email_settings['from_email'] ) ? $email_settings['from_email'] : get_option( 'admin_email' );
     2559
     2560        // Sample data for testing
     2561        $sample_data = array(
     2562            'transaction_id' => 'TEST-' . wp_rand( 1000, 9999 ),
     2563            'amount' => '$50.00',
     2564            'customer_name' => 'John Doe',
     2565            'customer_email' => $test_email,
     2566            'payment_date' => gmdate( 'Y-m-d H:i:s' ),
     2567            'payment_method' => 'Credit Card',
     2568            'form_title' => 'Sample Form',
     2569            'site_name' => get_bloginfo( 'name' ),
     2570        );
     2571
     2572        // Test email subject and message
     2573        $subject = __( 'FormPays Pro - Test Email', 'formpays-pro' );
     2574        $message = sprintf(
     2575            // translators: %1$s is the site name, %2$s is the transaction ID, %3$s is the amount, %4$s is the customer name, %5$s is the payment date, %6$s is the payment method, %7$s is the site name again
     2576            __( 'This is a test email from %1$s to verify that email notifications are working correctly.
     2577
     2578Sample Transaction Data:
     2579- Transaction ID: %2$s
     2580- Amount: %3$s
     2581- Customer Name: %4$s
     2582- Payment Date: %5$s
     2583- Payment Method: %6$s
     2584
     2585If you received this email, your email settings are configured properly.
     2586
     2587Best regards,
     2588%7$s', 'formpays-pro' ),
     2589            get_bloginfo( 'name' ),
     2590            $sample_data['transaction_id'],
     2591            $sample_data['amount'],
     2592            $sample_data['customer_name'],
     2593            $sample_data['payment_date'],
     2594            $sample_data['payment_method'],
     2595            get_bloginfo( 'name' )
     2596        );
     2597
     2598        // Set headers
     2599        $headers = array(
     2600            'Content-Type: text/html; charset=UTF-8',
     2601            'From: ' . $from_name . ' <' . $from_email . '>',
     2602        );
     2603
     2604        // Send test email
     2605        $sent = wp_mail( $test_email, $subject, $message, $headers );
     2606
     2607        if ( $sent ) {
     2608            wp_send_json_success( esc_html__( 'Test email sent successfully!', 'formpays-pro' ) );
     2609        } else {
     2610            wp_send_json_error( esc_html__( 'Failed to send test email. Please check your email settings.', 'formpays-pro' ) );
     2611        }
     2612    }
    23552613}
  • formpays-pro/trunk/assets/js/frontend.js

    r3379943 r3385037  
    24772477                label: $selectedInput.closest('.payment-method-option-wrapper').find('.payment-method-label').text()
    24782478            });
     2479           
     2480            // Recalculate amount display (amount should stay the same, just ensure display is correct)
     2481            FormPaysProFrontend.calculateTotalAmount($form);
    24792482        },
    24802483       
  • formpays-pro/trunk/formpays-pro.php

    r3379944 r3385037  
    44 * Plugin URI: https://version-next.com/formpays-pro/
    55 * Description: Advanced payment form with multiple payment gateways support and conditional logic
    6  * Version: 1.1.2
     6 * Version: 1.1.3
    77 * Author: versionnext, codexdemon
    88 * Author URI: https://version-next.com/
     
    7979
    8080    /**
     81     * Email handler instance
     82     */
     83    public $email_handler;
     84
     85    /**
    8186     * Admin instance
    8287     */
     
    122127        require_once FORMPAYS_PRO_PLUGIN_DIR . 'includes/class-formpays-pro-transactions.php';
    123128        require_once FORMPAYS_PRO_PLUGIN_DIR . 'includes/class-formpays-pro-analytics.php';
     129        require_once FORMPAYS_PRO_PLUGIN_DIR . 'includes/class-formpays-pro-email-handler.php';
    124130
    125131        if ( is_admin() ) {
     
    165171        $this->transactions = new FormPays_Pro_Transactions();
    166172        $this->analytics    = new FormPays_Pro_Analytics();
     173        $this->email_handler = new FormPays_Pro_Email_Handler();
    167174
    168175        if ( is_admin() ) {
     
    359366    private function get_success_page_content() {
    360367        return '
     368<style>
     369.formpays-pro-success-page {
     370    min-height: 60vh;
     371    display: flex;
     372    align-items: center;
     373    justify-content: center;
     374    padding: 40px 20px;
     375    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
     376}
     377.formpays-pro-success-page .success-container {
     378    max-width: 600px;
     379    width: 100%;
     380    text-align: center;
     381    background: #fff;
     382    padding: 40px;
     383    border-radius: 8px;
     384    box-shadow: 0 4px 6px rgba(0,0,0,0.1);
     385}
     386.formpays-pro-success-page .success-icon {
     387    margin-bottom: 20px;
     388}
     389.formpays-pro-success-page h1 {
     390    color: #2c3e50;
     391    margin-bottom: 15px;
     392    font-size: 32px;
     393}
     394.formpays-pro-success-page > .success-container > p:first-of-type {
     395    color: #7f8c8d;
     396    margin-bottom: 30px;
     397    font-size: 16px;
     398}
     399.formpays-pro-success-page .success-details {
     400    background: #f8f9fa;
     401    padding: 25px;
     402    border-radius: 6px;
     403    margin: 30px 0;
     404    text-align: left;
     405}
     406.formpays-pro-success-page .success-details p {
     407    margin: 12px 0;
     408    color: #34495e;
     409    font-size: 15px;
     410}
     411.formpays-pro-success-page .success-actions {
     412    margin-top: 30px;
     413    display: flex;
     414    gap: 15px;
     415    justify-content: center;
     416    flex-wrap: wrap;
     417}
     418.formpays-pro-success-page .btn {
     419    padding: 12px 30px;
     420    border: none;
     421    border-radius: 6px;
     422    text-decoration: none;
     423    display: inline-block;
     424    font-weight: 600;
     425    transition: all 0.3s ease;
     426    cursor: pointer;
     427}
     428.formpays-pro-success-page .btn-primary {
     429    background: #528FF0;
     430    color: white;
     431}
     432.formpays-pro-success-page .btn-primary:hover {
     433    background: #4278d1;
     434    color: white;
     435}
     436.formpays-pro-success-page .btn-secondary {
     437    background: #95a5a6;
     438    color: white;
     439}
     440.formpays-pro-success-page .btn-secondary:hover {
     441    background: #7f8c8d;
     442    color: white;
     443}
     444</style>
     445
    361446<div class="formpays-pro-success-page">
    362447    <div class="success-container">
     
    371456        <div class="success-details">
    372457            <p><strong>Transaction ID:</strong> [TRANSACTION_ID]</p>
    373             <p><strong>Amount:</strong> [AMOUNT]</p>
    374             <p><strong>Date:</strong> [DATE]</p>
     458            <p><strong>Amount Paid:</strong> [AMOUNT]</p>
     459            <p><strong>Payment Date & Time:</strong> [DATE]</p>
     460            <p><strong>Customer Name:</strong> [CUSTOMER_NAME]</p>
     461            <p><strong>Customer Email:</strong> [CUSTOMER_EMAIL]</p>
     462            <p><strong>Payment Status:</strong> [PAYMENT_STATUS]</p>
    375463        </div>
    376464        <div class="success-actions">
    377             <a href="' . home_url() . '" class="btn btn-primary">Return to Home</a>
    378             <a href="mailto:' . get_option( 'admin_email' ) . '" class="btn btn-secondary">Contact Support</a>
     465            <a href="' . esc_url( home_url() ) . '" class="btn btn-primary">Return to Home</a>
     466            <a href="mailto:' . esc_attr( get_option( 'admin_email' ) ) . '" class="btn btn-secondary">Contact Support</a>
    379467        </div>
    380468    </div>
     
    754842
    755843            $this->transactions->update_transaction( $transaction_id, $update_data );
     844
     845            // Send success emails
     846            $this->send_payment_emails( $transaction_id, 'success' );
    756847        } else {
    757848            // Payment failed
     
    764855                )
    765856            );
     857
     858            // Send failed emails
     859            $this->send_payment_emails( $transaction_id, 'failed' );
    766860        }
    767861
     
    793887        }
    794888
    795         // Replace placeholders with actual transaction data
     889        // Replace placeholders with actual transaction data.
     890        // Use updated_at for payment time (which is when status was updated), fallback to created_at if not available.
     891        $payment_timestamp = ! empty( $transaction->updated_at ) ? $transaction->updated_at : $transaction->created_at;
     892       
    796893        $replacements = array(
    797894            '[TRANSACTION_ID]' => $transaction->transaction_id,
    798895            '[AMOUNT]'         => $transaction->currency . ' ' . number_format( $transaction->amount, 2 ),
    799             '[DATE]'           => date_i18n( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), strtotime( $transaction->created_at ) ),
     896            '[DATE]'           => date_i18n( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), strtotime( $payment_timestamp ) ),
    800897            '[CUSTOMER_NAME]'  => $transaction->customer_name,
    801898            '[CUSTOMER_EMAIL]' => $transaction->customer_email,
     
    9261023        return ob_get_clean();
    9271024    }
     1025
     1026    /**
     1027     * Send payment emails based on status
     1028     *
     1029     * @param int    $transaction_id Transaction ID.
     1030     * @param string $status Payment status ('success' or 'failed').
     1031     * @return void
     1032     */
     1033    private function send_payment_emails( $transaction_id, $status ) {
     1034        if ( ! isset( $this->email_handler ) ) {
     1035            return;
     1036        }
     1037
     1038        // Get transaction data
     1039        $transaction = $this->transactions->get_transaction( $transaction_id );
     1040        if ( ! $transaction ) {
     1041            return;
     1042        }
     1043
     1044        // Get form data
     1045        $form = $this->forms->get_form( $transaction->form_id );
     1046        if ( ! $form ) {
     1047            return;
     1048        }
     1049
     1050        // Parse form data
     1051        $form_data = is_string( $transaction->form_data ) ? json_decode( $transaction->form_data, true ) : $transaction->form_data;
     1052        if ( ! is_array( $form_data ) ) {
     1053            $form_data = array();
     1054        }
     1055
     1056        // Send emails based on status
     1057        if ( 'success' === $status ) {
     1058            $this->email_handler->send_payment_success_customer( $transaction, $form, $form_data );
     1059            $this->email_handler->send_payment_success_admin( $transaction, $form, $form_data );
     1060        } elseif ( 'failed' === $status ) {
     1061            $this->email_handler->send_payment_failed_customer( $transaction, $form, $form_data );
     1062            $this->email_handler->send_payment_failed_admin( $transaction, $form, $form_data );
     1063        }
     1064    }
    9281065}
    9291066
  • formpays-pro/trunk/includes/class-formpays-pro-forms.php

    r3379943 r3385037  
    370370            );
    371371            wp_add_inline_script( 'formpays-pro-frontend', $form_init_script );
     372           
     373            // Initialize payment method and amount display for forms with payment methods
     374            if ( ! empty( $form->payment_methods ) && is_array( $form->payment_methods ) && ( ! isset( $form->payment_collection ) || $form->payment_collection !== 'disabled' ) ) {
     375                $payment_init_script = sprintf(
     376                    'jQuery(document).ready(function($) {
     377                        var $form = $("#formpays_pro_form_%s");
     378                        // Wait a bit for the form to be fully initialized
     379                        setTimeout(function() {
     380                            // Set default payment method data if not already set
     381                            if (!$form.data("selected-payment-method")) {
     382                                var $firstMethod = $form.find("input[name=\'payment_method\']:checked");
     383                                if ($firstMethod.length) {
     384                                    $form.data("selected-payment-method", $firstMethod.val());
     385                                }
     386                            }
     387                            // Ensure amount is calculated and displayed
     388                            if (typeof FormPaysProFrontend.calculateTotalAmount === "function") {
     389                                FormPaysProFrontend.calculateTotalAmount($form);
     390                            }
     391                        }, 100);
     392                    });',
     393                    esc_js( $form_id )
     394                );
     395                wp_add_inline_script( 'formpays-pro-frontend', $payment_init_script );
     396            }
    372397            ?>
    373398        <?php endif; ?>
     
    693718    }
    694719
     720    // Capture selected payment method if present.
     721    $selected_payment_method = '';
     722    if ( isset( $_POST['payment_method'] ) && ! empty( $_POST['payment_method'] ) ) {
     723        $selected_payment_method = sanitize_text_field( wp_unslash( $_POST['payment_method'] ) );
     724    }
     725
    695726    // Validate form data with extracted field data only
    696727    $validation_result = $this->validate_form_data( $form, $form_field_data );
     
    716747        );
    717748    } else {
    718         // Process payment
    719         $payment_result = $this->process_payment( $form, $validation_result );
     749        // Process payment (pass selected payment method).
     750        $payment_result = $this->process_payment( $form, $validation_result, $selected_payment_method );
    720751
    721752        if ( is_wp_error( $payment_result ) ) {
     
    10171048     * Process payment
    10181049     */
    1019 private function process_payment( $form, $data ) {
     1050private function process_payment( $form, $data, $selected_payment_method = '' ) {
    10201051    global $formpays_pro;
    10211052
     
    10551086    } elseif ( ! empty( $data['customer_phone'] ) ) {
    10561087        $customer_mobile = $data['customer_phone'];
     1088    } elseif ( ! empty( $data['contact'] ) ) {
     1089        $customer_mobile = $data['contact'];
    10571090    } else {
    10581091        // No mobile field found - provide a default value
     
    10611094    }
    10621095
     1096    // Format phone number to include country code for Razorpay
     1097    $customer_mobile = $this->format_phone_number_for_razorpay( $customer_mobile );
     1098
    10631099    // Gateway-specific field validation
    10641100    $validation_result = $this->validate_gateway_requirements( $form->gateway, $data );
     
    10871123    // Create transaction record
    10881124    $transaction_data = array(
    1089         'form_id'         => $form->id,
    1090         'transaction_id'  => $transaction_id,
    1091         'gateway_name'    => $form->gateway,
    1092         'customer_name'   => $customer_name,
    1093         'customer_email'  => $customer_email,
    1094         'customer_mobile' => $customer_mobile,
    1095         'amount'          => $payment_amount,
    1096         'currency'        => $form->currency,
    1097         'payment_status'  => 'pending',
    1098         'form_data'       => wp_json_encode( $data ),
    1099         'ip_address'      => $this->get_user_ip_address(),
    1100         'user_agent'      => isset( $_SERVER['HTTP_USER_AGENT'] ) ? sanitize_textarea_field( wp_unslash( $_SERVER['HTTP_USER_AGENT'] ) ) : '',
     1125        'form_id'              => $form->id,
     1126        'transaction_id'       => $transaction_id,
     1127        'gateway_name'         => $form->gateway,
     1128        'customer_name'        => $customer_name,
     1129        'customer_email'       => $customer_email,
     1130        'customer_mobile'      => $customer_mobile,
     1131        'amount'               => $payment_amount,
     1132        'currency'             => $form->currency,
     1133        'payment_status'       => 'pending',
     1134        'form_data'            => wp_json_encode( $data ),
     1135        'ip_address'           => $this->get_user_ip_address(),
     1136        'user_agent'           => isset( $_SERVER['HTTP_USER_AGENT'] ) ? sanitize_textarea_field( wp_unslash( $_SERVER['HTTP_USER_AGENT'] ) ) : '',
     1137        'selected_payment_method' => $selected_payment_method, // Pass selected payment method to gateway.
    11011138    );
    11021139
     
    16521689     * Get human-readable field label
    16531690     */
    1654 private function get_field_label( $field_id ) {
    1655     $field_labels = array(
    1656         'customer_name'   => __( 'Customer Name', 'formpays-pro' ),
    1657         'customer_email'  => __( 'Customer Email', 'formpays-pro' ),
    1658         'customer_mobile' => __( 'Customer Phone', 'formpays-pro' ),
    1659         'form_id'         => __( 'Form ID', 'formpays-pro' ),
    1660     );
    1661 
    1662     return isset( $field_labels[ $field_id ] ) ? $field_labels[ $field_id ] : ucfirst( str_replace( '_', ' ', $field_id ) );
    1663 }
    1664 }
     1691    private function get_field_label( $field_id ) {
     1692        $field_labels = array(
     1693            'customer_name'   => __( 'Customer Name', 'formpays-pro' ),
     1694            'customer_email'  => __( 'Customer Email', 'formpays-pro' ),
     1695            'customer_mobile' => __( 'Customer Phone', 'formpays-pro' ),
     1696            'form_id'         => __( 'Form ID', 'formpays-pro' ),
     1697        );
     1698
     1699        return isset( $field_labels[ $field_id ] ) ? $field_labels[ $field_id ] : ucfirst( str_replace( '_', ' ', $field_id ) );
     1700    }
     1701
     1702    /**
     1703     * Format phone number for Razorpay (add country code if missing)
     1704     *
     1705     * @param string $phone Phone number.
     1706     * @return string
     1707     */
     1708    private function format_phone_number_for_razorpay( $phone ) {
     1709        // Remove any whitespace or special characters
     1710        $phone = preg_replace( '/[^0-9+]/', '', $phone );
     1711
     1712        // If phone already has country code (starts with +), return as is
     1713        if ( strpos( $phone, '+' ) === 0 ) {
     1714            return $phone;
     1715        }
     1716
     1717        // If phone starts with 00, replace with +
     1718        if ( strpos( $phone, '00' ) === 0 ) {
     1719            return '+' . substr( $phone, 2 );
     1720        }
     1721
     1722        // Default: assume Indian number and add +91
     1723        if ( strlen( $phone ) === 10 ) {
     1724            return '+91' . $phone;
     1725        }
     1726
     1727        // If 11 digits and starts with 0, assume Indian and add +91
     1728        if ( strlen( $phone ) === 11 && substr( $phone, 0, 1 ) === '0' ) {
     1729            return '+91' . substr( $phone, 1 );
     1730        }
     1731
     1732        // For numbers longer than 10 digits without +, assume they might have country code
     1733        // Add + if not present and the number is already long enough
     1734        if ( strlen( $phone ) > 10 && strpos( $phone, '+' ) === false ) {
     1735            return '+' . $phone;
     1736        }
     1737
     1738        // Return with default +91 for Indian numbers
     1739        return '+91' . $phone;
     1740    }
     1741}
  • formpays-pro/trunk/includes/gateways/class-formpays-pro-razorpay.php

    r3379943 r3385037  
    427427            'description'  => sprintf( 'Payment for %s', $payment_data['customer_name'] ),
    428428            'callback_url' => $callback_url,
     429            'customer'     => array(
     430                'name'  => $payment_data['customer_name'],
     431                'email' => $payment_data['customer_email'],
     432                'contact' => ! empty( $payment_data['customer_mobile'] ) ? $payment_data['customer_mobile'] : ( ! empty( $payment_data['customer_phone'] ) ? $payment_data['customer_phone'] : '' ),
     433            ),
    429434        );
    430435
     
    482487                $cancel_url
    483488            );
     489        }
     490
     491        // Map internal payment methods to Razorpay methods.
     492        $method_mapping = array(
     493            'card'        => 'card',
     494            'upi'         => 'upi',
     495            'netbanking'  => 'netbanking',
     496            'wallet'      => 'wallet',
     497            'emi'         => 'emi',
     498        );
     499
     500        // Handle selected payment method.
     501        $method_options = array();
     502        if ( ! empty( $payment_data['selected_payment_method'] ) ) {
     503            $selected_method = $payment_data['selected_payment_method'];
     504            if ( isset( $method_mapping[ $selected_method ] ) ) {
     505                $method_options = array(
     506                    'method' => $method_mapping[ $selected_method ],
     507                );
     508            }
    484509        }
    485510
     
    495520                'name'    => $payment_data['customer_name'],
    496521                'email'   => $payment_data['customer_email'],
    497                 'contact' => $payment_data['customer_mobile'] ?? '',
     522                'contact' => ! empty( $payment_data['customer_mobile'] ) ? $payment_data['customer_mobile'] : ( ! empty( $payment_data['customer_phone'] ) ? $payment_data['customer_phone'] : '' ),
    498523            ),
    499524            'notes'        => array(
     
    507532            'cancel_url'   => $cancel_url,
    508533        );
     534
     535        // Add method filter if payment method is selected.
     536        if ( ! empty( $method_options ) ) {
     537            $checkout_data['method'] = $method_options['method'];
     538        }
    509539
    510540        // Debug: Log checkout data (only in debug mode and not during activation)
Note: See TracChangeset for help on using the changeset viewer.