Metadata-Version: 2.4
Name: makepay
Version: 0.3.0
Summary: Official MakePay Python SDK for payments, invoices, bookkeeping, POS, products, Simple Shop, branding, and webhooks.
Project-URL: Homepage, https://www.makepay.io
Project-URL: Documentation, https://www.makecrypto.io/documentation/sdk/python
Project-URL: Repository, https://github.com/makecryptoio/makeswap/tree/main/apps/plugins/python-sdk
Project-URL: Issues, https://github.com/makecryptoio/makeswap/issues
Author-email: MakePay <support@makepay.io>
License-Expression: MIT
License-File: LICENSE
Keywords: bookkeeping,crypto-payments,donations,invoices,makecrypto,makepay,payment-links,pos,products,webhooks
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Office/Business :: Financial
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.9
Description-Content-Type: text/markdown

# MakePay Python SDK

Official Python SDK for MakePay server-side integrations. Use it to create
crypto payment links, donation pages, invoices, bookkeeping records,
subscriptions, POS terminals, products, Simple Shop storefronts, customer
portals, branded domains, and signed webhook handlers.

## Install

```bash
pip install makepay
```

```bash
uv add makepay
```

The SDK targets Python 3.9 or newer, has no runtime dependencies, and uses
Python standard library HTTP and crypto modules.

## Configure

Create a MakePay API key in MakeCrypto and keep the secret on your server only.

```python
import os

from makepay import MakePayClient

makepay = MakePayClient(
    key_id=os.environ["MAKEPAY_KEY_ID"],
    key_secret=os.environ["MAKEPAY_KEY_SECRET"],
)
```

The client sends `X-MakeCrypto-Key-Id` and `X-MakeCrypto-Key-Secret` headers to
the MakePay partner API.

## Payment Links

```python
response = makepay.create_payment_link(
    {
        "title": "Order #1042",
        "description": "Checkout for order #1042",
        "amount": "129.99",
        "currency": "USDT",
        "orderId": "order_1042",
        "customerEmail": "buyer@example.com",
        "returnUrl": "https://merchant.example/orders/1042",
        "successUrl": "https://merchant.example/orders/1042/success",
        "failureUrl": "https://merchant.example/orders/1042/pay",
        "expirationTime": "12h",
    }
)

print(response["paymentLink"])
```

Read, update, and email existing links:

```python
makepay.list_payment_links()
makepay.get_payment_link("PAYMENT_LINK_UID")
makepay.update_payment_link("PAYMENT_LINK_UID", {"status": "paused"})
makepay.send_payment_request_email("PAYMENT_LINK_UID", "buyer@example.com")
```

## Donations

Donation pages are flexible-amount payment links with a public donation slug.

```python
donation = makepay.create_donation_link(
    {
        "title": "Spring campaign",
        "description": "Support the 2026 spring fundraiser.",
        "defaultAmountUsd": "25",
        "minimumAmountUsd": "5",
        "donationSlug": "spring-campaign",
    }
)

print(donation["paymentLink"]["publicUrl"])

makepay.list_donation_links()
makepay.get_donation_link("DONATION_UID")
makepay.update_donation_link("DONATION_UID", {"status": "paused"})
```

## Anonymous Payment Links

Anonymous links do not use a MakePay API key. They require an explicit
settlement route because MakePay cannot read merchant wallet settings.

```python
from makepay import create_anonymous_payment_link

response = create_anonymous_payment_link(
    {
        "amount": "25",
        "settlement": {
            "currency": "USDT",
            "priorities": [
                {
                    "chain": "ETH",
                    "address": "0xYourSettlementWallet",
                    "asset": "ETH.USDT-0xdAC17F958D2ee523a2206206994597C13D831ec7",
                }
            ],
        },
        "title": "Invoice #1042",
        "webhookUrl": "https://merchant.example/webhooks/makepay",
    }
)
```

## Checkout URLs And Embeds

Use hosted checkout for redirects, or the embed helpers when your frontend keeps
the shopper on the merchant site.

