rate/access-paysuite

API library to interact with Access Paysuite

Maintainers

Package info

github.com/fish3046/access-paysuite

Homepage

pkg:composer/rate/access-paysuite

Statistics

Installs: 4

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

1.2.0 2026-04-27 22:14 UTC

This package is auto-updated.

Last update: 2026-04-27 22:14:59 UTC


README

A PHP library for the Access Paysuite Direct Debit Management API v3, built on Saloon.

Requirements

  • PHP 8.3+
  • Laravel 10+ (for the service provider and caching; optional for standalone use)

Installation

composer require rate/access-paysuite

Laravel

The service provider is auto-discovered. Publish the config file:

php artisan vendor:publish --provider="Rate\AccessPaysuite\ServiceProvider\AccessPaysuiteServiceProvider"

Add your credentials to .env:

ACCESS_PAYSUITE_CLIENT_CODE=APICODE
ACCESS_PAYSUITE_API_KEY=your-api-key
ACCESS_PAYSUITE_CACHE=false

# Set to true to use the playpen (sandbox) environment instead of production
ACCESS_PAYSUITE_PLAYPEN=false

Publish the webhook-log migration and run it:

php artisan vendor:publish --tag=access-paysuite-migrations
php artisan migrate

Point every DDCMS callback at the package's built-in webhook route in one go:

php artisan paysuite:callback:set all

This registers the route named access-paysuite.webhook (default path /paysuite/webhook) as the callback URL for all five entities — customer, contract, payment, bulkpayment, and schedule.

Basic Usage

With Laravel (dependency injection)

use Rate\AccessPaysuite\AccessPaysuiteConnector;
use Rate\AccessPaysuite\AccessPaysuiteService;

class CustomerController
{
    public function __construct(
        private readonly AccessPaysuiteConnector $connector,
    ) {}

    public function show(string $customerId): Customer
    {
        $service = new AccessPaysuiteService($this->connector);
        return $service->getCustomer($customerId);
    }
}

Without Laravel (standalone)

use Rate\AccessPaysuite\AccessPaysuiteConnector;
use Rate\AccessPaysuite\Enums\Environment;
use Rate\AccessPaysuite\AccessPaysuiteService;

$connector = new AccessPaysuiteConnector(
    environment: Environment::PRODUCTION, // or Environment::PLAYPEN for testing
    clientCode: 'APICODE',
    apiKey: 'your-api-key',
);

$connector->disableCaching();

$service = new AccessPaysuiteService($connector);

Environments

The environment is configured via a boolean in config/access-paysuite.php (or the ACCESS_PAYSUITE_PLAYPEN env var). Production is the default.

Config Env var URL
'playpen' => false ACCESS_PAYSUITE_PLAYPEN=false https://ddcms.accesspaysuite.com/api/v3
'playpen' => true ACCESS_PAYSUITE_PLAYPEN=true https://playpen.accesspaysuite.com/api/v3

When constructing the connector directly (without Laravel), pass the environment explicitly:

use Rate\AccessPaysuite\Enums\Environment;

Environment::PLAYPEN;    // https://playpen.accesspaysuite.com/api/v3
Environment::PRODUCTION; // https://ddcms.accesspaysuite.com/api/v3

Customer Management

use Rate\AccessPaysuite\Enums\CustomerTitle;

// Create a customer
$response = $service->createCustomer(
    title: CustomerTitle::MR,
    customerRef: 'CUST-001',      // unique per client
    surname: 'Smith',
    postCode: 'SW1A 1AA',
    accountNumber: '12345678',    // exactly 8 digits
    bankSortCode: '112233',       // exactly 6 digits
    accountHolderName: 'John Smith',
    line1: '1 Test Street',
    line2: 'London',
    firstName: 'John',
    email: 'john@example.com',
);

// Retrieve a customer
$customer = $service->getCustomer('customer-uuid');
echo $customer->FirstName;         // 'John'
echo $customer->BankDetail->AccountNumber; // '12345678'
echo $customer->AddressDetail->PostCode;   // 'SW1A 1AA'

// Search customers
$collection = $service->getCustomers(
    pageSize: 20,
    pageNumber: 1,
    includePagingDetail: true,
    surname: 'Smith',
);
echo count($collection->items);   // number of results
echo $collection->paging?->TotalRecords;

// Update a customer (partial update — only supplied fields are changed)
$service->updateCustomer('customer-uuid', email: 'new@example.com', firstName: 'Jonathan');

Contract Management

use Carbon\Carbon;
use Rate\AccessPaysuite\Enums\AtTheEnd;
use Rate\AccessPaysuite\Enums\TerminationType;

// Get available schedules first
$schedules = $service->getAvailableSchedules();

// Find the earliest valid start date
$dates = $service->getPaymentDates()->json();

// Create a contract
$response = $service->createContract(
    customerId: 'customer-uuid',
    terminationType: TerminationType::UNTIL_FURTHER_NOTICE,
    atTheEnd: AtTheEnd::EXPIRE,
    isGiftAid: false,
    start: Carbon::parse($dates['EarliestFirstPaymentDate']),
    scheduleName: 'Monthly',
    amount: 25.00,
    paymentDayInMonth: 1,
);

// List contracts for a customer
$contracts = $service->getContracts('customer-uuid');
foreach ($contracts as $contract) {
    echo $contract->Status->value;  // 'Active'
    echo $contract->Amount;         // 25.0
}

Payment Management

// Add an ad-hoc payment (minimum 5 working days in the future)
$service->addPayment(
    contractId: 'contract-uuid',
    amount: 50.00,
    date: Carbon::now()->addWeekdays(6),
    comment: 'Additional contribution',
);

