cancel
Showing results for 
Search instead for 
Did you mean: 

Refunds etc in new API

So the XML-based API is supposed to be ready for prime time and that's what we should be using for new development?

 

I could be up for that and for retrofitting it, BUT...

 

I was more than a little surprised when installing per instructions put almost 4,200 files (and 25 MB) on my server to support what a little digging shows can be done in a couple of dozen lines of code or less per type of operation, probably less on average taking overlap into account.  IOW minimal change.  That's to get from input-array to output-array sandwiching actual execution of the transaction.  A guy sure can't tell that from a first look at the dox, though.

 

Even after (or because of) all that, there were unresolved dependencies and the sample code was dying on yaml.  It seems this general approach to installation and configuration would become a chronic source of inherent fragility and even vulnerability to deliberate sabotage.

 

So now I'm just embedding a curl connection pretty close to what my existing code base uses, merely spouting and digesting XML instead of the old format. 

 

If I'm not supposed to be using the new stuff yet for production work, then where can I find the docs and examples for old-style ARB and TD not dependent on adapters to the new schema?

 

Now about the refunds in my title:  I copied the example request verbatim.  (That part of the documentation seems a vast improvement over the past, quite an elegant little digest.)

 

<createTransactionRequest xmlns="AnetApi/xml/v1/schema/AnetApiSchema.xsd">
  <merchantAuthentication>
    <name>API_LOGIN_ID</name>
    <transactionKey>API_TRANSACTION_KEY</transactionKey>
  </merchantAuthentication>
  <refId>123456</refId>
  <transactionRequest>
    <transactionType>refundTransaction</transactionType>
    <amount>5</amount>
    <payment>
      <creditCard>
        <cardNumber>5424000000000015</cardNumber>
        <expirationDate>1220</expirationDate>
        <cardCode>999</cardCode>
      </creditCard>
    </payment>
    <refTransId>1122334455</refTransId>
  </transactionRequest>
</createTransactionRequest>

But I plugged in real live everything for a recently settled transaction.

 

Here's what I get: back:

<?xml version="1.0" encoding="utf-8"?>
<createTransactionResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="AnetApi/xml/v1/schema/AnetApiSchema.xsd">
	<refId>1448841865</refId>
	<messages>
		<resultCode>Error</resultCode>
		<message>
			<code>E00027</code>
			<text>The transaction was unsuccessful.</text>
		</message>
	</messages>
	<transactionResponse>
		<responseCode>3</responseCode>
		<authCode />
		<avsResultCode>P</avsResultCode>
		<cvvResultCode />
		<cavvResultCode />
		<transId>0</transId>
		<refTransID>9999999999</refTransID>
		<transHash>99999999999999999999999999999999</transHash>
		<testRequest>0</testRequest>
		<accountNumber>XXXX9999</accountNumber>
		<accountType>Visa</accountType>
		<errors>
			<error>
				<errorCode>33</errorCode>
				<errorText>Invoice Number is required.</errorText>
			</error>
			<error>
				<errorCode>33</errorCode>
				<errorText>Description is required.</errorText>
			</error>
			<error>
				<errorCode>33</errorCode>
				<errorText>Customer ID is required.</errorText>
			</error>
			<error>
				<errorCode>33</errorCode>
				<errorText>Bill To First Name is required.</errorText>
			</error>
			<error>
				<errorCode>33</errorCode>
				<errorText>Bill To Last Name is required.</errorText>
			</error>
			<error>
				<errorCode>33</errorCode>
				<errorText>Bill To Address is required.</errorText>
			</error>
			<error>
				<errorCode>33</errorCode>
				<errorText>Bill To City is required.</errorText>
			</error>
			<error>
				<errorCode>33</errorCode>
				<errorText>Bill To State/Province is required.</errorText>
			</error>
			<error>
				<errorCode>33</errorCode>
				<errorText>Bill To Zip/Postal Code is required.</errorText>
			</error>
			<error>
				<errorCode>33</errorCode>
				<errorText>Bill To Country is required.</errorText>
			</error>
			<error>
				<errorCode>33</errorCode>
				<errorText>Phone is required.</errorText>
			</error>
			<error>
				<errorCode>33</errorCode>
				<errorText>Email is required.</errorText>
			</error>
		</errors>
	</transactionResponse>
