Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

Waffo Python SDK

English | 中文

PyPI version Python Version License: MIT

Official Python SDK for Waffo Payment Platform, providing typed access to payments, refunds, subscriptions, subscription changes, merchant configuration, payment method configuration, and webhook signature verification.

Latest Release Highlights

  • Subscription update API: Added subscription.update() with amount, trialPeriodAmount, and scheduledAmounts support.
  • Scheduled amount models: Added generated scheduled amount fields across subscription create, change, update, and inquiry models.
  • Contract hardening: Added order capture timestamp auto-injection and expanded schema field coverage.

Introduction

Core Features

  • Global Payments: Create, query, cancel, and refund payment orders.
  • Subscription Management: Create, query, cancel, manage, and change subscriptions.
  • Webhook Handling: Verify Waffo signatures and route notification callbacks.
  • Typed Models: Pydantic v2 request/response models generated from openapi.json.
  • Secure Defaults: RSA request signing, response signature verification, explicit environment selection, and configurable timeouts.

Table of Contents

Requirements

  • Python 3.9+
  • pip

Version Compatibility

Python Version Support Status
3.13 Fully Supported
3.12 Fully Supported
3.11 Fully Supported (Recommended)
3.10 Fully Supported
3.9 Fully Supported
< 3.9 Not Supported

Installation

python -m pip install "waffo==0.1.0b0"
# or install the latest beta/pre-release
python -m pip install --pre waffo

Quick Start

1. Initialize the SDK

from waffo import Environment, Waffo, WaffoConfig

config = WaffoConfig(
    api_key="your-api-key",
    private_key="your-base64-encoded-private-key",
    waffo_public_key="waffo-public-key",
    merchant_id="your-merchant-id",
    environment=Environment.SANDBOX,
)

waffo = Waffo(config)

2. Create a Payment Order

from uuid import uuid4

payment_request_id = uuid4().hex

response = waffo.order().create(
    {
        "paymentRequestId": payment_request_id,
        "merchantOrderId": f"ORDER_{payment_request_id}",
        "orderCurrency": "HKD",
        "orderAmount": "100.00",
        "orderDescription": "Test Product",
        "notifyUrl": "https://your-site.com/webhook",
        "userInfo": {
            "userId": "user_123",
            "userEmail": "user@example.com",
            "userTerminal": "WEB",
        },
        "paymentInfo": {
            "productName": "ONE_TIME_PAYMENT",
        },
        "goodsInfo": {
            "goodsUrl": "https://your-site.com/product/001",
            "goodsName": "Test Product",
        },
    }
)

if response.is_success():
    data = response.get_data()
    print("Redirect action:", data.order_action if data else None)
    print("Acquiring Order ID:", data.acquiring_order_id if data else None)
else:
    print("Error:", response.get_message())

3. Query Order Status

response = waffo.order().inquiry({"paymentRequestId": payment_request_id})

if response.is_success():
    data = response.get_data()
    print("Order Status:", data.order_status if data else None)
    print("Order Amount:", data.order_amount if data else None)

Configuration

Full Configuration Options

from waffo import Environment, Waffo, WaffoConfig

waffo = Waffo(
    WaffoConfig(
        api_key="your-api-key",
        private_key="your-base64-private-key",
        waffo_public_key="waffo-public-key",
        environment=Environment.SANDBOX,
        merchant_id="your-merchant-id",
        connect_timeout=10000,
        read_timeout=30000,
    )
)

Environment Variables

export WAFFO_API_KEY=your-api-key
export WAFFO_PRIVATE_KEY=your-private-key
export WAFFO_PUBLIC_KEY=waffo-public-key
export WAFFO_ENVIRONMENT=SANDBOX
export WAFFO_MERCHANT_ID=your-merchant-id
from waffo import Waffo

waffo = Waffo.from_env()

Environment URLs

Environment Base URL Description
SANDBOX https://api-sandbox.waffo.com Test environment
PRODUCTION https://api.waffo.com Production environment

Important: Environment must be explicitly specified. SDKs do not default to any environment to prevent accidental requests to wrong environments.

Request-Level Configuration

from waffo import RequestOptions

response = waffo.order().create(
    params,
    RequestOptions(connect_timeout=10000, read_timeout=30000),
)

API Usage

Order Management

