Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
proteo committed Mar 24, 2021
0 parents commit 8683e2c
Show file tree
Hide file tree
Showing 50 changed files with 2,941 additions and 0 deletions.
11 changes: 11 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
root = true

[*]
end_of_line = lf
indent_size = 4
indent_style = space
trim_trailing_whitespace = true
insert_final_newline = true

[*.{json,yml,yaml}]
indent_size = 2
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
composer.lock
.phpunit.result.cache
vendor
339 changes: 339 additions & 0 deletions LICENSE

Large diffs are not rendered by default.

146 changes: 146 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
# Pin Payments API library.

This library enables the integration of the [Pin Payments API](https://pinpayments.com/developers/api-reference) with any PHP application.

## Requirements

- PHP 7.3 or above
- Composer

## Installation

Clone this repo:
```
git clone https://github.com/proteo/pin-php.git
```

Install composer dependencies:
```
cd pin-php
composer install
```

## Supported API endpoints

- **Cards**
- POST /cards
- **Charges**
- POST /charges
- PUT /charges/`charge-token`/void
- PUT /charges/`charge-token`/capture
- GET /charges
- GET /charges/`charge-token`
- **Customers**
- POST /customers
- GET /customers
- GET /customers/`customer-token`
- PUT /customers/`customer-token`
- DELETE /customers/`customer-token`
- **Plans**
- POST /plans
- GET /plans/
- GET /plans/`plan-token`
- PUT /plans/`plan-token`
- DELETE /plans/`plan-token`
- **Refunds**
- POST /charges/`charge-token`/refunds
- **Subscriptions**
- POST /subscriptions
- GET /subscriptions
- GET /subscriptions/`sub-token`
- PUT /subscriptions/`sub-token`
- DELETE /subscriptions/`sub-token`
- PUT /subscriptions/`sub-token`/reactivate
- GET /subscriptions/`sub-token`/ledger
- **Webhook Endpoints**
- POST /webhook_endpoints
- GET /webhook_endpoints
- GET /webhook_endpoints/`webhook-endpoint-token`
- DELETE /webhook_endpoints/`webhook-endpoint-token`

## How to use

Here's a brief example to get you started:

```php
<?php

use GuzzleHttp\Exception\RequestException;
use Pin\Configuration;
use Pin\Handler;

// Set your API settings.
$secret_key = 'ABCDEFGHIJKLMNOPQRSTUV123';
$public_key = 'ABCDEFGHIJKLMNOPQRSTUV456';
$environment = 'test'; /* or 'live' */

// Initialize a configuration object.
$config = new Configuration(
$secret_key,
$public_key,
$environment,
);

// Instantiate a handler with the configuration object. This is basically
// a helper that configures the request with the necessary bits before it
// can be submitted.
$handler = new Handler($config);

// You can create a request by passing a FQN class name and options as arguments
// (check the API reference to learn about options for each specific endpoint):
$handler->createRequest(Pin\Card\Create::class, [
'number' => '4200000000000000',
'expiry_month' => '12',
'expiry_year' => '2023',
'cvc' => '123',
'name' => 'Roland Robot',
'address_line1' => '42 Sevenoaks St',
'address_line2' => '',
'address_city' => 'Lathlain',
'address_postcode' => '6454',
'address_state' => 'WA',
'address_country' => 'Australia',
]);

// Finally, submit the request and grab its response. This should always be
// done inside a try block, as any error during the execution of the request
// will throw an exception:
try {
$response = $handler->submit();
} catch (RequestException $e) {
echo $e->getMessage();
}

echo '<pre>' . print_r($response, TRUE) . '</pre>';
```

If for some reason you need or prefer to instantiate the request separately (for example, if you plan to reuse the `$handler` instance), you can do it using the `$handler->setRequest()` method:

```php
<?php

// Instantiate a request separately...
$request = new Pin\Card\Create([
'number' => '4200000000000000',
'expiry_month' => '12',
'expiry_year' => '2023',
'cvc' => '123',
'name' => 'Roland Robot',
'address_line1' => '42 Sevenoaks St',
'address_line2' => '',
'address_city' => 'Lathlain',
'address_postcode' => '6454',
'address_state' => 'WA',
'address_country' => 'Australia',
]);

// ...and set it.
$handler->setRequest($request);

// Submit the request and grab its response.
try {
$response = $handler->submit();
} catch (RequestException $e) {
echo $e->getMessage();
}
```
34 changes: 34 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"name": "proteo/pin-php",
"description": "PHP library for Pinpayments.com API.",
"type": "library",
"homepage": "https://github.com/proteo/pin-php",
"license": "GPL-2.0+",
"authors": [
{
"name": "Proteo",
"email": "[email protected]"
}
],
"keywords": [
"payment",
"payments",
"pin",
"gateway"
],
"require": {
"php": ">=7.3.0",
"guzzlehttp/guzzle": "^6.5",
"guzzlehttp/psr7": "^1.7",
"symfony/options-resolver": "^5.2"
},
"require-dev": {
"phpunit/phpunit": "^9"
},
"autoload": {
"psr-4": {"Pin\\": "src"}
},
"autoload-dev": {
"psr-4": {"Pin\\Tests\\": "tests"}
}
}
11 changes: 11 additions & 0 deletions phpunit.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8" ?>
<phpunit bootstrap="vendor/autoload.php"
colors="true"
verbose="true"
stopOnFailure="true">
<testsuites>
<testsuite name="Pin API test suite">
<directory>tests</directory>
</testsuite>
</testsuites>
</phpunit>
59 changes: 59 additions & 0 deletions src/Card/Create.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php

