Troubleshooting
After testing payments on the test gateway, the next step is to add a production connection. If there are issues, it is almost always related to required credentials — a case of not providing the proper authentication parameters to the production gateway. Each gateway can have different requirements and their credentials can have a wide variety of naming patterns.
The best way to debug production issues is to look at the communication Spreedly had with the remote party (either a gateway or receiver). Spreedly provides full transparency via the transaction transcript.
Note: As of December 31, 2022, Spreedly only holds transaction transcripts for 90 days after the initial date of the transaction.
Using the transcript
For every Spreedly transaction that involves a remote API call, the details of that remote call are recorded as the transaction transcript. The human-readable, text-based transcript provides low-level insight into the actual details of the remote call including the request headers, body, response status:
curl https://core.spreedly.com/v1/transactions/KS3oZgWXCfFeirK16anYbijLxR/transcript \
-u 'C7cRfNJGODKh4Iu5Ox3PToKjniY:4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ'
The transcript is scrubbed of sensitive information and can be emailed to a support representative at the gateway or receiver.
The response from the gateway/receiver can help determine additional needs to get production transactions running. It may be additional fields to pass to the gateway, or different requirements for configuration settings that need to be adjusted with that provider.
For example, you may want to turn off the CVV requirement or turn off the billing address requirement if a gateway defaults to requiring them. Or, if a gateway requires a list of valid IP addresses, you may need to add Spreedly’s IP Addresses to the gateway UI.
Timeouts
It’s extremely important to us that the Spreedly API is fast. When you make a call to the API, we want to respond as quickly as possible.
The question is, how long should you wait before making the determination in your code that the Spreedly service isn’t operating as it should? Or, to put it another way, how long should you wait to determine that your application is having difficulty talking to the Spreedly service?
Let’s start by focusing on the API calls which are dependent on an external service like a payment gateway. We’re talking here about calls like purchase
and authorize
. You want to ensure in cases like this that you don’t set your timeout too low because if you do, that timeout could be reached before your gateway has responded. So from your application’s perspective, the transaction failed because it timed out. The reality though is that the transaction succeeded but took longer than expected to do so.
So how long is a reasonable amount of time to wait? We have seen gateways take up to 60 seconds to respond to requests when under heavy load. Therefore, when Spreedly talks to a gateway, we use an internal timeout of 61 seconds. At that point, we stop waiting for the gateway to respond and we mark the transaction as failed because we timed out talking to the gateway. This means that for your code, you’ll want to use a timeout at least a second or two more than that (perhaps 64 seconds) for the API calls which interact with a gateway. If you set your timeout for less than that, it could lead to cases where your customer has successfully paid you but your application thinks the payment has failed.
For the API calls that don’t interact with a gateway like showing a transaction or retaining a payment method, a much shorter timeout is necessary. We recommend a timeout of 5-10 seconds to determine that there’s an issue talking to the Spreedly service.
Response codes
There are multiple CVV and AVS response codes. These responses can help determine why a transaction was declined and inform next steps.
CVV response codes
Attribute | Description |
---|---|
D | Suspicious transaction |
I | Failed data validation check |
M | Match |
N | No match |
P | Not processed |
S | Should have been present |
U | Issuer unable to process request |
X | Card does not support verification |
AVS response codes
Attribute | Description |
---|---|
A | Street address matches, but postal code does not match. |
B | Street address matches, but postal code not verified. |
C | Street address and postal code do not match. |
D | Street address and postal code match. Code “M” is equivalent. |
E | AVS data is invalid or AVS is not allowed for this card type. |
F | Card member’s name does not match, but billing postal code matches. |
G | Non-U.S. issuing bank does not support AVS. |
H | Card member’s name does not match. Street address and postal code match. |
I | Address not verified. |
J | Card member’s name, billing address, and postal code match. |
K | Card member’s name matches but billing address and billing postal code do not match. |
L | Card member’s name and billing postal code match, but billing address does not match. |
M | Street address and postal code match. Code “D” is equivalent. |
N | Street address and postal code do not match. For American Express: Card member’s name, street address and postal code do not match. |
O | Card member’s name and billing address match, but billing postal code does not match. |
P | Postal code matches, but street address not verified. |
Q | Card member’s name, billing address, and postal code match. |
R | System unavailable. |
S | Bank does not support AVS. |
T | Card member’s name does not match, but street address matches. |
U | Address information unavailable. Returned if the U.S. bank does not support non-U.S. AVS or if the AVS in a U.S. bank is not functioning properly. |
V | Card member’s name, billing address, and billing postal code match. |
W | Street address does not match, but 9-digit postal code matches. |
X | Street address and 9-digit postal code match. |
Y | Street address and 5-digit postal code match. |
Z | Street address does not match, but 5-digit postal code matches. |
JSON vs XML array structure
There are differences when sending an array of data elements in JSON versus XML. When using the XML
version of an endpoint, the request body will have a parent wrapper XML element in plural form, describing what the element contains. Nested child XML elements specify the individual items of the array.
In the example below, you will see the items
XML element is the parent, with one or more item
XML elements.
<transaction>
<payment_method_token>56wyNnSmuA6CWYP7w0MiYCVIbW6</payment_method_token>
<amount>100</amount>
<currency_code>USD</currency_code>
<gateway_specific_fields>
<card_connect>
<items>
<item>
<line_no>1</line_no>
<material>MATERIAL-1</material>
<disc_amnt>0</disc_amnt>
<unit_cost>900</unit_cost>
<uom>CS</uom>
<description>DESCRIPTION-1</description>
<tax_amnt>117</tax_amnt>
<quantity>1000</quantity>
<upc>UPC-1</upc>
<net_amnt>150</net_amnt>
</item>
<item>
<line_no>2</line_no>
<material>MATERIAL-2</material>
<disc_amnt>0</disc_amnt>
<unit_cost>900</unit_cost>
<uom>CS</uom>
<description>DESCRIPTION-2</description>
<tax_amnt>117</tax_amnt>
<quantity>1000</quantity>
<upc>UPC-1</upc>
<net_amnt>150</net_amnt>
</item>
</items>
</card_connect>
</gateway_specific_fields>
</transaction>
For the JSON
version of an endpoint, the request body will have a parent wrapper object in plural form, describing what it contains. A child property in single form holds the array of objects.
In the example below, you will see the items
JSON element is an object, with an item
property which holds the array of item
objects.
{
"transaction": {
"payment_method_token": "56wyNnSmuA6CWYP7w0MiYCVIbW6",
"amount": 1691,
"currency_code": "USD",
"gateway_specific_fields": {
"card_connect": {
"items": {
"item": [
{
"line_no": "1",
"material": "MATERIAL-1",
"disc_amnt": "0",
"unit_cost": "900",
"uom": "CS",
"description": "DESCRIPTION-1",
"tax_amnt": "117",
"quantity": "1000",
"upc": "UPC-1",
"net_amnt": "150"
},
{
"line_no": "2",
"material": "MATERIAL-2",
"disc_amnt": "0",
"unit_cost": "900",
"uom": "CS",
"description": "DESCRIPTION-2",
"tax_amnt": "117",
"quantity": "1000",
"upc": "UPC-1",
"net_amnt": "150"
}
]
}
}
}
}
}
Updated 8 months ago