Skip to content

Code layout

Models

paykit.providers.payme.models

Django models for the Payme payment provider.

Covers merchants, transactions, receipts, and subscriptions. All monetary values are stored in tiyins (1 UZS = 100 tiyins).

PaymeMerchant

Bases: Model

Represents a Payme merchant account.

Each merchant holds its own credentials and can be linked to multiple transactions and subscriptions.

Attributes:

Name Type Description
name

Human-readable merchant name.

merchant_key

Payme merchant ID (unique).

merchant_secret

Payme secret key used for Basic Auth.

is_enabled

Whether this merchant is active.

created_at

Record creation timestamp.

updated_at

Record last-update timestamp.

base64_key: str property

    Base64-encoded Basic Auth credential for Payme API requests.

    Returns:
        Base64 string of ``Paycom:<merchant_secret>``.

    Example:
            merchant = PaymeMerchant.objects.get(pk=1)
            headers = {"Authorization": f"Basic {merchant.base64_key}"}

PaymeTransaction

Bases: Model

Records a single Payme payment transaction.

Tracks the full lifecycle from pending through performed or cancelled, including cancel reasons and timestamps from Payme's system.

Attributes:

Name Type Description
merchant

The merchant this transaction belongs to.

payme_id

Unique transaction ID assigned by Payme.

payme_time

Transaction creation time from Payme (Unix ms).

order_id

Your internal order identifier.

amount

Payment amount in tiyins.

state

Current transaction state (see TransactionState).

reason

Cancellation reason code (see CancelReason), if applicable.

create_time

Time transaction was created on Payme's side (Unix ms).

perform_time

Time transaction was performed (Unix ms).

cancel_time

Time transaction was cancelled (Unix ms).

extra

Arbitrary extra data from Payme's response.

TransactionState

Bases: IntegerChoices

Payme transaction lifecycle states.

CancelReason

Bases: IntegerChoices

Payme-defined cancellation reason codes.

PaymeReceipt

Bases: Model

Payme receipt linked one-to-one with a transaction.

Stores the fiscal/receipt data returned by Payme after a transaction is performed or cancelled.

Attributes:

Name Type Description
transaction

The related PaymeTransaction.

receipt_id

Payme's internal receipt _id.

state

Receipt state (0=created, 1=paid, 2=cancelled, 4=paid+fiscal).

type

Receipt type (0=debit, 1=credit).

external_id

Optional external reference ID.

description

Human-readable receipt description.

paid_at

Payment timestamp (Unix ms).

cancelled_at

Cancellation timestamp (Unix ms).

detail

Full receipt detail payload from Payme.

PaymeSubscription

Bases: Model

Represents a recurring subscription charged via Payme card token.

Subscriptions use a saved card token to charge the customer at a defined interval without redirecting to checkout.

Attributes:

Name Type Description
merchant

The merchant managing this subscription.

card_token

Payme card token for recurring charges.

card_number

Masked card number for display (e.g. "**** 1234").

amount

Charge amount in tiyins.

order_id

Your internal order/subscription identifier.

state

Current subscription state (see SubscriptionState).

next_payment_at

Scheduled datetime for the next charge.

last_payment_at

Datetime of the most recent successful charge.

SubscriptionState

Bases: TextChoices

Subscription lifecycle states.

is_active() -> bool

Check whether the subscription is currently active.

Returns:

Type Description
bool

True if state is active, False otherwise.

Source code in paykit/providers/payme/models.py
204
205
206
207
208
209
210
211
def is_active(self) -> bool:
    """
    Check whether the subscription is currently active.

    Returns:
        ``True`` if state is ``active``, ``False`` otherwise.
    """
    return self.state == self.SubscriptionState.STATE_ACTIVE

API Merchant

paykit.providers.payme.api.merchant

Triggers

check_order(merchant: PaymeMerchant, order_id: str, amount: int) -> bool

Return True if the order exists and amount is valid. Must be overridden.

Source code in paykit/providers/payme/api/merchant.py
20
21
22
def check_order(self, merchant: PaymeMerchant, order_id: str, amount: int) -> bool:
    """Return True if the order exists and amount is valid. Must be overridden."""
    raise NotImplementedError("check_order() must be implemented")

on_payment(merchant: PaymeMerchant, tx: PaymeTransaction) -> None

Called when a transaction is successfully performed. Must be overridden.

Source code in paykit/providers/payme/api/merchant.py
24
25
26
def on_payment(self, merchant: PaymeMerchant, tx: PaymeTransaction) -> None:
    """Called when a transaction is successfully performed. Must be overridden."""
    print("on_payment() must be implemented")

on_cancelled(merchant: PaymeMerchant, tx: PaymeTransaction) -> None

Called when a PENDING transaction is cancelled. Must be overridden.

Source code in paykit/providers/payme/api/merchant.py
29
30
31
def on_cancelled(self, merchant: PaymeMerchant, tx: PaymeTransaction) -> None:
    """Called when a PENDING transaction is cancelled. Must be overridden."""
    print("on_cancelled() must be implemented")

on_cancelled_after_perform(merchant: PaymeMerchant, tx: PaymeTransaction) -> None

Called when an already PERFORMED transaction is cancelled. Must be overridden.

Source code in paykit/providers/payme/api/merchant.py
34
35
36
37
38
def on_cancelled_after_perform(
    self, merchant: PaymeMerchant, tx: PaymeTransaction
) -> None:
    """Called when an already PERFORMED transaction is cancelled. Must be overridden."""
    print("on_cancelled_after_perform() must be implemented")

PaymeMerchantAPI

Bases: Triggers

Inherit this class and override check_order(). Auth is resolved from PaymeMerchant DB records — no hardcoded keys.

API Subscribe

paykit.providers.payme.api.subscribe

PaymeSubscribeAPI(merchant: PaymeMerchant | str | None = None, subscribe_client=None)

Subscribe API — card tokenisation + recurring charges. Merchant is resolved once at instantiation: - None → first enabled merchant in DB - str → merchant matched by name - PaymeMerchant → used directly

Source code in paykit/providers/payme/api/subscribe.py
29
30
31
32
33
34
35
def __init__(
    self, merchant: PaymeMerchant | str | None = None, subscribe_client=None
):
    self.merchant = self._resolve_merchant(merchant)
    self.client = (
        subscribe_client if subscribe_client is not None else PaymeSubscribeClient()
    )