Skip to main content

Python SDK for integrating the Xpress payment gateway (xpresspayonline.com)

Project description

xpresspay

A Python SDK for integrating the Xpress payment gateway into your application.

Supports card payments (PIN, AVS/3DSecure), direct bank-account debits, payment verification, and banks listing. Built on httpx with 3DES-24 encryption as required by the Xpresspay API.

Requirements

  • Python 3.9+
  • uv (recommended) or pip

Installation

uv add xpresspay
# or
pip install xpresspay

Security

  • Your secret key (XPSECK-…) is used only for local encryption — it is never sent over the network.
  • Only the resulting ciphertext travels to Xpresspay's servers over HTTPS.
  • Store credentials in environment variables, never in source code.

Quick start

import os
from xpresspay import XpressPay

client = XpressPay(
    public_key=os.environ["XPRESSPAY_PUBLIC_KEY"],
    secret_key=os.environ["XPRESSPAY_SECRET_KEY"],
    sandbox=True,   # False for production
)

Card payment flow

1 — Initiate

from xpresspay import CardPaymentRequest

response = client.cards.initiate(
    CardPaymentRequest(
        public_key=client.public_key,
        card_number="5438898014560229",
        cvv="789",
        expiry_month="09",
        expiry_year="25",
        amount="5000",
        email="customer@example.com",
        transaction_id="ORDER-001",
        phone_number="08012345678",
        first_name="Ada",
        last_name="Okonkwo",
    )
)

2a — Authenticate (Nigerian cards — PIN)

from xpresspay import CardPinAuthRequest

if response.suggested_authentication == "PIN":
    auth = client.cards.authenticate_pin(
        CardPinAuthRequest(
            public_key=client.public_key,
            transaction_id="ORDER-001",
            pin="1234",
        )
    )

2b — Authenticate (international cards — AVS/3DSecure)

from xpresspay import CardAvsAuthRequest

if response.suggested_authentication == "AVS_VBVSECURECODE":
    auth = client.cards.authenticate_avs(
        CardAvsAuthRequest(
            public_key=client.public_key,
            transaction_id="ORDER-001",
            billing_zip="07205",
            billing_city="Hillside",
            billing_address="470 Mundet PI",
            billing_state="NJ",
            billing_country="US",
        )
    )
    # If auth.auth_url is set, render it in an iframe for 3DSecure

3 — Validate OTP

from xpresspay import OtpValidationRequest

validated = client.cards.validate_otp(
    OtpValidationRequest(
        public_key=client.public_key,
        transaction_id="ORDER-001",
        otp="123456",
        payment_type="CARD",
    )
)

4 — Verify server-side (always do this before fulfilling orders)

from xpresspay import PaymentQueryRequest

result = client.cards.query(
    PaymentQueryRequest(
        public_key=client.public_key,
        transaction_id="ORDER-001",
        payment_type="CARD",
    )
)

if result.is_successful and result.amount == "5000":
    print("Payment confirmed:", result.transaction_reference)
else:
    print("Not confirmed:", result.raw)

Bank account payment flow

from xpresspay import AccountPaymentRequest, OtpValidationRequest, PaymentQueryRequest

banks = client.banks.list()
access_bank = next(b for b in banks if "Access" in b.name)

response = client.accounts.initiate(
    AccountPaymentRequest(
        public_key=client.public_key,
        account_number="0690000031",
        bank_code=access_bank.code,
        amount="10000",
        email="customer@example.com",
        transaction_id="ORDER-002",
        # date_of_birth="01011990",  # required for Zenith / UBA
        # bvn="12345678901",         # required for UBA
        # redirect_url="https://yourdomain.com/callback",  # required for GTB / First Bank
    )
)

validated = client.accounts.validate_otp(
    OtpValidationRequest(
        public_key=client.public_key,
        transaction_id="ORDER-002",
        otp="123456",
        payment_type="ACCOUNT",
    )
)

result = client.accounts.query(
    PaymentQueryRequest(
        public_key=client.public_key,
        transaction_id="ORDER-002",
        payment_type="ACCOUNT",
    )
)
assert result.is_successful

Exception handling

from xpresspay import (
    XpressPayError,
    AuthenticationError,
    ValidationError,
    NetworkError,
)

try:
    response = client.cards.initiate(...)
except AuthenticationError:
    ...  # invalid / missing API key
except ValidationError as e:
    print(e.message, e.error_type)
except NetworkError:
    ...  # timeout — safe to retry
except XpressPayError:
    ...  # catch-all

Exception reference

Exception Trigger
XpressPayError Base class
AuthenticationError HTTP 401
ValidationError HTTP 400
NotFoundError HTTP 404
ProcessingError HTTP 5xx
EncryptionError Local 3DES failure
NetworkError Timeout / connection error

Development

git clone https://github.com/praisegee/xpresspay
cd xpresspay
uv sync --group dev
uv run pytest
uv run ruff check xpresspay/ tests/

Environment variables

Variable Description
XPRESSPAY_PUBLIC_KEY Public key (XPPUBK-…)
XPRESSPAY_SECRET_KEY Secret key (XPSECK-…) — server-side only

License

MIT

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

xpresspay-0.1.0.tar.gz (83.7 kB view details)

Uploaded Source

Built Distribution

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

xpresspay-0.1.0-py3-none-any.whl (15.1 kB view details)

Uploaded Python 3

File details

Details for the file xpresspay-0.1.0.tar.gz.

File metadata

  • Download URL: xpresspay-0.1.0.tar.gz
  • Upload date:
  • Size: 83.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for xpresspay-0.1.0.tar.gz
Algorithm Hash digest
SHA256 122dbd1f65fde51ecfd767f5696c5a11c5e6eccedf56a3058bde1b165b065a51
MD5 fcf5eddab94d50b725db123c3c82bf52
BLAKE2b-256 d2b29c81f77c8eeec8e337f6ba7751c3de4615b40e6cc9f8bd96599556afc401

See more details on using hashes here.

Provenance

The following attestation bundles were made for xpresspay-0.1.0.tar.gz:

Publisher: publish.yml on praisegee/xpresspay

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file xpresspay-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: xpresspay-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 15.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for xpresspay-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 13d2d039ff9497f708365db19db3f7ce0df03856141e03f149bf524061933796
MD5 d882597f7e8d2dee16f68f8d87c2ce1c
BLAKE2b-256 9dd99094a8a67e0c0675efb7cee54ca3c0c245a456afe41490f6b0170d2de130

See more details on using hashes here.

Provenance

The following attestation bundles were made for xpresspay-0.1.0-py3-none-any.whl:

Publisher: publish.yml on praisegee/xpresspay

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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