Payment API Documentation

Comprehensive, production-ready API for secure payment processing. Built with modern standards, PCI compliance, and developer experience in mind.

Production Ready RESTful API PCI DSS Compliant Real-time Processing
Quick Example
curl -X POST https://gateway.circoflows.com/api/v1/payment/create \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "first_name": "John",
    "last_name": "Doe",
    "email": "john@example.com",
    "phone": "+19876543210",
    "line1": "123 Main St",
    "city": "New York",
    "state": "NY",
    "postal_code": "10001",
    "country": "US",
    "ip_address": "192.168.1.100",
    "amount": "100.50",
    "currency": "USD",
    "card_number": "4242424242424242",
    "card_expiry_month": "12",
    "card_expiry_year": "2028",
    "card_cvv": "123",
    "merchant_transaction_id": "ORDER-12345",
    "return_url": "https://yoursite.com/return",
    "webhook_url": "https://yoursite.com/webhook"
  }'

Authentication

All API requests require authentication using your API key. Include your API key in the Authorization header of every request.

API Key Authentication
curl -H "Authorization: Bearer YOUR_API_KEY" \
  https://gateway.circoflows.com/api/v1/payment/create

Security Best Practices

Important

  • Never expose your API key in client-side code
  • Use HTTPS for all API requests
  • Rotate your API keys regularly
  • Monitor API usage for suspicious activity

Quick Start

Get up and running with our API in just a few steps. This guide will walk you through setting up your first payment integration.

Prerequisites

Before you begin, make sure you have:

  • A merchant account with CircoFlows
  • Basic knowledge of HTTP APIs and JSON
  • A development environment for testing
1

Get Your API Key

Sign up for a merchant account and generate your API key from the dashboard. This key will authenticate all your API requests.

Dashboard Steps:

  1. Log into your merchant dashboard
  2. Navigate to Settings → API Keys
  3. Click Generate New Key
  4. Copy and securely store your API key

Security Note

Never expose your API key in client-side code or public repositories. Use environment variables to store it securely.

2

Make Your First Request

Test your API key with a simple authentication request to ensure everything is working correctly.

Test API Connection
curl -X POST https://gateway.circoflows.com/api/v1/payment/status \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"merchant_transaction_id": "YOUR_TRANSACTION_ID"}'

Expected Response

You should receive a 200 OK response with API status information.

3

Process Your First Payment

Now let's process a real payment using our test environment. Use the test card numbers provided below.

Test Payment Request
curl -X POST https://gateway.circoflows.com/api/v1/test/payment/create \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "first_name": "John",
    "last_name": "Doe",
    "email": "john@example.com",
    "phone": "+19876543210",
    "line1": "123 Main St",
    "city": "New York",
    "state": "NY",
    "postal_code": "10001",
    "country": "US",
    "ip_address": "192.168.1.100",
    "amount": "10.00",
    "currency": "USD",
    "card_number": "4242424242424242",
    "card_expiry_month": "12",
    "card_expiry_year": "2028",
    "card_cvv": "123",
    "merchant_transaction_id": "TEST-12345",
    "return_url": "https://yoursite.com/return",
    "webhook_url": "https://yoursite.com/webhook"
  }'

Test Cards

Success: 4242424242424242
Declined: 4000000000000002
3DS Required: 4000000000003220

Test Environment

Base URL: https://gateway.circoflows.com/api/v1/test
Webhook: https://webhook.site/your-url
4

Handle Responses & Webhooks

Process the API response and set up webhooks to receive real-time payment notifications.

Response Handling

Check the response status and handle accordingly:

  • success: true - Payment completed
  • requires_action: true - 3DS needed
  • error - Handle errors gracefully

Webhook Setup

Configure webhooks for real-time updates:

  • Set webhook URL in your dashboard
  • Verify webhook signatures
  • Handle payment status updates
  • Test with webhook.site

Direct Payment API

Process payments directly through our API with full control over the payment flow. Perfect for custom checkout experiences and server-side payment processing.

Real-time Processing

Instant payment confirmation

Full Control

Customize every aspect of the flow

Secure

End-to-end encryption

3DS Support

Automatic 3D Secure handling

POST /api/v1/payment/create

Process a payment directly with card details. If 3D Secure authentication is required, the response will include a redirect URL.

Test Environment

For testing, use: /api/v1/test/payment/create

Request Parameters

