Skip to content

Commit

Permalink
Merge pull request #49 from ThePay/v2.x-4650-http-psr
Browse files Browse the repository at this point in the history
4650 ThePay\ApiClient\Http replaced by PSR standarts
  • Loading branch information
Triplkrypl authored Jul 11, 2023
2 parents 9fa3c09 + 8f82beb commit 3e25a1e
Show file tree
Hide file tree
Showing 47 changed files with 573 additions and 1,097 deletions.
113 changes: 65 additions & 48 deletions .github/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,21 @@ interacts with The Pay's REST API. To get started see examples below.

## Requirements

- PHP 7.4+

- **curl** extension
- **json** extension
All necessary requirements are defined in [composer.json](../composer.json) `require` property.
We strongly recommend SDK installation using [Composer](https://getcomposer.org/)!

## Installation

To install the SDK we recommend to use [Composer](https://getcomposer.org/):

```console
composer require thepay/api-client
```

Installation with suggested PSR http client.

```console
composer require thepay/api-client guzzlehttp/guzzle
```

This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## Support & Contributions
Expand Down Expand Up @@ -54,15 +56,55 @@ You will work with only two classes when using this SDK.
All constructor parameters are described in [php doc](../src/TheConfig.php)

```php
$config = new ThePay\ApiClient\TheConfig(
$merchantId = '86a3eed0-95a4-11ea-ac9f-371f3488e0fa';
$projectId = 3;
$apiPassword = 'secret';
$apiUrl = 'https://demo.api.thepay.cz/'; // production: 'https://api.thepay.cz/'
$gateUrl = 'https://demo.gate.thepay.cz/'; // production: 'https://gate.thepay.cz/'
$language = 'cs';

$theConfig = new \ThePay\ApiClient\TheConfig(
$merchantId,
$projectId,
$apiPassword,
$apiUrl,
$gateUrl
);

$config->setLanguage($language);
$theConfig->setLanguage($language);
```

## TheClient instance

Before making `\ThePay\ApiClient\TheClient` instance, some dependencies must be prepared.

If you use some DI container automation, all other dependencies than `TheConfig`
should be auto-injected even PSR interfaces if you have some implementations
already installed in your application.

```php
/** @var \ThePay\ApiClient\TheConfig $theConfig */

// TheClient instance dependencies
$signatureService = new \ThePay\ApiClient\Service\SignatureService($theConfig);
/** @var \Psr\Http\Client\ClientInterface $httpClient some PSR-18 implementation */
/** @var \Psr\Http\Message\RequestFactoryInterface $requestFactory some PSR-17 implementation */
/** @var \Psr\Http\Message\StreamFactoryInterface $streamFactory some PSR-17 implementation */
// if you install suggested guzzle implementation you can use this:
// $httpClient = new \GuzzleHttp\Client();
// $requestFactory = $streamFactory = new \GuzzleHttp\Psr7\HttpFactory();
$apiService = new \ThePay\ApiClient\Service\ApiService(
$theConfig,
$signatureService,
$httpClient,
$requestFactory,
$streamFactory
);

$thePayClient = new \ThePay\ApiClient\TheClient(
$theConfig,
$apiService
);
```

## Usual workflow
Expand Down Expand Up @@ -124,31 +166,23 @@ Always create only one payment for your order for all payment creation options,

For more examples see [create-payment.md](../doc/create-payment.md)

```php
use ThePay\ApiClient\TheConfig;
use ThePay\ApiClient\TheClient;
use ThePay\ApiClient\Model\CreatePaymentParams;
[See how to make TheClient](#theclient-instance)

$merchantId = '86a3eed0-95a4-11ea-ac9f-371f3488e0fa';
$projectId = 3;
$apiPassword = 'secret';
$apiUrl = 'https://demo.api.thepay.cz/'; // production: 'https://api.thepay.cz/'
$gateUrl = 'https://demo.gate.thepay.cz/'; // production: 'https://gate.thepay.cz/'
```php

$config = new TheConfig($merchantId, $projectId, $apiPassword, $apiUrl, $gateUrl);
$thePay = new TheClient($config);
/** @var \ThePay\ApiClient\TheClient $thePayClient */

// Render payment methods for payment (100,- Kč)
$paymentParams = new CreatePaymentParams(10000, 'CZK', 'uid124');
$paymentParams = new \ThePay\ApiClient\Model\CreatePaymentParams(10000, 'CZK', 'uid124');

// display button, user will choose payment method at the payment gate
echo $thePay->getPaymentButton($paymentParams);
echo $thePayClient->getPaymentButton($paymentParams);

// or buttons with available payment methods, payment method will be preselected
// echo $thePay->getPaymentButtons($paymentParams);
// echo $thePayClient->getPaymentButtons($paymentParams);

// or just get payment link and redirect customer whenever you want
// $payment = $thePay->createPayment($createPayment);
// $payment = $thePayClient->createPayment($createPayment);
// $redirectLink = $payment->getPayUrl();
```

Expand All @@ -162,23 +196,14 @@ The state of payment must be checked at the time of customer return, since the p
For example the customer simply returns to the e-shop without paying.

#### General example of handling the customer return
```php
use ThePay\ApiClient\TheConfig;
use ThePay\ApiClient\TheClient;
use ThePay\ApiClient\Model\CreatePaymentParams;

$uid = $_GET["payment_uid"];
$projectId = $_GET["project_id"];
[See how to make TheClient](#theclient-instance)

$merchantId = '86a3eed0-95a4-11ea-ac9f-371f3488e0fa';
$apiPassword = 'secret';
$apiUrl = 'https://demo.api.thepay.cz/'; // production: 'https://api.thepay.cz/'
$gateUrl = 'https://demo.gate.thepay.cz/'; // production: 'https://gate.thepay.cz/'
```php

$config = new TheConfig($merchantId, $projectId, $apiPassword, $apiUrl, $gateUrl);
$thePay = new TheClient($config);
/** @var \ThePay\ApiClient\TheClient $thePayClient */

$payment = $thePay->getPayment($uid);
$payment = $thePayClient->getPayment($uid);

// check if the payment is paid
if ($payment->wasPaid()) {
Expand All @@ -191,21 +216,13 @@ if ($payment->wasPaid()) {

It's basically the same as second step (customer return), it's triggered everytime the payment has changed, for example when the state of payment has been changed.

```php
use ThePay\ApiClient\TheConfig;
use ThePay\ApiClient\TheClient;
use ThePay\ApiClient\Model\CreatePaymentParams;
[See how to make TheClient](#theclient-instance)

$uid = $_GET["payment_uid"];
$projectId = $_GET["project_id"];
```php

$merchantId = '86a3eed0-95a4-11ea-ac9f-371f3488e0fa';
$apiPassword = 'secret';
$apiUrl = 'https://demo.api.thepay.cz/'; // production: 'https://api.thepay.cz/'
$gateUrl = 'https://demo.gate.thepay.cz/'; // production: 'https://gate.thepay.cz/'
/** @var \ThePay\ApiClient\TheClient $thePayClient */

$config = new TheConfig($merchantId, $projectId, $apiPassword, $apiUrl, $gateUrl);
$thePay = new TheClient($config);
$payment = $thePayClient->getPayment($uid);

// check if the payment is paid
if ($payment->wasPaid()) {
Expand Down
23 changes: 20 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@ on:

jobs:
php82:
name: "php 8.2"
name: "php 8.2 psr/http-message 2.0"
runs-on: ubuntu-latest
container: "nofutur3/php-tests:8.2"
steps:
- name: Checkout repository
uses: actions/checkout@v3

- name: Install dependencies
run: composer install --no-interaction
run: composer update --no-interaction --with psr/http-message:^2.0

- name: Check code style
run: composer cs-check
Expand All @@ -26,6 +26,23 @@ jobs:
- name: Run tests
run: composer test

php82psrmessage10:
name: "php 8.2 psr/http-message 1.0"
runs-on: ubuntu-latest
container: "nofutur3/php-tests:8.2"
steps:
- name: Checkout repository
uses: actions/checkout@v3

- name: Install dependencies
run: composer update --no-interaction --with psr/http-message:^1.0

- name: Run static analysis
run: composer stan

- name: Run tests
run: composer test

php81:
name: "php 8.1"
runs-on: ubuntu-latest
Expand Down Expand Up @@ -77,7 +94,7 @@ jobs:
run: composer install --no-interaction

- name: Run static analysis
run: composer stan7
run: composer stan

- name: Run tests
run: composer test
Expand Down
13 changes: 8 additions & 5 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,20 @@
"type": "library",
"require": {
"php": "~7.4|~8.0",
"ext-curl": "*",
"ext-json": "*"
"ext-json": "*",
"psr/http-client": "^1.0",
"psr/http-factory": "^1.0",
"psr/http-message": "^1.0|^2.0"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "*",
"guzzlehttp/guzzle": "^7.7",
"phpstan/phpstan": "^1.9",
"phpunit/phpunit": "^9.0"
},
"suggest": {
"guzzlehttp/guzzle": "Widly used implementation of PSR-7 (psr/http-message), PSR-17 (psr/http-factory) and PSR-18 (psr/http-client)"
},
"config": {
"sort-packages": true
},
Expand All @@ -35,9 +41,6 @@
"test": [
"vendor/bin/phpunit tests --log-junit ./test-reports/junit.xml"
],
"stan7": [
"vendor/bin/phpstan analyse -c phpstan7.neon --memory-limit=1G"
],
"stan": [
"vendor/bin/phpstan analyse --memory-limit=1G"
]
Expand Down
4 changes: 2 additions & 2 deletions doc/change-payment-method-of-payment.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ This can be useful when you disallow to customer to change payment method in The


```php
/** @var \ThePay\ApiClient\TheClient $client */
/** @var \ThePay\ApiClient\TheClient $thePayClient */

/** @var non-empty-string $paymentMethodCode one method selected by user */

$client->changePaymentMethod('UID_OF_PAYMENT', $paymentMethodCode);
$thePayClient->changePaymentMethod('UID_OF_PAYMENT', $paymentMethodCode);

```
26 changes: 6 additions & 20 deletions doc/create-payment-recommended.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,10 @@
Example with optional detail information about customer.

```php
use ThePay\ApiClient\Model\Address;
use ThePay\ApiClient\Model\CreatePaymentCustomer;
use ThePay\ApiClient\TheConfig;
use ThePay\ApiClient\TheClient;
use ThePay\ApiClient\Model\CreatePaymentParams;

$merchantId = '86a3eed0-95a4-11ea-ac9f-371f3488e0fa';
$projectId = 3;
$apiPassword = 'secret';
// Connection to demo for testing
$apiUrl = 'https://demo.api.thepay.cz/';
$gateUrl = 'https://demo.gate.thepay.cz/';

$config = new TheConfig($merchantId, $projectId, $apiPassword, $apiUrl, $gateUrl);
$thePay = new TheClient($config);
/** @var \ThePay\ApiClient\TheClient $thePayClient */

// Create entity with information about customer
$customer = new CreatePaymentCustomer(
$customer = new \ThePay\ApiClient\Model\CreatePaymentCustomer(
'Mike',
'Smith',
'[email protected]',
Expand All @@ -31,13 +17,13 @@ $customer = new CreatePaymentCustomer(
);

// Create payment (105.20 € with unique id uid123)
$createPayment = new CreatePaymentParams(10520, 'EUR', 'uid123');
$createPayment = new \ThePay\ApiClient\Model\CreatePaymentParams(10520, 'EUR', 'uid123');
$createPayment->setOrderId('15478');
$createPayment->setDescriptionForCustomer('Payment for items on example.com');
$createPayment->setDescriptionForMerchant('Payment from VIP customer XYZ');
$createPayment->setCustomer($customer);

$payment = $thePay->createPayment($createPayment);
$payment = $thePayClient->createPayment($createPayment);

// Get url where user can pay
echo $payment->getPayUrl(); // https://demo.gate.thepay.cz/5aa4f4af546a74848/pay/
Expand All @@ -48,11 +34,11 @@ echo $payment->getPayUrl(); // https://demo.gate.thepay.cz/5aa4f4af546a74848/pay
In scenarios where you know the customer's preferred language, you can pass the language code in `CreatePaymentParams` constructor as the fourth argument. For example:

```php
$createPayment = new CreatePaymentParams(10520, 'EUR', 'uid123', 'en');
$createPayment = new \ThePay\ApiClient\Model\CreatePaymentParams(10520, 'EUR', 'uid123', 'en');
```

Possible values are described in ISO 639-1 standard. If you pass a language, that ThePay does not support, for example French (fr), then the English language will be used,
as is the most likely best choice for the customer. However, if the customer changed their language in ThePay system, then this setting will not have any impact.

You may wonder which language will be used if you do not enter any, then the language from TheConfig will be used, and if even here you did not select the default language,
the default language will be Czech (cs).
the default language will be Czech (cs).
14 changes: 7 additions & 7 deletions doc/create-payment.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Let's prepare payment of 1 CZK:
### Redirect user to gate without payment method

```php
$button = $client->getPaymentButton($params);
$button = $thePayClient->getPaymentButton($params);
```

### Redirect user to gate with specific payment method and/or specify custom button attributes
Expand All @@ -36,7 +36,7 @@ and method selection step is for user skipped in ThePay system.
/** @var non-empty-string $paymentMethodCode one method selected by user */

$buttonAttributes = array('class' => 'btn btn-success');
$button = $client->getPaymentButton($params, 'Button text', true, $paymentMethodCode, $buttonAttributes);
$button = $thePayClient->getPaymentButton($params, 'Button text', true, $paymentMethodCode, $buttonAttributes);
```

### Redirect user to gate with payment method selected
Expand All @@ -46,7 +46,7 @@ Method **getPaymentButtons** returns HTML code with form sended by click on paym
```php
/** @var string $paymentButtons */
// used default rendering
$paymentButtons = $client->getPaymentButtons($params);
$paymentButtons = $thePayClient->getPaymentButtons($params);
// Filter payment methods by tag. If tags are empty, all available methods will be displayed.
$onlyMethodsWithTags = array(
\ThePay\ApiClient\ValueObject\PaymentMethodTag::ONLINE,
Expand All @@ -58,12 +58,12 @@ Method **getPaymentButtons** returns HTML code with form sended by click on paym
// only payment methods matched used filter will be rendered in HTML,
// but be still available for user in payment process!
$filter = new \ThePay\ApiClient\Filter\PaymentMethodFilter(array(), $onlyMethodsWithTags, $onlyMethodsWithoutTags);
$paymentButtons = $client->getPaymentButtons($params, $filter);
$paymentButtons = $thePayClient->getPaymentButtons($params, $filter);
// used without css styles
// third bool parameter disable default css styles and javascript for payment method buttons
// css styles are rendered in <style> tag in begin of rendered HTML
// if default styles are disabled some custom styles must be implemented
$paymentButtons = $client->getPaymentButtons($params, null, false);
$paymentButtons = $thePayClient->getPaymentButtons($params, null, false);
```
Payment method buttons should look like this, second image is with hover.
Expand Down Expand Up @@ -104,7 +104,7 @@ set **$useInlineAssets** parameter to false and join CSS and JS on your own.

```php
// The third parameter disables joining inline styles and javascript
echo $client->getPaymentButtons($params, null, false);
echo $thePayClient->getPaymentButtons($params, null, false);
```

Adding thepay javascript to your own package
Expand Down Expand Up @@ -137,7 +137,7 @@ If even our HTML is not suitable for you we recommend create payment via API.

```php
/** @var \ThePay\ApiClient\Model\CreatePaymentResponse $response */
$response = $client->createPayment($params);
$response = $thePayClient->createPayment($params);
```

*CreatePaymentResponse* has two properties with url for redirection user to payment gate:
Expand Down
Loading

0 comments on commit 3e25a1e

Please sign in to comment.