News:

Support the VirtueMart project and become a member

Main Menu

Recent posts

#21
General Questions / Stopping fake and mistyped cus...
Last post by SendBridge - November 02, 2026, 15:20:27 PM
Hi everyone,

Disclosure first: I work for SendBridge, an email verification service, and I mention it in step 3. Steps 1, 2 and 4 work without any external service.

The problem this addresses: order confirmations and invoices bouncing because the customer typed "gmial.com", or guest checkouts made with throwaway addresses (often the same people behind fraudulent orders).

VirtueMart only checks the email syntax, so all of these get through. Here is what helped, from simplest to most thorough.

1. Ask for the email twice (core setting)
In the shopper fields manager (Configuration > Shopper Fields) you can add a second email field and compare the two. It's not elegant, but it catches a lot of typos for zero cost.

2. Catch common domain typos before submit
A few lines of JavaScript in your template override of the checkout/registration form can suggest the right domain:

var fixes = {"gmial.com":"gmail.com","gmal.com":"gmail.com","hotmial.com":"hotmail.com","outlok.com":"outlook.com","yaho.com":"yahoo.com"};
jQuery('#email_field').on('blur', function () {
  var v = this.value.trim(), d = v.split('@')[1];
  if (d && fixes[d.toLowerCase()]) {
    if (confirm('Did you mean ' + v.split('@')[0] + '@' + fixes[d.toLowerCase()] + '?')) {
      this.value = v.split('@')[0] + '@' + fixes[d.toLowerCase()];
    }
  }
});

