Package: cheddarpayments
Cheddar Bindings for PythonA Python wrapper for Cheddar's application interface. Cheddar is a payment gateway for processing and executing
transactions within a neat and universal API.At the moment, the following payment methods and services are supported by the Cheddar service and this library:CardPay with optional addition for ComfortPay service – Tatra banka, a.s.TatraPay – Tatra banka, a.s.ePlatby VÚB – VÚB, a.s.VÚB eCard – VÚB, a.s.SporoPay – Slovenská sporiteľna, a.s.iTerminal – Poštová banka, a.s.GP webpay – Global Payments Europe, s.r.o.PayPal – PayPal (Europe) S.à r.l. et Cie, S.C.A.To see what is new or changed in the current version, check out thechangelog.SetupYou can install this package by usingpip:pip install cheddarpaymentsIf you fancypipenvuse:pipenv install cheddarpaymentsTo install from source, run:python setup.py installFor the API client to work you would need Python 2.7+ or Python 3.4+.UsageFirst off, you need to require the library and provide authentication information by providing your user handle and
shared secret you got from the provider.importcheddarclient=cheddar.Cheddar(cheddar.Configuration(cheddar.Environment.Production,"TEST","00000000000000000000000000000000",))In case you'd like to use the sandbox mode usecheddar.Environment.Sandboxwhen creating configuration object. You
can also create your own environment pointing to any valid URL with Cheddar instance running:my_test_environment = cheddar.Environment("test", "https://my.cheddar.test")Please notethat only VÚB eCard, iTerminal, GP webpay and PayPal currently allow for using their test environments
so in case of other providers production URLs will be used! When using sandbox with supported bank or financial
institution never use real world credit cards / accounts for testing payment methods implementation (they will not
work). Always use virtual testing cards / accounts provided for this purpose by the payment institution.Creating a transactionIt is quite simple to instantiate a payment.Here’s a quick piece of example code to get you started which will call the Cheddar service and retrieve UUID –
universal identifier of the transaction and set the transaction status tonone(see next section for more on
transaction statuses).payment=client.payments.create(cheddar.Service.CARDPAY,{"amount":Decimal('9.99'),"currency":cheddar.Currency.EUR,"variable_symbol":"1000000000","description":"My first test payment","payer_name":"John Doe","payer_email":"john@doe.com","return_url":"https://my-test-server.dev","notification_url":"https://my-test-server.dev",},)When using the wrapper in web context, the user's IP is automatically added to the data array from the environment
variables. If you wish to provide your own, addpayer_ip_addresskey with valid address as a value.First argument is a service provider, which can currently be one of the following:Service nameDescriptioncheddar.Service.SPOROPAYSporoPay, Slovenská sporiteľňacheddar.Service.TATRAPAYTatraPay, Tatra bankacheddar.Service.CARDPAYCardpay, Tatra bankacheddar.Service.COMFORTPAYComfortPay (periodic payments), Tatra bankacheddar.Service.EPLATBYePlatby, VÚBcheddar.Service.ECARDeCard, VÚBcheddar.Service.PAYPALPayPal Payments Standard, PayPalcheddar.Service.GPWEBPAYGP webpay, Global Payments Europecheddar.Service.ITERMINALiTerminal, Poštová banka (firstdata.lv backend)cheddar.Service.ITERMINAL2iTerminal, Poštová banka (sia.eu backend)Second argument to the function call is an associative array of configuration options. Which options have to be used
and which have no effect at all depends on the service provider. The next table lists all possible attributes:Attribute nameData typeRequired?Notesamountfloat✓amount required in the specified currencycurrencystring✓currency code as inISO 4217variable_symbolstring✓constant_symbolstringcard_idstringoptional card token in periodical paymentsapplicable only to ComfortPay transactionspayer_namestring✓customer’s namepayer_emailstring✓customer’s email (which has to be a valid e-mail address)languagestringcustomer’s languagedescriptionstringreference for the customerreturn_urlorcallbackstring✓URL to return to after the paymentiTerminal does not use this attribute since you have to set this up once for all transactions in their administration interfacenotification_urlstringURL to send notifications torequired for PayPal transactionscpp_logo_imagestringheader image at PayPalapplicable only to PayPal transactionscpp_cart_border_colorstringHEX code of colour at PayPalapplicable only to PayPal transactionsperiodicityintegerperiodicity in days, when the next periodical payment will be automatically executed; default value is 30 daysapplicable only to ComfortPay transactionsNote that all of the supported currencies are available as a simple constant oncheddar.Currencyclass to make it
easier in code.After the call you can inspect the returningPaymentobject, which is described in theGetting transaction detailspart of this document.To get to the URL of a payments gateway at the bank where the payment is processed just redirect the user to value ofpayment.redirect_urlproperty.After the payment process at the payment gateway is finished, you will be redirected to the URL you specified inreturn_url/callbackparameter during the create call in the example above. The URL will have two more GET
parameters added -uuid, for the payment identifier andstatus, for the current status of the payment transaction
(for some payment methods this may change in time, and you will be notified about the change to the URL you specified
in thenotification_urlparameter
[see theAsynchronous transaction notificationspart of this document for more info])Allowed transaction statusesStatus nameDescriptionnonetransaction has been created, but the user has not been redirected to bank’s payment gatewayin_progressuser has been redirected to bank’s payment gatewaycompletedtransaction has been successfully completeddeniedorrejectedtransaction has been rejected by the bank (the most usual reasons include user error in inputting card details and insufficient funds)timeoutspecial temporary status used only by Tatra banka’s TatraPay servicependingspecial status for PayPal before an IPN notification has resolved the transaction status as either rejected or completedcancelledin case of periodical payments available only with Tatra banka’s ComfortPay service this status means that planned transaction has been cancelledexpiredold payment without clear result (e.g. user abandoned the payment form while at bank’s gateway)Getting transaction detailsTo get all details of an existing payment transaction simply pass the UUID of the payment to the following method:payment=client.payments.details(uuid)Afterwards you can inspect the returning object, which contains these properties:Property nameData typeAlways present?Default valueNotesuuidstring✓statusstring✓nonecurrent transaction status (see the next table)variable_symbolstring✓the same as was sent while creating  the payment object (see previous section)constant_symbolstring✓0308payment for servicesamountfloat✓0.00original amount of the transactionrefunded_amountfloat✓0.00refunded amount of the transactionservice_fee_amountfloat✓0.00provision for the transaction in card paymentsavailable when using CardPay / ComfortPay and set up with PGP encrypted statements or PayPal servicecurrencyCurrencies✓EURcurrency of the transactionperiodicityinteger0number of days in which next payment will be executedperiodicity_nointeger1number of transaction in order (using the same variable symbol)charge_onDatetimewhen was or should be this transaction executedcard_expire_onDatetimenulldate of card expirationavailable only when using ComfortPay or VÚB eCard servicecard_nostringmasked card numberavailable only when using ComfortPay or VÚB eCard servicetransaction_identifierstringinternal transaction identifier of the bankavailable only when using CardPay / ComfortPay, TatraPay or VÚB eCard serviceAsynchronous transaction notificationsTransactions may have anotification_urlattribute (in case of PayPal and ComfortPay the attribute is mandatory),
that will receive a ping on every change to a transaction (in case of PayPal or ComfortPay it is also the only way to
find out the status of the payment).Cheddar calls the value ofnotification_urlattribute as POST request with GET attributesuuidandsignature(which needs to be verified) andapplication/jsonbody with full payment details as explained in the previous section.To validate the signature, you need to call the following:is_valid=client.messages.validate(uuid,signature);In case the signature is incorrect acheddar.errors.MessageIntegrityErroris thrown, otherwise the function returnstrue. After a successful validation you can trust the json-encoded body of the request.The JSON-encoded body will look something like this:{
    "uuid": "b1fcc76a-d284-4cbc-bce9-b415dc973763",
    "service": {
        "handle": "cardpay",
        "provider": "Tatra banka, a.s.",
        "name": "CardPay"
    },
    "status": {
        "status": "completed",
        "description": "The payment has been approved by the bank or financial institution"
    },
    "variable_symbol": "1000000000",
    "constant_symbol": "0308",
    "amount": 9.99,
    "refunded_amount": 0,
    "service_fee_amount": 0,
    "currency": {
        "alpha_code": "EUR",
        "numeric_code": 978,
        "name": "Euro"
    },
    "periodicity": 0,
    "periodicity_no": 1,
    "created_at": "2018-12-01 10:34:26",
    "events": [],
    "note": "my first test payment",
    "card_no": "****************",
    "transaction_identifier": "Aq83Lys6WHdiP8TFo6pnkRvTlpC="
}Updating planned transactionThe next use case is the ability to change date and / or amount of a next planned periodical payment. The output of
the call is summary of the planned payment including its UUID.importdatetimepayment=client.payments.update(uuid,["charge_on":datetime.date.today()+datetime.timedelta(days=1),"amount":Decimal('11.99')]);However, also the status of the planned payment might be changed – fromnonetocancelledor the other way. Just
make sure that thecharge_onattribute is set to correct value or explicitly set it, when changing the status.Refunding transactionsWith Poštová banka’s iTerminal service you might once request a refund on executed transaction in part, or in full. In
case of Tatra banka's CardPay service you might request as many refunds as you'd like until sum of all prior refunds
reaches the amount of the original transaction.Thereasonis more informative and should be one of eitherrequested_by_customer,fraudelent,duplicateorunknown(default). Currency has to be the same as when executing the original payment.payment=client.payments.refund(uuid,["amount":Decimal("11.99"),"currency":client.Currency.EUR,"reason":"requested_by_customer"]);ContributingCheck for open issues or open a new issue for a feature request or a bug.Fork the repository and make your changes to the master branch (or branch off of it).Send a pull request.DevelopmentRun all tests on all supported Python versions:make testRun the linter with:make lintThe client library uses Black for code formatting. Code must be formatted with Black before PRs are submitted. Run the
formatter with:make fmt© 2022 BACKBONE, s.r.o.