Method Description
order().create() Create a payment order
order().inquiry() Query order status
order().cancel() Cancel an order
order().refund() Create an order refund
order().capture() Capture an authorized payment

Subscription Management

Method Description
subscription().create() Create a subscription
subscription().inquiry() Query a subscription
subscription().cancel() Cancel a subscription
subscription().manage() Get a subscription management URL
subscription().change() Upgrade or downgrade a subscription
subscription().change_inquiry() Query subscription change status

Subscription Change (Upgrade/Downgrade)

Change an existing subscription to a new plan (upgrade or downgrade).

Change Subscription

from uuid import uuid4

from waffo import WaffoUnknownStatusError

subscription_request = uuid4().hex
origin_subscription_request = "original-subscription-request-id"

try:
    response = waffo.subscription().change(
        {
            "subscriptionRequest": subscription_request,
            "originSubscriptionRequest": origin_subscription_request,
            "remainingAmount": "50.00",
            "currency": "HKD",
            "notifyUrl": "https://your-site.com/webhook/subscription",
            "productInfoList": [
                {
                    "description": "Annual Premium Subscription (12 months)",
                    "periodType": "MONTHLY",
                    "periodInterval": "12",
                    "amount": "999.00",
                }
            ],
            "userInfo": {
                "userId": "user_123",
                "userEmail": "user@example.com",
            },
            "goodsInfo": {
                "goodsId": "GOODS_PREMIUM",
                "goodsName": "Premium Plan",
            },
            "paymentInfo": {
                "productName": "SUBSCRIPTION",
            },
        }
    )

    if response.is_success():
        data = response.get_data()
        print("Change Status:", data.subscription_change_status if data else None)
        print("New Subscription ID:", data.subscription_id if data else None)
except WaffoUnknownStatusError as exc:
    print("Unknown status, query later or wait for webhook:", exc)

Subscription Change Status Values

Status Description
IN_PROGRESS Change is being processed
AUTHORIZATION_REQUIRED User needs to authorize the change (redirect to webUrl)
SUCCESS Change completed successfully
CLOSED Change was closed (timeout or failed)

Query Subscription Change Status

response = waffo.subscription().change_inquiry(
    {
        "subscriptionRequest": "new-subscription-request-id",
        "originSubscriptionRequest": "original-subscription-request-id",
    }
)

if response.is_success():
    data = response.get_data()
    print("Change Status:", data.subscription_change_status if data else None)
    print("New Subscription ID:", data.subscription_id if data else None)
    print("Remaining Amount:", data.remaining_amount if data else None)
    print("Currency:", data.currency if data else None)

Refund Query

response = waffo.refund().inquiry({"refundRequestId": "refund_request_id"})

Merchant Configuration

response = waffo.merchant_config().inquiry({})

Query Available Payment Methods

The payMethodDetails response includes the payment method category, supported currency, order amount limits, and refund policy. currentStatus can be absent when real-time availability is temporarily unavailable.

# merchant_id is auto-injected from config if not provided
response = waffo.pay_method_config().inquiry()

if response.is_success():
    data = response.get_data()
    for detail in data.pay_method_details if data and data.pay_method_details else []:
        print(
            {
                "name": detail.pay_method_name,
                "type": detail.pay_method_type,
                "country": detail.country,
                "currency": detail.currency,
                "amount_range": [detail.order_amount_min, detail.order_amount_max],
                "refund_allowed": detail.refund_allowed,
                "current_status": detail.current_status,
            }
        )
else:
    print("Pay method config inquiry failed:", response.get_code(), response.get_message())

Wallet Address Inquiry (x402)

Inquire the on-chain stablecoin receiving address for an x402 payment. The response returns the target network, the on-chain token contract, and the Waffo platform wallet address to send funds to. Phase 1 supports USDC.

# paymentRequestId: unique idempotency key; orderCurrency: Phase 1 supports USDC
# merchantInfo is auto-injected from config if not provided
response = waffo.wallet().inquiry(
    {
        "paymentRequestId": "unique-request-id",
        "orderCurrency": "USDC",
    }
)

if response.is_success():
    data = response.get_data()
    print("Network:", data.network if data else None)  # e.g. eip155:8453 (Base mainnet)
    print("Asset:", data.asset if data else None)       # on-chain token contract address
    print("Pay to:", data.pay_to if data else None)     # Waffo platform receiving wallet address
