Merge pull request #20 from ionux/master

Corrected company name, license and formatting
This commit is contained in:
Ryan X. Charles 2014-01-29 09:59:41 -08:00
commit 70ee93bbff
11 changed files with 728 additions and 556 deletions

View File

@ -1,4 +1,5 @@
©2011 BIT-PAY LLC. ©2011-2014 BITPAY, INC.
Permission is hereby granted to any person obtaining a copy of this software Permission is hereby granted to any person obtaining a copy of this software
and associated documentation for use and/or modification in association with and associated documentation for use and/or modification in association with
the bitpay.com service. the bitpay.com service.

View File

@ -1,24 +1,38 @@
<?php <?php
class Bitpay_Bitcoins_Block_Iframe extends Mage_Checkout_Block_Onepage_Payment /**
{ * ©2011,2012,2013,2014 BITPAY, INC.
protected function _construct() *
{ * Permission is hereby granted to any person obtaining a copy of this software
* and associated documentation for use and/or modification in association with
* the bitpay.com service.
*
* 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.
*
* Bitcoin payment plugin using the bitpay.com service.
*
*/
class Bitpay_Bitcoins_Block_Iframe extends Mage_Checkout_Block_Onepage_Payment {
protected function _construct() {
$this->setTemplate('bitcoins/iframe.phtml'); $this->setTemplate('bitcoins/iframe.phtml');
parent::_construct(); parent::_construct();
} }
public function GetQuoteId() public function GetQuoteId() {
{
$quote = $this->getQuote(); $quote = $this->getQuote();
$quoteId = $quote->getId(); $quoteId = $quote->getId();
return $quoteId; return $quoteId;
} }
// create an invoice and return the url so that iframe.phtml can display it // create an invoice and return the url so that iframe.phtml can display it
public function GetIframeUrl() public function GetIframeUrl() {
{
// are they using bitpay? // are they using bitpay?
if (!($quote = Mage::getSingleton('checkout/session')->getQuote()) if (!($quote = Mage::getSingleton('checkout/session')->getQuote())
or !($payment = $quote->getPayment()) or !($payment = $quote->getPayment())
@ -37,9 +51,11 @@ class Bitpay_Bitcoins_Block_Iframe extends Mage_Checkout_Block_Onepage_Payment
$quote = $this->getQuote(); $quote = $this->getQuote();
$quoteId = $quote->getId(); $quoteId = $quote->getId();
if (Mage::getModel('Bitcoins/ipn')->GetQuotePaid($quoteId)) if (Mage::getModel('Bitcoins/ipn')->GetQuotePaid($quoteId))
return 'paid'; // quote's already paid, so don't show the iframe return 'paid'; // quote's already paid, so don't show the iframe
$options = array( $options = array(
'currency' => $quote->getQuoteCurrencyCode(), 'currency' => $quote->getQuoteCurrencyCode(),
'fullNotifications' => 'true', 'fullNotifications' => 'true',
@ -60,11 +76,12 @@ class Bitpay_Bitcoins_Block_Iframe extends Mage_Checkout_Block_Onepage_Payment
$hash = $method->getQuoteHash($quoteId); $hash = $method->getQuoteHash($quoteId);
Mage::log('invoicing for '.$price.' '.$quote->getQuoteCurrencyCode(), NULL, 'bitpay.log'); Mage::log('invoicing for '.$price.' '.$quote->getQuoteCurrencyCode(), NULL, 'bitpay.log');
$invoice = bpCreateInvoice($quoteId, $price, array('quoteId' => $quoteId, 'quoteHash' => $hash), $options); $invoice = bpCreateInvoice($quoteId, $price, array('quoteId' => $quoteId, 'quoteHash' => $hash), $options);
Mage::log($invoice, NULL, 'bitpay.log'); Mage::log($invoice, NULL, 'bitpay.log');
if (array_key_exists('error', $invoice)) if (array_key_exists('error', $invoice)) {
{
Mage::log('Error creating bitpay invoice', null, 'bitpay.log'); Mage::log('Error creating bitpay invoice', null, 'bitpay.log');
Mage::log($invoice['error'], null, 'bitpay.log'); Mage::log($invoice['error'], null, 'bitpay.log');
Mage::throwException("Error creating bit-pay invoice. Please try again or use another payment option."); Mage::throwException("Error creating bit-pay invoice. Please try again or use another payment option.");
@ -73,4 +90,5 @@ class Bitpay_Bitcoins_Block_Iframe extends Mage_Checkout_Block_Onepage_Payment
return $invoice['url'].'&view=iframe'; return $invoice['url'].'&view=iframe';
} }
} }

View File

@ -1,15 +1,32 @@
<?php <?php
class Bitpay_Bitcoins_Model_Ipn extends Mage_Core_Model_Abstract /**
{ * ©2011,2012,2013,2014 BITPAY, INC.
function _construct() *
{ * Permission is hereby granted to any person obtaining a copy of this software
* and associated documentation for use and/or modification in association with
* the bitpay.com service.
*
* 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.
*
* Bitcoin payment plugin using the bitpay.com service.
*
*/
class Bitpay_Bitcoins_Model_Ipn extends Mage_Core_Model_Abstract {
function _construct() {
$this->_init('Bitcoins/ipn'); $this->_init('Bitcoins/ipn');
return parent::_construct(); return parent::_construct();
} }
function Record($invoice) function Record($invoice) {
{
return $this return $this
->setQuoteId(isset($invoice['posData']['quoteId']) ? $invoice['posData']['quoteId'] : NULL) ->setQuoteId(isset($invoice['posData']['quoteId']) ? $invoice['posData']['quoteId'] : NULL)
->setOrderId(isset($invoice['posData']['orderId']) ? $invoice['posData']['orderId'] : NULL) ->setOrderId(isset($invoice['posData']['orderId']) ? $invoice['posData']['orderId'] : NULL)
@ -26,32 +43,31 @@ class Bitpay_Bitcoins_Model_Ipn extends Mage_Core_Model_Abstract
->save(); ->save();
} }
function GetStatusReceived($quoteId, $statuses) function GetStatusReceived($quoteId, $statuses) {
{
if (!$quoteId) if (!$quoteId)
return false; return false;
$quote = Mage::getModel('sales/quote')->load($quoteId, 'entity_id'); $quote = Mage::getModel('sales/quote')->load($quoteId, 'entity_id');
if (!$quote)
{ if (!$quote) {
Mage::log('quote not found', NULL, 'bitpay.log'); Mage::log('quote not found', NULL, 'bitpay.log');
return false; return false;
} }
$quoteHash = Mage::getModel('Bitcoins/paymentMethod')->getQuoteHash($quoteId); $quoteHash = Mage::getModel('Bitcoins/paymentMethod')->getQuoteHash($quoteId);
if (!$quoteHash)
{ if (!$quoteHash) {
Mage::log('Could not find quote hash for quote '.$quoteId, NULL, 'bitpay.log'); Mage::log('Could not find quote hash for quote '.$quoteId, NULL, 'bitpay.log');
return false; return false;
} }
$collection = $this->getCollection()->AddFilter('quote_id', $quoteId); $collection = $this->getCollection()->AddFilter('quote_id', $quoteId);
foreach($collection as $i)
{ foreach($collection as $i) {
if (in_array($i->getStatus(), $statuses)) if (in_array($i->getStatus(), $statuses)) {
{
// check that quote data was not updated after IPN sent // check that quote data was not updated after IPN sent
$posData = json_decode($i->getPosData()); $posData = json_decode($i->getPosData());
if (!$posData) if (!$posData)
continue; continue;
@ -63,18 +79,14 @@ class Bitpay_Bitcoins_Model_Ipn extends Mage_Core_Model_Abstract
return false; return false;
} }
function GetQuotePaid($quoteId) function GetQuotePaid($quoteId) {
{
return $this->GetStatusReceived($quoteId, array('paid', 'confirmed', 'complete')); return $this->GetStatusReceived($quoteId, array('paid', 'confirmed', 'complete'));
} }
function GetQuoteComplete($quoteId) function GetQuoteComplete($quoteId) {
{
return $this->GetStatusReceived($quoteId, array('confirmed', 'complete')); return $this->GetStatusReceived($quoteId, array('confirmed', 'complete'));
} }
} }
?> ?>

View File

@ -1,10 +1,28 @@
<?php <?php
/**
* ©2011,2012,2013,2014 BITPAY, INC.
*
* Permission is hereby granted to any person obtaining a copy of this software
* and associated documentation for use and/or modification in association with
* the bitpay.com service.
*
* 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.
*
* Bitcoin payment plugin using the bitpay.com service.
*
*/
/** /**
* Our test CC module adapter * Our test CC module adapter
*/ */
class Bitpay_Bitcoins_Model_PaymentMethod extends Mage_Payment_Model_Method_Abstract class Bitpay_Bitcoins_Model_PaymentMethod extends Mage_Payment_Model_Method_Abstract {
{
/** /**
* unique internal payment method identifier * unique internal payment method identifier
* *
@ -75,26 +93,23 @@ class Bitpay_Bitcoins_Model_PaymentMethod extends Mage_Payment_Model_Method_Abst
//protected $_formBlockType = 'bitcoins/form'; //protected $_formBlockType = 'bitcoins/form';
//protected $_infoBlockType = 'bitcoins/info'; //protected $_infoBlockType = 'bitcoins/info';
function canUseForCurrency($currencyCode) function canUseForCurrency($currencyCode) {
{
$currencies = Mage::getStoreConfig('payment/Bitcoins/currencies'); $currencies = Mage::getStoreConfig('payment/Bitcoins/currencies');
$currencies = array_map('trim', explode(',', $currencies)); $currencies = array_map('trim', explode(',', $currencies));
return array_search($currencyCode, $currencies) !== false; return array_search($currencyCode, $currencies) !== false;
} }
public function canUseCheckout() public function canUseCheckout() {
{
$secret = Mage::getStoreConfig('payment/Bitcoins/api_key'); $secret = Mage::getStoreConfig('payment/Bitcoins/api_key');
if (!$secret or !strlen($secret))
{ if (!$secret or !strlen($secret)) {
Mage::log('Bitpay/Bitcoins: API key not entered', null, 'bitpay.log'); Mage::log('Bitpay/Bitcoins: API key not entered', null, 'bitpay.log');
return false; return false;
} }
$speed = Mage::getStoreConfig('payment/Bitcoins/speed'); $speed = Mage::getStoreConfig('payment/Bitcoins/speed');
if (!$speed or !strlen($speed))
{ if (!$speed or !strlen($speed)) {
Mage::log('Bitpay/Bitcoins: Transaction Speed invalid', null, 'bitpay.log'); Mage::log('Bitpay/Bitcoins: Transaction Speed invalid', null, 'bitpay.log');
return false; return false;
} }
@ -102,41 +117,33 @@ class Bitpay_Bitcoins_Model_PaymentMethod extends Mage_Payment_Model_Method_Abst
return $this->_canUseCheckout; return $this->_canUseCheckout;
} }
public function authorize(Varien_Object $payment, $amount) public function authorize(Varien_Object $payment, $amount) {
{
if (!Mage::getStoreConfig('payment/Bitcoins/fullscreen')) if (!Mage::getStoreConfig('payment/Bitcoins/fullscreen'))
return $this->CheckForPayment($payment); return $this->CheckForPayment($payment);
else else
return $this->CreateInvoiceAndRedirect($payment, $amount); return $this->CreateInvoiceAndRedirect($payment, $amount);
} }
function CheckForPayment($payment) function CheckForPayment($payment) {
{
$quoteId = $payment->getOrder()->getQuoteId(); $quoteId = $payment->getOrder()->getQuoteId();
$ipn = Mage::getModel('Bitcoins/ipn'); $ipn = Mage::getModel('Bitcoins/ipn');
if (!$ipn->GetQuotePaid($quoteId))
{ if (!$ipn->GetQuotePaid($quoteId)) {
Mage::throwException("Order not paid for. Please pay first and then Place your Order."); Mage::throwException("Order not paid for. Please pay first and then Place your Order.");
} } else if (!$ipn->GetQuoteComplete($quoteId)) {
else if (!$ipn->GetQuoteComplete($quoteId))
{
// order status will be PAYMENT_REVIEW instead of PROCESSING // order status will be PAYMENT_REVIEW instead of PROCESSING
$payment->setIsTransactionPending(true); $payment->setIsTransactionPending(true);
} } else {
else
{
$this->MarkOrderPaid($payment->getOrder()); $this->MarkOrderPaid($payment->getOrder());
} }
return $this; return $this;
} }
function MarkOrderPaid($order) function MarkOrderPaid($order) {
{
$order->setState(Mage_Sales_Model_Order::STATE_PROCESSING, true)->save(); $order->setState(Mage_Sales_Model_Order::STATE_PROCESSING, true)->save();
if (!count($order->getInvoiceCollection()))
{ if (!count($order->getInvoiceCollection())) {
$invoice = $order->prepareInvoice() $invoice = $order->prepareInvoice()
->setTransactionId(1) ->setTransactionId(1)
->addComment('Invoiced automatically by Bitpay/Bitcoins/controllers/IndexController.php') ->addComment('Invoiced automatically by Bitpay/Bitcoins/controllers/IndexController.php')
@ -146,17 +153,19 @@ class Bitpay_Bitcoins_Model_PaymentMethod extends Mage_Payment_Model_Method_Abst
$transactionSave = Mage::getModel('core/resource_transaction') $transactionSave = Mage::getModel('core/resource_transaction')
->addObject($invoice) ->addObject($invoice)
->addObject($invoice->getOrder()); ->addObject($invoice->getOrder());
$transactionSave->save(); $transactionSave->save();
} }
} }
// given Mage_Core_Model_Abstract, return api-friendly address // given Mage_Core_Model_Abstract, return api-friendly address
function ExtractAddress($address) function ExtractAddress($address) {
{
$options = array(); $options = array();
$options['buyerName'] = $address->getName(); $options['buyerName'] = $address->getName();
if ($address->getCompany()) if ($address->getCompany())
$options['buyerName'] = $options['buyerName'].' c/o '.$address->getCompany(); $options['buyerName'] = $options['buyerName'].' c/o '.$address->getCompany();
$options['buyerAddress1'] = $address->getStreet1(); $options['buyerAddress1'] = $address->getStreet1();
$options['buyerAddress2'] = $address->getStreet2(); $options['buyerAddress2'] = $address->getStreet2();
$options['buyerAddress3'] = $address->getStreet3(); $options['buyerAddress3'] = $address->getStreet3();
@ -167,21 +176,22 @@ class Bitpay_Bitcoins_Model_PaymentMethod extends Mage_Payment_Model_Method_Abst
$options['buyerCountry'] = $address->getCountry(); $options['buyerCountry'] = $address->getCountry();
$options['buyerEmail'] = $address->getEmail(); $options['buyerEmail'] = $address->getEmail();
$options['buyerPhone'] = $address->getTelephone(); $options['buyerPhone'] = $address->getTelephone();
// trim to fit API specs // trim to fit API specs
foreach(array('buyerName', 'buyerAddress1', 'buyerAddress2', 'buyerAddress3', 'buyerAddress4', 'buyerCity', 'buyerState', 'buyerZip', 'buyerCountry', 'buyerEmail', 'buyerPhone') as $f) foreach(array('buyerName', 'buyerAddress1', 'buyerAddress2', 'buyerAddress3', 'buyerAddress4', 'buyerCity', 'buyerState', 'buyerZip', 'buyerCountry', 'buyerEmail', 'buyerPhone') as $f)
$options[$f] = substr($options[$f], 0, 100); $options[$f] = substr($options[$f], 0, 100);
return $options; return $options;
} }
function CreateInvoiceAndRedirect($payment, $amount) function CreateInvoiceAndRedirect($payment, $amount) {
{
include Mage::getBaseDir('lib').'/bitpay/bp_lib.php'; include Mage::getBaseDir('lib').'/bitpay/bp_lib.php';
$apiKey = Mage::getStoreConfig('payment/Bitcoins/api_key'); $apiKey = Mage::getStoreConfig('payment/Bitcoins/api_key');
$speed = Mage::getStoreConfig('payment/Bitcoins/speed'); $speed = Mage::getStoreConfig('payment/Bitcoins/speed');
$order = $payment->getOrder(); $order = $payment->getOrder();
$orderId = $order->getIncrementId(); $orderId = $order->getIncrementId();
$options = array( $options = array(
'currency' => $order->getBaseCurrencyCode(), 'currency' => $order->getBaseCurrencyCode(),
'buyerName' => $order->getCustomerFirstname().' '.$order->getCustomerLastname(), 'buyerName' => $order->getCustomerFirstname().' '.$order->getCustomerLastname(),
@ -191,20 +201,16 @@ class Bitpay_Bitcoins_Model_PaymentMethod extends Mage_Payment_Model_Method_Abst
'transactionSpeed' => $speed, 'transactionSpeed' => $speed,
'apiKey' => $apiKey, 'apiKey' => $apiKey,
); );
$options += $this->ExtractAddress($order->getShippingAddress()); $options += $this->ExtractAddress($order->getShippingAddress());
$invoice = bpCreateInvoice($orderId, $amount, array('orderId' => $orderId), $options); $invoice = bpCreateInvoice($orderId, $amount, array('orderId' => $orderId), $options);
$payment->setIsTransactionPending(true); // status will be PAYMENT_REVIEW instead of PROCESSING $payment->setIsTransactionPending(true); // status will be PAYMENT_REVIEW instead of PROCESSING
if (array_key_exists('error', $invoice)) if (array_key_exists('error', $invoice)) {
{
Mage::log('Error creating bitpay invoice', null, 'bitpay.log'); Mage::log('Error creating bitpay invoice', null, 'bitpay.log');
Mage::log($invoice['error'], null, 'bitpay.log'); Mage::log($invoice['error'], null, 'bitpay.log');
Mage::throwException("Error creating bit-pay invoice. Please try again or use another payment option."); Mage::throwException("Error creating bit-pay invoice. Please try again or use another payment option.");
} } else {
else
{
$invoiceId = Mage::getModel('sales/order_invoice_api')->create($orderId, array()); $invoiceId = Mage::getModel('sales/order_invoice_api')->create($orderId, array());
Mage::getSingleton('customer/session')->setRedirectUrl($invoice['url']); Mage::getSingleton('customer/session')->setRedirectUrl($invoice['url']);
} }
@ -212,33 +218,29 @@ class Bitpay_Bitcoins_Model_PaymentMethod extends Mage_Payment_Model_Method_Abst
return $this; return $this;
} }
public function getOrderPlaceRedirectUrl() public function getOrderPlaceRedirectUrl() {
{
if (Mage::getStoreConfig('payment/Bitcoins/fullscreen')) if (Mage::getStoreConfig('payment/Bitcoins/fullscreen'))
return Mage::getSingleton('customer/session')->getRedirectUrl(); return Mage::getSingleton('customer/session')->getRedirectUrl();
else else
return ''; return '';
} }
# computes a unique hash determined by the contents of the cart // computes a unique hash determined by the contents of the cart
public function getQuoteHash($quoteId) public function getQuoteHash($quoteId) {
{
$quote = Mage::getModel('sales/quote')->load($quoteId, 'entity_id'); $quote = Mage::getModel('sales/quote')->load($quoteId, 'entity_id');
if (!$quote) if (!$quote) {
{
Mage::log('getQuoteTimestamp: quote not found', NULL, 'bitpay.log'); Mage::log('getQuoteTimestamp: quote not found', NULL, 'bitpay.log');
return false; return false;
} }
#encode items // encode items
$items = $quote->getAllItems(); $items = $quote->getAllItems();
$latest = NULL; $latest = NULL;
$description = ''; $description = '';
foreach($items as $i)
{
$description.= 'i'.$i->getItemId().'q'.$i->getQty();
# could encode $i->getOptions() here but item ids are incremented if options are changed foreach($items as $i) {
$description.= 'i'.$i->getItemId().'q'.$i->getQty();
// could encode $i->getOptions() here but item ids are incremented if options are changed
} }
$hash = base64_encode(hash_hmac('sha256', $description, $quoteId)); $hash = base64_encode(hash_hmac('sha256', $description, $quoteId));

View File

@ -1,9 +1,26 @@
<?php <?php
class Bitpay_Bitcoins_Model_Resource_Ipn extends Mage_Core_Model_Resource_Db_Abstract /**
{ * ©2011,2012,2013,2014 BITPAY, INC.
protected function _construct() *
{ * Permission is hereby granted to any person obtaining a copy of this software
* and associated documentation for use and/or modification in association with
* the bitpay.com service.
*
* 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.
*
* Bitcoin payment plugin using the bitpay.com service.
*
*/
class Bitpay_Bitcoins_Model_Resource_Ipn extends Mage_Core_Model_Resource_Db_Abstract {
protected function _construct() {
$this->_init('Bitcoins/ipn', 'id'); $this->_init('Bitcoins/ipn', 'id');
} }
} }

View File

@ -1,9 +1,26 @@
<?php <?php
class Bitpay_Bitcoins_Model_Resource_Ipn_Collection extends Mage_Core_Model_Resource_Db_Collection_Abstract /**
{ * ©2011,2012,2013,2014 BITPAY, INC.
protected function _construct() *
{ * Permission is hereby granted to any person obtaining a copy of this software
* and associated documentation for use and/or modification in association with
* the bitpay.com service.
*
* 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.
*
* Bitcoin payment plugin using the bitpay.com service.
*
*/
class Bitpay_Bitcoins_Model_Resource_Ipn_Collection extends Mage_Core_Model_Resource_Db_Collection_Abstract {
protected function _construct() {
$this->_init('Bitcoins/ipn'); $this->_init('Bitcoins/ipn');
} }
} }

View File

@ -1,10 +1,26 @@
<?php <?php
class Bitpay_Bitcoins_Model_Source_Speed /**
{ * ©2011,2012,2013,2014 BITPAY, INC.
public function toOptionArray() *
{ * Permission is hereby granted to any person obtaining a copy of this software
* and associated documentation for use and/or modification in association with
* the bitpay.com service.
*
* 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.
*
* Bitcoin payment plugin using the bitpay.com service.
*
*/
class Bitpay_Bitcoins_Model_Source_Speed {
public function toOptionArray() {
return array( return array(
array( array(
'value' => 'low', 'value' => 'low',

View File

@ -1,10 +1,28 @@
<?php <?php
/**
* ©2011,2012,2013,2014 BITPAY, INC.
*
* Permission is hereby granted to any person obtaining a copy of this software
* and associated documentation for use and/or modification in association with
* the bitpay.com service.
*
* 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.
*
* Bitcoin payment plugin using the bitpay.com service.
*
*/
// callback controller // callback controller
class Bitpay_Bitcoins_IndexController extends Mage_Core_Controller_Front_Action { class Bitpay_Bitcoins_IndexController extends Mage_Core_Controller_Front_Action {
public function checkForPaymentAction() public function checkForPaymentAction() {
{
$params = $this->getRequest()->getParams(); $params = $this->getRequest()->getParams();
$quoteId = $params['quote']; $quoteId = $params['quote'];
$paid = Mage::getModel('Bitcoins/ipn')->GetQuotePaid($quoteId); $paid = Mage::getModel('Bitcoins/ipn')->GetQuotePaid($quoteId);
@ -15,9 +33,7 @@ class Bitpay_Bitcoins_IndexController extends Mage_Core_Controller_Front_Action
// bitpay's IPN lands here // bitpay's IPN lands here
public function indexAction() { public function indexAction() {
require Mage::getBaseDir('lib').'/bitpay/bp_lib.php'; require Mage::getBaseDir('lib').'/bitpay/bp_lib.php';
Mage::log(file_get_contents('php://input'), null, 'bitpay.log'); Mage::log(file_get_contents('php://input'), null, 'bitpay.log');
$apiKey = Mage::getStoreConfig('payment/Bitcoins/api_key'); $apiKey = Mage::getStoreConfig('payment/Bitcoins/api_key');
$invoice = bpVerifyNotification($apiKey); $invoice = bpVerifyNotification($apiKey);
@ -28,8 +44,7 @@ class Bitpay_Bitcoins_IndexController extends Mage_Core_Controller_Front_Action
if (isset($invoice['posData']['quoteId'])) { if (isset($invoice['posData']['quoteId'])) {
$quoteId = $invoice['posData']['quoteId']; $quoteId = $invoice['posData']['quoteId'];
$order = Mage::getModel('sales/order')->load($quoteId, 'quote_id'); $order = Mage::getModel('sales/order')->load($quoteId, 'quote_id');
} } else {
else {
$orderId = $invoice['posData']['orderId']; $orderId = $invoice['posData']['orderId'];
$order = Mage::getModel('sales/order')->loadByIncrementId($orderId); $order = Mage::getModel('sales/order')->loadByIncrementId($orderId);
} }
@ -44,10 +59,11 @@ class Bitpay_Bitcoins_IndexController extends Mage_Core_Controller_Front_Action
case 'complete': case 'complete':
$method = Mage::getModel('Bitcoins/paymentMethod'); $method = Mage::getModel('Bitcoins/paymentMethod');
$method->MarkOrderPaid($order); $method->MarkOrderPaid($order);
break; break;
} }
}
}
} }
} }

View File

@ -1,15 +1,40 @@
<?php <?php
/**
* ©2011,2012,2013,2014 BITPAY, INC.
*
* Permission is hereby granted to any person obtaining a copy of this software
* and associated documentation for use and/or modification in association with
* the bitpay.com service.
*
* 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.
*
* Bitcoin payment plugin using the bitpay.com service.
*
*/
global $bpconfig; global $bpconfig;
$bpconfig['host']="bitpay.com"; $bpconfig['host']="bitpay.com";
$bpconfig['port']=443; $bpconfig['port']=443;
$bpconfig['hostAndPort']=$bpconfig['host']; $bpconfig['hostAndPort']=$bpconfig['host'];
if ($bpconfig['port']!=443) if ($bpconfig['port']!=443)
$bpconfig['hostAndPort'].=":".$bpconfig['host']; $bpconfig['hostAndPort'].=":".$bpconfig['host'];
$bpconfig['ssl_verifypeer']=1; $bpconfig['ssl_verifypeer']=1;
$bpconfig['ssl_verifyhost']=2; $bpconfig['ssl_verifyhost']=2;
//include custom config overrides if it exists //include custom config overrides if it exists
try { try {
include 'bp_config.php'; include 'bp_config.php';
} catch (Exception $e) { } catch (Exception $e) {
// do nothing
} }
?> ?>

View File

@ -1,5 +1,24 @@
<?php <?php
/**
* ©2011,2012,2013,2014 BITPAY, INC.
*
* Permission is hereby granted to any person obtaining a copy of this software
* and associated documentation for use and/or modification in association with
* the bitpay.com service.
*
* 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.
*
* Bitcoin payment plugin using the bitpay.com service.
*
*/
require_once 'bp_config_default.php'; require_once 'bp_config_default.php';
require_once 'bp_options.php'; require_once 'bp_options.php';
@ -8,8 +27,8 @@ function bpCurl($url, $apiKey, $post = false) {
$curl = curl_init($url); $curl = curl_init($url);
$length = 0; $length = 0;
if ($post)
{ if ($post) {
curl_setopt($curl, CURLOPT_POST, 1); curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $post); curl_setopt($curl, CURLOPT_POSTFIELDS, $post);
$length = strlen($post); $length = strlen($post);
@ -18,8 +37,8 @@ function bpCurl($url, $apiKey, $post = false) {
$uname = base64_encode($apiKey); $uname = base64_encode($apiKey);
$header = array( $header = array(
'Content-Type: application/json', 'Content-Type: application/json',
"Content-Length: $length", 'Content-Length: ' . $length,
"Authorization: Basic $uname", 'Authorization: Basic ' . $uname,
); );
curl_setopt($curl, CURLOPT_PORT, $bpconfig['port']); curl_setopt($curl, CURLOPT_PORT, $bpconfig['port']);
@ -41,9 +60,11 @@ function bpCurl($url, $apiKey, $post = false) {
if (!$response) if (!$response)
$response = array('error' => 'invalid json: '.$responseString); $response = array('error' => 'invalid json: '.$responseString);
} }
curl_close($curl); curl_close($curl);
return $response; return $response;
} }
// $orderId: Used to display an orderID to the buyer. In the account summary view, this value is used to // $orderId: Used to display an orderID to the buyer. In the account summary view, this value is used to
// identify a ledger entry if present. // identify a ledger entry if present.
// //
@ -64,21 +85,23 @@ function bpCreateInvoice($orderId, $price, $posData, $options = array()) {
global $bpOptions, $bpconfig; global $bpOptions, $bpconfig;
$options = array_merge($bpOptions, $options); // $options override any options found in bp_options.php $options = array_merge($bpOptions, $options); // $options override any options found in bp_options.php
$pos = array('posData' => $posData); $pos = array('posData' => $posData);
if ($bpOptions['verifyPos']) if ($bpOptions['verifyPos'])
$pos['hash'] = crypt(serialize($posData), $options['apiKey']); $pos['hash'] = crypt(serialize($posData), $options['apiKey']);
$options['posData'] = json_encode($pos);
$options['posData'] = json_encode($pos);
$options['orderID'] = $orderId; $options['orderID'] = $orderId;
$options['price'] = $price; $options['price'] = $price;
$postOptions = array('orderID', 'itemDesc', 'itemCode', 'notificationEmail', 'notificationURL', 'redirectURL', $postOptions = array('orderID', 'itemDesc', 'itemCode', 'notificationEmail', 'notificationURL', 'redirectURL',
'posData', 'price', 'currency', 'physical', 'fullNotifications', 'transactionSpeed', 'buyerName', 'posData', 'price', 'currency', 'physical', 'fullNotifications', 'transactionSpeed', 'buyerName',
'buyerAddress1', 'buyerAddress2', 'buyerCity', 'buyerState', 'buyerZip', 'buyerEmail', 'buyerPhone'); 'buyerAddress1', 'buyerAddress2', 'buyerCity', 'buyerState', 'buyerZip', 'buyerEmail', 'buyerPhone');
foreach($postOptions as $o) foreach($postOptions as $o)
if (array_key_exists($o, $options)) if (array_key_exists($o, $options))
$post[$o] = $options[$o]; $post[$o] = $options[$o];
$post = json_encode($post); $post = json_encode($post);
$response = bpCurl('https://'.$bpconfig['hostAndPort'].'/api/invoice/', $options['apiKey'], $post); $response = bpCurl('https://'.$bpconfig['hostAndPort'].'/api/invoice/', $options['apiKey'], $post);
@ -89,10 +112,12 @@ function bpCreateInvoice($orderId, $price, $posData, $options = array()) {
// Call from your notification handler to convert $_POST data to an object containing invoice data // Call from your notification handler to convert $_POST data to an object containing invoice data
function bpVerifyNotification($apiKey = false) { function bpVerifyNotification($apiKey = false) {
global $bpOptions, $bpconfig; global $bpOptions, $bpconfig;
if (!$apiKey) if (!$apiKey)
$apiKey = $bpOptions['apiKey']; $apiKey = $bpOptions['apiKey'];
$post = file_get_contents("php://input"); $post = file_get_contents("php://input");
if (!$post) if (!$post)
return 'No post data'; return 'No post data';
@ -105,8 +130,10 @@ function bpVerifyNotification($apiKey = false) {
return 'no posData'; return 'no posData';
$posData = json_decode($json['posData'], true); $posData = json_decode($json['posData'], true);
if($bpOptions['verifyPos'] and $posData['hash'] != crypt(serialize($posData['posData']), $apiKey)) if($bpOptions['verifyPos'] and $posData['hash'] != crypt(serialize($posData['posData']), $apiKey))
return 'authentication failed (bad hash)'; return 'authentication failed (bad hash)';
$json['posData'] = $posData['posData']; $json['posData'] = $posData['posData'];
return $json; return $json;
@ -115,17 +142,19 @@ function bpVerifyNotification($apiKey = false) {
// $options can include ('apiKey') // $options can include ('apiKey')
function bpGetInvoice($invoiceId, $apiKey=false) { function bpGetInvoice($invoiceId, $apiKey=false) {
global $bpOptions, $bpconfig; global $bpOptions, $bpconfig;
if (!$apiKey) if (!$apiKey)
$apiKey = $bpOptions['apiKey']; $apiKey = $bpOptions['apiKey'];
$response = bpCurl('https://'.$bpconfig['hostAndPort'].'/api/invoice/'.$invoiceId, $apiKey); $response = bpCurl('https://'.$bpconfig['hostAndPort'].'/api/invoice/'.$invoiceId, $apiKey);
if (is_string($response)) if (is_string($response))
return $response; // error return $response; // error
$response['posData'] = json_decode($response['posData'], true); $response['posData'] = json_decode($response['posData'], true);
$response['posData'] = $response['posData']['posData']; $response['posData'] = $response['posData']['posData'];
return $response; return $response;
} }
?> ?>

View File

@ -1,5 +1,24 @@
<?php <?php
/**
* ©2011,2012,2013,2014 BITPAY, INC.
*
* Permission is hereby granted to any person obtaining a copy of this software
* and associated documentation for use and/or modification in association with
* the bitpay.com service.
*
* 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.
*
* Bitcoin payment plugin using the bitpay.com service.
*
*/
global $bpOptions; global $bpOptions;
// do not edit this file // do not edit this file