Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
composer.lock
/vendor/
/vendor/
./.idea
./.phpunit.result.cache
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
# NOWPayments API Client

Forked from onetoweb/nowpayments

## Installing

```bash
composer require onetoweb/nowpayments
composer require mkhab7/nowpayments
```

## Usage
Expand All @@ -13,4 +15,4 @@ See example.php

## Example webhook authentication

See webhook.php
See webhook.php
10 changes: 6 additions & 4 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name" : "onetoweb/nowpayments",
"name" : "mkhab7/nowpayments",
"description" : "NOWPayments API Client",
"keywords" : [
"api",
Expand All @@ -15,15 +15,17 @@
}
],
"require" : {
"php" : ">=7.1.0",
"php" : ">=8",
"guzzlehttp/guzzle": "^7.3"
},
"require-dev" : {
"symfony/error-handler" : "^5.1"
"symfony/error-handler" : "^5.1",
"pestphp/pest": "^1.22"
},
"autoload" : {
"psr-4" : {
"Onetoweb\\NOWPayments\\" : "src/"
}
},
"files": ["src/helpers.php"]
}
}
21 changes: 10 additions & 11 deletions example.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,25 @@

// params
$apiKey = 'api key';
$testModus = true;
$testMode = true;

// init NOWPayments client
$nowPaymentsClient = new NOWPaymentsClient($apiKey, $testModus);
$nowPaymentsClient = nowPay($apiKey,$testMode);

// get status
$status = $nowPaymentsClient->status->get();

$status = $nowPaymentsClient->status()->fetch();
// get currencies
$currencies = $nowPaymentsClient->currency->get();
$currencies = $nowPaymentsClient->currency()->fetch();

