Compare commits
No commits in common. "master" and "2.2.x" have entirely different histories.
@ -4,9 +4,6 @@ php:
|
||||
- 5.4
|
||||
- 5.5
|
||||
- 5.6
|
||||
- 7.0
|
||||
- 7.1
|
||||
- 7.2
|
||||
|
||||
install:
|
||||
- composer install
|
||||
|
||||
80
CHANGELOG.md
80
CHANGELOG.md
@ -2,86 +2,6 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
This project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
## [2.2.20] - 2018-03-28
|
||||
### Fixed
|
||||
- Fixed failing phpunit tests (#262)
|
||||
- Fixed DateTime zone issues (#261)
|
||||
- Fixed $invoice->getPaymentTotals() returns subTotals instead (#264)
|
||||
|
||||
## [2.2.19] - 2018-03-08
|
||||
### Added
|
||||
- Added support for BCH fields in the invoice: transactionCurrency, amountPaid, exchangeRates, paymentSubtotals, paymentTotals
|
||||
|
||||
### Fixed
|
||||
- Set timezone to UTC (=timezone that BitPay invoices use), to prevent PHP errors when no default timezone is set
|
||||
|
||||
### Deprecated
|
||||
- Deprecated BTC specific fields, as documented at https://bitpay.com/api#resource-Invoices
|
||||
|
||||
|
||||
## [2.2.18] - 2018-01-15
|
||||
### Fixed
|
||||
- Pushed actual code changes to GitHub from previous release
|
||||
|
||||
|
||||
## [2.2.17] - 2018-01-15
|
||||
### Fixed
|
||||
- Fixed decimal check for currencies without decimals (e.g. HUF)
|
||||
|
||||
## [2.2.16] - 2017-12-12
|
||||
### Fixed
|
||||
- Fixed invoice time being set in milliseconds, whereas seconds are expected (Issue #256 and #257)
|
||||
- Removed deprecated factory methods from services.xml
|
||||
|
||||
|
||||
## [2.2.15] - 2017-11-28
|
||||
### Fixed
|
||||
- Fixed invoice time being set as numeric instead of datetime object
|
||||
|
||||
### Removed
|
||||
- Removed support for mcrypt (#254)
|
||||
|
||||
|
||||
## [2.2.14] - 2017-09-27
|
||||
### Fixed
|
||||
- Fixed token check in get invoices method for public facade calls (#243)
|
||||
- Spell fixes (#233 and #233)
|
||||
- Fix some of the tests (#228)
|
||||
|
||||
### Added
|
||||
- Added encrypt & decrypt functions to OpenSSL (#247)
|
||||
|
||||
|
||||
## [2.2.13] - 2017-05-12
|
||||
### Fixed
|
||||
- Updated VERSION and changelog
|
||||
- Clarified tutorial text
|
||||
|
||||
|
||||
## [2.2.12] - 2017-05-09
|
||||
### Added
|
||||
- Included IPN processor example in tutorials
|
||||
|
||||
### Fixed
|
||||
- broken exception in Client.php
|
||||
|
||||
|
||||
## [2.2.11] - 2017-05-09
|
||||
### Added
|
||||
- Added refund addresses to getInvoice
|
||||
- Included extendedNotifications
|
||||
|
||||
Included buyer notify field (when creating an invoice)
|
||||
### Fixed
|
||||
- Improved tutorial (https://github.com/bitpay/php-bitpay-client/tree/master/examples/tutorial)
|
||||
- Made fullNotifications=true default
|
||||
- Symfony v3 compatibility fixes
|
||||
- PHP 7 compatibility fixes
|
||||
|
||||
## [2.2.9] - 2017-02-21
|
||||
### Fixed
|
||||
- HTTP 100 messages not parsed correctly when doing payouts
|
||||
|
||||
## [Unreleased][unreleased]
|
||||
### Changed
|
||||
- Refactored function calls out of loops
|
||||
|
||||
29
README.md
29
README.md
@ -1,7 +1,3 @@
|
||||
# === Warning ===
|
||||
|
||||
This is the old BitPay based PHP client and should be considered deprecated (even though it currently still works). If you are building something from scratch, [use the new Greenfield API](https://github.com/btcpayserver/btcpayserver-greenfield-php).
|
||||
|
||||
bitpay/php-bitpay-client
|
||||
=================
|
||||
|
||||
@ -37,15 +33,8 @@ Add to your composer.json file by hand.
|
||||
...
|
||||
"require": {
|
||||
...
|
||||
"bitpay/php-client": "dev-master"
|
||||
},
|
||||
"repositories": [
|
||||
...
|
||||
{
|
||||
"type": "vcs",
|
||||
"url": "https://github.com/btcpayserver/php-bitpay-client"
|
||||
}
|
||||
],
|
||||
"bitpay/php-client": "^2.2"
|
||||
}
|
||||
...
|
||||
}
|
||||
```
|
||||
@ -59,12 +48,12 @@ php composer.phar update bitpay/php-client
|
||||
### Install using composer
|
||||
|
||||
```bash
|
||||
php composer.phar require bitpay/php-client:~2.2
|
||||
php composer.phar require bitpay/php-client:^2.2
|
||||
```
|
||||
|
||||
# Configuration
|
||||
|
||||
See https://support.bitpay.com/hc/en-us/articles/115003001063-How-do-I-configure-the-PHP-BitPay-Client-Library-
|
||||
See https://labs.bitpay.com/t/php-bitpay-client-library-configuration/555
|
||||
|
||||
# Usage
|
||||
|
||||
@ -92,21 +81,19 @@ Please see the ``docs`` directory for information on how to use this library
|
||||
and the ``examples`` directory for examples on using this library. You should
|
||||
be able to run all the examples by running ``php examples/File.php``.
|
||||
|
||||
The ``examples/tutorial`` directory provides four scripts that guide you with creating a BitPay invoice:
|
||||
https://github.com/bitpay/php-bitpay-client/blob/master/examples/tutorial/
|
||||
Reading the latest documentation at https://labs.bitpay.com/c/libraries/php might also help.
|
||||
|
||||
# Support
|
||||
|
||||
* https://github.com/bitpay/php-bitpay-client/issues
|
||||
* https://support.bitpay.com
|
||||
|
||||
When you receive blank IPN responses, please check https://support.bitpay.com/hc/en-us/articles/115003025706-Why-am-I-getting-a-blank-IPN-post-response-from-BitPay-when-using-PHP-
|
||||
* https://labs.bitpay.com/c/libraries/php
|
||||
* https://support.bitpay.com/
|
||||
|
||||
# License
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2017 BitPay, Inc.
|
||||
Copyright (c) 2015 BitPay, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@ -28,8 +28,9 @@
|
||||
"ext-curl": "*",
|
||||
"ext-json": "*",
|
||||
"ext-openssl": "*",
|
||||
"symfony/config": "^2.3 || ^3.0",
|
||||
"symfony/dependency-injection": "^2.3 || ^3.0"
|
||||
"ext-mcrypt": "*",
|
||||
"symfony/config": "2.5.*",
|
||||
"symfony/dependency-injection": "2.5.*"
|
||||
},
|
||||
"require-dev": {
|
||||
"behat/behat": "2.5.*@stable",
|
||||
|
||||
@ -29,7 +29,7 @@ $buyer
|
||||
->setFirstName('Some')
|
||||
->setLastName('Customer')
|
||||
->setPhone('555-5555-5555')
|
||||
->setEmail('test@test.com')
|
||||
->setEmail('integrations@bitpay.com')
|
||||
->setAddress(
|
||||
array(
|
||||
'123 Main St',
|
||||
@ -66,31 +66,16 @@ $currency->setCode('USD');
|
||||
$invoice->setCurrency($currency);
|
||||
|
||||
/**
|
||||
* To load up keys that you have previously saved, you need to use the same
|
||||
* storage engine. You also need to tell it the location of the key you want
|
||||
* to load.
|
||||
* Create a new client. You can see the example of how to configure this using
|
||||
* a yml file as well.
|
||||
*/
|
||||
$storageEngine = new \Bitpay\Storage\FilesystemStorage();
|
||||
$privateKey = $storageEngine->load('/tmp/private.key');
|
||||
$publicKey = $storageEngine->load('/tmp/public.key');
|
||||
|
||||
/**
|
||||
* Create a new client.
|
||||
*/
|
||||
$bitpay = new \Bitpay\Bitpay();
|
||||
$bitpay = new \Bitpay\Bitpay(__DIR__ . '/config.yml');
|
||||
|
||||
/**
|
||||
* Create the client that will be used to send requests to BitPay's API
|
||||
*/
|
||||
$client = $bitpay->get('client');
|
||||
|
||||
$client->setPrivateKey($privateKey);
|
||||
$client->setPublicKey($publicKey);
|
||||
/**
|
||||
* Add your btcpayserver url
|
||||
*/
|
||||
$client->setUri('https://btcpay.server/');
|
||||
|
||||
/**
|
||||
* You will need to set the token that was returned when you paired your
|
||||
* keys.
|
||||
|
||||
@ -30,7 +30,8 @@ printf("Public Key: %s\n", $public);
|
||||
printf("Private Key: %s\n", $private);
|
||||
printf("Sin Key: %s\n\n", $sin);
|
||||
|
||||
$manager = new \Bitpay\KeyManager(new \Bitpay\Storage\EncryptedFilesystemStorage('dN$8WNaT}j<gD3*q'));
|
||||
|
||||
$manager->persist($private);
|
||||
$manager->persist($public);
|
||||
/**
|
||||
* NOTE: You MUST save your keypairs and not regenerate them once you have already
|
||||
* generated a pair and have paired them with the BitPay's API. To see how to
|
||||
* persist keys to the filesystem, please see the SaveKeypairsToFilesystem.php
|
||||
*/
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
|
||||
/**
|
||||
* WARNING - This example will NOT work until you have generated your public
|
||||
* and private keys. Please see the example documentation on generating your
|
||||
* keys and also see the documentation on how to save those keys.
|
||||
*
|
||||
* Also please be aware that you CANNOT create an invoice until you have paired
|
||||
@ -18,41 +19,52 @@ $time = gmdate("Y-m-d\TH:i:s\.", 1414691179)."000Z";
|
||||
$token = new \Bitpay\Token();
|
||||
$token
|
||||
->setFacade('payroll')
|
||||
->setToken('<your payroll facade-enable token>'); //this is a special api that requires a explicit payroll relationship with BitPay
|
||||
|
||||
->setToken('your token here');
|
||||
|
||||
$instruction1 = new \Bitpay\PayoutInstruction();
|
||||
$instruction1
|
||||
->setAmount(100)
|
||||
->setAddress('2NA5EVH9HHHhM5RxSEWf54gP4v397EmFTxi')
|
||||
->setLabel('Paying Chris');
|
||||
->setAmount(990)
|
||||
->setAddress('n3Sx4askJeykUYk24sS5rQoCEm8BpwVrNg')
|
||||
->setLabel('Paying Tom');
|
||||
|
||||
$instruction2 = new \Bitpay\PayoutInstruction();
|
||||
$instruction2
|
||||
->setAmount(1490)
|
||||
->setAddress('mxRN6AQJaDi5R6KmvMaEmZGe3n5ScV9u33')
|
||||
->setLabel('Paying Harry');
|
||||
|
||||
$payout = new \Bitpay\Payout();
|
||||
$payout
|
||||
->setEffectiveDate($time)
|
||||
->setAmount(100)
|
||||
->setCurrency(new \Bitpay\Currency('USD'))
|
||||
->setPricingMethod('bitcoinbestbuy')
|
||||
->setReference('a reference, can be json')
|
||||
->setNotificationEmail('me@example.com')
|
||||
->setNotificationUrl('https://example.com/ipn.php')
|
||||
->setNotificationEmail('your@email.com')
|
||||
->setNotificationUrl('https://yoursite.com/callback')
|
||||
->setToken($token)
|
||||
->addInstruction($instruction1);
|
||||
->addInstruction($instruction1)
|
||||
->addInstruction($instruction2);
|
||||
|
||||
$private = new \Bitpay\PrivateKey();
|
||||
$private->setHex('662be90968bc659873d723374213fa5bf7a30c24f0f0713aa798eb7daa7230fc'); //this is your private key in some form (see GetKeys.php)
|
||||
|
||||
$public = new \Bitpay\PublicKey();
|
||||
$public->generate($private);
|
||||
/**
|
||||
* Create a new client. You can see the example of how to configure this using
|
||||
* a yml file as well.
|
||||
*/
|
||||
$bitpay = new \Bitpay\Bitpay(
|
||||
array(
|
||||
'bitpay' => array(
|
||||
'network' => 'testnet', // testnet or livenet, default is livenet
|
||||
'public_key' => getenv('HOME').'/.bitpayphp/api.pub',
|
||||
'private_key' => getenv('HOME').'/.bitpayphp/api.key',
|
||||
'key_storage' => 'Bitpay\Storage\FilesystemStorage',
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
$adapter = new \Bitpay\Client\Adapter\CurlAdapter();
|
||||
|
||||
$bitpay = new \Bitpay\Bitpay();
|
||||
|
||||
$client = new \Bitpay\Client\Client();
|
||||
$client->setPrivateKey($private);
|
||||
$client->setPublicKey($public);
|
||||
$client->setUri('https://btcpay.server/');
|
||||
$client->setAdapter($adapter);
|
||||
/**
|
||||
* Create the client that will be used to send requests to BitPay's API
|
||||
*/
|
||||
$client = $bitpay->get('client');
|
||||
|
||||
$client->createPayout($payout);
|
||||
|
||||
|
||||
@ -7,7 +7,6 @@ require __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
$bitpay = new \Bitpay\Bitpay(__DIR__ . '/config.yml');
|
||||
$client = $bitpay->get('client');
|
||||
$client->setUri('https://btcpay.server/');
|
||||
$currencies = $client->getCurrencies();
|
||||
|
||||
/** @var \Bitpay\Currency $currencies[0] **/
|
||||
|
||||
@ -1,36 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (c) 2014-2016 BitPay
|
||||
*/
|
||||
|
||||
require __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
$private = new \Bitpay\PrivateKey();
|
||||
//if you've got a hex-encoded private key string, you can use it to create a private key
|
||||
$private->setHex('662be90968bc659873d723374213fa5bf7a30c24f0f0713aa798eb7daa7230fc');
|
||||
$public = new \Bitpay\PublicKey();
|
||||
$public->generate($private);
|
||||
$sin = $public->getSin();
|
||||
|
||||
printf("Public Key: %s\n", $public);
|
||||
printf("Private Key: %s\n", $private);
|
||||
printf("Sin Key: %s\n\n", $sin);
|
||||
|
||||
$keypair = array($private->getHex(), $public->getHex());
|
||||
|
||||
printf("PEM keypair: %s\n", $private->pemEncode($keypair));
|
||||
|
||||
|
||||
// -or- if you've got a PEM-encoded text file containing your key pair, we can use this
|
||||
|
||||
$keys = file_get_contents(getenv('HOME') . '/.php-bitpay-client/key.pem');
|
||||
if (isset($keys) && strlen($keys) > 0) {
|
||||
$keys = chop($keys);
|
||||
|
||||
$private = new \Bitpay\PrivateKey();
|
||||
$private->setHex($private->pemDecode($keys)['private_key']);
|
||||
printf("\n\n");
|
||||
printf("Public Key: %s\n", $private->getPublicKey());
|
||||
printf("Private Key: %s\n", $private);
|
||||
printf("Sin Key: %s\n\n", $private->getPublicKey()->getSin());
|
||||
}
|
||||
@ -1,20 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (c) 2014-2015 BitPay
|
||||
*/
|
||||
|
||||
require __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
$client = new \Bitpay\Client\Client();
|
||||
$client->setAdapter(new \Bitpay\Client\Adapter\CurlAdapter());
|
||||
$request = new \Bitpay\Client\Request();
|
||||
$request->setUri('https://btcpay.server/');
|
||||
$request->setMethod(\Bitpay\Client\Request::METHOD_GET);
|
||||
$request->setPath('rates/USD');
|
||||
|
||||
$response = $client->sendRequest($request);
|
||||
$data = json_decode($response->getBody(), true);
|
||||
var_dump($data);
|
||||
|
||||
|
||||
|
||||
@ -14,14 +14,6 @@
|
||||
|
||||
require __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
/**
|
||||
* To load up keys that you have previously saved, you need to use the same
|
||||
* storage engine. You also need to tell it the location of the key you want
|
||||
* to load.
|
||||
*/
|
||||
$storageEngine = new \Bitpay\Storage\FilesystemStorage();
|
||||
$privateKey = $storageEngine->load('/tmp/bitpay.pri');
|
||||
$publicKey = $storageEngine->load('/tmp/bitpay.pub');
|
||||
|
||||
/**
|
||||
* Create a new client. You can see the example of how to configure this using
|
||||
@ -30,6 +22,7 @@ $publicKey = $storageEngine->load('/tmp/bitpay.pub');
|
||||
$bitpay = new \Bitpay\Bitpay(
|
||||
array(
|
||||
'bitpay' => array(
|
||||
'network' => 'testnet', // testnet or livenet, default is livenet
|
||||
'public_key' => '/tmp/bitpay.pub', //see tutorial/001.php and 002.php
|
||||
'private_key' => '/tmp/bitpay.pri',
|
||||
'key_storage' => 'Bitpay\Storage\EncryptedFilesystemStorage',
|
||||
@ -43,12 +36,5 @@ $bitpay = new \Bitpay\Bitpay(
|
||||
*/
|
||||
$client = $bitpay->get('client');
|
||||
|
||||
$client->setPrivateKey($privateKey);
|
||||
$client->setPublicKey($publicKey);
|
||||
/**
|
||||
* Add your btcpayserver url
|
||||
*/
|
||||
$client->setUri('https://btcpay.server/');
|
||||
|
||||
$tokens = $client->getTokens();
|
||||
print_r($tokens);
|
||||
|
||||
@ -5,6 +5,9 @@
|
||||
|
||||
require __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
// When running bitpay on your local server
|
||||
$network = new Bitpay\Network\Customnet("127.0.0.1", 8088, true);
|
||||
|
||||
// Customize the curl options
|
||||
$curl_options = array(
|
||||
CURLOPT_SSL_VERIFYPEER => false,
|
||||
|
||||
@ -1,22 +0,0 @@
|
||||
<?php
|
||||
|
||||
require __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
|
||||
$storageEngine = new \Bitpay\Storage\FilesystemStorage();
|
||||
|
||||
$private = $storageEngine->load('/tmp/private.key');
|
||||
$public = new \Bitpay\PublicKey('/tmp/public.key');
|
||||
|
||||
$public->setPrivateKey($private);
|
||||
$public->generate();
|
||||
|
||||
printf("Public Key: %s\n", $public);
|
||||
printf("Private Key: %s\n", $private);
|
||||
|
||||
$message = 'https://test.bitpay.com/subscriptions{"schedule":"weekly","token":"some token","billData":{"currency":"USD","price":"2.00","quantity":1}}';
|
||||
|
||||
$signedMessage = $private->sign($message);
|
||||
print_r('message to be signed:: ' . $message . "\n");
|
||||
print_r('signed message:: ' . $signedMessage);
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
* 002 - Pairing
|
||||
*
|
||||
* Requirements:
|
||||
* - Basic PHP Knowledge
|
||||
* - Baisic PHP Knowledge
|
||||
* - Private and Public keys from 001.php
|
||||
* - Account on https://test.bitpay.com
|
||||
* - Pairing code
|
||||
@ -28,6 +28,13 @@ $publicKey = $storageEngine->load('/tmp/bitpay.pub');
|
||||
*/
|
||||
$client = new \Bitpay\Client\Client();
|
||||
|
||||
/**
|
||||
* The network is either livenet or testnet. You can also create your
|
||||
* own as long as it implements the NetworkInterface. In this example
|
||||
* we will use testnet
|
||||
*/
|
||||
$network = new \Bitpay\Network\Testnet();
|
||||
|
||||
/**
|
||||
* The adapter is what will make the calls to BitPay and return the response
|
||||
* from BitPay. This can be updated or changed as long as it implements the
|
||||
@ -40,12 +47,7 @@ $adapter = new \Bitpay\Client\Adapter\CurlAdapter();
|
||||
*/
|
||||
$client->setPrivateKey($privateKey);
|
||||
$client->setPublicKey($publicKey);
|
||||
|
||||
/**
|
||||
* Add your btcpayserver url
|
||||
*/
|
||||
$client->setUri('https://btcpay.server/');
|
||||
|
||||
$client->setNetwork($network);
|
||||
$client->setAdapter($adapter);
|
||||
|
||||
/**
|
||||
@ -77,9 +79,6 @@ try {
|
||||
* decided that it makes more sense to allow your application to handle
|
||||
* this exception since each app is different and has different requirements.
|
||||
*/
|
||||
echo "Exception occured: " . $e->getMessage().PHP_EOL;
|
||||
|
||||
echo "Pairing failed. Please check whether you're trying to pair a production pairing code on test.".PHP_EOL;
|
||||
$request = $client->getRequest();
|
||||
$response = $client->getResponse();
|
||||
/**
|
||||
@ -6,7 +6,7 @@
|
||||
*
|
||||
* Requirements:
|
||||
* - Account on https://test.bitpay.com
|
||||
* - Basic PHP Knowledge
|
||||
* - Baisic PHP Knowledge
|
||||
* - Private and Public keys from 001.php
|
||||
* - Token value obtained from 002.php
|
||||
*/
|
||||
@ -17,10 +17,11 @@ $storageEngine = new \Bitpay\Storage\EncryptedFilesystemStorage('YourTopSecretPa
|
||||
$privateKey = $storageEngine->load('/tmp/bitpay.pri');
|
||||
$publicKey = $storageEngine->load('/tmp/bitpay.pub');
|
||||
$client = new \Bitpay\Client\Client();
|
||||
$network = new \Bitpay\Network\Testnet();
|
||||
$adapter = new \Bitpay\Client\Adapter\CurlAdapter();
|
||||
$client->setPrivateKey($privateKey);
|
||||
$client->setPublicKey($publicKey);
|
||||
$client->setUri('https://btcpay.server/');
|
||||
$client->setNetwork($network);
|
||||
$client->setAdapter($adapter);
|
||||
// ---------------------------
|
||||
|
||||
@ -41,13 +42,6 @@ $client->setToken($token);
|
||||
*/
|
||||
$invoice = new \Bitpay\Invoice();
|
||||
|
||||
$buyer = new \Bitpay\Buyer();
|
||||
$buyer
|
||||
->setEmail('buyeremail@test.com');
|
||||
|
||||
// Add the buyers info to invoice
|
||||
$invoice->setBuyer($buyer);
|
||||
|
||||
/**
|
||||
* Item is used to keep track of a few things
|
||||
*/
|
||||
@ -68,22 +62,13 @@ $invoice->setItem($item);
|
||||
*/
|
||||
$invoice->setCurrency(new \Bitpay\Currency('USD'));
|
||||
|
||||
// Configure the rest of the invoice
|
||||
$invoice
|
||||
->setOrderId('OrderIdFromYourSystem')
|
||||
// You will receive IPN's at this URL, should be HTTPS for security purposes!
|
||||
->setNotificationUrl('https://store.example.com/bitpay/callback');
|
||||
|
||||
|
||||
/**
|
||||
* Updates invoice with new information such as the invoice id and the URL where
|
||||
* a customer can view the invoice.
|
||||
*/
|
||||
try {
|
||||
echo "Creating invoice at BitPay now.".PHP_EOL;
|
||||
$client->createInvoice($invoice);
|
||||
} catch (\Exception $e) {
|
||||
echo "Exception occured: " . $e->getMessage().PHP_EOL;
|
||||
$request = $client->getRequest();
|
||||
$response = $client->getResponse();
|
||||
echo (string) $request.PHP_EOL.PHP_EOL.PHP_EOL;
|
||||
@ -92,5 +77,3 @@ try {
|
||||
}
|
||||
|
||||
echo 'Invoice "'.$invoice->getId().'" created, see '.$invoice->getUrl().PHP_EOL;
|
||||
echo "Verbose details.".PHP_EOL;
|
||||
print_r($invoice);
|
||||
132
examples/tutorial/004.php
Normal file
132
examples/tutorial/004.php
Normal file
@ -0,0 +1,132 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (c) 2014-2015 BitPay
|
||||
*
|
||||
* 004 - Advanced Functionality
|
||||
*
|
||||
* Requirements:
|
||||
* - Account on https://test.bitpay.com
|
||||
* - Baisic PHP Knowledge
|
||||
* - Private and Public keys from 001.php
|
||||
* - Token value obtained from 002.php
|
||||
* - Able to complete 003.php
|
||||
*/
|
||||
require __DIR__.'/../../vendor/autoload.php';
|
||||
|
||||
/**
|
||||
* This example file will teach you how to make an invoice using a container.
|
||||
* The container contains all the objects that you would need along with a few
|
||||
* configuration options that should allow you to easily configure and change
|
||||
* based on your environment or server.
|
||||
*
|
||||
* Below are some variables that may or may not be needed based on what you
|
||||
* comment/uncomment.
|
||||
*/
|
||||
$pairingCode = 'YCBrKpr';
|
||||
$tokenString = 'realtokengoeshere';
|
||||
$privateKeyPath = '/tmp/bitpay.pri';
|
||||
$publicKeyPath = '/tmp/bitpay.pub';
|
||||
$keyStoragePassword = 'YourTopSecretPassword';
|
||||
/*** end options ***/
|
||||
|
||||
/**
|
||||
* The Bitpay class takes care of all the dependency injection for
|
||||
* you while at the same time allowing you to easily configure based on
|
||||
* environment variables or other configuration system you have.
|
||||
*
|
||||
* For a list of options you can pass in please see the Bitpay\Config\Configuration
|
||||
* class. You will find a list of options and the default and valid values.
|
||||
*/
|
||||
$bitpay = new \Bitpay\Bitpay(
|
||||
array(
|
||||
'bitpay' => array(
|
||||
'network' => 'testnet', // Valid values are testnet/livenet
|
||||
'public_key' => $publicKeyPath,
|
||||
'private_key' => $privateKeyPath,
|
||||
'key_storage_password' => $keyStoragePassword,
|
||||
)
|
||||
)
|
||||
);
|
||||
echo 'Bitpay class initialized.'.PHP_EOL;
|
||||
|
||||
/**
|
||||
* If you have not already generated and persisted you keys, please uncomment
|
||||
* this code. This should only be ran once. Once you have generated your key
|
||||
* pairs, keep you keys in a secure location. If you regenerate your keys, you
|
||||
* will need to repair and get a new token.
|
||||
*
|
||||
$privateKey = \Bitpay\PrivateKey::create($privateKeyPath)->generate();
|
||||
$publicKey = \Bitpay\PublicKey::create($publicKeyPath)->setPrivateKey($privateKey)->generate();
|
||||
$bitpay->get('key_manager')->persist($privateKey);
|
||||
$bitpay->get('key_manager')->persist($publicKey);
|
||||
echo 'Public and Private keys have been generated and persisted.'.PHP_EOL;
|
||||
//exit(0); // exit in case you just wanted to generate keys
|
||||
*/
|
||||
|
||||
/**
|
||||
* If you have not already obtained a token, please uncomment this code, you
|
||||
* will need a pairing code. A pairing code is a one time use code and can only
|
||||
* be used once.
|
||||
*
|
||||
$publicKey = $bitpay->get('public_key'); // @var \Bitpay\PublicKey
|
||||
$sin = \Bitpay\SinKey::create()->setPublicKey($publicKey)->generate(); // @var \Bitpay\SinKey
|
||||
if (empty($pairingCode)) { throw new \Exception('Please set a pairing code to a value.'); }
|
||||
$token = $bitpay->get('client')->createToken(
|
||||
array(
|
||||
'pairingCode' => $pairingCode,
|
||||
'label' => 'Tutorial 004',
|
||||
'id' => (string) $sin,
|
||||
)
|
||||
);
|
||||
echo 'Token Obtained "'.$token->getToken().'"'.PHP_EOL;
|
||||
//exit(0);
|
||||
*/
|
||||
|
||||
/**
|
||||
* If you already have a token, uncomment this code
|
||||
*
|
||||
*/
|
||||
$token = new \Bitpay\Token();
|
||||
$token->setToken($tokenString);
|
||||
|
||||
/**
|
||||
* Code that makes the invoice
|
||||
*/
|
||||
$invoice = new \Bitpay\Invoice();
|
||||
$item = new \Bitpay\Item();
|
||||
$item
|
||||
->setCode('skuNumber')
|
||||
->setDescription('General Description of Item')
|
||||
->setPrice('1.99');
|
||||
$invoice->setCurrency(new \Bitpay\Currency('USD'));
|
||||
$invoice->setItem($item);
|
||||
$client = $bitpay->get('client');
|
||||
$client->setToken($token);
|
||||
try {
|
||||
$client->createInvoice($invoice);
|
||||
} catch (\Exception $e) {
|
||||
$request = $client->getRequest();
|
||||
$response = $client->getResponse();
|
||||
echo (string) $request.PHP_EOL.PHP_EOL.PHP_EOL;
|
||||
echo (string) $response.PHP_EOL.PHP_EOL;
|
||||
exit(1); // We do not want to continue if something went wrong
|
||||
}
|
||||
|
||||
echo 'Invoice "'.$invoice->getId().'" created, see '.$invoice->getUrl().PHP_EOL;
|
||||
|
||||
/**
|
||||
* Q: PHP Fatal error: Uncaught exception 'Exception' with message 'Unable to create token'
|
||||
* A: This error will happen if you are are trying to use a pairing code that has already
|
||||
* been used. To fix this issue, create a new pairing code and use that one.
|
||||
*
|
||||
* It might also mean that the pairing code you obtained was generated on 'bitpay.com'
|
||||
* and you have the network setup for 'testnet' or you generated a pairing code on
|
||||
* 'test.bitpay.com' and have the network set to 'livenet'. Please double check your
|
||||
* configuration settings.
|
||||
*
|
||||
* Q: PHP Fatal error: Uncaught exception 'Exception' with message 'Could not decode key'
|
||||
* A: The key was found, however when trying to decrypt it, it was unabled because the key
|
||||
* is either not encrypted or the key is encrypted and the password you have to decrypt
|
||||
* it is invalid. Double check and make sure that the settings are correct, if unsure,
|
||||
* regenerate your keys. You will need to decrypt using the same storage engine.
|
||||
*/
|
||||
@ -1,113 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (c) 2014-2017 BitPay
|
||||
*
|
||||
* 004 - Hosted payment page: create & display invoice
|
||||
* For details on displaying invoices, see https://bitpay.com/docs/display-invoice
|
||||
*
|
||||
* Requirements:
|
||||
* - Account on https://test.bitpay.com
|
||||
* - Basic PHP Knowledge
|
||||
* - Private and Public keys from 001.php
|
||||
* - Token value obtained from 002.php
|
||||
* - A webserver to run the code. Running locally works with firefox, but not with Safari & Chrome
|
||||
*/
|
||||
require __DIR__.'/../../vendor/autoload.php';
|
||||
|
||||
// See 002.php for explanation
|
||||
$storageEngine = new \Bitpay\Storage\EncryptedFilesystemStorage('YourTopSecretPassword'); // Password may need to be updated if you changed it
|
||||
$privateKey = $storageEngine->load('/tmp/bitpay.pri');
|
||||
$publicKey = $storageEngine->load('/tmp/bitpay.pub');
|
||||
$client = new \Bitpay\Client\Client();
|
||||
$adapter = new \Bitpay\Client\Adapter\CurlAdapter();
|
||||
$client->setPrivateKey($privateKey);
|
||||
$client->setPublicKey($publicKey);
|
||||
$client->setUri('https://btcpay.server/');
|
||||
$client->setAdapter($adapter);
|
||||
// ---------------------------
|
||||
|
||||
/**
|
||||
* The last object that must be injected is the token object.
|
||||
*/
|
||||
$token = new \Bitpay\Token();
|
||||
$token->setToken('UpdateThisValue'); // UPDATE THIS VALUE
|
||||
|
||||
/**
|
||||
* Token object is injected into the client
|
||||
*/
|
||||
$client->setToken($token);
|
||||
|
||||
/**
|
||||
* This is where we will start to create an Invoice object, make sure to check
|
||||
* the InvoiceInterface for methods that you can use.
|
||||
*/
|
||||
$invoice = new \Bitpay\Invoice();
|
||||
|
||||
$buyer = new \Bitpay\Buyer();
|
||||
$buyerEmail = "buyeremail@test.com";
|
||||
$buyer
|
||||
->setEmail($buyerEmail);
|
||||
|
||||
// Add the buyers info to invoice
|
||||
$invoice->setBuyer($buyer);
|
||||
|
||||
/**
|
||||
* Item is used to keep track of a few things
|
||||
*/
|
||||
$item = new \Bitpay\Item();
|
||||
$item
|
||||
->setCode('skuNumber')
|
||||
->setDescription('General Description of Item')
|
||||
->setPrice('1.99');
|
||||
$invoice->setItem($item);
|
||||
|
||||
/**
|
||||
* BitPay supports multiple different currencies. Most shopping cart applications
|
||||
* and applications in general have defined set of currencies that can be used.
|
||||
* Setting this to one of the supported currencies will create an invoice using
|
||||
* the exchange rate for that currency.
|
||||
*
|
||||
* @see https://test.bitpay.com/bitcoin-exchange-rates for supported currencies
|
||||
*/
|
||||
$invoice->setCurrency(new \Bitpay\Currency('USD'));
|
||||
|
||||
// Configure the rest of the invoice
|
||||
$invoice
|
||||
->setOrderId('OrderIdFromYourSystem')
|
||||
// You will receive IPN's at this URL, should be HTTPS for security purposes!
|
||||
->setNotificationUrl('https://store.example.com/bitpay/callback');
|
||||
|
||||
|
||||
/**
|
||||
* Updates invoice with new information such as the invoice id and the URL where
|
||||
* a customer can view the invoice.
|
||||
*/
|
||||
try {
|
||||
$client->createInvoice($invoice);
|
||||
} catch (\Exception $e) {
|
||||
$request = $client->getRequest();
|
||||
$response = $client->getResponse();
|
||||
echo (string) $request.PHP_EOL.PHP_EOL.PHP_EOL;
|
||||
echo (string) $response.PHP_EOL.PHP_EOL;
|
||||
exit(1); // We do not want to continue if something went wrong
|
||||
}
|
||||
?>
|
||||
<html>
|
||||
<head><title>BitPay - Modal CSS invoice demo</title></head>
|
||||
<body bgcolor="rgb(21,28,111)" textcolor="rgb(255,255,255)">
|
||||
<button onclick="openInvoice()">Pay Now</button>
|
||||
<br><br><br>
|
||||
For more information about BitPay's modal CSS invoice, please see <a href="https://bitpay.com/docs/display-invoice" target="_blank">https://bitpay.com/docs/display-invoice</a>
|
||||
</body>
|
||||
<script src="https://bitpay.com/bitpay.js"> </script>
|
||||
<script>
|
||||
function openInvoice() {
|
||||
var network = "testnet"
|
||||
if (network == "testnet")
|
||||
bitpay.setApiUrlPrefix("https://test.bitpay.com")
|
||||
else
|
||||
bitpay.setApiUrlPrefix("https://bitpay.com")
|
||||
bitpay.showInvoice("<?php echo $invoice->getId();?>");
|
||||
}
|
||||
</script>
|
||||
</html>
|
||||
@ -1,74 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (c) 2014-2017 BitPay
|
||||
*
|
||||
* 004 - IPN logger
|
||||
*
|
||||
* Requirements:
|
||||
* - Account on https://test.bitpay.com
|
||||
* - Baisic PHP Knowledge
|
||||
* - Private and Public keys from 001.php
|
||||
* - Token value obtained from 002.php
|
||||
* - Invoice created & paid
|
||||
*/
|
||||
require __DIR__.'/../../vendor/autoload.php';
|
||||
|
||||
|
||||
$myfile = fopen("/tmp/BitPayIPN.log", "a");
|
||||
|
||||
$raw_post_data = file_get_contents('php://input');
|
||||
|
||||
$date = date('m/d/Y h:i:s a', time());
|
||||
|
||||
if (false === $raw_post_data) {
|
||||
fwrite($myfile, $date . " : Error. Could not read from the php://input stream or invalid Bitpay IPN received.\n");
|
||||
fclose($myfile);
|
||||
throw new \Exception('Could not read from the php://input stream or invalid Bitpay IPN received.');
|
||||
}
|
||||
|
||||
$ipn = json_decode($raw_post_data);
|
||||
|
||||
if (true === empty($ipn)) {
|
||||
fwrite($myfile, $date . " : Error. Could not decode the JSON payload from BitPay.\n");
|
||||
fclose($myfile);
|
||||
throw new \Exception('Could not decode the JSON payload from BitPay.');
|
||||
}
|
||||
|
||||
if (true === empty($ipn->id)) {
|
||||
fwrite($myfile, $date . " : Error. Invalid Bitpay payment notification message received - did not receive invoice ID.\n");
|
||||
fclose($myfile);
|
||||
throw new \Exception('Invalid Bitpay payment notification message received - did not receive invoice ID.');
|
||||
}
|
||||
|
||||
// Now fetch the invoice from BitPay
|
||||
// This is needed, since the IPN does not contain any authentication
|
||||
$storageEngine = new \Bitpay\Storage\EncryptedFilesystemStorage('YourTopSecretPassword');
|
||||
$privateKey = $storageEngine->load('/tmp/bitpay.pri');
|
||||
$publicKey = $storageEngine->load('/tmp/bitpay.pub');
|
||||
$client = new \Bitpay\Client\Client();
|
||||
$adapter = new \Bitpay\Client\Adapter\CurlAdapter();
|
||||
$client->setPrivateKey($privateKey);
|
||||
$client->setPublicKey($publicKey);
|
||||
$client->setUri('https://btcpay.server/');
|
||||
$client->setAdapter($adapter);
|
||||
|
||||
$token = new \Bitpay\Token();
|
||||
$token->setToken('UpdateThisValue'); // UPDATE THIS VALUE
|
||||
$client->setToken($token);
|
||||
$token->setFacade('merchant');
|
||||
|
||||
/**
|
||||
* This is where we will fetch the invoice object
|
||||
*/
|
||||
$invoice = $client->getInvoice($ipn->id);
|
||||
$invoiceId = $invoice->getId();
|
||||
$invoiceStatus = $invoice->getStatus();
|
||||
$invoiceExceptionStatus = $invoice->getExceptionStatus();
|
||||
$invoicePrice = $invoice->getPrice();
|
||||
|
||||
fwrite($myfile, $date . " : IPN received for BitPay invoice ".$invoiceId." . Status = " .$invoiceStatus." / exceptionStatus = " . $invoiceExceptionStatus." Price = ". $invoicePrice." Tax Included = ". $taxIncluded."\n");
|
||||
fwrite($myfile, "Raw IPN: ". $raw_post_data."\n");
|
||||
|
||||
//Respond with HTTP 200, so BitPay knows the IPN has been received correctly
|
||||
//If BitPay receives <> HTTP 200, then BitPay will try to send the IPN again with increasing intervals for two more hours.
|
||||
header("HTTP/1.1 200 OK");
|
||||
@ -1,60 +1,22 @@
|
||||
# Creating BitPay invoices - the tutorial
|
||||
Tutorial 01 - Introduction
|
||||
==========================
|
||||
|
||||
## About this tutorial
|
||||
This tutorial contains five scripts. These scripts allow you to do the following:
|
||||
1) Create keys to communicate with BitPay's API
|
||||
2) Pair your keys to your BitPay merchant account
|
||||
3) Create BitPay invoices
|
||||
4) Display a BitPay invoice using BitPay's hosted payment page
|
||||
5) Log Instant Payment Notifications (IPNs, also called webhooks)
|
||||
In this tutorial I will give an example of going through all the steps required
|
||||
to get up and running with BitPay using the PHP SDK with code examples.
|
||||
|
||||
Script 001 & 002 need to be executed once, to properly configure your local installation.
|
||||
The code that you find here SHOULD run needing only to modify a few values. If
|
||||
you run into trouble or if the code becomes out of date and does not run, please
|
||||
bring it to our attention by opening a GitHub issue.
|
||||
|
||||
Script 003 creates BitPay invoices; this script can be run permanently.
|
||||
Script 004 is very similar to script 003. The main difference is that script 004 outputs HTML, so you can run this on your webserver.
|
||||
To begin, please visit https://test.bitpay.com and register for a test account.
|
||||
This will allow you to use BitPay using Bitcoin's testnet feature. If you are
|
||||
looking for a testnet wallet to test with, please visit https://copay.io and
|
||||
create a new wallet. When you first create your wallet, under the Advanced
|
||||
Options, you are given to option to make the wallet a testnet wallet.
|
||||
|
||||
IPNs will be sent after a BitPay invoice receives a payment. IPNs can be logged or processed with IPNlogger.php
|
||||
|
||||
## Getting started
|
||||
To begin please visit https://test.bitpay.com/dashboard/signup and register for a BitPay merchant test account. Please fill in all questions, so you get a fully working test account. When filling in the settlement address in your BitPay merchant test account, make sure to fill in a testnet bitcoin address (starting with m or n).
|
||||
|
||||
If you are looking for a testnet bitcoin wallet to test with, please visit https://bitpay.com/wallet and create a new wallet.
|
||||
|
||||
If you need testnet bitcoin please visit a testnet faucet, e.g. https://testnet.coinfaucet.eu/en/ or http://tpfaucet.appspot.com/
|
||||
|
||||
For more information about testing, please see https://bitpay.com/docs/testing
|
||||
|
||||
To install BitPay's latest PHP library, please follow the instructions from https://github.com/bitpay/php-bitpay-client/blob/master/README.md
|
||||
|
||||
## Script 1 & 2: configure your local installation
|
||||
The following two scripts need to be executed once. These scripts will generate your private/public keys and pair them to your BitPay merchant account:
|
||||
1. 001_generateKeys.php : generates the private/public keys to sign the communication with BitPay. The private/public keys are stored in your filesystem for later usage.
|
||||
2. 002_pair.php : pairs your private/public keys to your BitPay merchant account. Please make sure to first create a pairing code in your BitPay merchant account (Payment Tools -> Manage API tokens -> Add new token -> Add token) and put this 7 character pairing code in the script. The script returns an API token that should be put put in 003_createInvoice.php, to create invoices permanently.
|
||||
|
||||
These first two scripts need to be executed only once.
|
||||
|
||||
## Script 3: create a BitPay invoice
|
||||
3. 003_createInvoice.php : creates a BitPay invoice. Please make sure to update the script with the API token received from 002_pair.php
|
||||
|
||||
This script returns a BitPay invoice object. You can display the invoice by loading the invoice URL in a web browser. You can pay the invoice with your bitcoin wallet.
|
||||
|
||||
## Script 4: display a BitPay invoice using BitPay's hosted payment page
|
||||
4. 004_HostedPaymentPage.php : creates a BitPay invoice and returns the HTML to show the invoice. Please make sure to update the script with the API token received from 002_pair.php
|
||||
|
||||
For more information about paying a BitPay invoice, please see https://support.bitpay.com/hc/en-us/articles/203281456-How-do-I-pay-a-BitPay-invoice-
|
||||
|
||||
Script 003_createInvoice.php and 004_HostedPaymentPage.php can be run permanently with the token from 002_pair.php
|
||||
|
||||
## Script 5: log Instant Payment Notifications
|
||||
After you've paid the invoice, BitPay will send an IPN to the notificationURL of the invoice. A script to process the IPN should be put on your server and be reachable from the internet. Your should put the URL of IPNLogger.php in 003_createInvoice.php, e.g.:
|
||||
```
|
||||
// You will receive IPN's at this URL, should be HTTPS for security purposes!
|
||||
$invoice->setNotificationUrl('https://yourserver.com/IPNlogger.php');
|
||||
```
|
||||
IPNs can be used by the merchant to update order statuses. Please note to use IPNs as a trigger to fetch the BitPay invoice status, since the IPNs are not authenticated.
|
||||
|
||||
For more information about IPNs see https://bitpay.com/docs/invoice-callbacks
|
||||
Once you have an account and a testnet wallet, you should begin to go through
|
||||
this tutorial starting from file `001.php` and continuing on to the next
|
||||
files in order.
|
||||
|
||||
|
||||
Examples (c) 2014-2017 BitPay
|
||||
Examples (c) 2014-2015 BitPay
|
||||
|
||||
@ -1,44 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (c) 2014-2017 BitPay
|
||||
*
|
||||
* getInvoice
|
||||
*
|
||||
* Requirements:
|
||||
* - Account on https://test.bitpay.com
|
||||
* - Baisic PHP Knowledge
|
||||
* - Private and Public keys from 001.php
|
||||
* - Token value obtained from 002.php
|
||||
* - Invoice created
|
||||
*/
|
||||
require __DIR__.'/../../vendor/autoload.php';
|
||||
|
||||
// Now fetch the invoice from BitPay
|
||||
|
||||
$storageEngine = new \Bitpay\Storage\EncryptedFilesystemStorage('YourTopSecretPassword');
|
||||
$privateKey = $storageEngine->load('/tmp/bitpay.pri');
|
||||
$publicKey = $storageEngine->load('/tmp/bitpay.pub');
|
||||
$client = new \Bitpay\Client\Client();
|
||||
$adapter = new \Bitpay\Client\Adapter\CurlAdapter();
|
||||
$client->setPrivateKey($privateKey);
|
||||
$client->setPublicKey($publicKey);
|
||||
$client->setUri('https://btcpay.server/');
|
||||
$client->setAdapter($adapter);
|
||||
|
||||
$token = new \Bitpay\Token();
|
||||
$token->setToken('UpdateThisValue'); // UPDATE THIS VALUE
|
||||
$token->setFacade('merchant');
|
||||
|
||||
$client->setToken($token);
|
||||
|
||||
/**
|
||||
* This is where we will fetch the invoice object
|
||||
*/
|
||||
$invoice = $client->getInvoice("UpdateThisValue");
|
||||
|
||||
$request = $client->getRequest();
|
||||
$response = $client->getResponse();
|
||||
echo (string) $request.PHP_EOL.PHP_EOL.PHP_EOL;
|
||||
echo (string) $response.PHP_EOL.PHP_EOL;
|
||||
|
||||
print_r($invoice);
|
||||
@ -80,11 +80,8 @@ class CurlAdapter implements AdapterInterface
|
||||
/** @var ResponseInterface */
|
||||
$response = Response::createFromRawResponse($raw);
|
||||
|
||||
// For some unknown reason, on some machine, the status code is equal to 0
|
||||
// If that's the case, let's just ask to curl the real http code
|
||||
if ($response->getStatusCode() === 0)
|
||||
$response->setStatusCode(curl_getinfo($curl, CURLINFO_HTTP_CODE));
|
||||
curl_close($curl);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
@ -97,12 +94,14 @@ class CurlAdapter implements AdapterInterface
|
||||
private function getCurlDefaultOptions(RequestInterface $request)
|
||||
{
|
||||
return array(
|
||||
CURLOPT_URL => $request->getFullUri(),
|
||||
CURLOPT_URL => $request->getUri(),
|
||||
CURLOPT_PORT => $request->getPort(),
|
||||
CURLOPT_CUSTOMREQUEST => $request->getMethod(),
|
||||
CURLOPT_HTTPHEADER => $request->getHeaderFields(),
|
||||
CURLOPT_TIMEOUT => 10,
|
||||
CURLOPT_SSL_VERIFYPEER => 1,
|
||||
CURLOPT_SSL_VERIFYHOST => 2,
|
||||
CURLOPT_CAINFO => __DIR__.'/ca-bundle.crt',
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_FORBID_REUSE => 1,
|
||||
CURLOPT_FRESH_CONNECT => 1,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -53,13 +53,19 @@ class Client implements ClientInterface
|
||||
protected $privateKey;
|
||||
|
||||
/**
|
||||
* @var uri
|
||||
* @var NetworkInterface
|
||||
*/
|
||||
protected $uri;
|
||||
protected $network;
|
||||
|
||||
public function setUri($uri)
|
||||
/**
|
||||
* The network is either livenet or testnet and tells the client where to
|
||||
* send the requests.
|
||||
*
|
||||
* @param NetworkInterface
|
||||
*/
|
||||
public function setNetwork(NetworkInterface $network)
|
||||
{
|
||||
$this->uri = trim($uri);
|
||||
$this->network = $network;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -102,43 +108,6 @@ class Client implements ClientInterface
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
protected function fillInvoiceData(InvoiceInterface $invoice, $data)
|
||||
{
|
||||
# BitPay returns the invoice time in milliseconds. PHP's DateTime object expects the time to be in seconds
|
||||
$invoiceTime = is_numeric($data['invoiceTime']) ? intval($data['invoiceTime']/1000) : $data['invoiceTime'];
|
||||
$expirationTime = is_numeric($data['expirationTime']) ? intval($data['expirationTime']/1000) : $data['expirationTime'];
|
||||
$currentTime = is_numeric($data['currentTime']) ? intval($data['currentTime']/1000) : $data['currentTime'];
|
||||
|
||||
$invoiceToken = new \Bitpay\Token();
|
||||
$invoice
|
||||
->setToken($invoiceToken->setToken($data['token']))
|
||||
->setUrl($data['url'])
|
||||
->setPosData(array_key_exists('posData', $data) ? $data['posData'] : '')
|
||||
->setStatus($data['status'])
|
||||
->setBtcPrice(array_key_exists('btcPrice', $data) ? $data['btcPrice'] : '')
|
||||
->setPrice($data['price'])
|
||||
->setTaxIncluded($data['taxIncluded'])
|
||||
->setCurrency(new \Bitpay\CurrencyUnrestricted($data['currency']))
|
||||
->setOrderId(array_key_exists('orderId', $data) ? $data['orderId'] : '')
|
||||
->setInvoiceTime($invoiceTime)
|
||||
->setExpirationTime($expirationTime)
|
||||
->setCurrentTime($currentTime)
|
||||
->setId($data['id'])
|
||||
->setBtcPaid(array_key_exists('btcPaid', $data) ? $data['btcPaid'] : '')
|
||||
->setAmountPaid(array_key_exists('amountPaid', $data) ? $data['amountPaid'] : '')
|
||||
->setRate(array_key_exists('rate', $data) ? $data['rate'] : '')
|
||||
->setExceptionStatus($data['exceptionStatus'])
|
||||
->setRefundAddresses(array_key_exists('refundAddresses', $data) ? $data['refundAddresses'] : '')
|
||||
->setTransactionCurrency(array_key_exists('transactionCurrency', $data) ? $data['transactionCurrency'] : null)
|
||||
->setPaymentTotals(array_key_exists('paymentTotals', $data) ? $data['paymentTotals'] : '')
|
||||
->setPaymentSubtotals(array_key_exists('paymentSubtotals', $data) ? $data['paymentSubtotals'] : '')
|
||||
->setExchangeRates(array_key_exists('exchangeRates', $data) ? $data['exchangeRates'] : '');
|
||||
return $invoice;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
@ -157,13 +126,11 @@ class Client implements ClientInterface
|
||||
|
||||
$body = array(
|
||||
'price' => $item->getPrice(),
|
||||
'taxIncluded' => $item->getTaxIncluded(),
|
||||
'currency' => $currency->getCode(),
|
||||
'posData' => $invoice->getPosData(),
|
||||
'notificationURL' => $invoice->getNotificationUrl(),
|
||||
'transactionSpeed' => $invoice->getTransactionSpeed(),
|
||||
'fullNotifications' => $invoice->isFullNotifications(),
|
||||
'extendedNotifications' => $invoice->isExtendedNotifications(),
|
||||
'notificationEmail' => $invoice->getNotificationEmail(),
|
||||
'redirectURL' => $invoice->getRedirectUrl(),
|
||||
'orderID' => $invoice->getOrderId(),
|
||||
@ -179,19 +146,11 @@ class Client implements ClientInterface
|
||||
'buyerCountry' => $buyer->getCountry(),
|
||||
'buyerEmail' => $buyer->getEmail(),
|
||||
'buyerPhone' => $buyer->getPhone(),
|
||||
'buyerNotify' => $buyer->getNotify(),
|
||||
'guid' => Util::guid(),
|
||||
'nonce' => Util::nonce(),
|
||||
'token' => $this->token->getToken(),
|
||||
'paymentCurrencies' => $invoice->getPaymentCurrencies(),
|
||||
);
|
||||
|
||||
foreach(array_keys($body) as $key) {
|
||||
if(null === $body[$key]) {
|
||||
unset($body[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
$request->setBody(json_encode($body));
|
||||
$this->addIdentityHeader($request);
|
||||
$this->addSignatureHeader($request);
|
||||
@ -207,8 +166,20 @@ class Client implements ClientInterface
|
||||
throw new \Exception($error_message);
|
||||
}
|
||||
$data = $body['data'];
|
||||
|
||||
$invoice = $this->fillInvoiceData($invoice, $data);
|
||||
$invoiceToken = new \Bitpay\Token();
|
||||
$invoice
|
||||
->setToken($invoiceToken->setToken($data['token']))
|
||||
->setId($data['id'])
|
||||
->setUrl($data['url'])
|
||||
->setStatus($data['status'])
|
||||
->setBtcPrice($data['btcPrice'])
|
||||
->setPrice($data['price'])
|
||||
->setInvoiceTime($data['invoiceTime'])
|
||||
->setExpirationTime($data['expirationTime'])
|
||||
->setCurrentTime($data['currentTime'])
|
||||
->setBtcPaid($data['btcPaid'])
|
||||
->setRate($data['rate'])
|
||||
->setExceptionStatus($data['exceptionStatus']);
|
||||
|
||||
return $invoice;
|
||||
}
|
||||
@ -520,7 +491,7 @@ class Client implements ClientInterface
|
||||
public function createToken(array $payload = array())
|
||||
{
|
||||
if (isset($payload['pairingCode']) && 1 !== preg_match('/^[a-zA-Z0-9]{7}$/', $payload['pairingCode'])) {
|
||||
throw new \InvalidArgumentException("pairing code is not legal");
|
||||
throw new ArgumentException("pairing code is not legal");
|
||||
}
|
||||
|
||||
$this->request = $this->createNewRequest();
|
||||
@ -535,10 +506,6 @@ class Client implements ClientInterface
|
||||
throw new \Bitpay\Client\BitpayException($this->response->getStatusCode().": ".$body['error']);
|
||||
}
|
||||
|
||||
if($this->response->getStatusCode() >= 400) {
|
||||
throw new \Exception('invalid status code: '. $this->response->getStatusCode());
|
||||
}
|
||||
|
||||
$tkn = $body['data'][0];
|
||||
$createdAt = new \DateTime();
|
||||
$pairingExpiration = new \DateTime();
|
||||
@ -590,7 +557,7 @@ class Client implements ClientInterface
|
||||
{
|
||||
$this->request = $this->createNewRequest();
|
||||
$this->request->setMethod(Request::METHOD_GET);
|
||||
if ($this->token && $this->token->getFacade() === 'merchant') {
|
||||
if ($this->token->getFacade() === 'merchant') {
|
||||
$this->request->setPath(sprintf('invoices/%s?token=%s', $invoiceId, $this->token->getToken()));
|
||||
$this->addIdentityHeader($this->request);
|
||||
$this->addSignatureHeader($this->request);
|
||||
@ -607,15 +574,27 @@ class Client implements ClientInterface
|
||||
$data = $body['data'];
|
||||
|
||||
$invoice = new \Bitpay\Invoice();
|
||||
$invoice = $this->fillInvoiceData($invoice, $data);
|
||||
$invoiceToken = new \Bitpay\Token();
|
||||
$invoice
|
||||
->setToken($invoiceToken->setToken($data['token']))
|
||||
->setUrl($data['url'])
|
||||
->setPosData($data['posData'])
|
||||
->setStatus($data['status'])
|
||||
->setBtcPrice($data['btcPrice'])
|
||||
->setPrice($data['price'])
|
||||
->setCurrency(new \Bitpay\Currency($data['currency']))
|
||||
->setOrderId($data['orderId'])
|
||||
->setInvoiceTime($data['invoiceTime'])
|
||||
->setExpirationTime($data['expirationTime'])
|
||||
->setCurrentTime($data['currentTime'])
|
||||
->setId($data['id'])
|
||||
->setBtcPaid($data['btcPaid'])
|
||||
->setRate($data['rate'])
|
||||
->setExceptionStatus($data['exceptionStatus']);
|
||||
|
||||
return $invoice;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param RequestInterface $request
|
||||
* @return ResponseInterface
|
||||
@ -651,7 +630,15 @@ class Client implements ClientInterface
|
||||
throw new \Exception('Please set your Private Key');
|
||||
}
|
||||
|
||||
$url = $request->getFullUri();
|
||||
if (true == property_exists($this->network, 'isPortRequiredInUrl')) {
|
||||
if ($this->network->isPortRequiredInUrl === true) {
|
||||
$url = $request->getUriWithPort();
|
||||
} else {
|
||||
$url = $request->getUri();
|
||||
}
|
||||
} else {
|
||||
$url = $request->getUri();
|
||||
}
|
||||
|
||||
$message = sprintf(
|
||||
'%s%s',
|
||||
@ -666,16 +653,12 @@ class Client implements ClientInterface
|
||||
|
||||
/**
|
||||
* @return RequestInterface
|
||||
*
|
||||
* @throws BitpayException
|
||||
*/
|
||||
protected function createNewRequest()
|
||||
{
|
||||
if ($this->uri === null) {
|
||||
throw new BitpayException('You should provider the url of your BTCPAY server');
|
||||
}
|
||||
$request = new Request();
|
||||
$request->setUri($this->uri);
|
||||
$request->setHost($this->network->getApiHost());
|
||||
$request->setPort($this->network->getApiPort());
|
||||
$this->prepareRequestHeaders($request);
|
||||
|
||||
return $request;
|
||||
@ -700,5 +683,14 @@ class Client implements ClientInterface
|
||||
|
||||
protected function checkPriceAndCurrency($price, $currency)
|
||||
{
|
||||
$decimalPosition = strpos($price, '.');
|
||||
if ($decimalPosition == 0) {
|
||||
$decimalPrecision = 0;
|
||||
} else {
|
||||
$decimalPrecision = strlen(substr($price, $decimalPosition + 1));
|
||||
}
|
||||
if (($decimalPrecision > 2 && $currency != 'BTC') || $decimalPrecision > 6) {
|
||||
throw new \Exception('Incorrect price format or currency type.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -25,8 +25,8 @@ interface ClientInterface
|
||||
*
|
||||
* @see RFC2616 section 14.43 for User-Agent Format
|
||||
*/
|
||||
const NAME = 'BitPay PHP-Client BTCPAY';
|
||||
const VERSION = '2.2.23';
|
||||
const NAME = 'BitPay PHP-Client';
|
||||
const VERSION = '0.0.0';
|
||||
|
||||
//public function createApplication(ApplicationInterface $application);
|
||||
|
||||
@ -56,8 +56,6 @@ interface ClientInterface
|
||||
*/
|
||||
public function getInvoice($invoiceId);
|
||||
|
||||
|
||||
|
||||
//public function getLedgers();
|
||||
//public function getLedger(CurrencyInterface $currency);
|
||||
|
||||
|
||||
@ -37,6 +37,13 @@ class Request implements RequestInterface
|
||||
*/
|
||||
protected $method;
|
||||
|
||||
/**
|
||||
* This should be something such as `test.bitpay.com` or just `bitpay.com`
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $host;
|
||||
|
||||
/**
|
||||
* The path is added to the end of the host
|
||||
*
|
||||
@ -44,6 +51,13 @@ class Request implements RequestInterface
|
||||
*/
|
||||
protected $path;
|
||||
|
||||
/**
|
||||
* Default is 443 but should be changed by whatever is passed in through the Adapter.
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $port;
|
||||
|
||||
/**
|
||||
*/
|
||||
public function __construct()
|
||||
@ -68,7 +82,7 @@ class Request implements RequestInterface
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
$request = sprintf("%s %s HTTP/1.1\r\n", $this->getMethod(), $this->getFullUri());
|
||||
$request = sprintf("%s %s HTTP/1.1\r\n", $this->getMethod(), $this->getUriWithPort());
|
||||
$request .= $this->getHeadersAsString();
|
||||
$request .= $this->getBody();
|
||||
|
||||
@ -83,6 +97,24 @@ class Request implements RequestInterface
|
||||
return (strtoupper($method) == strtoupper($this->method));
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getPort()
|
||||
{
|
||||
return $this->port;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is called in the Adapter
|
||||
*
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function setPort($port)
|
||||
{
|
||||
$this->port = $port;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
@ -105,31 +137,55 @@ class Request implements RequestInterface
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getUri()
|
||||
public function getSchema()
|
||||
{
|
||||
return $this->uri;
|
||||
return 'https';
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getFullUri()
|
||||
public function getUri()
|
||||
{
|
||||
$uriNormalized = rtrim($this->getUri(), '/');
|
||||
$pathNormalized = ltrim($this->getPath(), '/');
|
||||
return sprintf(
|
||||
'%s/%s',
|
||||
$uriNormalized,
|
||||
$pathNormalized
|
||||
'%s://%s/%s',
|
||||
$this->getSchema(),
|
||||
$this->getHost(),
|
||||
$this->getPath()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function setUri($uri)
|
||||
public function getUriWithPort()
|
||||
{
|
||||
$this->uri = $uri;
|
||||
return sprintf(
|
||||
'%s://%s:%s/%s',
|
||||
$this->getSchema(),
|
||||
$this->getHost(),
|
||||
$this->getPort(),
|
||||
$this->getPath()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getHost()
|
||||
{
|
||||
return $this->host;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the host for the request
|
||||
*
|
||||
* @param string $host
|
||||
*/
|
||||
public function setHost($host)
|
||||
{
|
||||
$this->host = $host;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
@ -24,6 +24,28 @@ interface RequestInterface
|
||||
*/
|
||||
public function getMethod();
|
||||
|
||||
/**
|
||||
* Should always return https
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSchema();
|
||||
|
||||
/**
|
||||
* Returns the host to send the request to. The host would be something
|
||||
* such as `test.bitpay.com` or `bitpay.com`
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getHost();
|
||||
|
||||
/**
|
||||
* Returns port to send request on
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getPort();
|
||||
|
||||
/**
|
||||
* example of path is `api/invoice` as this is appended to $host
|
||||
*
|
||||
@ -36,7 +58,7 @@ interface RequestInterface
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFullUri();
|
||||
public function getUri();
|
||||
|
||||
/**
|
||||
* Checks the request to see if the method matches a known value
|
||||
|
||||
@ -52,40 +52,26 @@ class Response implements ResponseInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $rawResponse
|
||||
* @return Response
|
||||
*/
|
||||
public static function createFromRawResponse($rawResponse)
|
||||
{
|
||||
$response = new self($rawResponse);
|
||||
//remove HTTP 100 responses
|
||||
$delimiter = "\r\n\r\n";// HTTP header delimiter
|
||||
//check if the 100 Continue header exists
|
||||
while (preg_match('#^HTTP/[0-9\\.]+\s+100\s+Continue#i', $rawResponse)) {
|
||||
$tmp = explode($delimiter, $rawResponse, 2);// grab the 100 Continue header
|
||||
$rawResponse = $tmp[1];// update the response, purging the most recent 100 Continue header
|
||||
}// repeat
|
||||
|
||||
$lines = preg_split('/(\\r?\\n)/', $rawResponse);
|
||||
$linesLen = count($lines);
|
||||
|
||||
for ($i = 0; $i < $linesLen; $i++) {
|
||||
if (0 == $i) {
|
||||
preg_match('/^HTTP\/(\d\.\d)\s(\d+)\s(.+)/', $lines[$i], $statusLine);
|
||||
|
||||
$response->setStatusCode($statusCode = $statusLine[2]);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (empty($lines[$i])) {
|
||||
$body = array_slice($lines, $i + 1);
|
||||
$response->setBody(implode("\n", $body));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (strpos($lines[$i], ':') !== false) {
|
||||
if (strpos($lines[$i], ':')) {
|
||||
$headerParts = explode(':', $lines[$i]);
|
||||
$response->setHeader($headerParts[0], $headerParts[1]);
|
||||
}
|
||||
|
||||
@ -40,6 +40,11 @@ class Configuration implements ConfigurationInterface
|
||||
->info('Private Key Filename')
|
||||
->defaultValue(getenv('HOME').'/.bitpay/api.sin')
|
||||
->end()
|
||||
->enumNode('network')
|
||||
->values(array('livenet', 'testnet'))
|
||||
->info('Network')
|
||||
->defaultValue('livenet')
|
||||
->end()
|
||||
->enumNode('adapter')
|
||||
->values(array('curl', 'mock'))
|
||||
->info('Client Adapter')
|
||||
|
||||
175
src/Bitpay/Crypto/McryptExtension.php
Normal file
175
src/Bitpay/Crypto/McryptExtension.php
Normal file
@ -0,0 +1,175 @@
|
||||
<?php
|
||||
/**
|
||||
* @license Copyright 2011-2014 BitPay Inc., MIT License
|
||||
* see https://github.com/bitpay/php-bitpay-client/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
namespace Bitpay\Crypto;
|
||||
|
||||
/**
|
||||
* Wrapper around the Mcrypt PHP Extension
|
||||
*
|
||||
* @see http://php.net/manual/en/book.mcrypt.php
|
||||
*/
|
||||
class McryptExtension implements CryptoInterface
|
||||
{
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static function hasSupport()
|
||||
{
|
||||
return function_exists('mcrypt_encrypt');
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getAlgos()
|
||||
{
|
||||
return mcrypt_list_algorithms();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the inititialization size used for a particular cipher
|
||||
* type. Returns an integer IV size on success or boolean false
|
||||
* on failure. If no IV is needed for the cipher type and mode,
|
||||
* a zero is returned.
|
||||
*
|
||||
* @param string $cipher_type
|
||||
* @return int|bool
|
||||
*/
|
||||
public function getIVSize($cipher_type = MCRYPT_TRIPLEDES)
|
||||
{
|
||||
$block_mode = 'cbc';
|
||||
|
||||
return mcrypt_get_iv_size($cipher_type, $block_mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the maximum key size that can be used with a particular
|
||||
* cipher type. Any key size equal to or less than the returned
|
||||
* value are legal key sizes. Depending on if the local mycrypt
|
||||
* extension is linked against 2.2 or 2.3/2.4 the block mode could
|
||||
* be required, hence the if/else statement.
|
||||
*
|
||||
* @param string $cipher_type
|
||||
* @return int
|
||||
*/
|
||||
public function getKeySize($cipher_type = MCRYPT_TRIPLEDES)
|
||||
{
|
||||
$block_mode = 'cbc';
|
||||
|
||||
$max_key_size = mcrypt_get_key_size($cipher_type);
|
||||
|
||||
if ($max_key_size !== false) {
|
||||
return $max_key_size;
|
||||
} else {
|
||||
return mcrypt_get_key_size($cipher_type, $block_mode);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs an internal self-test on the specified mcrypt algorithm and
|
||||
* returns either boolean true/false depending on if the self-test passed
|
||||
* or failed.
|
||||
*
|
||||
* @param string $cipher_type
|
||||
* @return boolean
|
||||
*/
|
||||
public function algoSelfTest($cipher_type = MCRYPT_TRIPLEDES)
|
||||
{
|
||||
return mcrypt_module_self_test($cipher_type);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Encrypts $text based on your $key and $iv. The returned text is
|
||||
* base-64 encoded to make it easier to work with in various scenarios.
|
||||
* Default cipher is MCRYPT_TRIPLEDES but you can substitute depending
|
||||
* on your specific encryption needs.
|
||||
*
|
||||
* @param string $text
|
||||
* @param string $key
|
||||
* @param string $iv
|
||||
* @param int $bit_check
|
||||
* @param string $cipher_type
|
||||
* @return string $text
|
||||
* @throws Exception $e
|
||||
*
|
||||
*/
|
||||
public function encrypt($text, $key = '', $iv = '', $bit_check = 8, $cipher_type = MCRYPT_TRIPLEDES)
|
||||
{
|
||||
try {
|
||||
/* Ensure the key & IV is the same for both encrypt & decrypt. */
|
||||
if (!empty($text) && is_string($text)) {
|
||||
$text_num = str_split($text, $bit_check);
|
||||
$text_num = $bit_check - strlen($text_num[count($text_num) - 1]);
|
||||
|
||||
for ($i = 0; $i<$text_num; $i++) {
|
||||
$text = $text.chr($text_num);
|
||||
}
|
||||
|
||||
$cipher = mcrypt_module_open($cipher_type, '', 'cbc', '');
|
||||
mcrypt_generic_init($cipher, $key, $iv);
|
||||
|
||||
$encrypted = mcrypt_generic($cipher, $text);
|
||||
mcrypt_generic_deinit($cipher);
|
||||
|
||||
mcrypt_module_close($cipher);
|
||||
|
||||
return base64_encode($encrypted);
|
||||
} else {
|
||||
return $text;
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Decrypts $text based on your $key and $iv. Make sure you use the same key
|
||||
* and initialization vector that you used when encrypting the $text. Default
|
||||
* cipher is MCRYPT_TRIPLEDES but you can substitute depending on the cipher
|
||||
* used for encrypting the text - very important.
|
||||
*
|
||||
* @param string $encrypted_text
|
||||
* @param string $key
|
||||
* @param string $iv
|
||||
* @param int $bit_check
|
||||
* @param string $cipher_type
|
||||
* @return string $text
|
||||
* @throws Exception $e
|
||||
*
|
||||
*/
|
||||
public function decrypt($encrypted_text, $key = '', $iv = '', $bit_check = 8, $cipher_type = MCRYPT_TRIPLEDES)
|
||||
{
|
||||
try {
|
||||
/* Ensure the key & IV is the same for both encrypt & decrypt. */
|
||||
if (!empty($encrypted_text)) {
|
||||
$cipher = mcrypt_module_open($cipher_type, '', 'cbc', '');
|
||||
|
||||
mcrypt_generic_init($cipher, $key, $iv);
|
||||
$decrypted = mdecrypt_generic($cipher, base64_decode($encrypted_text));
|
||||
|
||||
mcrypt_generic_deinit($cipher);
|
||||
$last_char = substr($decrypted, -1);
|
||||
|
||||
for ($i = 0; $i < $bit_check; $i++) {
|
||||
if (chr($i) == $last_char) {
|
||||
$decrypted = substr($decrypted, 0, strlen($decrypted) - $i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mcrypt_module_close($cipher);
|
||||
|
||||
return $decrypted;
|
||||
} else {
|
||||
return $encrypted_text;
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -26,7 +26,6 @@ class OpenSSLExtension implements CryptoInterface
|
||||
*/
|
||||
public function getAlgos()
|
||||
{
|
||||
return openssl_get_cipher_methods();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -98,7 +97,7 @@ class OpenSSLExtension implements CryptoInterface
|
||||
|
||||
return false;
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
while ($msg = openssl_error_string()) {
|
||||
throw new \Exception('Error in generateOpenSSLKeypair: OpenSSL reported error: '.$msg);
|
||||
}
|
||||
@ -178,86 +177,4 @@ class OpenSSLExtension implements CryptoInterface
|
||||
|
||||
return openssl_csr_export($csr, $out, $notext);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* Encrypts $text based on your $key and $iv. The returned text is
|
||||
* base-64 encoded to make it easier to work with in various scenarios.
|
||||
* Default cipher is AES-256-CBC but you can substitute depending
|
||||
* on your specific encryption needs.
|
||||
*
|
||||
* @param string $text
|
||||
* @param string $key
|
||||
* @param string $iv
|
||||
* @param int $bit_check
|
||||
* @param string $cipher_type
|
||||
* @return string $text
|
||||
* @throws Exception $e
|
||||
*
|
||||
*/
|
||||
public function encrypt($text, $key = '', $iv = '', $bit_check = 8, $cipher_type = 'AES-256-CBC')
|
||||
{
|
||||
try {
|
||||
if (function_exists('openssl_pkey_new')) {
|
||||
/* Ensure the key & IV is the same for both encrypt & decrypt. */
|
||||
if (!empty($text) && is_string($text)) {
|
||||
$text_num = str_split($text, $bit_check);
|
||||
$text_num = $bit_check - strlen($text_num[count($text_num) - 1]);
|
||||
|
||||
for ($i = 0; $i < $text_num; $i++) {
|
||||
$text = $text . chr($text_num);
|
||||
}
|
||||
$encrypted = openssl_encrypt($text, $cipher_type, $key, 0, $iv);
|
||||
return base64_encode($encrypted);
|
||||
} else {
|
||||
return $text;
|
||||
}
|
||||
} else {
|
||||
throw new \Exception('Error in OpenSSL encrypt: OpenSSL PHP extension missing. openssl_encrypt function not found.');
|
||||
|
||||
return false;
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Decrypts $text based on your $key and $iv. Make sure you use the same key
|
||||
* and initialization vector that you used when encrypting the $text. Default
|
||||
* cipher is AES-256-CBC but you can substitute depending on the cipher
|
||||
* used for encrypting the text - very important.
|
||||
*
|
||||
* @param string $encrypted_text
|
||||
* @param string $key
|
||||
* @param string $iv
|
||||
* @param int $bit_check
|
||||
* @param string $cipher_type
|
||||
* @return string $text
|
||||
* @throws Exception $e
|
||||
*
|
||||
*/
|
||||
public function decrypt($encrypted_text, $key = '', $iv = '', $bit_check = 8, $cipher_type = 'AES-256-CBC')
|
||||
{
|
||||
try {
|
||||
/* Ensure the key & IV is the same for both encrypt & decrypt. */
|
||||
if (!empty($encrypted_text)) {
|
||||
|
||||
$decrypted = openssl_decrypt(base64_decode($encrypted_text), $cipher_type, $key, 0, $iv);
|
||||
$last_char = substr($decrypted, -1);
|
||||
|
||||
for ($i = 0; $i < $bit_check; $i++) {
|
||||
if (chr($i) == $last_char) {
|
||||
$decrypted = substr($decrypted, 0, strlen($decrypted) - $i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $decrypted;
|
||||
} else {
|
||||
return $encrypted_text;
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,16 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Bitpay;
|
||||
|
||||
class CurrencyUnrestricted extends Currency
|
||||
{
|
||||
/**
|
||||
* Overrides the parent method to allow any currency symbol to be set.
|
||||
*/
|
||||
public function setCode($code)
|
||||
{
|
||||
$this->code = $code;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
@ -30,6 +30,7 @@ class BitpayExtension implements ExtensionInterface
|
||||
$loader = new XmlFileLoader($container, new FileLocator(__DIR__));
|
||||
$loader->load('services.xml');
|
||||
|
||||
$container->setParameter('network.class', 'Bitpay\Network\\'.ContainerBuilder::camelize($config['network']));
|
||||
$container->setParameter(
|
||||
'adapter.class',
|
||||
'Bitpay\Client\Adapter\\'.ContainerBuilder::camelize($config['adapter']).'Adapter'
|
||||
|
||||
@ -1,20 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!--
|
||||
/**
|
||||
* @license Copyright 2011-2017 BitPay Inc., MIT License
|
||||
* @license Copyright 2011-2014 BitPay Inc., MIT License
|
||||
* see https://github.com/bitpay/php-bitpay-client/blob/master/LICENSE
|
||||
*/
|
||||
-->
|
||||
<container xmlns="http://symfony.com/schema/dic/services">
|
||||
<parameters>
|
||||
<parameter key="network.class">Bitpay\Network\Livenet</parameter>
|
||||
<parameter key="adapter.class">Bitpay\Client\Adapter\CurlAdapter</parameter>
|
||||
<parameter key="key_manager.class">Bitpay\KeyManager</parameter>
|
||||
<parameter key="key_storage.class">Bitpay\Storage\FilesystemStorage</parameter>
|
||||
</parameters>
|
||||
<services>
|
||||
<service id="network" class="%network.class%" />
|
||||
<service id="adapter" class="%adapter.class%" />
|
||||
|
||||
<service id="client" class="Bitpay\Client\Client">
|
||||
<call method="setNetwork">
|
||||
<argument type="service" id="network" />
|
||||
</call>
|
||||
<call method="setAdapter">
|
||||
<argument type="service" id="adapter" />
|
||||
</call>
|
||||
@ -26,7 +31,7 @@
|
||||
</call>
|
||||
</service>
|
||||
|
||||
<service id="key_storage" class="%key_storage.class%">
|
||||
<service id="key_storage" class="%key_storage.class%" public="false">
|
||||
<argument>%bitpay.key_storage_password%</argument>
|
||||
</service>
|
||||
|
||||
@ -34,11 +39,11 @@
|
||||
<argument type="service" id="key_storage" />
|
||||
</service>
|
||||
|
||||
<service id="public_key" class="Bitpay\PublicKey">
|
||||
<service id="public_key" class="Bitpay\PublicKey" factory-service="key_storage" factory-method="load">
|
||||
<argument>%bitpay.public_key%</argument>
|
||||
</service>
|
||||
|
||||
<service id="private_key" class="Bitpay\PrivateKey">
|
||||
<service id="private_key" class="Bitpay\PrivateKey" factory-service="key_storage" factory-method="load">
|
||||
<argument>%bitpay.private_key%</argument>
|
||||
</service>
|
||||
</services>
|
||||
|
||||
@ -30,7 +30,7 @@ class Invoice implements InvoiceInterface
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $transactionSpeed = self::TRANSACTION_SPEED_MEDIUM;
|
||||
protected $transactionSpeed;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
@ -60,12 +60,7 @@ class Invoice implements InvoiceInterface
|
||||
/**
|
||||
* @var boolean
|
||||
*/
|
||||
protected $fullNotifications = true;
|
||||
|
||||
/**
|
||||
* @var boolean
|
||||
*/
|
||||
protected $extendedNotifications = false;
|
||||
protected $fullNotifications;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
@ -78,7 +73,6 @@ class Invoice implements InvoiceInterface
|
||||
protected $url;
|
||||
|
||||
/**
|
||||
* @deprecated Deprecated with introduction of BCH
|
||||
* @var float
|
||||
*/
|
||||
protected $btcPrice;
|
||||
@ -109,18 +103,11 @@ class Invoice implements InvoiceInterface
|
||||
protected $exceptionStatus;
|
||||
|
||||
/**
|
||||
* @deprecated Deprecated with introduction of BCH
|
||||
* @var
|
||||
*/
|
||||
protected $btcPaid;
|
||||
|
||||
/**
|
||||
* @var
|
||||
*/
|
||||
protected $amountPaid;
|
||||
|
||||
/**
|
||||
* @deprecated Deprecated with introduction of BCH
|
||||
* @var
|
||||
*/
|
||||
protected $rate;
|
||||
@ -131,34 +118,12 @@ class Invoice implements InvoiceInterface
|
||||
protected $token;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $refundAddresses;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $transactionCurrency;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $exchangeRates;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $paymentSubtotals;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $paymentTotals;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $paymentCurrencies;
|
||||
public function __construct()
|
||||
{
|
||||
$this->transactionSpeed = self::TRANSACTION_SPEED_MEDIUM;
|
||||
$this->fullNotifications = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
@ -168,14 +133,6 @@ class Invoice implements InvoiceInterface
|
||||
return $this->getItem()->getPrice();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getTaxIncluded()
|
||||
{
|
||||
return $this->getItem()->getTaxIncluded();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param float $price
|
||||
*
|
||||
@ -190,20 +147,6 @@ class Invoice implements InvoiceInterface
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param float $taxIncluded
|
||||
*
|
||||
* @return InvoiceInterface
|
||||
*/
|
||||
public function setTaxIncluded($taxIncluded)
|
||||
{
|
||||
if (!empty($taxIncluded)) {
|
||||
$this->getItem()->setTaxIncluded($taxIncluded);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
@ -429,21 +372,6 @@ class Invoice implements InvoiceInterface
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function isExtendedNotifications()
|
||||
{
|
||||
return $this->extendedNotifications;
|
||||
}
|
||||
|
||||
public function setExtendedNotifications($notifications)
|
||||
{
|
||||
$this->extendedNotifications = (boolean) $notifications;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
@ -489,7 +417,6 @@ class Invoice implements InvoiceInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Deprecated with introduction of BCH
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getBtcPrice()
|
||||
@ -498,7 +425,6 @@ class Invoice implements InvoiceInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Deprecated with introduction of BCH
|
||||
* @param float $btcPrice
|
||||
*
|
||||
* @return InvoiceInterface
|
||||
@ -527,13 +453,10 @@ class Invoice implements InvoiceInterface
|
||||
*/
|
||||
public function setInvoiceTime($invoiceTime)
|
||||
{
|
||||
if (is_a($invoiceTime, 'DateTime')) {
|
||||
if (!empty($invoiceTime)) {
|
||||
$this->invoiceTime = $invoiceTime;
|
||||
} else if (is_numeric($invoiceTime)) {
|
||||
$invoiceDateTime = new \DateTime('', new \DateTimeZone("UTC"));
|
||||
$invoiceDateTime->setTimestamp($invoiceTime);
|
||||
$this->invoiceTime = $invoiceDateTime;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@ -552,13 +475,10 @@ class Invoice implements InvoiceInterface
|
||||
*/
|
||||
public function setExpirationTime($expirationTime)
|
||||
{
|
||||
if (is_a($expirationTime, 'DateTime')) {
|
||||
if (!empty($expirationTime)) {
|
||||
$this->expirationTime = $expirationTime;
|
||||
} else if (is_numeric($expirationTime)) {
|
||||
$expirationDateTime = new \DateTime('', new \DateTimeZone("UTC"));
|
||||
$expirationDateTime->setTimestamp($expirationTime);
|
||||
$this->expirationTime = $expirationDateTime;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@ -577,13 +497,10 @@ class Invoice implements InvoiceInterface
|
||||
*/
|
||||
public function setCurrentTime($currentTime)
|
||||
{
|
||||
if (is_a($currentTime, 'DateTime')) {
|
||||
if (!empty($currentTime)) {
|
||||
$this->currentTime = $currentTime;
|
||||
} else if (is_numeric($currentTime)) {
|
||||
$currentDateTime = new \DateTime('', new \DateTimeZone("UTC"));
|
||||
$currentDateTime->setTimestamp($currentTime);
|
||||
$this->currentTime = $currentDateTime;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@ -602,7 +519,10 @@ class Invoice implements InvoiceInterface
|
||||
*/
|
||||
public function setOrderId($orderId)
|
||||
{
|
||||
$this->orderId = $orderId;
|
||||
if (!empty($orderId) && ctype_print($orderId)) {
|
||||
$this->orderId = trim($orderId);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@ -729,7 +649,6 @@ class Invoice implements InvoiceInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Deprecated with introduction of BCH
|
||||
* @param void
|
||||
* @return
|
||||
*/
|
||||
@ -739,7 +658,6 @@ class Invoice implements InvoiceInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Deprecated with introduction of BCH
|
||||
* @param
|
||||
* @return Invoice
|
||||
*/
|
||||
@ -753,29 +671,6 @@ class Invoice implements InvoiceInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @param void
|
||||
* @return
|
||||
*/
|
||||
public function getAmountPaid()
|
||||
{
|
||||
return $this->amountPaid;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param
|
||||
* @return Invoice
|
||||
*/
|
||||
public function setAmountPaid($amountPaid)
|
||||
{
|
||||
if (isset($amountPaid)) {
|
||||
$this->amountPaid = $amountPaid;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Deprecated with introduction of BCH
|
||||
* @param void
|
||||
* @return Invoice
|
||||
*/
|
||||
@ -785,7 +680,6 @@ class Invoice implements InvoiceInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Deprecated with introduction of BCH
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
@ -798,29 +692,6 @@ class Invoice implements InvoiceInterface
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param void
|
||||
* @return Invoice
|
||||
*/
|
||||
public function getExchangeRates()
|
||||
{
|
||||
return $this->exchangeRates;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
public function setExchangeRates($exchangeRates)
|
||||
{
|
||||
if (!empty($exchangeRates)) {
|
||||
$this->exchangeRates = $exchangeRates;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return TokenInterface
|
||||
*/
|
||||
@ -837,107 +708,4 @@ class Invoice implements InvoiceInterface
|
||||
$this->token = $token;
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getRefundAddresses()
|
||||
{
|
||||
return $this->refundAddresses;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $refundAddress
|
||||
*
|
||||
* @return InvoiceInterface
|
||||
*/
|
||||
public function setRefundAddresses($refundAddresses)
|
||||
{
|
||||
if (!empty($refundAddresses)) {
|
||||
$this->refundAddresses = $refundAddresses;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getTransactionCurrency()
|
||||
{
|
||||
return $this->transactionCurrency;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $transactionCurrency
|
||||
*
|
||||
* @return InvoiceInterface
|
||||
*/
|
||||
public function setTransactionCurrency($transactionCurrency)
|
||||
{
|
||||
if (!empty($transactionCurrency) && ctype_print($transactionCurrency)) {
|
||||
$this->transactionCurrency = trim($transactionCurrency);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param void
|
||||
* @return Invoice
|
||||
*/
|
||||
public function getPaymentSubtotals()
|
||||
{
|
||||
return $this->paymentSubtotals;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
public function setPaymentSubtotals($paymentSubtotals)
|
||||
{
|
||||
if (!empty($paymentSubtotals)) {
|
||||
$this->paymentSubtotals = $paymentSubtotals;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
* @param void
|
||||
* @return Invoice
|
||||
*/
|
||||
public function getPaymentTotals()
|
||||
{
|
||||
return $this->paymentTotals;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
public function setPaymentTotals($paymentTotals)
|
||||
{
|
||||
if (!empty($paymentTotals)) {
|
||||
$this->paymentTotals = $paymentTotals;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getPaymentCurrencies() {
|
||||
return $this->paymentCurrencies;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function setPaymentCurrencies($paymentCurrencies) {
|
||||
$this->paymentCurrencies = $paymentCurrencies;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
||||
@ -84,8 +84,6 @@ interface InvoiceInterface
|
||||
*/
|
||||
public function getPrice();
|
||||
|
||||
public function getTaxIncluded();
|
||||
|
||||
/**
|
||||
* This is the currency code set for the price setting. The pricing currencies
|
||||
* currently supported are USD, EUR, BTC, and all of the codes listed on this page:
|
||||
@ -168,7 +166,7 @@ interface InvoiceInterface
|
||||
public function getStatus();
|
||||
|
||||
/**
|
||||
* default value: true
|
||||
* default value: false
|
||||
* ● true: Notifications will be sent on every status change.
|
||||
* ● false: Notifications are only sent when an invoice is confirmed (according
|
||||
* to the “transactionSpeed” setting).
|
||||
@ -177,15 +175,6 @@ interface InvoiceInterface
|
||||
*/
|
||||
public function isFullNotifications();
|
||||
|
||||
/**
|
||||
* default value: false
|
||||
* ● true: Notifications will also be sent for expired invoices and refunds.
|
||||
* ● false: Notifications will not be sent for expired invoices and refunds
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isExtendedNotifications();
|
||||
|
||||
/**
|
||||
* The unique id of the invoice assigned by bitpay.com
|
||||
*
|
||||
@ -367,34 +356,4 @@ interface InvoiceInterface
|
||||
/**
|
||||
*/
|
||||
public function getToken();
|
||||
|
||||
/**
|
||||
* An array containing all bitcoin addresses linked to the invoice.
|
||||
* Only filled when doing a getInvoice using the Merchant facade.
|
||||
* The array contains
|
||||
* [refundAddress] => Array
|
||||
* [type] => string (e.g. "PaymentProtocol")
|
||||
* [date] => datetime string
|
||||
*
|
||||
* @return array|object
|
||||
*/
|
||||
public function getRefundAddresses();
|
||||
|
||||
/**
|
||||
* Get the enforced transaction currencies.
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
public function getPaymentCurrencies();
|
||||
|
||||
/**
|
||||
* Set specific invoice currencies and to enforce them on payment step.
|
||||
*
|
||||
* @param array $paymentCurrencies
|
||||
* The currencies need to match what is supported by BTCPay Server.
|
||||
* E.g. BTC, BTC_ONCHAIN, BTC_OFFCHAIN, LTC, XMR_MONEROLIKE etc.
|
||||
*
|
||||
* @return InvoiceInterface
|
||||
*/
|
||||
public function setPaymentCurrencies($paymentCurrencies);
|
||||
}
|
||||
|
||||
@ -29,11 +29,6 @@ class Item implements ItemInterface
|
||||
*/
|
||||
protected $price;
|
||||
|
||||
/**
|
||||
* @var float
|
||||
*/
|
||||
protected $taxIncluded;
|
||||
|
||||
/**
|
||||
* @var integer
|
||||
*/
|
||||
@ -101,16 +96,6 @@ class Item implements ItemInterface
|
||||
return $this->price;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function getTaxIncluded()
|
||||
{
|
||||
return $this->taxIncluded;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $price A float, integer, or en_US formatted numeric string
|
||||
*
|
||||
@ -127,17 +112,6 @@ class Item implements ItemInterface
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setTaxIncluded($taxIncluded)
|
||||
{
|
||||
if (is_string($taxIncluded)) {
|
||||
$this->checkPriceFormat($taxIncluded);
|
||||
}
|
||||
|
||||
$this->taxIncluded = (float)$taxIncluded;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
@ -183,8 +157,12 @@ class Item implements ItemInterface
|
||||
* values with more than 6 decimals.
|
||||
*
|
||||
* @param string $price The price value to check
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function checkPriceFormat($price)
|
||||
{
|
||||
if (preg_match('/^[0-9]+?[\.,][0-9]{1,6}?$/', $price) !== 1) {
|
||||
throw new \Bitpay\Client\ArgumentException("Price must be formatted as a float");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -34,11 +34,6 @@ interface ItemInterface
|
||||
*/
|
||||
public function getPrice();
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getTaxIncluded();
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
|
||||
@ -30,9 +30,9 @@ class GmpEngine implements EngineInterface
|
||||
* @param String $a Numeric String
|
||||
* @param String $b Numeric String
|
||||
*/
|
||||
public function div($a, $b, $round = GMP_ROUND_ZERO)
|
||||
public function div($a, $b)
|
||||
{
|
||||
return gmp_strval(gmp_div_q($a, $b, $round));
|
||||
return gmp_strval(gmp_div($a, $b));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -9,37 +9,23 @@ namespace Bitpay\Math;
|
||||
class Math
|
||||
{
|
||||
private static $engine;
|
||||
private static $engineName;
|
||||
|
||||
public static function setEngine($engine)
|
||||
{
|
||||
static::$engine = $engine;
|
||||
}
|
||||
|
||||
public static function setEngineName($engineName)
|
||||
{
|
||||
static::$engineName = $engineName;
|
||||
}
|
||||
|
||||
public static function getEngine()
|
||||
{
|
||||
return static::$engine;
|
||||
}
|
||||
|
||||
public static function getEngineName()
|
||||
{
|
||||
return static::$engineName;
|
||||
}
|
||||
|
||||
public static function __callStatic($name, $arguments)
|
||||
{
|
||||
if (is_null(static::$engine)) {
|
||||
if (extension_loaded('gmp')) {
|
||||
static::$engine = new GmpEngine();
|
||||
static::$engineName = "GMP";
|
||||
} elseif (extension_loaded('bcmath')) {
|
||||
static::$engine = new BcEngine();
|
||||
static::$engineName = "BCMATH";
|
||||
} else {
|
||||
throw new \Exception('The GMP or BCMATH extension for PHP is required.');
|
||||
}
|
||||
|
||||
47
src/Bitpay/Network/Customnet.php
Normal file
47
src/Bitpay/Network/Customnet.php
Normal file
@ -0,0 +1,47 @@
|
||||
<?php
|
||||
/**
|
||||
* @license Copyright 2011-2014 BitPay Inc., MIT License
|
||||
* see https://github.com/bitpay/php-bitpay-client/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
namespace Bitpay\Network;
|
||||
|
||||
/**
|
||||
*
|
||||
* @package Bitcore
|
||||
*/
|
||||
class Customnet implements NetworkInterface
|
||||
{
|
||||
protected $host_url;
|
||||
|
||||
protected $host_port;
|
||||
|
||||
public $isPortRequiredInUrl;
|
||||
|
||||
public function __construct($url, $port, $isPortRequiredInUrl = false)
|
||||
{
|
||||
$this->host_url = $url;
|
||||
$this->host_port = $port;
|
||||
$this->isPortRequiredInUrl = $isPortRequiredInUrl;
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return 'Custom Network';
|
||||
}
|
||||
|
||||
public function getAddressVersion()
|
||||
{
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
public function getApiHost()
|
||||
{
|
||||
return $this->host_url;
|
||||
}
|
||||
|
||||
public function getApiPort()
|
||||
{
|
||||
return $this->host_port;
|
||||
}
|
||||
}
|
||||
34
src/Bitpay/Network/Livenet.php
Normal file
34
src/Bitpay/Network/Livenet.php
Normal file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
/**
|
||||
* @license Copyright 2011-2014 BitPay Inc., MIT License
|
||||
* see https://github.com/bitpay/php-bitpay-client/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
namespace Bitpay\Network;
|
||||
|
||||
/**
|
||||
*
|
||||
* @package Bitcore
|
||||
*/
|
||||
class Livenet implements NetworkInterface
|
||||
{
|
||||
public function getName()
|
||||
{
|
||||
return 'livenet';
|
||||
}
|
||||
|
||||
public function getAddressVersion()
|
||||
{
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
public function getApiHost()
|
||||
{
|
||||
return 'bitpay.com';
|
||||
}
|
||||
|
||||
public function getApiPort()
|
||||
{
|
||||
return 443;
|
||||
}
|
||||
}
|
||||
27
src/Bitpay/Network/NetworkAware.php
Normal file
27
src/Bitpay/Network/NetworkAware.php
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
/**
|
||||
* @license Copyright 2011-2014 BitPay Inc., MIT License
|
||||
* see https://github.com/bitpay/php-bitpay-client/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
namespace Bitpay\Network;
|
||||
|
||||
/**
|
||||
*
|
||||
* @package Bitcore
|
||||
*/
|
||||
abstract class NetworkAware implements NetworkAwareInterface
|
||||
{
|
||||
/**
|
||||
* @var NetworkInterface
|
||||
*/
|
||||
protected $network;
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function setNetwork(NetworkInterface $network = null)
|
||||
{
|
||||
$this->network = $network;
|
||||
}
|
||||
}
|
||||
21
src/Bitpay/Network/NetworkAwareInterface.php
Normal file
21
src/Bitpay/Network/NetworkAwareInterface.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
/**
|
||||
* @license Copyright 2011-2014 BitPay Inc., MIT License
|
||||
* see https://github.com/bitpay/php-bitpay-client/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
namespace Bitpay\Network;
|
||||
|
||||
/**
|
||||
*
|
||||
* @package Bitcore
|
||||
*/
|
||||
interface NetworkAwareInterface
|
||||
{
|
||||
/**
|
||||
* Set the network the object will work with
|
||||
*
|
||||
* @param NetworkInterface $network
|
||||
*/
|
||||
public function setNetwork(NetworkInterface $network = null);
|
||||
}
|
||||
43
src/Bitpay/Network/NetworkInterface.php
Normal file
43
src/Bitpay/Network/NetworkInterface.php
Normal file
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
/**
|
||||
* @license Copyright 2011-2014 BitPay Inc., MIT License
|
||||
* see https://github.com/bitpay/php-bitpay-client/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
namespace Bitpay\Network;
|
||||
|
||||
/**
|
||||
*
|
||||
* @package Bitcore
|
||||
*/
|
||||
interface NetworkInterface
|
||||
{
|
||||
/**
|
||||
* Name of network, currently on livenet and testnet
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName();
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getAddressVersion();
|
||||
|
||||
/**
|
||||
* The host that is used to interact with this network
|
||||
*
|
||||
* @see https://github.com/bitpay/insight
|
||||
* @see https://github.com/bitpay/insight-api
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getApiHost();
|
||||
|
||||
/**
|
||||
* The port of the host
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getApiPort();
|
||||
}
|
||||
34
src/Bitpay/Network/Testnet.php
Normal file
34
src/Bitpay/Network/Testnet.php
Normal file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
/**
|
||||
* @license Copyright 2011-2014 BitPay Inc., MIT License
|
||||
* see https://github.com/bitpay/php-bitpay-client/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
namespace Bitpay\Network;
|
||||
|
||||
/**
|
||||
*
|
||||
* @package Bitcore
|
||||
*/
|
||||
class Testnet implements NetworkInterface
|
||||
{
|
||||
public function getName()
|
||||
{
|
||||
return 'testnet';
|
||||
}
|
||||
|
||||
public function getAddressVersion()
|
||||
{
|
||||
return 0x6f;
|
||||
}
|
||||
|
||||
public function getApiHost()
|
||||
{
|
||||
return 'test.bitpay.com';
|
||||
}
|
||||
|
||||
public function getApiPort()
|
||||
{
|
||||
return 443;
|
||||
}
|
||||
}
|
||||
@ -40,19 +40,6 @@ class PrivateKey extends Key
|
||||
return (string) $this->hex;
|
||||
}
|
||||
|
||||
/*
|
||||
* Use this method if you have a hex-encoded private key
|
||||
* and you want to initialize your private key.
|
||||
* If you have a private key, you can derive your public key
|
||||
* and also your sin.
|
||||
* @param string
|
||||
*/
|
||||
public function setHex($hex)
|
||||
{
|
||||
$this->hex = $hex;
|
||||
$this->dec = Util::decodeHex($this->hex);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return PublicKey
|
||||
*/
|
||||
@ -220,7 +207,7 @@ class PrivateKey extends Key
|
||||
$byte = strrev($byte);
|
||||
|
||||
// msb check
|
||||
if (Math::cmp('0x'.bin2hex($byte[0]), '0'.'x80') >= 0) {
|
||||
if (Math::cmp('0x'.bin2hex($byte[0]), '0x80') >= 0) {
|
||||
$byte = chr(0x00).$byte;
|
||||
}
|
||||
|
||||
@ -240,7 +227,7 @@ class PrivateKey extends Key
|
||||
$byte = strrev($byte);
|
||||
|
||||
// msb check
|
||||
if (Math::cmp('0x'.bin2hex($byte[0]), '0'.'x80') >= 0) {
|
||||
if (Math::cmp('0x'.bin2hex($byte[0]), '0x80') >= 0) {
|
||||
$byte = chr(0x00).$byte;
|
||||
}
|
||||
|
||||
|
||||
@ -36,7 +36,7 @@ class PublicKey extends Key
|
||||
return '';
|
||||
}
|
||||
|
||||
if (Math::mod('0x'.$this->y, '0'.'x02') == '1') {
|
||||
if (Math::mod('0x'.$this->y, '0x02') == '1') {
|
||||
return sprintf('03%s', $this->x);
|
||||
} else {
|
||||
return sprintf('02%s', $this->x);
|
||||
|
||||
@ -15,11 +15,6 @@ class EncryptedFilesystemStorage implements StorageInterface
|
||||
*/
|
||||
private $password;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $unencoded_password;
|
||||
|
||||
/**
|
||||
* Initialization Vector
|
||||
*/
|
||||
@ -40,10 +35,7 @@ class EncryptedFilesystemStorage implements StorageInterface
|
||||
*/
|
||||
public function __construct($password)
|
||||
{
|
||||
//to make this an non-breaking api change,
|
||||
//I will have to keep both versions of the password
|
||||
$this->password = base64_encode($password);
|
||||
$this->unencoded_password = $password;
|
||||
$this->password = $password;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -80,10 +72,6 @@ class EncryptedFilesystemStorage implements StorageInterface
|
||||
$encoded = file_get_contents($id);
|
||||
$decoded = openssl_decrypt(\Bitpay\Util\Util::binConv($encoded), self::METHOD, $this->password, 1, self::IV);
|
||||
|
||||
if (false === $decoded) {
|
||||
$decoded = openssl_decrypt(\Bitpay\Util\Util::binConv($encoded), self::METHOD, $this->unencoded_password, 1, self::IV);
|
||||
}
|
||||
|
||||
if (false === $decoded) {
|
||||
throw new \Exception('Could not decode key');
|
||||
}
|
||||
|
||||
@ -61,11 +61,6 @@ class User implements UserInterface
|
||||
*/
|
||||
protected $agreedToTOSandPP;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $notify;
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
@ -277,6 +272,7 @@ class User implements UserInterface
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
@ -284,26 +280,4 @@ class User implements UserInterface
|
||||
{
|
||||
return $this->agreedToTOSandPP;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function getNotify()
|
||||
{
|
||||
return $this->notify;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $boolvalue
|
||||
*
|
||||
* @return User
|
||||
*/
|
||||
public function setNotify($boolvalue)
|
||||
{
|
||||
if (!empty($boolvalue)) {
|
||||
$this->notify = $boolvalue;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
||||
@ -58,9 +58,4 @@ interface UserInterface
|
||||
* @return string
|
||||
*/
|
||||
public function getCountry();
|
||||
|
||||
/**
|
||||
* @return boolean
|
||||
*/
|
||||
public function getNotify();
|
||||
}
|
||||
|
||||
@ -235,12 +235,7 @@ class Util
|
||||
} else {
|
||||
$bin .= '0';
|
||||
}
|
||||
$prevDec = $dec;
|
||||
$dec = Math::div($dec, 2);
|
||||
//sanity check to avoid infinite loop
|
||||
if (Math::cmp($prevDec, $dec) < 1) {
|
||||
throw new \Exception('Math library has unexpected behavior, please report the following information to support@bitpay.com. Math Engine is: ' . Math::getEngineName() . '. PHP Version is: ' . phpversion() . '.');
|
||||
}
|
||||
}
|
||||
|
||||
return $bin;
|
||||
@ -433,6 +428,13 @@ class Util
|
||||
$requirements['PHP'] = true;
|
||||
}
|
||||
|
||||
// Mcrypt Extension
|
||||
if (!extension_loaded('mcrypt')) {
|
||||
$requirements['Mcrypt'] = 'The Mcrypt PHP extension could not be found.';
|
||||
} else {
|
||||
$requirements['Mcrypt'] = true;
|
||||
}
|
||||
|
||||
// OpenSSL Extension
|
||||
if (!extension_loaded('openssl')) {
|
||||
$requirements['OpenSSL'] = 'The OpenSSL PHP extension could not be found.';
|
||||
|
||||
@ -15,7 +15,9 @@ class BitpayTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
$bitpay = new \Bitpay\Bitpay(
|
||||
array(
|
||||
'bitpay' => array()
|
||||
'bitpay' => array(
|
||||
'network' => 'testnet',
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
@ -29,11 +31,11 @@ class BitpayTest extends \PHPUnit_Framework_TestCase
|
||||
public function testGet()
|
||||
{
|
||||
$bitpay = new \Bitpay\Bitpay();
|
||||
$this->assertInstanceOf('Bitpay\Client\Adapter\CurlAdapter', $bitpay->get('adapter'));
|
||||
$this->assertInstanceOf('Bitpay\Network\Livenet', $bitpay->get('network'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
|
||||
* @expectedException Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function testGetInvalidService()
|
||||
{
|
||||
@ -47,6 +49,7 @@ class BitpayTest extends \PHPUnit_Framework_TestCase
|
||||
$bitpay = new \Bitpay\Bitpay(
|
||||
array(
|
||||
'bitpay' => array(
|
||||
'network' => 'testnet',
|
||||
'private_key' => vfsStream::url('tmp/key.pri'),
|
||||
'public_key' => vfsStream::url('tmp/key.pub'),
|
||||
)
|
||||
|
||||
@ -29,25 +29,24 @@ class CurlAdapterTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertEquals(array(), $adapter->getCurlOptions());
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Bitpay\Client\ConnectionException
|
||||
*/
|
||||
public function testSendRequestWithException()
|
||||
{
|
||||
$this->setExpectedException('Bitpay\Client\ConnectionException');
|
||||
|
||||
$curl_options = array(
|
||||
CURLOPT_URL => 'btcpay.example.com',
|
||||
CURLOPT_URL => "www.example.com",
|
||||
CURLOPT_SSL_VERIFYPEER => 1,
|
||||
CURLOPT_SSL_VERIFYHOST => 2,
|
||||
);
|
||||
|
||||
$adapter = new CurlAdapter($curl_options);
|
||||
$adapter->sendRequest($this->request);
|
||||
$response = $adapter->sendRequest($this->request);
|
||||
}
|
||||
|
||||
public function testSendRequestWithoutException()
|
||||
{
|
||||
$curl_options = array(
|
||||
CURLOPT_URL => 'www.bitpay.com',
|
||||
CURLOPT_URL => "www.bitpay.com",
|
||||
CURLOPT_SSL_VERIFYPEER => 1,
|
||||
CURLOPT_SSL_VERIFYHOST => 2,
|
||||
);
|
||||
@ -57,4 +56,4 @@ class CurlAdapterTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertNotNull($response);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -22,7 +22,7 @@ class ClientTest extends \PHPUnit_Framework_TestCase
|
||||
public function setUp()
|
||||
{
|
||||
$this->client = new Client();
|
||||
$this->client->setUri('https://btcpay.server/');
|
||||
$this->client->setNetwork(new \Bitpay\Network\Testnet());
|
||||
$this->client->setToken($this->getMockToken());
|
||||
$this->client->setPublicKey($this->getMockPublicKey());
|
||||
$this->client->setPrivateKey($this->getMockPrivateKey());
|
||||
@ -48,13 +48,11 @@ class ClientTest extends \PHPUnit_Framework_TestCase
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Bitpay\Client\BitpayException
|
||||
* @expectedExceptionMessage You should provider the url of your BTCPAY server
|
||||
* @expectedException \Exception
|
||||
*/
|
||||
public function testBtcPayServerUrlNotProvided()
|
||||
{
|
||||
$client = new Client();
|
||||
$client->getTokens();
|
||||
public function testCheckPriceAndCurrencyWithException() {
|
||||
$client = new ChildOfClient();
|
||||
$res = $client->checkPriceAndCurrency(.991, 'ABC');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -168,6 +166,7 @@ class ClientTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
public function testCreateInvoice()
|
||||
{
|
||||
|
||||
$buyer = $this->getMockBuyer();
|
||||
$buyer->method('getAddress')->will($this->returnValue(array()));
|
||||
|
||||
@ -183,6 +182,7 @@ class ClientTest extends \PHPUnit_Framework_TestCase
|
||||
$item->setPrice('19.95');
|
||||
$invoice->setItem($item);
|
||||
|
||||
|
||||
$response = $this->getMockResponse();
|
||||
$response->method('getBody')->willReturn(file_get_contents(__DIR__ . '/../../DataFixtures/invoice.json'));
|
||||
|
||||
@ -195,12 +195,12 @@ class ClientTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertEquals('abcdefghijkmnopqrstuvw', $invoice->getId());
|
||||
$this->assertEquals('https://test.bitpay.com/invoice?id=abcdefghijkmnopqrstuvw', $invoice->getUrl());
|
||||
$this->assertEquals('new', $invoice->getStatus());
|
||||
//$this->assertEquals('0.0632', $invoice->getBtcPrice());
|
||||
$this->assertEquals('0.0632', $invoice->getBtcPrice());
|
||||
$this->assertEquals(19.95, $invoice->getPrice());
|
||||
$this->assertInstanceOf('DateTime', $invoice->getInvoiceTime());
|
||||
$this->assertInstanceOf('DateTime', $invoice->getExpirationTime());
|
||||
$this->assertInstanceOf('DateTime', $invoice->getCurrentTime());
|
||||
//$this->assertEquals('0.0000', $invoice->getBtcPaid());
|
||||
$this->assertEquals(1412594514486, $invoice->getInvoiceTime());
|
||||
$this->assertEquals(1412595414486, $invoice->getExpirationTime());
|
||||
$this->assertEquals(1412594514518, $invoice->getCurrentTime());
|
||||
$this->assertEquals('0.0000', $invoice->getBtcPaid());
|
||||
$this->assertEquals(315.7, $invoice->getRate());
|
||||
$this->assertEquals(false, $invoice->getExceptionStatus());
|
||||
$this->assertEquals('abcdefghijklmno', $invoice->getToken()->getToken());
|
||||
@ -223,12 +223,12 @@ class ClientTest extends \PHPUnit_Framework_TestCase
|
||||
$invoice->method('setId')->will($this->returnSelf());
|
||||
$invoice->method('setUrl')->will($this->returnSelf());
|
||||
$invoice->method('setStatus')->will($this->returnSelf());
|
||||
//$invoice->method('setBtcPrice')->will($this->returnSelf());
|
||||
$invoice->method('setBtcPrice')->will($this->returnSelf());
|
||||
$invoice->method('setPrice')->will($this->returnSelf());
|
||||
$invoice->method('setInvoiceTime')->will($this->returnSelf());
|
||||
$invoice->method('setExpirationTime')->will($this->returnSelf());
|
||||
$invoice->method('setCurrentTime')->will($this->returnSelf());
|
||||
//$invoice->method('setBtcPaid')->will($this->returnSelf());
|
||||
$invoice->method('setBtcPaid')->will($this->returnSelf());
|
||||
$invoice->method('setRate')->will($this->returnSelf());
|
||||
$invoice->method('setExceptionStatus')->will($this->returnSelf());
|
||||
$invoice->method('getCurrency')->willReturn($this->getMockCurrency());
|
||||
@ -243,6 +243,71 @@ class ClientTest extends \PHPUnit_Framework_TestCase
|
||||
$this->client->createInvoice($invoice);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException Exception
|
||||
*/
|
||||
public function testCreateInvoiceWithTooMuchPrecisionForAnythingButBitcoin()
|
||||
{
|
||||
$item = $this->getMockItem();
|
||||
$currency = $this->getMockCurrency();
|
||||
$currency->method('getCode')->will($this->returnValue("USD"));
|
||||
$item->method('getPrice')->will($this->returnValue(9.999));
|
||||
|
||||
$buyer = $this->getMockBuyer();
|
||||
$buyer->method('getAddress')->will($this->returnValue(array()));
|
||||
|
||||
$invoice = $this->getMockInvoice();
|
||||
$invoice->method('getItem')->willReturn($item);
|
||||
$invoice->method('getBuyer')->willReturn($buyer);
|
||||
$invoice->method('setId')->will($this->returnSelf());
|
||||
$invoice->method('setUrl')->will($this->returnSelf());
|
||||
$invoice->method('setStatus')->will($this->returnSelf());
|
||||
$invoice->method('setBtcPrice')->will($this->returnSelf());
|
||||
$invoice->method('setPrice')->will($this->returnSelf());
|
||||
$invoice->method('setInvoiceTime')->will($this->returnSelf());
|
||||
$invoice->method('setExpirationTime')->will($this->returnSelf());
|
||||
$invoice->method('setCurrentTime')->will($this->returnSelf());
|
||||
$invoice->method('setBtcPaid')->will($this->returnSelf());
|
||||
$invoice->method('setRate')->will($this->returnSelf());
|
||||
$invoice->method('setExceptionStatus')->will($this->returnSelf());
|
||||
$invoice->method('getCurrency')->willReturn($currency);
|
||||
|
||||
$this->client->createInvoice($invoice);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @expectedException Exception
|
||||
*/
|
||||
public function testCreateInvoiceWithTooMuchPrecisionEvenForBitcoin()
|
||||
{
|
||||
$item = $this->getMockItem();
|
||||
$currency = $this->getMockCurrency();
|
||||
$currency->method('getCode')->will($this->returnValue("BTC"));
|
||||
$item->method('getPrice')->will($this->returnValue(.9999999));
|
||||
|
||||
$buyer = $this->getMockBuyer();
|
||||
$buyer->method('getAddress')->will($this->returnValue(array()));
|
||||
|
||||
$invoice = $this->getMockInvoice();
|
||||
$invoice->method('getItem')->willReturn($item);
|
||||
$invoice->method('getBuyer')->willReturn($buyer);
|
||||
$invoice->method('setId')->will($this->returnSelf());
|
||||
$invoice->method('setUrl')->will($this->returnSelf());
|
||||
$invoice->method('setStatus')->will($this->returnSelf());
|
||||
$invoice->method('setBtcPrice')->will($this->returnSelf());
|
||||
$invoice->method('setPrice')->will($this->returnSelf());
|
||||
$invoice->method('setInvoiceTime')->will($this->returnSelf());
|
||||
$invoice->method('setExpirationTime')->will($this->returnSelf());
|
||||
$invoice->method('setCurrentTime')->will($this->returnSelf());
|
||||
$invoice->method('setBtcPaid')->will($this->returnSelf());
|
||||
$invoice->method('setRate')->will($this->returnSelf());
|
||||
$invoice->method('setExceptionStatus')->will($this->returnSelf());
|
||||
$invoice->method('getCurrency')->willReturn($currency);
|
||||
|
||||
$this->client->createInvoice($invoice);
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testCreateInvoice
|
||||
*/
|
||||
@ -273,12 +338,12 @@ class ClientTest extends \PHPUnit_Framework_TestCase
|
||||
$invoice->method('setId')->will($this->returnSelf());
|
||||
$invoice->method('setUrl')->will($this->returnSelf());
|
||||
$invoice->method('setStatus')->will($this->returnSelf());
|
||||
//$invoice->method('setBtcPrice')->will($this->returnSelf());
|
||||
$invoice->method('setBtcPrice')->will($this->returnSelf());
|
||||
$invoice->method('setPrice')->will($this->returnSelf());
|
||||
$invoice->method('setInvoiceTime')->will($this->returnSelf());
|
||||
$invoice->method('setExpirationTime')->will($this->returnSelf());
|
||||
$invoice->method('setCurrentTime')->will($this->returnSelf());
|
||||
//$invoice->method('setBtcPaid')->will($this->returnSelf());
|
||||
$invoice->method('setBtcPaid')->will($this->returnSelf());
|
||||
$invoice->method('setRate')->will($this->returnSelf());
|
||||
$invoice->method('setExceptionStatus')->will($this->returnSelf());
|
||||
$invoice->method('getCurrency')->willReturn($this->getMockCurrency());
|
||||
@ -551,16 +616,15 @@ class ClientTest extends \PHPUnit_Framework_TestCase
|
||||
$invoice = $this->getMockBuilder('Bitpay\InvoiceInterface')
|
||||
->setMethods(
|
||||
array(
|
||||
'getPrice', 'getTaxIncluded', 'getCurrency', 'getItem', 'getBuyer', 'getTransactionSpeed',
|
||||
'getPrice', 'getCurrency', 'getItem', 'getBuyer', 'getTransactionSpeed',
|
||||
'getNotificationEmail', 'getNotificationUrl', 'getRedirectUrl', 'getPosData', 'getStatus',
|
||||
'isFullNotifications', 'getId', 'getUrl', 'getBtcPrice', 'getInvoiceTime',
|
||||
'getExpirationTime', 'getCurrentTime', 'getOrderId', 'getItemDesc', 'getItemCode',
|
||||
'isPhysical', 'getBuyerName', 'getBuyerAddress1', 'getBuyerAddress2', 'getBuyerCity',
|
||||
'getBuyerState', 'getBuyerZip', 'getBuyerCountry', 'getBuyerEmail', 'getBuyerPhone',
|
||||
'getExceptionStatus', 'getBtcPaid', 'getRate', 'getToken', 'getRefundAddresses',
|
||||
'setId', 'setUrl', 'setStatus', 'setBtcPrice', 'setPrice', 'setInvoiceTime', 'setExpirationTime',
|
||||
'setCurrentTime', 'setBtcPaid', 'setRate', 'setToken', 'setExceptionStatus', 'isExtendedNotifications',
|
||||
'setPosData',
|
||||
'getExceptionStatus', 'getBtcPaid', 'getRate', 'getToken', 'setId', 'setUrl',
|
||||
'setStatus', 'setBtcPrice', 'setPrice', 'setInvoiceTime', 'setExpirationTime',
|
||||
'setCurrentTime', 'setBtcPaid', 'setRate', 'setToken', 'setExceptionStatus',
|
||||
)
|
||||
)
|
||||
->getMock();
|
||||
@ -624,7 +688,6 @@ class ClientTest extends \PHPUnit_Framework_TestCase
|
||||
'getState',
|
||||
'getZip',
|
||||
'getCountry',
|
||||
'getNotify'
|
||||
)
|
||||
)
|
||||
->getMock();
|
||||
@ -638,7 +701,6 @@ class ClientTest extends \PHPUnit_Framework_TestCase
|
||||
'getCode',
|
||||
'getDescription',
|
||||
'getPrice',
|
||||
'getTaxIncluded',
|
||||
'getQuantity',
|
||||
'isPhysical',
|
||||
)
|
||||
|
||||
@ -8,9 +8,6 @@ namespace Bitpay\Client;
|
||||
|
||||
class RequestTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/** @var Request */
|
||||
private $request;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
$this->request = new Request();
|
||||
@ -80,10 +77,35 @@ class RequestTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertFalse($this->request->isMethod('unknown method'));
|
||||
}
|
||||
|
||||
public function testSetUri()
|
||||
public function testGetPort()
|
||||
{
|
||||
$this->request->setUri('https://btcpay.server/');
|
||||
$this->assertSame('https://btcpay.server/', $this->request->getUri());
|
||||
$this->assertSame(443, $this->request->getPort());
|
||||
}
|
||||
|
||||
public function testSetPort()
|
||||
{
|
||||
$this->request->setPort(444);
|
||||
$this->assertSame(444, $this->request->getPort());
|
||||
}
|
||||
|
||||
|
||||
public function testGetSchema()
|
||||
{
|
||||
$this->assertSame('https', $this->request->getSchema());
|
||||
}
|
||||
|
||||
public function testGetHost()
|
||||
{
|
||||
$this->assertNull($this->request->getHost());
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testGetHost
|
||||
*/
|
||||
public function testSetHost()
|
||||
{
|
||||
$this->request->setHost('test.bitpay.com');
|
||||
$this->assertSame('test.bitpay.com', $this->request->getHost());
|
||||
}
|
||||
|
||||
public function testGetPath()
|
||||
@ -100,6 +122,26 @@ class RequestTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertSame('api/invoice', $this->request->getPath());
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testSetHost
|
||||
* @depends testGetPath
|
||||
*/
|
||||
public function testGetUri()
|
||||
{
|
||||
$this->request->setHost('test.bitpay.com');
|
||||
$this->assertSame('https://test.bitpay.com/', $this->request->getUri());
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testSetHost
|
||||
* @depends testGetPath
|
||||
*/
|
||||
public function testGetUriWithPort()
|
||||
{
|
||||
$this->request->setHost('test.bitpay.com');
|
||||
$this->assertSame('https://test.bitpay.com:443/', $this->request->getUriWithPort());
|
||||
}
|
||||
|
||||
public function testGetHeaders()
|
||||
{
|
||||
$this->assertInternalType('array', $this->request->getHeaders());
|
||||
@ -140,15 +182,15 @@ class RequestTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
/**
|
||||
* @depends testGetMethod
|
||||
* @depends testSetUri
|
||||
* @depends testGetUri
|
||||
* @depends testGetHeaders
|
||||
* @depends testGetBody
|
||||
*/
|
||||
public function testToStringWithoutBody()
|
||||
{
|
||||
$this->request->setUri('https://btcpay.server:443');
|
||||
$this->request->setHost('test.bitpay.com');
|
||||
$raw = array(
|
||||
'POST https://btcpay.server:443/ HTTP/1.1',
|
||||
'POST https://test.bitpay.com:443/ HTTP/1.1',
|
||||
'Content-Type: application/json',
|
||||
);
|
||||
$raw = implode("\r\n", $raw);
|
||||
@ -157,16 +199,16 @@ class RequestTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
/**
|
||||
* @depends testGetMethod
|
||||
* @depends testSetUri
|
||||
* @depends testGetUri
|
||||
* @depends testGetHeaders
|
||||
* @depends testGetBody
|
||||
*/
|
||||
public function testToStringWithBody()
|
||||
{
|
||||
$this->request->setUri('https://btcpay.server:443');
|
||||
$this->request->setHost('test.bitpay.com');
|
||||
$this->request->setBody('{"json":true}');
|
||||
$raw = array(
|
||||
'POST https://btcpay.server:443/ HTTP/1.1',
|
||||
'POST https://test.bitpay.com:443/ HTTP/1.1',
|
||||
'Content-Type: application/json',
|
||||
'Content-Length: 13',
|
||||
'',
|
||||
|
||||
@ -21,14 +21,15 @@ class ConfigurationTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertArrayHasKey('public_key', $processedConfig);
|
||||
$this->assertArrayHasKey('private_key', $processedConfig);
|
||||
$this->assertArrayHasKey('sin_key', $processedConfig);
|
||||
$this->assertArrayHasKey('network', $processedConfig);
|
||||
$this->assertArrayHasKey('adapter', $processedConfig);
|
||||
$this->assertArrayHasKey('key_storage', $processedConfig);
|
||||
$this->assertArrayHasKey('key_storage_password', $processedConfig);
|
||||
$this->assertCount(6, $processedConfig);
|
||||
$this->assertCount(7, $processedConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Exception
|
||||
* @expectedException Exception
|
||||
*/
|
||||
public function testClassNotFoundKeyStorageConfig()
|
||||
{
|
||||
@ -44,7 +45,7 @@ class ConfigurationTest extends \PHPUnit_Framework_TestCase
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Exception
|
||||
* @expectedException Exception
|
||||
*/
|
||||
public function testClassDoesNotImplementInterfaceKeyStorageConfig()
|
||||
{
|
||||
|
||||
70
tests/Bitpay/Crypto/McryptExtensionTest.php
Normal file
70
tests/Bitpay/Crypto/McryptExtensionTest.php
Normal file
@ -0,0 +1,70 @@
|
||||
<?php
|
||||
/**
|
||||
* @license Copyright 2011-2014 BitPay Inc., MIT License
|
||||
* see https://github.com/bitpay/php-bitpay-client/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
namespace Bitpay\Crypto;
|
||||
|
||||
/**
|
||||
* @package Bitauth
|
||||
*/
|
||||
class McryptExtensionTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
|
||||
public function testHasSupport()
|
||||
{
|
||||
$mcrypt = new McryptExtension();
|
||||
$this->assertSame(extension_loaded('mcrypt'), $mcrypt->hasSupport());
|
||||
}
|
||||
|
||||
public function testEncrypt()
|
||||
{
|
||||
|
||||
$mcrypt = new McryptExtension();
|
||||
$key = 'testEncrypt';
|
||||
$data = array(
|
||||
'lsdkjflaslkfslj' => 'kz2DG4D3vkA6bkDbhrvD+Q==',
|
||||
'a340932084093280' => 'gNaNgXFc7ecle8SaAJAJOw==',
|
||||
'*&($*@*%&*$*#*&@(*#*(' => 'cVGF2lnyH6OHLYWHa+8XxHbFzVNK5IYL',
|
||||
'___asdfa234($*(#__' => 'I8OFg5parn9b0Qk8mJnQH0+SgQWwYER5'
|
||||
);
|
||||
|
||||
foreach($data as $unencrypted => $encrypted )
|
||||
{
|
||||
$encryptedtext = $mcrypt->encrypt($unencrypted, $key, '00000000');
|
||||
$this->assertEquals($encrypted, $encryptedtext);
|
||||
}
|
||||
}
|
||||
|
||||
public function testDecrypt()
|
||||
{
|
||||
|
||||
$mcrypt = new McryptExtension();
|
||||
$key = 'testEncrypt';
|
||||
$data = array(
|
||||
'lsdkjflaslkfslj' => 'kz2DG4D3vkA6bkDbhrvD+Q==',
|
||||
'a340932084093280' => 'gNaNgXFc7ecle8SaAJAJOw==',
|
||||
'*&($*@*%&*$*#*&@(*#*(' => 'cVGF2lnyH6OHLYWHa+8XxHbFzVNK5IYL',
|
||||
'___asdfa234($*(#__' => 'I8OFg5parn9b0Qk8mJnQH0+SgQWwYER5'
|
||||
);
|
||||
|
||||
foreach($data as $unencrypted => $encrypted )
|
||||
{
|
||||
$plaintext = $mcrypt->decrypt($encrypted, $key, '00000000');
|
||||
$this->assertEquals($unencrypted, $plaintext);
|
||||
}
|
||||
}
|
||||
|
||||
private function generateRandomString($length = 10)
|
||||
{
|
||||
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||
$randomString = '';
|
||||
for ($i = 0; $i < $length; $i++) {
|
||||
$randomString .= $characters[rand(0, strlen($characters) - 1)];
|
||||
}
|
||||
|
||||
return $randomString;
|
||||
}
|
||||
|
||||
}
|
||||
@ -181,7 +181,7 @@ class InvoiceTest extends \PHPUnit_Framework_TestCase
|
||||
public function testIsFullNotifications()
|
||||
{
|
||||
$this->assertNotNull($this->invoice);
|
||||
$this->assertTrue($this->invoice->isFullNotifications());
|
||||
$this->assertFalse($this->invoice->isFullNotifications());
|
||||
}
|
||||
|
||||
public function testGetId()
|
||||
@ -244,7 +244,7 @@ class InvoiceTest extends \PHPUnit_Framework_TestCase
|
||||
public function testSetInvoiceTime()
|
||||
{
|
||||
$this->assertNotNull($this->invoice);
|
||||
$date = new \DateTime('now', new \DateTimeZone("UTC"));
|
||||
$date = new \DateTime();
|
||||
$this->invoice->setInvoiceTime($date);
|
||||
$this->assertSame($date, $this->invoice->getInvoiceTime());
|
||||
}
|
||||
@ -262,7 +262,7 @@ class InvoiceTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
$this->assertNotNull($this->invoice);
|
||||
|
||||
$date = new \DateTime('now',new \DateTimeZone("UTC"));
|
||||
$date = new \DateTime();
|
||||
|
||||
$this->assertNotNull($date);
|
||||
|
||||
@ -283,7 +283,7 @@ class InvoiceTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
$this->assertNotNull($this->invoice);
|
||||
|
||||
$date = new \DateTime('now',new \DateTimeZone("UTC"));
|
||||
$date = new \DateTime();
|
||||
|
||||
$this->assertNotNull($date);
|
||||
|
||||
@ -523,9 +523,9 @@ class InvoiceTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
public function testSetFullNotifications()
|
||||
{
|
||||
$this->assertTrue($this->invoice->isFullNotifications());
|
||||
$this->invoice->setFullNotifications(false);
|
||||
$this->assertFalse($this->invoice->isFullNotifications());
|
||||
$this->invoice->setFullNotifications(true);
|
||||
$this->assertTrue($this->invoice->isFullNotifications());
|
||||
}
|
||||
|
||||
private function getMockItem()
|
||||
|
||||
@ -83,6 +83,9 @@ class ItemTest extends \PHPUnit_Framework_TestCase
|
||||
// throw an error
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Bitpay\Client\ArgumentException
|
||||
*/
|
||||
public function testBadStringPrice()
|
||||
{
|
||||
// Accepts standard integer string
|
||||
@ -138,6 +141,21 @@ class ItemTest extends \PHPUnit_Framework_TestCase
|
||||
setlocale(LC_NUMERIC, 'en_US');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Bitpay\Client\ArgumentException
|
||||
*/
|
||||
public function testSetPriceExceptionNoNumber()
|
||||
{
|
||||
$this->item->setPrice(".");
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Bitpay\Client\ArgumentException
|
||||
*/
|
||||
public function testSetPriceExceptionDoubleDecimal()
|
||||
{
|
||||
$this->item->setPrice("6..5");
|
||||
}
|
||||
|
||||
public function testGetQuantity()
|
||||
{
|
||||
|
||||
@ -17,7 +17,11 @@ class BcEngineTest extends \PHPUnit_Framework_TestCase
|
||||
if (!extension_loaded('bcmath'))
|
||||
{
|
||||
$this->markTestSkipped('The Bcmath extension is NOT loaded! You must enable it to run this test');
|
||||
} elseif (!extension_loaded('gmp'))
|
||||
{
|
||||
$this->markTestSkipped('The GMPmath extension is NOT loaded! You must enable it to run this test');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function testConstruct()
|
||||
@ -33,11 +37,9 @@ class BcEngineTest extends \PHPUnit_Framework_TestCase
|
||||
$b = '1234123412341234123412341234123412412341234213412421341342342';
|
||||
$c = '0x1234123412341234123412341234123412412341234213412421341342342';
|
||||
$math = new BcEngine();
|
||||
$this->assertEquals('2468', $math->add($a, $a));
|
||||
$this->assertEquals('2468246824682468246824682468246824824682468426824842682684684',
|
||||
$math->add($b, $b));
|
||||
$this->assertEquals('4020328592351456034599241982311497811554079037632048678982517743814198916',
|
||||
$math->add($c, $c));
|
||||
$this->assertEquals(gmp_strval(gmp_add($a, $a)), $math->add($a, $a));
|
||||
$this->assertEquals(gmp_strval(gmp_add($b, $b)), $math->add($b, $b));
|
||||
$this->assertEquals(gmp_strval(gmp_add($c, $c)), $math->add($c, $c));
|
||||
$this->assertEquals(2, $math->add(1, 1));
|
||||
}
|
||||
|
||||
@ -47,10 +49,9 @@ class BcEngineTest extends \PHPUnit_Framework_TestCase
|
||||
$b = '1234123412341234123412341234123412412341234213412421341342342';
|
||||
$c = '0x1234123412341234123412341234123412412341234213412421341342342';
|
||||
$math = new BcEngine();
|
||||
$this->assertEquals('0', $math->cmp($a, $a));
|
||||
$this->assertEquals('1', $math->cmp($b, $a));
|
||||
$this->assertEquals('-1', $math->cmp($a, $b));
|
||||
$this->assertEquals('0', $math->cmp($c, $c));
|
||||
$this->assertEquals(gmp_strval(gmp_cmp($a, $a)), $math->cmp($a, $a));
|
||||
$this->assertEquals(gmp_strval(gmp_cmp($b, $b)), $math->cmp($b, $b));
|
||||
$this->assertEquals(gmp_strval(gmp_cmp($c, $c)), $math->cmp($c, $c));
|
||||
$this->assertEquals(0, $math->cmp(1, 1));
|
||||
}
|
||||
|
||||
@ -59,14 +60,10 @@ class BcEngineTest extends \PHPUnit_Framework_TestCase
|
||||
$a = 1234;
|
||||
$b = '1234123412341234123412341234123412412341234213412421341342342';
|
||||
$c = '0x1234123412341234123412341234123412412341234213412421341342342';
|
||||
$d = 256;
|
||||
$math = new BcEngine();
|
||||
$this->assertEquals('4', $math->div($a, $d));
|
||||
$this->assertEquals('4820794579457945794579457945794579735707946146142270864618', $math->div($b, $d));
|
||||
$this->assertEquals('1', $math->div($c, $c));
|
||||
$this->assertEquals('7852204281936437567576644496702144163191560620375095076137729968387107',
|
||||
$math->div($c, $d));
|
||||
|
||||
$this->assertEquals(gmp_strval(gmp_div($a, $a)), $math->div($a, $a));
|
||||
$this->assertEquals(gmp_strval(gmp_div($b, $b)), $math->div($b, $b));
|
||||
$this->assertEquals(gmp_strval(gmp_div($c, $c)), $math->div($c, $c));
|
||||
$this->assertEquals(1, $math->div(1, 1));
|
||||
}
|
||||
|
||||
@ -79,12 +76,12 @@ class BcEngineTest extends \PHPUnit_Framework_TestCase
|
||||
$c = '0x1234123412341234123412341234123412412341234213412421341342342';
|
||||
|
||||
|
||||
$this->assertEquals(0, $math->invertm($a, $a));
|
||||
$this->assertEquals(0, $math->invertm($b, $b));
|
||||
$this->assertEquals(0, $math->invertm($c, $c));
|
||||
$this->assertEquals(gmp_strval(gmp_invert($a, $a)), $math->invertm($a, $a));
|
||||
$this->assertEquals(gmp_strval(gmp_invert($b, $b)), $math->invertm($b, $b));
|
||||
$this->assertEquals(gmp_strval(gmp_invert($c, $c)), $math->invertm($c, $c));
|
||||
|
||||
$this->assertEquals('1', $math->invertm(15, 14));
|
||||
$this->assertEquals(0, $math->invertm(-1, 1));
|
||||
$this->assertEquals(gmp_strval(gmp_invert(15, 14)), $math->invertm(15, 14));
|
||||
$this->assertEquals(gmp_strval(gmp_invert(-1, 1)), $math->invertm(-1, 1));
|
||||
$this->assertEquals(0, $math->invertm(1, 1));
|
||||
|
||||
$o = '2';
|
||||
@ -102,10 +99,10 @@ class BcEngineTest extends \PHPUnit_Framework_TestCase
|
||||
$b = '-1675975991242824637446753124775730765934920727574049172215445180465096172921808707643480960976619010162856846742450225672776411590632518780962349126898196';
|
||||
$c = '115792089237316195423570985008687907853269984665640564039457584007908834671663';
|
||||
$math = new BcEngine();
|
||||
$this->assertEquals(0, $math->mod($a, $a));
|
||||
$this->assertEquals('1234', $math->mod($a, $b));
|
||||
$this->assertEquals('14474011154664524427946373126085988481658748083205070504932198000988604333958'
|
||||
, $math->mod($b, $c));
|
||||
$gmp = new GmpEngine();
|
||||
$this->assertEquals($gmp->mod($a, $a), $math->mod($a, $a));
|
||||
$this->assertEquals($gmp->mod($a, $b), $math->mod($a, $b));
|
||||
$this->assertEquals($gmp->mod($b, $c), $math->mod($b, $c));
|
||||
|
||||
}
|
||||
|
||||
@ -115,11 +112,9 @@ class BcEngineTest extends \PHPUnit_Framework_TestCase
|
||||
$b = '1234123412341234123412341234123412412341234213412421341342342';
|
||||
$c = '0x1234123412341234123412341234123412412341234213412421341342342';
|
||||
$math = new BcEngine();
|
||||
$this->assertEquals(1522756, $math->mul($a, $a));
|
||||
$this->assertEquals('1523060596888771785469376020510342038779135661438916853827453718463560582690945158853917400742616234688308574558442044964',
|
||||
$math->mul($b, $b));
|
||||
$this->assertEquals('4040760497619659988396017237570892345412667279675376001385393199805230792128304954488986267360185801341164900937850776470852477066413262703893764',
|
||||
$math->mul($c, $c));
|
||||
$this->assertEquals(gmp_strval(gmp_mul($a, $a)), $math->mul($a, $a));
|
||||
$this->assertEquals(gmp_strval(gmp_mul($b, $b)), $math->mul($b, $b));
|
||||
$this->assertEquals(gmp_strval(gmp_mul($c, $c)), $math->mul($c, $c));
|
||||
$this->assertEquals(1, $math->mul(1, 1));
|
||||
}
|
||||
|
||||
@ -128,11 +123,10 @@ class BcEngineTest extends \PHPUnit_Framework_TestCase
|
||||
$a = 1234;
|
||||
$b = '1234';
|
||||
$c = '0x4D2';
|
||||
$pow = '20';
|
||||
$math = new BcEngine();
|
||||
$this->assertEquals('67035243914691711794360082394262505332216263021359359696306176', $math->pow($a, $pow));
|
||||
$this->assertEquals('67035243914691711794360082394262505332216263021359359696306176', $math->pow($b, $pow));
|
||||
$this->assertEquals('67035243914691711794360082394262505332216263021359359696306176', $math->pow($c, $pow));
|
||||
$this->assertEquals(gmp_strval(gmp_pow($a, $a)), $math->pow($a, $a));
|
||||
$this->assertEquals(gmp_strval(gmp_pow($b, $b)), $math->pow($b, $b));
|
||||
$this->assertEquals(gmp_strval(gmp_pow($c, $c)), $math->pow($c, $c));
|
||||
$this->assertEquals(1, $math->pow(1, 1));
|
||||
}
|
||||
|
||||
@ -142,11 +136,9 @@ class BcEngineTest extends \PHPUnit_Framework_TestCase
|
||||
$b = '1234123412341234123412341234123412412341234213412421341342342';
|
||||
$c = '0x1234123412341234123412341234123412412341234213412421341342342';
|
||||
$math = new BcEngine();
|
||||
$this->assertEquals(0, $math->sub($a, $a));
|
||||
$this->assertEquals('1234123412341234123412341234123412412341234213412421341341108',
|
||||
$math->sub($b, $a));
|
||||
$this->assertEquals('2010164296174493893887279757032336564542916106403683105277846450565757116',
|
||||
$math->sub($c, $b));
|
||||
$this->assertEquals(gmp_strval(gmp_sub($a, $a)), $math->sub($a, $a));
|
||||
$this->assertEquals(gmp_strval(gmp_sub($b, $b)), $math->sub($b, $b));
|
||||
$this->assertEquals(gmp_strval(gmp_sub($c, $c)), $math->sub($c, $c));
|
||||
$this->assertEquals(0, $math->sub(1, 1));
|
||||
}
|
||||
|
||||
|
||||
30
tests/Bitpay/Network/LivenetTest.php
Normal file
30
tests/Bitpay/Network/LivenetTest.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
/**
|
||||
* @license Copyright 2011-2014 BitPay Inc., MIT License
|
||||
* see https://github.com/bitpay/php-bitpay-client/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
namespace Bitpay\Network;
|
||||
|
||||
class LivenetTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function setUp()
|
||||
{
|
||||
$this->network = new Livenet();
|
||||
}
|
||||
|
||||
public function testGetName()
|
||||
{
|
||||
$this->assertSame('livenet', $this->network->getName());
|
||||
}
|
||||
|
||||
public function testGetAddressVersion()
|
||||
{
|
||||
$this->assertSame(0x00, $this->network->getAddressVersion());
|
||||
}
|
||||
|
||||
public function testGetApiHost()
|
||||
{
|
||||
$this->assertSame('bitpay.com', $this->network->getApiHost());
|
||||
}
|
||||
}
|
||||
23
tests/Bitpay/Network/NetworkAwareTest.php
Normal file
23
tests/Bitpay/Network/NetworkAwareTest.php
Normal file
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
/**
|
||||
* @license Copyright 2011-2014 BitPay Inc., MIT License
|
||||
* see https://github.com/bitpay/php-bitpay-client/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
namespace Bitpay\Network;
|
||||
|
||||
class NetworkAwareTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testSetNetwork()
|
||||
{
|
||||
$networkAware = $this->getMockForAbstractClass('Bitpay\Network\NetworkAware');
|
||||
$networkAware->setNetwork(new \Bitpay\Network\Testnet());
|
||||
|
||||
$r = new \ReflectionObject($networkAware);
|
||||
$network = $r->getProperty('network');
|
||||
$network->setAccessible(true);
|
||||
$network = $network->getValue($networkAware);
|
||||
|
||||
$this->assertInstanceOf('Bitpay\Network\NetworkInterface', $network);
|
||||
}
|
||||
}
|
||||
30
tests/Bitpay/Network/TestnetTest.php
Normal file
30
tests/Bitpay/Network/TestnetTest.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
/**
|
||||
* @license Copyright 2011-2014 BitPay Inc., MIT License
|
||||
* see https://github.com/bitpay/php-bitpay-client/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
namespace Bitpay\Network;
|
||||
|
||||
class TestnetTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function setUp()
|
||||
{
|
||||
$this->network = new Testnet();
|
||||
}
|
||||
|
||||
public function testGetName()
|
||||
{
|
||||
$this->assertSame('testnet', $this->network->getName());
|
||||
}
|
||||
|
||||
public function testGetAddressVersion()
|
||||
{
|
||||
$this->assertSame(0x6f, $this->network->getAddressVersion());
|
||||
}
|
||||
|
||||
public function testGetApiHost()
|
||||
{
|
||||
$this->assertSame('test.bitpay.com', $this->network->getApiHost());
|
||||
}
|
||||
}
|
||||
@ -17,34 +17,21 @@ class EncryptedFilesystemStorageTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
public function testPersist()
|
||||
{
|
||||
$storage = new EncryptedFilesystemStorage('dN$8WNaT}j<gD3*q');
|
||||
$storage = new EncryptedFilesystemStorage('satoshi');
|
||||
$storage->persist(new \Bitpay\PublicKey(vfsStream::url('tmp/public.key')));
|
||||
$this->assertTrue($this->root->hasChild('tmp/public.key'));
|
||||
}
|
||||
|
||||
public function testUnencodedLoad()
|
||||
{
|
||||
$storage = new EncryptedFilesystemStorage('dN$8WNaT}j<gD3*q');
|
||||
|
||||
vfsStream::newFile('public.key')
|
||||
->at($this->root)
|
||||
->setContent('97f394f4153a75ad7da3d9b8844cf0593c5abbea78695ba41c8528bc7bcd158cdc73a93ba2826d4a9ef1b3552f0f754a2db43010488ebea5648c7d897749df8d27d761683de7c17d225d2464413c89cc5ddc6d0a1b522b0efbeb47cc247a9ecb8d4e5a8790a2eb82cf1a9b6a727b90e3de444f2245b3c6aae7a1f12f3727ad926935f6540a49fd7e7e633b613ee1a196ed56b8c19d2c9353a4d9ee1f94f6a39f0a5bcf6729ea9677e9d9d590e53cdf25e04e2b00ee31f2489b7ae42cb0666dd002b536a95224f11ca0a9dc771b3eaf230b2f2bad72e13837308a58e0acfc03d2ac53522dad3231e754c647c75282bc9882f4b9d4ab712cb901f6d4d03c346df444c4e2a2a2114fd22a3c396c2a0e8ddf6838fa3fc54ea72b5095807c3a6f402cfd7ad15da7b45630bb31ed4c7e95bdfdff477c6b9c0e48fe678266d6b15505eeb2a0e8ff60b400af3f376fd261619fa9c1233efbb75ace29f9dfbc6360f9e4ac7d53e1bf112fa2ab8740f53dd40318da0e7360cb40cbcc15fe3c589bf34fdf7b981800b50d666b2e795438ce22b2640b4d55b98fa08aa37e18d6581e198d5c960574b07ab7daaf89b9e361719d85040a0c1e53b51f96f3119b27f922ab1ae7989bc8d686860f8c2d7201fe427a401be9dba0fd19ced8124d99b1475f75f007bf8cf213065c52544b3dffc126b05c5c3b2965ffacd4a16a395f11341a0149023b9b6df3326a6161cdb28d2e71690560a2');
|
||||
|
||||
$key = $storage->load(vfsStream::url('tmp/public.key'));
|
||||
$this->assertInstanceOf('Bitpay\PublicKey', $key);
|
||||
}
|
||||
|
||||
public function testLoad()
|
||||
{
|
||||
$storage = new EncryptedFilesystemStorage('dN$8WNaT}j<gD3*q');
|
||||
$storage = new EncryptedFilesystemStorage('satoshi');
|
||||
|
||||
vfsStream::newFile('public.key')
|
||||
->at($this->root)
|
||||
->setContent('222464cf5e76807259205ed98a1114e3164ecada597352259f9e09ce06524cdf7eaf862bff208d44163b8b24719afbfe031344d97a44502955b63158e012c09f604f66f3c7ca99290e9991a4a1413c3a4095fb6522653ceda25d831d115be3de6756fd7511ed91d970dac0e4e01a5df91ce9b412a0c8a42eb266cf2a93e1d1b50090b3eb89c93fcd85ed2cee6ee08499a6d69c3ffe7836878e30a37df92226fc78a2936f6037d8bf4b0a33bb11dad77b544a1baaf1c097be38d04f6b642285811b9c9e27c51d460a57e298851bb047f6fa2a02f501e7902a660fa66630240cf8586f6cf774b6b0a6e62a06de6eee328b3dfaa3658fd692b0e7590ea58281c8a563e3fe09a1209de96c7919a3b92c5307b782b4729a68b08f220b03df02c15e7742977a48b48c4bff7d060020e3b4717d5ae05d630e9e5f1374d2bb9ac04652ee12ef9de37c67cd07461ae7a201ddd04975ec4f60e781e214b50ca1b756988b7a1868fdbf2b07db66e0e7c9a29526c7d11127bb58c606c515325d7375a21c9d1db63167fb34106c87c49d238fc1eb41309eb5f23d946743534bf8d454729dd94ac9c3d18cb7261fd773c913e674a4427c0b90b4f9a541b77363d43f957445fff395ad5c48b51131913917882413ce8084db0d20ab308b3504d43e8f67afb4f6611324d07d8980ffc8d9ae6817bfe1be5e4f5ad6e5155b9767d15c01c96fc101538071f9bef40978f805e52e31a8e169bf');
|
||||
->setContent('8bc03b8e4272d47ea81d63c6571b8172072ed03203ff7cd3fd434c03f7994b5721363d0dda3cec833f6f263bde0ececa06b79f68d5616be18b8e9311c486223e18c7424daaa59991f4b10db9f2fb8b4c42896c50d216010b403d562738ef5a96');
|
||||
|
||||
$key = $storage->load(vfsStream::url('tmp/public.key'));
|
||||
$this->assertInstanceOf('Bitpay\PublicKey', $key);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -94,5 +81,4 @@ class EncryptedFilesystemStorageTest extends \PHPUnit_Framework_TestCase
|
||||
$key = $storage->load(vfsStream::url('tmp/public.key'));
|
||||
$this->assertInstanceOf('Bitpay\PublicKey', $key);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -273,6 +273,13 @@ class UtilTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertTrue(is_string($requirements['PHP']));
|
||||
}
|
||||
|
||||
// Mcrypt Extension
|
||||
if (extension_loaded('mcrypt')) {
|
||||
$this->assertTrue($requirements['Mcrypt']);
|
||||
} else {
|
||||
$this->assertTrue(is_string($requirements['Mcrypt']));
|
||||
}
|
||||
|
||||
// OpenSSL Extension
|
||||
if (extension_loaded('openssl')) {
|
||||
$this->assertTrue($requirements['OpenSSL']);
|
||||
|
||||
@ -14,7 +14,6 @@
|
||||
"btcPrice":"0.0632",
|
||||
"btcDue":"0.0632",
|
||||
"price":19.95,
|
||||
"taxIncluded": 0.0,
|
||||
"currency":"USD",
|
||||
"exRates":
|
||||
{
|
||||
|
||||
@ -1 +1 @@
|
||||
{"facade":"public/invoice","data":{"url":"https://test.bitpay.com/invoice?id=5NxFkXcJbCSivtQRJa4kHP","posData":"{\"posData\":{\"orderId\":\"100000009\"},\"hash\":\"GA.VW7o8puqPA\"}","status":"expired","btcPrice":"0.0032","btcDue":"0.0032","price":1.99,"taxIncluded":0.0,"currency":"USD","exRates":{"USD":619.39},"orderId":"100000009","invoiceTime":1405974404088,"expirationTime":1405975304088,"currentTime":1412886370907,"id":"5NxFkXcJbCSivtQRJa4kHP","btcPaid":"0.0000","rate":619.39,"exceptionStatus":false,"token":"9CKEkTYE4VA4skhMPBxUsPQyUqXE36qpmitmYbtKssPnY3p8rYqhTTcEzUeowKwvzL"}}
|
||||
{"facade":"public/invoice","data":{"url":"https://test.bitpay.com/invoice?id=5NxFkXcJbCSivtQRJa4kHP","posData":"{\"posData\":{\"orderId\":\"100000009\"},\"hash\":\"GA.VW7o8puqPA\"}","status":"expired","btcPrice":"0.0032","btcDue":"0.0032","price":1.99,"currency":"USD","exRates":{"USD":619.39},"orderId":"100000009","invoiceTime":1405974404088,"expirationTime":1405975304088,"currentTime":1412886370907,"id":"5NxFkXcJbCSivtQRJa4kHP","btcPaid":"0.0000","rate":619.39,"exceptionStatus":false,"token":"9CKEkTYE4VA4skhMPBxUsPQyUqXE36qpmitmYbtKssPnY3p8rYqhTTcEzUeowKwvzL"}}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user