When trying to issue a refund on a transaction I get this error

The element 'transactionRequest' in namespace 'AnetApi/xml/v1/schema/AnetApiSchema.xsd' has invalid child element 'payment' in namespace 'AnetApi/xml/v1/schema/AnetApiSchema.xsd'. List of possible elements expected: 'splitTenderId, order, lineItems, tax, duty, shipping, taxExempt, poNumber, customer, billTo, shipTo, customerIP, cardholderAuthentication, retail, employeeId, transactionSettings, userFields, surcharge, merchantDescriptor, subMerchant' in namespace 'AnetApi/xml/v1/schema/AnetApiSchema.xsd'.

In case it matters was using a sandbox account with checkout set to authorize only and then did a manual capture through the order interface.

Comments

ctrlADel created an issue. See original summary.

ctrladel’s picture

Issue summary: View changes
ctrladel’s picture

Attached patch resolved my issue. There were 2 separate issues.

ctrladel’s picture

StatusFileSize
new1.24 KB

Small fix to where I put the refTransId

josephdpurcell’s picture

Status: Active » Needs work
  1. +++ b/src/Plugin/Commerce/PaymentGateway/AuthorizeNet.php
    @@ -329,15 +329,15 @@ class AuthorizeNet extends OnsitePaymentGatewayBase implements AuthorizeNetInter
    +      'expirationDate' => 'XXXX',
    

    This will break non-sandbox, yes? Can you use the "Is sandbox?" flag to toggle whether to pull expiration date from the $payment_method?

  2. +++ b/src/Plugin/Commerce/PaymentGateway/AuthorizeNet.php
    @@ -329,15 +329,15 @@ class AuthorizeNet extends OnsitePaymentGatewayBase implements AuthorizeNetInter
    +    $transaction_request->refTransId = $payment->getRemoteId();
    

    If moving this out of the constructor is to control the order of parameters, I don't think this solution is best. Ordering restrictions should be seamless to the caller of the AuthorizeNet.php class--i.e. can we put ordering logic into the class?

ctrladel’s picture

Status: Needs work » Active

This will break non-sandbox, yes? Can you use the "Is sandbox?" flag to toggle whether to pull expiration date from the $payment_method?

The documentation doesn't specify a difference between sandbox and production for refunds.

expirationDate	Required. 
The expiration date should be submitted masked as simply "XXXX" 
Optional for Card Present
If moving this out of the constructor is to control the order of parameters, I don't think this solution is best. Ordering restrictions should be seamless to the caller of the AuthorizeNet.php class--i.e. can we put ordering logic into the class?

The class is provided by the SDK and looks fairly bare bones currently, would need some input from mglaman on if this should be resolved there.

mglaman’s picture

So the API documentation is conflicting.

For the root payment entry

When issuing a credit card refund, the request must include either a full card number and expiration, or previous transId and last 4 digits of the card number. If you don't have the last 4 digits, you can use getTransactionDetails to get the payment object needed to issue a refund.

But for

expirationDate

inside of it

The expiration date should be submitted masked as simply "XXXX"

Also

If moving this out of the constructor is to control the order of parameters, I don't think this solution is best. Ordering restrictions should be seamless to the caller of the AuthorizeNet.php class--i.e. can we put ordering logic into the class?

As painful as it sounds, it seems like there needs to be a serializer class which puts properties where they are expected to belong when a request is fired.

mglaman’s picture

I've updated the SDK to provide property mapping which fixes the refTransId issue. I also added refund tests. Passing XXXX or 1234 didn't matter.

mglaman’s picture

Status: Active » Postponed (maintainer needs more info)

Can you run composer update commerceguys/authnet and see if the latest commits fix refund issues? I'm thinking it might not need changes in the module itself.

onedotover’s picture

I just tried out the latest from commerceguys/authnet and I'm getting this error now:

The 'AnetApi/xml/v1/schema/AnetApiSchema.xsd:expirationDate' element is invalid - The value XX is invalid according to its datatype 'String' - The actual length is less than the MinLength value.

mglaman’s picture

Status: Postponed (maintainer needs more info) » Active

Thanks.

The test code in the SDK is

        $request = $this->xmlRequestFactory->createTransactionRequest();
        $request->setTransactionRequest(new TransactionRequest([
            'transactionType' => TransactionRequest::REFUND,
            'refTransId' => $response->transactionResponse->transId,
            'amount' => 5.00,
        ]));
        $transactionRequest->addPayment(new CreditCard([
            'cardNumber' => 'XXXX1111',
            'expirationDate' => 'XXXX',
        ]));

The module

    $request = new CreateTransactionRequest($this->authnetConfiguration, $this->httpClient);
    $transaction_request = new TransactionRequest([
      'transactionType' => TransactionRequest::REFUND,
      'amount' => $payment->getAmount()->getNumber(),
      'refTransId' => $payment->getRemoteId(),
    ]);
    /** @var \Drupal\commerce_payment\Entity\PaymentMethod $payment_method */
    $payment_method = $payment->getPaymentMethod();
    $transaction_request->addPayment(new CreditCardDataType([
      'cardNumber' => $payment_method->card_number->value,
      'expirationDate' => $payment_method->expiration_month->value . $payment_method->expiration_year->value,
    ]));

From #10 it looks like a string less than four digits was passed. Not sure how, especially if just XX.

Can someone just try manually changing the code to pass XXXX instead of the payment method's expiration information?

onedotover’s picture

Ok, so the error returned from Auth.net is adding the XX for some reason. The actual request was sending an empty expirationDate. I tested with both the actual expiration date, and XXXX and both seemed to work in the Sandbox (which lines up with what mglaman found in #8).

I also found a related bug having to do with the amount refunded. The attached patch for the module fixed things for me.

mglaman’s picture

Status: Active » Needs review

Sweet! Thanks so much for the find. I want to just see another +1 from other users here then I'll commit. Won't tag a new beta, though, as we'll be rolling Commerce RC1 soon and need a new beta just for that.

mglaman’s picture

Status: Needs review » Fixed

Thanks, everyone!

  • mglaman committed d7777b6 on 8.x-1.x authored by onedotover
    Issue #2883122 by ctrlADel, onedotover, mglaman, josephdpurcell: Error...
ctrladel’s picture

Was finally able to keep a database long enough to settle a transaction and can confirm that the issue is fixed. Thanks for all the hard work.

Status: Fixed » Closed (fixed)

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