Parameter Type Required Description
Customer Information
first_name string Yes Customer's first name
last_name string Yes Customer's last name
email string Yes Customer's email address
phone string Yes Phone number with country code (e.g., +19876543210)
ip_address string Yes Customer's IP address
Billing Address
line1 string Yes Address line 1
city string Yes City name
state string Yes State/Province code (2 letters, e.g., NY, TX)
postal_code string Yes Postal/ZIP code
country string Yes Country code (ISO 3166-1 alpha-2, e.g., US)
Transaction Details
amount string Yes Transaction amount (decimal format, e.g., "100.50")
currency string Yes Currency code (ISO 4217, e.g., USD, EUR)
merchant_transaction_id string Yes Your unique transaction reference
Card Information
card_number string Yes Card number (13-19 digits)
card_expiry_month string Yes Expiry month (2 digits, e.g., "01")
card_expiry_year string Yes Expiry year (4 digits, e.g., "2028")
card_cvv string Yes Card security code (3-4 digits)
Callback URLs
return_url string Yes URL to redirect after payment (for 3DS)
webhook_url string Yes URL to receive webhook notifications

Request Example

Create Payment Request
{
  "first_name": "John",
  "last_name": "Doe",
  "line1": "123 Main Street",
  "country": "US",
  "state": "NY",
  "city": "New York",
  "postal_code": "10001",
  "ip_address": "192.168.1.100",
  "email": "john.doe@example.com",
  "phone": "+19876543210",
  "amount": "100.50",
  "currency": "USD",
  "card_number": "4242424242424242",
  "card_expiry_month": "01",
  "card_expiry_year": "2028",
  "card_cvv": "123",
  "return_url": "https://yoursite.com/payment/return",
  "webhook_url": "https://yoursite.com/webhooks/payment",
  "merchant_transaction_id": "ORDER-12345"
}

Success Response

Payment Successful
{
  "status": "success",
  "reason": "Payment completed",
  "merchant_transaction_id": "MRF-3",
  "transaction_id": "txn_bY32XICH0yXnp0s7"
}

3DS Response

3DS Authentication Required
{
  "status": "processing",
  "3ds_url": "http://localhost:8002/test-gateway/authentication/eyJpdiI6Ikxmd0ZRTTBQR0pvcGFTSXdsdnRKdXc9PSIsInZhbHVlIjoiQnVVQ1I3S1BKQVlvNGU4YTRmdjhMMFpTRVF5eGwrTEVhMEhRZjE1MHliaz0iLCJtYWMiOiJiZTBiMmQwNTE2NzJjN2MyNTVmNzEwZTNjMTE0MWYzOTBmMTdmNjBhNjFkZTMyNzE0MWVjYTNjY2RhZWExM2EyIiwidGFnIjoiIn0=",
  "reason": "Payment authentication reqiured.",
  "merchant_transaction_id": "MRF-1",
  "transaction_id": "txn_SAx5Fyj4X1pyFIYO"
}

Declined Response

Payment Declined
{
  "status": "declined",
  "reason": "Payment failed.",
  "merchant_transaction_id": "MRF-2",
  "transaction_id": "txn_KhZl1qEc33JamngW"
}

Validation Failed Response

Validation Error
{
  "status": "declined",
  "reason": "The first name field is required.",
  "merchant_transaction_id": "MRF-141"
}

Response Fields

Field Type Description
status string Transaction status: success, declined, processing
reason string Human-readable message about the transaction
transaction_id string Internal transaction ID (unique system identifier)
merchant_transaction_id string Your unique transaction reference ID
3ds_url string 3DS authentication URL (only when status is "processing")
POST /api/v1/payment/status

Check the current status of a payment transaction using your merchant transaction ID.

Test Environment

For testing, use: /api/v1/test/payment/status

Request Parameters

Parameter Type Required Description
merchant_transaction_id string Yes Your unique transaction reference

Request Example

Check Payment Status Request
{
  "merchant_transaction_id": "ORDER-12345"
}

Success Response

Transaction Status - Success
{
  "success": true,
  "data": {
    "transaction_id": "txn_Cf7Gr7PgqIObMAcM",
    "merchant_transaction_id": "MRF-123",
    "status": "success",
    "amount": 10,
    "currency": "USD",
    "message": "Payment completed.",
    "customer_info": {
      "phone": "+19876549872",
      "line1": "Address",
      "postal_code": "12345",
      "city": "MINS",
      "state": "TX",
      "name": "Fname Lname",
      "email": "test@gmail.com",
      "country": "US"
    },
    "created_at": "2025-10-06 18:19:53",
    "processed_at": "2025-10-06 18:19:53",
    "payment_info": {
      "card_number": "4242",
      "card_expiry_month": 1,
      "card_expiry_year": 2028
    }
  }
}

Error Response

