API Documentation

Complete guide to integrating PayzPool into your application

Getting Started

Welcome to the PayzPool API! Our API allows you to process payments across multiple Stripe accounts with intelligent load balancing.

Base URL:

https://payzpool.com/api

Authentication

All API requests require authentication using API Key and API Secret in headers.

Headers:

X-API-Key: your_api_key
X-API-Secret: your_api_secret
Content-Type: application/json

Load Balancing Strategies

PayzPool intelligently distributes payments across your Stripe accounts using 6 different load balancing strategies:

Weighted Round Robin

Recommended

Distributes payments based on usage percentage (e.g., 60%, 30%, 10%). Only successful transactions count. If no weights are set, falls back to simple round robin.

Round Robin

Distributes requests evenly across all accounts in a sequential cycle. Simple and fair distribution.

Weighted

Prioritizes accounts based on priority level and success rate. Prefers reliable accounts with higher priority.

Least Used

Routes to the account with lowest usage. Ideal for preventing hitting daily/monthly limits.

Failover

Uses primary account first, falls back to secondary for high availability setup.

Random

Randomly selects an available account from your pool.

💡 Configure Strategy: You can select and configure your load balancing strategy in the Dashboard → Stripe Accounts section.

Manual Account Selection

You can bypass all load balancing strategies by specifying a payment_account_id in your payment request:

Example:

{
  "amount": 99.99,
  "currency": "usd",
  "customer_email": "[email protected]",
  "return_url": "https://yoursite.com/success",
  "payment_account_id": 6
}

Requirements for manual selection:

  • • Account must belong to your user account
  • • Account must be active
  • • Account must be able to process the requested amount (not exceeding daily/monthly limits)

Error responses:

  • 403 Forbidden - Account does not belong to you
  • 400 Bad Request - Account is not active or cannot process amount

Create Payment Intent

POST /api/payment-intents

Creates a new payment intent using intelligent routing across your Stripe accounts. Returns a client_secret to complete payment on the embedded checkout page.

Request Body:

{
  "amount": 99.99,
  "currency": "usd",
  "customer_email": "[email protected]",
  "customer_name": "John Doe",
  "description": "Order #12345",
  "return_url": "https://yoursite.com/payment/success",
  "webhook_url": "https://yoursite.com/webhooks/payment",
  "metadata": {
    "order_id": "12345",
    "product": "Premium Plan"
  }
}

Required fields:

  • amount - Amount in currency units (e.g., 99.99 for $99.99)
  • currency - Three-letter ISO currency code (e.g., "usd")
  • customer_email - Customer email address
  • return_url - URL to redirect after successful payment

Optional fields:

  • customer_name - Customer full name
  • description - Payment description (max 500 characters)
  • webhook_url - Transaction-specific webhook URL for payment notifications (max 500 characters)
  • metadata - Custom key-value pairs for your reference
  • payment_account_id - Specific payment account ID to use (bypasses all load balancing strategies)

Response (201 Created):

{
  "success": true,
  "data": {
    "transaction_id": "txn_abc123xyz",
    "checkout_url": "https://payzpool.com/checkout/txn_abc123xyz",
    "payment_intent": {
      "id": "pi_3Abc123xyz",
      "client_secret": "pi_3Abc123xyz_secret_abc",
      "status": "requires_payment_method",
      "amount": 99.99,
      "currency": "usd"
    },
    "stripe_account": {
      "publishable_key": "pk_live_xxxxx"
    }
  }
}

💡 Next Step: Redirect your customer to the checkout_url provided in the response to complete the payment using our embedded Stripe checkout page.

Note: If you've configured a custom domain for your Stripe account, the checkout_url will automatically use your branded domain (e.g., https://pay.yourdomain.com/checkout/{transaction_id})

⚠️ Return URL: After payment completion, Stripe will redirect the customer to your return_url with query parameters: ?payment_intent=pi_xxx&redirect_status=succeeded. Make sure your return URL can handle these parameters.

List Payment Intents

GET /api/payment-intents

Retrieves a list of your payment intents with optional filters.

Query Parameters (all optional):

status=succeeded           (pending|processing|succeeded|failed|refunded|cancelled)
[email protected]
from_date=2025-01-01
to_date=2025-12-31
limit=50                   (max: 100)
offset=0

Response (200 OK):

{
  "success": true,
  "data": [
    {
      "transaction_id": "txn_abc123xyz",
      "payment_intent_id": "pi_3Abc123xyz",
      "amount": 99.99,
      "currency": "usd",
      "status": "succeeded",
      "customer_email": "[email protected]",
      "customer_name": "John Doe",
      "description": "Order #12345",
      "created_at": "2025-11-11T14:30:00+00:00"
    }
  ],
  "count": 1
}

