From 0df7306cf7b53d27a0ed4345a17728cdd02e6e8c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 15 Jun 2026 17:29:35 +0000 Subject: [PATCH] feat: sync SDK with API changes --- pyproject.toml | 2 +- src/blindpay/__init__.py | 10 +- src/blindpay/client.py | 41 ++- src/blindpay/resources/__init__.py | 6 + src/blindpay/resources/customers/__init__.py | 47 +++ src/blindpay/resources/customers/customers.py | 314 ++++++++++++++++++ src/blindpay/resources/limits/__init__.py | 21 ++ src/blindpay/resources/limits/limits.py | 58 ++++ src/blindpay/resources/ownership/__init__.py | 17 + src/blindpay/resources/ownership/ownership.py | 49 +++ src/blindpay/resources/payins/payins.py | 2 + src/blindpay/resources/payouts/payouts.py | 3 + src/blindpay/resources/upload/__init__.py | 4 + src/blindpay/resources/upload/upload.py | 17 +- src/blindpay/types.py | 16 + 15 files changed, 603 insertions(+), 4 deletions(-) create mode 100644 src/blindpay/resources/customers/__init__.py create mode 100644 src/blindpay/resources/customers/customers.py create mode 100644 src/blindpay/resources/limits/__init__.py create mode 100644 src/blindpay/resources/limits/limits.py create mode 100644 src/blindpay/resources/ownership/__init__.py create mode 100644 src/blindpay/resources/ownership/ownership.py diff --git a/pyproject.toml b/pyproject.toml index 2bc800b..415a080 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "blindpay" -version = "2.2.0" +version = "2.3.0" description = "Official Python SDK for the Blindpay API — Global payments infrastructure" readme = "README.md" authors = [{ name = "Blindpay", email = "alves@blindpay.com" }] diff --git a/src/blindpay/__init__.py b/src/blindpay/__init__.py index 2372588..9ee0a57 100644 --- a/src/blindpay/__init__.py +++ b/src/blindpay/__init__.py @@ -1,9 +1,11 @@ -__version__ = "2.2.0" +__version__ = "2.3.0" from ._internal.exceptions import BlindPayError from .client import BlindPay, BlindPaySync from .types import ( AccountClass, + AipriseDocumentType, + ApprovalRate, BankAccountType, BankingPartner, BlindpayApiResponse, @@ -13,6 +15,7 @@ Currency, CurrencyType, ErrorResponse, + ManualExecutionStatus, Network, PaginationMetadata, PaginationParams, @@ -27,6 +30,7 @@ TrackingTransaction, TransactionDocumentType, TransactionStatus, + WebhookEvent, ) __all__ = [ @@ -34,11 +38,14 @@ "BlindPaySync", "BlindPayError", "AccountClass", + "AipriseDocumentType", + "ApprovalRate", "BankAccountType", "BankingPartner", "Country", "Currency", "CurrencyType", + "ManualExecutionStatus", "Network", "PaymentMethod", "Rail", @@ -46,6 +53,7 @@ "StablecoinToken", "TransactionDocumentType", "TransactionStatus", + "WebhookEvent", "BlindpayApiResponse", "BlindpayErrorResponse", "BlindpaySuccessResponse", diff --git a/src/blindpay/client.py b/src/blindpay/client.py index 78c3c57..2bd55fd 100644 --- a/src/blindpay/client.py +++ b/src/blindpay/client.py @@ -17,8 +17,11 @@ CustodialWalletsResource, CustodialWalletsResourceSync, ) + from blindpay.resources.customers.customers import CustomersResource, CustomersResourceSync from blindpay.resources.fees.fees import FeesResource, FeesResourceSync from blindpay.resources.instances.instances import InstancesResource, InstancesResourceSync + from blindpay.resources.limits.limits import LimitsResource, LimitsResourceSync + from blindpay.resources.ownership.ownership import OwnershipResource, OwnershipResourceSync from blindpay.resources.partner_fees.partner_fees import PartnerFeesResource, PartnerFeesResourceSync from blindpay.resources.payins.payins import PayinsResource, PayinsResourceSync from blindpay.resources.payins.quotes import PayinQuotesResource, PayinQuotesResourceSync @@ -39,7 +42,7 @@ from blindpay.resources.wallets.offramp import OfframpWalletsResource, OfframpWalletsResourceSync from blindpay.resources.webhooks.webhooks import WebhookEndpointsResource, WebhookEndpointsResourceSync -__version__ = "2.2.0" +__version__ = "2.3.0" T = TypeVar("T") @@ -283,6 +286,12 @@ def available(self) -> "AvailableResource": def instances(self) -> _InstancesNamespace: return _InstancesNamespace(self._instance_id, self._api) + @cached_property + def ownership(self) -> "OwnershipResource": + from blindpay.resources.ownership import create_ownership_resource + + return create_ownership_resource(self._instance_id, self._api) + @cached_property def partner_fees(self) -> "PartnerFeesResource": from blindpay.resources.partner_fees import create_partner_fees_resource @@ -325,12 +334,24 @@ def transfers(self) -> "TransfersResource": return create_transfers_resource(self._instance_id, self._api) + @cached_property + def customers(self) -> "CustomersResource": + from blindpay.resources.customers import create_customers_resource + + return create_customers_resource(self._instance_id, self._api) + @cached_property def fees(self) -> "FeesResource": from blindpay.resources.fees import create_fees_resource return create_fees_resource(self._instance_id, self._api) + @cached_property + def limits(self) -> "LimitsResource": + from blindpay.resources.limits import create_limits_resource + + return create_limits_resource(self._instance_id, self._api) + @cached_property def upload(self) -> "UploadResource": from blindpay.resources.upload import create_upload_resource @@ -513,6 +534,12 @@ def available(self) -> "AvailableResourceSync": def instances(self) -> _InstancesNamespaceSync: return _InstancesNamespaceSync(self._instance_id, self._api) + @cached_property + def ownership(self) -> "OwnershipResourceSync": + from blindpay.resources.ownership import create_ownership_resource_sync + + return create_ownership_resource_sync(self._instance_id, self._api) + @cached_property def partner_fees(self) -> "PartnerFeesResourceSync": from blindpay.resources.partner_fees import create_partner_fees_resource_sync @@ -555,12 +582,24 @@ def transfers(self) -> "TransfersResourceSync": return create_transfers_resource_sync(self._instance_id, self._api) + @cached_property + def customers(self) -> "CustomersResourceSync": + from blindpay.resources.customers import create_customers_resource_sync + + return create_customers_resource_sync(self._instance_id, self._api) + @cached_property def fees(self) -> "FeesResourceSync": from blindpay.resources.fees import create_fees_resource_sync return create_fees_resource_sync(self._instance_id, self._api) + @cached_property + def limits(self) -> "LimitsResourceSync": + from blindpay.resources.limits import create_limits_resource_sync + + return create_limits_resource_sync(self._instance_id, self._api) + @cached_property def upload(self) -> "UploadResourceSync": from blindpay.resources.upload import create_upload_resource_sync diff --git a/src/blindpay/resources/__init__.py b/src/blindpay/resources/__init__.py index 3819881..120006c 100644 --- a/src/blindpay/resources/__init__.py +++ b/src/blindpay/resources/__init__.py @@ -2,8 +2,11 @@ from .available import create_available_resource from .bank_accounts import create_bank_accounts_resource from .custodial_wallets import create_custodial_wallets_resource +from .customers import create_customers_resource from .fees import create_fees_resource from .instances import create_instances_resource +from .limits import create_limits_resource +from .ownership import create_ownership_resource from .partner_fees import create_partner_fees_resource from .payins import create_payin_quotes_resource, create_payins_resource from .payouts import create_payouts_resource @@ -20,9 +23,12 @@ "create_api_keys_resource", "create_available_resource", "create_bank_accounts_resource", + "create_customers_resource", "create_custodial_wallets_resource", "create_fees_resource", "create_instances_resource", + "create_limits_resource", + "create_ownership_resource", "create_partner_fees_resource", "create_payins_resource", "create_payin_quotes_resource", diff --git a/src/blindpay/resources/customers/__init__.py b/src/blindpay/resources/customers/__init__.py new file mode 100644 index 0000000..9b5f4aa --- /dev/null +++ b/src/blindpay/resources/customers/__init__.py @@ -0,0 +1,47 @@ +from .customers import ( + AccountPurpose, + AdditionalInfoItem, + BusinessIndustry, + BusinessType, + CreateCustomerInput, + CreateCustomerResponse, + Customer, + CustomersResource, + CustomersResourceSync, + CustomerType, + EstimatedAnnualRevenue, + IdDocType, + KycType, + ListCustomersResponse, + ProofOfAddressDocType, + PurposeOfTransactions, + SourceOfWealth, + SuccessResponse, + UpdateCustomerInput, + create_customers_resource, + create_customers_resource_sync, +) + +__all__ = [ + "create_customers_resource", + "create_customers_resource_sync", + "AccountPurpose", + "AdditionalInfoItem", + "BusinessIndustry", + "BusinessType", + "CreateCustomerInput", + "CreateCustomerResponse", + "Customer", + "CustomerType", + "CustomersResource", + "CustomersResourceSync", + "EstimatedAnnualRevenue", + "IdDocType", + "KycType", + "ListCustomersResponse", + "ProofOfAddressDocType", + "PurposeOfTransactions", + "SourceOfWealth", + "SuccessResponse", + "UpdateCustomerInput", +] diff --git a/src/blindpay/resources/customers/customers.py b/src/blindpay/resources/customers/customers.py new file mode 100644 index 0000000..1739353 --- /dev/null +++ b/src/blindpay/resources/customers/customers.py @@ -0,0 +1,314 @@ +from typing import Any, Dict, List, Optional +from urllib.parse import urlencode + +from typing_extensions import Literal, TypedDict + +from ..._internal.api_client import InternalApiClient, InternalApiClientSync +from ...types import BlindpayApiResponse, Country, PaginationMetadata, PaginationParams + +# Customer Types +CustomerType = Literal["individual", "business"] +KycType = Literal["light", "standard", "enhanced"] + +ProofOfAddressDocType = Literal[ + "UTILITY_BILL", "BANK_STATEMENT", "RENTAL_AGREEMENT", "TAX_DOCUMENT", "GOVERNMENT_CORRESPONDENCE" +] + +IdDocType = Literal["PASSPORT", "ID_CARD", "DRIVERS"] + +PurposeOfTransactions = Literal[ + "business_transactions", + "charitable_donations", + "investment_purposes", + "payments_to_friends_or_family_abroad", + "personal_or_living_expenses", + "protect_wealth", + "purchase_good_and_services", + "receive_payment_for_freelancing", + "receive_salary", + "other", +] + +AccountPurpose = Literal[ + "charitable_donations", + "ecommerce_retail_payments", + "investment_purposes", + "business_expenses", + "payments_to_friends_or_family_abroad", + "personal_or_living_expenses", + "protect_wealth", + "purchase_goods_and_services", + "receive_payments_for_goods_and_services", + "tax_optimization", + "third_party_money_transmission", + "payroll", + "treasury_management", + "other", +] + +BusinessType = Literal["corporation", "llc", "partnership", "sole_proprietorship", "trust", "non_profit"] + +EstimatedAnnualRevenue = Literal[ + "0_99999", "100000_999999", "1000000_9999999", "10000000_49999999", "50000000_249999999", "250000000_plus" +] + +SourceOfWealth = Literal[ + "business_dividends_or_profits", + "investments", + "asset_sales", + "client_investor_contributions", + "gambling", + "charitable_contributions", + "inheritance", + "affiliate_or_royalty_income", +] + +# Business Industry - abbreviated list (144 values mentioned in changelog) +BusinessIndustry = Literal[ + "technology", + "finance", + "healthcare", + "retail", + "manufacturing", + "agriculture", + "education", + "transportation", + "real_estate", + "consulting", + # ... (This would need to be expanded with all 144 values) +] + + +# Additional Info Item +class AdditionalInfoItem(TypedDict): + key: str + value: str + + +# Main Customer TypedDict +class Customer(TypedDict): + id: str + customer_id: str + type: CustomerType + kyc_type: KycType + email: str + tax_id: Optional[str] + address_line_1: Optional[str] + address_line_2: Optional[str] + city: Optional[str] + state_province_region: Optional[str] + country: Country + postal_code: Optional[str] + ip_address: Optional[str] + image_url: Optional[str] + phone_number: Optional[str] + proof_of_address_doc_type: Optional[ProofOfAddressDocType] + proof_of_address_doc_file: Optional[str] + first_name: Optional[str] + last_name: Optional[str] + date_of_birth: Optional[str] # Using str for unknown type + id_doc_country: Optional[Country] + id_doc_type: Optional[IdDocType] + id_doc_front_file: Optional[str] + id_doc_back_file: Optional[str] + legal_name: Optional[str] + alternate_name: Optional[str] + formation_date: Optional[str] # Using str for date-time + website: Optional[str] + owners: Optional[List[Dict[str, Any]]] # Array of objects + incorporation_doc_file: Optional[str] + proof_of_ownership_doc_file: Optional[str] + source_of_funds_doc_file: Optional[str] + selfie_file: Optional[str] + purpose_of_transactions: Optional[PurposeOfTransactions] + purpose_of_transactions_explanation: Optional[str] + account_purpose: Optional[AccountPurpose] + account_purpose_other: Optional[str] + business_type: Optional[BusinessType] + business_description: Optional[str] + business_industry: Optional[BusinessIndustry] + estimated_annual_revenue: Optional[EstimatedAnnualRevenue] + source_of_wealth: Optional[SourceOfWealth] + publicly_traded: Optional[bool] + occupation: Optional[str] + external_id: Optional[str] + tos_id: Optional[str] + additional_info: Optional[List[AdditionalInfoItem]] + + +# Input/Output Types +class CreateCustomerInput(TypedDict): + type: CustomerType + kyc_type: KycType + email: str + tax_id: Optional[str] + address_line_1: Optional[str] + address_line_2: Optional[str] + city: Optional[str] + state_province_region: Optional[str] + country: Country + postal_code: Optional[str] + ip_address: Optional[str] + image_url: Optional[str] + phone_number: Optional[str] + proof_of_address_doc_type: Optional[ProofOfAddressDocType] + proof_of_address_doc_file: Optional[str] + first_name: Optional[str] + last_name: Optional[str] + date_of_birth: Optional[str] + id_doc_country: Optional[Country] + id_doc_type: Optional[IdDocType] + id_doc_front_file: Optional[str] + id_doc_back_file: Optional[str] + legal_name: Optional[str] + alternate_name: Optional[str] + formation_date: Optional[str] + website: Optional[str] + owners: Optional[List[Dict[str, Any]]] + incorporation_doc_file: Optional[str] + proof_of_ownership_doc_file: Optional[str] + source_of_funds_doc_file: Optional[str] + selfie_file: Optional[str] + purpose_of_transactions: Optional[PurposeOfTransactions] + purpose_of_transactions_explanation: Optional[str] + account_purpose: Optional[AccountPurpose] + account_purpose_other: Optional[str] + business_type: Optional[BusinessType] + business_description: Optional[str] + business_industry: Optional[BusinessIndustry] + estimated_annual_revenue: Optional[EstimatedAnnualRevenue] + source_of_wealth: Optional[SourceOfWealth] + publicly_traded: Optional[bool] + occupation: Optional[str] + external_id: Optional[str] + tos_id: Optional[str] + additional_info: Optional[List[AdditionalInfoItem]] + + +class CreateCustomerResponse(TypedDict): + id: str + customer_id: str + + +class UpdateCustomerInput(TypedDict): + email: str + tax_id: Optional[str] + address_line_1: Optional[str] + address_line_2: Optional[str] + city: Optional[str] + state_province_region: Optional[str] + country: Country + postal_code: Optional[str] + ip_address: Optional[str] + image_url: Optional[str] + phone_number: Optional[str] + proof_of_address_doc_type: Optional[ProofOfAddressDocType] + proof_of_address_doc_file: Optional[str] + first_name: Optional[str] + last_name: Optional[str] + date_of_birth: Optional[str] + id_doc_country: Optional[Country] + id_doc_type: Optional[IdDocType] + id_doc_front_file: Optional[str] + id_doc_back_file: Optional[str] + legal_name: Optional[str] + alternate_name: Optional[str] + formation_date: Optional[str] + website: Optional[str] + owners: Optional[List[Dict[str, Any]]] + incorporation_doc_file: Optional[str] + proof_of_ownership_doc_file: Optional[str] + source_of_funds_doc_file: Optional[str] + selfie_file: Optional[str] + purpose_of_transactions: Optional[PurposeOfTransactions] + purpose_of_transactions_explanation: Optional[str] + account_purpose: Optional[AccountPurpose] + account_purpose_other: Optional[str] + business_type: Optional[BusinessType] + business_description: Optional[str] + business_industry: Optional[BusinessIndustry] + estimated_annual_revenue: Optional[EstimatedAnnualRevenue] + source_of_wealth: Optional[SourceOfWealth] + publicly_traded: Optional[bool] + occupation: Optional[str] + external_id: Optional[str] + tos_id: Optional[str] + additional_info: Optional[List[AdditionalInfoItem]] + + +class ListCustomersResponse(TypedDict): + data: List[Customer] + pagination: PaginationMetadata + + +class SuccessResponse(TypedDict): + success: bool + + +# --- Async resource --- + + +class CustomersResource: + def __init__(self, instance_id: str, client: InternalApiClient): + self._instance_id = instance_id + self._client = client + + async def list(self, params: Optional[PaginationParams] = None) -> BlindpayApiResponse[ListCustomersResponse]: + query_string = "" + if params: + filtered_params = {k: v for k, v in params.items() if v is not None} + if filtered_params: + query_string = f"?{urlencode(filtered_params)}" + return await self._client.get(f"/instances/{self._instance_id}/customers{query_string}") + + async def get(self, customer_id: str) -> BlindpayApiResponse[Customer]: + return await self._client.get(f"/instances/{self._instance_id}/customers/{customer_id}") + + async def create(self, data: CreateCustomerInput) -> BlindpayApiResponse[CreateCustomerResponse]: + return await self._client.post(f"/instances/{self._instance_id}/customers", data) + + async def update(self, customer_id: str, data: UpdateCustomerInput) -> BlindpayApiResponse[SuccessResponse]: + return await self._client.put(f"/instances/{self._instance_id}/customers/{customer_id}", data) + + async def delete(self, customer_id: str) -> BlindpayApiResponse[SuccessResponse]: + return await self._client.delete(f"/instances/{self._instance_id}/customers/{customer_id}") + + +# --- Sync resource --- + + +class CustomersResourceSync: + def __init__(self, instance_id: str, client: InternalApiClientSync): + self._instance_id = instance_id + self._client = client + + def list(self, params: Optional[PaginationParams] = None) -> BlindpayApiResponse[ListCustomersResponse]: + query_string = "" + if params: + filtered_params = {k: v for k, v in params.items() if v is not None} + if filtered_params: + query_string = f"?{urlencode(filtered_params)}" + return self._client.get(f"/instances/{self._instance_id}/customers{query_string}") + + def get(self, customer_id: str) -> BlindpayApiResponse[Customer]: + return self._client.get(f"/instances/{self._instance_id}/customers/{customer_id}") + + def create(self, data: CreateCustomerInput) -> BlindpayApiResponse[CreateCustomerResponse]: + return self._client.post(f"/instances/{self._instance_id}/customers", data) + + def update(self, customer_id: str, data: UpdateCustomerInput) -> BlindpayApiResponse[SuccessResponse]: + return self._client.put(f"/instances/{self._instance_id}/customers/{customer_id}", data) + + def delete(self, customer_id: str) -> BlindpayApiResponse[SuccessResponse]: + return self._client.delete(f"/instances/{self._instance_id}/customers/{customer_id}") + + +# --- Factory functions --- + + +def create_customers_resource(instance_id: str, client: InternalApiClient) -> CustomersResource: + return CustomersResource(instance_id, client) + + +def create_customers_resource_sync(instance_id: str, client: InternalApiClientSync) -> CustomersResourceSync: + return CustomersResourceSync(instance_id, client) diff --git a/src/blindpay/resources/limits/__init__.py b/src/blindpay/resources/limits/__init__.py new file mode 100644 index 0000000..7f4443d --- /dev/null +++ b/src/blindpay/resources/limits/__init__.py @@ -0,0 +1,21 @@ +from .limits import ( + CustomerLimits, + GetCustomerLimitsResponse, + LimitsResource, + LimitsResourceSync, + PayinLimit, + PayoutLimit, + create_limits_resource, + create_limits_resource_sync, +) + +__all__ = [ + "create_limits_resource", + "create_limits_resource_sync", + "CustomerLimits", + "GetCustomerLimitsResponse", + "LimitsResource", + "LimitsResourceSync", + "PayinLimit", + "PayoutLimit", +] diff --git a/src/blindpay/resources/limits/limits.py b/src/blindpay/resources/limits/limits.py new file mode 100644 index 0000000..6612459 --- /dev/null +++ b/src/blindpay/resources/limits/limits.py @@ -0,0 +1,58 @@ +from typing_extensions import TypedDict + +from ..._internal.api_client import InternalApiClient, InternalApiClientSync +from ...types import BlindpayApiResponse + + +class PayinLimit(TypedDict): + daily: float + monthly: float + + +class PayoutLimit(TypedDict): + daily: float + monthly: float + + +class CustomerLimits(TypedDict): + payin: PayinLimit + payout: PayoutLimit + + +class GetCustomerLimitsResponse(TypedDict): + limits: CustomerLimits + + +# --- Async resource --- + + +class LimitsResource: + def __init__(self, instance_id: str, client: InternalApiClient): + self._instance_id = instance_id + self._client = client + + async def get_customer_limits(self, customer_id: str) -> BlindpayApiResponse[GetCustomerLimitsResponse]: + return await self._client.get(f"/instances/{self._instance_id}/limits/customers/{customer_id}") + + +# --- Sync resource --- + + +class LimitsResourceSync: + def __init__(self, instance_id: str, client: InternalApiClientSync): + self._instance_id = instance_id + self._client = client + + def get_customer_limits(self, customer_id: str) -> BlindpayApiResponse[GetCustomerLimitsResponse]: + return self._client.get(f"/instances/{self._instance_id}/limits/customers/{customer_id}") + + +# --- Factory functions --- + + +def create_limits_resource(instance_id: str, client: InternalApiClient) -> LimitsResource: + return LimitsResource(instance_id, client) + + +def create_limits_resource_sync(instance_id: str, client: InternalApiClientSync) -> LimitsResourceSync: + return LimitsResourceSync(instance_id, client) diff --git a/src/blindpay/resources/ownership/__init__.py b/src/blindpay/resources/ownership/__init__.py new file mode 100644 index 0000000..ebd0db4 --- /dev/null +++ b/src/blindpay/resources/ownership/__init__.py @@ -0,0 +1,17 @@ +from .ownership import ( + MigrateInstanceOwnershipInput, + MigrateInstanceOwnershipResponse, + OwnershipResource, + OwnershipResourceSync, + create_ownership_resource, + create_ownership_resource_sync, +) + +__all__ = [ + "create_ownership_resource", + "create_ownership_resource_sync", + "MigrateInstanceOwnershipInput", + "MigrateInstanceOwnershipResponse", + "OwnershipResource", + "OwnershipResourceSync", +] diff --git a/src/blindpay/resources/ownership/ownership.py b/src/blindpay/resources/ownership/ownership.py new file mode 100644 index 0000000..f1193d1 --- /dev/null +++ b/src/blindpay/resources/ownership/ownership.py @@ -0,0 +1,49 @@ +from typing_extensions import TypedDict + +from ..._internal.api_client import InternalApiClient, InternalApiClientSync +from ...types import BlindpayApiResponse + + +class MigrateInstanceOwnershipInput(TypedDict): + user_id: str + + +class MigrateInstanceOwnershipResponse(TypedDict): + success: bool + + +# --- Async resource --- + + +class OwnershipResource: + def __init__(self, instance_id: str, client: InternalApiClient): + self._instance_id = instance_id + self._client = client + + async def migrate( + self, data: MigrateInstanceOwnershipInput + ) -> BlindpayApiResponse[MigrateInstanceOwnershipResponse]: + return await self._client.post(f"/instances/{self._instance_id}/ownership", data) + + +# --- Sync resource --- + + +class OwnershipResourceSync: + def __init__(self, instance_id: str, client: InternalApiClientSync): + self._instance_id = instance_id + self._client = client + + def migrate(self, data: MigrateInstanceOwnershipInput) -> BlindpayApiResponse[MigrateInstanceOwnershipResponse]: + return self._client.post(f"/instances/{self._instance_id}/ownership", data) + + +# --- Factory functions --- + + +def create_ownership_resource(instance_id: str, client: InternalApiClient) -> OwnershipResource: + return OwnershipResource(instance_id, client) + + +def create_ownership_resource_sync(instance_id: str, client: InternalApiClientSync) -> OwnershipResourceSync: + return OwnershipResourceSync(instance_id, client) diff --git a/src/blindpay/resources/payins/payins.py b/src/blindpay/resources/payins/payins.py index 2f7ed59..c975679 100644 --- a/src/blindpay/resources/payins/payins.py +++ b/src/blindpay/resources/payins/payins.py @@ -4,6 +4,7 @@ from ..._internal.api_client import InternalApiClient, InternalApiClientSync from ...types import ( BlindpayApiResponse, + ManualExecutionStatus, Network, PaginationMetadata, PaginationParams, @@ -96,6 +97,7 @@ class Payin(TypedDict): pse_payment_link: Optional[str] pse_tax_id: Optional[str] partner_fee_id: Optional[str] + manual_execution_status: Optional[ManualExecutionStatus] class ListPayinsInput(PaginationParams): diff --git a/src/blindpay/resources/payouts/payouts.py b/src/blindpay/resources/payouts/payouts.py index b8db790..ee03f31 100644 --- a/src/blindpay/resources/payouts/payouts.py +++ b/src/blindpay/resources/payouts/payouts.py @@ -96,6 +96,9 @@ class Payout(TypedDict): ted_bank_code: Optional[str] ted_branch_code: Optional[str] ted_cpf_cnpj: Optional[str] + billing_fee_amount: Optional[float] + cpn_payment_id: Optional[str] + sender_legal_name: Optional[str] class ListPayoutsInput(PaginationParams, total=False): diff --git a/src/blindpay/resources/upload/__init__.py b/src/blindpay/resources/upload/__init__.py index e3eab79..dce346c 100644 --- a/src/blindpay/resources/upload/__init__.py +++ b/src/blindpay/resources/upload/__init__.py @@ -1,4 +1,6 @@ from .upload import ( + UploadAnalyzeInput, + UploadAnalyzeOutput, UploadBucket, UploadInput, UploadResource, @@ -11,6 +13,8 @@ __all__ = [ "create_upload_resource", "create_upload_resource_sync", + "UploadAnalyzeInput", + "UploadAnalyzeOutput", "UploadBucket", "UploadInput", "UploadResource", diff --git a/src/blindpay/resources/upload/upload.py b/src/blindpay/resources/upload/upload.py index cce0f12..00bd358 100644 --- a/src/blindpay/resources/upload/upload.py +++ b/src/blindpay/resources/upload/upload.py @@ -1,7 +1,7 @@ from typing_extensions import Literal, TypedDict from ..._internal.api_client import InternalApiClient, InternalApiClientSync -from ...types import BlindpayApiResponse +from ...types import ApprovalRate, BlindpayApiResponse UploadBucket = Literal["avatar", "onboarding", "limit_increase"] @@ -15,6 +15,15 @@ class UploadResponse(TypedDict): url: str +class UploadAnalyzeInput(TypedDict): + file: str + + +class UploadAnalyzeOutput(TypedDict): + approval_rate: ApprovalRate + description: str + + class UploadResource: def __init__(self, client: InternalApiClient): self._client = client @@ -22,6 +31,9 @@ def __init__(self, client: InternalApiClient): async def create(self, data: UploadInput) -> BlindpayApiResponse[UploadResponse]: return await self._client.post("/upload", data) + async def analyze(self, data: UploadAnalyzeInput) -> BlindpayApiResponse[UploadAnalyzeOutput]: + return await self._client.post("/upload/analyze", data) + class UploadResourceSync: def __init__(self, client: InternalApiClientSync): @@ -30,6 +42,9 @@ def __init__(self, client: InternalApiClientSync): def create(self, data: UploadInput) -> BlindpayApiResponse[UploadResponse]: return self._client.post("/upload", data) + def analyze(self, data: UploadAnalyzeInput) -> BlindpayApiResponse[UploadAnalyzeOutput]: + return self._client.post("/upload/analyze", data) + def create_upload_resource(client: InternalApiClient) -> UploadResource: return UploadResource(client) diff --git a/src/blindpay/types.py b/src/blindpay/types.py index 5e85ffa..64c1baa 100644 --- a/src/blindpay/types.py +++ b/src/blindpay/types.py @@ -392,3 +392,19 @@ class TrackingPartnerFee(TypedDict): PaymentMethod = Literal["ach", "wire", "pix", "spei", "transfers", "pse", "international_swift", "rtp", "ted"] KycStatus = Literal["awaiting_contract", "compliance_request"] + +AipriseDocumentType = Literal[ + "ADDRESS_PROOF_DOCUMENT", + "BANK_STATEMENT_DOCUMENT", + "OTHER", + "SOURCE_OF_FUNDS_DOCUMENT", + "TAX_CERTIFICATE", + "USER_SELFIE", + "VISA_DOCUMENT", +] + +ApprovalRate = Literal["high", "low", "medium"] + +ManualExecutionStatus = Literal["failed"] + +WebhookEvent = Literal["receiver.delete"]