Transaction Not Found
{
  "success": false,
  "error": "Transaction not found."
}

Transaction Statuses

Status Description Action Required
success Payment completed successfully Complete the order
declined Payment failed, was declined, or validation error occurred Show error message to user from reason field
processing Payment requires 3D Secure authentication Redirect user to 3ds_url for authentication

Common Error Messages

Validation Errors:

  • "The first name field is required."
  • "The last name field is required."
  • "The email must be a valid email address."
  • "The card number field is required."
  • "The card CVV field is required."

Payment Declined Reasons:

  • "Payment failed." (Generic decline)
  • "Insufficient funds."
  • "Card expired."
  • "Invalid card number."
  • "CVV verification failed."

Best Practices

  • Check the status field in payment creation responses
  • Display the reason field to users for user-friendly error messages
  • Handle 3DS redirects when status is "processing"
  • Implement retry logic with the same merchant_transaction_id to prevent duplicates
  • Validate input on client-side before sending to API
  • Log all errors with transaction IDs for debugging

Hosted Payment API

Create secure, hosted payment pages that handle sensitive card data collection. Perfect for businesses that want to minimize PCI compliance requirements while maintaining full control over customer experience.

PCI Compliant

Minimal PCI scope - card data never touches your server

Secure Card Input

Hosted card input page with 3DS support

Mobile Optimized

Responsive design for all devices

Global Ready

Multi-currency support

How It Works

  1. Create Payment Request: Send customer and payment details to the Hosted API endpoint
  2. Receive Card URL: Get a secure card_url where the customer can enter their card details
  3. Redirect Customer: Redirect the customer to the card_url to complete payment
  4. Payment Processing: Customer enters card details, 3DS authentication is handled automatically if required
  5. Callback: Customer is redirected to your return_url after payment completion
  6. Webhook Notification: Receive payment status via webhook
POST /api/v1/hosted/create

Create a hosted payment session. Returns a secure card input URL where the customer can enter their card details.

Live Environment

Use this endpoint for production transactions with real cards.

Request Headers

Header Value Required
Authorization Bearer YOUR_API_KEY Yes
Content-Type application/json Yes

Request Parameters

Parameter Type Required Description
first_name string Yes Customer's first name
last_name string Yes Customer's last name
email string Yes Customer's email address
phone string Yes Customer's phone number (with country code)
line1 string Yes Billing address line 1
city string Yes Billing city
state string Yes Billing state/province code
postal_code string Yes Billing postal/ZIP code
country string Yes Two-letter country code (e.g., US, GB)
ip_address string Yes Customer's IP address
amount string Yes Payment amount (e.g., "10" for $10.00)
currency string Yes Three-letter currency code (e.g., USD, INR)
merchant_transaction_id string Yes Your unique transaction reference ID
return_url string Yes URL to redirect customer after payment
webhook_url string Yes URL to receive payment status notifications

Request Example

cURL Request
curl -X POST https://gateway.circoflows.com/api/v1/hosted/create \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "first_name": "Firstname",
    "last_name": "Lastname",
    "line1": "Address",
    "country": "US",
    "state": "TX",
    "city": "Dallas",
    "postal_code": "123456",
    "ip_address": "15.6.48.247",
    "email": "test@gmail.com",
    "phone": "+19876549872",
    "amount": "10",
    "currency": "USD",
    "return_url": "https://yoursite.com/return",
    "webhook_url": "https://yoursite.com/webhook",
    "merchant_transaction_id": "MRF-156"
  }'

Request Body (JSON)

JSON Payload
{
  "first_name": "Firstname",
  "last_name": "Lastname",
  "line1": "Address",
  "country": "US",
  "state": "TX",
  "city": "Dallas",
  "postal_code": "123456",
  "ip_address": "15.6.48.247",
  "email": "test@gmail.com",
  "phone": "+19876549872",
  "amount": "10",
  "currency": "USD",
  "return_url": "https://yoursite.com/return",
  "webhook_url": "https://yoursite.com/webhook",
  "merchant_transaction_id": "MRF-156"
}

Success Response

200 OK - Card URL Response
{
  "status": "card_url",
  "card_url": "https://gateway.circoflows.com/v1/hosted/card/input/ZEhodVh6Uk5UMXBHTTBKQmRVWjNTSFoyUW1ZPQ==",
  "reason": "Redirect to card_url.",
  "merchant_transaction_id": "MRF-156",
  "transaction_id": "txn_4MOZF3BAuFwHvvBf"
}

Response Fields

