Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ on:
jobs:
test:

runs-on: ubuntu-20.04
runs-on: ubuntu-22.04

steps:
- uses: actions/checkout@v2
- name: Setup Python
run: sudo add-apt-repository -y ppa:deadsnakes/ppa && sudo apt-get install -y python3.6 python3.7 python3.9 python3.6-distutils python3.7-distutils python3.9-distutils
run: sudo add-apt-repository -y ppa:deadsnakes/ppa && sudo apt-get install -y python3.7 python3.9 python3.7-distutils python3.9-distutils

- name: Install dependencies
run: |
Expand Down
7 changes: 7 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
Change Log
----------

1.5.8
+++++++++++++++++++++

**Features**

- Add support for `checkoutSession` API method.

1.5.7
+++++++++++++++++++++

Expand Down
13 changes: 3 additions & 10 deletions README.rst
Original file line number Diff line number Diff line change
@@ -1,13 +1,6 @@
.. image:: https://travis-ci.org/coolshop-com/AltaPay.svg
:target: https://travis-ci.org/coolshop-com/AltaPay

.. image:: https://codecov.io/github/coolshop-com/AltaPay/coverage.svg?branch=master
:target: https://codecov.io/github/coolshop-com/AltaPay?branch=master

.. image:: https://img.shields.io/pypi/v/altapay.svg
:target: https://pypi.python.org/pypi/altapay

This is an unofficial Python SDK for AltaPay (formerly Valitor/Pensio), https://altapay.com/. The SDK is maintained by Coolshop.com, https://www.coolshop.com/.
AltaPay - Python SDK
============
For integrating Python projects with the AltaPay gateway.

Requirements
============
Expand Down
3 changes: 2 additions & 1 deletion altapay/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
__title__ = 'altapay'
__version__ = '1.5.7'
__version__ = '1.5.8'
__author__ = 'Coolshop.com'
__license__ = 'MIT'
__github_url__ = 'https://github.com/coolshop-com/AltaPay'
Expand All @@ -11,6 +11,7 @@
from altapay.api import API # NOQA
from altapay.callback import Callback # NOQA
from altapay.chargeback import ChargebackEvent # NOQA
from altapay.checkout_session import CheckoutSession # NOQA
from altapay.credit_card_wallet_initiate_app_payment import \
CreditCardWalletInitiateAppPayment # NOQA
from altapay.funding import CustomReport, Funding, FundingList # NOQA
Expand Down
49 changes: 49 additions & 0 deletions altapay/checkout_session.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
from __future__ import absolute_import, unicode_literals

from altapay.resource import Resource


class CheckoutSession(Resource):
def create(self, terminals, shop_orderid, amount, currency, **kwargs):
"""
Create a checkout session.

Creates a checkout session for the current customer's basket grouping
all available payment methods. The session should be reused for
different payment methods until the payment is not finalized.

Checkout session is used to improve fraud detection and help maximize
conversion rate.

:arg terminals: list of terminal names available for the user based on
the checkout parameters. Can also be a single terminal name string.
:arg shop_orderid: your order ID to be attached to the checkout session
:arg amount: order amount in floating point
:arg currency: currency for the checkout session
:arg kwargs: used for remaining, optional, parameters, see the AltaPay
documentation for a full list. Note that you will need to use
lists and dictionaries to map the URL structures from the AltaPay
documentation into these kwargs.

:rtype: :samp:`True` if a checkout session was created, otherwise
:samp:`False`.
"""
if isinstance(terminals, str):
terminals = [terminals]

parameters = {
'terminals': terminals,
'shop_orderid': shop_orderid,
'amount': amount,
'currency': currency,
}

parameters.update(kwargs)

response = self.api.post(
self.get_post_url(), data=parameters)
self.merge_response(response)
return self.success

def get_post_url(self):
return 'API/checkoutSession'
5 changes: 3 additions & 2 deletions example/example_klarna.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@

"""

import sys, random
import secrets
import sys

# Update this with real path and uncomment before use, please
# sys.path.append('/absolute_path_to/sdk-python')
Expand All @@ -31,7 +32,7 @@
params = {

'terminal': 'AltaPay Klarna DK', # Update terminal name
'shop_orderid': 'Example_Klarna' + str(random.randint(1, 1000)),
'shop_orderid': 'Example_Klarna' + str(secrets.randbelow(1000) + 1),
'amount': 5.5,
'currency': 'DKK',
'type': 'payment',
Expand Down
4 changes: 2 additions & 2 deletions example/example_mobilepay.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@

"""

import secrets
import sys
import random

# Update this with real path and uncomment before use, please
# sys.path.append('/absolute_path_to/python-client-library')
Expand All @@ -31,7 +31,7 @@

