PHPackages                             cyclesoftware/oauth2-twsc - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Authentication &amp; Authorization](/categories/authentication)
4. /
5. cyclesoftware/oauth2-twsc

ActiveLibrary[Authentication &amp; Authorization](/categories/authentication)

cyclesoftware/oauth2-twsc
=========================

CycleSoftware TWSC OAuth 2.0 Client Provider for The PHP League OAuth2-Client

2.7(2mo ago)038.6k↓17.7%MITPHPPHP &gt;=7.0.0CI failing

Since Mar 23Pushed 2mo ago5 watchersCompare

[ Source](https://github.com/CycleSoftware/oauth2-twsc)[ Packagist](https://packagist.org/packages/cyclesoftware/oauth2-twsc)[ RSS](/packages/cyclesoftware-oauth2-twsc/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (10)Dependencies (8)Versions (28)Used By (0)

This client is deprecated.
==========================

[](#this-client-is-deprecated)

Please refer to [CycleSoftware documentation](https://docs.cyclesoftware.nl/).

CycleSoftware Twsc Provider and Client for accessing TWSC Api Resources
=======================================================================

[](#cyclesoftware-twsc-provider-and-client-for-accessing-twsc-api-resources)

This package provides CycleSoftware TWSC Api support using PHP League's [OAuth 2.0 Client](https://github.com/thephpleague/oauth2-client).

Install
-------

[](#install)

Via Composer

```
$ composer require cyclesoftware/oauth2-twsc
```

Usage with authorization grant
------------------------------

[](#usage-with-authorization-grant)

Usage scenario is very similar to the one for The League's OAuth client, using `\League\OAuth2\Client\Provider\Twsc` as the provider.

```
$provider = new League\OAuth2\Client\Provider\Twsc([
    'clientId'     => '{cs-client-id}',
    'clientSecret' => '{cs-client-secret}',
    'redirectUri'  => 'https://example.com/callback-url',
]);

if (!isset($_GET['code'])) {

    // If we don't have an authorization code then get one
    $authUrl = $provider->getAuthorizationUrl();
    $_SESSION['oauth2state'] = $provider->getState();
    header('Location: '.$authUrl);
    exit;

// Check given state against previously stored one to mitigate CSRF attack
} elseif (empty($_GET['state']) || ($_GET['state'] !== $_SESSION['oauth2state'])) {

    unset($_SESSION['oauth2state']);
    exit('Invalid state');

} else {

    // Try to get an access token (using the authorization code grant)
    $token = $provider->getAccessToken('authorization_code', [
        'code' => $_GET['code']
    ]);

    // Optional: Now you have a token you can look up a users profile data
    try {

        // We got an access token, now we can access resources on TWSC Api
        // First create client
        $client = new League\OAuth2\Client\Provider\Client($provider);
        // now we can get list of available repair codes
        $result = $client->getRepairCodes($token);
        // We have list of repair codes
        print_r($result);

    } catch (Exception $e) {
        // Failed to get resources
        exit('Oh dear...');
    }

    // Use this to interact with an API on the users behalf
    echo $token->getToken();
}
```

Class Client has lot of implemented methods for getting resources from server.

There are two create and update methods to create new objects and update existing ones. We illustrate creation of RepairObject using Client. Scenario is pretty much as the previous, and we assume that we already have access token.

```
    try {

        // We got an access token, now we can access resources on TWSC Api
        // First create client
        $client = new League\OAuth2\Client\Provider\Client($provider);
        // Create RepairObject instance
        $repairObject = new League\OAuth2\Client\Provider\ValueObjects\RepairObject();
        // Fill repairObject fields
        $repairObject->is_active = 1;
        $repairObject->object_barcode = '3600 2600';
        $repairObject->customer_id = 2002;
        $repairObject->object_type_name = 'bicycle';
        $repairObject->brand = 'A-bike';
        $repairObject->model = 'mountain bike';
        $repairObject->color = 'red';
        $repairObject->phone_number_id = '12345';
        $repairObject->license_plate = 'nl 1234';
        $repairObject->km_mileage = '200';
        $repairObject->frame_id = 'HK6429';
        $repairObject->chip_id = '4321';
        $repairObject->key_id = '1234';
        $repairObject->engine_id = '4321';
        $repairObject->model_year = '2017';
        $repairObject->battery_id = '1234';
        $repairObject->lock_id = '4321';
        // Now we can create repair object on the server
        $repairObjectId = $client->createRepairObject($token, $repairObject);
        // We got repair object identifier
        print_r($repairObjectId);
    } catch (Exception $e) {
        // Failed to create repair object
        exit('Oh dear...');
    }
```

Usage with client\_credentials grant
------------------------------------

[](#usage-with-client_credentials-grant)

When using a credentials grant the first step is to obtain an AccessToken.

```
try {
    $provider = new League\OAuth2\Client\Provider\Twsc([
        'clientId'     => '{cs-client-id}',
        'clientSecret' => '{cs-client-secret}',
    ]);
    $access_token = $provider->getAccessToken('client_credentials');
    $customer = new Customer();
    $customer->customer_reference = ''; // e.g. your customer number
    $customer->postcode = '100AM';
    $customer->house_number = '1';
    $customer->house_number_postfix = '2';
    $customer->title = 'Dhr.';
    $customer->initials = 'A';
    $customer->insertion = 'van';
    $customer->name = 'Laak';
    $customer->street = 'Hoofdweg';
    $customer->city = 'Amsterdam';
    $customer->country_code_iso_3166 = 'NL';
    $customer->email = 'email@mail.com';
    $customer->discount_percentage = 10;
    $customer_phones = [];
    $customer_phone = new CustomerPhone();
    $customer_phone->phone_number = '+31612345678';
    $customer_phones[] = $customer_phone;
    $customer_phone = new CustomerPhone();
    $customer_phone->phone_number = '+3173030050';
    $customer_phones[] = $customer_phone;
    $customer->phone_numbers = $customer_phones;
    $client = new Client($provider);
    $result = $client->createCustomer($access_token, $customer);
} catch(League\OAuth2\Client\Provider\ClientErrorException $e){
    // ClientErrorException gives you information about what went wrong
    // echo $e->getMessage();
    // echo $e->getReason();
    // echo $e->getMessageNL();
}
```

Create a Repair Order
---------------------

[](#create-a-repair-order)

```
try {
    $provider = new League\OAuth2\Client\Provider\Twsc([
        'clientId' => '{cs-client-id}',
        'clientSecret' => '{cs-client-secret}',
    ]);
    $access_token = $provider->getAccessToken('client_credentials');
    $repair = new Repair();
    $repair->customer_id = 24;
    $repair->repair_object_id = 1105;
    $repair->reference_text = 'some-reference'; // your reference
    $repair->datetime_scheduled_start = '2019-03-11T15:41:46+01:00';
    $repair->mechanic_employee_id = 1; // default for TWSC 1
    $repair->repair_description = 'Some description of the repair order';
    /**
     * Status:
     * STATUS_WAIT_FOR_OBJECT = 1;
     * STATUS_WAIT_FOR_REPAIR = 2;
     * STATUS_WAIT_FOR_ARTICLES = 3;
     * STATUS_IN_REPAIR = 4;
     * STATUS_WAIT_FOR_CUSTOMER = 5;
     * STATUS_WAIT_FOR_INVOICE = 6;
     * STATUS_COMPLETED = 7;
     * STATUS_DONE = 8;
     * STATUS_WAIT_FOR_SUPPLIER = 9;
     * STATUS_WAIT_FOR_OBJECT_ONLINE = 10;
     * STATUS_WAIT_FOR_INSURANCE = 11;
     * STATUS_WAIT_FOR_INSURANCE_EXPERT = 12;
     * STATUS_PICKUP_AT_CUSTOMER = 13;
     * STATUS_WAIT_FOR_OBJECT_SUPPLIER = 14;
     * STATUS_CANCELLED = 15;
     * STATUS_DECLINED = 16;
     */
    $repair->status_id = 10; // default: 10
    $repair->custom_repair_time_minutes = 0; // time not related to order_items

    // add a normal article
    $item = new RepairOrderItem();
    $item->item_type_id = 1; // 1: Article, 4: RepairCode
    $item->special_type_id = 1;
    $item->quantity = 1;
    $item->barcode = '8712812812';
    $item->pos_group_id = 2; // 2: Repair, 21: Parts
    $item->description = 'In- en uitbouwen electromotor in- en uitbouwen accu';
    $item->unit_price_in_vat_cents = 12100;
    $item->unit_discount_amount_in_vat_cents = 0;
    $item->price_in_vat_cents = 12100;
    $item->discount_percentage = 0;
    $item->vat_code = 2; // 1: LOW VAT; 2: HIGH VAT, 0: NO VAT
    $item->vat_percentage = 21.0;
    $item->vat_amount_cents = 2100;
    $item->item_status_id = 0; // 0: No status, 1: Ordered at supplier 2: Ready for pickup 3: Delivered 4: Picked up 5: Cancelled
    $item->unit_work_time_minutes = 15;
    $repair->order_items[] = $item;

    $client = new Client($provider);
    $result = $client->createRepair($access_token, $repair);
}
catch (League\OAuth2\Client\Provider\ClientErrorException $e) {
    // ClientErrorException gives you information about what went wrong
    // echo $e->getMessage();
    // echo $e->getReason();
    // echo $e->getMessageNL();
}
```

Update a Repair Order With Order items
--------------------------------------

[](#update-a-repair-order-with-order-items)

Make sure that service\_items and repair\_codes have the value null. Only the order\_item provided in the array order\_items are updated. When adding new order items, leave item\_id=null. When an existing order\_item is omitted in the PUT, it will not be deleted or updated. To cancel an item use item\_status\_id=5

Find a customer to prevent duplicates
-------------------------------------

[](#find-a-customer-to-prevent-duplicates)

When creating customers try to avoid creating new customers by keeping an index of created customers and reuse the customer-id or by finding a customer based on unique identifiers such as phone-number or email.

```
try {
    $provider = new League\OAuth2\Client\Provider\Twsc([
        'clientId' => '{cs-client-id}',
        'clientSecret' => '{cs-client-secret}',
    ]);
    $access_token = $provider->getAccessToken('client_credentials');

    $client = new Client($provider);
    $result = $client->findCustomers($token, ['phone_number' => '0733030050']);
    var_dump($result);
    if(empty($result)){
        $result = $client->findCustomers($token, ['email' => 'example@domain.nl']);
    }
    var_dump($result);
}
catch (League\OAuth2\Client\Provider\ClientErrorException $e) {
    // ClientErrorException gives you information about what went wrong
    // echo $e->getMessage();
    // echo $e->getReason();
    // echo $e->getMessageNL();
}
```

Testing
-------

[](#testing)

```
$ ./vendor/bin/phpunit
```

Security
--------

[](#security)

If you discover any security related issues, please email :author\_email instead of using the issue tracker.

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

52

—

FairBetter than 96% of packages

Maintenance85

Actively maintained with recent releases

Popularity28

Limited adoption so far

Community12

Small or concentrated contributor base

Maturity68

Established project with proven stability

 Bus Factor1

Top contributor holds 54.7% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~172 days

Recently: every ~542 days

Total

20

Last Release

77d ago

Major Versions

0.1 → 1.32017-11-10

1.3 → 2.02017-12-07

PHP version history (3 changes)1.0PHP &gt;=5.5.0

2.0PHP &gt;=5.6.0

2.2PHP &gt;=7.0.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/8ee50f16ea88a080f0922b0b37b1345039a02a2c3986d6bd554077c1c5ecd5a5?d=identicon)[gielwijgergangs](/maintainers/gielwijgergangs)

---

Top Contributors

[![gielwijgergangs](https://avatars.githubusercontent.com/u/1364607?v=4)](https://github.com/gielwijgergangs "gielwijgergangs (41 commits)")[![coacoacoa](https://avatars.githubusercontent.com/u/8606228?v=4)](https://github.com/coacoacoa "coacoacoa (31 commits)")[![DaanBaars](https://avatars.githubusercontent.com/u/46622305?v=4)](https://github.com/DaanBaars "DaanBaars (3 commits)")

---

Tags

clientAuthenticationoauthoauth2authorizationcyclesoftware

###  Code Quality

TestsPHPUnit

Code StylePHP\_CodeSniffer

### Embed Badge

![Health badge](/badges/cyclesoftware-oauth2-twsc/health.svg)

```
[![Health](https://phpackages.com/badges/cyclesoftware-oauth2-twsc/health.svg)](https://phpackages.com/packages/cyclesoftware-oauth2-twsc)
```

###  Alternatives

[league/oauth2-google

Google OAuth 2.0 Client Provider for The PHP League OAuth2-Client

42121.2M118](/packages/league-oauth2-google)[cakedc/oauth2-cognito

Cognito OAuth 2.0 Client Provider for The PHP League OAuth2-Client

18597.7k](/packages/cakedc-oauth2-cognito)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