else:
    print("Wallet inquiry failed:", response.get_code(), response.get_message())

Wallet Inquiry Response Fields

Field Description
network CAIP-2 network id (Phase 1: eip155:8453, Base mainnet)
asset On-chain token contract address for the network + currency
payTo Waffo platform receiving wallet address (send funds here)

Webhook Handling

from fastapi import FastAPI, Header, Request, Response
from waffo import Waffo

app = FastAPI()
waffo = Waffo.from_env()

waffo.webhook().on_payment(
    lambda notification: print(notification.get("result", {}).get("acquiringOrderId"))
)

@app.post("/webhook")
async def webhook(request: Request, x_signature: str | None = Header(default=None)) -> Response:
    body = (await request.body()).decode("utf-8")
    result = waffo.webhook().handle_webhook(body, x_signature)
    return Response(
        content=result.response_body,
        media_type="application/json",
        headers={"X-SIGNATURE": result.response_signature},
        status_code=200 if result.success else 400,
    )

Webhook Notification Types

Event Type Handler Method Description
PAYMENT_NOTIFICATION onPayment() Payment result notification (triggered on every payment attempt, including retries)
REFUND_NOTIFICATION onRefund() Refund result notification
SUBSCRIPTION_STATUS_NOTIFICATION onSubscriptionStatus() Subscription status change notification (triggered when subscription main record status changes)
SUBSCRIPTION_PERIOD_CHANGED_NOTIFICATION onSubscriptionPeriodChanged() Subscription period change notification (final result of each period)
SUBSCRIPTION_CHANGE_NOTIFICATION onSubscriptionChange() Subscription change (upgrade/downgrade) result notification

Subscription Notification Types Explained

Notification Type Trigger Condition Scope Includes Retry Events Typical Use Case
SUBSCRIPTION_STATUS_NOTIFICATION Subscription main record status changes Subscription level No Track subscription lifecycle: first payment success activation (ACTIVE), cancellation (MERCHANT_CANCELLED, CHANNEL_CANCELLED), first payment failure close (CLOSE), etc.
SUBSCRIPTION_PERIOD_CHANGED_NOTIFICATION Subscription period reaches final state Period level No (only final result) Only need final result of each period, no intermediate retry events
SUBSCRIPTION_CHANGE_NOTIFICATION Subscription change (upgrade/downgrade) completes Change request level No (only final result) Track subscription change results: SUCCESS or CLOSED
PAYMENT_NOTIFICATION Every payment order Payment order level Yes (includes all retries) Need complete details of every payment attempt, including failure reasons, timestamps, retry details

Selection Guide:

  • If you only care about subscription activation/cancellation, use SUBSCRIPTION_STATUS_NOTIFICATION
  • If you only care about final renewal result of each period, use SUBSCRIPTION_PERIOD_CHANGED_NOTIFICATION
  • If you only care about subscription change (upgrade/downgrade) final result, use SUBSCRIPTION_CHANGE_NOTIFICATION
  • If you need to track every payment attempt (including retries), use PAYMENT_NOTIFICATION

Subscription Payment Note: Each period's payment (including first payment and renewals) triggers PAYMENT_NOTIFICATION events. You can get subscription-related info (subscriptionId, period, etc.) from subscriptionInfo.

Subscription Change (Upgrade/Downgrade) Webhook Note: When a subscription change is processed, the following notifications are triggered:

  • SUBSCRIPTION_CHANGE_NOTIFICATION: When subscription change completes (SUCCESS or CLOSED)
  • SUBSCRIPTION_STATUS_NOTIFICATION: When original subscription status changes to MERCHANT_CANCELLED
  • SUBSCRIPTION_STATUS_NOTIFICATION: When new subscription status changes to ACTIVE
  • PAYMENT_NOTIFICATION: If upgrade requires additional payment (price difference)

Webhook Notification Payload Examples

The following examples show the actual payload structure for each notification type.

PAYMENT_NOTIFICATION

