Skip to main content

A comprehensive Python SDK for PayAgency payment processing platform

Project description

PayAgency API Python SDK

A comprehensive Python SDK for PayAgency payment processing platform, supporting multiple payment methods including card payments, cryptocurrency transactions, payouts, and payment links.

Table of Contents

Installation

pip install payagency-api

Quick Start

from payagency_api import PayAgencyApi

# Initialize the SDK with minimal configuration
pay_agency = PayAgencyApi(
    encryption_key="89ca59fb3b49ada55851021df12cfbc5",  # 32-character encryption key
    secret_key="PA_TEST_your-secret-key",  # or PA_LIVE_ for production
    # base_url is optional - defaults to https://backend.pay.agency
)

# Or with custom base URL
pay_agency = PayAgencyApi(
    encryption_key="89ca59fb3b49ada55851021df12cfbc5",
    secret_key="PA_TEST_your-secret-key",
    base_url="https://CUSTOM_SUB_DOMAIN.pay.agency"
)

# Make a payment
payment = pay_agency.payment.s2s({
    "first_name": "James",
    "last_name": "Dean",
    "email": "james@gmail.com",
    "address": "64 Hertingfordbury Rd",
    "country": "GB",
    "city": "Newport",
    "state": "GB",
    "zip": "TF10 8DF",
    "ip_address": "127.0.0.1",
    "phone_number": "7654233212",
    "amount": 100,
    "currency": "GBP",
    "card_number": "4111111111111111",
    "card_expiry_month": "12",
    "card_expiry_year": "2027",
    "card_cvv": "029",
    "redirect_url": "https://pay.agency",
    "webhook_url": "https://pay.agency/webhook",
    "terminal_id": "T12345",  # optional
})

Configuration

PayAgencyClientOptions

