Skip to main content

Official Python SDK for the Piaxis partner API

Project description

Piaxis Python SDK

Official Python SDK for the Piaxis partner/payments API.

  • Package: piaxis-sdk
  • PyPI: https://pypi.org/project/piaxis-sdk/
  • Repository: https://github.com/piaxepay/python-sdk
  • REST API docs: https://api.gopiaxis.com/api/docs/
  • TypeScript SDK: https://github.com/piaxepay/typescript-sdk

What this SDK covers

This SDK is the Python client for the public partner/payments surface exposed at api.gopiaxis.com.

It currently covers:

  • OAuth authorize URL generation and token exchange for piaxis_external
  • OTP requests
  • Direct payments
  • Escrows and escrow actions
  • Direct disbursements
  • Escrow disbursements
  • Shared transport concerns like auth headers, timeouts, and structured API errors

It does not attempt to wrap every backend endpoint in piaxis-api, such as internal dashboard, admin, or other non-public surfaces. For fields or endpoints not yet promoted into the SDK surface, use the raw REST documentation at https://api.gopiaxis.com/api/docs/.

Install

pip install piaxis-sdk

Python 3.10+ is required.

Choose your auth mode

Use one of these two authentication modes:

  • api_key: merchant-owned operations like OTP, direct payments, escrows, and disbursements
  • access_token: end-user-authorized piaxis_external payments after the OAuth flow completes

Environment variables supported by PiaxisClient.from_env():

  • PIAXIS_API_KEY
  • PIAXIS_ACCESS_TOKEN
  • PIAXIS_CLIENT_ID or PIAXIS_OAUTH_CLIENT_ID
  • PIAXIS_API_BASE_URL

Base URLs:

  • Sandbox: https://sandbox.api.gopiaxis.com/api
  • Production: https://api.gopiaxis.com/api

PiaxisClient.from_env() requires either PIAXIS_API_KEY or PIAXIS_ACCESS_TOKEN. The SDK rejects non-HTTPS base_url values unless you are explicitly targeting localhost for local tests.

export PIAXIS_API_KEY="your_sandbox_api_key"
export PIAXIS_API_BASE_URL="https://sandbox.api.gopiaxis.com/api"
from piaxis_sdk import PiaxisClient

client = PiaxisClient.from_env()

Direct payment flow

Typical mobile-money flow:

  1. Request an OTP for the customer.
  2. Create the payment with payment_method="mtn" or payment_method="airtel".
  3. Poll get_payment(...) and/or consume your webhook events until the payment settles.
import os
import secrets

from piaxis_sdk import PiaxisClient, generate_pkce_pair


with PiaxisClient.from_env() as client:
    otp = client.request_otp(
        {
            "email": "buyer@example.com",
            "phone_number": "+256700000000",
        }
    )

    payment = client.create_payment(
        {
            "amount": "15000",
            "currency": "UGX",
            "payment_method": "mtn",
            "user_info": {
                "email": "buyer@example.com",
                "phone_number": "+256700000000",
                "otp": os.getenv("PIAXIS_TEST_OTP", "123456"),
            },
            "customer_pays_fees": True,
        }
    )

    print("otp:", otp)
    print("payment:", payment)
    print("latest:", client.get_payment(payment["payment_id"]))

Notes:

  • user_info, products, and terms[*].data follow the raw API payload shape from the REST docs.
  • Many payment methods are asynchronous. Plan for polling and webhooks instead of assuming the create call means “completed”.

OAuth and piaxis_external flow

Use this when the payer must authorize access to an external Piaxis wallet.

import os

from piaxis_sdk import PiaxisClient


base_url = os.getenv("PIAXIS_API_BASE_URL", "https://sandbox.api.gopiaxis.com/api")

auth_client = PiaxisClient(base_url=base_url)
pkce = generate_pkce_pair()
oauth_state = secrets.token_urlsafe(24)

authorize_url = auth_client.build_authorize_url(
    merchant_id=os.environ["PIAXIS_MERCHANT_ID"],
    external_user_id="customer-123",
    redirect_uri=os.environ["PIAXIS_REDIRECT_URI"],
    state=oauth_state,
    code_challenge=pkce["code_challenge"],
    code_challenge_method=pkce["code_challenge_method"],
)

print("redirect the customer to:", authorize_url)

tokens = auth_client.exchange_token(
    code=os.environ["PIAXIS_AUTH_CODE"],
    redirect_uri=os.environ["PIAXIS_REDIRECT_URI"],
    client_id=os.environ["PIAXIS_OAUTH_CLIENT_ID"],
    client_secret=os.environ["PIAXIS_OAUTH_CLIENT_SECRET"],
    code_verifier=pkce["code_verifier"],
)

payer_client = PiaxisClient(
    access_token=tokens["access_token"],
    base_url=base_url,
)

payment = payer_client.create_payment(
    {
        "amount": "15000",
        "currency": "UGX",
        "payment_method": "piaxis_external",
        "recipient_id": os.environ.get("PIAXIS_RECIPIENT_ID"),
        "customer_pays_fees": True,
    }
)

