# cURL Examples

Complete cURL examples for the most common API operations.

---

## ERP / Server Integration (API Key Auth)

For ERP and server-to-server integrations, use the Public API with your API key. Merchant-scoped keys resolve tenant and merchant from the key; tenant-wide (`lv_erp_…`) keys must also send `X-Merchant-ID`.

> **Note:** Raw card numbers are rejected on Sandbox and Production (`400 PCI_SCOPE_VIOLATION`). Tokenize first — in the browser with the PCI SDK, or server-side with `/tokenize-card` — and charge the `pci_tok_…` token.

```bash
export API_KEY="YOUR_API_KEY"
export BASE_URL="https://uat.auxcore.net/api/v1/public"

# Test connection
curl -X POST "$BASE_URL/testConnection" \
  -H "x-api-key: $API_KEY"

# Tokenize a card (server-side key only — SDK public keys get 403)
curl -X POST "$BASE_URL/tokenize-card" \
  -H "x-api-key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "cardNumber": "4111111111111111",
    "expiryMonth": "12",
    "expiryYear": "2027",
    "cvv": "123",
    "cardHolderName": "John Doe"
  }'
# → { "success": true, "data": { "tokenId": "pci_tok_…", "pciToken": "pci_tok_…", "last4": "1111", "cardBrand": "visa", ... } }

# Process a sale with the token
curl -X POST "$BASE_URL/transaction" \
  -H "x-api-key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "Amount": 100.00,
    "pciToken": "pci_tok_a1b2c3d4e5f6",
    "BillingCustomerName": "John Doe",
    "BillingEmail": "john@example.com",
    "OrderId": "ORD-1001"
  }'
# 200 approved or pending (ACH) / 402 declined ("success": false, "status": "declined"):
# { "success": true, "status": "success", "status_code": 200, "message": "...",
#   "data": { "TransactionId": "3f6c2a1e-…", "Status": "1", "Amount": 100, "ResponseCode": "100", "AuthCode": "...", ... } }

# Void a transaction (id = TransactionId UUID or TXN-… reference)
curl -X POST "$BASE_URL/void" \
  -H "x-api-key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "transactionId": "3f6c2a1e-8b7d-4c1a-9f2e-1a2b3c4d5e6f" }'

# Refund a transaction (omit amount for a full refund)
curl -X POST "$BASE_URL/refund" \
  -H "x-api-key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "transactionId": "3f6c2a1e-8b7d-4c1a-9f2e-1a2b3c4d5e6f", "amount": 50.00 }'

# Get transaction
curl "$BASE_URL/transaction/3f6c2a1e-8b7d-4c1a-9f2e-1a2b3c4d5e6f" \
  -H "x-api-key: $API_KEY"

# List transactions
curl "$BASE_URL/transaction-list?page=1&limit=50&status=approved" \
  -H "x-api-key: $API_KEY"
```

---

## Dashboard / Admin Operations (JWT Bearer Auth)

For operations requiring user-level access, obtain a JWT first. Admin routes need `Authorization: Bearer <JWT>` plus `X-Tenant-ID`.

## Authentication

### Login

```bash
curl -X POST https://uat.auxcore.net/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -H "X-Tenant-ID: your-tenant-id" \
  -d '{
    "email": "user@example.com",
    "password": "your-password"
  }'
```

The response is `{ "success": true, "data": { "token", "refreshToken", "tokenType": "Bearer", "expiresIn", "user": {...} } }`. If the user has MFA enabled the first call returns `data.mfaRequired: true`; repeat the call with `otpCode`.

**Save token:**
```bash
export TOKEN=$(curl -s -X POST https://uat.auxcore.net/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -H "X-Tenant-ID: your-tenant-id" \
  -d '{"email": "user@example.com", "password": "your-password"}' \
  | jq -r '.data.token')
```

---

## Transactions

### Process Sale

`pciToken` is a `pci_tok_…` value from the PCI SDK or `/public/tokenize-card`. Send an `Idempotency-Key` (16–255 characters) to make retries safe.

```bash
curl -X POST https://uat.auxcore.net/api/v1/transactions/sale \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Tenant-ID: your-tenant-id" \
  -H "Idempotency-Key: order-1001-attempt-0001" \
  -H "Content-Type: application/json" \
  -d '{
    "merchantId": "8d1f6a2c-3b4e-4f5a-9c8d-7e6f5a4b3c2d",
    "amount": 100.00,
    "currency": "USD",
    "pciToken": "pci_tok_a1b2c3d4e5f6",
    "billingCustomerName": "John Doe",
    "billingEmail": "john@example.com",
    "billingAddress": "123 Main St",
    "billingCity": "New York",
    "billingState": "NY",
    "billingPostalCode": "10001",
    "billingCountry": "US"
  }'
```

Returns `201 { "success": true, "data": { "id", "transactionId", "status", "amount", ... } }`.

### Authorization