</createTransactionResponse>

(Transaction-specific return data changed to 9999s)

 

What's going on?  I've tried providing some of that information, but then it complains about the enclosing elements.  It's almost like it's not recognizing this as a refund request.  But surely the feature must work or it would have come to light already.  So what do I need to do?

 

Having now put my client on notice of the need to implement a new protocol to get new functionality they have requested/demanded, I'm reluctant to backtrack.  But the main thing is to have refunds, subscriptions, and transaction detail functioning by Wednesday AM, so I'll do it the old way if that gets there faster.

Timberliner
Member
1 ACCEPTED SOLUTION

Accepted Solutions

OK, the bottom line is that refunds were failing in the live environment (after succeeding in the sandbox) based non-intuitively on account settings under:

 

Account | Settings | Payment Form | Form Fields and the "Required" column

 

...even though we don't use SIM or the form it generates.

 

Any item marked required on the SIM Form controller page will be required for all refund submissions as well.  The fields marked required control not only SIM and AIM transactions but the new unified methodology, too.  And you may further find that due to mutual exclusions between elements in the schema, you aren't actually able to submit all the account-required fields for a refund.  I haven't had time to completely get to the bottom of that, but e.g. as noted in my earlier post, the order element containing the (previously) required invoiceNumber element was being required by the processing logic but rejected by the schema.

 

