MyCryptoCheckout / wordpress

MyCryptoCheckout Wordpress plugin
https://wordpress.org/plugins/mycryptocheckout/
28 stars 23 forks source link

Payment spread affects amount too much with BTC #13

Closed asheroto closed 4 months ago

asheroto commented 4 months ago

On a $4.37 order, if you put 100 in the Payment amount spread, on a $4.37 order / 0.000069 BTC, that increases the actual amount due to 0.000159 BTC which is $10. That's 2.29 times higher than the original price.

Also, the estimated amount in the checkout page is different than the amount that says to pay. This could be a problem, because users will expect to pay the amount quoted, not a higher amount on the next step, unless insignificant. If it's a few half-pennies different, no big deal. But the amount really shouldn't be different than the original price. 😔

My guess is that the spread is causing this problem because the value of BTC has become so high that the function that handles the spread doesn't make the amount to increase small enough. For now I've just adjusted the spread to a low value. For the other currencies this may make since since their value is lower, but with at least BTC it doesn't.

asheroto commented 4 months ago

Looks like the $currency_data->decimal_precision is set to 6 for BTC, but 8 would probably be better. 😊

https://github.com/MyCryptoCheckout/wordpress/blob/7906c604538e41e8c5903fdf76b4bad32f60d3f1/src/currencies_trait.php#L67

I added a debug line and found the currency data:

MyCryptoCheckout()->debug('[Currency] ' . $currency_id . ' ' . $currency_data->name . ' [Decimal Precision] ' . $currency_data->decimal_precision);

result:

2024-05-13 20:03:01.0554 MyCryptoCheckout: [Currency] BTC Bitcoin [Decimal Precision] 6
2024-05-13 20:03:01.5553 MyCryptoCheckout: [Currency] ETH Ethereum [Decimal Precision] 5
2024-05-13 20:03:01.5572 MyCryptoCheckout: [Currency] LTC Litecoin [Decimal Precision] 6
2024-05-13 20:03:01.5615 MyCryptoCheckout: [Currency] XMR Monero [Decimal Precision] 6

But these currencies support more decimal places:

Cryptocurrency Decimal Places Supported
BTC (Bitcoin) 8
ETH (Ethereum) 18
LTC (Litecoin) 8
XMR (Monero) 12
asheroto commented 4 months ago

Since this info is acquired from the MyCryptoCheckout server, as a temporary workaround, on the currencies I use I just wrote a switch statement to handle the more decimal places.

https://github.com/MyCryptoCheckout/wordpress/blob/master/src/currencies_trait.php#L63

Above line 63 on currencies_trait.php I added:

/************************** DECIMAL PRECISION FIX - START **************************/
$showDecimalPrecisionDebug = true;

// Array holding the correct decimal precision for specific currencies
$decimalPrecisions = [
    'BTC' => 8,
    'ETH' => 8,
    'LTC' => 8,
    'XMR' => 8,
];

if (array_key_exists($currency_id, $decimalPrecisions)) {
    $correctPrecision = $decimalPrecisions[$currency_id];
    if ($currency_data->decimal_precision !== $correctPrecision) {
        if ($showDecimalPrecisionDebug) {
            MyCryptoCheckout()->debug('[Currency] ' . $currency_id . ' ' . $currency_data->name . ' decimal precision adjusted from ' . $currency_data->decimal_precision . ' to ' . $correctPrecision);
        }
        $currency_data->decimal_precision = $correctPrecision;
    }
}
/************************** DECIMAL PRECISION FIX - END **************************/   

This method makes it so it only adds a tiny amount to the amount due, where the actual fiat currency amount doesn't change much. I'm using 10 for the payment spread. Here's the debug log after the change:

