Create Authorization
Overview
Create an Authorization to reserve funds on a payment instrument before completing the transaction. Authorizations provide a hold on funds that can later be captured or voided. Supports 3D Secure authentication, CVV verification, buyer charges, and level 2/3 processing data.
Resource Access
- User Permissions: Merchant users with authorization permissions
- Endpoint:
POST /authorizations
Arguments
| Parameter | Type | Required | Description |
|---|---|---|---|
| amount | integer | Yes | Amount to authorize in cents |
| currency | string | Yes | Currency code (e.g., USD) |
| merchant | string | Yes | ID of the merchant |
| source | string | Yes | ID of the payment instrument |
| tags | object | No | Key-value metadata tags |
| idempotency_id | string | No | Unique ID to ensure request is performed only once |
| 3d_secure_authentication | object | No | 3D Secure authentication data |
| additional_buyer_charges | object | No | Additional buyer charges (e.g., surcharges) |
| additional_purchase_data | object | No | Level 2/3 processing data |
3D Secure Authentication Object
| Parameter | Type | Required | Description |
|---|---|---|---|
| cardholder_authentication | string | Yes | Base64 encoded cardholder authentication value (CAVV) |
| electronic_commerce_indicator | string | Yes | ECI value (AUTHENTICATED, ATTEMPTED, NOT_AUTHENTICATED) |
| transaction_id | string | Yes | 3DS transaction ID |
Additional Buyer Charges Object
| Parameter | Type | Required | Description |
|---|---|---|---|
| cc_surcharge_amount | integer | No | Credit card surcharge amount in cents |
Additional Purchase Data Object
| Parameter | Type | Required | Description |
|---|---|---|---|
| customer_reference_number | string | No | Customer reference number |
| sales_tax | integer | No | Sales tax amount in cents |
| item_data | array | No | Array of item details for level 3 processing |
Example Requests
Basic Authorization
curl -X POST \
'https://api.ahrvo.network/payments/na/authorizations' \
-u username:password \
-H 'Content-Type: application/json' \
-d '{
"amount": 100,
"currency": "USD",
"merchant": "MU7noQ1wdgdAeAfymw2rfBMq",
"source": "PIkxmtueemLD6dN9ZoWGHT44",
"tags": {
"order_number": "21DFASJSAKAS"
}
}'
Authorization with 3D Secure
curl -X POST \
'https://api.ahrvo.network/payments/na/authorizations' \
-u username:password \
-H 'Content-Type: application/json' \
-d '{
"amount": 100,
"currency": "USD",
"merchant": "MU7noQ1wdgdAeAfymw2rfBMq",
"source": "PIkxmtueemLD6dN9ZoWGHT44",
"3d_secure_authentication": {
"cardholder_authentication": "BwABBJQ1AgAAAAAgJDUCAAAAAAA=",
"electronic_commerce_indicator": "AUTHENTICATED",
"transaction_id": "EaOMucALHQqLAEGAgk"
}
}'
Authorization with Buyer Surcharge
curl -X POST \
'https://api.ahrvo.network/payments/na/authorizations' \
-u username:password \
-H 'Content-Type: application/json' \
-d '{
"amount": 100,
"currency": "USD",
"merchant": "MU7noQ1wdgdAeAfymw2rfBMq",
"source": "PIkxmtueemLD6dN9ZoWGHT44",
"additional_buyer_charges": {
"cc_surcharge_amount": 10
}
}'
Authorization with Level 2/3 Data
curl -X POST \
'https://api.ahrvo.network/payments/na/authorizations' \
-u username:password \
-H 'Content-Type: application/json' \
-d '{
"amount": 100,
"currency": "USD",
"merchant": "MU7noQ1wdgdAeAfymw2rfBMq",
"source": "PIkxmtueemLD6dN9ZoWGHT44",
"additional_purchase_data": {
"customer_reference_number": "CUST123",
"sales_tax": 10,
"item_data": [
{
"amount_excluding_sales_tax": 100,
"amount_including_sales_tax": 110,
"commodity_code": "CODE123",
"description": "Product description",
"quantity": 1,
"unit_of_measure": "EA"
}
]
}
}'
Example Response
{
"id": "AUgspz5X2AwSne5g78qNeYD1",
"created_at": "2024-12-04T08:25:21.93Z",
"updated_at": "2024-12-04T08:25:21.93Z",
"amount": 100,
"amount_requested": 100,
"application": "APc9vhYcPsRuTSpKD9KpMtPe",
"currency": "USD",
"expires_at": "2024-12-11T08:25:21.93Z",
"state": "SUCCEEDED",
"merchant": "MU7noQ1wdgdAeAfymw2rfBMq",
"source": "PIkxmtueemLD6dN9ZoWGHT44",
"address_verification": "POSTAL_CODE_AND_STREET_MATCH",
"security_code_verification": "MATCHED",
"is_void": false,
"void_state": "UNATTEMPTED",
"tags": {
"order_number": "21DFASJSAKAS"
},
"trace_id": "27aad359-b747-4159-9f01-bcaa77245d71",
"transfer": null,
"_links": {
"self": {
"href": "https://api.ahrvo.network/payments/na/authorizations/AUgspz5X2AwSne5g78qNeYD1"
}
}
}
Response Fields
| Field | Type | Description |
|---|---|---|
| id | string | Unique authorization ID |
| created_at | string | Timestamp when created |
| updated_at | string | Timestamp when last updated |
| amount | integer | Authorized amount in cents |
| amount_requested | integer | Requested amount in cents |
| application | string | ID of the application |
| currency | string | Currency code |
| expires_at | string | Authorization expiration timestamp (typically 7 days) |
| state | string | State (SUCCEEDED, FAILED, PENDING) |
| merchant | string | ID of the merchant |
| source | string | ID of the payment instrument |
| address_verification | string | AVS result |
| security_code_verification | string | CVV verification result |
| is_void | boolean | Whether authorization has been voided |
| void_state | string | Void attempt state |
| tags | object | Metadata tags |
| trace_id | string | Trace ID for tracking |
| transfer | string | ID of transfer if captured (null if not) |
Authorization States
| State | Description |
|---|---|
| SUCCEEDED | Authorization approved and funds reserved |
| FAILED | Authorization declined or failed |
| PENDING | Authorization pending approval |
Verification Results
Address Verification (AVS)
| Result | Description |
|---|---|
| POSTAL_CODE_AND_STREET_MATCH | Both postal code and street address match |
| POSTAL_CODE_MATCH | Only postal code matches |
| STREET_MATCH | Only street address matches |
| NO_MATCH | Neither postal code nor street match |
| UNAVAILABLE | AVS not available |
Security Code Verification (CVV)
| Result | Description |
|---|---|
| MATCHED | CVV matches |
| NOT_MATCHED | CVV does not match |
| UNAVAILABLE | CVV check not available |
Additional Information
-
Authorization Hold: Reserves funds temporarily
- Holds typically last 7 days
expires_atshows expiration timestamp- Must capture before expiration
- Void to release hold early
-
Capture vs Void: Two options after authorization
- Capture: Complete transaction and move funds (PUT with capture_amount)
- Void: Release hold and cancel transaction (PUT with void_me=true)
-
Idempotency: Prevent duplicate authorizations
- Use
idempotency_idparameter - Same ID returns original authorization
- Prevents accidental duplicate charges
- Recommended for all production transactions
- Use
-
3D Secure: Enhanced fraud protection
- Requires cardholder authentication
- Shifts liability to card issuer
- Lower fraud rates
- May increase approval rates
- Obtain 3DS data before authorization
-
Buyer Surcharges: Credit card fees
- Add surcharge to transaction
- Check state regulations (some prohibit)
- Clearly disclose to customers
- Separate from base amount
-
Level 2/3 Processing: Lower interchange fees
- Provide detailed purchase data
- Reduces processing fees for B2B/B2G
- Requires item-level details
- Sales tax breakdown
- Customer reference numbers
-
Address/CVV Verification: Fraud prevention
- AVS checks billing address
- CVV checks security code
- Both reduce fraud risk
- Check verification results in response
- MATCHED results preferred
Use Cases
Basic Card Authorization
// Create basic authorization for $1.00
async function createAuthorization(merchantId, paymentInstrumentId) {
const response = await fetch(
'https://api.ahrvo.network/payments/na/authorizations',
{
method: 'POST',
headers: {
'Authorization': 'Basic ' + btoa('username:password'),
'Content-Type': 'application/json'
},
body: JSON.stringify({
amount: 100,
currency: 'USD',
merchant: merchantId,
source: paymentInstrumentId,
tags: {
order_number: 'ORD-' + Date.now()
}
})
}
);
const authorization = await response.json();
if (authorization.state === 'SUCCEEDED') {
console.log('✓ Authorization approved');
console.log(` Amount: $${authorization.amount / 100}`);
console.log(` Expires: ${authorization.expires_at}`);
console.log(` AVS: ${authorization.address_verification}`);
console.log(` CVV: ${authorization.security_code_verification}`);
} else {
console.log('✗ Authorization declined');
}
return authorization;
}
Authorization with Idempotency
// Use idempotency to prevent duplicate authorizations
async function safeAuthorization(merchantId, paymentInstrumentId, orderId) {
const idempotencyId = `order-${orderId}`;
const response = await fetch(
'https://api.ahrvo.network/payments/na/authorizations',
{
method: 'POST',
headers: {
'Authorization': 'Basic ' + btoa('username:password'),
'Content-Type': 'application/json'
},
body: JSON.stringify({
amount: 5000,
currency: 'USD',
merchant: merchantId,
source: paymentInstrumentId,
idempotency_id: idempotencyId,
tags: {
order_id: orderId
}
})
}
);
const authorization = await response.json();
console.log('Authorization created with idempotency protection');
console.log(`Idempotency ID: ${idempotencyId}`);
console.log('Duplicate requests will return this same authorization');
return authorization;
}
3D Secure Authorization
// Process authorization with 3D Secure authentication
async function create3DSecureAuthorization(merchantId, paymentInstrumentId, threeDSData) {
const response = await fetch(
'https://api.ahrvo.network/payments/na/authorizations',
{
method: 'POST',
headers: {
'Authorization': 'Basic ' + btoa('username:password'),
'Content-Type': 'application/json'
},
body: JSON.stringify({
amount: 10000,
currency: 'USD',
merchant: merchantId,
source: paymentInstrumentId,
'3d_secure_authentication': {
cardholder_authentication: threeDSData.cavv,
electronic_commerce_indicator: 'AUTHENTICATED',
transaction_id: threeDSData.transactionId
},
tags: {
secure_transaction: 'true'
}
})
}
);
const authorization = await response.json();
console.log('3D Secure authorization created');
console.log('Liability shifted to card issuer');
console.log(`State: ${authorization.state}`);
return authorization;
}
Authorization with Surcharge
// Add credit card surcharge to authorization
async function authorizationWithSurcharge(merchantId, paymentInstrumentId) {
const baseAmount = 10000; // $100.00
const surchargeAmount = 350; // $3.50 (3.5% surcharge)
const response = await fetch(
'https://api.ahrvo.network/payments/na/authorizations',
{
method: 'POST',
headers: {
'Authorization': 'Basic ' + btoa('username:password'),
'Content-Type': 'application/json'
},
body: JSON.stringify({
amount: baseAmount,
currency: 'USD',
merchant: merchantId,
source: paymentInstrumentId,
additional_buyer_charges: {
cc_surcharge_amount: surchargeAmount
},
tags: {
base_amount: baseAmount.toString(),
surcharge: surchargeAmount.toString(),
total: (baseAmount + surchargeAmount).toString()
}
})
}
);
const authorization = await response.json();
console.log('Authorization with surcharge created');
console.log(`Base amount: $${baseAmount / 100}`);
console.log(`Surcharge: $${surchargeAmount / 100}`);
console.log(`Total: $${(baseAmount + surchargeAmount) / 100}`);
return authorization;
}
Level 3 Processing Authorization
// Create authorization with level 3 data for lower fees
async function level3Authorization(merchantId, paymentInstrumentId) {
const response = await fetch(
'https://api.ahrvo.network/payments/na/authorizations',
{
method: 'POST',
headers: {
'Authorization': 'Basic ' + btoa('username:password'),
'Content-Type': 'application/json'
},
body: JSON.stringify({
amount: 25000,
currency: 'USD',
merchant: merchantId,
source: paymentInstrumentId,
additional_purchase_data: {
customer_reference_number: 'PO-12345',
sales_tax: 2000,
item_data: [
{
amount_excluding_sales_tax: 15000,
amount_including_sales_tax: 16500,
commodity_code: 'WIDGET-A',
description: 'Premium Widget',
quantity: 10,
unit_of_measure: 'EA'
},
{
amount_excluding_sales_tax: 8500,
amount_including_sales_tax: 9350,
commodity_code: 'GADGET-B',
description: 'Standard Gadget',
quantity: 5,
unit_of_measure: 'EA'
}
]
},
tags: {
transaction_type: 'b2b',
po_number: 'PO-12345'
}
})
}
);
const authorization = await response.json();
console.log('Level 3 authorization created');
console.log('Lower interchange fees applied');
console.log(`Items: ${authorization.additional_purchase_data?.item_data?.length || 0}`);
return authorization;
}
Best Practices
-
Always Check State: Verify authorization succeeded
if (authorization.state === 'SUCCEEDED') {
// Proceed with fulfillment
} else {
// Handle decline
} -
Use Idempotency: Prevent duplicate charges
- Generate unique ID per order
- Use order ID or similar identifier
- Store for reference
-
Check Verification Results: AVS and CVV
const isVerified =
authorization.address_verification === 'POSTAL_CODE_AND_STREET_MATCH' &&
authorization.security_code_verification === 'MATCHED';
if (!isVerified) {
// Consider additional fraud checks
} -
Monitor Expiration: Capture before expires_at
- Authorizations typically expire in 7 days
- Set reminders for capture
- Void if not capturing
-
Use 3D Secure: When available
- Better fraud protection
- Liability shift
- May improve approval rates
-
Store Authorization ID: For later capture
- Save to database
- Link to order
- Reference for capture/void
-
Tag Everything: Comprehensive metadata
- Order numbers
- Customer IDs
- Transaction types
- Helps with reconciliation
Common Workflows
Standard Authorization Flow
// Complete authorization workflow
async function processOrder(order) {
console.log('=== Processing Order ===\n');
// Step 1: Create authorization
console.log('Step 1: Creating authorization...');
const authorization = await fetch(
'https://api.ahrvo.network/payments/na/authorizations',
{
method: 'POST',
headers: {
'Authorization': 'Basic ' + btoa('username:password'),
'Content-Type': 'application/json'
},
body: JSON.stringify({
amount: order.amount,
currency: 'USD',
merchant: order.merchantId,
source: order.paymentInstrumentId,
idempotency_id: `order-${order.id}`,
tags: {
order_id: order.id,
customer_id: order.customerId
}
})
}
).then(r => r.json());
// Step 2: Check state
if (authorization.state !== 'SUCCEEDED') {
console.log('✗ Authorization declined');
return { success: false, authorization };
}
console.log('✓ Authorization approved');
console.log(` Authorization ID: ${authorization.id}`);
console.log(` Amount: $${authorization.amount / 100}`);
console.log(` Expires: ${authorization.expires_at}`);
// Step 3: Verify AVS/CVV
const avsGood = authorization.address_verification === 'POSTAL_CODE_AND_STREET_MATCH';
const cvvGood = authorization.security_code_verification === 'MATCHED';
if (!avsGood || !cvvGood) {
console.log('⚠ Verification warning:');
console.log(` AVS: ${authorization.address_verification}`);
console.log(` CVV: ${authorization.security_code_verification}`);
console.log('Consider additional fraud review');
}
// Step 4: Store authorization
await saveToDatabase({
orderId: order.id,
authorizationId: authorization.id,
amount: authorization.amount,
expiresAt: authorization.expires_at
});
console.log('\n✓ Order processing complete');
console.log('Authorization held - capture to complete transaction');
return { success: true, authorization };
}
Retry Failed Authorizations
// Retry logic for failed authorizations
async function authorizationWithRetry(merchantId, paymentInstrumentId, amount, maxRetries = 3) {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
console.log(`Authorization attempt ${attempt} of ${maxRetries}...`);
const response = await fetch(
'https://api.ahrvo.network/payments/na/authorizations',
{
method: 'POST',
headers: {
'Authorization': 'Basic ' + btoa('username:password'),
'Content-Type': 'application/json'
},
body: JSON.stringify({
amount: amount,
currency: 'USD',
merchant: merchantId,
source: paymentInstrumentId,
tags: {
attempt: attempt.toString()
}
})
}
);
const authorization = await response.json();
if (authorization.state === 'SUCCEEDED') {
console.log(`✓ Authorization succeeded on attempt ${attempt}`);
return authorization;
}
if (attempt < maxRetries) {
console.log(`✗ Attempt ${attempt} failed, retrying...`);
await new Promise(resolve => setTimeout(resolve, 1000 * attempt));
}
}
console.log('✗ All authorization attempts failed');
return null;
}
Security Considerations
-
PCI Compliance: Never log sensitive data
- Don't log full card numbers
- Don't log CVV codes
- Use trace_id for debugging
-
Authentication: Secure credentials
- Use HTTPS only
- Protect API credentials
- Rotate credentials regularly
-
Fraud Prevention: Multiple checks
- Verify AVS results
- Verify CVV results
- Use 3D Secure when possible
- Monitor for suspicious patterns
-
Amount Limits: Check before authorizing
- Respect merchant limits
- Check customer limits
- Validate reasonable amounts
Error Responses
Insufficient Funds
{
"state": "FAILED",
"failure_code": "INSUFFICIENT_FUNDS",
"failure_message": "Insufficient funds"
}
Invalid Card
{
"state": "FAILED",
"failure_code": "INVALID_CARD",
"failure_message": "Invalid card number"
}
Declined
{
"state": "FAILED",
"failure_code": "CARD_DECLINED",
"failure_message": "Do not honor"
}
Troubleshooting
Authorization Declined
- Check payment instrument is valid
- Verify sufficient funds
- Check merchant processing enabled
- Review failure_code and failure_message
AVS/CVV Mismatch
- Verify billing address correct
- Check CVV entered correctly
- May require customer to update info
- Consider manual review
Expired Authorization
- Check expires_at timestamp
- Must capture within 7 days
- Create new authorization if expired
- Cannot extend expiration
Related Endpoints
- PUT /authorizations/{id}: Capture or void authorization
- GET /authorizations: List all authorizations
- GET /authorizations/{id}: Fetch authorization details
- POST /transfers: Create direct transfer (auto-capture)