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.
Issue fork commerce_authnet-3561322
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
Comment #2
tkiehne commentedI 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 eCheckSo, 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.
Comment #3
tkiehne commentedOne 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.
Comment #4
tkiehne commentedComment #5
vmarchukI will take a look, it was changed here https://git.drupalcode.org/project/commerce_authnet/-/commit/f92cabbe1c8...
Comment #6
rlangille commentedConsidering 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.
Comment #7
tkiehne commentedNormalizing 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.
Comment #8
vmarchukComment #10
vmarchuk@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.
Comment #11
tkiehne commentedI 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.
Comment #12
rwanthI would just like to suggested that we add a little more documentation that explains why this step is necessary. Something like:
Comment #14
vmarchukCommitted and tagged a new release https://www.drupal.org/project/commerce_authnet/releases/8.x-1.13