Authorize.Net sends form data, not JSON.
Your webhook handler is probably wrong.
Authorize.Net uses numeric response codes (1 through 4), Basic auth with a Login ID and Transaction Key, and Silent Post for payment notifications — not modern JSON webhooks. Getting a sandbox account takes time. This mock skips all of that so you can start testing right now.
Authorize.Net is one of North America's oldest payment gateways. It uses a numeric response code system: 1 = Approved, 2 = Declined, 3 = Error, 4 = Held for Review. Payment notifications arrive as form-encoded Silent Posts — not modern JSON webhooks. Every field in the Silent Post is prefixed with x_.
Getting a sandbox account at developer.authorize.net takes time and requires separate credentials from your production account. This mock lets you start testing your response code branching logic and Silent Post handler immediately — no account setup needed. You can trigger any of the four response codes on demand and validate your x_-field parsing.
The Held for Review state (code 4) trips up most integrations because it is neither approved nor declined. The transaction requires manual review by the merchant before funds are captured. Your system needs to handle this as a pending state — do not fulfill the order, do not show a failure message. Wait for the subsequent Silent Post that confirms approval or rejection after review.
How it works
Get your mock credentials
Copy the API Login ID and Transaction Key from MockGateway. You don't need a real Authorize.Net merchant account or a developer sandbox at developer.authorize.net.
POST the payment request
Send amount, currency, and invoice number using Basic auth. The mock responds with a redirectUrl to the hosted payment form and a transaction ID.
Read the response code
Your server receives responseCode 1, 2, 3, or 4. Each means something different. Branch your logic on this number — do not rely on the text reason string.
Handle the Silent Post
After payment, Authorize.Net sends form-encoded data to your listener URL. MockGateway delivers the same x_-prefixed fields that production sends.
Response codes
Authorize.Net returns one of four numeric codes. Your integration must handle all of them.
responseCode = 1→ Fulfill the orderThe payment went through. You will see responseCode = 1 and a 6-character authCode from the bank. Safe to confirm the order and start fulfillment.
responseCode = 2→ Ask customer to retryThe bank refused the charge. Check reasonCode to find out why — insufficient funds, expired card, or velocity limit. Show the customer a clear message and let them try a different card.
responseCode = 3→ Check your codeA technical problem occurred — a bad field, a connection timeout, or a validation failure. This is not a customer decline. Log the reasonCode, fix the issue, then retry.
responseCode = 4→ Check fraud consoleAuthorize.Net's fraud filters flagged this transaction. The charge has not gone through yet. Review it in the merchant console and either approve or void it manually.
Silent Post is not a webhook
Most payment gateways send JSON webhooks today. Authorize.Net uses Silent Post — form-encoded data with x_-prefixed field names. If you write a JSON handler expecting event.type, it will not work. Here is the difference:
x_response_code, x_trans_idreq.body.x_response_codeevent.type, data.object.idrequest.json()['data'] Calling request.json() on a Silent Post body returns nothing because the Content-Type is application/x-www-form-urlencoded. In Node.js, use express.urlencoded() middleware and read req.body.x_response_code. In Python, use request.form.get('x_response_code').
Integration code
Request, response, verify, and the exact Silent Post payload your listener will receive.
curl -X POST https://mockgateway.com/api/base/authorize-net/init \
-H "Authorization: Basic $(echo -n 'API_LOGIN_ID:TRANSACTION_KEY' | base64)" \
-H "Content-Type: application/json" \
-d '{
"amount": "99.99",
"currency": "USD",
"description": "Order #1234",
"invoice_number": "INV-001"
}'Request parameters
Fields accepted by POST /api/base/authorize-net/init
| Parameter | Type | Required | Description |
|---|---|---|---|
amount | number | required | Transaction amount e.g. 99.99 |
currency | string | required | ISO 4217 currency e.g. USD |
description | string | optional | Transaction description |
invoice_number | string | optional | Your invoice reference e.g. INV-001 |
Response fields
Fields returned in the AIM response and Silent Post payload.
| Field | Type | Description |
|---|---|---|
transactionId | string | Authorize.Net transaction ID |
responseCode | enum | 0=Awaiting submission, 1=Approved, 2=Declined, 3=Error, 4=Held for Review |
authCode | string | Authorization code |
created_at | datetime | |
detailResponseCode | integer | The numeric response code getTransactionDetails returns, as opposed to the string the charge returns |
Why developers use this mock
No merchant account needed
Authorize.Net requires a separate sandbox account at developer.authorize.net with its own credentials. This mock skips that entirely. Use fake credentials and start testing your responseCode logic right away.
Test all four response codes
Pick responseCode 1, 2, 3, or 4 on demand. Confirm that your code handles each one correctly — including code 3 (technical error) which most integrations never test before going live.
Silent Post without production
Authorize.Net sends form-encoded data, not JSON. The mock delivers the same x_-prefixed Silent Post payload to your listener URL so you can test parsing before your account is provisioned.
Frequently asked questions
What is the difference between test mode and a sandbox account?
Test mode is a toggle on your live Authorize.Net account. Transactions go through but are not charged. A sandbox account is a completely separate environment at developer.authorize.net with its own credentials. They are not the same — most developers need the sandbox, not test mode.
What is Silent Post and why is it different from a webhook?
Silent Post is form-encoded data, not JSON. Authorize.Net POSTs it to a URL you set in your account settings. Your listener must read x_response_code, x_trans_id, and other x_-prefixed fields from the form body. Calling request.json() on a Silent Post body returns nothing.
What does responseCode 3 mean?
Code 3 is a technical error, not a customer decline. Something went wrong with the request itself — a bad field format, a connection timeout, or a validation failure. Do not show a card declined message to the customer. Log the reasonCode and investigate.
When should I move to the real Authorize.Net sandbox?
After your responseCode branching and Silent Post handler are working correctly here. The Authorize.Net developer sandbox at developer.authorize.net gives you full access to the hosted payment form and real AIM API responses with your test credentials.
Other gateway templates
Looking for a different provider?