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
29 changes: 29 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: CI Workflow

on:
release:
types: [published]
push:
branches:
- master
pull_request:

jobs:
build:
timeout-minutes: 10
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@v4
with:
enable-cache: true
cache-dependency-glob: "uv.lock"
- name: Set up Python 3.8
run: uv python install 3.8.19
- name: Install the project
run: uv sync --extra dev
- name: Run pre-commit
run: uv run pre-commit run --all-files --config .pre-commit-config.ci.yaml
- name: Run tests
run: uv run python -m unittest discover tests
11 changes: 10 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,13 @@ __pycache__/
dist/
build/
*.egg-info
.envrc
.envrc
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
.ruff_cache
.mypy_cache
34 changes: 34 additions & 0 deletions .pre-commit-config.ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
repos:
- repo: https://github.com/charliermarsh/ruff-pre-commit
rev: v0.6.6
hooks:
# Run linter
- id: ruff
language: system
types_or: [ python, pyi, ]
args: [--fix, --exit-non-zero-on-fix, --select, I]
# Run formatter
- id: ruff-format
language: system
types_or: [ python, pyi, ]

- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0
hooks:
- id: trailing-whitespace
exclude: "(^static/|/static/|^fobi/|.md$|.django.po$|.csv$)"
- id: end-of-file-fixer
exclude: "(^static/|/static/|^fobi/)"
- id: debug-statements
- id: check-added-large-files
- id: check-merge-conflict
- id: mixed-line-ending
args: ["--fix=lf"]
exclude: "^(static/|theme/|fixtures/static/|core/static/|fobi/)"

- repo: https://github.com/pycqa/bandit
rev: 1.7.9
hooks:
- id: bandit
args: ['-iii', '-ll', "-c", "pyproject.toml"]
additional_dependencies: ["bandit[toml]"]
30 changes: 30 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
hooks:
- id: trailing-whitespace
exclude: "(^static/|/static/|^fobi/|.md$|.django.po$|.csv$)"
- id: end-of-file-fixer
exclude: "(^static/|/static/|^fobi/)"
- id: debug-statements
- id: check-added-large-files
- id: check-merge-conflict
- id: check-json
- id: check-toml
- id: detect-private-key
- id: check-builtin-literals
- id: check-case-conflict

- repo: https://github.com/pycqa/bandit
rev: 1.7.10
hooks:
- id: bandit
args: ['-iii', '-ll', "-c", "pyproject.toml"]
additional_dependencies: ["bandit[toml]"]

- repo: https://github.com/charliermarsh/ruff-pre-commit
rev: v0.6.6
hooks:
- id: ruff
args: [ --fix ]
- id: ruff-format
65 changes: 38 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@
- Void transactions
- Update a customer's payment setup in PayWay

# Install
## Install

```
```bash
pip install python-payway
```

# Take payment using a stored credit card
## Take payment using a stored credit card

Create a Client class with your PayWay API credentials

Expand All @@ -41,7 +41,7 @@ customer = PayWayCustomer(custom_id='c981a',
state='NSW',
postal_code='2000')
```

Create a PayWayCard class with your customer's card details

```python
Expand All @@ -62,7 +62,7 @@ payway_customer, customer_errors = client.create_customer(customer)
```

Note the 'payway_customer' object contains the full customer response fields from PayWay.

Create a Payment class with the payment details and process the transaction

```python
Expand All @@ -74,16 +74,16 @@ payment = PayWayPayment(customer_number=customer_number,
order_number='',
ip_address='')
transaction, errors = client.process_payment(payment)
```
```

Check the `transaction` for the result

```python
if not errors and transaction.status == 'approved':
# process successful response
```

# Take payment using a credit card token only
## Take payment using a credit card token only

```python
client = Client(merchant_id='',
Expand All @@ -109,10 +109,10 @@ payment = PayWayPayment(customer_number=customer_number,
transaction, errors = client.process_payment(payment)
```

# Handling errors
## Handling errors

Documented errors (such as 422 Unprocessable entity) are parsed into an PaymentError class that you can use in an customer error message.
https://www.payway.com.au/docs/rest.html#http-response-codes
For more info, visit <https://www.payway.com.au/docs/rest.html#http-response-codes>

```python
if errors:
Expand All @@ -122,9 +122,10 @@ if errors:
print(error.field_name)
# or use a method
PaymentError().list_to_message(errors)
```
```

## Direct Debit

# Direct Debit
Direct debit transactions are possible by creating a token from a bank account:

```python
Expand All @@ -137,15 +138,15 @@ Store the token with a customer in PayWay using the same process as the card out

Note: direct debit transactions take days to process so they must be polled regularly for the latest transaction status from the customer's bank.

# Lookup transaction
## Lookup transaction

Poll a transaction using the `get_transaction` method.

```python
transaction, errors = client.get_transaction(transaction.transaction_id)
```
```

# Process and capture a pre-authorisation
## Process and capture a pre-authorisation

To process a credit card pre-authorisation using a credit card stored against a customer use `preAuth` as the `transaction_type` along with the customer's PayWay number, amount and currency.

Expand All @@ -170,7 +171,7 @@ capture_payment = PayWayPayment(transaction_type='capture',
transaction, errors = client.process_payment(capture_payment)
```

# Refunds
## Refunds

Refund a transaction by supplying a PayWay transaction ID and the refund amount.

Expand All @@ -181,34 +182,44 @@ refund, errors = client.refund_transaction(
)
```

# Voiding a transaction
## Voiding a transaction

Void a transaction by supplying a PayWay transaction ID.

```python
void_transaction, errors = client.void_transaction(transaction.transaction_id)
```

# Update Payment Setup
## Update Payment Setup

Update a customer's payment setup with a new credit card or bank account in PayWay. Supply the new token and an existing PayWay customer number.

```python
payment_setup, errors = client.update_payment_setup(new_token, payway_customer.customer_number)
```

# Additional notes
PayWay API documentation
https://www.payway.com.au/docs/rest.html
## Additional notes

PayWay API documentation <https://www.payway.com.au/docs/rest.html>

It is recommended to use PayWay's Trusted Frame https://www.payway.com.au/docs/rest.html#trusted-frame
It is recommended to use PayWay's Trusted Frame <https://www.payway.com.au/docs/rest.html#trusted-frame>
when creating a single use token of a card or bank account so your PCI-compliance scope is reduced.

# Fraud
## Fraud

Please follow PayWay's advice about reducing your risk of fraudulent transactions. <https://www.payway.com.au/docs/card-testing.html#card-testing>

Please follow PayWay's advice about reducing your risk of fraudulent transactions.
https://www.payway.com.au/docs/card-testing.html#card-testing
## Running the project

# Testing
```bash
uv python install 3.8.19
uv venv
source .venv/bin/activate
uv sync --extra dev
```

## Testing

1. Run the tests using `python -m unittest discover tests`
```bash
python -m unittest discover tests
```
Loading
Loading