```python
from makepay import (
    build_makepay_embedded_checkout_url,
    build_makepay_hosted_checkout_url,
    build_makepay_iframe_html,
)

payment_uid = response["paymentLink"]["uid"]

hosted_url = build_makepay_hosted_checkout_url(payment_uid)
embed_url = build_makepay_embedded_checkout_url(
    payment_uid,
    parent_origin="https://merchant.example",
)
iframe_html = build_makepay_iframe_html(payment_uid)
```

Donation pages also have URL helpers:

```python
makepay.hosted_donation_url("spring-campaign")
makepay.embedded_donation_url(
    "spring-campaign",
    parent_origin="https://merchant.example",
)
```

For static CMS pages, `build_makepay_embed_button_html(payment_uid)` returns a
button snippet that loads the MakePay modal script, and
`build_makepay_iframe_html(payment_uid)` returns an iframe snippet.

## Customers And Subscriptions

```python
makepay.upsert_customer(
    {
        "email": "buyer@example.com",
        "name": "Buyer Example",
        "clientId": "crm_123",
    }
)

makepay.create_customer_portal(
    "CUSTOMER_ID",
    {"returnUrl": "https://merchant.example/account"},
)

makepay.create_subscription(
    {
        "amountUsd": "29",
        "customerEmail": "buyer@example.com",
        "label": "Monthly plan",
        "billingIntervalUnit": "month",
        "billingIntervalCount": 1,
    }
)
```

## POS Terminals

```python
terminal = makepay.create_pos_terminal(
    {
        "name": "Front counter",
        "pin": "1234",
        "allowedAssets": ["ETH.USDT-0xdAC17F958D2ee523a2206206994597C13D831ec7"],
        "emailCollectionMode": "optional_after_deposit",
        "catalogEnabled": True,
    }
)

makepay.list_pos_terminals()
makepay.get_pos_terminal(str(terminal["terminal"]["uid"]))
```

## Products And Simple Shop

```python
makepay.create_product(
    {
        "name": "Digital guide",
        "productType": "digital",
        "basePriceUsd": "19",
        "shopSlug": "digital-guide",
        "images": [{"url": "https://merchant.example/guide.png", "alt": "Guide cover"}],
        "variants": [{"name": "PDF", "priceUsd": "19"}],
    }
)

makepay.create_product_download(
    "PRODUCT_UID",
    {
        "fileName": "guide.pdf",
        "contentType": "application/pdf",
        "url": "https://merchant.example/downloads/guide.pdf",
    },
)

makepay.update_shop(
    {
        "slug": "merchant-shop",
        "displayCurrency": "USD",
        "checkoutMode": "hosted",
        "branding": {"accentColor": "#14b8a6"},
    }
)

makepay.update_shop_domain("shop.merchant.example")
makepay.refresh_shop_domain()
makepay.create_shop_coupon(
    {
        "code": "SPRING10",
        "discountType": "percent",
        "value": "10",
    }
)
makepay.list_shop_orders({"status": "paid", "limit": 25})
```

## Invoices And Bookkeeping

Bookkeeping APIs manage merchant invoices, expenses, supporting documents, OCR,
and reconciliation links.

```python
created = makepay.create_bookkeeping_invoice(
    {
        "title": "Invoice #1042",
        "currency": "USD",
        "issueDate": "2026-05-15",
        "dueDate": "2026-05-30",
        "counterparty": {
            "name": "Buyer Example",
            "email": "buyer@example.com",
            "clientId": "crm_123",
        },
        "lineItems": [
            {
                "description": "Implementation services",
                "quantity": "1",
                "unitAmount": "500",
                "taxAmount": "0",
            }
        ],
        "metadata": {"orderId": "order_1042"},
    }
)

makepay.create_bookkeeping_invoice_payment_link(
    "INVOICE_UID",
    {"sendPaymentRequestEmail": True},
)

makepay.list_bookkeeping_invoices()
makepay.get_bookkeeping_invoice("INVOICE_UID")
makepay.update_bookkeeping_invoice("INVOICE_UID", {"status": "open"})
```

Expenses can be created manually or from wallet activity, then linked back to
payments, transfers, invoices, or uploaded receipts.