// List recent payments
$payments = $service->getPayments('contract-uuid', rows: 10);
foreach ($payments as $payment) {
    echo $payment->Status->value;      // 'Pending'
    echo $payment->Date->format('Y-m-d');
}

// Update a payment (before BACS submission)
$service->updatePayment('contract-uuid', 'payment-uuid', 'Corrected amount', 30.00, Carbon::parse('2025-06-01'));

// Delete a payment (before BACS submission)
$service->deletePayment('contract-uuid', 'payment-uuid', 'Cancelled by customer');

Bulk Payments

$service->bulkAddPayments([
    [
        'contract' => 'contract-uuid-1',
        'amount'   => 25.00,
        'date'     => Carbon::now()->addWeekdays(6),
        'comment'  => 'Monthly collection',
    ],
    [
        'contract' => 'contract-uuid-2',
        'amount'   => 50.00,
        'date'     => Carbon::now()->addWeekdays(6),
    ],
]);

Contract Status Changes

$service->cancelContract('contract-uuid');
$service->reactivateContract('contract-uuid');
$service->archiveContract('contract-uuid');  // irreversible

use Rate\AccessPaysuite\Enums\AtTheEnd;
use Rate\AccessPaysuite\Enums\TerminationType;

$service->restartContract(
    contractId: 'contract-uuid',
    terminationType: TerminationType::UNTIL_FURTHER_NOTICE,
    atTheEnd: AtTheEnd::EXPIRE,
);

Contract Amendments

// Change the monthly payment day
$service->changeMonthlyDate('contract-uuid', monthDay: '15', comment: 'Customer request', patchNextPayment: false);

// Change the amount
$service->changeContractAmount('contract-uuid', amount: 30.00, comment: 'Price increase');

Patches (Temporary Modifications)

use Carbon\Carbon;

$from = Carbon::parse('2025-07-01');
$to   = Carbon::parse('2025-09-30');

// Freeze collections for a period
$service->addFreezePatch('contract-uuid', $from, $to, comment: 'Customer on holiday');

// Skip collections (contract schedule adjusts)
$service->addSkipPatch('contract-uuid', $from, $to, comment: 'Waived for 3 months');

// Change amount for a period
$service->addChangeAmountPatch('contract-uuid', $from, $to, amount: 10.00, comment: 'Reduced rate');

// List all patches
$patches = $service->getPatches('contract-uuid');

Questions & Answers

use Rate\AccessPaysuite\Enums\QuestionType;

// Create a custom question
$service->createQuestion(
    label: 'How did you hear about us?',
    type: QuestionType::LIST,
    isMandatory: false,
    options: 'Website,Social Media,Word of Mouth',
);

// Add an answer for a customer
$service->addAnswer('customer-uuid', 'question-uuid', 'Website');

Callback URLs

use Rate\AccessPaysuite\Enums\CallbackEntity;

// Register a webhook for payment BACS callbacks
$service->setCallbackUrl(CallbackEntity::PAYMENT, 'https://your-app.com/webhooks/paysuite');

// Remove a callback
$service->deleteCallbackUrl(CallbackEntity::PAYMENT);

Laravel Artisan Commands

When the package is installed in a Laravel application, three Artisan commands are available for managing callback URLs from the terminal.

List all callback URLs

Fetches all five entity callback URLs concurrently and displays them in a table:

php artisan paysuite:callback:list
+-------------+----------------------------------+
| Entity      | Callback URL                     |
+-------------+----------------------------------+
| bulkpayment | https://your-app.com/webhooks/bp |
| customer    | —                                |
| contract    | —                                |
| payment     | https://your-app.com/webhooks/py |
| schedule    | —                                |
+-------------+----------------------------------+

Set a callback URL

php artisan paysuite:callback:set {entity} {url}
php artisan paysuite:callback:set payment https://your-app.com/webhooks/payment

Delete a callback URL

php artisan paysuite:callback:delete {entity}
php artisan paysuite:callback:delete payment

Prompts for confirmation before deleting. Pass --no-interaction to skip the prompt (the command will safely no-op when non-interactive).

Valid entity values for all three commands: bulkpayment, customer, contract, payment, schedule.

Using Requests Directly

For fine-grained control, create request objects and send them via the connector:

use Rate\AccessPaysuite\Requests\Customer\GetCustomer;

$response = $connector->send(new GetCustomer('customer-uuid'));
$customer = $response->dto();      // typed Customer model
$raw      = $response->json();     // raw array

Direct Debit Process Overview

  1. Create a Customer with bank details and address.
  2. Call GET /paymentdate to find the earliest valid start date.
  3. Create a Contract referencing a schedule (from GET /schedules).
  4. The start date must be at least the First Payment Delay (default: 10 working days) in the future.
  5. For ad-hoc payments, the date must be at least the Subsequent Payment Delay (default: 5 working days) ahead.
  6. Payments are submitted to BACS ~3 working days before their collection date; they cannot be modified after submission.
  7. Final payment status is available ~3 working days after the collection date.

Running Tests

# Unit tests (with mock responses — no network calls)
composer test

# Static analysis
composer phpstan

# Code style check
composer check-style

# All quality checks
composer qa

# Live integration tests against the playpen environment
./vendor/bin/phpunit tests/LiveTest.php

Configure live test credentials in tests/.env (copy from tests/.env.example).

Support

For API support: support@accesspaysuite.com

For library issues: raise a ticket in Bitbucket.