print(payment)

If your access token expires, refresh it on the same route family:

refreshed = auth_client.refresh_token(
    refresh_token=tokens["refresh_token"],
    client_id=os.environ["PIAXIS_OAUTH_CLIENT_ID"],
    client_secret=os.environ["PIAXIS_OAUTH_CLIENT_SECRET"],
)

If you want to test the authorize step without a browser redirect, use authorize_test(...). That helper is for merchant-controlled testing only: the redirect_uri must already be registered for the merchant, and the x-test-request bootstrap path is only meant for merchant owners/admins in controlled environments. redirect_uri should use HTTPS in every real environment. Plain HTTP is only accepted for localhost development callbacks.

Security helpers

The SDK ships a PKCE generator and webhook verification helper:

from piaxis_sdk import generate_pkce_pair, verify_webhook_signature

pkce = generate_pkce_pair()

is_valid = verify_webhook_signature(
    raw_body,
    secret=os.environ["PIAXIS_WEBHOOK_SECRET"],
    signature=request.headers.get("X-piaxis-Signature"),
    signature_v2=request.headers.get("X-piaxis-Signature-V2"),
    timestamp=request.headers.get("X-piaxis-Signature-Timestamp"),
)

Prefer X-piaxis-Signature-V2 plus X-piaxis-Signature-Timestamp when they are present; the helper falls back to the legacy signature for older deliveries.

Escrow flow

Escrows are a separate flow from direct payments. The common lifecycle is:

  1. create_escrow(...)
  2. get_escrow(...) or get_escrow_status(...)
  3. fulfill_escrow_term(...), release_escrow(...), reverse_escrow(...), or dispute_escrow(...) depending on your business rules
import os

from piaxis_sdk import PiaxisClient


with PiaxisClient.from_env() as client:
    escrow = client.create_escrow(
        {
            "receiver_id": os.environ["PIAXIS_RECEIVER_ID"],
            "amount": "50000",
            "currency_code": "UGX",
            "payment_method": "mtn",
            "external_order_id": "order-789",
            "metadata": {"channel": "marketplace"},
            "allocations": [
                {
                    "allocation_key": "seller-alpha",
                    "amount": "20000",
                    "seller_reference": "seller-001",
                    "description": "Alpha seller settlement",
                },
                {
                    "allocation_key": "seller-beta",
                    "amount": "30000",
                    "seller_reference": "seller-002",
                    "description": "Beta seller settlement",
                },
            ],
            "user_info": {
                "email": "buyer@example.com",
                "phone_number": "+256700000000",
                "otp": os.getenv("PIAXIS_TEST_OTP", "123456"),
            },
            "terms": [{"type": "manual_release", "data": {}}],
        }
    )

    print(client.get_escrow_status(escrow["id"]))
    print(
        client.release_escrow(
            escrow["id"],
            payload={
                "allocation_keys": ["seller-alpha"],
                "amount": "20000",
                "reason": "Sandbox partial release for seller alpha",
            },
        )
    )

    print(escrow["allocation_summary"])

For marketplace checkouts, keep receiver_id set to the merchant account and represent seller or fulfillment slices with allocations. The escrow still belongs to the merchant; allocations let you release or reverse only the affected slices.

Merchants should surface those allocation balances and actions directly on the order page where the buyer placed the order so users can review what is still held versus what has already been released or reversed.

Disbursement flows

Use direct disbursements for payouts that do not need escrow, and escrow disbursements when each payout item must satisfy terms before release.

from piaxis_sdk import PiaxisClient


with PiaxisClient.from_env() as client:
    direct = client.disburse(
        recipients=[
            {"recipient_id": "recipient-123", "amount": "100000", "reference": "supplier-001"},
            {"phone_number": "+256711111111", "amount": "50000", "reference": "supplier-002"},
        ],
        currency="UGX",
        payment_method="airtel",
        description="Weekly supplier payout",
    )

    escrow_batch = client.escrow_disburse(
        recipients=[
            {
                "recipient_id": "recipient-123",
                "amount": "100000",
                "reference": "courier-001",
                "terms": [{"type": "manual_release", "data": {}}],
            }
        ],
        currency="UGX",
        payment_method="mtn",
        description="Courier escrow batch",
        user_location={"latitude": 0.312, "longitude": 32.582},
    )

    print(direct)
    print(escrow_batch)

Related methods:

  • get_disbursement(...), list_disbursements(...), cancel_disbursement(...)
  • get_escrow_disbursement(...), list_escrow_disbursements(...), release_escrow_disbursement(...), cancel_escrow_disbursement(...)

Error handling

API failures raise PiaxisApiError.

from piaxis_sdk import PiaxisApiError, PiaxisClient


try:
    client = PiaxisClient(api_key="invalid")
    client.list_merchant_payments()
except PiaxisApiError as exc:
    print("message:", exc.message)
    print("status:", exc.status_code)
    print("code:", exc.code)
    print("request_id:", exc.request_id)
    print("details:", exc.details)

