Problem/Motivation

I received an error message for a customer trying to complete an order:

Unsupported credit card type "American Express"

I can see in Authorize.net that payment methods were created for this customer, but none was created in our Drupal Commerce system due to the reported error.

Steps to reproduce

Install commerce with authnet 8.x-1.12; set up a credit card payment AcceptJs gateway; attempt to use an Amex card with the gateway.

Proposed resolution

Looking at the last update, commit f92cabbe moved the mapCreditCardType() function to the new PaymentGateway Utility service; there are differences in the CC mapping:

Previous (in AcceptJs Plugin):

    $map = [
      'American Express' => 'amex',
      'Diners Club' => 'dinersclub',
      'Discover' => 'discover',
      'JCB' => 'jcb',
      'MasterCard' => 'mastercard',
      'Visa' => 'visa',
      'China UnionPay' => 'unionpay',
    ];

New:

    $map = [
      'AmericanExpress' => 'amex',
      'DinersClub' => 'dinersclub',
      'Discover' => 'discover',
      'JCB' => 'jcb',
      'MasterCard' => 'mastercard',
      'Visa' => 'visa',
      'UnionChinaPay' => 'unionpay',
    ];

Note the differences with spaces - I can't find any documentation for why these were changed, so I don't know if the new mappings are correct in any way, but I know from the error that at least we need "American Express" as an option in the map.

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

tkiehne created an issue. See original summary.

tkiehne’s picture

I can see in the Authnet API docs where the strings are defined:

https://developer.authorize.net/api/reference/index.html

Visa, Mastercard, Discover, AmericanExpress, DinersClub, JCB, UnionChinaPay, or eCheck

So, while the current implementation may be correct per the documentation, clearly there is something off if we are getting values that are not in this list. API change log has not been updated since 2019, so I can't tell if this is a recent change or not.

tkiehne’s picture

One more note of clarification, this issue was encountered using AcceptJs. Looking at the code, the card type is extracted from the customer profile, parsed from the validationDirectResponseList string in the response (see doCreatePaymentMethod() in AcceptJs.php)

The API docs don't explain what values to expect here as they do when grabbing the value from accountType when processing a payment transaction:
https://developer.authorize.net/api/reference/index.html#customer-profil...

So theoretically the values for card type could be different.

tkiehne’s picture

Issue summary: View changes
vmarchuk’s picture

rlangille’s picture

Considering the discrepancy between the accountTypes returned by accept.js and the documentation - I'd think it would be prudent to strip white-space and case before doing the mapping.

tkiehne’s picture

Normalizing case and spacing would be good, if nothing else owing to the difference in the documented allowed values (e.g. 'MasterCard') and the values they show in their examples (e.g. 'Mastercard')

There is the problem with "UnionChinaPay" versus "China UnionPay" that that doesn't fix though.

I'm under the impression that values placed in the validationDirectResponseList string are user-facing labels as opposed to the internal codes returned under accountType. Either we need to account for all permutations in the service method or revert to gateway plugin-specific functions.

vmarchuk’s picture

Version: 8.x-1.12 » 8.x-1.x-dev

vmarchuk’s picture

Status: Active » Needs review

@rlangille @tkiehne
Yes, the list is different due to validationDirectResponseList. We can send a GetTransactionDetailsRequest and get the same list as in paymentGatewayUtility->mapCreditCardType(), but this will be an additional request to the API.
We can also make a smooth transition between what we can get from validationDirectResponseList and what we have in paymentGatewayUtility->mapCreditCardType(). What do you think about https://git.drupalcode.org/project/commerce_authnet/-/merge_requests/41/...? I tested this MR, and all credit cards work fine.
We can also just use the old list with mapCreditCardType() values.
I can tag 8.x-1.13 with this fix today.

tkiehne’s picture

I think either approach works and avoids another API hit. My local fix has been to merge both lists, but I can see how that could cause confusion later on depending on which context someone is coming from, so remanding the mapping back to the plugin helps keep the context consistent at least.

rwanth’s picture

I would just like to suggested that we add a little more documentation that explains why this step is necessary. Something like:

/**
 * Maps a user-facing label for an Authorize.Net credit card type, retrieved
 * from the API response's validationDirectResponseList, to a Commerce credit
 * card type.
 *
 * @see https://www.drupal.org/project/commerce_authnet/issues/3561322
 *
 * @param string $card_type
 *   The user-facing label of Authorize.Net credit card type.
 *
 * @return string
 *   The Commerce credit card type.
 */
protected function mapCreditCardType(string $card_type): string {
  // Map labels to Authorize.Net accountType ID strings.
  $map = [
    'American Express' => 'AmericanExpress',
    'Diners Club' => 'DinersClub',
    'Discover' => 'Discover',
    'JCB' => 'JCB',
    'MasterCard' => 'MasterCard',
    'Visa' => 'Visa',
    'China UnionPay' => 'UnionChinaPay',
  ];

  // Then, map Authorize.Net accountType to Commerce credit card type.
  return $this->paymentGatewayUtility->mapCreditCardType($map[$card_type]);
}

  • vmarchuk committed d3e9a6d8 on 8.x-1.x
    Issue #3561322: Update list of supported credit cards.
    
vmarchuk’s picture

Status: Needs review » Fixed

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.