Integrating with Python

This guide demonstrates how to integrate the Trustist Ecommerce Payments API into your Python application using the Requests library and Mohawk for Hawk authentication.

1. Installation

Install the Requests library and Mohawk (Hawk authentication) using pip:

pip install requests mohawk

2. Configuration

Create a session object and configure it with your API credentials and the desired environment (sandbox or production). The Hawk authentication will be applied to all requests via a custom auth class.

import requests
from mohawk import Sender
import json

BASE_URL = 'https://api-sandbox.trustistecommerce.com'
CLIENT_ID = 'your-client-id'
CLIENT_KEY = 'your-private-key'

class HawkAuth(requests.auth.AuthBase):
    def __call__(self, request):
        sender_kwarg = {
            'credentials': {
                'id': CLIENT_ID,
                'key': CLIENT_KEY,
                'algorithm': 'sha256'
            },
            'url': request.url,
            'method': request.method,
            'always_hash_content': False
        }

        if request.method != 'GET':
            sender_kwarg['content'] = request.body
            sender_kwarg['content_type'] = request.headers['Content-Type']

        sender = Sender(**sender_kwarg)
        request.headers['Authorization'] = sender.request_header
        return request

3. Creating a Payment

To create a new payment, make a POST request to the /v1/payments endpoint with the payment details.

def create_payment(amount, reference, return_url):
    session = requests.Session()
    session.auth = HawkAuth()

    data = {
        'amount': amount,
        'reference': reference,
        'returnUrl': return_url
    }

    response = session.post(BASE_URL + '/v1/payments', json=data)
    response.raise_for_status()
    return response.json()

# Usage example
payment = create_payment(99.99, 'ORDER-12345', 'https://yoursite.com/payment/success')

print(f"Payment ID: {payment['id']}")
print(f"Payment Link: {payment['payLink']}")

4. Retrieving a Payment

To retrieve the details of an existing payment, make a GET request to the /v1/payments/{paymentId} endpoint.

def get_payment(payment_id):
    session = requests.Session()
    session.auth = HawkAuth()

    response = session.get(BASE_URL + f'/v1/payments/{payment_id}')
    response.raise_for_status()
    return response.json()

# Usage example
payment = get_payment('your-payment-id')

print(f"Status: {payment['status']}")
print(f"Amount: {payment['amount']}")
print(f"Reference: {payment['sourceReference']}")

Example: Complete Integration Class

Here's a complete client class for better organization:

import requests
from mohawk import Sender
from typing import Optional, Dict, Any

class TrustistEcommerceClient:
    def __init__(self, client_id: str, private_key: str, environment: str = 'sandbox'):
        self.client_id = client_id
        self.private_key = private_key
        self.base_url = (
            'https://api-sandbox.trustistecommerce.com' if environment == 'sandbox'
            else 'https://api.trustistecommerce.com'
        )
        self.session = requests.Session()
        self.session.auth = self._create_hawk_auth()

    def _create_hawk_auth(self):
        class HawkAuth(requests.auth.AuthBase):
            def __init__(self, client_id, private_key):
                self.client_id = client_id
                self.private_key = private_key

            def __call__(self, request):
                sender_kwarg = {
                    'credentials': {
                        'id': self.client_id,
                        'key': self.private_key,
                        'algorithm': 'sha256'
                    },
                    'url': request.url,
                    'method': request.method,
                    'always_hash_content': False
                }

                if request.method != 'GET' and request.body:
                    sender_kwarg['content'] = request.body
                    sender_kwarg['content_type'] = request.headers.get('Content-Type', 'application/json')

                sender = Sender(**sender_kwarg)
                request.headers['Authorization'] = sender.request_header
                return request

        return HawkAuth(self.client_id, self.private_key)

    def create_payment(self, amount: float, reference: str, return_url: str, **kwargs) -> Dict[str, Any]:
        """Create a new payment."""
        data = {
            'amount': amount,
            'reference': reference,
            'returnUrl': return_url,
            **kwargs
        }

        response = self.session.post(f'{self.base_url}/v1/payments', json=data)
        response.raise_for_status()
        return response.json()

    def get_payment(self, payment_id: str) -> Dict[str, Any]:
        """Get payment status."""
        response = self.session.get(f'{self.base_url}/v1/payments/{payment_id}')
        response.raise_for_status()
        return response.json()

    def create_standing_order(self, amount: float, reference: str, start_date: str, 
                             frequency: str, number_of_payments: int = 0, **kwargs) -> Dict[str, Any]:
        """Create a new standing order."""
        data = {
            'amount': amount,
            'reference': reference,
            'startDate': start_date,  # yyyy-MM-dd format
            'frequency': frequency,  # Weekly, Monthly, Annually
            'numberOfPayments': number_of_payments,
            'returnUrl': kwargs.get('returnUrl', 'https://yoursite.com/standing-order/success'),
            **kwargs
        }

        response = self.session.post(f'{self.base_url}/v1/standingorders', json=data)
        response.raise_for_status()
        return response.json()

    def get_standing_order(self, standing_order_id: str) -> Dict[str, Any]:
        """Get standing order status."""
        response = self.session.get(f'{self.base_url}/v1/standingorders/{standing_order_id}')
        response.raise_for_status()
        return response.json()