Get Payment Intent

GET /api/payment-intents/{transaction_id}

Retrieves details of a specific payment intent.

Response (200 OK):

{
  "success": true,
  "data": {
    "transaction_id": "txn_abc123xyz",
    "payment_intent_id": "pi_3Abc123xyz",
    "amount": 99.99,
    "currency": "usd",
    "status": "succeeded",
    "customer_email": "[email protected]",
    "customer_name": "John Doe",
    "description": "Order #12345",
    "metadata": {
      "order_id": "12345"
    },
    "created_at": "2025-11-11T14:30:00+00:00",
    "updated_at": "2025-11-11T14:31:00+00:00"
  }
}

Cancel Payment Intent

POST /api/payment-intents/{transaction_id}/cancel

Cancels a pending or processing payment intent. Only applicable to payments that haven't been completed yet.

Response (200 OK):

{
  "success": true,
  "message": "Payment intent cancelled successfully",
  "data": {
    "transaction_id": "txn_abc123xyz",
    "status": "cancelled"
  }
}

⚠️ Note: Only payments with status "pending" or "processing" can be cancelled.

Refund Payment

POST /api/payment-intents/{transaction_id}/refund

Refunds a successful payment partially or fully.

Request Body (optional):

{
  "amount": 50.00,  // Optional: leave empty for full refund
  "reason": "requested_by_customer"  // duplicate|fraudulent|requested_by_customer
}

Response (200 OK):

{
  "success": true,
  "message": "Refund created successfully",
  "data": {
    "transaction_id": "txn_abc123xyz",
    "refund_id": "re_3Abc123xyz",
    "amount": 50.00,
    "status": "refunded"
  }
}

⚠️ Note: Only successful payments can be refunded.

Webhooks

PayzPool automatically registers webhooks with your Stripe accounts and forwards events to your configured webhook URL.

💡 Automatic Setup: When you add a Stripe account through the dashboard, PayzPool automatically registers the necessary webhooks with Stripe.

Transaction-Specific Webhooks

PayzPool supports transaction-specific webhook URLs. When creating a payment intent, you can provide a unique webhook_url parameter for that specific transaction. PayzPool will send all payment events for that transaction to the provided URL.

💡 Per-Transaction Webhooks: This allows you to have different webhook endpoints for different payments, making it easier to route notifications to the right systems or customers.

Webhook Events

PayzPool forwards the following events:

  • payment_intent.succeeded - Payment completed successfully
  • payment_intent.payment_failed - Payment failed
  • payment_intent.canceled - Payment was cancelled
  • charge.refunded - Payment was refunded

Webhook Payload

Example webhook payload:

{
  "event": "payment_intent.succeeded",
  "data": {
    "transaction_id": "txn_abc123xyz",
    "payment_intent_id": "pi_3Abc123xyz",
    "amount": 99.99,
    "currency": "usd",
    "status": "succeeded",
    "customer_email": "[email protected]"
  },
  "timestamp": "2025-11-11T14:30:00+00:00"
}

Webhook Signature Verification

All webhooks are signed with HMAC-SHA256 using your webhook secret. Verify the signature to ensure the webhook is from PayzPool and hasn't been tampered with.

Signature is sent in the header:

X-PayzPool-Signature: signature_hash

Verify signature (PHP example):

$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_PAYZPOOL_SIGNATURE'];
$webhookSecret = 'your_webhook_secret'; // Get from API Credentials page

$expectedSignature = hash_hmac('sha256', $payload, $webhookSecret);

if (!hash_equals($expectedSignature, $signature)) {
    http_response_code(401);
    exit('Invalid signature');
}

// Signature is valid, process the webhook
$data = json_decode($payload, true);

⚠️ Security: Always verify webhook signatures before processing events. This prevents unauthorized parties from sending fake webhook events to your endpoint.

View Webhook Logs

Monitor all incoming and outgoing webhooks in the Webhook Logs section of your dashboard. You can view request/response payloads, status codes, and timestamps.

Error Handling

PayzPool uses conventional HTTP response codes to indicate success or failure.

200

Success - Request completed successfully

400

Bad Request - Invalid parameters

401

Unauthorized - Invalid or missing API credentials

404

Not Found - Transaction not found

500

Server Error - Something went wrong on our end

Ready to Start?

Get your API credentials and start processing payments

Get Started Free