diff --git a/app/code/community/Bitpay/Bitcoins/Helper/Data.php b/app/code/community/Bitpay/Bitcoins/Helper/Data.php
index 1b5c7f8..4d0072d 100644
--- a/app/code/community/Bitpay/Bitcoins/Helper/Data.php
+++ b/app/code/community/Bitpay/Bitcoins/Helper/Data.php
@@ -3,7 +3,7 @@
/**
* The MIT License (MIT)
*
- * Copyright (c) 2011-2014 BitPay LLC
+ * Copyright (c) 2011-2014 BitPay, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -67,4 +67,107 @@ class Bitpay_Bitcoins_Helper_Data extends Mage_Core_Helper_Abstract
return !empty($speed);
}
+
+ /**
+ * This method is used to removed IPN records in the database that
+ * are expired and update the magento orders to canceled if they have
+ * expired.
+ */
+ public function cleanExpired()
+ {
+ $expiredRecords = Mage::getModel('Bitcoins/ipn')->getExpired();
+
+ foreach ($expiredRecords as $ipn) {
+ $incrementId = $ipn->getOrderId();
+ if (empty($incrementId)) {
+ $this->logIpnParseError($ipn);
+ continue;
+ }
+
+ // Cancel the order
+ $order = Mage::getModel('sales/order')->loadByIncrementId($incrementId);
+ $this->cancelOrder($order);
+
+ // Delete all IPN records for order id
+ Mage::getModel('Bitcoins/ipn')
+ ->deleteByOrderId($ipn->getOrderId());
+ Mage::log(
+ sprintf('Deleted Record: %s', $ipn->toJson()),
+ Zend_Log::DEBUG,
+ self::LOG_FILE
+ );
+ }
+ }
+
+ /**
+ * Log error if there is an issue parsing an IPN record
+ *
+ * @param Bitpay_Bitcoins_Model_Ipn $ipn
+ * @param boolean $andDelete
+ */
+ private function logIpnParseError(Bitpay_Bitcoins_Model_Ipn $ipn, $andDelete = true)
+ {
+ Mage::log(
+ 'Error processing IPN record',
+ Zend_Log::DEBUG,
+ self::LOG_FILE
+ );
+ Mage::log(
+ $ipn->toJson(),
+ Zend_Log::DEBUG,
+ self::LOG_FILE
+ );
+
+ if ($andDelete) {
+ $ipn->delete();
+ Mage::log(
+ 'IPN record deleted from database',
+ Zend_Log::DEBUG,
+ self::LOG_FILE
+ );
+ }
+ }
+
+ /**
+ * This will cancel the order in the magento database, this will return
+ * true if the order was canceled or it will return false if the order
+ * was not updated. For example, if the order is complete, we don't want
+ * to cancel that order so this method would return false.
+ *
+ * @param Mage_Sales_Model_Order
+ *
+ * @return boolean
+ */
+ private function cancelOrder(Mage_Sales_Model_Order $order)
+ {
+ $orderState = $order->getState();
+
+ /**
+ * These order states are useless and can just be skipped over. No
+ * need to cancel an order that is alread canceled.
+ */
+ $statesWeDontCareAbout = array(
+ Mage_Sales_Model_Order::STATE_CANCELED,
+ Mage_Sales_Model_Order::STATE_CLOSED,
+ Mage_Sales_Model_Order::STATE_COMPLETE,
+ );
+
+ if (in_array($orderState, $statesWeDontCareAbout)) {
+ return false;
+ }
+
+ $order->setState(
+ Mage_Sales_Model_Order::STATE_CANCELED,
+ true,
+ 'BitPay Invoice has expired', // Comment
+ false // notifiy customer?
+ )->save();
+ Mage::log(
+ sprintf('Order "%s" has been canceled', $order->getIncrementId()),
+ Zend_Log::DEBUG,
+ self::LOG_FILE
+ );
+
+ return true;
+ }
}
diff --git a/app/code/community/Bitpay/Bitcoins/Model/Ipn.php b/app/code/community/Bitpay/Bitcoins/Model/Ipn.php
index 37b61f2..d84012f 100644
--- a/app/code/community/Bitpay/Bitcoins/Model/Ipn.php
+++ b/app/code/community/Bitpay/Bitcoins/Model/Ipn.php
@@ -31,9 +31,8 @@ class Bitpay_Bitcoins_Model_Ipn extends Mage_Core_Model_Abstract
*/
function _construct()
{
+ parent::_construct();
$this->_init('Bitcoins/ipn');
-
- return parent::_construct();
}
/**
@@ -133,4 +132,125 @@ class Bitpay_Bitcoins_Model_Ipn extends Mage_Core_Model_Abstract
{
return $this->GetStatusReceived($quoteId, array('confirmed', 'complete'));
}
+
+ /**
+ * This method returns an array of orders in the database that have paid
+ * using bitcoins, but are still open and we need to query the invoice
+ * IDs at BitPay and see if they invoice has expired, is invalid, or is
+ * complete.
+ *
+ * @return array
+ */
+ public function getOpenOrders()
+ {
+ $doneCollection = $this->getCollection();
+
+ /**
+ * Get all the IPNs that have been completed
+ *
+ * SELECT
+ * order_id
+ * FROM
+ * bitpay_ipns
+ * WHERE
+ * status IN ('completed','invalid','expired') AND order_id IS NOT NULL
+ * GROUP BY
+ * order_id
+ */
+ $doneCollection
+ ->addFieldToSelect('order_id')
+ ->addFieldToFilter(
+ 'status',
+ array(
+ 'in' => array(
+ 'complete',
+ 'invalid',
+ 'expired',
+ )
+ )
+ );
+ $doneCollection
+ ->getSelect()
+ ->where('order_id IS NOT NULL')
+ ->group('order_id');
+
+ $collection = $this->getCollection();
+
+ /**
+ * Get all the open orders that have not received a IPN that closes
+ * the invoice.
+ *
+ * SELECT
+ * *
+ * FROM
+ * bitpay_ipns
+ * JOIN
+ * 'sales/order' ON bitpay_ipns.order_id='sales/order'.increment_id
+ * WHERE
+ * order_id NOT IN (?) AND order_id IS NOT NULL
+ * GROUP BY
+ * order_id
+ */
+ if (0 < $doneCollection->count()) {
+ $collection
+ ->addFieldToFilter(
+ 'status',
+ array(
+ 'in' => $doneCollection->getColumnValues('order_id')
+ )
+ );
+ }
+
+ $collection
+ ->getSelect()
+ ->where('order_id IS NOT NULL')
+ ->group('order_id');
+
+ return $collection->getItems();
+ }
+
+ /**
+ * Returns all records that have expired
+ */
+ public function getExpired()
+ {
+ $collection = $this->getCollection();
+ $now = new DateTime('now', new DateTimezone('UTC'));
+
+ $collection
+ ->removeFieldFromSelect('status')
+ ->addFieldToFilter(
+ 'expiration_time',
+ array(
+ 'lteq' => $now->getTimestamp()
+ )
+ );
+
+ $collection
+ ->getSelect()
+ ->group('order_id')
+ // Newest to oldest
+ ->order('expiration_time DESC');
+
+ return $collection->getItems();
+ }
+
+ /**
+ * This will delete all records that match the order id (order id is also
+ * the increment id of the magento order)
+ *
+ * @see Bitpay_Bitcoins_Model_Resource_Ipn_Collection::delete()
+ *
+ * @param string $orderId
+ */
+ public function deleteByOrderId($orderId)
+ {
+ $collection = Mage::getModel('Bitcoins/ipn')
+ ->getCollection();
+ $collection
+ ->getSelect()
+ ->where('order_id = ?', $orderId);
+
+ $collection->delete();
+ }
}
diff --git a/app/code/community/Bitpay/Bitcoins/Model/Observer.php b/app/code/community/Bitpay/Bitcoins/Model/Observer.php
new file mode 100644
index 0000000..781e281
--- /dev/null
+++ b/app/code/community/Bitpay/Bitcoins/Model/Observer.php
@@ -0,0 +1,95 @@
+getLogFile()
+ );
+
+ $apiKey = Mage::getStoreConfig('payment/Bitcoins/api_key');
+
+ if (empty($apiKey)) {
+ Mage::log(
+ 'cronjob: Api Key not set.',
+ Zend_Log::ERR,
+ Mage::helper('bitpay')->getLogFile()
+ );
+ return; // Api Key needs to be set
+ }
+
+
+ /**
+ * Get all of the orders that are open and have not received an IPN for
+ * complete, expired, or invalid.
+ *
+ * If anyone knows of a better way to do this, please let me know
+ */
+ $orders = Mage::getModel('Bitcoins/ipn')->getOpenOrders();
+
+ /**
+ * Get all orders that have been paid using bitpay and
+ * are not complete/closed/etc
+ */
+ foreach ($orders as $order) {
+ /**
+ * Query BitPay with the invoice ID to get the status. We must take
+ * care not to anger the API limiting gods and disable our access
+ * to the API.
+ */
+ $status = null;
+
+ // Does the order need to be updated?
+ // Yes? Update Order Status
+ // No? continue
+ }
+
+ Mage::log(
+ 'cronjob: end',
+ Zend_Log::DEBUG,
+ Mage::helper('bitpay')->getLogFile()
+ );
+ }
+
+ /**
+ * Method that is called via the magento cron to update orders if the
+ * invoice has expired
+ */
+ public function cleanExpired()
+ {
+ Mage::helper('bitpay')->cleanExpired();
+ }
+}
diff --git a/app/code/community/Bitpay/Bitcoins/Model/Resource/Ipn.php b/app/code/community/Bitpay/Bitcoins/Model/Resource/Ipn.php
index f4c53f3..2df09ee 100644
--- a/app/code/community/Bitpay/Bitcoins/Model/Resource/Ipn.php
+++ b/app/code/community/Bitpay/Bitcoins/Model/Resource/Ipn.php
@@ -3,7 +3,7 @@
/**
* The MIT License (MIT)
*
- * Copyright (c) 2011-2014 BitPay LLC
+ * Copyright (c) 2011-2014 BitPay, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -24,7 +24,7 @@
* THE SOFTWARE.
*/
-class Bitpay_Bitcoins_Model_Resource_Ipn extends Mage_Core_Model_Resource_Db_Abstract
+class Bitpay_Bitcoins_Model_Resource_Ipn extends Mage_Core_Model_Mysql4_Abstract
{
protected function _construct()
{
diff --git a/app/code/community/Bitpay/Bitcoins/Model/Resource/Ipn/Collection.php b/app/code/community/Bitpay/Bitcoins/Model/Resource/Ipn/Collection.php
index 3821a8c..b5b563a 100644
--- a/app/code/community/Bitpay/Bitcoins/Model/Resource/Ipn/Collection.php
+++ b/app/code/community/Bitpay/Bitcoins/Model/Resource/Ipn/Collection.php
@@ -3,7 +3,7 @@
/**
* The MIT License (MIT)
*
- * Copyright (c) 2011-2014 BitPay LLC
+ * Copyright (c) 2011-2014 BitPay, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -24,13 +24,21 @@
* THE SOFTWARE.
*/
-class Bitpay_Bitcoins_Model_Resource_Ipn_Collection extends Mage_Core_Model_Resource_Db_Collection_Abstract
+class Bitpay_Bitcoins_Model_Resource_Ipn_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract
{
/**
*/
protected function _construct()
{
+ parent::_construct();
$this->_init('Bitcoins/ipn');
}
+
+ public function delete()
+ {
+ foreach ($this->getItems() as $item) {
+ $item->delete();
+ }
+ }
}
diff --git a/app/code/community/Bitpay/Bitcoins/etc/config.xml b/app/code/community/Bitpay/Bitcoins/etc/config.xml
index 5d8a452..e669244 100644
--- a/app/code/community/Bitpay/Bitcoins/etc/config.xml
+++ b/app/code/community/Bitpay/Bitcoins/etc/config.xml
@@ -1,118 +1,136 @@
-
-
-
-
-
-
-
-
- Bitpay_Bitcoins
- bitpay_callback
-
-
-
-
-
-
- bitcoins.xml
-
-
-
-
-
-
-
-
- 1.1.0
-
-
-
-
-
-
- Bitpay_Bitcoins_Block
-
-
-
-
-
- Bitpay_Bitcoins_Helper
-
-
-
-
-
- Bitpay_Bitcoins_Model
- Bitcoins_resource
-
-
- Bitpay_Bitcoins_Model_Resource
-
-
-
-
-
-
-
-
-
-
-
-
- Bitpay_Bitcoins
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 1
- Bitcoins/paymentMethod
- Bitcoins
- low
- 0
- BTC, USD, EUR, GBP, JPY, CAD, AUD, CNY, CHF, SEK, NZD, KRW, AED, AFN, ALL, AMD, ANG, AOA, ARS, AWG, AZN, BAM, BBD, BDT, BGN, BHD, BIF, BMD, BND, BOB, BRL, BSD, BTN, BWP, BYR, BZD, CDF, CLF, CLP, COP, CRC, CVE, CZK, DJF, DKK, DOP, DZD, EEK, EGP, ETB, FJD, FKP, GEL, GHS, GIP, GMD, GNF, GTQ, GYD, HKD, HNL, HRK, HTG, HUF, IDR, ILS, INR, IQD, ISK, JEP, JMD, JOD, KES, KGS, KHR, KMF, KWD, KYD, KZT, LAK, LBP, LKR, LRD, LSL, LTL, LVL, LYD, MAD, MDL, MGA, MKD, MMK, MNT, MOP, MRO, MUR, MVR, MWK, MXN, MYR, MZN, NAD, NGN, NIO, NOK, NPR, OMR, PAB, PEN, PGK, PHP, PKR, PLN, PYG, QAR, RON, RSD, RUB, RWF, SAR, SBD, SCR, SDG, SGD, SHP, SLL, SOS, SRD, STD, SVC, SYP, SZL, THB, TJS, TMT, TND, TOP, TRY, TTD, TWD, TZS, UAH, UGX, UYU, UZS, VEF, VND, VUV, WST, XAF, XAG, XAU, XCD, XOF, XPF, YER, ZAR, ZMW, ZWL
- authorize
-
-
-
-
+
+
+
+
+
+
+
+
+ Bitpay_Bitcoins
+ bitpay_callback
+
+
+
+
+
+
+ bitcoins.xml
+
+
+
+
+
+
+
+
+ 1.1.0
+
+
+
+
+
+
+ Bitpay_Bitcoins_Block
+
+
+
+
+
+ Bitpay_Bitcoins_Helper
+
+
+
+
+
+ Bitpay_Bitcoins_Model
+ Bitcoins_resource
+
+
+ Bitpay_Bitcoins_Model_Resource
+
+
+
+
+
+
+
+
+
+
+
+
+ Bitpay_Bitcoins
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ */30 * * * *
+
+
+ Bitcoins/Observer::cleanExpired
+
+
+
+
+
+
+
+
+ 1
+ Bitcoins/paymentMethod
+ Bitcoins
+ low
+ 0
+ BTC, USD, EUR, GBP, JPY, CAD, AUD, CNY, CHF, SEK, NZD, KRW, AED, AFN, ALL, AMD, ANG, AOA, ARS, AWG, AZN, BAM, BBD, BDT, BGN, BHD, BIF, BMD, BND, BOB, BRL, BSD, BTN, BWP, BYR, BZD, CDF, CLF, CLP, COP, CRC, CVE, CZK, DJF, DKK, DOP, DZD, EEK, EGP, ETB, FJD, FKP, GEL, GHS, GIP, GMD, GNF, GTQ, GYD, HKD, HNL, HRK, HTG, HUF, IDR, ILS, INR, IQD, ISK, JEP, JMD, JOD, KES, KGS, KHR, KMF, KWD, KYD, KZT, LAK, LBP, LKR, LRD, LSL, LTL, LVL, LYD, MAD, MDL, MGA, MKD, MMK, MNT, MOP, MRO, MUR, MVR, MWK, MXN, MYR, MZN, NAD, NGN, NIO, NOK, NPR, OMR, PAB, PEN, PGK, PHP, PKR, PLN, PYG, QAR, RON, RSD, RUB, RWF, SAR, SBD, SCR, SDG, SGD, SHP, SLL, SOS, SRD, STD, SVC, SYP, SZL, THB, TJS, TMT, TND, TOP, TRY, TTD, TWD, TZS, UAH, UGX, UYU, UZS, VEF, VND, VUV, WST, XAF, XAG, XAU, XCD, XOF, XPF, YER, ZAR, ZMW, ZWL
+ authorize
+
+
+
+
diff --git a/build.xml b/build.xml
index 72738c1..34e324b 100644
--- a/build.xml
+++ b/build.xml
@@ -123,6 +123,15 @@
-->
+
+
+
+
+
+
+
+
+
@@ -206,7 +215,8 @@
-
+
+
@@ -220,22 +230,31 @@
-
+
-
+
-
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/build/phpunit.xml.dist b/build/phpunit.xml.dist
index 9898031..03a3d1a 100644
--- a/build/phpunit.xml.dist
+++ b/build/phpunit.xml.dist
@@ -46,7 +46,10 @@
../app/code/community/Bitpay/Bitcoins/
- ../lib/bitpay
+ ../shell
+
+ ../app/code/community/Bitpay/Bitcoins/sql
+
diff --git a/composer.json b/composer.json
index d2db870..72607a7 100644
--- a/composer.json
+++ b/composer.json
@@ -22,7 +22,8 @@
"pdepend/pdepend" : "1.1.0",
"squizlabs/php_codesniffer": "*",
"phpunit/phpunit": "*",
- "phploc/phploc": "*"
+ "phploc/phploc": "*",
+ "fzaninotto/faker": "*"
},
"config": {
"bin-dir": "bin"
diff --git a/modman b/modman
index da4063c..a647434 100644
--- a/modman
+++ b/modman
@@ -25,3 +25,4 @@ app/design/frontend/base/default/layout/bitcoins.xml app/design/frontend/base/de
app/design/frontend/base/default/template/bitcoins app/design/frontend/base/default/template/bitcoins
app/etc/modules/Bitpay_Bitcoins.xml app/etc/modules/Bitpay_Bitcoins.xml
lib/bitpay lib/bitpay
+shell/bitpay.php shell/bitpay.php
diff --git a/shell/bitpay.php b/shell/bitpay.php
new file mode 100644
index 0000000..4257309
--- /dev/null
+++ b/shell/bitpay.php
@@ -0,0 +1,92 @@
+getArg('clean')) {
+ switch ($clean) {
+ case 'expired':
+ $this->cleanExpired();
+ break;
+ default:
+ echo $this->usageHelp();
+ return 1;
+ break;
+ }
+
+ return 0;
+ }
+
+ echo $this->usageHelp();
+ }
+
+ /**
+ * Removes expired IPNs from database and updates order if they are
+ * open
+ */
+ public function cleanExpired()
+ {
+ Mage::helper('bitpay')->clearExpired();
+ }
+
+ /**
+ * Display help on how to use this bad boy
+ */
+ public function usageHelp()
+ {
+ $figlet = new Zend_Text_Figlet(
+ array(
+ 'justification' => Zend_Text_Figlet::JUSTIFICATION_CENTER
+ )
+ );
+
+ return <<render('BitPay')}
+
+Usage: php -f bitpay.php
+
+ --clean Delete all IPN records based on
+
+List of Statuses:
+
+ expired
+
+USAGE;
+ }
+}
+
+$shell = new Bitpay_Shell_Bitpay();
+$shell->run();
diff --git a/tests/Bitpay/Bitcoins/Helper/DataTest.php b/tests/Bitpay/Bitcoins/Helper/DataTest.php
index a5ae1d2..c077cb1 100644
--- a/tests/Bitpay/Bitcoins/Helper/DataTest.php
+++ b/tests/Bitpay/Bitcoins/Helper/DataTest.php
@@ -27,6 +27,13 @@
class Bitpay_Bitcoins_Helper_DataTest extends PHPUnit_Framework_TestCase
{
+ protected static $faker;
+
+ public static function setUpBeforeClass()
+ {
+ self::$faker = Faker\Factory::create();
+ }
+
public function testHasApiKeyFalse()
{
Mage::app()->getStore()->setConfig('payment/Bitcoins/api_key', null);
@@ -54,4 +61,182 @@ class Bitpay_Bitcoins_Helper_DataTest extends PHPUnit_Framework_TestCase
$this->assertTrue(Mage::helper('bitpay')->hasTransactionSpeed());
}
+
+ public function testCleanExpired()
+ {
+ // Create a few expired/invalid ipns
+ $invalidIpn = $this->createInvalidIpn();
+ $expiredIpn = $this->createExpiredIpn();
+
+ // Are the IPNs in the database?
+ $ipn = Mage::getModel('Bitcoins/ipn');
+ $dbInvalidIpn = $ipn->load($invalidIpn->getId())->toArray();
+ $dbExpiredIpn = $ipn->load($expiredIpn->getId())->toArray();
+ $this->assertArrayHasKey('id', $dbInvalidIpn);
+ $this->assertArrayHasKey('id', $dbExpiredIpn);
+ unset($dbInvalidIpn, $dbExpiredIpn);
+
+ // clean them
+ Mage::helper('bitpay')->cleanExpired();
+
+ // check the database and see if they are still there
+ $ipn = Mage::getModel('Bitcoins/ipn');
+ $dbInvalidIpn = $ipn->load($invalidIpn->getId())->toArray();
+ $dbExpiredIpn = $ipn->load($expiredIpn->getId())->toArray();
+ $this->assertEmpty($dbInvalidIpn);
+ $this->assertEmpty($dbExpiredIpn);
+ }
+
+ private function createInvalidIpn()
+ {
+ $ipn = new Bitpay_Bitcoins_Model_Ipn();
+ $ipn->setData(
+ array(
+ 'quote_id' => '',
+ 'order_id' => '',
+ 'invoice_id' => '',
+ 'url' => '',
+ 'pos_data' => '',
+ 'status' => '',
+ 'btc_price' => '',
+ 'price' => '',
+ 'currency' => '',
+ 'invoice_time' => '',
+ 'expiration_time' => '',
+ 'current_time' => '',
+ )
+ );
+ $ipn->save();
+ $ipn->load($ipn->getId());
+
+ return $ipn;
+ }
+
+ private function createExpiredIpn()
+ {
+ $order = $this->createOrder();
+ $ipn = new Bitpay_Bitcoins_Model_Ipn();
+ $ipn->setData(
+ array(
+ 'quote_id' => '',
+ 'order_id' => $order->getIncrementId(),
+ 'invoice_id' => '',
+ 'url' => '',
+ 'pos_data' => '',
+ 'status' => '',
+ 'btc_price' => '',
+ 'price' => '',
+ 'currency' => '',
+ 'invoice_time' => '',
+ 'expiration_time' => '',
+ 'current_time' => '',
+ )
+ );
+ $ipn->save();
+ $ipn->load($ipn->getId());
+
+ return $ipn;
+ }
+
+ private function createOrder()
+ {
+ $product = $this->createProduct();
+ $quote = $this->createQuote();
+ $quote->addProduct(
+ $product,
+ new Varien_Object(
+ array(
+ 'qty' => 1,
+ )
+ )
+ );
+ $address = array(
+ 'firstname' => self::$faker->firstName,
+ 'lastname' => self::$faker->lastName,
+ 'company' => self::$faker->company,
+ 'email' => self::$faker->email,
+ 'city' => self::$faker->city,
+ 'region_id' => '',
+ 'region' => 'State/Province',
+ 'postcode' => self::$faker->postcode,
+ 'telephone' => self::$faker->phoneNumber,
+ 'country_id' => self::$faker->state,
+ 'customer_password' => '',
+ 'confirm_password' => '',
+ 'save_in_address_book' => 0,
+ 'use_for_shipping' => 1,
+ 'street' => array(
+ self::$faker->streetAddress
+ ),
+ );
+
+ $quote->getBillingAddress()
+ ->addData($address);
+
+ $quote->getShippingAddress()
+ ->addData($address)
+ ->setShippingMethod('flatrate_flatrate')
+ ->setPaymentMethod('checkmo')
+ ->setCollectShippingRates(true)
+ ->collectTotals();
+
+ $quote
+ ->setCheckoutMethod('guest')
+ ->setCustomerId(null)
+ ->setCustomerEmail($address['email'])
+ ->setCustomerIsGuest(true)
+ ->setCustomerGroupId(Mage_Customer_Model_Group::NOT_LOGGED_IN_ID);
+
+ $quote->getPayment()
+ ->importData(array('method' => 'checkmo'));
+
+ $quote->save();
+
+ $service = Mage::getModel('sales/service_quote', $quote);
+ $service->submitAll();
+ $order = $service->getOrder();
+
+ $order->save();
+ $order->load($order->getId());
+
+ return $order;
+ }
+
+ private function createProduct()
+ {
+ $product = Mage::getModel('catalog/product');
+
+ $product->addData(
+ array(
+ 'attribute_set_id' => 1,
+ 'website_ids' => array(1),
+ 'categories' => array(),
+ 'type_id' => Mage_Catalog_Model_Product_Type::TYPE_SIMPLE,
+ 'sku' => self::$faker->randomNumber,
+ 'name' => self::$faker->name,
+ 'weight' => self::$faker->randomDigit,
+ 'status' => Mage_Catalog_Model_Product_Status::STATUS_ENABLED,
+ 'tax_class_id' => 2,
+ 'visibility' => Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH,
+ 'price' => self::$faker->randomFloat(2),
+ 'description' => self::$faker->paragraphs,
+ 'short_description' => self::$faker->sentence,
+ 'stock_data' => array(
+ 'is_in_stock' => 1,
+ 'qty' => 100,
+ ),
+ )
+ );
+
+ $product->save();
+ $product->load($product->getId());
+
+ return $product;
+ }
+
+ private function createQuote()
+ {
+ return Mage::getModel('sales/quote')
+ ->setStoreId(Mage::app()->getStore('default')->getId());
+ }
}
diff --git a/tests/Bitpay/Bitcoins/Model/PaymentMethodTest.php b/tests/Bitpay/Bitcoins/Model/PaymentMethodTest.php
index 9b81e93..4040d96 100644
--- a/tests/Bitpay/Bitcoins/Model/PaymentMethodTest.php
+++ b/tests/Bitpay/Bitcoins/Model/PaymentMethodTest.php
@@ -3,7 +3,7 @@
/**
* The MIT License (MIT)
*
- * Copyright (c) 2011-2014 BitPay
+ * Copyright (c) 2011-2014 BitPay, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/tests/bootstrap.php b/tests/bootstrap.php
index 824ea24..b0a1ca1 100644
--- a/tests/bootstrap.php
+++ b/tests/bootstrap.php
@@ -3,7 +3,7 @@
/**
* The MIT License (MIT)
*
- * Copyright (c) 2011-2014 BitPay
+ * Copyright (c) 2011-2014 BitPay, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -31,3 +31,9 @@ if ($mage = realpath(__DIR__ . '/../build/magento/app/Mage.php')) {
} else {
exit('Could not find Mage.php');
}
+
+if ($composer = realpath(__DIR__ . '/../vendor/autoload.php')) {
+ require_once $composer;
+} else {
+ exit('Composer not found');
+}