{
  "eventType": "PAYMENT_NOTIFICATION",
  "result": {
    "acquiringOrderId": "A2026xxxxxxxxxxxxxxxxxxxx",
    "orderStatus": "PAY_SUCCESS",
    "orderAmount": "109.00",
    "orderCurrency": "USD",
    "finalDealAmount": "109.00",
    "userCurrency": "USD",
    "orderDescription": "Sample Product",
    "orderRequestedAt": "2026-02-28T10:05:58.000Z",
    "orderCompletedAt": "2026-02-28T10:06:10.000Z",
    "orderUpdatedAt": "2026-02-28T10:06:10.000Z",
    "refundExpiryAt": "2026-08-26T23:59:59.999Z",
    "userInfo": {
      "userId": "user@example.com",
      "userEmail": "user@example.com"
    },
    "merchantInfo": {
      "merchantId": "YOUR_MERCHANT_ID"
    },
    "goodsInfo": {
      "goodsId": "goods_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
      "goodsName": "Sample Product"
    },
    "addressInfo": {},
    "paymentInfo": {
      "productName": "SUBSCRIPTION",
      "payMethodType": "CREDITCARD",
      "payMethodName": "CC_VISA",
      "payMethodProperties": "{\"cardToken\":\"CARD_TOKEN_XXXXXXXXXXXXXXXXXXXX\",\"cardTransactionType\":\"CIT\"}",
      "payMethodResponse": "{\"maskCardData\":\"XXXX42****XX4242\"}"
    },
    "subscriptionInfo": {
      "subscriptionId": "SC2026xxxxxxxxxxxxxxxxxxxxxxxxxx",
      "subscriptionRequest": "sub_req_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
      "merchantRequest": "sub_req_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
      "period": "1"
    },
    "cancelRedirectUrl": "https://YOUR_DOMAIN/checkout/YOUR_CHECKOUT_ID"
  }
}

For x402 stablecoin payments, PAYMENT_NOTIFICATION.result also includes x402Info with x402Request, paymentSignatureHeader, and x402Response.

SUBSCRIPTION_STATUS_NOTIFICATION / SUBSCRIPTION_PERIOD_CHANGED_NOTIFICATION

These two notification types share the same payload structure:

{
  "eventType": "SUBSCRIPTION_STATUS_NOTIFICATION",
  "result": {
    "subscriptionId": "SC2026xxxxxxxxxxxxxxxxxxxxxxxxxx",
    "subscriptionRequest": "sub_req_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "merchantSubscriptionId": "sub_req_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "subscriptionStatus": "ACTIVE",
    "currency": "USD",
    "userCurrency": "USD",
    "amount": "109.00",
    "requestedAt": "2026-02-28T10:05:58.000Z",
    "updatedAt": "2026-02-28T10:06:10.000Z",
    "userInfo": {
      "userId": "user@example.com",
      "userEmail": "user@example.com"
    },
    "merchantInfo": {
      "merchantId": "YOUR_MERCHANT_ID"
    },
    "goodsInfo": {
      "goodsId": "goods_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
      "goodsName": "Sample Product"
    },
    "productInfo": {
      "periodType": "MONTHLY",
      "periodInterval": "1",
      "currentPeriod": "1",
      "startDateTime": "2026-02-28T10:06:10.000Z",
      "nextPaymentDateTime": "2026-03-28T10:06:10.000Z",
      "description": "Sample Product"
    },
    "paymentInfo": {
      "productName": "SUBSCRIPTION",
      "payMethodType": "CREDITCARD",
      "payMethodName": "CC_VISA",
      "payMethodProperties": "{}"
    },
    "paymentDetails": [
      {
        "period": "1",
        "acquiringOrderId": "A2026xxxxxxxxxxxxxxxxxxxx",
        "orderAmount": "109.00",
        "orderCurrency": "USD",
        "orderStatus": "PAY_SUCCESS",
        "orderUpdatedAt": "2026-02-28T10:06:10.000Z"
      }
    ]
  }
}

Payment Method Types

payMethodType Reference

Type Description Example payMethodName
CREDITCARD Credit Card CC_VISA, CC_MASTERCARD, CC_AMEX, CC_JCB, etc.
DEBITCARD Debit Card DC_VISA, DC_MASTERCARD, DC_ELO, etc.
EWALLET E-Wallet GCASH, DANA, PROMPTPAY, GRABPAY, etc.
VA Virtual Account BCA, BNI, BRI, MANDIRI, etc.
APPLEPAY Apple Pay APPLEPAY
GOOGLEPAY Google Pay GOOGLEPAY

Usage Examples

// Specify type only, let user choose on checkout page
paymentInfo: {
  payMethodType: 'CREDITCARD',
}