```python
makepay.create_bookkeeping_expense(
    {
        "title": "Hosting",
        "amount": "49",
        "currency": "USD",
        "incurredOn": "2026-05-15",
        "category": "Infrastructure",
        "counterparty": {"name": "Vendor Example", "type": "vendor"},
    }
)

makepay.create_bookkeeping_expense_from_activity(
    {
        "walletActivityEventKey": "CHAIN_EVENT_KEY",
        "category": "Settlement",
    }
)

makepay.create_bookkeeping_reconciliation(
    {
        "invoiceId": "INVOICE_UID",
        "paymentSessionId": "PAYMENT_SESSION_ID",
        "linkType": "payment",
    }
)
```

Document uploads use multipart form data. Pass bytes, a file path, or a readable
file object.

```python
with open("receipt.pdf", "rb") as receipt:
    makepay.upload_bookkeeping_document(
        {
            "file": receipt,
            "fileName": "receipt.pdf",
            "documentType": "receipt",
            "expenseId": "EXPENSE_UID",
        }
    )

makepay.list_bookkeeping_documents()
makepay.get_bookkeeping_document_download_url("DOCUMENT_UID")
makepay.run_bookkeeping_document_ocr("DOCUMENT_UID")
makepay.get_bookkeeping_summary()
```

## Branding And Domains

```python
makepay.update_branding(
    {
        "brandName": "Merchant",
        "supportEmail": "support@merchant.example",
        "brandingBrandColor": "#111827",
        "brandingAccentColor": "#14b8a6",
        "paymentLinkTheme": "system",
        "paymentLinkDomain": "pay.merchant.example",
        "emailSendingDomain": "mail.merchant.example",
    }
)

makepay.refresh_branding_domains("all")
```

## Settings And Operational APIs

```python
makepay.get_settings()
makepay.update_settings(
    {
        "callbackUrl": "https://merchant.example/webhooks/makepay",
    }
)

makepay.list_destination_assets()
makepay.list_webhook_requests({"limit": 25})
```

## Webhook Verification

Read the exact raw body before parsing JSON.

```python
import os

from makepay import parse_makepay_webhook


def handle_makepay_webhook(raw_body: bytes, headers: dict[str, str]):
    event = parse_makepay_webhook(
        raw_body,
        headers.get("x-makepay-signature"),
        os.environ["MAKEPAY_WEBHOOK_SECRET"],
    )

    if event.get("event", {}).get("type") == "status_changed":
        # Update your local order status.
        pass

    return "ok", 200
```

Use `verify_makepay_webhook` when you only need a boolean result.

## Method Coverage

| Area | SDK methods |
| --- | --- |
| Payment links | `create_payment_link`, `list_payment_links`, `get_payment_link`, `update_payment_link`, `send_payment_request_email` |
| Donations | `create_donation_link`, `list_donation_links`, `get_donation_link`, `update_donation_link` |
| Anonymous links | `create_anonymous_payment_link` |
| Checkout | hosted, embedded, modal, button, iframe, and donation URL helpers |
| Customers | `list_customers`, `upsert_customer`, `create_customer_portal` |
| Subscriptions | `list_subscriptions`, `create_subscription` |
| POS terminals | `list_pos_terminals`, `create_pos_terminal`, `get_pos_terminal`, `update_pos_terminal` |
| Products | `list_products`, `create_product`, `get_product`, `update_product`, `list_product_downloads`, `create_product_download` |
| Simple Shop | `get_shop`, `update_shop`, `get_shop_builder`, `update_shop_builder`, `get_shop_domain`, `update_shop_domain`, `refresh_shop_domain`, coupons, orders |
| Bookkeeping | summary, invoice, expense, document upload/OCR, and reconciliation methods |
| Branding | `get_branding`, `update_branding`, `refresh_branding_domains` |
| Operations | `get_settings`, `update_settings`, `list_destination_assets`, `list_webhook_requests` |
| Webhooks | `verify_makepay_webhook`, `parse_makepay_webhook` |

## Data Models And Response Models