# Usage
client = TrustistEcommerceClient(
    client_id='your-client-id',
    private_key='your-private-key',
    environment='sandbox'
)

try:
    # Create a payment
    payment = client.create_payment(
        amount=99.99,
        reference='ORDER-12345',
        return_url='https://yoursite.com/payment/success'
    )
    
    print(f"Redirect customer to: {payment['payLink']}")
    
    # Later, verify payment status
    status = client.get_payment(payment['id'])
    if status['status'] == 'COMPLETE':
        print("Payment completed!")
        
except requests.exceptions.HTTPError as e:
    print(f"HTTP Error: {e.response.status_code} - {e.response.text}")
except Exception as e:
    print(f"Error: {str(e)}")

Flask Integration

Here's an example of integrating with a Flask application:

from flask import Flask, request, redirect, jsonify
import os

app = Flask(__name__)

# Initialize client
trustist_client = TrustistEcommerceClient(
    client_id=os.environ.get('TRUSTIST_CLIENT_ID'),
    private_key=os.environ.get('TRUSTIST_PRIVATE_KEY'),
    environment=os.environ.get('TRUSTIST_ENV', 'sandbox')
)

@app.route('/api/payments', methods=['POST'])
def create_payment():
    try:
        data = request.json
        payment = trustist_client.create_payment(
            amount=data['amount'],
            reference=data['reference'],
            return_url=data['returnUrl']
        )
        
        return jsonify({
            'id': payment['id'],
            'payLink': payment['payLink']
        })
    except Exception as e:
        return jsonify({'error': str(e)}), 500

@app.route('/api/payments/', methods=['GET'])
def get_payment(payment_id):
    try:
        payment = trustist_client.get_payment(payment_id)
        return jsonify(payment)
    except Exception as e:
        return jsonify({'error': str(e)}), 500

@app.route('/payment/complete')
def payment_complete():
    payment_id = request.args.get('paymentId')
    
    try:
        payment = trustist_client.get_payment(payment_id)
        
        if payment['status'] == 'COMPLETE':
            return redirect('/payment/success')
        else:
            return redirect('/payment/failed')
    except Exception as e:
        return redirect('/payment/error')

if __name__ == '__main__':
    app.run(debug=True)

Django Integration

For Django, create a service module:

# services/trustist_service.py
from django.conf import settings

def get_trustist_client():
    return TrustistEcommerceClient(
        client_id=settings.TRUSTIST_CLIENT_ID,
        private_key=settings.TRUSTIST_PRIVATE_KEY,
        environment=settings.TRUSTIST_ENV
    )

# views.py
from django.http import JsonResponse
from django.shortcuts import redirect
from .services.trustist_service import get_trustist_client

def create_payment(request):
    if request.method == 'POST':
        client = get_trustist_client()
        payment = client.create_payment(
            amount=request.POST['amount'],
            reference=request.POST['reference'],
            return_url=request.POST['returnUrl']
        )
        
        return JsonResponse({
            'id': payment['id'],
            'payLink': payment['payLink']
        })

def payment_complete(request):
    client = get_trustist_client()
    payment_id = request.GET.get('paymentId')
    
    payment = client.get_payment(payment_id)
    
    if payment['status'] == 'COMPLETE':
        return redirect('payment_success')
    return redirect('payment_failed')

Best Practices

  • Use environment variables for API credentials
  • Never commit credentials to version control
  • Always verify payment status server-side before fulfilling orders
  • Implement proper error handling with try-except blocks
  • Set up webhooks for real-time payment notifications
  • Log errors for debugging and monitoring
  • Use type hints for better code documentation

Environment Variables

Create a .env file (add to .gitignore):

TRUSTIST_CLIENT_ID=your-client-id
TRUSTIST_PRIVATE_KEY=your-private-key
TRUSTIST_ENV=sandbox

Load with python-dotenv:

from dotenv import load_dotenv
import os

load_dotenv()

client = TrustistEcommerceClient(
    client_id=os.getenv('TRUSTIST_CLIENT_ID'),
    private_key=os.getenv('TRUSTIST_PRIVATE_KEY'),
    environment=os.getenv('TRUSTIST_ENV', 'sandbox')
)

Error Handling

import logging

logger = logging.getLogger(__name__)

try:
    payment = client.create_payment(99.99, 'ORDER-12345', return_url)
except requests.exceptions.HTTPError as e:
    logger.error(f"HTTP Error: {e.response.status_code} - {e.response.text}")
    # Handle based on status code
    if e.response.status_code == 400:
        print("Bad request - check your payment data")
    elif e.response.status_code == 401:
        print("Unauthorized - check your API credentials")
except requests.exceptions.RequestException as e:
    logger.error(f"Request failed: {str(e)}")
    # Handle network errors
except Exception as e:
    logger.error(f"Unexpected error: {str(e)}")
    # Handle other errors

Next Steps