3. Check that the mailbox really exists (server side)
Syntax and typo checks won't tell you whether the mailbox exists or whether it's a disposable inbox. For that you need an MX lookup plus an SMTP-level check. Most shared hosts block outbound port 25, so the usual route is an email verification API over HTTPS instead (for example SendBridge's email address verification service; other providers work the same way). A small system plugin hooks into user/order saving and rejects the address when the API says "invalid" or "disposable":

// plugins/system/emailcheck/emailcheck.php (simplified)
public function plgVmOnUserStore(&$data)
{
    $email = isset($data['email']) ? trim($data['email']) : '';
    if ($email === '') return true;

    $http = Joomla\CMS\Http\HttpFactory::getHttp();
    try {
        $res = $http->get('https://YOUR-VERIFIER/verify?email=' . urlencode($email),
                          ['Authorization' => 'Bearer ' . $this->params->get('api_key')], 3);
        $status = json_decode($res->body)->status ?? 'unknown';
    } catch (Exception $e) {
        return true; // fail open, never block a sale because the API is slow
    }
    if (in_array($status, ['invalid', 'disposable'])) {
        vmError('Please enter a valid, permanent email address.');
        return false;
    }
    return true;
}

Two things to keep in mind:
- Always fail open (short timeout, allow the order on errors), so an outage on the verifier's side never costs you a sale.
- Don't reject "catch-all" results. Plenty of company domains accept every address, so treat those as valid.

4. Clean the existing customer list
If you send newsletters (AcyMailing etc.), export the addresses from #__virtuemart_userinfos / #__users once and run them through the same check before the next campaign. Bounce rates matter a lot for whether your mail lands in the inbox.

Is anyone doing this with a ready-made extension instead? I'd be interested to compare.

Peter Braun (SendBridge)
#22
For Addressing then problem with the correct way, what i did was in file : administrator/components/com_virtuemart/helpers/vmtablexarray.php

i changed :

line 198 with       
foreach ($newArray as $sKeyInd => &$newValue) {

line 203 with       
$newValue['id'] = $oldArray[$sKeyInd]['id'];

line 214 Added   
unset($newValue);



the functions
store($updateNulls = false)  code in vmtablexarray.php calculated each image's order number but never wrote it to the database. It assigned the number to a copy of the row (foreach (... as $k => $newValue)), so the original row never got it. Every row was stored without an order number.

the fix should be considered for a next version of virtuemart.
#23
Hello,

After updating VirtueMart and the vmadmin template to version 4.8.2, I encountered an "Invalid Token" error when trying to delete log files in the VirtueMart administration.

Error message:
Invalid Token, in view=log task=delete

The log files could not be deleted.

Cause:

After investigating the issue, I found that the delete link in the vmadmin template does not include a security token.

The affected file is:

administrator/templates/vmadmin/html/com_virtuemart/log/default.php

The original code generates a GET request:

echo '<a href="'.JRoute::_('index.php?option=com_virtuemart&view=log&task=delete&logfile='.$logFile).'"><span class="" uk-icon="icon: trash; ratio: 1"></span></a>';

However, the delete controller in:

administrator/components/com_virtuemart/controllers/log.php

requires a valid token through:

vRequest::vmCheckToken();

Solution:

I replaced the original delete link with a POST form containing the Joomla security token:

<td align="left">
    <form method="post"
          action="<?php echo JRoute::_('index.php?option=com_virtuemart&view=log&task=delete'); ?>"
          style="margin:0;">

        <input type="hidden"
               name="logfile"
               value="<?php echo htmlspecialchars($logFile, ENT_QUOTES, 'UTF-8'); ?>">

        <?php echo JHtml::_('form.token'); ?>

        <button type="submit"
                title="Delete log file"
                style="background:none;border:none;cursor:pointer;padding:0;">
            <span uk-icon="icon: trash; ratio: 1"></span>
        </button>
    </form>
</td>

After this modification, deleting log files works correctly with vRequest::vmCheckToken() enabled.

Both VirtueMart and vmadmin were updated together to version 4.8.2.

It appears that the delete link in the vmadmin template needs to be updated to comply with the token validation.

Hopefully, this can be corrected in a future release.

Best regards,
Slavomir
#24
VirtueMart 4.8.4. After checkout, a literal + in the billing name and phone is stored as a space. B+T Vill. Ltd becomes B T Vill. Ltd. A leading + on a phone number disappears.

prepareFieldDataSave() reads every user field with vRequest::getString($name, '', $data). Because the third argument is the already decoded data array, getString() calls filterUrl(), which runs urldecode(). PHP has already decoded the POST, so + becomes a space.
#25
Installation, Migration & Upgrade / Re: Problem with searching aft...
Last post by Oleksii - October 28, 2026, 20:43:49 PM
Installed version 4.0.0 and searching again working :)
#26
Installation, Migration & Upgrade / Problem with searching after u...
Last post by Oleksii - October 28, 2026, 19:20:56 PM
Hi!
I updated VirtueMart from 3.8.6 to 4.4.4 version. After this via VirtueMart Seach I can't find any items from my shop.
I checked that all items steal in mysql.
In options indicated searching by description of goods and items code.
Help to return searching to my shop.

Joomla 3.10.12
PHP 7.3.33   
#27
Virtuemart Development and bug reports / BUG Stripe Checkout 1.3.0
Last post by geldany - October 28, 2026, 13:53:05 PM
BUG Stripe Checkout 1.3.0 - PHP 8.5 Type Error in plgVmDisplayListFEPayment(No response to tickets)

Hello,

I am posting here because I submitted two support tickets starting on October 20th and have received no response at all so far.

Selling a plugin that causes a fatal error on recent PHP versions without providing support is very frustrating. We had to temporarily patch the code ourselves to unblock our shop, but this is obviously not a viable long-term solution as our changes will be overwritten with the next update.

Environment:

Joomla version: 5.4.10

VirtueMart version: 4.8.4

Plugin: Stripe Checkout v1.3.0

PHP version: 8.5.12

Error details:
Fatal Error: PLGVMPAYMENTVMSTRIPECO::PLGVMDISPLAYLISTFEPAYMENT(): Argument #3 ($htmlIn) must be of type array, null given

Issue:
Under PHP 8.5, strict typing throws a TypeError because $htmlIn is passed as null instead of an array when rendering the payment method list in the frontend.

Could someone please check support tickets or provide an official PHP 8.5-compatible patch for this issue?

Best regards
#28
Coding Central / Re: Add option to exclude ship...
Last post by razor7 - October 21, 2026, 00:36:13 AM
Great! hope it gets implemented
#29
While setting up paypal_checkout on VirtueMart 4.8.2 we ran into a payment failure and ended up documenting ten issues. Full report attached.

1. Order creation fails for every VAT order with quantity > 1, if With Breakdown is enabled. amount.breakdown.tax_total is computed from the unrounded per-unit tax and then rounded, while items[].tax is rounded per unit. PayPal validates tax_total as the sum of items[].tax × quantity, so the two differ by a cent and the order is rejected with UNPROCESSABLE_ENTITY. Depending on which check trips first you get TAX_TOTAL_MISMATCH or AMOUNT_MISMATCH. Workaround: set With Breakdown to No.

2. With Debug mode enabled, the OAuth bearer token is printed in the storefront checkout page, in full, together with the customer's shipping address. The token carries refund, payout and vault scopes and is valid for about nine hours.

The remaining eight are smaller: render() without a .catch(), two buttons rendered without checking the container exists, the stored client secret written into the admin form's value attribute, and the fact that PayPal's error response is replaced by one fixed message with nothing logged. That last one is why the first issue took us five test payments to find.

Measured on Joomla 5.4.8, VM 4.8.2, PHP 8.3, live credentials. Request and response bodies with debug_id values are in the attachment.
#30
Coding Central / Re: Add option to exclude ship...
Last post by Milbo - October 20, 2026, 19:20:39 PM
yes, that sounds interesting. Lets see how it fits in vm5