Skip to content

Payments

The Xpresspay integration uses a hosted payment page flow — you initialize a transaction from your server, then redirect the customer to Xpresspay's hosted page to complete payment. Once the customer pays, they are sent back to your callback_url.

Initialize (server-side)
       └─ Redirect customer to payment_url
               └─ Customer pays on Xpresspay hosted page
                       └─ Redirect to callback_url
                               └─ Verify (server-side) ← always do this

Initialize a transaction

from xpresspay import XpressPay, InitializeRequest

# Reads XPRESSPAY_PUBLIC_KEY from the environment automatically
client = XpressPay(sandbox=True)

response = client.payments.initialize(
    InitializeRequest(
        amount="1000.00",
        email="customer@example.com",
        transaction_id="ORDER-001",
        callback_url="https://yourdomain.com/payment/callback",
    )
)

if response.is_successful:
    # Redirect the customer to the hosted payment page
    print(response.payment_url)
    print(response.reference)

InitializeRequest fields

Field Type Required Description
amount str Amount to charge, e.g. "1000.00"
email str Customer's email address
transaction_id str Your unique transaction ID (6–30 characters)
currency str Default: "NGN"
product_id str Unique product identifier
product_description str Description shown on the payment page
callback_url str URL the customer is redirected to after payment
body_color str Custom hex colour for the payment page body
button_color str Custom hex colour for payment page buttons
footer_text str Custom footer text on the payment page
footer_logo str URL to your logo shown in the page footer
split_payment_reference str Reference for a pre-configured split payment
is_split_payment bool Set True to enable split settlement
is_api_user bool Default: True — set when integrating via API
merchant_name str Your business name shown on the payment page
logo_url str URL to your business logo
mode str Payment mode
apply_conveniency_charge bool Pass the convenience charge to the customer
is_recurring bool Mark transaction as recurring
metadata list[dict] Extra data: [{"name": "key", "value": "val"}]

InitializeResponse properties

Property Type Description
is_successful bool True when responseCode == "00"
payment_url str \| None Hosted payment page URL — redirect the customer here
reference str \| None Transaction reference from Xpresspay
response_code str Raw API response code
response_message str Human-readable API message
raw dict Full JSON response

Verify a payment

Always verify before fulfilling an order

Never trust the client-side redirect. Always confirm the payment server-side before delivering goods or services.

from xpresspay import VerifyRequest

result = client.payments.verify(
    VerifyRequest(transaction_id="ORDER-001")
)

if result.is_successful and result.amount == "1000.00":
    # Safe to fulfill the order
    print("Confirmed:", result.gateway_response)
else:
    print("Not confirmed:", result.status)

VerifyResponse properties

Property Type Description
is_successful bool True when the transaction was successfully settled
amount str \| None Transaction amount
currency str \| None Currency code, e.g. "NGN"
status str \| None Status description, e.g. "Transaction Successful"
payment_type str \| None e.g. "Card"
gateway_response str \| None Raw gateway message
transaction_id str \| None Your original transaction ID
response_code str Raw API response code
response_message str Human-readable API message
raw dict Full JSON response

Complete example

from xpresspay import (
    XpressPay,
    InitializeRequest,
    VerifyRequest,
    AuthenticationError,
    ValidationError,
    NetworkError,
)

# Reads XPRESSPAY_PUBLIC_KEY from the environment automatically
client = XpressPay(sandbox=True)

try:
    # 1 — Initialize
    resp = client.payments.initialize(
        InitializeRequest(
            amount="1000.00",
            email="customer@example.com",
            transaction_id="ORDER-001",
            callback_url="https://yourdomain.com/payment/callback",
            merchant_name="My Store",
        )
    )

    if resp.is_successful:
        print("Redirect customer to:", resp.payment_url)

    # 2 — After customer returns to callback_url, verify server-side
    result = client.payments.verify(
        VerifyRequest(transaction_id="ORDER-001")
    )

    if result.is_successful:
        print("Payment confirmed:", result.gateway_response)

except ValidationError as e:
    print("Bad request:", e.message)
except AuthenticationError:
    print("Check your API key")
except NetworkError:
    print("Network issue — safe to retry")
finally:
    client.close()