Field Type Description
status string Response status. Value: card_url
card_url string Secure URL where customer enters card details. Redirect customer to this URL.
reason string Human-readable description of the response
merchant_transaction_id string Your transaction reference ID (echoed back)
transaction_id string CircoFlows unique transaction identifier

Next Step

Redirect your customer to the card_url. After entering their card details and completing any required 3D Secure authentication, they will be redirected to your return_url.

POST /api/v1/test/hosted/create

Create a hosted payment session in test mode. Use this endpoint during development and testing.

Test Environment

Use this endpoint for testing with test card numbers. No real payments will be processed.

Request Example

cURL Request (Test Mode)
curl -X POST https://gateway.circoflows.com/api/v1/test/hosted/create \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "first_name": "Firstname",
    "last_name": "Lastname",
    "line1": "Address",
    "country": "US",
    "state": "TX",
    "city": "Dallas",
    "postal_code": "123456",
    "ip_address": "15.6.48.247",
    "email": "test@gmail.com",
    "phone": "+19876549872",
    "amount": "10",
    "currency": "USD",
    "return_url": "https://yoursite.com/return",
    "webhook_url": "https://webhook.site/your-webhook-url",
    "merchant_transaction_id": "MRF-150"
  }'

The request and response format is identical to the live endpoint. Only the base URL path differs (/api/v1/test/hosted/create).

Test Cards

Use these test card numbers when testing the hosted payment page:

Card Number Result Description
4242424242424242 Success Visa card that will always succeed
4000000000000002 Declined Card that will always be declined
4000000000003220 3DS Required Card that requires 3D Secure authentication

Test Card Details

Expiry Month: Any valid future month (e.g., 01)
Expiry Year: Any valid future year (e.g., 2028)
CVV: Any 3 digits (e.g., 123)

3D Secure Support

The hosted payment page automatically handles 3D Secure (3DS) authentication when required by the card issuer.

3D Secure Flow

  1. Customer is redirected to the card_url
  2. Customer enters their card details on the secure hosted page
  3. If 3DS is required, customer is redirected to their bank's authentication page
  4. After authentication, the payment is processed
  5. Customer is redirected to your return_url
  6. You receive a webhook notification with the payment result

Integration Example (PHP)

PHP Integration
public function createHostedPayment(Request $request)
{
    $apiKey = config('payment.api_key');
    $baseUrl = config('payment.base_url'); // https://gateway.circoflows.com

    $payload = [
        'first_name' => $request->first_name,
        'last_name' => $request->last_name,
        'email' => $request->email,
        'phone' => $request->phone,
        'line1' => $request->address,
        'city' => $request->city,
        'state' => $request->state,
        'postal_code' => $request->postal_code,
        'country' => $request->country,
        'ip_address' => $request->ip(),
        'amount' => $request->amount,
        'currency' => 'USD',
        'merchant_transaction_id' => 'ORDER-' . uniqid(),
        'return_url' => route('payment.return'),
        'webhook_url' => route('payment.webhook'),
    ];

    $response = Http::withHeaders([
        'Authorization' => 'Bearer ' . $apiKey,
        'Content-Type' => 'application/json',
    ])->post($baseUrl . '/api/v1/hosted/create', $payload);

    $data = $response->json();

    if ($data['status'] === 'card_url') {
        // Store transaction_id for later reference
        session(['transaction_id' => $data['transaction_id']]);

        // Redirect customer to the hosted card input page
        return redirect()->away($data['card_url']);
    }

    // Handle error
    return back()->with('error', $data['reason'] ?? 'Payment initialization failed');
}

Error Responses

Error Code HTTP Status Description
invalid_request 400 Missing or invalid request parameters
invalid_amount 400 Amount is invalid or below minimum
invalid_currency 400 Currency code is not supported
authentication_failed 401 Invalid or missing API key
duplicate_transaction 409 merchant_transaction_id already exists
invalid_webhook_url 400 Webhook URL is invalid or unreachable
invalid_return_url 400 Return URL is invalid

Webhooks

Webhooks notify your system about payment status changes in real-time. Configure your webhook URL in each payment request to receive instant notifications when the payment status changes.

Key Points

  • Webhooks are sent to the webhook_url specified in your payment request
  • Your endpoint must respond with a 200 OK status
  • Process webhooks asynchronously for best performance
  • Store the transaction_id to prevent duplicate processing

Webhook Request Headers

Headers
Content-Type: application/json
X-Signature: sha256_hmac_signature (optional)
X-Event-Type: payment.notify

Webhook Payload