// Specify exact payment method
paymentInfo: {
  payMethodType: 'CREDITCARD',
  payMethodName: 'CC_VISA',
}

// Combine multiple types
paymentInfo: {
  payMethodType: 'CREDITCARD,DEBITCARD',
}

// E-wallet with specific channel
paymentInfo: {
  payMethodType: 'EWALLET',
  payMethodName: 'GCASH',
}

Note: For available ProductName, PayMethodType, PayMethodName values, merchants can log in to Waffo Portal to view contracted payment methods (Home → Service → Pay-in).

Advanced Configuration

Timeout Configuration Recommendations

Operation Type Connect Timeout Read Timeout Notes
Create Order 5s 30s Recommended
Create Subscription 5s 30s Recommended
Refund Operation 5s 30s Recommended
Query Operations 5s 15s Can be shorter

Connection Pool Recommendations

Scenario Max Connections Max Per Route Notes
Low Traffic (< 10 QPS) 20 10 Default config sufficient
Medium Traffic (10-100 QPS) 50 20 Consider using OkHttp
High Traffic (> 100 QPS) 100-200 50 Consider Apache HttpClient

Instance Reuse

Create one Waffo instance during application startup and reuse it across requests.

Handling New API Fields (ExtraParams)

When Waffo API adds new fields that are not yet defined in the SDK, you can use the ExtraParams feature to access these fields without waiting for an SDK update.

Reading Unknown Fields from Responses

Sending Extra Fields in Requests

Important Notes

Upgrade SDK Promptly

ExtraParams is designed as a temporary solution for accessing new API fields before SDK updates.

Best Practices:

  1. Check SDK release notes regularly for new field support
  2. Once SDK officially supports the field, migrate from getExtraParam("field") to the official getter (e.g., getField())
  3. The SDK logs a warning when you use getExtraParam() on officially supported fields

Why migrate?

  • Official getters provide type safety
  • Better IDE auto-completion and documentation
  • Reduced risk of typos in field names

Error Handling

Error Code Classification

Error codes are classified by first letter:

Prefix Category Description
S SDK Internal Error SDK client internal error such as network timeout, signing failure, etc.
A Merchant Related Parameter, signature, permission, contract issues on merchant side
B User Related User status, balance, authorization issues
C System Related Waffo system or payment channel issues
D Risk Related Risk control rejection
E Unknown Status Server returned unknown status

Complete Error Code Table

SDK Internal Errors (Sxxxx)

Code Description Exception Type Handling Suggestion
S0001 Network Error WaffoUnknownStatusError Status unknown, need to query order to confirm
S0002 Invalid Public Key WaffoError Check if public key is valid Base64 encoded X509 format
S0003 RSA Signing Failed WaffoError Check if private key format is correct
S0004 Response Signature Verification Failed ApiResponse.error() Check Waffo public key config, contact Waffo
S0005 Request Serialization Failed ApiResponse.error() Check request parameter format
S0006 SDK Unknown Error ApiResponse.error() Check logs, contact technical support
S0007 Invalid Private Key WaffoError Check if private key is valid Base64 encoded PKCS8 format

Important: S0001 and E0001 (returned by server) indicate unknown status. Do not close order directly! Should call query API or wait for webhook to confirm actual status.

Merchant Related Errors (Axxxxx)