Parameter Type Required Description
encryption_key str Yes 32-character encryption key for payload encryption
secret_key str Yes Your API secret key (PA_TEST for test, PA_LIVE for live)
base_url str No PayAgency API base URL (defaults to https://backend.pay.agency)

Environment Detection

The SDK automatically detects the environment based on your secret key:

  • Keys starting with PA_LIVE_ use live endpoints
  • Keys starting with PA_TEST_ use test endpoints

API Reference

Payment

The Payment module supports multiple payment methods:

Server-to-Server (S2S) Card Payments

result = pay_agency.payment.s2s({
    "first_name": "James",
    "last_name": "Dean",
    "email": "james@gmail.com",
    "address": "64 Hertingfordbury Rd",
    "country": "GB",
    "city": "Newport",
    "state": "GB",
    "zip": "TF10 8DF",
    "ip_address": "127.0.0.1",
    "phone_number": "7654233212",
    "amount": 100,
    "currency": "GBP",
    "card_number": "4111111111111111",
    "card_expiry_month": "12",
    "card_expiry_year": "2027",
    "card_cvv": "029",
    "redirect_url": "https://pay.agency",
    "webhook_url": "https://pay.agency/webhook",  # optional
    "order_id": "ORDER_123",  # optional
    "terminal_id": "T12345",  # optional
})

# Response format (Python dict):
{
    "status": "SUCCESS" | "REDIRECT" | "FAILED",
    "message": str,
    "data": {
        "amount": int,
        "currency": str,
        "order_id": str | None,
        "transaction_id": str,
        "customer": {
            "first_name": str,
            "last_name": str,
            "email": str,
        },
        "refund": {
            "status": bool,
            "refund_date": str | None,
        },
        "chargeback": {
            "status": bool,
            "chargeback_date": str | None,
        },
    },
    "redirect_url": str  # Present for REDIRECT status
}

Hosted Payment

hosted_payment = pay_agency.payment.hosted({
    "first_name": "James",
    "last_name": "Dean",
    "email": "james@gmail.com",
    "address": "64 Hertingfordbury Rd",
    "country": "GB",
    "city": "Newport",
    "state": "GB",
    "zip": "TF10 8DF",
    "ip_address": "127.0.0.1",
    "phone_number": "7654233212",
    "amount": 100,
    "currency": "GBP",
    "redirect_url": "https://pay.agency",
    "webhook_url": "https://pay.agency/webhook",  # optional
    "order_id": "ORDER_123",  # optional
    "terminal_id": "T12345",  # optional
})

# Returns the same response format as S2S

Alternative Payment Methods (APM)

apm_payment = pay_agency.payment.apm({
    "first_name": "James",
    "last_name": "Dean",
    "email": "james@gmail.com",
    "address": "64 Hertingfordbury Rd",
    "country": "GB",
    "city": "Newport",
    "state": "GB",
    "zip": "TF10 8DF",
    "ip_address": "127.0.0.1",
    "phone_number": "7654233212",
    "amount": 100,
    "currency": "GBP",
    "redirect_url": "https://pay.agency",
    "webhook_url": "https://pay.agency/webhook",  # optional
    "order_id": "ORDER_123",  # optional
    "terminal_id": "T12345",  # optional
})

# Returns the same response format as S2S

Payout

Manage payouts and wallet operations:

Create Payout

payout = pay_agency.payout.create_payout({
    "wallet_id": "WAL1234567890",
    "first_name": "James",
    "last_name": "Dean",
    "email": "james@gmail.com",
    "address": "64 Hertingfordbury Rd",
    "country": "US",
    "city": "Newport",
    "state": "US",
    "zip": "TF10 8DF",
    "ip_address": "127.0.0.1",
    "phone_number": "7654233212",
    "amount": 100,
    "currency": "USD",
    "card_number": "4222222222222222",
    "card_expiry_month": "10",
    "card_expiry_year": "2030",
    "webhook_url": "https://pay.agency/webhook",  # optional
    "order_id": "ORDER_123",  # optional
})

# Response format:
{
    "status": "SUCCESS" | "BLOCKED" | "PENDING",
    "message": str,
    "data": {
        "amount": int,
        "currency": str,
        "order_id": str | None,
        "transaction_id": str,
        "customer": {
            "first_name": str,
            "last_name": str,
            "email": str,
        },
    },
    "redirect_url": str  # optional
}

Get Wallets

# Get all wallets
wallets = pay_agency.payout.get_wallets()

# Response format:
{
    "data": [
        {
            "wallet_id": str,
            "currency": str,
            "amount": int,
            "payment_method": str,
            "status": "Active" | "Inactive",
        }
    ]
}

Estimate Payout Fee

fee_estimate = pay_agency.payout.estimate_fee({
    "wallet_id": "WAL7825818519632620",
    "amount": 200,
    "card_number": "4111111111111111",
})

# Response format:
{
    "data": {
        "amount_required": int,
        "wallet_balance": int,
        "total_fee": int,
    }
}

Check Payout Status

status = pay_agency.payout.get_payout_status("PAYOUT_REFERENCE_123")

# Response format:
{
    "status": "SUCCESS" | "PENDING" | "FAILED",
    "message": str,
    "data": {
        "amount": int,
        "currency": str,
        "order_id": str | None,
        "transaction_id": str,
        "customer": {
            "first_name": str,
            "last_name": str,
            "email": str,
        },
    }
}

Payment Links

Create and manage payment links:

Create Payment Link

payment_link = pay_agency.payment_link.create({
    "payment_template_id": "PLI07435325281394735",  # Required
    "amount": 1000,  # optional
    "currency": "USD",  # optional
    "expiry_date": "2024-12-31",  # optional
    "terminal_id": "T12345",  # optional
    "order_id": "ORDER_123",  # optional
})

# Response format:
{
    "message": str,
    "data": str  # The payment link URL
}

Get Payment Templates

templates = pay_agency.payment_link.get_templates()

# Response format:
{
    "data": [
        {
            "template_id": str,
            "template_name": str,
            "payment_template_id": str,
            "template_screenshot": str,
            "redirect_url": str,
            "webhook_url": str,
        }
    ]
}

Cryptocurrency

Handle cryptocurrency transactions:

Comprehensive Methods

The Crypto module provides both individual convenience methods and comprehensive methods for full control:

Full-Featured Payment Method
# Full crypto payment method - handles both OnRamp and OffRamp based on transaction_type
crypto_payment = pay_agency.crypto.payment({
    "transaction_type": "ONRAMP",  # or "OFFRAMP"
    "first_name": "Diana",
    "last_name": "Prince",
    "email": "diana@pay.agency",
    "phone_number": "0123456789",
    "fiat_amount": 200,  # Required for ONRAMP, omit for OFFRAMP
    # "crypto_amount": "0.05",  # Required for OFFRAMP, omit for ONRAMP
    "fiat_currency": "EUR",
    "crypto_currency": "BTC",
    "wallet_address": "1BoatSLRHtKNngkdXEeobR76b53LETtpyT",
    "ip_address": "127.0.0.1",
    "country": "GB",
    "crypto_network": "BITCOIN",
    "redirect_url": "https://pay.agency",
    "webhook_url": "https://pay.agency/webhook",  # optional
    "order_id": "ORDER_123",  # optional
    "terminal_id": "T12345",  # optional
})
OnRamp (Fiat to Crypto)
# Create OnRamp payment link
on_ramp_link = pay_agency.crypto.on_ramp_link({
    "fiat_amount": 100,
    "fiat_currency": "GBP",
    "crypto_currency": "BTC",
    "payment_template_id": "PLI07435325281394735",
    "order_id": "ORDER_123",  # optional
    "terminal_id": "T12345",  # optional
    "expiry_date": "2024-12-31",  # optional
})

# Direct OnRamp transaction
on_ramp = pay_agency.crypto.on_ramp({
    "first_name": "Diana",
    "last_name": "Prince",
    "email": "diana@pay.agency",
    "phone_number": "0123456789",
    "fiat_amount": 200,
    "fiat_currency": "EUR",
    "crypto_currency": "BTC",
    "wallet_address": "1BoatSLRHtKNngkdXEeobR76b53LETtpyT",
    "ip_address": "127.0.0.1",
    "country": "GB",
    "crypto_network": "BITCOIN",
    "redirect_url": "https://pay.agency",
    "webhook_url": "https://pay.agency/webhook",  # optional
    "order_id": "ORDER_123",  # optional
    "terminal_id": "T12345",  # optional
})

# Response format:
{
    "status": "REDIRECT" | "PENDING" | "FAILED",
    "message": str,
    "redirect_url": str,  # optional
    "data": {
        "transaction_id": str,
        "fiat": str,
        "fiat_amount": int,
        "crypto": str,
        "crypto_amount": int,
        "customer": {
            "first_name": str,
            "last_name": str,
            "email": str,
        },
    }
}
OffRamp (Crypto to Fiat)
# Create OffRamp payment link
off_ramp_link = pay_agency.crypto.off_ramp_link({
    "fiat_currency": "GBP",
    "crypto_currency": "BTC",
    "crypto_amount": "0.01",
    "payment_template_id": "PLI07435325281394735",
    "order_id": "ORDER_123",  # optional
    "terminal_id": "T12345",  # optional
    "expiry_date": "2024-12-31",  # optional
})

# Direct OffRamp transaction
off_ramp = pay_agency.crypto.off_ramp({
    "first_name": "Ethan",
    "last_name": "Hunt",
    "email": "ethan@pay.agency",
    "phone_number": "0123456789",
    "fiat_currency": "GBP",
    "crypto_currency": "BTC",
    "crypto_amount": "0.05",
    "wallet_address": "1BoatSLRHtKNngkdXEeobR76b53LETtpyT",
    "ip_address": "127.0.0.1",
    "country": "GB",
    "crypto_network": "BITCOIN",
    "redirect_url": "https://pay.agency",
    "webhook_url": "https://pay.agency/webhook",  # optional
    "order_id": "ORDER_123",  # optional
    "terminal_id": "T12345",  # optional
})

# Returns the same response format as OnRamp

Crypto PayIn

# Get supported currencies
currencies = pay_agency.crypto.get_currencies({
    "country": "GB",  # ISO 3166-1 alpha-2 country code
    "amount": 100,
})

# Response format:
{
    "message": str,
    "data": [
        {
            "name": str,
            "code": str,
            "symbol": str,
        }
    ]
}

# Create PayIn link
payin_link = pay_agency.crypto.payin_link({
    "fiat_amount": 150,
    "fiat_currency": "USD",
    "crypto_currency": "BTC",
    "payment_template_id": "PLI07435325281394735",
    "order_id": "ORDER_123",  # optional
    "terminal_id": "T12345",  # optional
    "expiry_date": "2024-12-31",  # optional
})

# Direct crypto payin
payin = pay_agency.crypto.payin({
    "first_name": "Fiona",
    "last_name": "Gallagher",
    "email": "hello@gmail.com",
    "address": "64 Hertingfordbury Rd",
    "phone_number": "0123456789",
    "ip_address": "127.0.0.1",
    "crypto_currency": "BTC",
    "amount": 300,
    "currency": "USD",
    "crypto_network": "BITCOIN",
    "country": "US",
    "redirect_url": "https://pay.agency",
    "webhook_url": "https://pay.agency/webhook",  # optional
    "order_id": "ORDER_123",  # optional
    "terminal_id": "T12345",  # optional
})

# Response format:
{
    "status": "SUCCESS" | "PENDING" | "FAILED",
    "message": str,
    "redirect_url": str,  # optional
    "data": {
        "amount": int,
        "currency": str,
        "order_id": str | None,
        "transaction_id": str,
        "customer": {
            "first_name": str,
            "last_name": str,
            "email": str,
        },
        "crypto_currency": str,
    }
}

Transactions

Query transaction history:

Get Transactions

transactions = pay_agency.txn.get_transactions({
    "transaction_start_date": "2023-01-01",  # optional
    "transaction_end_date": "2023-12-31",  # optional
    "nextCursor": "cursor_value",  # optional - for pagination
    "prevCursor": "cursor_value",  # optional - for pagination
})

# Response format:
{
    "message": str,
    "data": [
        {
            "first_name": str,
            "last_name": str,
            "converted_amount": str,
            "converted_currency": str,
            "transaction_id": str,
            "amount": str,
            "currency": str,
            "status": str,
            "card_type": str | None,
            "card_number": str | None,
            "transaction_type": str,
            "order_id": str | None,
            "country": str,
            "email": str,
            "created_at": str,
            "transaction_date": str,
            "chargeback_date": str | None,
            "refund_date": str | None,
            "suspicious_date": str | None,
            "merchant_connector": {
                "name": str,
            },
            "user": {
                "name": str,
                "user_kyc": {
                    "name": str,
                },
            },
        }
    ],
    "meta": {
        "hasNextPage": bool,
        "hasPreviousPage": bool,
        "nextCursor": str,  # optional
        "prevCursor": str,  # optional
        "totalCount": int,
    }
}

Get Wallet Transactions

wallet_transactions = pay_agency.txn.get_wallet_transactions({
    "transaction_start_date": "2023-01-01",  # optional
    "transaction_end_date": "2023-12-31",  # optional
    "next_cursor": "cursor_value",  # optional - for pagination
    "prev_cursor": "cursor_value",  # optional - for pagination
})

# Returns the same response format as get_transactions

Refunds

Process refunds:

# Direct refund method
refund = pay_agency.refund({
    "reason": "Customer request",
    "transaction_id": "TXN_123",
})

# Response format:
{
    "status": "SUCCESS",
    "message": str,
    "data": {
        "amount": int,
        "currency": str,
        "order_id": str | None,
        "transaction_id": str,
        "customer": {
            "first_name": str,
            "last_name": str,
            "email": str,
        },
        "refund": {
            "status": bool,
            "refund_date": str | None,
        },
        "chargeback": {
            "status": bool,
            "chargeback_date": str | None,
        },
    }
}

Error Handling

The SDK uses requests for HTTP requests and will raise exceptions for failed requests:

from payagency_api import PayAgencyApi, PayAgencyError

try:
    payment = pay_agency.payment.s2s(payment_data)
    print("Payment successful:", payment)
except PayAgencyError as e:
    # PayAgency API error
    print(f"Payment failed: {e}")
    print(f"Status code: {e.status_code}")
    print(f"Response: {e.response}")
except requests.RequestException as e:
    # Network error
    print(f"Network error: {e}")
except Exception as e:
    # Other error
    print(f"Error: {e}")

Security

Encryption

The SDK automatically encrypts request payloads using AES-256-CBC encryption with your provided encryption key. Some endpoints (like payment links and refunds) skip encryption as indicated by the skip_encryption parameter.

API Key Security

  • Never expose your API keys in client-side code
  • Use test keys (PA_TEST_) for development
  • Use live keys (PA_LIVE_) only in production
  • Rotate your keys regularly

Best Practices

  1. Store API keys in environment variables
  2. Use HTTPS for all webhook URLs
  3. Validate webhook signatures on your server
  4. Implement proper error handling
  5. Log transactions for auditing

Environment

The SDK supports both test and live environments:

Test Environment

  • Use secret keys starting with PA_TEST_
  • Returns mock data for certain endpoints (wallets, fee estimation)
  • Safe for development and testing

Live Environment

  • Use secret keys starting with PA_LIVE_
  • Processes real transactions
  • Use only in production

Type Hints Support

The SDK is written with comprehensive type hints for better IDE support and type checking:

from payagency_api import PayAgencyApi
from payagency_api.types import (
    PaymentResponse,
    PayoutResponse,
    CryptoPaymentResponse,
    RefundResponse,
)

# Type hints are included for all methods and responses
def process_payment(pay_agency: PayAgencyApi) -> PaymentResponse:
    return pay_agency.payment.s2s({
        "first_name": "John",
        "last_name": "Doe",
        # ... other fields
    })

Important Notes

  • Payment amounts: Use actual currency amounts as integers (e.g., 1 for $1.00 or £1.00)
  • Crypto amounts: For crypto, use string format for precise decimal values (e.g., "0.01" for Bitcoin)
  • Country codes: Use ISO 3166-1 alpha-2 country codes (e.g., "GB", "US")
  • Currency codes: Use ISO 4217 currency codes (e.g., "USD", "GBP", "EUR")
  • Crypto networks: Use uppercase format (e.g., "BITCOIN", "ETHEREUM")
  • Card expiry years: Use full 4-digit format (e.g., "2027", not "27")
  • Optional fields: Fields marked as optional can be omitted from the payload

License

MIT License - see the LICENSE file for details.

Support

For support and documentation, please visit PayAgency Documentation or contact support@pay.agency


Version: 1.0.0

Author: PaneruVipin

Repository: payagency-python

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

payagency_api-1.1.0.tar.gz (25.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

payagency_api-1.1.0-py3-none-any.whl (20.6 kB view details)

Uploaded Python 3

File details

Details for the file payagency_api-1.1.0.tar.gz.

File metadata

  • Download URL: payagency_api-1.1.0.tar.gz
  • Upload date:
  • Size: 25.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.5

File hashes

Hashes for payagency_api-1.1.0.tar.gz
Algorithm Hash digest
SHA256 6c8ce15a2bbcc8384dbac88c5c483568e8b9404f47e42882cf1998303b0ac579
MD5 967dd2064eb9bc0991a413ab69be2385
BLAKE2b-256 5f8699cc3cf8932910e8c26d228f7c989e65911f78b70ca6e2f89c796b734f75

See more details on using hashes here.

File details

Details for the file payagency_api-1.1.0-py3-none-any.whl.

File metadata

  • Download URL: payagency_api-1.1.0-py3-none-any.whl
  • Upload date:
  • Size: 20.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.5

File hashes

Hashes for payagency_api-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 2fc4bd5e2feae742d3a48ded68951745ead64c0a011601c8bf238093abbdeab0
MD5 0b3f4b18fff19f29f51a11991f7a7c31
BLAKE2b-256 5af0e4f18c98fd2af0e171defb50d08bb2fcda3e964d2f5bfc7364e94fb3f690

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page