```bash
curl -X POST https://uat.auxcore.net/api/v1/transactions/auth \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Tenant-ID: your-tenant-id" \
  -H "Content-Type: application/json" \
  -d '{
    "merchantId": "8d1f6a2c-3b4e-4f5a-9c8d-7e6f5a4b3c2d",
    "amount": 100.00,
    "currency": "USD",
    "pciToken": "pci_tok_a1b2c3d4e5f6"
  }'
```

### Capture

Captures the full authorized amount; the endpoint takes no body.

```bash
curl -X POST https://uat.auxcore.net/api/v1/transactions/3f6c2a1e-8b7d-4c1a-9f2e-1a2b3c4d5e6f/capture \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Tenant-ID: your-tenant-id"
```

### Void

Only `approved` (unsettled) transactions can be voided; settled ones must be refunded.

```bash
curl -X POST https://uat.auxcore.net/api/v1/transactions/3f6c2a1e-8b7d-4c1a-9f2e-1a2b3c4d5e6f/void \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Tenant-ID: your-tenant-id"
```

### Refund

Omit `amount` for a full refund; use `/refund/partial` with `amount` for a partial one.

```bash
curl -X POST https://uat.auxcore.net/api/v1/transactions/3f6c2a1e-8b7d-4c1a-9f2e-1a2b3c4d5e6f/refund/partial \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Tenant-ID: your-tenant-id" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 50.00
  }'
```

### Get Transaction

```bash
curl https://uat.auxcore.net/api/v1/transactions/3f6c2a1e-8b7d-4c1a-9f2e-1a2b3c4d5e6f \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Tenant-ID: your-tenant-id"
```

### List Transactions

```bash
curl "https://uat.auxcore.net/api/v1/transactions?page=1&limit=50&status=approved&dateFrom=2026-01-01&dateTo=2026-01-31" \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Tenant-ID: your-tenant-id"
```

---

## Subscriptions

### Create Subscription

```bash
curl -X POST https://uat.auxcore.net/api/v1/recurring \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Tenant-ID: your-tenant-id" \
  -H "Content-Type: application/json" \
  -d '{
    "merchantId": "8d1f6a2c-3b4e-4f5a-9c8d-7e6f5a4b3c2d",
    "customerId": "c7e2b9a4-1d3f-4e6a-8b5c-9f0a1b2c3d4e",
    "recurringUserName": "John Doe",
    "customerEmail": "john@example.com",
    "recurringAmount": 99.00,
    "period": "Monthly",
    "recurringDate1": "2026-11-01",
    "maximumOccurrence": "NoExpire",
    "suggestedMode": "CARD",
    "children": [
      { "pciToken": "pci_tok_a1b2c3d4e5f6", "isDefault": true }
    ]
  }'
```

`period` is one of `Weekly`, `BiWeekly`, `Monthly`, `SemiMonthly`, `Quarterly`, `Annually`, `Custom`. `recurringDate1` (first charge) must be in the future.

### Pause Subscription

```bash
curl -X POST https://uat.auxcore.net/api/v1/recurring/5b9e1c7a-2d4f-4a6b-8c1d-3e5f7a9b1c2d/pause \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Tenant-ID: your-tenant-id"
```

### Resume Subscription

```bash
curl -X POST https://uat.auxcore.net/api/v1/recurring/5b9e1c7a-2d4f-4a6b-8c1d-3e5f7a9b1c2d/resume \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Tenant-ID: your-tenant-id"
```

### Cancel Subscription

```bash
curl -X POST https://uat.auxcore.net/api/v1/recurring/5b9e1c7a-2d4f-4a6b-8c1d-3e5f7a9b1c2d/cancel \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Tenant-ID: your-tenant-id" \
  -H "Content-Type: application/json" \
  -d '{
    "reason": "Customer request"
  }'
```

---

## Invoices

### Create Invoice

```bash
curl -X POST https://uat.auxcore.net/api/v1/invoices \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Tenant-ID: your-tenant-id" \
  -H "Content-Type: application/json" \
  -d '{
    "merchantId": "8d1f6a2c-3b4e-4f5a-9c8d-7e6f5a4b3c2d",
    "customerName": "Jane Customer",
    "customerEmail": "customer@example.com",
    "dueDate": "2026-11-15",
    "lineItems": [
      {
        "name": "Web Design",
        "description": "Web Design Services",
        "quantity": 1,
        "unitPrice": 500.00
      }
    ]
  }'
```

Send either `lineItems` or a top-level `amount`.

### Send Invoice

`method` is `email` or `sms`; both `method` and `to` are required. Email goes to the invoice's `customerEmail`.

```bash
curl -X POST https://uat.auxcore.net/api/v1/invoices/9a8b7c6d-5e4f-4a3b-2c1d-0e9f8a7b6c5d/send \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Tenant-ID: your-tenant-id" \
  -H "Content-Type: application/json" \
  -d '{
    "method": "email",
    "to": "customer@example.com"
  }'
```

### Download PDF