// estimate
$estimate = $nowPaymentsClient->estimate->get([
$estimate = $nowPaymentsClient->estimate()->fetch([
'amount' => 1,
'currency_from' => 'eur',
'currency_to' => 'doge'
]);

// create payment
$payment = $nowPaymentsClient->payment->create([
$payment = $nowPaymentsClient->pay()->create([
'price_amount' => 32,
'price_currency' => 'eur',
'pay_currency' => 'doge',
Expand All @@ -36,7 +35,7 @@

// get payment
$paymentId = 42;
$payment = $nowPaymentsClient->payment->get($paymentId);
$payment = $nowPaymentsClient->pay()->fetch($paymentId);

// list payments
$payments = $nowPaymentsClient->payment->list([
Expand All @@ -49,18 +48,18 @@
]);

// get min amount
$minAmount = $nowPaymentsClient->minAmount->get([
$minAmount = $nowPaymentsClient->amount()->fetch([
'currency_from' => 'btc',
'currency_to' => 'doge',
]);

// create invoice
$invoice = $nowPaymentsClient->invoice->create([
$invoice = $nowPaymentsClient->invoice()->create([
'price_amount' => 1000,
'price_currency' => 'eur',
'order_id' => 'order 1',
'order_description' => 'order_description',
'ipn_callback_url' => 'https://example.com/webhook.php',
'success_url' => 'https://example.com/webhook.php',
'cancel_url' => 'https://example.com/webhook.php'
]);
]);
18 changes: 18 additions & 0 deletions phpunit.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="./vendor/phpunit/phpunit/phpunit.xsd"
bootstrap="vendor/autoload.php"
colors="true"
>
<testsuites>
<testsuite name="Test Suite">
<directory suffix="Test.php">./tests</directory>
</testsuite>
</testsuites>
<coverage processUncoveredFiles="true">
<include>
<directory suffix=".php">./app</directory>
<directory suffix=".php">./src</directory>
</include>
</coverage>
</phpunit>
55 changes: 27 additions & 28 deletions src/Authentication.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,40 +2,39 @@

namespace Onetoweb\NOWPayments;

use Onetoweb\NOWPayments\Responses\DataResponse;

/**
* Authentication.
*
*
* @author Jonathan van 't Ende <jvantende@onetoweb.nl>
* @copyright Onetoweb B.V.
*/
class Authentication
{
/**
* @param string $content
* @param string $receivedHmac
* @param string $ipnSecret
*
* @return bool
*/
public static function authenticate(string $content, string $receivedHmac, string $ipnSecret): bool
public static function authenticated(?string $ipnSecret = null): bool|DataResponse
{
if (!empty($content) and !empty($receivedHmac) and !empty($ipnSecret)) {

$data = json_decode($content, true);
ksort($data);
$json = json_encode($data);

if ($json !== false and !empty($json)) {

$hmac = hash_hmac('sha512', $json, $ipnSecret);

if ($receivedHmac == $hmac) {
return true;
}

}
}

return false;
$ipnSecret ??= getenv('NOW_PAYMENT_SECRET');

if (empty($ipnSecret))
throw new \InvalidArgumentException('IPN secret does not exists. please set an IPN !');

if (empty($receivedHmac = $_SERVER['HTTP_X_NOWPAYMENTS_SIG'] ?? ''))
throw new \InvalidArgumentException('Can not find "HTTP_X_NOWPAYMENTS_SIG" in $_SERVER');

if (empty($requestJson = file_get_contents('php://input')))
throw new \InvalidArgumentException('The request body is empty !');


$requestData = json_decode($requestJson, true);
ksort($requestData);
$sorted_request_json = json_encode($requestData, JSON_UNESCAPED_SLASHES);
$hmac = hash_hmac('sha512', $sorted_request_json, trim($ipnSecret));

if ($hmac != $receivedHmac)
throw new \InvalidArgumentException('HMAC is not valid !');

return new DataResponse($requestData);
}
}

}
87 changes: 45 additions & 42 deletions src/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,16 @@
namespace Onetoweb\NOWPayments;

use Onetoweb\NOWPayments\Endpoint;
use Onetoweb\NOWPayments\Endpoint\Currency;
use Onetoweb\NOWPayments\Endpoint\Estimate;
use Onetoweb\NOWPayments\Endpoint\Invoice;
use Onetoweb\NOWPayments\Endpoint\MinAmount;
use Onetoweb\NOWPayments\Endpoint\Payment;
use Onetoweb\NOWPayments\Endpoint\Status;

/**
* Client.
*
*
* @author Jonathan van 't Ende <jvantende@onetoweb.nl>
* @copyright Onetoweb B.V.
*/
Expand All @@ -16,65 +22,62 @@ class Client
* API endpoint
*/
const API_ENDPOINT = 'https://api.nowpayments.io';
const API_SANDBOX_ENDPOINT = 'https://api.sandbox.nowpayments.io';

/**
* API version
*/
const API_SANDBOX_ENDPOINT = 'https://api-sandbox.nowpayments.io';
const API_VERSION = 'v1';

/**
* @var string
*/
private $apiKey;

/**
* @var bool
*/
private $testModus;

/**
* @param string $apiKey
* @param bool $testModus = false
*/
public function __construct(string $apiKey, bool $testModus = false)

public function __construct(protected string $apiKey, protected bool $testMode = false)
{
$this->apiKey = $apiKey;
$this->testModus = $testModus;

$this->initializeEndpoints();

}

/**
* @return string
*/
public function getApiKey(): string
{
return $this->apiKey;
}

/**
* @return string
*/
public function getApiEndpoint(): string
{
if ($this->testModus) {
if ($this->testMode) {
return self::API_SANDBOX_ENDPOINT;
}

return self::API_ENDPOINT;
}

/**
* Initialize endpoints.
*/
private function initializeEndpoints()

public function status(): Status
{
$this->status = new Endpoint\Status($this);
$this->currency = new Endpoint\Currency($this);
$this->payment = new Endpoint\Payment($this);
$this->estimate = new Endpoint\Estimate($this);
$this->invoice = new Endpoint\Invoice($this);
$this->minAmount = new Endpoint\MinAmount($this);
return new Status($this);
}
}

public function amount(): MinAmount
{
return new MinAmount($this);
}

public function currency(): Currency
{
return new Currency($this);
}

public function estimate(): Estimate
{
return new Estimate($this);
}

public function invoice(): Invoice
{
return new Invoice($this);
}

public function pay(): Payment
{
return new Payment($this);
}

}
Loading