Expand Accept.js to include Accept.js UI

Created on 11 December 2018, about 6 years ago
Updated 8 August 2024, 4 months ago

Using the Accept.js library and methodology alone results in a SAQ A-EP level of compliance. While a step in the right direction, Authnet offers something called the Accept.js UI, which would integrate with the existing work already done to enable this module to use the Accept.js library. The primary difference is that this module would no longer be responsible for building and presenting the Card Information form elements to the user. Instead, the user clicks a "Pay" button, and a lightbox appears where the user enters ONLY their card number, expiration date, and security code. This lightbox is generated and displayed entirely by Authorize.net and counts as an entirely separate page, ensuring the sensitive card data never touches the merchant's server. This would result in SAQ A compliance.

Once the client does this, Authorize.net returns a payment nonce to the site, which is then submitted to Authnet with the rest of the payment information just like in the existing Accept.js framework. The end-user never feels like they never left the merchant's website, and PCI compliance overhead is reduced significantly. Yes, this would reduce the ability of Drupal to perform certain functions like allow transactions from the admin interface, and it may not completely work with Card on File, but for many merchants? These sacrifices pale in comparison to the benefit of the reduction to PCI compliance level SAQ-A.

It's easy for me, a non-developer, to say that implementation would simply be a matter of creating a "drop-in replacement" for the card information form, but I'm sure there's a lot more work to it than that. Still though, the heavy lifting has already been done as the Accept.js framework is already committed as the rest of the callbacks are largely similar.

Feature request
Status

Needs review

Version

1.0

Component

User interface

Created by

🇺🇸United States TynanFox

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • 🇺🇸United States morbus iff

    @tkiehne: There was no reason for them not being included. Likely an oversight. Patch away. Can they be moved to AcceptJsBase.php to reduce duplication?

  • 🇺🇸United States tkiehne

    Unfortunately the forms are defined in the gateway annotation, so it can't be consolidated into the base class.

    There is also a question of organization: the subject forms are Drupal\commerce_authnet\PluginForm\AcceptJs\PaymentApproveForm and Drupal\commerce_authnet\PluginForm\AcceptJs\PaymentDeclineForm - While these work just fine for both AcceptJs and AcceptJsUi would we want to create a copy of each in src/PluginForm/AcceptJsUi just to keep things separate and futureproof? Or maybe refactor those to be in src/PluginForm and make them common to both gateways?

  • 🇺🇸United States tkiehne

    I've found one more issue with this patch. When a customer is selecting a payment method during checkout, there is a script for the UI patch that attempts to reload the AcceptJS-UI script after an AJAX action. The script checks for a specific context id set to a presumed default checkout flow, e.g., in commerce_authnet.acceptjs_ui.form.js:

    if (context.id == 'commerce-checkout-flow-multistep-default' && document.getElementsByClassName('button AcceptUI').length > 0)

    This is all fine and good if you happen to be using this presumed default checkout flow, or if the Authnet payment method is selected by default and the user doesn't select a different payment method, but in our case we have custom checkout flows so this check is never triggered, meaning the AcceptJS-UI script is not reloaded when the user changes the payment method and the "Add payment information" button doesn't have events attached. Clicking the button will reload the screen and display an error. Ironically, since the Authnet payment method is preselected on the reload, the button will work correctly on second press.

    Not sure what the exact fix is, but we shouldn't be presuming a fixed checkout flow id here. Perhaps just check that the context id starts with "commerce-checkout-flow-"?

  • 🇺🇸United States tkiehne

    I've re-rolled the patch in #31 against 8.x-1.8 and added code to address #33 & #36. This checks out against my environments, but it would be nice to have additional verification.

    Seems like #32 is the only remaining outstanding issue with this patch. What will it take to get this feature on the release roadmap?

  • Open in Jenkins → Open on Drupal.org →
    Core: 9.5.x + Environment: PHP 8.1 & MySQL 5.6
    last update over 1 year ago
    6 fail
  • Open in Jenkins → Open on Drupal.org →
    Core: 9.5.x + Environment: PHP 8.1 & MySQL 8
    last update over 1 year ago
    7 pass, 2 fail
  • Open in Jenkins → Open on Drupal.org →
    Core: 9.5.x + Environment: PHP 7.4 & MySQL 5.7
    last update over 1 year ago
    12 pass
  • 🇮🇳India vipin.j

    I've updated patch #37 in order to fix a bug with this patch.

    to reproduce:

    1. Head to user/#/payment-methods
    2. Create a new payment method with Authorize.net (Accept.js UI)
    3. On success, edit this newly created payment method.
    4. Regardless of what YEAR you have specified (while adding the payment method), the year on the saved payment method will always show the first item in the select dropdown (in this case: 23).

    The old patch overrides Commerce Payment's default expected expiry year storage format i.e. YYYY to YY. so, the payment methods created by Authorize.net (Accept.js UI) gateway will store year in YY format instead of YYYY. This because the Accept.js UI form allows YY for the expiration year, and that value followed in the whole processing of validation and storing to database.

  • Open in Jenkins → Open on Drupal.org →
    Core: 9.5.x + Environment: PHP 7.3 & MySQL 5.7
    last update about 1 year ago
    12 pass
  • 🇺🇸United States tkiehne

    Re-rolled patch #38 against 8.x-1.10. Also added some modifications to the UI js to disable the pane submit form if no payment info has been added to address #32; I've had this feature in my production site for over a month with no issues, but I have a fairly standard checkout flow so caveat emptor if your checkout flow is highly customized. I also added a few coding standards fixes.

  • 🇺🇸United States tkiehne

    Only remaining issue that I can see is that in the new AcceptJsBase class, the createPaymentMethod() method has code to handle CCA logic which calls a method $this->getCcaApiKey() which was left behind in the AcceptJs plugin. This isn't likely an issue wince the AcceptJsUi plugin will not trigger that code, but I figure this ought to be refactored to have the AcceptJs plugin override createPaymentMethod() to add this logic before calling the Base method. But, I don't use the CCA feature and would appreciate some confirmation before taking that step from someone in the know.

    Otherwise, I've been using this patch in its various states in a production environment for almost 18 months with no issues - would love to get some RTBC focus here and move this into the main branch.

  • Open in Jenkins → Open on Drupal.org →
    Core: 10.2.1 + Environment: PHP 8.1 & MySQL 8
    last update 8 months ago
    7 pass, 2 fail
  • Open in Jenkins → Open on Drupal.org →
    Core: 10.2.1 + Environment: PHP 7.4 & MySQL 5.7
    last update 8 months ago
    Composer require failure
  • 🇺🇸United States tkiehne

    Re-rolled #39 to apply to 8.x-1.11

    Issue in #40 still unresolved

Production build 0.71.5 2024