We're nearing launch of two new Drupal Commerce sites, one of them being this one. It turns out Freelock.com has some relatively sophisticated commerce needs: some taxable products, some non-taxable products. Recurring subscriptions. Arbitrary invoice payments.
We previously blogged about Commerce 2 Price Resolvers. Now, let's get into some of the details of payment gateways and taxes.
This post is going to be more high-level, less code, because there are some critical concepts that are fundamental to how Commerce 2 currently works that site owners need to understand.
Onsite Payment Gateways always store credit card info
Payment gateways have different capabilities. Some support storing a user's card in the gateway. Others have an "offsite" flow, sending you to their site to collect card info and then returning you back to the commerce site when done.
An "Onsite" payment gateway is one that keeps the visitor on the site, collects the card numbers and posts it from the site to the gateway. In Drupal Commerce 2, the payment flow for onsite gateways is completely different than in Commerce 1, Ubercart, or many other shopping carts: it now stores the credit card in the gateway first, and creates a "Payment Method" associated with the user that contains the token from the gateway. It can then use that token for any future charges (as long as the gateway continues to honor it).
This is a fundamental change that makes recurring transactions and "card on file" functionality pretty much built into Commerce 2!
This means that the Commerce EPN Gateway module we created has full support for recurring functionality out of the box.
One other thing of note: Each gateway can declare its capabilities in its code, and Commerce then automatically exposes that functionality to the store admins. One thing that confused me slightly was "Voids" -- in most payment gateways, you can void a transaction up until the batch closes (which usually happens once per day). However, in Commerce 2, "Void" is used to cancel an authorization, not void a transaction. If you use "authorization only" transactions, and capture the payment after the order is fulfilled, then you can use Void to cancel the authorization (or Capture to process it).
The Tax system needs help to recognize taxable vs non-taxable products
Out of the box, the tax system is extremely smart about zones and tax registrations. You can define, per store, which taxes you need to collect, and Commerce will automatically charge tax to customers in a taxable zone. However there is no built-in distinction for taxable vs non-taxable products.
There are tax rules coming, but in the meantime if you have both taxable and non-taxable sales, you need a custom tax resolver to do the right thing. These are relatively easy to create. We borrowed heavily from another tax module the configuration settings that allow you to define on a tax type which product variation(s) it applies to.
One other gotcha we found while testing recurring payments -- if you use the "Include tax in product price" option, recurring billing adds the tax again each time the purchase recurs -- be sure to uncheck these boxes and keep the tax separate, and then it works fine.
If you're in Washington State and need to collect sales tax, this module works fine today -- check it out here. However note that it's not yet possible to create a tax report -- we do store the location data with each transaction, and will be sure to have this report available by April, when we need it!
Working with Drupal Commerce 2 is really refreshing. It feels like you're working on a robust, well-oiled system with a very nice user experience right out of the gate. It is still missing some bits and pieces around the edges, and customizing it does involve turning to code more quickly than previous versions, but overall we're finding it really straightforward to work with. Stay tuned for our coming sites, and if you need a Commerce site, reach out to us!