2024-05-13 20:46:13.1774 MyCryptoCheckout: Creating order! Available: 1
2024-05-13 20:46:13.1792 MyCryptoCheckout: Marking up total: 4.37 USD -> 4.37
2024-05-13 20:46:13.1792 MyCryptoCheckout: Conversion: 0.00006930
2024-05-13 20:46:13.1793 MyCryptoCheckout: Precision: 8
2024-05-13 20:46:13.1794 MyCryptoCheckout: Next amounts:
array (
  0 => '0.00006930',
  1 => '0.00006931',
  2 => '0.00006932',
  3 => '0.00006933',
  4 => '0.00006934',
  5 => '0.00006935',
  6 => '0.00006936',
  7 => '0.00006937',
  8 => '0.00006938',
  9 => '0.00006939',
  10 => '0.0000694',
)

2024-05-13 20:46:13.1795 MyCryptoCheckout: Amount selected: 0.00006931

Now the USD total is still $4.37. 😊 Even if it used 0.0000694 instead, it would only go up a penny.

asheroto commented 4 months ago

I used ChatGPT to generate a list of cryptocurrencies with decimal places that differ from their supported values. These aren't confirmed, but according to ChatGPT this is the correct info. I understand you may not want to use all of the available digits. 8 decimal places seems to be a happy number.

Hope this helps! 😊

Cryptocurrency Current Decimal Places Correct Decimal Places
BCH Bitcoin Cash 6 8
BTC Bitcoin 6 8
DASH Dash 6 8
DOGE Dogecoin 6 8
DGB DigiByte 6 8
ETH Ethereum 5 18
FLUX Flux 6 8
GRS Groestlcoin 6 8
LTC Litecoin 6 8
MAZA Maza 6 8
PUT PUTinCoin 6 8
QASH Qash 6 8
TRX Tron 6 8
USDT_TRON Tether 6 8
USDT_ERC20 Tether 4 8
ZEC Zcash 6 8
XMR Monero 6 12
jjs2484 commented 4 months ago

Hi, The reason the decimals have been shortened is because some popular wallets round off after so many decimals for some reason when sending data to them either over web3 or via URI. In most cases its still fine because it still allows for fractions of pennies/pennies.

Also, the Payment amount spread shouldn't need to be changed from default in most cases, it was added for very high volume shops that could receive 100s of orders per minute in the same currency. It should be noted better in the settings. That said, you are right, the BTC price has gone up so if its needed in a case like that now its problematic.

However, after that setting was added we added HD wallet support for BTC which is what we recommend in a case like that and pretty much in general. That way you don't have to deal with payment spreads at all for BTC and you can also set payment tolerances. Electrum is the HD wallet we recommend for BTC ecomm.

We are pushing out a large update very soon which includes updated web3, solana, phantom wallet support, WooCommerce checkout blocks support, and other stuff. Will look to see if some wallets have stopped rounding off BTC at 6 decimals now too.

asheroto commented 4 months ago

Awesome! Great info. Thank you.

asheroto commented 4 months ago

I did work with zpub today for BTC, but also found that other currencies don't necessarily support this type of thing, so payment spread is still needed for ETH, XMR, etc.

jjs2484 commented 4 months ago

Yes some chains including EVM chains (ETH, MATIC, BSC) do not natively support HD wallets but for chains that do (BTC, LTC, etc.) you can use them.

For EVM chains to cut down on payment spreads, you could for example, setup more than one ETH address in the MCC currency list. You could setup as many as you'd like (2 or 20). When you configure more than one wallet per currency, the wallets are used in a round-robin fashion. This also creates a layer of semi-privacy but still obviously won't be as private as HD wallet though.

We've just released a large update which includes updated web3, solana, phantom wallet support, WooCommerce checkout blocks support, and other stuff. Smaller update coming soon and will check on some popular wallets to see how many BTC decimals they are supporting these days.

jjs2484 commented 4 months ago

BTC bumped to 7 decimals after testing lots of wallets support these days. Payment spread for singular address use should now be fractions of a penny again. We would still recommend using HD wallets for BTC when possible though.

Thanks for reporting.

asheroto commented 4 months ago

Got it. Thanks for the info! So you found some wallets that did not support 8 decimals?