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 payment data. Perfect for businesses that want to minimize PCI compliance requirements.

PCI Compliant

Minimal PCI scope

Customizable

Branded payment pages

Mobile Optimized

Responsive design

Global Ready

Multi-currency support

POST /api/hosted-payment/create

Create a hosted payment session that customers can use to complete their payment.

Request Parameters

Parameter Type Required Description
amount integer Yes Amount in cents (e.g., 1000 for $10.00)
currency string Yes Three-letter currency code (e.g., USD, EUR)
description string Yes Payment description shown to customer
customer_info object No Pre-filled customer information
metadata object No Additional data to store
webhook_url string No URL to receive payment notifications
return_url string No URL to redirect after payment
expires_at string No ISO 8601 timestamp for expiration

Request Example

Create Hosted Payment Session
{
  "amount": 25000,
  "currency": "USD",
  "description": "Premium Subscription - Annual Plan",
  "customer_info": {
    "name": "Jane Smith",
    "email": "jane@example.com",
    "phone": "+1234567890"
  },
  "metadata": {
    "subscription_id": "sub_12345",
    "plan_type": "premium_annual"
  },
  "webhook_url": "https://your-site.com/webhooks/payment",
  "return_url": "https://your-site.com/payment/success",
  "expires_at": "2025-08-23T23:59:59Z"
}

Success Response

Payment Session Created
{
  "success": true,
  "message": "Payment session created successfully",
  "data": {
    "session_id": "sess_ABC123DEF456",
    "payment_url": "https://pay.example.com/sess_ABC123DEF456",
    "amount": 25000,
    "currency": "USD",
    "description": "Premium Subscription - Annual Plan",
    "status": "pending",
    "expires_at": "2025-08-23T23:59:59Z",
    "created_at": "2025-07-23T07:11:23Z"
  }
}
GET /api/hosted-payment/{session_id}/status

Check the current status of a hosted payment session.

Response Example

Session Status
{
  "success": true,
  "data": {
    "session_id": "sess_ABC123DEF456",
    "amount": 25000,
    "currency": "USD",
    "description": "Premium Subscription - Annual Plan",
    "status": "completed",
    "transaction_id": "txn_XYZ789",
    "customer_info": {
      "name": "Jane Smith",
      "email": "jane@example.com"
    },
    "created_at": "2025-07-23T07:11:23Z",
    "completed_at": "2025-07-23T07:15:45Z"
  }
}
DELETE /api/hosted-payment/{session_id}

Cancel an active payment session before it expires.

Response Example

Session Cancelled
{
  "success": true,
  "message": "Payment session cancelled successfully",
  "data": {
    "session_id": "sess_ABC123DEF456",
    "status": "cancelled",
    "cancelled_at": "2025-07-23T08:30:00Z"
  }
}

3D Secure Support

Our hosted payment pages automatically handle 3D Secure authentication when required by the card issuer.

3D Secure Flow

  1. Customer enters card details on the hosted page
  2. If 3DS is required, customer is redirected to their bank
  3. After authentication, customer returns to your return URL
  4. Payment is processed and webhook is sent

Error Responses

Error Code HTTP Status Description
invalid_amount 400 Amount is invalid or below minimum
invalid_currency 400 Currency code is not supported
session_not_found 404 Payment session does not exist
session_expired 410 Payment session has expired
session_already_completed 409 Payment session is already completed
invalid_webhook_url 400 Webhook URL is invalid
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