From f3325154771effb67c4ac2bfbe2c052e4d24ecd9 Mon Sep 17 00:00:00 2001 From: Rene <105488705+Buckaroo-Rene@users.noreply.github.com> Date: Thu, 13 Aug 2026 16:25:03 +0200 Subject: [PATCH] Update README.md --- README.md | 343 +++++++++++++++++++++++++++++------------------------- 1 file changed, 183 insertions(+), 160 deletions(-) diff --git a/README.md b/README.md index a3b47fb..f438468 100644 --- a/README.md +++ b/README.md @@ -1,86 +1,107 @@

- + + Buckaroo — Python SDK +

-# Buckaroo Python SDK -[![Latest release](https://badgen.net/github/release/buckaroo-it/BuckarooSDK_Python)](https://github.com/buckaroo-it/BuckarooSDK_Python/releases) +

Buckaroo Python SDK

+ +

+ Latest release + Python versions + License + Documentation +

+ +

+ About · + Requirements · + Installation · + Getting started · + Buckaroo solutions · + Testing · + Support · + Contribute +

---- -### Index -- [About](#about) -- [Requirements](#requirements) -- [Pip Installation](#pip-installation) -- [Example](#example) -- [iDIN](#idin) -- [Instant Refunds](#instant-refunds) -- [eMandate](#emandate) -- [Split Payments](#split-payments) -- [Credit Management](#credit-management) -- [Point of Sale (POS)](#point-of-sale-pos) -- [Contribute](#contribute) -- [Versioning](#versioning) -- [Additional information](#additional-information) --- -### About +## About -Buckaroo is the Payment Service Provider for all your online payments with more than 30,000 companies relying on Buckaroo's platform to securely process their payments, subscriptions and unpaid invoices. -Buckaroo developed their own Python SDK. The SDK is a modern, open-source Python library that makes it easy to integrate your Python application with Buckaroo's services. -Start accepting payments today with Buckaroo. +Buckaroo is a Dutch Payment Service Provider. More than 54,000 organisations rely on the Buckaroo platform to process their payments, subscriptions and unpaid invoices. -### Requirements +This is Buckaroo's official Python SDK: a modern, open source library that connects a Python application to the Buckaroo API. Beyond payments and refunds it covers iDIN identity verification, eMandates, Split Payments, Credit Management and Point of Sale. -To use the Buckaroo API client, the following things are required: +If you run a shop on an e-commerce platform, use the ready-made plugin for [Magento 2](https://github.com/buckaroo-it/Magento2), [Shopware 6](https://github.com/buckaroo-it/Shopware6), [WooCommerce](https://github.com/buckaroo-it/WooCommerce), [PrestaShop](https://github.com/buckaroo-it/PrestaShop) or [Odoo](https://github.com/buckaroo-it/Odoo) instead. This SDK is for custom applications. -+ A Buckaroo account ([Dutch](https://www.buckaroo.nl/start) or [English](https://www.buckaroo.eu/solutions/request-form)) -+ Python >= 3.9 -+ Up-to-date OpenSSL (or other SSL/TLS toolkit) +[Full API documentation on docs.buckaroo.io](https://docs.buckaroo.io/reference) -### Pip Installation +--- -By far the easiest way to install the Buckaroo SDK is via [pip](https://pip.pypa.io/). +## Requirements - $ pip install buckaroo-sdk +| Requirement | Supported versions | +|---|---| +| Python | 3.9 or higher | +| OpenSSL | An up-to-date SSL/TLS toolkit | -Then import the client in your project: +You also need a Buckaroo account. Don't have one yet? [Request an account](https://www.buckaroo.nl/start). -```python -from buckaroo import BuckarooClient +--- + +## Installation + +Install the SDK with [pip](https://pip.pypa.io/): + +```bash +pip install buckaroo-sdk ``` -### Example -Create and configure the Buckaroo client. -You can find your credentials in [Buckaroo Plaza](https://plaza.buckaroo.nl/Configuration/Merchant/ApiKeys). +--- + +## Getting started + +### Configuring the client + +You can find your Store key and Secret key under [API credentials in Buckaroo Plaza](https://plaza.buckaroo.nl/Configuration/Merchant/ApiKeys). Set `mode` to `test` while developing and to `live` in production. ```python from buckaroo import BuckarooClient from buckaroo.services.payment_service import PaymentService -# Get your store & secret key in your plaza. -# mode="test" routes calls to the test environment; use "live" for production. client = BuckarooClient("STORE_KEY", "SECRET_KEY", mode="test") payments = PaymentService(client) ``` -Create a payment with any of the available payment methods. In this example, we show how to create a credit card payment. Each payment has a slightly different payload. +Alternatively, read the credentials from the environment. Copy `.env.example` to `.env`, fill it in, and use: + +```python +from buckaroo.app import Buckaroo + +app = Buckaroo.from_env() +``` + +This gives you `app.payments` and `app.solutions`, which are used interchangeably with `PaymentService` and `SolutionService` throughout the examples below. + +### Creating a payment + +Every payment method takes a slightly different payload. This example charges a Visa card: ```python -# Create a new payment response = ( payments.create_payment( "creditcard", { "currency": "EUR", - "amount": 10.00, # The amount we want to charge - "invoice": "UNIQUE-INVOICE-NO", # Each payment must contain a unique invoice number - "service_parameters": {"brand": "visa"}, # Request to pay with Visa + "amount": 10.00, + "invoice": "UNIQUE-INVOICE-NO", # must be unique per payment + "service_parameters": {"brand": "visa"}, }, ) .description("Order #UNIQUE-INVOICE-NO") .pay() ) -# Inspect the response from Buckaroo if response.is_successful(): print("transaction id:", response.get_transaction_id()) print("redirect:", response.get_redirect_url()) @@ -88,7 +109,7 @@ else: print("status message:", response.get_message()) ``` -You can also use the fluent interface directly: +The same request can be built with the fluent interface: ```python response = ( @@ -100,11 +121,15 @@ response = ( ) ``` -Find our full documentation online on [docs.buckaroo.io](https://docs.buckaroo.io). +Service codes for every payment method are listed in the [API reference](https://docs.buckaroo.io/reference). + +--- + +## Buckaroo solutions ### iDIN -iDIN lets Dutch banks confirm a consumer's identity on your behalf. It carries no amount or currency — only the return URLs plus the `issuerId` (BIC code of the consumer's bank) service parameter. Three actions are available: `identify()`, `verify()` (age 18+), and `login()`. +iDIN lets Dutch banks confirm a consumer's identity on your behalf. It carries no amount or currency, only the return URLs plus the `issuerId` service parameter, which is the BIC code of the consumer's bank. Three actions are available: `identify()`, `verify()` for age 18+, and `login()`. ```python response = payments.create_payment( @@ -122,11 +147,11 @@ print("key:", response.key) print("redirect:", response.get_redirect_url()) ``` -See [`examples/idin.py`](examples/idin.py) for a runnable demo of all three actions. +Runnable demo of all three actions: [`examples/idin.py`](https://github.com/buckaroo-it/BuckarooSDK_Python/blob/master/examples/idin.py). -### Instant Refunds +### Instant refunds -Instant refunds send money back to the shopper immediately instead of via the regular batch refund process. They are processed as an instant payment rather than a standard refund, and are supported for iDEAL and Payconiq via `instantRefund()`. Pass the `original_transaction_key` of a settled payment; `refund_amount` is optional — omit it for a full refund. +Instant refunds return money to the shopper immediately rather than through the regular batch refund process, and are processed as an instant payment instead of a standard refund. They are supported for iDEAL. Pass the `original_transaction_key` of a settled payment. `refund_amount` is optional, so omit it for a full refund. ```python response = payments.create_payment( @@ -143,26 +168,21 @@ response = payments.create_payment( print("key:", response.key) ``` -See [`examples/instant_refund.py`](examples/instant_refund.py) for a runnable demo covering both iDEAL and Payconiq. +Runnable demo: [`examples/instant_refund.py`](https://github.com/buckaroo-it/BuckarooSDK_Python/blob/master/examples/instant_refund.py). ### eMandate -eMandate is a DataRequest-based solution for managing SEPA direct debit mandates, reached through -`app.solutions` rather than `app.payments`. It comes in two variants that share the same five -actions — only the service name differs: - -- `emandate` — retail (B2C) -- `emandateb2b` — business (B2B) +eMandate is a DataRequest-based solution for managing SEPA direct debit mandates, reached through `app.solutions` rather than `app.payments`. Two variants share the same five actions, differing only in service name: `emandate` for retail (B2C) and `emandateb2b` for business (B2B). ```python from buckaroo.app import Buckaroo app = Buckaroo.from_env() -# List available issuers (GetIssuerList — no parameters) +# GetIssuerList - no parameters response = app.solutions.create_solution("emandate").issuer_list() -# Create a mandate (CreateMandate — debtorReference is required) +# CreateMandate - debtorReference is required response = app.solutions.create_solution( "emandate", { @@ -177,36 +197,29 @@ response = app.solutions.create_solution( ).create_mandate() mandate_id = response.get_service_parameter("MandateId") -# Look up a mandate's status (GetStatus — mandateId is required) +# GetStatus - mandateId is required response = app.solutions.create_solution( "emandate", {"service_parameters": {"mandateId": mandate_id}} ).status() -# Modify a mandate (ModifyMandate — mandateId is required) +# ModifyMandate - mandateId is required response = app.solutions.create_solution( "emandate", {"service_parameters": {"mandateId": mandate_id, "maxAmount": "1000.00"}}, ).modify_mandate() -# Cancel a mandate (CancelMandate — mandateId is required) +# CancelMandate - mandateId is required response = app.solutions.create_solution( "emandate", {"service_parameters": {"mandateId": mandate_id, "purchaseId": "PUR-001"}}, ).cancel_mandate() ``` -The B2B variant exposes the same five methods — swap `"emandate"` for `"emandateb2b"`. - -See [`examples/emandate.py`](examples/emandate.py) for a runnable demo of all five actions -against both the B2C and B2B services. +Swap `"emandate"` for `"emandateb2b"` to use the B2B variant. Runnable demo of all five actions against both services: [`examples/emandate.py`](https://github.com/buckaroo-it/BuckarooSDK_Python/blob/master/examples/emandate.py). -### Split Payments +### Split payments -Split Payments (Buckaroo service `Marketplaces`) lets a platform divide one -customer payment across its own funds account and one or more seller accounts. -Following the other Buckaroo SDKs, `split` and `refund_supplementary` build a -supplementary service that is *combined* into a payment or refund; `transfer` and -`manual_transfer` are standalone. +Split Payments (Buckaroo service `Marketplaces`) lets a platform divide one customer payment across its own funds account and one or more seller accounts. `split` and `refund_supplementary` build a supplementary service that is *combined* into a payment or refund; `transfer` and `manual_transfer` are standalone. ```python from buckaroo import BuckarooClient @@ -218,9 +231,7 @@ payments = PaymentService(client) marketplaces = SolutionService(client) ``` -**Split** — build the split, then combine it into the funding payment (e.g. -iDEAL). `daysUntilTransfer` is `"0"` for immediate payout, or omit it to hold the -funds until a later Transfer. +**Split** — build the split, then combine it into the funding payment. Set `daysUntilTransfer` to `"0"` for immediate payout, or omit it to hold the funds until a later Transfer. ```python split = marketplaces.create_solution("marketplaces").split( @@ -254,21 +265,15 @@ response = ( ) ``` -**Transfer** — release held funds of an existing split payment. With no split -data it transfers everything (Transfer I); pass `marketplace`/`sellers` to -transfer a partial or re-specified split (Transfer II). +**Transfer** — release the held funds of an existing split payment. With no split data it transfers everything (Transfer I); pass `marketplace` or `sellers` for a partial or re-specified split (Transfer II). ```python marketplaces.create_solution("marketplaces").transfer( - { - "originalTransactionKey": "SPLIT_TRANSACTION_KEY", - } + {"originalTransactionKey": "SPLIT_TRANSACTION_KEY"} ) ``` -**RefundSupplementary** — refund the consumer and pull the funds back from the -target accounts. Combine it into the refund. Without seller data it reverts all -transfers (I); pass `sellers` to retrieve specific amounts per account (II). +**RefundSupplementary** — refund the consumer and pull the funds back from the target accounts, combined into the refund. Without seller data it reverts all transfers; pass `sellers` to retrieve specific amounts per account. ```python supplementary = marketplaces.create_solution("marketplaces").refund_supplementary() @@ -305,39 +310,25 @@ marketplaces.create_solution("marketplaces").manual_transfer( ) ``` -A runnable demo of all six request types is in -[`examples/marketplaces.py`](examples/marketplaces.py). - -### Credit Management - -Credit Management is a DataRequest-based solution for invoicing and debtor -administration, reached through `app.solutions` rather than `app.payments`. -It covers creating and pausing invoices, managing debtors and their files, -credit notes, product lines, and payment plans. `create_combined_invoice` is -the exception — it builds a supplementary service that is *combined* into a -funding payment or refund, like Split Payments. - -`invoice` and `currency` are **top-level** request fields for `CreateInvoice`, -`CreateCombinedInvoice`, `CreateCreditNote`, `PauseInvoice`, `UnPauseInvoice` -and `InvoiceInfo` — set them via the top-level `invoice`/`currency` payload -keys (or `.invoice(...)`/`.currency(...)`), not inside `service_parameters`. -The gateway rejects them as service parameters with `ParameterMissing`. -`description` is likewise a **top-level** request field for -`CreatePaymentPlan` — set it via the top-level `description` payload key (or -`.description(...)`), not inside `service_parameters`. The gateway rejects it -as an unknown parameter when sent as one. -`schemeKey` is store-specific: it must belong to the same store as your store -key. `txnpk6` below is the scheme of the demo account used to write these -examples — replace it with the scheme key configured for your own store -(Plaza → Credit Management → CM scheme settings). +Runnable demo of all six request types: [`examples/marketplaces.py`](https://github.com/buckaroo-it/BuckarooSDK_Python/blob/master/examples/marketplaces.py). + +### Credit management + +Credit Management is a DataRequest-based solution for invoicing and debtor administration, reached through `app.solutions`. It covers creating and pausing invoices, managing debtors and their files, credit notes, product lines and payment plans. `create_combined_invoice` is the exception: it builds a supplementary service that is *combined* into a funding payment or refund, like Split Payments. + +> [!IMPORTANT] +> `invoice` and `currency` are **top-level** request fields for `CreateInvoice`, `CreateCombinedInvoice`, `CreateCreditNote`, `PauseInvoice`, `UnPauseInvoice` and `InvoiceInfo`. Set them through the top-level payload keys or `.invoice(...)` and `.currency(...)`, not inside `service_parameters` — the gateway rejects them there with `ParameterMissing`. The same applies to `description` for `CreatePaymentPlan`, which the gateway rejects as an unknown parameter when sent as a service parameter. + +> [!NOTE] +> `schemeKey` is store-specific and must belong to the same store as your Store key. The `txnpk6` value below is the scheme of the demo account these examples were written against — replace it with the scheme key configured for your own store, found in Plaza under **Credit Management → CM scheme settings**. ```python from buckaroo.app import Buckaroo app = Buckaroo.from_env() -# Create an invoice (CreateInvoice — invoiceAmount, dueDate, schemeKey and a -# Debtor group with a code are required; invoice/currency go top-level) +# CreateInvoice - invoiceAmount, dueDate, schemeKey and a Debtor group with a +# code are required; invoice and currency go top-level response = app.solutions.create_solution( "creditmanagement", { @@ -353,8 +344,8 @@ response = app.solutions.create_solution( ).create_invoice() invoice_key = response.get_service_parameter("InvoiceKey") -# Create or update a debtor (AddOrUpdateDebtor — a Debtor group with a code -# is required; Person/Company/Address/Email/Phone groups are optional) +# AddOrUpdateDebtor - a Debtor group with a code is required; +# Person, Company, Address, Email and Phone groups are optional response = app.solutions.create_solution( "creditmanagement", { @@ -366,16 +357,15 @@ response = app.solutions.create_solution( }, ).add_or_update_debtor() -# Look up a debtor (DebtorInfo — a Debtor group with a code is required) +# DebtorInfo - a Debtor group with a code is required response = app.solutions.create_solution( "creditmanagement", {"service_parameters": {"debtor": {"code": "DEBTOR-001"}}}, ).debtor_info() -# Add product lines (AddOrUpdateProductLines — articles must be passed as -# the `articles` method argument, not through service_parameters; each -# article requires type, totalAmount and totalVat on top of the usual -# identifier/description/quantity/price) +# AddOrUpdateProductLines - articles are passed as the `articles` method +# argument, not through service_parameters; each article requires type, +# totalAmount and totalVat alongside the usual fields builder = app.solutions.create_solution( "creditmanagement", {"service_parameters": {"invoiceKey": "INVK-001"}}, @@ -395,12 +385,11 @@ response = builder.add_or_update_product_lines( ] ) -# Create a payment plan (CreatePaymentPlan — includedInvoiceKey, -# dossierNumber, startDate, interval, paymentPlanCostAmount and -# recipientEmail are required service parameters; description goes -# top-level; either installmentCount or installmentAmount must also be -# given. Requires an active Buckaroo Credit Management subscription and an -# included invoice past its due date — enforced by the gateway, not the SDK) +# CreatePaymentPlan - includedInvoiceKey, dossierNumber, startDate, interval, +# paymentPlanCostAmount and recipientEmail are required service parameters; +# description goes top-level; either installmentCount or installmentAmount is +# also required. Needs an active Credit Management subscription and an included +# invoice past its due date, both enforced by the gateway rather than the SDK response = app.solutions.create_solution( "creditmanagement", { @@ -417,15 +406,13 @@ response = app.solutions.create_solution( }, ).create_payment_plan() -# Look up an invoice (InvoiceInfo — invoice is required, top-level) -response = app.solutions.create_solution("creditmanagement", {"invoice": "INV-001"}).invoice_info() +# InvoiceInfo - invoice is required, top-level +response = app.solutions.create_solution( + "creditmanagement", {"invoice": "INV-001"} +).invoice_info() ``` -`create_combined_invoice` accepts the same invoice service fields as -`create_invoice`, including the `Debtor` group, and combines into the -funding payment or refund. The combined request has a single shared top -level, so `invoice`/`currency` are set on the *funding* payment, not on the -CreditManagement3 sub-builder: +`create_combined_invoice` accepts the same invoice service fields as `create_invoice`, including the `Debtor` group. A combined request has a single shared top level, so `invoice` and `currency` are set on the *funding* payment rather than on the CreditManagement3 sub-builder: ```python cm = app.solutions.create_solution( @@ -460,24 +447,18 @@ response = ( ) ``` -Other actions follow the same shape: `create_credit_note` (`invoice` -top-level, `originalInvoiceNumber` and `Debtor` as service parameters), -`resume_debtor_file`/`pause_debtor_file`, `pause_invoice`/`unpause_invoice` -(`invoice` top-level, no service parameters), and `terminate_payment_plan` -(`includedInvoiceKey`). +The remaining actions follow the same shape: `create_credit_note` with `invoice` top-level and `originalInvoiceNumber` plus `Debtor` as service parameters, `resume_debtor_file` and `pause_debtor_file`, `pause_invoice` and `unpause_invoice` with `invoice` top-level and no service parameters, and `terminate_payment_plan` with `includedInvoiceKey`. -See [`examples/credit_management.py`](examples/credit_management.py) for a -runnable demo of the main actions. +Runnable demo of the main actions: [`examples/credit_management.py`](https://github.com/buckaroo-it/BuckarooSDK_Python/blob/master/examples/credit_management.py). -### Point of Sale (POS) +### Point of Sale -POS transactions are PIN-based in-store payments processed through a physical payment terminal. -You initiate the transaction via API with the terminal's unique `TerminalID`; Buckaroo routes the -request to that terminal, which prompts the customer to complete payment there. There's no -redirect flow, every request is sent with a fixed `Channel: "Web"`, set internally by the SDK. +> [!WARNING] +> This is the older POS solution. It has been replaced by UPG, which is not part of this SDK — see the [UPG documentation](https://docs.buckaroo.io/v2/docs/authentication) if you are building a new in-store integration. -The immediate response carries a pending/awaiting status. The final result, plus the printable -`Ticket` receipt text for the customer, arrives later via push notification. +POS transactions are PIN-based in-store payments processed through a physical payment terminal. You initiate the transaction via the API with the terminal's `TerminalID`, and Buckaroo routes the request to that terminal, which prompts the customer to complete payment there. There is no redirect flow, and every request is sent with a fixed `Channel: "Web"` that the SDK sets internally. + +The immediate response carries a pending status. The final result, along with the printable `Ticket` receipt text, arrives later by push notification. ```python response = ( @@ -497,8 +478,7 @@ print("key:", response.key) print("pending:", response.is_pending()) ``` -Parsing the push notification once the terminal completes the transaction push bodies wrap the -transaction under a `Transaction` key, so unwrap it before handing it to `PaymentResponse`: +Push bodies wrap the transaction under a `Transaction` key, so unwrap it before handing it to `PaymentResponse`: ```python from buckaroo.models.payment_response import PaymentResponse @@ -509,23 +489,66 @@ response = PaymentResponse({"data": transaction}) ticket = response.get_service_parameter("Ticket") # printable receipt text ``` -See [`examples/pos_payment.py`](examples/pos_payment.py) for a runnable demo of both the `Pay` -action and push-notification parsing. +Runnable demo of both the Pay action and push parsing: [`examples/pos_payment.py`](https://github.com/buckaroo-it/BuckarooSDK_Python/blob/master/examples/pos_payment.py). + +--- -### Contribute +## Testing -We really appreciate it when developers contribute to improve the Buckaroo plugins. -If you want to contribute as well, then please follow our [Contribution Guidelines](CONTRIBUTING.md). +```bash +pip install -r requirements-dev.txt +pytest +``` -### Versioning +The runnable examples in [`examples/`](https://github.com/buckaroo-it/BuckarooSDK_Python/tree/master/examples) expect credentials in a `.env` file. Copy `.env.example` and fill in your test Store key and Secret key. -- **MAJOR:** Breaking changes that require additional testing/caution -- **MINOR:** Changes that should not have a big impact -- **PATCHES:** Bug and hotfixes only +--- + +## Support + +Having trouble? Work through this list before reaching out: + +1. Check the [API reference](https://docs.buckaroo.io/reference) for the service and action you are calling. +2. Confirm you are on the [latest release](https://github.com/buckaroo-it/BuckarooSDK_Python/releases). +3. Reproduce the issue with `mode="test"` and inspect `response.get_message()` and the raw response. +4. Verify that your push URL is reachable from outside your network. Buckaroo sends push messages from fixed IP addresses and ports, so make sure these are on your allow list. See [push messages](https://docs.buckaroo.io/docs/integration-push-messages) for the current list. + +Still stuck? Contact us and include your Python version, SDK version, the service and action you called, the error message and the transaction key. + +- **Bug reports and feature requests:** [open an issue](https://github.com/buckaroo-it/BuckarooSDK_Python/issues) +- **Technical support:** [support@buckaroo.nl](mailto:support@buckaroo.nl) +- **Phone:** +31 (0)30 711 50 50 +- **Gateway status:** [status.buckaroo.io](https://status.buckaroo.io/) + +--- -### Additional information -- **Support:** https://docs.buckaroo.io/docs/contact-us -- **Contact:** [support@buckaroo.nl](mailto:support@buckaroo.nl) or [+31 (0)30 711 50 50](tel:+310307115050) +## Contribute + +We really appreciate it when developers help improve the Buckaroo SDKs. Please read our [Contribution Guidelines](https://github.com/buckaroo-it/BuckarooSDK_Python/blob/master/CONTRIBUTING.md) before opening a pull request, and target the `master` branch. + +Found a security issue? Please report it privately to [support@buckaroo.nl](mailto:support@buckaroo.nl) instead of opening a public issue. + +--- + +## Versioning + +We follow semantic versioning (`MAJOR.MINOR.PATCH`): + +- **MAJOR** — breaking changes that require additional testing and caution. +- **MINOR** — new functionality with limited impact. +- **PATCH** — bug fixes and hotfixes only. + +All changes are documented in the [changelog](https://github.com/buckaroo-it/BuckarooSDK_Python/blob/master/CHANGELOG.md) and on the [releases page](https://github.com/buckaroo-it/BuckarooSDK_Python/releases). + +--- ## License -Buckaroo Python SDK is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT). + +This SDK is open source software licensed under the [MIT license](https://github.com/buckaroo-it/BuckarooSDK_Python/blob/master/LICENSE.txt). + +--- + +

+ Made with care by Buckaroo.
+ This document is subject to change; typos and language errors are possible.
+