params = {
'terminal': 'AltapPay MobilePay Terminal', # Update terminal name
'shop_orderid': 'Example_MobilePay' + str(random.randint(1, 1000)),
'shop_orderid': 'Example_MobilePay' + str(secrets.randbelow(1000) + 1),
'amount': 5.5,
'currency': 'DKK',
'type': 'payment',
Expand Down
6 changes: 3 additions & 3 deletions example/example_reservation.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@

from altapay import API, Reservation, Transaction

import string
import random
import json
import string
import secrets

def id_generator(size=15, chars=string.digits):
return ''.join(random.choice(chars) for _ in range(size))
return ''.join(secrets.choice(chars) for _ in range(size))

order_id=id_generator()
# print order_id
Expand Down
2 changes: 1 addition & 1 deletion example/example_terminals.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

"""

import sys, random
import sys

# Update this with real path and uncomment before use, please
# sys.path.append('/absolute_path_to/python-client-library')
Expand Down
1 change: 1 addition & 0 deletions sonar-project.properties
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
sonar.projectKey=AltaPay_sdk-python_307c8b3c-eb03-4e95-8a4f-3cb5510110a9
sonar.coverage.exclusions=**
27 changes: 21 additions & 6 deletions tests/integration/test_merchant_api.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import os
import random
import secrets
import unittest
from datetime import date

from altapay import (API, Funding, FundingList, Invoice, Payment, Reservation,
Transaction)
from altapay import (API, CheckoutSession, Funding, FundingList, Invoice,
Payment, Reservation, Transaction)
from tests.integration import (altapay_account, altapay_contract_identifier,
altapay_invoice_test_terminal_name,
altapay_password, altapay_test_terminal_name,
altapay_url)


def generate_order_id():
return 'Test_' + str(random.randint(1000, 999999)) + '_PY'
return 'Test_' + str(secrets.randbelow(999000) + 1000) + '_PY'


class APITest(unittest.TestCase):
Expand All @@ -22,13 +22,27 @@ def setUp(self):
password=altapay_password,
url=altapay_url)

def create_checkout_session(self):
session = CheckoutSession(api=self.api)
session.create(
terminals=[altapay_test_terminal_name],
shop_orderid=generate_order_id(),
amount=1.00,
currency='EUR'
)
return session.session['id']

def test_create_checkout_session(self):
self.create_checkout_session()

def test_create_payment_request(self):
payment = Payment(api=self.api)
params = {
'terminal': altapay_test_terminal_name,
'shop_orderid': generate_order_id(),
'amount': 1.00,
'currency': 'EUR'
'currency': 'EUR',
'session_id': self.create_checkout_session()
}
self.assertEqual(payment.create(**params), True)
self.assertIn('url', payment)
Expand All @@ -45,7 +59,8 @@ def test_create_payment_request_with_agreement(self):
'agreement': {
'type': 'unscheduled',
'unscheduled_type': 'incremental'
}
},
'session_id': self.create_checkout_session()
}
self.assertEqual(payment.create(**params), True)
self.assertIn('url', payment)
Expand Down
3 changes: 2 additions & 1 deletion tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ def test_login_successful(self):
body=self.load_xml_response('200_login.xml'),
status=200, content_type='application/xml')
api = API(
mode='test', account='test', password='test', auto_login=False)
mode='test', account='test',
password='test', auto_login=False) # NOSONAR
# Before login is called state should be not authenticated
self.assertEqual(api._is_authenticated, False)
api.login()
Expand Down
29 changes: 29 additions & 0 deletions tests/test_checkout_session.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from __future__ import absolute_import, unicode_literals

import responses

from altapay import API, CheckoutSession

from .test_cases import TestCase


class CheckoutSessionTest(TestCase):
def setUp(self):
self.api = API(mode='test', auto_login=False)

@responses.activate
def test_create_simple_checkout_session(self):
session = CheckoutSession(api=self.api)
responses.add(
responses.POST, self.get_api_url('API/checkoutSession'),
body=self.load_xml_response('200_checkout_session.xml'),
status=200, content_type='application/xml')
parameters = {
'terminals': ['Test Terminal'],
'shop_orderid': 1234567,
'amount': 9.95,
'currency': 'EUR'
}
self.assertEqual(session.create(**parameters), True)
self.assertIn('session', session)
self.assertEqual(len(session.session['id']) > 0, True)
15 changes: 15 additions & 0 deletions tests/xml/200_checkout_session.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0"?>
<APIResponse version="20251231">
<Header>
<Date>2026-04-19T09:57:02+02:00</Date>
<Path>API/checkoutSession</Path>
<ErrorCode>0</ErrorCode>
<ErrorMessage/>
</Header>
<Body>
<Session>
<Id>abc12345-6789-4def-a012-bcdef0123456</Id>
<Status>CREATED</Status>
</Session>
</Body>
</APIResponse>
Loading