Code Description HTTP Status
0 Success 200
A0001 Invalid API Key 401
A0002 Invalid Signature 401
A0003 Parameter Validation Failed 400
A0004 Insufficient Permission 401
A0005 Merchant Limit Exceeded 400
A0006 Merchant Status Abnormal 400
A0007 Unsupported Transaction Currency 400
A0008 Transaction Amount Exceeded 400
A0009 Order Not Found 400
A0010 Merchant Contract Does Not Allow This Operation 400
A0011 Idempotent Parameter Mismatch 400
A0012 Merchant Account Insufficient Balance 400
A0013 Order Already Paid, Cannot Cancel 400
A0014 Refund Rules Do Not Allow Refund 400
A0015 Payment Channel Does Not Support Cancel 400
A0016 Payment Channel Rejected Cancel 400
A0017 Payment Channel Does Not Support Refund 400
A0018 Payment Method Does Not Match Merchant Contract 400
A0019 Cannot Refund Due to Chargeback Dispute 400
A0020 Payment Amount Exceeds Single Transaction Limit 400
A0021 Cumulative Payment Amount Exceeds Daily Limit 400
A0022 Multiple Products Exist, Need to Specify Product Name 400
A0023 Token Expired, Cannot Create Order 400
A0024 Exchange Rate Expired, Cannot Process Order 400
A0026 Unsupported Checkout Language 400
A0027 Refund Count Reached Limit (50 times) 400
A0029 Invalid Card Data Provided by Merchant 400
A0030 Card BIN Not Found 400
A0031 Unsupported Card Scheme or Card Type 400
A0032 Invalid Payment Token Data 400
A0033 Multiple Payment Methods with Same Name, Need to Specify Country 400
A0034 Order Expiry Time Provided by Merchant Has Passed 400
A0035 Current Order Does Not Support Capture Operation 400
A0036 Current Order Status Does Not Allow Capture Operation 400
A0037 User Payment Token Invalid or Expired 400
A0038 MIT Transaction Requires Verified User Payment Token 400
A0039 Order Already Refunded by Chargeback Prevention Service 400
A0040 Order Cannot Be Created Concurrently 400
A0045 MIT Transaction Cannot Process, tokenId Status Unverified 400

User Related Errors (Bxxxxx)

Code Description HTTP Status
B0001 User Status Abnormal 400
B0002 User Limit Exceeded 400
B0003 User Insufficient Balance 400
B0004 User Did Not Pay Within Timeout 400
B0005 User Authorization Failed 400
B0006 Invalid Phone Number 400
B0007 Invalid Email Format 400

System Related Errors (Cxxxxx)

Code Description HTTP Status
C0001 System Error 500
C0002 Merchant Contract Invalid 500
C0003 Order Status Invalid, Cannot Continue Processing 500
C0004 Order Information Mismatch 500
C0005 Payment Channel Rejected 503
C0006 Payment Channel Error 503
C0007 Payment Channel Under Maintenance 503

Risk Related Errors (Dxxxxx)

Code Description HTTP Status
D0001 Risk Control Rejected 406

Unknown Status Errors (Exxxxx)

Code Description HTTP Status
E0001 Unknown Status (Need to query or wait for callback) 500

Note: When receiving E0001 error code, it indicates transaction status is unknown. Do not close order directly, should call query API to confirm actual status, or wait for webhook callback notification.

Development

python -m pip install -e ".[dev]"
ruff check src tests examples
mypy src/waffo
pytest tests/unit -q

Support

License

MIT

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

waffo-0.4.0b0.tar.gz (84.9 kB view details)

Uploaded Source

Built Distribution

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

waffo-0.4.0b0-py3-none-any.whl (43.4 kB view details)

Uploaded Python 3

File details

Details for the file waffo-0.4.0b0.tar.gz.

File metadata

  • Download URL: waffo-0.4.0b0.tar.gz
  • Upload date:
  • Size: 84.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for waffo-0.4.0b0.tar.gz
Algorithm Hash digest
SHA256 2858db9d55d5c15b7f45cca942b2f1c47bb722ee00fd019e971d59b0e4060db4
MD5 9bccc468ae003a3471d8d0df39fbd7cc
BLAKE2b-256 7898a096a2cc35cd460fbef0ff4262980ac511d0f75f4d1b7495bb8caf6caede

See more details on using hashes here.

Provenance

The following attestation bundles were made for waffo-0.4.0b0.tar.gz:

Publisher: publish-python.yml on waffo-com/waffo-sdk

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

File details

Details for the file waffo-0.4.0b0-py3-none-any.whl.

File metadata

  • Download URL: waffo-0.4.0b0-py3-none-any.whl
  • Upload date:
  • Size: 43.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for waffo-0.4.0b0-py3-none-any.whl
Algorithm Hash digest
SHA256 1e33335b62fa6abcbbba609befd09ff167ed7b2e6a6465d29d1595cec66cd925
MD5 245752f57711b50db94fb31ba9836fdc
BLAKE2b-256 a2c5dbd1cd661869043295c80c75a36758a1560e9a9b37b6255f1ef5af1d49a0

See more details on using hashes here.

Provenance

The following attestation bundles were made for waffo-0.4.0b0-py3-none-any.whl:

Publisher: publish-python.yml on waffo-com/waffo-sdk

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

Release history Release notifications | RSS feed

This release

0.4.0b0 This release

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page