Use request_id when talking to Piaxis support.

Request customization

You can identify your application and override request behavior:

from piaxis_sdk import PiaxisClient


client = PiaxisClient(
    api_key="your_api_key",
    base_url="https://sandbox.api.gopiaxis.com/api",
    timeout=60.0,
    app_name="orders-service",
    app_version="1.4.0",
)

payment = client.get_payment(
    "payment-id",
    request_options={
        "headers": {"x-request-id": "merchant-trace-123"},
        "timeout": 10.0,
    },
)

This sends:

  • api-key or Authorization: Bearer ...
  • x-piaxis-sdk-client: orders-service/1.4.0 when app_name is set
  • any extra headers you pass via request_options

Method map

Capability Python method REST endpoint
Build authorize URL build_authorize_url(...) GET /authorize
Test authorize redirect authorize_test(...) GET /authorize with x-test-request: true (merchant-controlled testing only)
Exchange OAuth token exchange_token(...) POST /token
Refresh OAuth token refresh_token(...) POST /token with grant_type=refresh_token
Request OTP request_otp(...) POST /request-otp
Create payment create_payment(...) POST /payments/create
Get payment get_payment(...) GET /payments/{payment_id}
List merchant payments list_merchant_payments(...) GET /merchant-payments
Create escrow create_escrow(...) POST /escrows/
Get escrow get_escrow(...) GET /escrows/{escrow_id}
Get escrow status get_escrow_status(...) GET /escrows/{escrow_id}/status
Release escrow release_escrow(...) POST /escrows/{escrow_id}/release
Fulfill escrow term fulfill_escrow_term(...) POST /escrows/{escrow_id}/terms/{term_id}/fulfill
Reverse escrow reverse_escrow(...) POST /escrows/{escrow_id}/reverse
Dispute escrow dispute_escrow(...) POST /escrows/{escrow_id}/disputes
Create disbursement disburse(...) POST /disbursements
Get disbursement get_disbursement(...) GET /disbursements/{disbursement_id}
List disbursements list_disbursements(...) GET /disbursements
Cancel disbursement cancel_disbursement(...) POST /disbursements/{disbursement_id}/cancel
Create escrow disbursement escrow_disburse(...) POST /escrow-disbursements
Get escrow disbursement get_escrow_disbursement(...) GET /escrow-disbursements/{disbursement_id}
List escrow disbursements list_escrow_disbursements(...) GET /escrow-disbursements
Release escrow disbursement release_escrow_disbursement(...) POST /escrow-disbursements/{disbursement_id}/release (force=False by default)
Cancel escrow disbursement cancel_escrow_disbursement(...) POST /escrow-disbursements/{disbursement_id}/cancel

Examples and references

  • Direct payment example: https://github.com/piaxepay/python-sdk/blob/main/examples/direct_payment.py
  • OAuth example: https://github.com/piaxepay/python-sdk/blob/main/examples/oauth_flow.py
  • Escrow example: https://github.com/piaxepay/python-sdk/blob/main/examples/escrow_flow.py
  • Disbursement example: https://github.com/piaxepay/python-sdk/blob/main/examples/disbursement_flow.py
  • Sandbox onboarding: https://github.com/piaxepay/python-sdk/blob/main/SANDBOX_ONBOARDING.md
  • Repository architecture: https://github.com/piaxepay/python-sdk/blob/main/ARCHITECTURE.md
  • REST API docs: https://api.gopiaxis.com/api/docs/

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

piaxis_sdk-0.2.4.tar.gz (17.8 kB view details)

Uploaded Source

Built Distribution

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

piaxis_sdk-0.2.4-py3-none-any.whl (15.8 kB view details)

Uploaded Python 3

File details

Details for the file piaxis_sdk-0.2.4.tar.gz.

File metadata

  • Download URL: piaxis_sdk-0.2.4.tar.gz
  • Upload date:
  • Size: 17.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.9

File hashes

Hashes for piaxis_sdk-0.2.4.tar.gz
Algorithm Hash digest
SHA256 fbe92815c0cebcb1143ffd9471a4801a2305fb6ce1cca9cff7fa0de88fdf7203
MD5 07a2aa094da2d549fbd1351806e479f4
BLAKE2b-256 783474e86160bd7d3be0b892d575679338baf1c28fd0bb2762b426ac697317e3

See more details on using hashes here.

File details

Details for the file piaxis_sdk-0.2.4-py3-none-any.whl.

File metadata

  • Download URL: piaxis_sdk-0.2.4-py3-none-any.whl
  • Upload date:
  • Size: 15.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.9

File hashes

Hashes for piaxis_sdk-0.2.4-py3-none-any.whl
Algorithm Hash digest
SHA256 8530beaea6e0e5d58f237674a74ac79a44652e49a6ab88d4dee1ac2a22a146a1
MD5 cbbfaedbccafa3b35bc4eeb3c0bf054d
BLAKE2b-256 9f5ab2555a19066106152f5626666c4410eec758e1a53af1871f7cb7795921de

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