fjffk简单的咖啡店科开发2方法2
环滁皆山也。其西南诸峰,林壑尤美,望之蔚然而深秀者,琅琊也。山行六七里,渐闻水声潺潺,而泻出于两峰之间者,酿泉也
???????????????????????????????
??????????????/?????????????????
............/...................
.........................../...
???????????????????????????????
>>>>>>>>>>>>>/>>>>>>>>>>>>>>>>>
ÿØÿà JFIF ÿÛ „ ( %!1!%)+//.383,7(-.+
-%%-////---/-.+/--+------/------/--0+--/-/-----.-----ÿÀ ¥2" ÿÄ ÿÄ J ! 1AQ"aq2‘#BR‚¡ÁÑ3br’¢±Âð$CSƒ²á4c“%DsÓñÿÄ ÿÄ * !1AQa‘"2q3±ð#b¡ÿÚ ? ¼QxJQaÍuò¸Zö Úü8,ÐÚú
"SSn<rçù–´âE—^ªBÖ9À\†¸ÔÁTÃÛ5
ëd´³Í#Ý;Þ38œî ¶H£M:wÎ3…³…âpÔF&‚FK¸9„â4àGEõªfÿ ‘ñ(ßwpŽF|È¥ù®häðÍѶ¹‘[ÒinÙW¶ùñY˜Q{›K"išÒ[Ú8žë\F¹@-?v"ÔU”,ìöžkÿ {I‡£šÍ?e
ríV
?>
.........................................
.............................................................................
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
>>>>>>>>>>>>>/>>>>>>>>>>>>>>>>>>
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
ppphp-client/package.json 0000755 00000001566 15250364036 0011114 0 ustar 00 {
"name": "php-bitpay-client",
"description": "PHP Client Library for the BitPay Bitcoin Payment Gateway",
"directories": {
"lib": "src",
"doc": "docs",
"example": "examples",
"test": "tests"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "https://github.com/bitpay/php-bitpay-client.git"
},
"keywords": [
"bitpay",
"bitcoin",
"php",
"library",
"payment",
"gateway",
"ecommerce",
"merchant",
"money"
],
"author": "BitPay Integrations Development Team",
"license": "MIT",
"bugs": {
"url": "https://github.com/bitpay/php-bitpay-client/issues"
},
"homepage": "https://github.com/bitpay/php-bitpay-client",
"engines": {
"node": ">=0.10.33",
"npm": "~2.1.5"
},
"devDependencies": {
"phantomjs": "^1.9.12"
}
}
php-client/build.xml 0000755 00000002317 15250364036 0010442 0 ustar 00
php-client/VERSION 0000755 00000000011 15250364036 0007656 0 ustar 00 3.0.0-p1
php-client/CHANGELOG.md 0000755 00000006516 15250364036 0010437 0 ustar 00 # Change Log
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).
## [Unreleased][unreleased]
## [3.0.0] - 2016-03-10
###Fixed
- should respect that numbers coming from the api might not have decimal points at all, but they are still valid
- Bug fixes that include proper type checking for invoice object creation
- Fixed invoice, expiration, and current time error
- Repaired tests based on current changes to the code.
###Added
- Using this library with Symfony >=2.3 or Symfony 3.0.x should work. So if you are already using Symfony 3.0, then this library should work with it too.
- Leo Hochberg added PaymentUrl support to the library since the BitPay backend support it. Thanks Leo.
## [2.2.7] - 2015-10-28
###Fixed
- btcPaid on invoice responses now contains the amount paid instead of the price
## [2.2.6] - 2015-07-31
###Fixed
- The fixes several issues, including "Price only accepts .00 precision" and "Invoice exception state"
### Changed
- Refactored function calls out of loops
## [2.2.5] - 2015-06-23
### Fixed
- Item::setPrice accepts en_US formatted numeric strings
- getInvoice now works with merchant and public facades
## [2.2.4] - 2015-06-04
### Added
- Token functionality for client-sided pairing
- Set payout bitcoin amount, as returned by BitPay
- Utility method for checking requirements
- Autoloader documentation
### Changed
- Documentation from RST to Markdown
- Autoloader now loads relative to library root directory
- Client now sets invoice tokens upon creation and retrieval
## [2.2.3] - 2015-05-29
### Fixed
- BitPay API errors are now passthrough
## [2.2.2] - 2015-01-13
### Added
- Mink/Behat testing
### Fixed
- Corrected behavior of Math::mod
## [2.2.1] - 2014-12-10
### Added
- Payroll feature
- Detailed tutorials
### Fixed
- Math Engine issues
- Stalling tests
## [2.2.0] - 2014-11-21
### Changed
- No longer solely depends on GMP for big integer math. Can now use BCMath as well
## [2.1.1] - 2014-11-19
### Changed
- Encrypted file storage is now default persistance for keys
### Fixed
- McryptExtensionTest no longer fails randomly
### Removed
- PHP 5.3 support. Now requires PHP >= 5.4
## [2.1.0] - 2014-11-10
### Added
- Code Coverage tools
- Integration testing
- CA Bundle for Curl Adapter
- Additional invoice tests
- PEM Encoding and Decoding
- Storage Class tutorial
- `fullNotifications` for invoices
### Changed
- Point arrays to objects
- Better exception handling for Curl errors
- Refactored `isGenerated`
### Fixed
- MCrypt cipher type default is now a valid cipher type
## 2.0.0 - 2014-09-27
### Changed
- Client library now uses BitPay's new API
[unreleased]: https://github.com/bitpay/php-bitpay-client/compare/v2.2.5...HEAD
[2.2.5]: https://github.com/bitpay/php-bitpay-client/compare/v2.2.4...v2.2.5
[2.2.4]: https://github.com/bitpay/php-bitpay-client/compare/v2.2.3...v2.2.4
[2.2.3]: https://github.com/bitpay/php-bitpay-client/compare/v2.2.2...v2.2.3
[2.2.2]: https://github.com/bitpay/php-bitpay-client/compare/v2.2.1...v2.2.2
[2.2.1]: https://github.com/bitpay/php-bitpay-client/compare/v2.2.0...v2.2.1
[2.2.0]: https://github.com/bitpay/php-bitpay-client/compare/v2.1.1...v2.2.0
[2.1.1]: https://github.com/bitpay/php-bitpay-client/compare/v2.1.0...v2.1.1
[2.1.0]: https://github.com/bitpay/php-bitpay-client/compare/v2.0.0...v2.1.0
php-client/integration_tests.sh 0000755 00000004046 15250364036 0012723 0 ustar 00 #!/usr/bin/env bash
set_variables ()
{
while true
do
read -p "Input Email: " EMAIL
regex="^[a-z0-9!#\$%&'*+/=?^_\`{|}~-]+(\.[a-z0-9!#$%&'*+/=?^_\`{|}~-]+)*@([a-z0-9]([a-z0-9-]*[a-z0-9])?\.)+[a-z0-9]([a-z0-9-]*[a-z0-9])?\$";
if [[ "$EMAIL" =~ $regex ]]
then
export BITPAY_EMAIL=$EMAIL
break
else
echo "Please input a valid email"
fi
done
while true
do
read -p "Input Password: " PASSWORD
read -p "Password Confirmation: " PASSWORD2
if [ "$PASSWORD" = "$PASSWORD2" ]
then
break
else
echo "Please input a valid password"
fi
done
while true
do
read -p "Input URL: " URL
if [ -z $URL ]
then
echo "Please input a valid URL"
else
break
fi
done
}
if [ -z "$1" ]
then
echo "No parameters passed so using Environment Variables"
if [ -z "$BITPAY_EMAIL" ] || [ -z "$BITPAY_PASSWORD"]
then
echo "ERROR: No Email or password are set."
echo "set BITPAY_EMAIL and BITPAY_PASSWORD as environment variables"
echo "or pass them as arguments when running this script"
while true; do
read -p "Do you wish to set your environment variables here? " yn
case $yn in
[Yy]* ) set_variables; break;;
[Nn]* ) echo "Closing script"; exit;;
* ) echo "Please answer yes or no.";;
esac
done
else
echo "Environment Variables already exist for BITPAY."
fi
else
echo "Username $1 and Password $2 passed from command line"
URL=$1
EMAIL=$2
PASSWORD=$3
echo "Setting user and Password to new environment variables..."
fi
export BITPAY_EMAIL=$EMAIL
export BITPAY_PASSWORD=$PASSWORD
export BITPAY_URL=$URL
echo "Using Email: $EMAIL"
echo "Using URL: $URL"
echo "Removing old keys..."
if [ -e /tmp/bitpay.pub ]
then
rm -rf /tmp/bitpay.pub
rm -rf /tmp/bitpay.pri
rm -rf /tmp/token.json
fi
echo "Checking if Selenium exists..."
if [ ! -f selenium-server-standalone-2.44.0.jar ]
then
echo "Downloading Selenium"
curl -O http://selenium-release.storage.googleapis.com/2.44/selenium-server-standalone-2.44.0.jar
fi
echo "Running Selenium and the tests"
php bin/behat tests/integrations php-client/behat.yml 0000755 00000001156 15250364036 0010427 0 ustar 00 # behat.yml
default:
context:
parameters:
user:
password:
base_url:
driver: 'selenium2'
paths:
features: tests/integrations
bootstrap: %behat.paths.features%/bootstrap
extensions:
Behat\MinkExtension\Extension:
goutte: ~
selenium2: ~
phantomjs:
context:
parameters:
user:
password:
base_url:
driver: 'phantomjs'
paths:
features: tests/integrations
bootstrap: %behat.paths.features%/bootstrap
extensions:
Behat\MinkExtension\Extension:
goutte: ~
selenium2:
wd_host: "http://localhost:8643/wd/hub"
php-client/src/Bitpay/Util/Util.php 0000755 00000031063 15250364036 0013203 0 ustar 00 0) {
$q = Math::div($dec, '16');
$rem = Math::mod($dec, '16');
$dec = $q;
$hex = substr(self::HEX_CHARS, intval($rem), 1) . $hex;
}
return $hex;
}
/**
* Decodes a hexadecimal value into decimal.
*
* @param string $hex
* @return string
* @throws \Exception
*/
public static function decodeHex($hex)
{
if (!is_string($hex) || !ctype_xdigit($hex) && '0x' != substr($hex, 0, 2)) {
throw new \Exception('Argument must be a string of hex digits.');
}
$hex = strtolower(trim($hex));
// if it has a prefix of 0x this needs to be trimed
if (substr($hex, 0, 2) == '0x') {
$hex = substr($hex, 2);
}
$hexLen = strlen($hex);
for ($dec = '0', $i = 0; $i < $hexLen; $i++) {
$current = strpos(self::HEX_CHARS, $hex[$i]);
$dec = Math::add(Math::mul($dec, '16'), $current);
}
return $dec;
}
/**
* Calculates a new EC curve point.
*
* @param string $hex
* @param PointInterface $point
* @param CurveParameterInterface $parameters
* @return Point
*/
public static function doubleAndAdd($hex, PointInterface $point, CurveParameterInterface $parameters = null)
{
if (null === $parameters) {
$parameters = new Secp256k1();
}
$tmp = self::decToBin($hex);
$n = strlen($tmp) - 1;
$S = new Point(PointInterface::INFINITY, PointInterface::INFINITY);
while ($n >= 0) {
$S = self::pointDouble($S);
if ($tmp[$n] == 1) {
$S = self::pointAdd($S, $point);
}
$n--;
}
return new Point($S->getX(), $S->getY());
}
/**
* This method returns a binary string representation of
* the decimal number. Used for the doubleAndAdd() method.
*
* @see http://php.net/manual/en/function.decbin.php (but for large numbers)
* @param string $dec
* @return string $bin
*/
public static function decToBin($dec)
{
if (substr(strtolower($dec), 0, 2) == '0x') {
$dec = self::decodeHex(substr($dec, 2));
}
$bin = '';
while (Math::cmp($dec, '0') > 0) {
if (Math::mod($dec, '2') == '1') {
$bin .= '1';
} else {
$bin .= '0';
}
$dec = Math::div($dec, '2');
}
return $bin;
}
/**
* Point multiplication method 2P = R where
* s = (3xP2 + a)/(2yP) mod p
* xR = s2 - 2xP mod p
* yR = -yP + s(xP - xR) mod p
*
* @param PointInterface $point
* @param CurveParameterInterface $parameters
* @return PointInterface
* @throws \Exception
*/
public static function pointDouble(PointInterface $point, CurveParameterInterface $parameters = null)
{
if ($point->isInfinity()) {
return $point;
}
if (null === $parameters) {
$parameters = new Secp256k1();
}
$p = $parameters->pHex();
$a = $parameters->aHex();
$s = 0;
$R = array(
'x' => 0,
'y' => 0,
);
// Critical math section
try {
$m = Math::add(Math::mul(3, Math::mul($point->getX(), $point->getX())), $a);
$o = Math::mul('2', $point->getY());
$n = Math::invertm($o, $p);
$n2 = Math::mod($o, $p);
$st = Math::mul($m, $n);
$st2 = Math::mul($m, $n2);
$s = Math::mod($st, $p);
$s2 = Math::mod($st2, $p);
$xmul = Math::mul('2', $point->getX());
$smul = Math::mul($s, $s);
$xsub = Math::sub($smul, $xmul);
$xmod = Math::mod($xsub, $p);
$R['x'] = $xmod;
$ysub = Math::sub($point->getX(), $R['x']);
$ymul = Math::mul($s, $ysub);
$ysub2 = Math::sub('0', $point->getY());
$yadd = Math::add($ysub2, $ymul);
$R['y'] = Math::mod($yadd, $p);
} catch (\Exception $e) {
throw new \Exception('Error in Util::pointDouble(): ' . $e->getMessage());
}
return new Point($R['x'], $R['y']);
}
/**
* Point addition method P + Q = R where:
* s = (yP - yQ)/(xP - xQ) mod p
* xR = s2 - xP - xQ mod p
* yR = -yP + s(xP - xR) mod p
*
* @param PointInterface $P
* @param PointInterface $Q
* @return PointInterface
*/
public static function pointAdd(PointInterface $P, PointInterface $Q)
{
if ($P->isInfinity()) {
return $Q;
}
if ($Q->isInfinity()) {
return $P;
}
if ($P->getX() == $Q->getX() && $P->getY() == $Q->getY()) {
return self::pointDouble(new Point($P->getX(), $P->getY()));
}
$p = '0x' . Secp256k1::P;
$a = '0x' . Secp256k1::A;
$s = 0;
$R = array(
'x' => 0,
'y' => 0,
's' => 0,
);
// Critical math section
try {
$m = Math::sub($P->getY(), $Q->getY());
$n = Math::sub($P->getX(), $Q->getX());
$o = Math::invertm($n, $p);
$st = Math::mul($m, $o);
$s = Math::mod($st, $p);
$R['x'] = Math::mod(
Math::sub(
Math::sub(
Math::mul($s, $s),
$P->getX()
),
$Q->getX()
),
$p
);
$R['y'] = Math::mod(
Math::add(
Math::sub(
'0',
$P->getY()
),
Math::mul(
$s,
Math::sub(
$P->getX(),
$R['x']
)
)
),
$p
);
$R['s'] = $s;
} catch (Exception $e) {
throw new \Exception('Error in Util::pointAdd(): ' . $e->getMessage());
}
return new Point($R['x'], $R['y']);
}
/**
* Converts hex value into octet (byte) string.
*
* @param string $hex
* @return string $byte
*/
public static function binConv($hex)
{
$rem = '';
$dv = '';
$byte = '';
$digits = array();
for ($x = 0; $x < 256; $x++) {
$digits[$x] = chr($x);
}
if (substr(strtolower($hex), 0, 2) != '0x') {
$hex = '0x' . strtolower(trim($hex));
}
while (Math::cmp($hex, '0') > 0) {
$dv = Math::div($hex, '256');
$rem = Math::mod($hex, '256');
$hex = $dv;
$byte = $byte . $digits[$rem];
}
return strrev($byte);
}
/**
* Checks dependencies for the library.
*
* @return array list of each requirement, boolean true if met, string error message if not as value
*/
public static function checkRequirements()
{
$requirements = array();
// PHP Version
if (!defined('PHP_VERSION_ID')) {
$version = explode('.', PHP_VERSION);
define('PHP_VERSION_ID', ($version[0] * 10000 + $version[1] * 100 + $version[2]));
}
if (PHP_VERSION_ID < 50400) {
$requirements['PHP'] = 'Your PHP version, ' . PHP_VERSION . ', is too low. PHP version >= 5.4 is required.';
} else {
$requirements['PHP'] = true;
}
// OpenSSL Extension
if (!extension_loaded('openssl')) {
$requirements['OpenSSL'] = 'The OpenSSL PHP extension could not be found.';
} else {
$requirements['OpenSSL'] = true;
}
// JSON Extension
if (!extension_loaded('json')) {
$requirements['JSON'] = 'The JSON PHP extension could not be found.';
} else {
$requirements['JSON'] = true;
}
// cURL Extension
if (!extension_loaded('curl')) {
$requirements['cURL'] = 'The cURL PHP extension could not be found.';
} else {
$requirements['cURL'] = true;
$curl_version = curl_version();
$ssl_supported = ($curl_version['features'] & CURL_VERSION_SSL);
if (!$ssl_supported) {
$requirements['cURL.SSL'] = 'The cURL PHP extension does not have SSL support.';
} else {
$requirements['cURL.SSL'] = true;
}
}
// Math
if (!extension_loaded('bcmath') && !extension_loaded('gmp')) {
$requirements['Math'] = 'Either the BC Math or GMP PHP extension is required. Neither could be found.';
} else {
$requirements['Math'] = true;
}
return $requirements;
}
}
php-client/src/Bitpay/Util/Error.php 0000755 00000010422 15250364036 0013353 0 ustar 00 = 4.3.0, PHP 5)
*
* @param bool
* @param bool
* @param int
* @return array|void
*/
final public function backtrace($print = false, $options = false, $limit = 0)
{
if ($print == true) {
return debug_print_backtrace($options, $limit);
} else {
return debug_backtrace($options, $limit);
}
}
/**
* Get the last occurred error and returns an associative
* array describing the last error with keys "type", "message",
* "file" and "line". If the error has been caused by a PHP
* internal function then the "message" begins with its name.
* Returns NULL if there hasn't been an error yet.
* (PHP 5 >= 5.2.0)
*
* @param void
* @return array
*/
final public function last()
{
return error_get_last();
}
/**
* Send an error message to the defined error handling
* routines. Returns true on success or false on failure.
* The possible values for $message_type are: 0 = system log,
* 1 = email to $destination, 2 = depricated, 3 = appended
* to file $destination, 4 = sent to SAPI log handler.
* (PHP 4, PHP 5)
*
* @param string
* @param int
* @param string
* @param string
*/
final public function log($message, $message_type = 0, $destination = '', $extra_headers = '')
{
return error_log((string) $message, $message_type = 0, $destination = '', $extra_headers = '');
}
/**
* Sets which PHP errors are reported or returns the old
* error_reporting level or the current level if no level
* parameter is given.
* (PHP 4, PHP 5)
*
* @param bool
* @return int
*/
final public function reporting($level = false)
{
if ($level !== false) {
return error_reporting($level);
} else {
return error_reporting();
}
}
/**
* Sets or restores either the error or exception handler
* based on the $type and $action parameters.
* (PHP 4 >= 4.0.1, PHP 5)
*
* @param string
* @param string
* @param mixed
* @param int
* return mixed
*/
final public function handler($type = 'error', $action = 'restore', $callable_handler = false, $error_types = null)
{
if (empty($error_types)) {
$error_types = E_ALL | E_STRICT;
}
switch (strtolower($type)) {
case 'error':
switch (strtolower($action)) {
case 'restore':
return restore_error_handler();
break;
case 'set':
return set_error_handler($callable_handler, $error_types);
break;
default:
return false;
}
break;
case 'exception':
switch (strtolower($action)) {
case 'restore':
return restore_exception_handler();
break;
case 'set':
return set_exception_handler($callable_handler);
break;
default:
return false;
}
break;
default:
return false;
}
}
/**
* Generates a user-level error/warning/notice message.
* This function returns FALSE if wrong $error_type is
* specified, TRUE otherwise. The $error_msg param is
* limited to 1024 bytes.
* (PHP 4 >= 4.0.1, PHP 5)
*
* @param string
* @param int
* @return bool
*/
final public function raise($error_msg, $error_type = E_USER_NOTICE)
{
return trigger_error($error_msg, $error_type);
}
}
php-client/src/Bitpay/Util/Base58.php 0000755 00000004116 15250364036 0013314 0 ustar 00 0) {
$q = Math::div($x, '58');
$r = Math::mod($x, '58');
$output_string .= substr($code_string, intval($r), 1);
$x = $q;
}
for ($i = 0; $i < $dataLen && substr($data, $i, 2) == '00'; $i += 2) {
$output_string .= substr($code_string, 0, 1);
}
$output_string = strrev($output_string);
return $output_string;
}
/**
* Decodes a numeric string from BASE-58 format.
*
* @param string $data
* @return string $return
*/
public static function decode($data)
{
$dataLen = strlen($data);
for ($return = '0', $i = 0; $i < $dataLen; $i++) {
$current = strpos(self::BASE58_CHARS, $data[$i]);
$return = Math::mul($return, '58');
$return = Math::add($return, $current);
}
$return = Util::encodeHex($return);
for ($i = 0; $i < $dataLen && substr($data, $i, 1) == '1'; $i++) {
$return = '00' . $return;
}
if (strlen($return) % 2 != 0) {
$return = '0' . $return;
}
return $return;
}
}
php-client/src/Bitpay/Util/CurveParameterInterface.php 0000755 00000000657 15250364036 0017041 0 ustar 00 $v) {
if (in_array(strtolower($k), $serverVariables)) {
self::$sigData[] = $v;
}
}
self::$sigData[] = phpversion();
self::$sigData[] = get_current_user();
self::$sigData[] = php_uname('s') . php_uname('n') . php_uname('m') . PHP_OS . PHP_SAPI . ICONV_IMPL . ICONV_VERSION;
self::$sigData[] = sha1_file(__FILE__);
self::$finHash = implode(self::$sigData);
self::$finHash = sha1(str_ireplace(' ', '', self::$finHash) . strlen(self::$finHash) . metaphone(self::$finHash));
self::$finHash = sha1(self::$finHash);
return self::$finHash;
}
}
php-client/src/Bitpay/Util/Secp256k1.php 0000755 00000002701 15250364036 0013646 0 ustar 00 txid;
}
/**
* Set transaction ID for payout.
* @param $txid
* @return $this
*/
public function setTransactionId($txid)
{
if (!empty($txid)) {
$this->txid = $txid;
}
return $this;
}
/**
* @inheritdoc
*/
public function getAmount()
{
return $this->amount;
}
/**
* Set the amount of bitcoin paid in the paout.
* @param $amount
* @return $this
*/
public function setAmount($amount)
{
if (!empty($amount)) {
$this->amount = $amount;
}
return $this;
}
/**
* @inheritdoc
*/
public function getDate()
{
return $this->date;
}
/**
* Set the date and time of when the payment was sent.
* @param $date
* @return $this
*/
public function setDate($date)
{
if (!empty($date)) {
$this->date = $date;
}
return $this;
}
}
php-client/src/Bitpay/Token.php 0000755 00000005725 15250364036 0012437 0 ustar 00 policies = array();
}
/**
* @return string
*/
public function __toString()
{
return (string)$this->getToken();
}
/**
* @return string
*/
public function getToken()
{
return $this->token;
}
/**
* @param string
* @return Token
*/
public function setToken($token)
{
$this->token = $token;
return $this;
}
/**
* @return string
*/
public function getResource()
{
return $this->resource;
}
/**
* @param string
* @return Token
*/
public function setResource($resource)
{
$this->resource = $resource;
return $this;
}
/**
* @return string
*/
public function getFacade()
{
return $this->facade;
}
/**
* @param string
* @return Token
*/
public function setFacade($facade)
{
$this->facade = $facade;
return $this;
}
/**
* @return \DateTime
*/
public function getCreatedAt()
{
return $this->createdAt;
}
/**
* @param \DateTime
* @return Token
*/
public function setCreatedAt(\DateTime $createdAt)
{
$this->createdAt = $createdAt;
return $this;
}
/**
* @return array
*/
public function getPolicies()
{
return $this->policies;
}
/**
* @param string
* @return Token
*/
public function setPolicies($policies)
{
$this->policies = $policies;
return $this;
}
/**
* @return string
*/
public function getPairingCode()
{
return $this->pairingCode;
}
/**
* @param string
* @return Token
*/
public function setPairingCode($pairingCode)
{
$this->pairingCode = $pairingCode;
return $this;
}
/**
* @return \DateTime
*/
public function getPairingExpiration()
{
return $this->pairingExpiration;
}
/**
* @param \DateTime
* @return Token
*/
public function setPairingExpiration(\DateTime $pairingExpiration)
{
$this->pairingExpiration = $pairingExpiration;
return $this;
}
}
php-client/src/Bitpay/TokenInterface.php 0000755 00000001360 15250364036 0014247 0 ustar 00 password = $password;
}
/**
* @inheritdoc
*/
public function persist(\Bitpay\KeyInterface $key)
{
$path = $key->getId();
$data = serialize($key);
$encrypted = $this->dataEncrypt($data);
$encoded = $this->dataEncode($encrypted);
$this->saveToFile($encoded, $path);
}
/**
* @inheritdoc
*/
public function load($id)
{
$encoded = $this->readFromFile($id);
$decoded = $this->dataDecode($encoded);
$decrypted = $this->dataDecrypt($decoded);
return unserialize($decrypted);
}
/**
* @param string $data
* @return string
* @throws \Exception
*/
private function dataEncrypt($data)
{
$encrypted = openssl_encrypt($data, self::METHOD, $this->password, self::OPENSSL_RAW_DATA, self::IV);
if ($encrypted === false) {
throw new \Exception('[ERROR] In EncryptedFilesystemStorage::dataEncrypt(): Could not encrypt data "' . $data . '". OpenSSL error(s) are: "' . $this->getOpenSslErrors() . '".');
}
return $encrypted;
}
/**
* @param string $data
* @return string
* @throws \Exception
*/
private function dataDecrypt($data)
{
$decrypted = openssl_decrypt($data, self::METHOD, $this->password, self::OPENSSL_RAW_DATA, self::IV);
if ($decrypted === false) {
throw new \Exception('[ERROR] In EncryptedFilesystemStorage::dataDecrypt(): Could not decrypt data "' . $data . '". OpenSSL error(s) are: "' . $this->getOpenSslErrors() . '".');
}
return $decrypted;
}
/**
* @param string $data
* @return string
* @throws \Exception
*/
private function dataEncode($data)
{
$encoded = base64_encode($data);
if ($encoded === false) {
throw new \Exception('[ERROR] In EncryptedFilesystemStorage::dataEncode(): Could not encode data "' . $data . '".');
}
return $encoded;
}
/**
* @param string $data
* @return string
* @throws \Exception
*/
private function dataDecode($data)
{
$decoded = base64_decode($data);
if ($decoded === false) {
throw new \Exception('[ERROR] In EncryptedFilesystemStorage::dataDecode(): Could not decode data "' . $data . '".');
}
return $decoded;
}
/**
* @param string $data
* @param string $path
* @throws \Exception
*/
private function saveToFile($data, $path)
{
if (file_put_contents($path, $data) === false) {
throw new \Exception('[ERROR] In EncryptedFilesystemStorage::saveToFile(): Could not write to the file "' . $path . '".');
}
}
/**
* @param string $path
* @return string
* @throws \Exception
*/
private function readFromFile($path)
{
if (is_file($path) === false || is_readable($path) === false) {
throw new \Exception('[ERROR] In EncryptedFilesystemStorage::readFromFile(): The file "' . $path . '" does not exist or cannot be read, check permissions.');
}
$data = file_get_contents($path);
if ($data === false) {
throw new \Exception('[ERROR] In EncryptedFilesystemStorage::readFromFile(): The file "' . $path . '" cannot be read, check permissions.');
}
return $data;
}
/**
* @return string
*/
private function getOpenSslErrors()
{
$openssl_error_msg = '';
while ($msg = openssl_error_string()) {
$openssl_error_msg .= $msg . "\r\n";
}
return $openssl_error_msg;
}
}
php-client/src/Bitpay/Storage/StorageInterface.php 0000755 00000000661 15250364036 0016202 0 ustar 00 getId();
file_put_contents($path, serialize($key));
} catch (\Exception $e) {
throw new \Exception('[ERROR] In FilesystemStorage::persist(): ' . $e->getMessage());
}
}
/**
* @inheritdoc
*/
public function load($id)
{
if (!is_file($id)) {
throw new \Exception(sprintf('[ERROR] In FilesystemStorage::load(): Could not find "%s".', $id));
}
if (!is_readable($id)) {
throw new \Exception(sprintf('[ERROR] In FilesystemStorage::load(): "%s" cannot be read, check permissions.', $id));
}
return unserialize(file_get_contents($id));
}
}
php-client/src/Bitpay/AccessToken.php 0000755 00000003511 15250364036 0013550 0 ustar 00 id = $id;
$this->email = $email;
$this->label = $label;
}
/**
* Setter for the id.
*
* @param string $id
* @return AccessToken
*/
public function setId($id)
{
if (!empty($id) && is_string($id) && ctype_print($id)) {
$this->id = trim($id);
}
return $this;
}
/**
* @inheritdoc
*/
public function getId()
{
return $this->id;
}
/**
* Setter for the email address.
*
* @param string $email
* @return AccessToken
*/
public function setEmail($email)
{
if (!empty($email) && is_string($email) && ctype_print($email)) {
$this->email = trim($email);
}
return $this;
}
/**
* @inheritdoc
*/
public function getEmail()
{
return $this->email;
}
/**
* Setter for the label.
*
* @param string $label
* @return AccessToken
*/
public function setLabel($label)
{
if (!empty($label) && is_string($label) && ctype_print($label)) {
$this->label = trim($label);
}
return $this;
}
/**
* @inheritdoc
*/
public function getLabel()
{
return $this->label;
}
}
php-client/src/Bitpay/ItemInterface.php 0000755 00000002001 15250364036 0014056 0 ustar 00 x)) {
return '';
}
if (Math::mod('0x'.$this->y, '0x02') == '1') {
return sprintf('03%s', $this->x);
} else {
return sprintf('02%s', $this->x);
}
}
/**
* @param PrivateKey
* @return PublicKey
*/
public static function createFromPrivateKey(PrivateKey $private)
{
$public = new self();
$public->setPrivateKey($private);
return $public;
}
/**
* @param PrivateKey
* @return PublicKey
*/
public function setPrivateKey(PrivateKey $privateKey)
{
$this->privateKey = $privateKey;
return $this;
}
/**
* Generates an uncompressed and compressed EC public key.
*
* @param \Bitpay\PrivateKey $privateKey
* @return \Bitpay\PublicKey
* @throws \Exception
*/
public function generate(PrivateKey $privateKey = null)
{
if ($privateKey instanceof PrivateKey) {
$this->setPrivateKey($privateKey);
}
if (!empty($this->hex)) {
return $this;
}
if (is_null($this->privateKey)) {
throw new \Exception('Please `setPrivateKey` before you generate a public key');
}
if (!$this->privateKey->isGenerated()) {
$this->privateKey->generate();
}
if (!$this->privateKey->isValid()) {
throw new \Exception('Private Key is invalid and cannot be used to generate a public key');
}
$point = new Point(
'0x'.substr(Secp256k1::G, 2, 64),
'0x'.substr(Secp256k1::G, 66, 64)
);
$R = Util::doubleAndAdd(
'0x'.$this->privateKey->getHex(),
$point
);
$RxHex = Util::encodeHex($R->getX());
$RyHex = Util::encodeHex($R->getY());
$RxHex = str_pad($RxHex, 64, '0', STR_PAD_LEFT);
$RyHex = str_pad($RyHex, 64, '0', STR_PAD_LEFT);
$this->x = $RxHex;
$this->y = $RyHex;
$this->hex = sprintf('%s%s', $RxHex, $RyHex);
$this->dec = Util::decodeHex($this->hex);
return $this;
}
/**
* Checks to see if the public key is not blank and contains
* valid decimal and hex valules for this->hex & this->dec
*
* @return boolean
*/
public function isValid()
{
return ((!empty($this->hex) && ctype_xdigit($this->hex)) && (!empty($this->dec) && ctype_digit($this->dec)));
}
/**
* @return SinKey
*/
public function getSin()
{
if (empty($this->hex)) {
$this->generate();
}
if (null === $this->sin) {
$this->sin = new SinKey();
$this->sin->setPublicKey($this);
$this->sin->generate();
}
return $this->sin;
}
}
php-client/src/Bitpay/Point.php 0000755 00000003004 15250364036 0012434 0 ustar 00 x = (string) $x;
$this->y = (string) $y;
}
/**
* @return string
*/
public function __toString()
{
if ($this->isInfinity()) {
return self::INFINITY;
}
return sprintf('(%s, %s)', $this->x, $this->y);
}
/**
* @return string
*/
public function getX()
{
return $this->x;
}
/**
* @return string
*/
public function getY()
{
return $this->y;
}
/**
* @return boolean
*/
public function isInfinity()
{
return (self::INFINITY == $this->x || self::INFINITY == $this->y);
}
/**
* @inheritdoc
*/
public function serialize()
{
return serialize(array($this->x, $this->y));
}
/**
* @inheritdoc
*/
public function unserialize($data)
{
list(
$this->x,
$this->y
) = unserialize($data);
}
}
php-client/src/Bitpay/Buyer.php 0000755 00000000370 15250364036 0012434 0 ustar 00 storage = $storage;
}
/**
* @param KeyInterface $key
*/
public function persist(KeyInterface $key)
{
$this->storage->persist($key);
}
/**
* @return KeyInterface
*/
public function load($id)
{
return $this->storage->load($id);
}
}
php-client/src/Bitpay/Math/BcEngine.php 0000755 00000011126 15250364036 0013712 0 ustar 00 input($a);
$b = $this->input($b);
return bcadd($a, $b);
}
/**
* @param String $a Numeric String
* @param String $b Numeric String
*/
public function cmp($a, $b)
{
$a = $this->input($a);
$b = $this->input($b);
return bccomp($a, $b);
}
/**
* @param String $a Numeric String
* @param String $b Numeric String
*/
public function div($a, $b)
{
$a = $this->input($a);
$b = $this->input($b);
return bcdiv($a, $b);
}
/**
* Finds inverse number $inv for $num by modulus $mod, such as:
* $inv * $num = 1 (mod $mod)
*
* @param string $num
* @param string $mod
* @return string
* @access public
*/
public function invertm($num, $mod)
{
$num = $this->input($num);
$mod = $this->input($mod);
$x = '1';
$y = '0';
$num1 = $mod;
do {
$tmp = bcmod($num, $num1);
$q = bcdiv($num, $num1);
$num = $num1;
$num1 = $tmp;
$tmp = bcsub($x, bcmul($y, $q));
$x = $y;
$y = $tmp;
} while (bccomp($num1, '0'));
if (bccomp($x, '0') < 0) {
$x = bcadd($x, $mod);
}
if (substr($num, 0, 1) === '-') {
$x = bcsub($mod, $x);
}
return $x;
}
/**
* @param String $a Numeric String
* @param String $b Numeric String
*/
public function mod($a, $b)
{
$a = $this->input($a);
$b = $this->input($b);
if (substr($a, 0, 1) === '-') {
return bcadd(bcmod($a, $b), $b);
}
return bcmod($a, $b);
}
/**
* @param String $a Numeric String
* @param String $b Numeric String
*/
public function mul($a, $b)
{
$a = $this->input($a);
$b = $this->input($b);
return bcmul($a, $b);
}
/**
* @param String $a Numeric String
* @param String $b Numeric String
*/
public function pow($a, $b)
{
$a = $this->input($a);
$b = $this->input($b);
return bcpow($a, $b);
}
/**
* @param String $a Numeric String
* @param String $b Numeric String
*/
public function sub($a, $b)
{
$a = $this->input($a);
$b = $this->input($b);
return bcsub($a, $b);
}
public function input($x)
{
if (empty($x)) {
return '0';
}
$x = strtolower(trim($x));
if (preg_match('/^(-?)0x([0-9a-f]+)$/', $x, $matches)) {
$sign = $matches[1];
$hex = $matches[2];
for ($dec = '0', $i = 0; $i < strlen($hex); $i++) {
$current = strpos('0123456789abcdef', $hex[$i]);
$dec = bcadd(bcmul($dec, 16), $current);
}
return $sign.$dec;
} elseif (preg_match('/^-?[0-9]+$/', $x)) {
return $x;
} else {
throw new \Exception("The input must be a numeric string in decimal or hexadecimal (with leading 0x) format.\n".var_export($x, true));
}
}
/**
* Function to determine if two numbers are
* co-prime according to the Euclidean algo.
*
* @param string $a First param to check.
* @param string $b Second param to check.
* @return bool Whether the params are cp.
*/
public function coprime($a, $b)
{
$small = 0;
$diff = 0;
while (bccomp($a, '0') > 0 && bccomp($b, '0') > 0) {
if (bccomp($a, $b) == -1) {
$small = $a;
$diff = bcmod($b, $a);
}
if (bccomp($a, $b) == 1) {
$small = $b;
$diff = bcmod($a, $b);
}
if (bccomp($a, $b) == 0) {
$small = $a;
$diff = bcmod($b, $a);
}
$a = $small;
$b = $diff;
}
if (bccomp($a, '1') == 0) {
return true;
}
return false;
}
}
php-client/src/Bitpay/Math/GmpEngine.php 0000755 00000003224 15250364036 0014111 0 ustar 00 $digest_alg,
'private_key_bits' => (int) $keybits,
'private_key_type' => OPENSSL_KEYTYPE_RSA,
);
$resource = openssl_pkey_new($config);
if (!$resource) {
throw new \Exception('Error in generateOpenSSLKeypair: Could not create new OpenSSL resource.');
/* with the openssl extension, you also have it's own errors returned */
while ($msg = openssl_error_string()) {
throw new \Exception('Error in generateOpenSSLKeypair: OpenSSL reported error: '.$msg);
}
return false;
}
if (openssl_pkey_export($resource, $keypair['pri'])) {
$publickey = openssl_pkey_get_details($resource);
$keypair['pub'] = $publickey['key'];
} else {
throw new \Exception('Error in generateOpenSSLKeypair: Private key could not be determined from OpenSSL key resource.');
while ($msg = openssl_error_string()) {
throw new \Exception('Error in generateOpenSSLKeypair: OpenSSL reported error: '.$msg);
}
return false;
}
openssl_pkey_free($resource);
return $keypair;
} else {
throw new \Exception('Error in generateOpenSSLKeypair: OpenSSL PHP extension missing. Cannot continue.');
return false;
}
} catch (Exception $e) {
while ($msg = openssl_error_string()) {
throw new \Exception('Error in generateOpenSSLKeypair: OpenSSL reported error: '.$msg);
}
throw $e;
return false;
}
}
/**
* Generates a high-quality random number suitable for
* use in cryptographic functions and returns hex value.
*
* @param int
* @return string|bool
*/
final public function randomNumber($bytes = 32)
{
$random_data = openssl_random_pseudo_bytes($bytes, $cstrong);
if (!$cstrong || !$random_data) {
return false;
} else {
return bin2hex($random_data);
}
}
/**
* Returns the cipher length on success, or FALSE
* on failure. (PHP 5 >= PHP 5.3.3)
*
* @param string
* @return int|bool
*/
final public function cypherIVLength($cypher = '')
{
return openssl_cipher_iv_length($cypher);
}
/**
* Takes the Certificate Signing Request represented
* by $csr and saves it as ascii-armoured text into
* the file named by $outfilename.
* (PHP 4 >= 4.2.0, PHP 5)
*
* @param resource
* @param string
* @param bool
* @return bool
*/
final public function saveCSRtoFile($csr, $outfilename, $notext = true)
{
if (!is_resource($csr)) {
return false;
}
return openssl_csr_export_to_file($csr, $outfilename, $notext);
}
/**
* Takes the Certificate Signing Request represented
* by $csr and stores it as ascii-armoured text into
* $out, which is passed by reference.
* (PHP 4 >= 4.2.0, PHP 5)
*
* @param resource
* @param string
* @param bool
* @return bool
*/
final public function saveCSRtoString($csr, $out, $notext = true)
{
if (!is_resource($csr)) {
return false;
}
return openssl_csr_export($csr, $out, $notext);
}
}
php-client/src/Bitpay/Crypto/HashExtension.php 0000755 00000014777 15250364036 0015426 0 ustar 00 = 5.1.2, PECL hash >= 1.1)
*
* @return array
*/
public function getAlgos()
{
return hash_algos();
}
/**
* Copy a hashing context.
* (PHP 5 >= 5.3.0)
*
* @param resource
* @return resource
*/
final public function copy($context)
{
if (!is_resource($context)) {
return false;
}
return hash_copy($context);
}
/**
* Compares two strings using the same time
* whether they're equal or not. This function
* should be used to mitigate timing attacks;
* for instance, when testing crypt() password
* hashes.
* (PHP 5 >= 5.6.0)
*
* @param string
* @param string
*/
public function equals($string1, $string2)
{
if (!is_string($string1) || !is_string($string2)) {
return false;
}
return hash_equals($string1, $string2);
}
/**
* Generate a hash value using the contents of
* a given file. Returns a string containing
* the calculated message digest as lowercase
* hexits unless raw_output is set to true in
* which case the raw binary representation of
* the message digest is returned.
* (PHP 5 >= 5.1.2, PECL hash >= 1.1)
*
* @param string
* @param string
* @param bool
* @return string
*/
public function file($algorithm, $filename, $raw_output = false)
{
return hash_file($algorithm, (string) $filename, $raw_output);
}
/**
* Finalize an incremental hash and return
* resulting digest.
* (PHP 5 >= 5.1.2, PECL hash >= 1.1)
*
* @param resource
* @param bool
* @return string
*/
public function finalize($context, $raw_output = false)
{
if (!is_resource($context)) {
return false;
}
return hash_final($context, $raw_output);
}
/**
* Generate a keyed hash value using the HMAC
* method and the contents of a given file.
* (PHP 5 >= 5.1.2, PECL hash >= 1.1)
*
* @param string
* @param string
* @param string
* @param bool
* @return string
*/
public function hmacFile($algorithm, $filename, $key, $raw_output = false)
{
return hash_hmac_file($algorithm, $filename, $key, $raw_output);
}
/**
* Generate a keyed hash value using the HMAC
* method and the message passed via $data.
* (PHP 5 >= 5.1.2, PECL hash >= 1.1)
*
* @param string
* @param string
* @param string
* @param bool
* @return string
*/
public function hmac($algo, $data, $key, $raw_output = false)
{
return hash_hmac($algo, $data, $key, $raw_output);
}
/**
* Initialize an incremental hashing context and
* returns a Hashing Context resource for use with
* hash_update(), hash_update_stream(), hash_update_file(),
* and hash_final(). Note: the only option possible
* for $options at this time is HASH_HMAC. When
* this is specified, the key *must* be used as well.
* (PHP 5 >= 5.1.2, PECL hash >= 1.1)
*
* @param string
* @param int
* @param string
* @return resource
*/
public function init($algorithm, $options = 0, $key = null)
{
return hash_init($algorithm, $options, $key);
}
/**
* Generate a PBKDF2 key derivation of a supplied
* password. An E_WARNING will be raised if the
* algorithm is unknown, the iterations parameter
* is less than or equal to 0, the length is less
* than 0 or the salt is too long (greater than
* INT_MAX - 4). The salt should be generated
* randomly with openssl_ramdom_pseudo_bytes().
* (PHP 5 >= 5.5.0)
*
* @param string
* @param string
* @param string
* @param int
* @param int
* @param bool
* @return string
*/
public function pbkdf2($algo, $password, $salt, $iterations, $length = 0, $raw_output = false)
{
return hash_pbkdf2($algo, $password, $salt, $iterations, $length, $raw_output);
}
/**
* Pump data into an active hashing context
* from a file. Returns TRUE on success or
* FALSE on failure.
* (PHP 5 >= 5.1.2, PECL hash >= 1.1)
*
* @param resource
* @param string
* @param resource
* @return bool
*/
public function updateFile($hcontext, $filename, $scontext = null)
{
if (!is_resource($hcontext)) {
return false;
}
return hash_update_file($hcontext, $filename, $scontext);
}
/**
* Pump data into an active hashing context
* from an open stream. Returns the actual
* number of bytes added to the hashing
* context from handle.
* (PHP 5 >= 5.1.2, PECL hash >= 1.1)
*
* @param resource
* @param resource
* @param int
* @return int
*/
public function updateStream($context, $handle, $length = -1)
{
if (!is_resource($context) || !is_resource($handle)) {
return false;
}
return hash_update_stream($context, $handle, $length);
}
/**
* Pump data into an active hashing context.
* The PHP function itself only returns true.
* (PHP 5 >= 5.1.2, PECL hash >= 1.1)
*
* @param resource
* @param string
* @return bool
*/
public function update($context, $data)
{
if (!is_resource($context)) {
return false;
}
return hash_update($context, $data);
}
/**
* Generate a hash value (message digest)
* based on the request algorithm and the
* provided data. Outputs hex unless the
* $raw_output param is set to true.
* (PHP 5 >= 5.1.2, PECL hash >= 1.1)
*
* @param string
* @param string
* @param bool
* @return string
*/
public function generate($algo, $data, $raw_output = false)
{
if (empty($data)) {
return false;
}
return hash($algo, $data, $raw_output);
}
}
php-client/src/Bitpay/Crypto/CryptoInterface.php 0000755 00000001035 15250364036 0015726 0 ustar 00 phone;
}
/**
* @param string $phone
* @return User
*/
public function setPhone($phone)
{
if (!empty($phone) && is_string($phone) && ctype_print($phone)) {
$this->phone = trim($phone);
}
return $this;
}
/**
* @inheritdoc
*/
public function getEmail()
{
return $this->email;
}
/**
* @param string $email
* @return User
*/
public function setEmail($email)
{
if (!empty($email) && is_string($email) && ctype_print($email)) {
$this->email = trim($email);
}
return $this;
}
/**
* @inheritdoc
*/
public function getFirstName()
{
return $this->firstName;
}
/**
* @param string $firstName
* @return User
*/
public function setFirstName($firstName)
{
if (!empty($firstName) && is_string($firstName) && ctype_print($firstName)) {
$this->firstName = trim($firstName);
}
return $this;
}
/**
* @inheritdoc
*/
public function getLastName()
{
return $this->lastName;
}
/**
* @param string $lastName
* @return User
*/
public function setLastName($lastName)
{
if (!empty($lastName) && is_string($lastName) && ctype_print($lastName)) {
$this->lastName = trim($lastName);
}
return $this;
}
/**
* @inheritdoc
*/
public function getAddress()
{
return $this->address;
}
/**
* @param array $address
* @return User
*/
public function setAddress(array $address)
{
if (!empty($address) && is_array($address)) {
$this->address = $address;
}
return $this;
}
/**
* @inheritdoc
*/
public function getCity()
{
return $this->city;
}
/**
* @param string $city
* @return User
*/
public function setCity($city)
{
if (!empty($city) && is_string($city) && ctype_print($city)) {
$this->city = trim($city);
}
return $this;
}
/**
* @inheritdoc
*/
public function getState()
{
return $this->state;
}
/**
* @param string $state
* @return User
*/
public function setState($state)
{
if (!empty($state) && is_string($state) && ctype_print($state)) {
$this->state = trim($state);
}
return $this;
}
/**
* @inheritdoc
*/
public function getZip()
{
return $this->zip;
}
/**
* @param string $zip
* @return User
*/
public function setZip($zip)
{
if (!empty($zip) && is_string($zip) && ctype_print($zip)) {
$this->zip = trim($zip);
}
return $this;
}
/**
* @inheritdoc
*/
public function getCountry()
{
return $this->country;
}
/**
* @param string $country
* @return User
*/
public function setCountry($country)
{
if (!empty($country) && is_string($country) && ctype_print($country)) {
$this->country = trim($country);
}
return $this;
}
/**
* @param bool $boolvalue
* @return User
*/
public function setAgreedToTOSandPP($boolvalue)
{
if (!empty($boolvalue)) {
$this->agreedToTOSandPP = $boolvalue;
}
return $this;
}
/**
* @return bool
*/
public function getAgreedToTOSandPP()
{
return $this->agreedToTOSandPP;
}
}
php-client/src/Bitpay/PayoutTransactionInterface.php 0000755 00000001173 15250364036 0016660 0 ustar 00 address = array();
$this->archived = false;
$this->currency = new Currency();
$this->items = array();
}
/**
* @inheritdoc
*/
public function getItems()
{
return $this->items;
}
/**
* @param Item $item
* @return Bill
*/
public function addItem(Item $item)
{
if (!empty($item)) {
$this->items[] = $item;
}
return $this;
}
/**
* @inheritdoc
*/
public function getCurrency()
{
return $this->currency;
}
/**
* @param Currency $currency
* @return Bill
*/
public function setCurrency(Currency $currency)
{
if (!empty($currency)) {
$this->currency = $currency;
}
return $this;
}
/**
* @inheritdoc
*/
public function getName()
{
return $this->name;
}
/**
* @param string $name
* @return Bill
*/
public function setName($name)
{
if (!empty($name) && ctype_print($name)) {
$this->name = trim($name);
}
return $this;
}
/**
* @inheritdoc
*/
public function getAddress()
{
return $this->address;
}
/**
* @param array $address
* @return Bill
*/
public function setAddress($address)
{
if (!empty($address) && is_array($address)) {
$this->address = $address;
}
return $this;
}
/**
* @inheritdoc
*/
public function getCity()
{
return $this->city;
}
/**
* @param string $city
* @return Bill
*/
public function setCity($city)
{
if (!empty($city) && ctype_print($city)) {
$this->city = trim($city);
}
return $this;
}
/**
* @inheritdoc
*/
public function getState()
{
return $this->state;
}
/**
* @param string $state
* @return Bill
*/
public function setState($state)
{
if (!empty($state) && ctype_print($state)) {
$this->state = trim($state);
}
return $this;
}
/**
* @inheritdoc
*/
public function getZip()
{
return $this->zip;
}
/**
* @param string $zip
* @return Bill
*/
public function setZip($zip)
{
if (!empty($zip) && ctype_print($zip)) {
$this->zip = trim($zip);
}
return $this;
}
/**
* @inheritdoc
*/
public function getCountry()
{
return $this->country;
}
/**
* @param string $country
* @return Bill
*/
public function setCountry($country)
{
if (!empty($country) && ctype_print($country)) {
$this->country = trim($country);
}
return $this;
}
/**
* @inheritdoc
*/
public function getEmail()
{
return $this->email;
}
/**
* @param string $email
* @return Bill
*/
public function setEmail($email)
{
if (!empty($email) && ctype_print($email)) {
$this->email = trim($email);
}
return $this;
}
/**
* @inheritdoc
*/
public function getPhone()
{
return $this->phone;
}
/**
* @param string $phone
* @return Bill
*/
public function setPhone($phone)
{
if (!empty($phone) && ctype_print($phone)) {
$this->phone = trim($phone);
}
return $this;
}
/**
* @inheritdoc
*/
public function getStatus()
{
return $this->status;
}
/**
* @param string $status
* @return Bill
*/
public function setStatus($status)
{
if (!empty($status) && ctype_print($status)) {
$this->status = trim($status);
}
return $this;
}
/**
* @inheritdoc
*/
public function getShowRate()
{
return $this->showRate;
}
/**
* @param string $showRate
* @return Bill
*/
public function setShowRate($showRate)
{
if (!empty($showRate) && ctype_print($showRate)) {
$this->showRate = trim($showRate);
}
return $this;
}
/**
* @inheritdoc
*/
public function getArchived()
{
return $this->archived;
}
/**
* @param boolean $archived
* @return Bill
*/
public function setArchived($archived)
{
$this->archived = (boolean) $archived;
return $this;
}
}
php-client/src/Bitpay/KeyInterface.php 0000755 00000000602 15250364036 0013715 0 ustar 00 value;
}
/**
* @param PublicKey
* @return SinKey
*/
public function setPublicKey(PublicKey $publicKey)
{
$this->publicKey = $publicKey;
return $this;
}
/**
* Generates a Service Identification Number (SIN), see:
* https://en.bitcoin.it/wiki/Identity_protocol_v1
*
* @return SinKey
* @throws \Exception
*/
public function generate()
{
if (is_null($this->publicKey)) {
throw new \Exception('Public Key has not been set');
}
$compressedValue = $this->publicKey;
if (empty($compressedValue)) {
throw new \Exception('The Public Key needs to be generated.');
}
$step1 = Util::sha256(Util::binConv($compressedValue), true);
$step2 = Util::ripe160($step1);
$step3 = sprintf(
'%s%s%s',
self::SIN_VERSION,
self::SIN_TYPE,
$step2
);
$step4 = Util::twoSha256(Util::binConv($step3), true);
$step5 = substr(bin2hex($step4), 0, 8);
$step6 = $step3 . $step5;
$this->value = Base58::encode($step6);
return $this;
}
/**
* Checks to make sure that this SIN is a valid object.
*
* @return boolean
*/
public function isValid()
{
return (!is_null($this->value) && (substr($this->value, 0, 1) == 'T'));
}
}
php-client/src/Bitpay/PaymentUrlSet.php 0000755 00000001673 15250364036 0014131 0 ustar 00 paymentUrls = $paymentUrls;
}
/**
* Return the account parameter given by Bitpay.
*
* @return string
*/
public function getUrl($urlType)
{
if (array_key_exists($urlType, $this->paymentUrls)) {
return $this->paymentUrls[$urlType];
}
return null;
}
/**
* Return the account parameter given by Bitpay.
*
* @return PaymentUrlInterface
*/
public function setUrls(array $paymentUrls)
{
$this->paymentUrls = $paymentUrls;
return $this;
}
}
php-client/src/Bitpay/Application.php 0000755 00000002226 15250364036 0013613 0 ustar 00 users = array();
$this->orgs = array();
}
/**
* @inheritdoc
*/
public function getUsers()
{
return $this->users;
}
/**
* @inheritdoc
*/
public function getOrgs()
{
return $this->orgs;
}
/**
* Add user to stack
*
* @param User $user
* @return Application
*/
public function addUser(User $user)
{
if (!empty($user)) {
$this->users[] = $user;
}
return $this;
}
/**
* Add org to stack
*
* @param Org $org
* @return Application
*/
public function addOrg(Org $org)
{
if (!empty($org)) {
$this->orgs[] = $org;
}
return $this;
}
}
php-client/src/Bitpay/Config/Configuration.php 0000755 00000010274 15250364036 0015366 0 ustar 00 root('bitpay');
$rootNode
->children()
->scalarNode('public_key')
->info('Public Key Filename')
->defaultValue($this->getPubKeyFilename())
->end()
->scalarNode('private_key')
->info('Private Key Filename')
->defaultValue($this->getPriKeyFilename())
->end()
->scalarNode('sin_key')
->info('SIN Filename')
->defaultValue($this->getSinFilename())
->end()
->enumNode('network')
->values($this->networks)
->info('Network')
->defaultValue($this->networks[0])
->end()
->enumNode('adapter')
->values($this->adapters)
->info('Client Adapter')
->defaultValue($this->adapters[0])
->end()
->append($this->addKeyStorageNode())
->scalarNode('key_storage_password')
->info('Used to encrypt and decrypt keys when saving to filesystem')
->defaultNull()
->end()
->end();
return $treeBuilder;
}
/**
* Adds the key_storage node with validation rules.
* key_storage MUST:
* * implement Bitpay\Storage\StorageInterface
* * be a class that can be loaded
*
* @return \Symfony\Component\Config\Definition\Builder\NodeDefinition
* @throws \Exception
*/
protected function addKeyStorageNode()
{
$builder = new TreeBuilder();
$node = $builder->root('key_storage', 'scalar');
$node
->info('Class that is used to store your keys')
->defaultValue($this->defstorage)
->validate()
->always()
->then(function ($value) {
if (!class_exists($value)) {
throw new \Exception(
sprintf(
'Could not find class "%s".',
$value
)
);
}
// requires PHP >= 5.3.7
if (is_subclass_of($value, 'Bitpay\Storage\StorageInterface') === false) {
throw new \Exception('[ERROR] In Configuration::addKeyStorageNode(): "' . $value . '" does not implement "Bitpay\Storage\StorageInterface".');
}
return $value;
})
->end();
return $node;
}
/**
* @return string
*/
private function getPubKeyFilename()
{
return getenv('HOME') . $this->pubfilename;
}
/**
* @return string
*/
private function getPriKeyFilename()
{
return getenv('HOME') . $this->prifilename;
}
/**
* @return string
*/
private function getSinFilename()
{
return getenv('HOME') . $this->sinfilename;
}
}
php-client/src/Bitpay/PayoutInstruction.php 0000755 00000007354 15250364036 0015102 0 ustar 00 transactions = array();
}
/**
* @inheritdoc
*/
public function getId()
{
return $this->id;
}
/**
* Set the Bitpay ID for this payout instruction
*
* @param $id
* @return $this
*/
public function setId($id)
{
if (!empty($id)) {
$this->id = trim($id);
}
return $this;
}
/**
* @inheritdoc
*/
public function getLabel()
{
return $this->label;
}
/**
* Set the employers label for this instruction.
* @param $label
* @return $this
*/
public function setLabel($label)
{
if (!empty($label)) {
$this->label = trim($label);
}
return $this;
}
/**
* @inheritdoc
*/
public function getAddress()
{
return $this->address;
}
/**
* Set the bitcoin address for this instruction.
* @param $address
* @return $this
*/
public function setAddress($address)
{
if (!empty($address)) {
$this->address = trim($address);
}
return $this;
}
/**
* @inheritdoc
*/
public function getAmount()
{
return $this->amount;
}
/**
* Set the amount for this instruction.
* @param $amount
* @return $this
*/
public function setAmount($amount)
{
if (!empty($amount)) {
$this->amount = $amount;
}
return $this;
}
/**
* @inheritdoc
*/
public function getBtc()
{
return $this->btc;
}
/**
* Set BTC array (available once rates are set)
* @param $btc
* @return $this
*/
public function setBtc($btc)
{
if (!empty($btc) && is_array($btc)) {
$this->btc = $btc;
}
return $this;
}
/**
* @inheritdoc
*/
public function getStatus()
{
return $this->status;
}
/**
* Set the status for this instruction
* @param $status
* @return $this
*/
public function setStatus($status)
{
if (!empty($status) && ctype_print($status)) {
$this->status = trim($status);
}
return $this;
}
/**
* @inheritdoc
*/
public function getTransactions()
{
return $this->transactions;
}
/**
* Add payout transaction to the
* @param PayoutTransactionInterface $transaction
* @return $this
*/
public function addTransaction(PayoutTransactionInterface $transaction)
{
if (!empty($transaction)) {
$this->transactions[] = $transaction;
}
return $this;
}
}
php-client/src/Bitpay/Currency.php 0000755 00000014347 15250364036 0013151 0 ustar 00 setCode($code);
}
$this->payoutEnabled = false;
$this->payoutFields = array();
}
/**
* @inheritdoc
*/
public function getCode()
{
return $this->code;
}
/**
* This will change the $code to all uppercase
*
* @param string $code The Currency Code to use, ie USD
* @throws Exception Throws an exception if the Currency Code is not supported
* @return CurrencyInterface
*/
public function setCode($code)
{
if (null !== $code && !in_array(strtoupper($code), self::$availableCurrencies)) {
throw new \Bitpay\Client\ArgumentException(
sprintf('The currency code "%s" is not supported.', $code)
);
}
$this->code = strtoupper($code);
return $this;
}
/**
* @inheritdoc
*/
public function getSymbol()
{
return $this->symbol;
}
/**
* @param string $symbol
*
* @return CurrencyInterface
*/
public function setSymbol($symbol)
{
if (!empty($symbol) && ctype_print($symbol)) {
$this->symbol = trim($symbol);
}
return $this;
}
/**
* @inheritdoc
*/
public function getPrecision()
{
return $this->precision;
}
/**
* @param integer $precision
*
* @return CurrencyInterface
*/
public function setPrecision($precision)
{
if (!empty($precision) && ctype_digit(strval($precision))) {
$this->precision = (int) $precision;
}
return $this;
}
/**
* @inheritdoc
*/
public function getExchangePctFee()
{
return $this->exchangePercentageFee;
}
/**
* @param string $fee
*
* @return CurrencyInterface
*/
public function setExchangePctFee($fee)
{
if (!empty($fee) && ctype_print($fee)) {
$this->exchangePercentageFee = trim($fee);
}
return $this;
}
/**
* @inheritdoc
*/
public function isPayoutEnabled()
{
return $this->payoutEnabled;
}
/**
* @param boolean $enabled
*
* @return CurrencyInterface
*/
public function setPayoutEnabled($enabled)
{
$this->payoutEnabled = (boolean) $enabled;
return $this;
}
/**
* @inheritdoc
*/
public function getName()
{
return $this->name;
}
/**
* @param string $name
*
* @return CurrencyInterface
*/
public function setName($name)
{
if (!empty($name) && ctype_print($name)) {
$this->name = trim($name);
}
return $this;
}
/**
* @inheritdoc
*/
public function getPluralName()
{
return $this->pluralName;
}
/**
* @param string $pluralName
*
* @return CurrencyInterface
*/
public function setPluralName($pluralName)
{
if (!empty($pluralName) && ctype_print($pluralName)) {
$this->pluralName = trim($pluralName);
}
return $this;
}
/**
* @inheritdoc
*/
public function getAlts()
{
return $this->alts;
}
/**
* @param array $alts
*
* @return CurrencyInterface
*/
public function setAlts($alts)
{
$this->alts = $alts;
return $this;
}
/**
* @inheritdoc
*/
public function getPayoutFields()
{
return $this->payoutFields;
}
/**
* @param array $payoutFields
*
* @return CurrencyInterface
*/
public function setPayoutFields(array $payoutFields)
{
$this->payoutFields = $payoutFields;
return $this;
}
}
php-client/src/Bitpay/Key.php 0000755 00000003460 15250364036 0012101 0 ustar 00 id = $id;
}
/**
* @return string
*/
public function getId()
{
return $this->id;
}
/**
* Returns a new instance of self.
*
* @param string $id
* @return \Bitpay\KeyInterface
*/
public static function create($id = null)
{
$class = get_called_class();
return new $class($id);
}
/**
* @return string
*/
public function getHex()
{
return $this->hex;
}
/**
* @return string
*/
public function getDec()
{
return $this->dec;
}
/**
* @inheritdoc
*/
public function serialize()
{
return serialize(
array(
$this->id,
$this->x,
$this->y,
$this->hex,
$this->dec,
)
);
}
/**
* @inheritdoc
*/
public function unserialize($data)
{
list(
$this->id,
$this->x,
$this->y,
$this->hex,
$this->dec
) = unserialize($data);
}
/**
* @return boolean
*/
public function isGenerated()
{
return (!empty($this->hex));
}
}
php-client/src/Bitpay/PointInterface.php 0000755 00000001041 15250364036 0014254 0 ustar 00 id;
}
/**
* Set the batch ID as assigned from bitpay.
*
* @param $id
* @return $this
*/
public function setId($id)
{
if (!empty($id) && ctype_print($id)) {
$this->id = trim($id);
}
return $this;
}
/**
* @inheritdoc
*/
public function getAccountId()
{
return $this->account_id;
}
/**
* Set Account Id - Bitpays account ID for the payout.
*
* @param $id
* @return $this
*/
public function setAccountId($id)
{
if (!empty($id) && ctype_print($id)) {
$this->account_id = $id;
}
return $this;
}
/**
* @inheritdoc
*/
public function getAmount()
{
return $this->amount;
}
/**
* Sets the amount for this payout.
* @param $amount
* @return $this
*/
public function setAmount($amount)
{
if (!empty($amount)) {
$this->amount = $amount;
}
return $this;
}
/**
* @interitdoc
*/
public function getCurrency()
{
return $this->currency;
}
/**
* Set Currency
* @param CurrencyInterface $currency
* @return $this
*/
public function setCurrency(CurrencyInterface $currency)
{
if (!empty($currency)) {
$this->currency = $currency;
}
return $this;
}
/**
* @inheritdoc
*/
public function getEffectiveDate()
{
return $this->effectiveDate;
}
/**
* Set Effective date - date payout should be given to employees.
* @param $effectiveDate
* @return $this
*/
public function setEffectiveDate($effectiveDate)
{
if (!empty($effectiveDate)) {
$this->effectiveDate = $effectiveDate;
}
return $this;
}
/**
* Get rate assigned to payout at effectiveDate
*/
public function getRate()
{
return $this->rate;
}
/**
* Set the rate in bitcoin for the payouts of this transaction.
* @param $rate
* @return $this
*/
public function setRate($rate)
{
if (!empty($rate)) {
$this->rate = $rate;
}
return $this;
}
/**
* @inheritdoc
*/
public function getBtcAmount()
{
return $this->btc;
}
/**
* Set the Bitcoin amount for this payout, once set by Bitpay.
* @param $amount
* @return $this
*/
public function setBtcAmount($amount)
{
if (!empty($amount)) {
$this->btc = $amount;
}
return $this;
}
/**
* @inheritdoc
*/
public function getRequestDate()
{
return $this->requestDate;
}
/**
* Set
*/
public function setRequestDate($requestDate)
{
if (!empty($requestDate)) {
$this->requestDate = $requestDate;
}
return $this;
}
/**
* @inheritdoc
*/
public function getInstructions()
{
return $this->instructions;
}
/**
* Add Instruction of PayoutInstructionInterface type
* Increases $this->amount by value.
*
* @param PayoutInstructionInterface $instruction
* @return $this
*/
public function addInstruction(PayoutInstructionInterface $instruction)
{
if (!empty($instruction)) {
$this->instructions[] = $instruction;
}
return $this;
}
/**
* Update Instruction - Supply an index of the instruction to update,
* plus the function and single argument, to do something to an instruction.
*
* @param $index
* @param $function
* @param $argument
* @return $this
*/
public function updateInstruction($index, $function, $argument)
{
if (!empty($argument) && ctype_print($argument)) {
$this->instructions[$index]->$function($argument);
}
return $this;
}
/**
* @inheritdoc
*/
public function getStatus()
{
return $this->status;
}
/**
* Sets the status for the current payout request
* @param $status
* @return $this
*/
public function setStatus($status)
{
if (!empty($status) && ctype_print($status)) {
$this->status = trim($status);
}
return $this;
}
/**
* @inheritdoc
*/
public function getToken()
{
return $this->token;
}
/**
* Set the token to authorize this request.
* @param TokenInterface $token
* @return $this
*/
public function setToken(TokenInterface $token)
{
if (!empty($token)) {
$this->token = $token;
}
return $this;
}
/**
* @inheritdoc
*/
public function getResponseToken()
{
return $this->responseToken;
}
/**
* Set Response Token - returned by Bitpay when payout request is created
*
* @param $responseToken
* @return $this
*/
public function setResponseToken($responseToken)
{
if (!empty($responseToken)) {
$this->responseToken = trim($responseToken);
}
return $this;
}
/**
* @inheritdoc
*/
public function getPricingMethod()
{
return $this->pricingMethod;
}
/**
* Set the pricing method for this payout request
* @param $pricingMethod
* @return $this
*/
public function setPricingMethod($pricingMethod)
{
if (!empty($pricingMethod) && ctype_print($pricingMethod)) {
$this->pricingMethod = trim($pricingMethod);
}
return $this;
}
/**
* @inheritdoc
*/
public function getReference()
{
return $this->reference;
}
/**
* Set the payroll providers reference for this payout
*
* @param $reference
* @return $this
*/
public function setReference($reference)
{
if (!empty($reference) && ctype_print($reference)) {
$this->reference = trim($reference);
}
return $this;
}
/**
* @inheritdoc
*/
public function getNotificationEmail()
{
return $this->notificationEmail;
}
/**
* Set an email address where updates to payout status should be sent.
*
* @param $notificationEmail
* @return $this
*/
public function setNotificationEmail($notificationEmail)
{
if (!empty($notificationEmail) && ctype_print($notificationEmail)) {
$this->notificationEmail = trim($notificationEmail);
}
return $this;
}
/**
* @inheritdoc
*/
public function getNotificationUrl()
{
return $this->notificationUrl;
}
/**
* Set a notification url - where updated Payout objects will be sent
*
* @param $notificationUrl
* @return $this
*/
public function setNotificationUrl($notificationUrl)
{
if (!empty($notificationUrl) && ctype_print($notificationUrl)) {
$this->notificationUrl = trim($notificationUrl);
}
return $this;
}
}
php-client/src/Bitpay/Invoice.php 0000755 00000033644 15250364036 0012754 0 ustar 00 currency = $currency;
$this->transactionSpeed = $transactionSpeed;
$this->fullNotifications = $fullNotifications;
$this->item = $item;
$this->orderId = $orderId;
$this->posData = $posData;
}
/**
* @inheritdoc
*/
public function getPrice()
{
if (is_a($this->item, '\Bitpay\Item')) {
return $this->getItem()->getPrice();
} else {
return 0.000000;
}
}
/**
* @param float $price
* @return Invoice
*/
public function setPrice($price)
{
if (is_numeric($price)) {
$this->getItem()->setPrice(floatval($price));
}
return $this;
}
/**
* @inheritdoc
*/
public function getCurrency()
{
if ($this->currency === null) {
$this->currency = new Currency('BTC');
}
return $this->currency;
}
/**
* @param CurrencyInterface $currency
* @return Invoice
*/
public function setCurrency(CurrencyInterface $currency)
{
if (is_a($currency, '\Bitpay\Currency')) {
$this->currency = $currency;
}
return $this;
}
/**
* @inheritdoc
*/
public function getItem()
{
if (null === $this->item) {
$this->item = new Item();
}
return $this->item;
}
/**
* @param ItemInterface $item
* @return Invoice
*/
public function setItem(ItemInterface $item)
{
if (is_a($item, '\Bitpay\Item')) {
$this->item = $item;
}
return $this;
}
/**
* @inheritdoc
*/
public function getBuyer()
{
if ($this->buyer === null) {
$this->buyer = new Buyer();
}
return $this->buyer;
}
/**
* @param BuyerInterface $buyer
* @return Invoice
*/
public function setBuyer(BuyerInterface $buyer)
{
if (is_a($buyer, '\Bitpay\Buyer')) {
$this->buyer = $buyer;
}
return $this;
}
/**
* @inheritdoc
*/
public function getTransactionSpeed()
{
return $this->transactionSpeed;
}
/**
* @param string $transactionSpeed
* @return Invoice
*/
public function setTransactionSpeed($transactionSpeed)
{
switch (strtolower(trim($transactionSpeed))) {
case 'high':
$this->transactionSpeed = self::TRANSACTION_SPEED_HIGH;
break;
case 'medium':
$this->transactionSpeed = self::TRANSACTION_SPEED_MEDIUM;
break;
case 'low':
default:
$this->transactionSpeed = self::TRANSACTION_SPEED_LOW;
}
return $this;
}
/**
* @inheritdoc
*/
public function getNotificationEmail()
{
return $this->notificationEmail;
}
/**
* @param string $notificationEmail
* @return Invoice
*/
public function setNotificationEmail($notificationEmail)
{
if (filter_var($notificationEmail, FILTER_VALIDATE_EMAIL)) {
$this->notificationEmail = trim($notificationEmail);
}
return $this;
}
/**
* @inheritdoc
*/
public function getNotificationUrl()
{
return $this->notificationUrl;
}
/**
* @param string $notificationUrl
* @return Invoice
*/
public function setNotificationUrl($notificationUrl)
{
if (preg_match("/\b(?:(?:https?|ftp):\/\/|www\.)[-a-z0-9+&@#\/%?=~_|!:,.;]*[-a-z0-9+&@#\/%=~_|]/i", $notificationUrl)) {
$this->notificationUrl = trim($notificationUrl);
}
return $this;
}
/**
* @inheritdoc
*/
public function getRedirectUrl()
{
return $this->redirectUrl;
}
/**
* @param string $redirectUrl
* @return Invoice
*/
public function setRedirectUrl($redirectUrl)
{
if (preg_match("/\b(?:(?:https?|ftp):\/\/|www\.)[-a-z0-9+&@#\/%?=~_|!:,.;]*[-a-z0-9+&@#\/%=~_|]/i", $redirectUrl)) {
$this->redirectUrl = trim($redirectUrl);
}
return $this;
}
/**
* @inheritdoc
*/
public function getPosData()
{
return $this->posData;
}
/**
* @param string $posData
* @return Invoice
*/
public function setPosData($posData)
{
if (is_string($posData)) {
$this->posData = $posData;
}
return $this;
}
/**
* @inheritdoc
*/
public function getStatus()
{
return $this->status;
}
/**
* @param string $status
* @return Invoice
*/
public function setStatus($status)
{
if (is_string($status)) {
$this->status = trim($status);
}
return $this;
}
/**
* @inheritdoc
*/
public function isFullNotifications()
{
return $this->fullNotifications;
}
public function setFullNotifications($notifications)
{
$this->fullNotifications = (boolean) $notifications;
return $this;
}
/**
* @inheritdoc
*/
public function getId()
{
return $this->id;
}
/**
* @param string $id
* @return Invoice
*/
public function setId($id)
{
if (is_string($id)) {
$this->id = trim($id);
}
return $this;
}
/**
* @inheritdoc
*/
public function getUrl()
{
return $this->url;
}
/**
* @param string $url
* @return Invoice
*/
public function setUrl($url)
{
if (preg_match("/\b(?:(?:https?|ftp):\/\/|www\.)[-a-z0-9+&@#\/%?=~_|!:,.;]*[-a-z0-9+&@#\/%=~_|]/i", $url)) {
$this->url = trim($url);
}
return $this;
}
/**
* @inheritdoc
*/
public function getBtcPrice()
{
return $this->btcPrice;
}
/**
* @param float $btcPrice
* @return Invoice
*/
public function setBtcPrice($btcPrice)
{
if (is_numeric($btcPrice)) {
$this->btcPrice = floatval($btcPrice);
}
return $this;
}
/**
* @inheritdoc
*/
public function getInvoiceTime()
{
return $this->invoiceTime;
}
/**
* @param \DateTime $invoiceTime
* @return Invoice
*/
public function setInvoiceTime($invoiceTime)
{
if (is_a($invoiceTime, 'DateTime')) {
$this->invoiceTime = $invoiceTime;
} else if (is_numeric($invoiceTime)) {
$invoiceDateTime = new \DateTime();
$invoiceDateTime->setTimestamp($invoiceTime);
$this->invoiceTime = $invoiceDateTime;
}
return $this;
}
/**
* @inheritdoc
*/
public function getExpirationTime()
{
return $this->expirationTime;
}
/**
* @param \DateTime $expirationTime
* return Invoice
*/
public function setExpirationTime($expirationTime)
{
if (is_a($expirationTime, 'DateTime')) {
$this->expirationTime = $expirationTime;
} else if (is_numeric($expirationTime)) {
$expirationDateTime = new \DateTime();
$expirationDateTime->setTimestamp($expirationTime);
$this->expirationTime = $expirationDateTime;
}
return $this;
}
/**
* @inheritdoc
*/
public function getCurrentTime()
{
return $this->currentTime;
}
/**
* @param \DateTime $currentTime
* @return Invoice
*/
public function setCurrentTime($currentTime)
{
if (is_a($currentTime, 'DateTime')) {
$this->currentTime = $currentTime;
} else if (is_numeric($currentTime)) {
$currentDateTime = new \DateTime();
$currentDateTime->setTimestamp($currentTime);
$this->currentTime = $currentDateTime;
}
return $this;
}
/**
* @inheritdoc
*/
public function getOrderId()
{
return $this->orderId;
}
/**
* @param string $orderId
* @return Invoice
*/
public function setOrderId($orderId)
{
if (is_string($orderId)) {
$this->orderId = trim($orderId);
}
return $this;
}
/**
* @inheritdoc
*/
public function getItemDesc()
{
return $this->getItem()->getDescription();
}
/**
* @inheritdoc
*/
public function getItemCode()
{
return $this->getItem()->getCode();
}
/**
* @inheritdoc
*/
public function isPhysical()
{
return $this->getItem()->isPhysical();
}
/**
* @inheritdoc
*/
public function getBuyerName()
{
$firstName = $this->getBuyer()->getFirstName();
$lastName = $this->getBuyer()->getLastName();
return trim($firstName . ' ' . $lastName);
}
/**
* @inheritdoc
*/
public function getBuyerAddress1()
{
$address = $this->getBuyer()->getAddress();
return $address[0];
}
/**
* @inheritdoc
*/
public function getBuyerAddress2()
{
$address = $this->getBuyer()->getAddress();
return $address[1];
}
/**
* @inheritdoc
*/
public function getBuyerCity()
{
return $this->getBuyer()->getCity();
}
/**
* @inheritdoc
*/
public function getBuyerState()
{
return $this->getBuyer()->getState();
}
/**
* @inheritdoc
*/
public function getBuyerZip()
{
return $this->getBuyer()->getZip();
}
/**
* @inheritdoc
*/
public function getBuyerCountry()
{
return $this->getBuyer()->getCountry();
}
/**
* @inheritdoc
*/
public function getBuyerEmail()
{
return $this->getBuyer()->getEmail();
}
/**
* @inheritdoc
*/
public function getBuyerPhone()
{
return $this->getBuyer()->getEmail();
}
/**
* @inheritdoc
*/
public function getExceptionStatus()
{
return $this->exceptionStatus;
}
/**
* @param
* @return Invoice
*/
public function setExceptionStatus($exceptionStatus)
{
$this->exceptionStatus = $exceptionStatus;
return $this;
}
/**
* @param void
* @return
*/
public function getBtcPaid()
{
return $this->btcPaid;
}
/**
* @param
* @return Invoice
*/
public function setBtcPaid($btcPaid)
{
if (is_numeric($btcPaid)) {
$this->btcPaid = $btcPaid;
}
return $this;
}
/**
* @param void
* @return Invoice
*/
public function getRate()
{
return $this->rate;
}
/**
* @param
* @return
*/
public function setRate($rate)
{
if (is_numeric($rate)) {
$this->rate = floatval($rate);
}
return $this;
}
/**
* @return TokenInterface
*/
public function getToken()
{
return $this->token;
}
/**
* @param TokenInterface $token
* @return Invoice
*/
public function setToken(TokenInterface $token)
{
if (is_a($token, '\Bitpay\Token')) {
$this->token = $token;
}
return $this;
}
/**
* @return PaymentUrlInterface
*/
public function getPaymentUrls()
{
if ($this->paymentUrls === null) {
$this->paymentUrls = new PaymentUrlSet();
}
return $this->paymentUrls;
}
/**
* @param PaymentUrlInterface $paymentUrls
* @return Invoice
*/
public function setPaymentUrls(PaymentUrlInterface $paymentUrls)
{
$this->paymentUrls = $paymentUrls;
return $this;
}
/**
* @param string $paymentUrlType
* @return string
*/
public function getPaymentUrl($paymentUrlType)
{
return $this->getPaymentUrls()->getUrl($paymentUrlType);
}
}
php-client/src/Bitpay/PrivateKey.php 0000755 00000023476 15250364036 0013445 0 ustar 00 hex;
}
/**
* @return PublicKey
*/
public function getPublicKey()
{
if (null === $this->publicKey) {
$this->publicKey = new PublicKey();
$this->publicKey->setPrivateKey($this);
$this->publicKey->generate();
}
return $this->publicKey;
}
/**
* Generates an EC private key
*
* @return \Bitpay\PrivateKey
*/
public function generate()
{
if (!empty($this->hex)) {
return $this;
}
do {
$privateKey = \Bitpay\Util\SecureRandom::generateRandom(32);
$this->hex = strtolower(bin2hex($privateKey));
} while (Math::cmp('0x'.$this->hex, '1') <= 0 || Math::cmp('0x' . $this->hex, '0x' . Secp256k1::N) >= 0);
$this->dec = Util::decodeHex($this->hex);
return $this;
}
/**
* Checks to see if the private key value is not empty and
* the hex form only contains hexits and the decimal form
* only contains devimal digits.
*
* @return boolean
*/
public function isValid()
{
return ($this->hasValidDec() && $this->hasValidHex());
}
/**
* @return boolean
*/
public function hasValidHex()
{
return (!empty($this->hex) || ctype_xdigit($this->hex));
}
/**
* @return boolean
*/
public function hasValidDec()
{
return (!empty($this->dec) || ctype_digit($this->dec));
}
/**
* Creates an ECDSA signature of $data.
*
* @param string
* @return string
* @throws \Exception
*/
public function sign($data)
{
if (!ctype_xdigit($this->hex)) {
throw new \Exception('The private key must be in hex format.');
}
if (empty($data)) {
throw new \Exception('You did not provide any data to sign.');
}
$e = Util::decodeHex(hash('sha256', $data));
do {
if (substr(strtolower($this->hex), 0, 2) != '0x') {
$d = '0x' . $this->hex;
} else {
$d = $this->hex;
}
$k = SecureRandom::generateRandom(32);
$k_hex = '0x' . strtolower(bin2hex($k));
$n_hex = '0x' . Secp256k1::N;
$Gx = '0x' . substr(Secp256k1::G, 2, 64);
$Gy = '0x' . substr(Secp256k1::G, 66, 64);
$P = new Point($Gx, $Gy);
// Calculate a new curve point from Q=k*G (x1,y1)
$R = Util::doubleAndAdd($k_hex, $P);
$Rx_hex = Util::encodeHex($R->getX());
$Rx_hex = str_pad($Rx_hex, 64, '0', STR_PAD_LEFT);
// r = x1 mod n
$r = Math::mod('0x' . $Rx_hex, $n_hex);
// s = k^-1 * (e+d*r) mod n
$edr = Math::add($e, Math::mul($d, $r));
$invk = Math::invertm($k_hex, $n_hex);
$kedr = Math::mul($invk, $edr);
$s = Math::mod($kedr, $n_hex);
// The signature is the pair (r,s)
$signature = array(
'r' => Util::encodeHex($r),
's' => Util::encodeHex($s),
);
$signature['r'] = str_pad($signature['r'], 64, '0', STR_PAD_LEFT);
$signature['s'] = str_pad($signature['s'], 64, '0', STR_PAD_LEFT);
} while (Math::cmp($r, '0') <= 0 || Math::cmp($s, '0') <= 0);
$sig = array(
'sig_rs' => $signature,
'sig_hex' => self::serializeSig($signature['r'], $signature['s']),
);
return $sig['sig_hex']['seq'];
}
/**
* ASN.1 DER encodes the signature based on the form:
* 0x30 + size(all) + 0x02 + size(r) + r + 0x02 + size(s) + s
* http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
*
* @param string
* @param string
* @return string
*/
public static function serializeSig($r, $s)
{
$dec = '';
$byte = '';
$seq = '';
$digits = array();
$retval = array();
for ($x = 0; $x < 256; $x++) {
$digits[$x] = chr($x);
}
$dec = Util::decodeHex($r);
while (Math::cmp($dec, '0') > 0) {
$dv = Math::div($dec, '256');
$rem = Math::mod($dec, '256');
$dec = $dv;
$byte = $byte . $digits[$rem];
}
$byte = strrev($byte);
// msb check
if (Math::cmp('0x' . bin2hex($byte[0]), '0x80') >= 0) {
$byte = chr(0x00) . $byte;
}
$retval['bin_r'] = bin2hex($byte);
$seq = chr(0x02) . chr(strlen($byte)) . $byte;
$dec = Util::decodeHex($s);
$byte = '';
while (Math::cmp($dec, '0') > 0) {
$dv = Math::div($dec, '256');
$rem = Math::mod($dec, '256');
$dec = $dv;
$byte = $byte . $digits[$rem];
}
$byte = strrev($byte);
// msb check
if (Math::cmp('0x' . bin2hex($byte[0]), '0x80') >= 0) {
$byte = chr(0x00) . $byte;
}
$retval['bin_s'] = bin2hex($byte);
$seq = $seq . chr(0x02) . chr(strlen($byte)) . $byte;
$seq = chr(0x30) . chr(strlen($seq)) . $seq;
$retval['seq'] = bin2hex($seq);
return $retval;
}
/**
* Decodes PEM data to retrieve the keypair.
*
* @param string $pem_data The data to decode.
* @return array The keypair info.
* @throws \Exception
*/
public function pemDecode($pem_data)
{
$beg_ec_text = '-----BEGIN EC PRIVATE KEY-----';
$end_ec_text = '-----END EC PRIVATE KEY-----';
$decoded = '';
$ecpemstruct = array();
$pem_data = str_ireplace($beg_ec_text, '', $pem_data);
$pem_data = str_ireplace($end_ec_text, '', $pem_data);
$pem_data = str_ireplace("\r", '', trim($pem_data));
$pem_data = str_ireplace("\n", '', trim($pem_data));
$pem_data = str_ireplace(' ', '', trim($pem_data));
$decoded = bin2hex(base64_decode($pem_data));
if (strlen($decoded) < 230) {
throw new \Exception('Invalid or corrupt secp256k1 key provided. Cannot decode the supplied PEM data.');
}
$ecpemstruct = array(
'oct_sec_val' => substr($decoded, 14, 64),
'obj_id_val' => substr($decoded, 86, 10),
'bit_str_val' => substr($decoded, 106),
);
if ($ecpemstruct['obj_id_val'] != '2b8104000a') {
throw new \Exception('Invalid or corrupt secp256k1 key provided. Cannot decode the supplied PEM data.');
}
$private_key = $ecpemstruct['oct_sec_val'];
$public_key = $ecpemstruct['bit_str_val'];
if (strlen($private_key) < 64 || strlen($public_key) < 128) {
throw new \Exception('Invalid or corrupt secp256k1 key provided. Cannot decode the supplied PEM data.');
}
$this->pemDecoded = array('private_key' => $private_key, 'public_key' => $public_key);
return $this->pemDecoded;
}
/**
* Encodes keypair data to PEM format.
*
* @param array $keypair The keypair info.
* @return string The data to decode.
* @throws \Exception
*/
public function pemEncode($keypair)
{
if (is_array($keypair) && (strlen($keypair[0]) < 64 || strlen($keypair[1]) < 128)) {
throw new \Exception('Invalid or corrupt secp256k1 keypair provided. Cannot decode the supplied PEM data.');
}
$dec = '';
$byte = '';
$beg_ec_text = '';
$end_ec_text = '';
$ecpemstruct = array();
$digits = array();
for ($x = 0; $x < 256; $x++) {
$digits[$x] = chr($x);
}
$ecpemstruct = array(
'sequence_beg' => '30',
'total_len' => '74',
'int_sec_beg' => '02',
'int_sec_len' => '01',
'int_sec_val' => '01',
'oct_sec_beg' => '04',
'oct_sec_len' => '20',
'oct_sec_val' => $keypair[0],
'a0_ele_beg' => 'a0',
'a0_ele_len' => '07',
'obj_id_beg' => '06',
'obj_id_len' => '05',
'obj_id_val' => '2b8104000a',
'a1_ele_beg' => 'a1',
'a1_ele_len' => '44',
'bit_str_beg' => '03',
'bit_str_len' => '42',
'bit_str_val' => '00' . $keypair[1],
);
$beg_ec_text = '-----BEGIN EC PRIVATE KEY-----';
$end_ec_text = '-----END EC PRIVATE KEY-----';
$dec = trim(implode($ecpemstruct));
if (strlen($dec) < 230) {
throw new \Exception('Invalid or corrupt secp256k1 keypair provided. Cannot encode the supplied data.');
}
$dec = Util::decodeHex('0x' . $dec);
while (Math::cmp($dec, '0') > 0) {
$dv = Math::div($dec, '256');
$rem = Math::mod($dec, '256');
$dec = $dv;
$byte = $byte . $digits[$rem];
}
$byte = $beg_ec_text . "\r\n" . chunk_split(base64_encode(strrev($byte)), 64) . $end_ec_text;
$this->pemEncoded = $byte;
return $byte;
}
}
php-client/src/Bitpay/Network/NetworkInterface.php 0000755 00000001435 15250364036 0016254 0 ustar 00 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;
}
}
php-client/src/Bitpay/Network/Livenet.php 0000755 00000001023 15250364036 0014401 0 ustar 00 network = $network;
}
}
php-client/src/Bitpay/Network/Testnet.php 0000755 00000001047 15250364036 0014427 0 ustar 00 container = $container;
if (is_null($container)) {
$this->initializeContainer($config);
}
}
/**
* Initialize the container
*
* @param array|string $config
*/
protected function initializeContainer($config)
{
$this->container = $this->buildContainer($config);
$this->container->compile();
}
/**
* Build the container of services and parameters.
*
* @param array|string $config
* @return ContainerBuilder
*/
protected function buildContainer($config)
{
$container = new ContainerBuilder(new ParameterBag($this->getParameters()));
$this->prepareContainer($container);
$this->getContainerLoader($container)->load($config);
return $container;
}
/**
* @return array
*/
protected function getParameters()
{
return array(
'bitpay.root_dir' => realpath(__DIR__ . '/..'),
);
}
/**
* @param ContainerBuilder $container
*/
private function prepareContainer(ContainerBuilder $container)
{
foreach ($this->getDefaultExtensions() as $ext) {
$container->registerExtension($ext);
$container->loadFromExtension($ext->getAlias());
}
}
/**
* @param ContainerBuilder $container
* @return DelegatingLoader
*/
private function getContainerLoader(ContainerBuilder $container)
{
$locator = new FileLocator();
$resolver = new LoaderResolver(
array(
new ArrayLoader($container),
new YamlFileLoader($container, $locator),
)
);
return new DelegatingLoader($resolver);
}
/**
* Returns an array of the default extensions.
*
* @return BitpayExtension[]
*/
private function getDefaultExtensions()
{
return array(
new BitpayExtension(),
);
}
/**
* @return ContainerBuilder
*/
public function getContainer()
{
return $this->container;
}
/**
* @return object|null
*/
public function get($service)
{
return $this->container->get($service);
}
}
php-client/src/Bitpay/UserInterface.php 0000755 00000001622 15250364036 0014106 0 ustar 00 physical = false;
}
/**
* @inheritdoc
*/
public function getCode()
{
return $this->code;
}
/**
* @param string $code
* @return ItemInterface
*/
public function setCode($code)
{
$this->code = $code;
return $this;
}
/**
* @inheritdoc
*/
public function getDescription()
{
return $this->description;
}
/**
* @param string $description
* @return ItemInterface
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* @inheritdoc
*/
public function getPrice()
{
return $this->price;
}
/**
* @param mixed $price A float, integer, or en_US formatted numeric string
* @return Item
*/
public function setPrice($price)
{
if (is_string($price)) {
$this->checkPriceFormat($price);
}
$this->price = (float)$price;
return $this;
}
/**
* @inheritdoc
*/
public function getQuantity()
{
return $this->quantity;
}
/**
* @param integer $quantity
* @return Item
*/
public function setQuantity($quantity)
{
$this->quantity = $quantity;
return $this;
}
/**
* @inheritdoc
*/
public function isPhysical()
{
return $this->physical;
}
/**
* @param boolean $physical
* @return Item
*/
public function setPhysical($physical)
{
$this->physical = (boolean)$physical;
return $this;
}
/**
* Checks the new price to include BTC
* 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('[ERROR] In Item::checkPriceFormat(): Price value must be formatted as a float.');
}
}
}
php-client/src/Bitpay/PayoutInterface.php 0000755 00000010641 15250364036 0014452 0 ustar 00 container = $container;
}
public function load($resource, $type = null)
{
// validation
foreach (array_keys($resource) as $namespace) {
if (in_array($namespace, array('imports', 'paramters', 'services'))) {
continue;
}
if (!$this->container->hasExtension($namespace)) {
$extensionNamespaces = array_filter(
array_map(
function ($ext) {
return $ext->getAlias();
},
$this->container->getExtensions()
)
);
throw new InvalidArgumentException(sprintf(
'There is no extension able to load the configuration for "%s". Looked for namespace "%s", found %s',
$namespace,
$namespace,
$extensionNamespaces ? sprintf('"%s"', implode('", "', $extensionNamespaces)) : 'none'
));
}
}
// Set Paramters
if (isset($resource['parameters'])) {
foreach ($resource['parameters'] as $key => $value) {
$this->container->setParameter($key, $value);
}
}
// extensions
foreach ($resource as $namespace => $values) {
if (in_array($namespace, array('imports', 'parameters', 'services'))) {
continue;
}
if (!is_array($values)) {
$values = array();
}
$this->container->loadFromExtension($namespace, $values);
}
}
public function supports($resource, $type = null)
{
return is_array($resource);
}
}
php-client/src/Bitpay/DependencyInjection/BitpayExtension.php 0000755 00000003373 15250364036 0020422 0 ustar 00 processConfiguration(new Configuration(), $configs);
foreach (array_keys($config) as $key) {
$container->setParameter('bitpay.'.$key, $config[$key]);
}
$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'
);
$container->setParameter('key_storage.class', $config['key_storage']);
}
/**
* @codeCoverageIgnore
*/
public function getAlias()
{
return 'bitpay';
}
/**
* @codeCoverageIgnore
*/
public function getNamespace()
{
return 'http://example.org/schema/dic/bitpay';
}
/**
* @codeCoverageIgnore
*/
public function getXsdValidationBasePath()
{
return false;
}
}
php-client/src/Bitpay/DependencyInjection/services.xml 0000755 00000003512 15250364036 0017124 0 ustar 00
Bitpay\Network\Livenet
Bitpay\Client\Adapter\CurlAdapter
Bitpay\KeyManager
Bitpay\Storage\FilesystemStorage
%bitpay.key_storage_password%
%bitpay.public_key%
%bitpay.private_key%
php-client/src/Bitpay/Client/RequestInterface.php 0000755 00000003117 15250364036 0016037 0 ustar 00 $value array of http headers
*
* @return array
*/
public function getHeaders();
}
php-client/src/Bitpay/Client/ConnectionException.php 0000755 00000000366 15250364036 0016547 0 ustar 00 headers = array(
'Content-Type' => 'application/json',
'X-BitPay-Plugin-Info' => null,
);
$this->port = 443;
// Default method is POST
$this->method = self::METHOD_POST;
}
/**
* Converts this request into a standard HTTP/1.1 message to be sent over
* the wire.
*
* @return string
*/
public function __toString()
{
$request = sprintf("%s %s HTTP/1.1\r\n", $this->getMethod(), $this->getUriWithPort());
$request .= $this->getHeadersAsString();
$request .= $this->getBody();
return trim($request);
}
/**
* @inheritdoc
*/
public function isMethod($method)
{
return (strtoupper($method) == strtoupper($this->method));
}
/**
* @inheritdoc
*/
public function getPort()
{
return $this->port;
}
/**
* @inheritdoc
*/
public function setPort($port)
{
$this->port = $port;
}
/**
* @inheritdoc
*/
public function getMethod()
{
return $this->method;
}
/**
* Set the method of the request, for known methods see the
* RequestInterface.
*
* @param string $method
*/
public function setMethod($method)
{
$this->method = $method;
}
/**
* @inheritdoc
*/
public function getSchema()
{
return 'https';
}
/**
* @inheritdoc
*/
public function getUri()
{
return sprintf(
'%s://%s/%s',
$this->getSchema(),
$this->getHost(),
$this->getPath()
);
}
/**
* @inheritdoc
*/
public function getUriWithPort()
{
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
* @return Request
*/
public function setHost($host)
{
$this->host = $host;
return $this;
}
/**
* @inheritdoc
*/
public function getHeaders()
{
// remove invalid headers
$headers = $this->headers;
foreach ($headers as $header => $value) {
if (empty($header) || empty($value)) {
unset($headers[$header]);
}
}
return $headers;
}
/**
* @return array
*/
public function getHeaderFields()
{
$fields = array();
foreach ($this->getHeaders() as $header => $value) {
$fields[] = sprintf('%s: %s', $header, $value);
}
return $fields;
}
/**
* @return string
*/
public function getHeadersAsString()
{
$headers = $this->getHeaders();
$return = '';
foreach ($headers as $h => $v) {
$return .= sprintf("%s: %s\r\n", $h, $v);
}
return $return . "\r\n";
}
/**
* Set a http header for the request.
*
* @param string $header
* @param string $value
* @throws \Exception
*/
public function setHeader($header, $value)
{
if (is_array($value)) {
throw new \Exception('Could not set the header: ' . $header);
}
$this->headers[$header] = $value;
}
/**
* @inheritdoc
*/
public function getBody()
{
return $this->body;
}
/**
* Sets the body of the request.
*
* @param string $body
* @return Request
*/
public function setBody($body)
{
$this->body = $body;
$this->setHeader('Content-Length', strlen($body));
return $this;
}
/**
* @inheritdoc
*/
public function getPath()
{
return $this->path;
}
/**
* @param string $host
* @return Request
*/
public function setPath($path)
{
$this->path = $path;
return $this;
}
}
php-client/src/Bitpay/Client/Client.php 0000755 00000056564 15250364036 0014022 0 ustar 00 network = $network;
}
/**
* Set the Public Key to use to help identify who you are to BitPay. Please
* note that you must first pair your keys and get a token in return to use.
*
* @param PublicKey $key
*/
public function setPublicKey(PublicKey $key)
{
$this->publicKey = $key;
}
/**
* Set the Private Key to use, this is used when signing request strings
*
* @param PrivateKey $key
*/
public function setPrivateKey(PrivateKey $key)
{
$this->privateKey = $key;
}
/**
* Set the network adapter object to use.
*
* @param AdapterInterface $adapter
*/
public function setAdapter(AdapterInterface $adapter)
{
$this->adapter = $adapter;
}
/**
* Assigns the token to use for a request.
*
* @param TokenInterface $token
* @return ClientInterface
*/
public function setToken(TokenInterface $token)
{
$this->token = $token;
return $this;
}
/**
* @inheritdoc
*/
public function createInvoice(InvoiceInterface $invoice)
{
$request = $this->createNewRequest();
$request->setMethod(Request::METHOD_POST);
$request->setPath('invoices');
$currency = $invoice->getCurrency();
$item = $invoice->getItem();
$buyer = $invoice->getBuyer();
$buyerAddress = $buyer->getAddress();
$this->checkPriceAndCurrency($item->getPrice(), $currency->getCode());
$body = array(
'price' => $item->getPrice(),
'currency' => $currency->getCode(),
'posData' => $invoice->getPosData(),
'notificationURL' => $invoice->getNotificationUrl(),
'transactionSpeed' => $invoice->getTransactionSpeed(),
'fullNotifications' => $invoice->isFullNotifications(),
'notificationEmail' => $invoice->getNotificationEmail(),
'redirectURL' => $invoice->getRedirectUrl(),
'orderID' => $invoice->getOrderId(),
'itemDesc' => $item->getDescription(),
'itemCode' => $item->getCode(),
'physical' => $item->isPhysical(),
'buyerName' => trim(sprintf('%s %s', $buyer->getFirstName(), $buyer->getLastName())),
'buyerAddress1' => isset($buyerAddress[0]) ? $buyerAddress[0] : '',
'buyerAddress2' => isset($buyerAddress[1]) ? $buyerAddress[1] : '',
'buyerCity' => $buyer->getCity(),
'buyerState' => $buyer->getState(),
'buyerZip' => $buyer->getZip(),
'buyerCountry' => $buyer->getCountry(),
'buyerEmail' => $buyer->getEmail(),
'buyerPhone' => $buyer->getPhone(),
'guid' => Util::guid(),
'token' => $this->token->getToken(),
);
$request->setBody(json_encode($body));
$this->addIdentityHeader($request);
$this->addSignatureHeader($request);
$this->request = $request;
$this->response = $this->sendRequest($request);
$body = json_decode($this->response->getBody(), true);
$error_message = false;
$error_message = (!empty($body['error'])) ? $body['error'] : $error_message;
$error_message = (!empty($body['errors'])) ? $body['errors'] : $error_message;
$error_message = (is_array($error_message)) ? implode("\n", $error_message) : $error_message;
if (false !== $error_message) {
throw new \Exception($error_message);
}
$data = $body['data'];
$invoiceToken = new \Bitpay\Token();
$paymentUrls = new \Bitpay\PaymentUrlSet();
$invoice
->setToken($invoiceToken->setToken($data['token']))
->setId($data['id'])
->setUrl($data['url'])
->setStatus($data['status'])
->setBtcPrice($data['btcPrice'])
->setPrice($data['price'])
->setInvoiceTime($data['invoiceTime'] / 1000)
->setExpirationTime($data['expirationTime'] / 1000)
->setCurrentTime($data['currentTime'] / 1000)
->setBtcPaid($data['btcPaid'])
->setRate($data['rate'])
->setExceptionStatus($data['exceptionStatus'])
->setPaymentUrls($paymentUrls->setUrls($data['paymentUrls']));
return $invoice;
}
/**
* @inheritdoc
*/
public function getCurrencies()
{
$this->request = $this->createNewRequest();
$this->request->setMethod(Request::METHOD_GET);
$this->request->setPath('currencies');
$this->response = $this->sendRequest($this->request);
$body = json_decode($this->response->getBody(), true);
if (empty($body['data'])) {
throw new \Exception('Error with request: no data returned');
}
$currencies = $body['data'];
array_walk($currencies, function (&$value, $key) {
$currency = new \Bitpay\Currency();
$currency
->setCode($value['code'])
->setSymbol($value['symbol'])
->setPrecision($value['precision'])
->setExchangePctFee($value['exchangePctFee'])
->setPayoutEnabled($value['payoutEnabled'])
->setName($value['name'])
->setPluralName($value['plural'])
->setAlts($value['alts'])
->setPayoutFields($value['payoutFields']);
$value = $currency;
});
return $currencies;
}
/**
* @inheritdoc
*/
public function createPayout(PayoutInterface $payout)
{
$request = $this->createNewRequest();
$request->setMethod($request::METHOD_POST);
$request->setPath('payouts');
$amount = $payout->getAmount();
$currency = $payout->getCurrency();
$effectiveDate = $payout->getEffectiveDate();
$token = $payout->getToken();
$body = array(
'token' => $token->getToken(),
'amount' => $amount,
'currency' => $currency->getCode(),
'instructions' => array(),
'effectiveDate' => $effectiveDate,
'pricingMethod' => $payout->getPricingMethod(),
'guid' => Util::guid(),
);
// Optional
foreach (array('reference','notificationURL','notificationEmail') as $value) {
$function = 'get' . ucfirst($value);
if ($payout->$function() != null) {
$body[$value] = $payout->$function();
}
}
// Add instructions
foreach ($payout->getInstructions() as $instruction) {
$body['instructions'][] = array(
'label' => $instruction->getLabel(),
'address' => $instruction->getAddress(),
'amount' => $instruction->getAmount()
);
}
$request->setBody(json_encode($body));
$this->addIdentityHeader($request);
$this->addSignatureHeader($request);
$this->request = $request;
$this->response = $this->sendRequest($request);
$body = json_decode($this->response->getBody(), true);
$error_message = false;
$error_message = (!empty($body['error'])) ? $body['error'] : $error_message;
$error_message = (!empty($body['errors'])) ? $body['errors'] : $error_message;
$error_message = (is_array($error_message)) ? implode("\n", $error_message) : $error_message;
if (false !== $error_message) {
throw new \Exception($error_message);
}
$data = $body['data'];
$payout
->setId($data['id'])
->setAccountId($data['account'])
->setResponseToken($data['token'])
->setStatus($data['status']);
foreach ($data['instructions'] as $c => $instruction) {
$payout->updateInstruction($c, 'setId', $instruction['id']);
}
return $payout;
}
/**
* @inheritdoc
*/
public function getPayouts($status = null)
{
$request = $this->createNewRequest();
$request->setMethod(Request::METHOD_GET);
$path = 'payouts?token='
. $this->token->getToken()
. (($status == null) ? '' : '&status=' . $status);
$request->setPath($path);
$this->addIdentityHeader($request);
$this->addSignatureHeader($request);
$this->request = $request;
$this->response = $this->sendRequest($this->request);
$body = json_decode($this->response->getBody(), true);
$error_message = false;
$error_message = (!empty($body['error'])) ? $body['error'] : $error_message;
$error_message = (!empty($body['errors'])) ? $body['errors'] : $error_message;
$error_message = (is_array($error_message)) ? implode("\n", $error_message) : $error_message;
if (false !== $error_message) {
throw new \Exception($error_message);
}
$payouts = array();
array_walk($body['data'], function ($value, $key) use (&$payouts) {
$payout = new \Bitpay\Payout();
$payout
->setId($value['id'])
->setAccountId($value['account'])
->setCurrency(new \Bitpay\Currency($value['currency']))
->setEffectiveDate($value['effectiveDate'])
->setRequestdate($value['requestDate'])
->setPricingMethod($value['pricingMethod'])
->setStatus($value['status'])
->setAmount($value['amount'])
->setResponseToken($value['token'])
->setRate(@$value['rate'])
->setBtcAmount(@$value['btc'])
->setReference(@$value['reference'])
->setNotificationURL(@$value['notificationURL'])
->setNotificationEmail(@$value['notificationEmail']);
array_walk($value['instructions'], function ($value, $key) use (&$payout) {
$instruction = new \Bitpay\PayoutInstruction();
$instruction
->setId($value['id'])
->setLabel($value['label'])
->setAddress($value['address'])
->setAmount($value['amount'])
->setStatus($value['status']);
array_walk($value['transactions'], function ($value, $key) use (&$instruction) {
$transaction = new \Bitpay\PayoutTransaction();
$transaction
->setTransactionId($value['txid'])
->setAmount($value['amount'])
->setDate($value['date']);
$instruction->addTransaction($transaction);
});
$payout->addInstruction($instruction);
});
$payouts[] = $payout;
});
return $payouts;
}
/**
* @inheritdoc
*/
public function deletePayout(PayoutInterface $payout)
{
$request = $this->createNewRequest();
$request->setMethod(Request::METHOD_DELETE);
$request->setPath(sprintf('payouts/%s?token=%s', $payout->getId(), $payout->getResponseToken()));
$this->addIdentityHeader($request);
$this->addSignatureHeader($request);
$this->request = $request;
$this->response = $this->sendRequest($this->request);
$body = json_decode($this->response->getBody(), true);
if (empty($body['data'])) {
throw new \Exception('Error with request: no data returned');
}
$data = $body['data'];
$payout->setStatus($data['status']);
return $payout;
}
/**
* @inheritdoc
*/
public function getPayout($payoutId)
{
$request = $this->createNewRequest();
$request->setMethod(Request::METHOD_GET);
$request->setPath(sprintf('payouts/%s?token=%s', $payoutId, $this->token->getToken()));
$this->addIdentityHeader($request);
$this->addSignatureHeader($request);
$this->request = $request;
$this->response = $this->sendRequest($this->request);
$body = json_decode($this->response->getBody(), true);
if (empty($body['data'])) {
throw new \Exception('Error with request: no data returned');
}
$data = $body['data'];
$payout = new \Bitpay\Payout();
$payout
->setId($data['id'])
->setAccountId($data['account'])
->setStatus($data['status'])
->setCurrency(new \Bitpay\Currency($data['currency']))
->setRate(@$data['rate'])
->setAmount($data['amount'])
->setBtcAmount(@$data['btc'])
->setPricingMethod(@$data['pricingMethod'])
->setReference(@$data['reference'])
->setNotificationEmail(@$data['notificationEmail'])
->setNotificationUrl(@$data['notificationURL'])
->setRequestDate($data['requestDate'])
->setEffectiveDate($data['effectiveDate'])
->setResponseToken($data['token']);
array_walk($data['instructions'], function ($value, $key) use (&$payout) {
$instruction = new \Bitpay\PayoutInstruction();
$instruction
->setId($value['id'])
->setLabel($value['label'])
->setAddress($value['address'])
->setStatus($value['status'])
->setAmount($value['amount'])
->setBtc($value['btc']);
array_walk($value['transactions'], function ($value, $key) use (&$instruction) {
$transaction = new \Bitpay\PayoutTransaction();
$transaction
->setTransactionId($value['txid'])
->setAmount($value['amount'])
->setDate($value['date']);
$instruction->addTransaction($transaction);
});
$payout->addInstruction($instruction);
});
return $payout;
}
/**
* @inheritdoc
*/
public function getTokens()
{
$request = $this->createNewRequest();
$request->setMethod(Request::METHOD_GET);
$request->setPath('tokens');
$this->addIdentityHeader($request);
$this->addSignatureHeader($request);
$this->request = $request;
$this->response = $this->sendRequest($this->request);
$body = json_decode($this->response->getBody(), true);
if (empty($body['data'])) {
throw new \Exception('Error with request: no data returned');
}
$tokens = array();
array_walk($body['data'], function ($value, $key) use (&$tokens) {
$key = current(array_keys($value));
$value = current(array_values($value));
$token = new \Bitpay\Token();
$token
->setFacade($key)
->setToken($value);
$tokens[$token->getFacade()] = $token;
});
return $tokens;
}
/**
* @inheritdoc
*/
public function createToken(array $payload = array())
{
if (isset($payload['pairingCode']) && 1 !== preg_match('/^[a-zA-Z0-9]{7}$/', $payload['pairingCode'])) {
throw new \Exception('[ERROR] In Client::createToken(): The pairing code provided is not legal.');
}
$this->request = $this->createNewRequest();
$this->request->setMethod(Request::METHOD_POST);
$this->request->setPath('tokens');
$payload['guid'] = Util::guid();
$this->request->setBody(json_encode($payload));
$this->response = $this->sendRequest($this->request);
$body = json_decode($this->response->getBody(), true);
if (isset($body['error'])) {
throw new \Bitpay\Client\BitpayException($this->response->getStatusCode() . ': ' . $body['error']);
}
$tkn = $body['data'][0];
$createdAt = new \DateTime();
$pairingExpiration = new \DateTime();
$token = new \Bitpay\Token();
$token
->setPolicies($tkn['policies'])
->setToken($tkn['token'])
->setFacade($tkn['facade'])
->setCreatedAt($createdAt->setTimestamp(floor($tkn['dateCreated'] / 1000)));
if (isset($tkn['resource'])) {
$token->setResource($tkn['resource']);
}
if (isset($tkn['pairingCode'])) {
$token->setPairingCode($tkn['pairingCode']);
$token->setPairingExpiration($pairingExpiration->setTimestamp(floor($tkn['pairingExpiration'] / 1000)));
}
return $token;
}
/**
* Returns the Response object that BitPay returned from
* the request that was sent.
*
* @return ResponseInterface
*/
public function getResponse()
{
return $this->response;
}
/**
* Returns the request object that was sent to BitPay.
*
* @return RequestInterface
*/
public function getRequest()
{
return $this->request;
}
/**
* @inheritdoc
*/
public function getInvoice($invoiceId)
{
$this->request = $this->createNewRequest();
$this->request->setMethod(Request::METHOD_GET);
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);
} else {
$this->request->setPath(sprintf('invoices/%s', $invoiceId));
}
$this->response = $this->sendRequest($this->request);
$body = json_decode($this->response->getBody(), true);
if (isset($body['error'])) {
throw new \Exception($body['error']);
}
$data = $body['data'];
$invoice = new \Bitpay\Invoice();
$invoiceToken = new \Bitpay\Token();
$paymentUrls = new \Bitpay\PaymentUrlSet();
$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'] / 1000)
->setExpirationTime($data['expirationTime'] / 1000)
->setCurrentTime($data['currentTime'] / 1000)
->setId($data['id'])
->setBtcPaid($data['btcPaid'])
->setRate($data['rate'])
->setExceptionStatus($data['exceptionStatus']);
if (isset($data['paymentUrls'])) {
$invoice
->setPaymentUrls($paymentUrls->setUrls($data['paymentUrls']));
}
return $invoice;
}
/**
* @param RequestInterface $request
* @return ResponseInterface
*/
public function sendRequest(RequestInterface $request)
{
if (null === $this->adapter) {
// Uses the default adapter
$this->adapter = new \Bitpay\Client\Adapter\CurlAdapter();
}
return $this->adapter->sendRequest($request);
}
/**
* @param RequestInterface $request
* @throws \Exception
*/
protected function addIdentityHeader(RequestInterface $request)
{
if (null === $this->publicKey) {
throw new \Exception('[ERROR] In Client::addIdentityHeader(): No public key value found. Please set your kublic key first before you can add the x-identity header.');
}
$request->setHeader('x-identity', (string) $this->publicKey);
}
/**
* @param RequestInterface $request
* @throws \Exception
*/
protected function addSignatureHeader(RequestInterface $request)
{
if (null === $this->privateKey) {
throw new \Exception('Please set your Private Key');
}
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',
$url,
$request->getBody()
);
$signature = $this->privateKey->sign($message);
$request->setHeader('x-signature', $signature);
}
/**
* @return RequestInterface
*/
protected function createNewRequest()
{
$request = new Request();
$request->setHost($this->network->getApiHost());
$request->setPort($this->network->getApiPort());
$this->prepareRequestHeaders($request);
return $request;
}
/**
* Prepares the request object by adding additional headers
*
* @see http://en.wikipedia.org/wiki/User_agent
* @param RequestInterface $request
*/
protected function prepareRequestHeaders(RequestInterface $request)
{
$request->setHeader(
'User-Agent',
sprintf('%s/%s (PHP %s)', self::NAME, self::VERSION, phpversion())
);
$request->setHeader('X-BitPay-Plugin-Info', sprintf('%s/%s', self::NAME, self::VERSION));
$request->setHeader('Content-Type', 'application/json');
$request->setHeader('X-Accept-Version', '2.0.0');
}
/**
* @param string $price
* @param string $currency
* @throws \Exception
*/
protected function checkPriceAndCurrency($price, $currency)
{
// Get the decimal precision of the price
$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.');
}
}
}
php-client/src/Bitpay/Client/Response.php 0000755 00000005265 15250364036 0014372 0 ustar 00 headers = array();
$this->raw = $raw;
}
/**
* Returns the raw http response
*
* @return string
*/
public function __toString()
{
return (string)$this->raw;
}
/**
* @param Response
*/
public static function createFromRawResponse($rawResponse)
{
$response = new self($rawResponse);
$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], ':')) {
$headerParts = explode(':', $lines[$i]);
$response->setHeader($headerParts[0], $headerParts[1]);
}
}
return $response;
}
/**
* @inheritdoc
*/
public function getStatusCode()
{
return $this->statusCode;
}
/**
* @param integer
* @return Response
*/
public function setStatusCode($statusCode)
{
$this->statusCode = (integer)$statusCode;
return $this;
}
/**
* @inheritdoc
*/
public function getBody()
{
return $this->body;
}
/**
* Set the body of the response
*
* @param string $body
* @return Response
*/
public function setBody($body)
{
$this->body = $body;
return $this;
}
/**
* @inheritdoc
*/
public function getHeaders()
{
return $this->headers;
}
/**
* @param string $header
* @param string $value
* @return Response
*/
public function setHeader($header, $value)
{
$this->headers[$header] = $value;
return $this;
}
}
php-client/src/Bitpay/Client/ClientInterface.php 0000755 00000003513 15250364036 0015625 0 ustar 00 curlOptions = $curlOptions;
}
/**
* Returns an array of cURL settings to use
*
* @return array
*/
public function getCurlOptions()
{
return $this->curlOptions;
}
/**
* @inheritdoc
*/
public function sendRequest(\Bitpay\Client\Request $request)
{
$curl = curl_init();
if ($curl === false) {
throw new \Exception('[ERROR] In CurlAdapter::sendRequest(): Could not initialize cURL.');
}
$default_curl_options = $this->getCurlDefaultOptions($request);
foreach ($this->getCurlOptions() as $curl_option_key => $curl_option_value) {
if (is_null($curl_option_value) === false) {
$default_curl_options[$curl_option_key] = $curl_option_value;
}
}
curl_setopt_array($curl, $default_curl_options);
if (RequestInterface::METHOD_POST == $request->getMethod()) {
curl_setopt_array(
$curl,
array(
CURLOPT_POST => 1,
CURLOPT_POSTFIELDS => $request->getBody(),
)
);
}
$raw = curl_exec($curl);
if ($raw === false) {
$errorMessage = curl_error($curl);
curl_close($curl);
throw new \Exception('[ERROR] In CurlAdapter::sendRequest(): curl_exec failed with the error "' . $errorMessage . '".');
}
/** @var Response */
$response = Response::createFromRawResponse($raw);
curl_close($curl);
return $response;
}
/**
* Returns an array of default cURL settings to use.
*
* @param \Bitpay\Client\Request $request
* @return array
*/
private function getCurlDefaultOptions(\Bitpay\Client\Request $request)
{
return array(
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,
CURLOPT_HEADER => true,
);
}
}
php-client/src/Bitpay/Client/ResponseInterface.php 0000755 00000001061 15250364036 0016201 0 ustar 00 $value array of http headers
*
* @return array
*/
public function getHeaders();
}
php-client/src/Bitpay/Client/BitpayException.php 0000755 00000000364 15250364036 0015676 0 ustar 00 Permission is hereby granted, free of charge, to any person obtaining a copy
> of this software and associated documentation files (the "Software"), to deal
> in the Software without restriction, including without limitation the rights
> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> copies of the Software, and to permit persons to whom the Software is
> furnished to do so, subject to the following conditions:
>
> The above copyright notice and this permission notice shall be included in
> all copies or substantial portions of the Software.
>
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
> THE SOFTWARE.