Design pattern for payment gateways

Looks like we need a multicurrency aware design pattern for payment gateways.
Following issue in the Commerce Multicurrency queue contains several reports of problems with payment gateways when using multiple currencies: http://drupal.org/node/1932598

In comment 10 I tried to outline a possible "design pattern" payment gateways should follow:

Payment gateways can't assume that they get the amount in a supported currency. However they should always be able to use commerce_currency_conversion() to convert the given amount from the provided to a supported currency.
Payment gateways that support multiple currencies could / should allow to configure which currency has to be used (generally or for the case the provided currency isn't supported).

Addition by Ryans comment:
Payment gateways can't assume that they get the amount in a certain precision, even if the currency supports a certain precision by default. Thus the payment gateway has to ensure the amount meets the required precision.
Attention rounding to a certain precision can be tricky. Check out commerce_round()

Could this become part of the developer documentation?


Posted: Apr 4, 2013


Ryan Ryan Szrama on April 4, 2013

I think this makes sense, especially since at least one of those problem modules was mine. We should also document that even if the currency supports a certain precision by default, that doesn't mean the payment gateway module can assume that will be the case when they prepare API requests. We've run into issues where a payment gateway expects a price with two decimal places but hit odd precision issues or just altered currency definitions that resulted in erroneous payment API requests using more decimal places than allowed.

dwkitchen David Kitchen on April 5, 2013

I have to completely disagree with you that the payment gateway module can always convert the currency.

If the order total presented to the user is 50 USD their payment method must be charged 50 USD, never converted to 34 GBP. Unless this is presented to the user and the order total given in GBP (and hence what would be passed to the payment gateway module) this would be illegal in the EU and I am sure the true is the same for the USA.

If a merchant site trades in multiple currencies it needs to have merchant accounts with payment processors for all the currencies. The merchant site would then configure the rules that make each payment gateway available only available if it supports the currency the order total is in.

das-peter on April 5, 2013

That's a valid point, so the guideline should say: "The payment gateway has to be currency and precision aware - and act appropriate e.g. notify the user about an unsupported currency or precision".
I don't see that Commerce Multi Currency or any other module that relies on the hooks / rules of commerce_product_calculate_sell_price() can / should be payment aware.
And even if they should, I think it's quite complex (if not bad architecture) to provide the necessary context and at the same time communicate the expectations of the payment gateway.