declare(strict_types=1);

namespace Pin\Card;

use Pin\Request\Post as PostRequest;
use Symfony\Component\OptionsResolver\OptionsResolver;

/**
* Stores a card’s details and returns its token and other information.
*
* @link https://pinpayments.com/developers/api-reference/cards
*
* @package Pin\Card
*/
class Create extends PostRequest
{
/**
* Pin API endpoint path for this resource.
*
* @var string
*/
public const URI = '/cards';

/**
* {@inheritdoc}
*/
public function setDefaultOptions(OptionsResolver $resolver)
{
$resolver
->setRequired([
'number',
'expiry_month',
'expiry_year',
'cvc',
'name',
'address_line1',
'address_city',
'address_postcode',
'address_state',
'address_country',
])
->setDefined([
'address_line2',
])
->setAllowedTypes('number', 'numeric')
->setAllowedTypes('expiry_month', 'numeric')
->setAllowedTypes('expiry_year', 'numeric')
->setAllowedTypes('cvc', 'numeric')
->setAllowedTypes('name', 'string')
->setAllowedTypes('address_line1', 'string')
->setAllowedTypes('address_line2', 'string')
->setAllowedTypes('address_city', 'string')
->setAllowedTypes('address_postcode', 'numeric')
->setAllowedTypes('address_state', 'string')
->setAllowedTypes('address_country', 'string');
}
}
43 changes: 43 additions & 0 deletions src/Charge/Capture.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

declare(strict_types=1);

namespace Pin\Charge;

use Pin\Request\Put as PutRequest;

/**
* Captures a previously authorised charge and returns its details.
*
* @link https://pinpayments.com/developers/api-reference/charges#capture-charges
*
* @package Pin\Charge
*/
class Capture extends PutRequest
{
/**
* Pin API endpoint path for this resource.
*
* @var string
*/
public const URI = '/charges/__TOKEN__/capture';

/**
* The charge token.
*
* @var string
*/
protected $token;

/**
* Capture charge class constructor.
*
* @param string $token
* The charge token.
*/
public function __construct(string $token)
{
$this->token = $token;
parent::__construct();
}
}
74 changes: 74 additions & 0 deletions src/Charge/Create.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<?php

declare(strict_types=1);

namespace Pin\Charge;

use Pin\Configuration;
use Pin\Request\Post as PostRequest;
use Symfony\Component\OptionsResolver\Exception\MissingOptionsException;
use Symfony\Component\OptionsResolver\OptionsResolver;

/**
* Creates a new charge and returns its details.
*
* @link https://pinpayments.com/developers/api-reference/charges#post-charges
*
* @package Pin\Charge
*/
class Create extends PostRequest
{
/**
* Pin API endpoint path for this resource.
*
* @var string
*/
public const URI = '/charges';

/**
* {@inheritdoc}
*/
public function setDefaultOptions(OptionsResolver $resolver)
{
$resolver
->setRequired([
'amount',
'description',
'email',
'ip_address',
])
->setDefined([
'card',
'card_token',
'customer_token',
'currency',
'metadata',
'capture',
])
->setAllowedTypes('currency', 'string')
->setAllowedTypes('amount', 'numeric')
->setAllowedTypes('description', 'string')
->setAllowedTypes('email', 'string')
->setAllowedTypes('card', 'array')
->setAllowedTypes('card_token', 'string')
->setAllowedTypes('customer_token', 'string')
->setAllowedTypes('capture', 'boolean')
->setAllowedTypes('metadata', 'array')
->setAllowedValues('currency', Configuration::supportedCurrencies());
}

/**
* {@inheritdoc}
*/
public function validateOptions()
{
// Checks that one of the required options with card information exists.
if (
empty($this->options['card']) &&
empty($this->options['card_token']) &&
empty($this->options['customer_token'])
) {
throw new MissingOptionsException('Must provide one of the following options: card (array), card_token or customer_token.');
}
}
}
Loading

0 comments on commit 8683e2c

Please sign in to comment.