Payment Notification Webhook
{
  "event": "payment.notify",
  "data": {
    "transaction_id": "txn_Cf7Gr7PgqIObMAcM",
    "merchant_transaction_id": "MRF-123",
    "status": "success",
    "amount": 10,
    "currency": "USD",
    "message": "Payment completed.",
    "customer_info": {
      "phone": "+19876549872",
      "line1": "Address",
      "postal_code": "12345",
      "city": "MINS",
      "state": "TX",
      "name": "Fname Lname",
      "email": "test@gmail.com",
      "country": "US"
    },
    "created_at": "2025-10-06 18:19:53",
    "processed_at": "2025-10-06 18:19:53",
    "payment_info": {
      "card_number": "4242",
      "card_expiry_month": 1,
      "card_expiry_year": 2028
    }
  }
}

Webhook Events

Event Type Description When Triggered
payment.notify Payment status notification When payment status changes (success, declined, processing)

Handling Webhooks (PHP Example)

Webhook Handler
public function handlePaymentWebhook(Request $request)
{
    // Verify signature (optional but recommended)
    $signature = $request->header('X-Signature');
    if ($signature && !$this->verifySignature($request->getContent(), $signature)) {
        Log::error('Invalid webhook signature');
        return response()->json(['error' => 'Invalid signature'], 401);
    }

    // Get webhook data
    $event = $request->input('event'); // "payment.notify"
    $data = $request->input('data');

    // Extract transaction details
    $transactionId = $data['transaction_id'];
    $merchantTxnId = $data['merchant_transaction_id'];
    $status = $data['status']; // "success", "declined", etc.
    $message = $data['message'];

    // Process based on status
    if ($status === 'success') {
        // Update order as paid
        Log::info("Payment successful: {$merchantTxnId}");
        // Your business logic here
    } elseif ($status === 'declined') {
        // Handle failed payment
        Log::warning("Payment declined: {$merchantTxnId} - {$message}");
        // Your business logic here
    }

    // Respond immediately
    return response()->json(['received' => true]);
}

private function verifySignature($payload, $signature)
{
    $secret = config('payment.webhook_secret');
    $computed = hash_hmac('sha256', $payload, $secret);
    return hash_equals($computed, $signature);
}

Webhook Security

While signature verification is optional, we recommend implementing it to ensure webhook authenticity.

Best Practices

  • Always verify the signature if provided
  • Store processed transaction IDs to prevent duplicate processing
  • Respond with 200 OK immediately, process asynchronously
  • Implement retry logic for failed webhook processing
  • Use HTTPS endpoints for webhook URLs
  • Log all webhook events for debugging

Testing

Use our test environment to develop and test your integration before going live.

Test Cards

Card Number Result Description
4242424242424242 Success Visa card that will always succeed
4000000000000002 Declined Card that will always be declined
4000000000003220 3DS Required Card that requires 3D Secure authentication

Test Environment

Use the test API endpoint: https://gateway.circoflows.com/api/v1/test

For test payment creation: https://gateway.circoflows.com/api/v1/test/payment/create
For test payment status: https://gateway.circoflows.com/api/v1/test/payment/status

Error Handling

Handle errors gracefully by checking the response status and error details.

Error Response Format

Error Response Example
{
  "error": {
    "code": "card_declined",
    "message": "Your card was declined.",
    "type": "card_error",
    "decline_code": "insufficient_funds"
  }
}

Common Error Codes

Error Code HTTP Status Description
invalid_request 400 The request was invalid
authentication_failed 401 Invalid API key
rate_limit_exceeded 429 Too many requests
server_error 500 Internal server error

Security

We take security seriously and implement industry best practices to protect your data.

PCI Compliance

Our platform is PCI DSS Level 1 compliant, the highest level of certification available in the payments industry.

Data Encryption

  • All data is encrypted in transit using TLS 1.3
  • Sensitive data is encrypted at rest using AES-256
  • API keys are hashed using bcrypt

Fraud Protection

Our advanced fraud detection system analyzes transactions in real-time to identify and prevent fraudulent activity.

Rate Limits

To ensure fair usage and system stability, we implement rate limits on our API endpoints.

Rate Limit Headers

All API responses include rate limit headers:

Rate Limit Headers
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1640995200

Default Limits

  • Authentication endpoints: 10 requests per minute
  • Payment endpoints: 100 requests per minute
  • Webhook endpoints: 1000 requests per minute

Changelog

Track the latest updates and improvements to our API.

Version 2.0.0 - 2025-01-15

  • Added support for 3D Secure 2.0
  • Improved webhook reliability
  • Enhanced error messages
  • New fraud detection features

Version 1.9.0 - 2024-12-01

  • Added support for Apple Pay and Google Pay
  • Improved rate limiting
  • Enhanced documentation