```bash
curl https://uat.auxcore.net/api/v1/invoices/9a8b7c6d-5e4f-4a3b-2c1d-0e9f8a7b6c5d/pdf \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Tenant-ID: your-tenant-id" \
  -o invoice.pdf
```

---

## Webhooks

### Create Webhook

`merchantId` is required when the caller is a tenant admin; merchant users are bound to their own merchant. The response carries the signing `secret` — store it, it is never returned again.

```bash
curl -X POST https://uat.auxcore.net/api/v1/webhooks/endpoints \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Tenant-ID: your-tenant-id" \
  -H "Content-Type: application/json" \
  -d '{
    "merchantId": "8d1f6a2c-3b4e-4f5a-9c8d-7e6f5a4b3c2d",
    "url": "https://your-server.com/webhook",
    "events": [
      "transaction.approved",
      "transaction.declined",
      "transaction.refunded"
    ]
  }'
```

Valid events: `transaction.approved`, `transaction.pending`, `transaction.declined`, `transaction.voided`, `transaction.refunded`, `transaction.refund_failed`, `transaction.returned`, `session.cancelled`, `session.expired`.

### Test Webhook

Sends a `webhook.test` event to the endpoint; no body.

```bash
curl -X POST https://uat.auxcore.net/api/v1/webhooks/endpoints/4e3d2c1b-0a9f-4e8d-7c6b-5a4f3e2d1c0b/test \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Tenant-ID: your-tenant-id"
```

---

## Batch Operations

### Create Multiple Transactions

```bash
# Using a loop — one Idempotency-Key per sale
for i in {1..5}; do
  curl -X POST https://uat.auxcore.net/api/v1/transactions/sale \
    -H "Authorization: Bearer $TOKEN" \
    -H "X-Tenant-ID: your-tenant-id" \
    -H "Idempotency-Key: batch-20261001-sale-000$i" \
    -H "Content-Type: application/json" \
    -d "{\"merchantId\": \"8d1f6a2c-3b4e-4f5a-9c8d-7e6f5a4b3c2d\", \"amount\": $((i * 10)).00, \"pciToken\": \"pci_tok_a1b2c3d4e5f6\"}"
done
```

### Export Transactions

`merchantId`, `dateFrom` and `dateTo` are required.

```bash
curl "https://uat.auxcore.net/api/v1/reports/export/csv?merchantId=8d1f6a2c-3b4e-4f5a-9c8d-7e6f5a4b3c2d&dateFrom=2026-01-01&dateTo=2026-01-31" \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Tenant-ID: your-tenant-id" \
  -o transactions.csv
```

---

## Advanced Examples

### Pagination Loop

```bash
page=1
while true; do
  response=$(curl -s "https://uat.auxcore.net/api/v1/transactions?page=$page&limit=50" \
    -H "Authorization: Bearer $TOKEN" \
    -H "X-Tenant-ID: your-tenant-id")

  echo "$response" | jq '.data[]'

  has_more=$(echo "$response" | jq '.meta.page < .meta.totalPages')
  if [ "$has_more" = "false" ]; then
    break
  fi

  page=$((page + 1))
done
```

### Error Handling

```bash
response=$(curl -s -w "\n%{http_code}" \
  -X POST https://uat.auxcore.net/api/v1/public/transaction \
  -H "x-api-key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"Amount": 10.00, "pciToken": "pci_tok_a1b2c3d4e5f6"}')

http_code=$(echo "$response" | tail -n1)
body=$(echo "$response" | sed '$d')

if [ "$http_code" -eq 200 ]; then
  echo "Success: $body"
elif [ "$http_code" -eq 402 ]; then
  echo "Declined: $(echo "$body" | jq -r '.message')"
else
  echo "Error $http_code: $body"
fi
```

### Retry with Backoff

Retry only on `429` and `5xx`. Public sales are not deduplicated by `Idempotency-Key`, so check the transaction list (e.g. by `orderId`) before retrying a sale that may have gone through.

```bash
function retry_request() {
  local max_attempts=3
  local attempt=1

  while [ $attempt -le $max_attempts ]; do
    response=$(curl -s -w "\n%{http_code}" \
      "https://uat.auxcore.net/api/v1/public/transaction-list?orderId=ORD-1001" \
      -H "x-api-key: $API_KEY")

    http_code=$(echo "$response" | tail -n1)

    if [ "$http_code" -eq 200 ]; then
      echo "$response" | sed '$d'
      return 0
    fi

    if [ "$http_code" -eq 429 ] || [ "$http_code" -ge 500 ]; then
      wait_time=$((2 ** attempt))
      echo "Retrying in $wait_time seconds..."
      sleep $wait_time
      attempt=$((attempt + 1))
    else
      echo "Error: $response"
      return 1
    fi
  done
}

retry_request
```

---

## Next Steps

- [Node.js examples →](./nodejs.md)
- [PHP examples →](./php.md)
- [Python examples →](./python.md)

---

**Need help?** Contact support@auxcore.net