In my opinion, requiring items checked on the SIM form configuration page to be present on refunds using the new methodology is an implementation error.  But regardless of your opinion on that, at the very least the caveat needs to be added to the documentation on the main online reference page (http://developer.authorize.net/api/reference/index.html) and in the AIM XML PDF most recently revised Oct 15.  Who would ordinarily guess such a thing?  I just happened to have the intuition.

 

I'm accepting my own reply since it contains the fundamental answer but giving kudos to @RichardH and @RaynorC1emen7 for assistance rendered.

View solution in original post

Timberliner
Member
12 REPLIES 12

Hello @Timberliner

 

Try removing <refTransId> from your request if you are providing the full card number.  Or provide <refTransId> and remove <payment> if you have the transaction ID for a previously settled transaction.

 

Richard

RichardH
Administrator Administrator
Administrator

Thanks for getting back so quickly, Richard.

 

Removing the payment element results in:

 

<code>E00027</code>
...
<errorText>Credit card number is required.</errorText>

 

 

Providing full payment information and removing refTransId results in:

 

<code>E00027</code>
...
<errorText>A valid referenced transaction ID is required.</errorText>

 

 

If I use the full card number plus the refTransId element, I get:

<errorText>Invoice Number is required.</errorText>

So if I add an order element with invoiceNumer and description before the refTransId, I get:

<code>E00003</code><text>The element 'transactionRequest' in namespace 'AnetApi/xml/v1/schema/AnetApiSchema.xsd' has invalid child element 'refTransId' in namespace 'AnetApi/xml/v1/schema/AnetApiSchema.xsd'...

 

Now if I scrounge a copy of my AIM PDF, I guess refund will be one of the options described in there.

 

Is the refund function being used successfully through the XML protocol on production sites?

 

I've had no trouble testing the transaction detail functions live through the new protocol -- only the refund is balking -- but I can't support a hybrid payment implementation.  I need to either retrofit everything with the new or else use the old for TD and ARB.

 

PS In any case, I can't store the full card number or the card code (storing expiration is permitted without full card number), so I'll either need a solution where I can initiate a refund using last4 (or none), or I'll have to tell the client they can't have a refund function outside the merchant interface.  But it's not just messy for them, it's also messier for me if they're doing all their refunds through the ANet site.  That's more importation and reconciliation.

http://www.authorize.net/content/dam/authorize/documents/AIM_guide.pdf

Page 28

The transaction is submitted with the valid transaction ID (x_trans_id) of an original,successfully settled transaction.
The amount being requested for refund is less than or equal to the original settled amount.
The sum of multiple Credit transactions submitted against the original transaction is less than or equal to the original settled amount.
At least the last four digits of the credit card number (x_card_num) used for the original, successfully settled transaction
are submitted. An expiration date is not required.
The transaction is submitted within 120 days of the settlement date of the original transaction.
 
 
refTransId with masked last 4 CC# (e.g. XXXX0015)

OK, the bottom line is that refunds were failing in the live environment (after succeeding in the sandbox) based non-intuitively on account settings under:

 

Account | Settings | Payment Form | Form Fields and the "Required" column

 

...even though we don't use SIM or the form it generates.

 

Any item marked required on the SIM Form controller page will be required for all refund submissions as well.  The fields marked required control not only SIM and AIM transactions but the new unified methodology, too.  And you may further find that due to mutual exclusions between elements in the schema, you aren't actually able to submit all the account-required fields for a refund.  I haven't had time to completely get to the bottom of that, but e.g. as noted in my earlier post, the order element containing the (previously) required invoiceNumber element was being required by the processing logic but rejected by the schema.

 

In my opinion, requiring items checked on the SIM form configuration page to be present on refunds using the new methodology is an implementation error.  But regardless of your opinion on that, at the very least the caveat needs to be added to the documentation on the main online reference page (http://developer.authorize.net/api/reference/index.html) and in the AIM XML PDF most recently revised Oct 15.  Who would ordinarily guess such a thing?  I just happened to have the intuition.

 

I'm accepting my own reply since it contains the fundamental answer but giving kudos to @RichardH and @RaynorC1emen7 for assistance rendered.

Timberliner
Member

Also, although the schema requires an expiration date with the credit card, it appears the processing logic for refunds accepts any future date, i.e. does not validate the expiration against the card.

 

I don't know if that's universally true, but it works with the live card I'm using for testing.

 

That's useful for people concerned about storing the date (though multiple authorities claim it's OK to store the date as long as you don't also store the full card number) or who need to add refunds to an existing implementation that discards the date.

Timberliner
Member

One other correction to what I wrote about mutual exclusions:

 

I dug into the schema and found there are no mutual exclusions, only a required order of elements, most of which are optional. Those can look like mutual exclusions if you don't know the order.   Anyway, it was a little too late to correct the post in question.

 

So once you have a refTransId, it becomes too late to include a payment.  Once you include an order, it becomes too late to include a refTransId.  The provided code takes care of ordering the elements for you.  But if installation fails or you're adapting existing code to send and receive the new XML, you obviously have to know what the schema requires.  I've seen I'm not the only one for whom installation via composer went off the deep end, and that form of installation will always inherently be the sum of all the frailties of all its individual pieces. So it's good to know how to encode and decode your own XML.

 

Child elements of a transactionRequest must occur in the following order.

 

<amount>

<currencyCode>

<payment>

<profile>

<solution>

<callId>

<authCode>

<refTransId>

<splitTenderId>

<order>

<lineItems>

<tax>

<duty>

<shipping>

<taxExempt>

<poNumber>

<customer>

<billTo>

<shipTo>

<customerIP>

<cardholderAuthentication>

<retail>

<employeeId>

<transactionSettings>

<userFields>

Timberliner
Member

Hello this is my request

{
"createTransactionRequest": {
"merchantAuthentication": {
"name": "XXXXXXX",
"transactionKey": "XXXXXXXX"
},
"refId": "123456",
"transactionRequest": {
"transactionType": "refundTransaction",
"amount": "0.01",
"refTransId": "8746352001"
}
}
}

 

and its throwing me error as 

 

"errors": [
{
"errorCode": "33",
"errorText": "Credit card number is required."
}
],

 

can anyone help me? 

 

Thanx

@Nilam

 

Refund transactions require either the entire card number and expiration, or the refTransId, last 4 of the card number and masked expiration date.  See https://developer.authorize.net/api/reference/#payment-transactions-refund-a-transaction

 

If you don't have the last 4 and expiration, use getTransactionDetails to obtain the payment object which includes this information. https://developer.authorize.net/api/reference/#transaction-reporting-get-transaction-details

 

Richard