Python payloads are plain dictionaries that use the MakePay API field names.
New integrations should send camelCase keys such as `customerEmail`,
`paymentLinkDomain`, and `billingIntervalUnit`.

Model conventions:

- Use strings for decimal money values when precision matters, for example
  `"129.99"` instead of `129.99`.
- Dates are ISO strings. Date-only fields, such as invoice `issueDate`, should
  use `YYYY-MM-DD`.
- IDs are usually public `uid` values. Bookkeeping detail endpoints accept an
  internal UUID or public UID.
- API methods raise `MakePayError` for non-2xx responses. Successful responses
  are decoded JSON dictionaries, so production can add fields without requiring
  a Python package update.

### Accepted Payload Models

| Model | Used by | Required fields | Common optional fields |
| --- | --- | --- | --- |
| Payment link payload | `create_payment_link` | `amount` | `title`, `description`, `currency`, `asset`, `orderId`, `customerEmail`, `clientId`, `returnUrl`, `successUrl`, `metadata` |
| Donation link payload | `create_donation_link` | none | `defaultAmountUsd`, `minimumAmountUsd`, `donationSlug`, payment-link display and redirect fields |
| Anonymous payment link payload | `create_anonymous_payment_link` | `amount`, `settlement.currency`, `settlement.priorities` | `title`, `customerEmail`, `orderId`, `metadata`, `branding`, `webhookUrl`, checkout redirect URLs |
| Customer payload | `upsert_customer` | one of `email`, `customerEmail`, `name`, `clientId` | `metadata` |
| Subscription payload | `create_subscription` | plan amount/customer fields for your billing flow | `amountUsd`, `customerEmail`, `label`, `billingIntervalUnit`, `billingIntervalCount`, `startAt`, `sendPaymentRequestEmail` |
| POS terminal payload | `create_pos_terminal`, `update_pos_terminal` | `name` | `pin`, `status`, `allowedAssets`, `emailCollectionMode`, `catalogEnabled`, `displaySettings`, `metadata` |
| Product payload | `create_product`, `update_product` | `name` | `description`, `sku`, `status`, `productType`, `basePriceUsd`, `shopSlug`, `images`, `variants`, `taxRates`, `metadata` |
| Shop payload | `update_shop` | none | `slug`, `status`, `displayCurrency`, `checkoutMode`, `billingDetailsRequired`, shipping fields, links, SEO, tracking, branding |
| Branding payload | `update_branding` | none | brand name, support email, website URL, theme colors, `paymentLinkDomain`, `emailSendingDomain` |
| Bookkeeping invoice payload | `create_bookkeeping_invoice`, `update_bookkeeping_invoice` | none; blank invoices are allowed as drafts | `invoiceNumber`, `status`, `paymentStatus`, `currency`, `issueDate`, `dueDate`, `counterparty`, `lineItems`, `documentIds` |
| Bookkeeping expense payload | `create_bookkeeping_expense`, `create_bookkeeping_expense_from_activity`, `update_bookkeeping_expense` | none; amount defaults to zero if no activity is used | `amount`, `currency`, `category`, `incurredOn`, `walletActivityEventId`, `walletActivityEventKey`, `counterparty`, `metadata` |
| Bookkeeping document upload | `upload_bookkeeping_document` | `file` | `fileName`, `documentType`, `invoiceId`, `expenseId` |
| Bookkeeping reconciliation payload | `create_bookkeeping_reconciliation` | one target and one source | target: `invoiceId` or `expenseId`; source: payment link/session, subscription cycle, or wallet activity; `amount`, `assetSymbol` |
| Dictionary payload | product downloads, shop builder, coupons, settings, customer portal | route-specific | these advanced surfaces stay open-ended while their server schemas evolve |

## Errors

API calls raise `MakePayError` with `status` and `response_body` fields.

```python
from makepay import MakePayError

try:
    makepay.get_payment_link("PAYMENT_LINK_UID")
except MakePayError as error:
    print(error.status, error.response_body)
```

## Release Notes

The package is published as `makepay` on PyPI. Version `0.3.0` aligns the
Python surface with the MakePay JavaScript SDK `0.3.0`.
