Merge pull request #20 from ionux/master
Corrected company name, license and formatting
This commit is contained in:
commit
70ee93bbff
|
@ -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.
|
||||||
|
|
|
@ -1,76 +1,94 @@
|
||||||
<?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
|
||||||
$this->setTemplate('bitcoins/iframe.phtml');
|
* and associated documentation for use and/or modification in association with
|
||||||
parent::_construct();
|
* the bitpay.com service.
|
||||||
}
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
public function GetQuoteId()
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
{
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
$quote = $this->getQuote();
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
$quoteId = $quote->getId();
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
return $quoteId;
|
* 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.
|
||||||
// create an invoice and return the url so that iframe.phtml can display it
|
*
|
||||||
public function GetIframeUrl()
|
*/
|
||||||
{
|
|
||||||
// are they using bitpay?
|
class Bitpay_Bitcoins_Block_Iframe extends Mage_Checkout_Block_Onepage_Payment {
|
||||||
if (!($quote = Mage::getSingleton('checkout/session')->getQuote())
|
protected function _construct() {
|
||||||
or !($payment = $quote->getPayment())
|
$this->setTemplate('bitcoins/iframe.phtml');
|
||||||
or !($instance = $payment->getMethodInstance())
|
parent::_construct();
|
||||||
or ($instance->getCode() != 'Bitcoins'))
|
}
|
||||||
return 'notbitpay';
|
|
||||||
|
public function GetQuoteId() {
|
||||||
// fullscreen disabled?
|
$quote = $this->getQuote();
|
||||||
if (Mage::getStoreConfig('payment/Bitcoins/fullscreen'))
|
$quoteId = $quote->getId();
|
||||||
return 'disabled';
|
return $quoteId;
|
||||||
|
}
|
||||||
include Mage::getBaseDir('lib').'/bitpay/bp_lib.php';
|
|
||||||
|
// create an invoice and return the url so that iframe.phtml can display it
|
||||||
|
public function GetIframeUrl() {
|
||||||
|
// are they using bitpay?
|
||||||
|
if (!($quote = Mage::getSingleton('checkout/session')->getQuote())
|
||||||
|
or !($payment = $quote->getPayment())
|
||||||
|
or !($instance = $payment->getMethodInstance())
|
||||||
|
or ($instance->getCode() != 'Bitcoins'))
|
||||||
|
return 'notbitpay';
|
||||||
|
|
||||||
|
// fullscreen disabled?
|
||||||
|
if (Mage::getStoreConfig('payment/Bitcoins/fullscreen'))
|
||||||
|
return 'disabled';
|
||||||
|
|
||||||
|
include Mage::getBaseDir('lib').'/bitpay/bp_lib.php';
|
||||||
|
|
||||||
|
$apiKey = Mage::getStoreConfig('payment/Bitcoins/api_key');
|
||||||
|
$speed = Mage::getStoreConfig('payment/Bitcoins/speed');
|
||||||
|
|
||||||
|
$quote = $this->getQuote();
|
||||||
|
$quoteId = $quote->getId();
|
||||||
|
|
||||||
|
if (Mage::getModel('Bitcoins/ipn')->GetQuotePaid($quoteId))
|
||||||
|
return 'paid'; // quote's already paid, so don't show the iframe
|
||||||
|
|
||||||
|
|
||||||
|
$options = array(
|
||||||
|
'currency' => $quote->getQuoteCurrencyCode(),
|
||||||
|
'fullNotifications' => 'true',
|
||||||
|
'notificationURL' => Mage::getUrl('bitpay_callback'),
|
||||||
|
'redirectURL' => Mage::getUrl('checkout/onepage/success'),
|
||||||
|
'transactionSpeed' => $speed,
|
||||||
|
'apiKey' => $apiKey,
|
||||||
|
);
|
||||||
|
|
||||||
|
// customer data
|
||||||
|
$method = Mage::getModel('Bitcoins/paymentMethod');
|
||||||
|
$options += $method->ExtractAddress($quote->getShippingAddress());
|
||||||
|
|
||||||
|
// Mage doesn't round the total until saving and it can have more precision at this point which would be bad for later comparing records w/ bitpay. So round here to match what the price will be saved as:
|
||||||
|
$price = round($quote->getGrandTotal(),4);
|
||||||
|
|
||||||
|
//serialize info about the quote to detect changes
|
||||||
|
$hash = $method->getQuoteHash($quoteId);
|
||||||
|
|
||||||
|
Mage::log('invoicing for '.$price.' '.$quote->getQuoteCurrencyCode(), NULL, 'bitpay.log');
|
||||||
|
|
||||||
|
$invoice = bpCreateInvoice($quoteId, $price, array('quoteId' => $quoteId, 'quoteHash' => $hash), $options);
|
||||||
|
|
||||||
|
Mage::log($invoice, NULL, 'bitpay.log');
|
||||||
|
|
||||||
|
if (array_key_exists('error', $invoice)) {
|
||||||
|
Mage::log('Error creating bitpay invoice', 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.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $invoice['url'].'&view=iframe';
|
||||||
|
}
|
||||||
|
|
||||||
$apiKey = Mage::getStoreConfig('payment/Bitcoins/api_key');
|
|
||||||
$speed = Mage::getStoreConfig('payment/Bitcoins/speed');
|
|
||||||
|
|
||||||
$quote = $this->getQuote();
|
|
||||||
$quoteId = $quote->getId();
|
|
||||||
if (Mage::getModel('Bitcoins/ipn')->GetQuotePaid($quoteId))
|
|
||||||
return 'paid'; // quote's already paid, so don't show the iframe
|
|
||||||
|
|
||||||
$options = array(
|
|
||||||
'currency' => $quote->getQuoteCurrencyCode(),
|
|
||||||
'fullNotifications' => 'true',
|
|
||||||
'notificationURL' => Mage::getUrl('bitpay_callback'),
|
|
||||||
'redirectURL' => Mage::getUrl('checkout/onepage/success'),
|
|
||||||
'transactionSpeed' => $speed,
|
|
||||||
'apiKey' => $apiKey,
|
|
||||||
);
|
|
||||||
|
|
||||||
// customer data
|
|
||||||
$method = Mage::getModel('Bitcoins/paymentMethod');
|
|
||||||
$options += $method->ExtractAddress($quote->getShippingAddress());
|
|
||||||
|
|
||||||
// Mage doesn't round the total until saving and it can have more precision at this point which would be bad for later comparing records w/ bitpay. So round here to match what the price will be saved as:
|
|
||||||
$price = round($quote->getGrandTotal(),4);
|
|
||||||
|
|
||||||
//serialize info about the quote to detect changes
|
|
||||||
$hash = $method->getQuoteHash($quoteId);
|
|
||||||
|
|
||||||
Mage::log('invoicing for '.$price.' '.$quote->getQuoteCurrencyCode(), NULL, 'bitpay.log');
|
|
||||||
$invoice = bpCreateInvoice($quoteId, $price, array('quoteId' => $quoteId, 'quoteHash' => $hash), $options);
|
|
||||||
Mage::log($invoice, NULL, 'bitpay.log');
|
|
||||||
|
|
||||||
if (array_key_exists('error', $invoice))
|
|
||||||
{
|
|
||||||
Mage::log('Error creating bitpay invoice', 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.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $invoice['url'].'&view=iframe';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,80 +1,92 @@
|
||||||
<?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
|
||||||
$this->_init('Bitcoins/ipn');
|
* and associated documentation for use and/or modification in association with
|
||||||
return parent::_construct();
|
* the bitpay.com service.
|
||||||
}
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
function Record($invoice)
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
{
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
return $this
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
->setQuoteId(isset($invoice['posData']['quoteId']) ? $invoice['posData']['quoteId'] : NULL)
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
->setOrderId(isset($invoice['posData']['orderId']) ? $invoice['posData']['orderId'] : NULL)
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
->setPosData(json_encode($invoice['posData']))
|
* THE SOFTWARE.
|
||||||
->setInvoiceId($invoice['id'])
|
*
|
||||||
->setUrl($invoice['url'])
|
* Bitcoin payment plugin using the bitpay.com service.
|
||||||
->setStatus($invoice['status'])
|
*
|
||||||
->setBtcPrice($invoice['btcPrice'])
|
*/
|
||||||
->setPrice($invoice['price'])
|
|
||||||
->setCurrency($invoice['currency'])
|
class Bitpay_Bitcoins_Model_Ipn extends Mage_Core_Model_Abstract {
|
||||||
->setInvoiceTime(intval($invoice['invoiceTime']/1000.0))
|
|
||||||
->setExpirationTime(intval($invoice['expirationTime']/1000.0))
|
function _construct() {
|
||||||
->setCurrentTime(intval($invoice['currentTime']/1000.0))
|
$this->_init('Bitcoins/ipn');
|
||||||
->save();
|
return parent::_construct();
|
||||||
}
|
}
|
||||||
|
|
||||||
function GetStatusReceived($quoteId, $statuses)
|
function Record($invoice) {
|
||||||
{
|
return $this
|
||||||
if (!$quoteId)
|
->setQuoteId(isset($invoice['posData']['quoteId']) ? $invoice['posData']['quoteId'] : NULL)
|
||||||
return false;
|
->setOrderId(isset($invoice['posData']['orderId']) ? $invoice['posData']['orderId'] : NULL)
|
||||||
|
->setPosData(json_encode($invoice['posData']))
|
||||||
$quote = Mage::getModel('sales/quote')->load($quoteId, 'entity_id');
|
->setInvoiceId($invoice['id'])
|
||||||
if (!$quote)
|
->setUrl($invoice['url'])
|
||||||
{
|
->setStatus($invoice['status'])
|
||||||
Mage::log('quote not found', NULL, 'bitpay.log');
|
->setBtcPrice($invoice['btcPrice'])
|
||||||
return false;
|
->setPrice($invoice['price'])
|
||||||
}
|
->setCurrency($invoice['currency'])
|
||||||
|
->setInvoiceTime(intval($invoice['invoiceTime']/1000.0))
|
||||||
$quoteHash = Mage::getModel('Bitcoins/paymentMethod')->getQuoteHash($quoteId);
|
->setExpirationTime(intval($invoice['expirationTime']/1000.0))
|
||||||
if (!$quoteHash)
|
->setCurrentTime(intval($invoice['currentTime']/1000.0))
|
||||||
{
|
->save();
|
||||||
Mage::log('Could not find quote hash for quote '.$quoteId, NULL, 'bitpay.log');
|
}
|
||||||
return false;
|
|
||||||
}
|
function GetStatusReceived($quoteId, $statuses) {
|
||||||
|
if (!$quoteId)
|
||||||
$collection = $this->getCollection()->AddFilter('quote_id', $quoteId);
|
return false;
|
||||||
foreach($collection as $i)
|
|
||||||
{
|
$quote = Mage::getModel('sales/quote')->load($quoteId, 'entity_id');
|
||||||
if (in_array($i->getStatus(), $statuses))
|
|
||||||
{
|
if (!$quote) {
|
||||||
// check that quote data was not updated after IPN sent
|
Mage::log('quote not found', NULL, 'bitpay.log');
|
||||||
$posData = json_decode($i->getPosData());
|
return false;
|
||||||
if (!$posData)
|
}
|
||||||
continue;
|
|
||||||
|
$quoteHash = Mage::getModel('Bitcoins/paymentMethod')->getQuoteHash($quoteId);
|
||||||
if ($quoteHash == $posData->quoteHash)
|
|
||||||
return true;
|
if (!$quoteHash) {
|
||||||
}
|
Mage::log('Could not find quote hash for quote '.$quoteId, NULL, 'bitpay.log');
|
||||||
}
|
return false;
|
||||||
|
}
|
||||||
return false;
|
|
||||||
}
|
$collection = $this->getCollection()->AddFilter('quote_id', $quoteId);
|
||||||
|
|
||||||
function GetQuotePaid($quoteId)
|
foreach($collection as $i) {
|
||||||
{
|
if (in_array($i->getStatus(), $statuses)) {
|
||||||
return $this->GetStatusReceived($quoteId, array('paid', 'confirmed', 'complete'));
|
// check that quote data was not updated after IPN sent
|
||||||
}
|
$posData = json_decode($i->getPosData());
|
||||||
|
|
||||||
function GetQuoteComplete($quoteId)
|
if (!$posData)
|
||||||
{
|
continue;
|
||||||
return $this->GetStatusReceived($quoteId, array('confirmed', 'complete'));
|
|
||||||
}
|
if ($quoteHash == $posData->quoteHash)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
|
||||||
|
return false;
|
||||||
?>
|
}
|
||||||
|
|
||||||
|
function GetQuotePaid($quoteId) {
|
||||||
|
return $this->GetStatusReceived($quoteId, array('paid', 'confirmed', 'complete'));
|
||||||
|
}
|
||||||
|
|
||||||
|
function GetQuoteComplete($quoteId) {
|
||||||
|
return $this->GetStatusReceived($quoteId, array('confirmed', 'complete'));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
|
@ -1,253 +1,255 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Our test CC module adapter
|
* ©2011,2012,2013,2014 BITPAY, INC.
|
||||||
*/
|
*
|
||||||
class Bitpay_Bitcoins_Model_PaymentMethod extends Mage_Payment_Model_Method_Abstract
|
* 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.
|
||||||
* unique internal payment method identifier
|
*
|
||||||
*
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* @var string [a-z0-9_]
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
*/
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
protected $_code = 'Bitcoins';
|
* 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
|
||||||
|
*/
|
||||||
|
class Bitpay_Bitcoins_Model_PaymentMethod extends Mage_Payment_Model_Method_Abstract {
|
||||||
|
/**
|
||||||
|
* unique internal payment method identifier
|
||||||
|
*
|
||||||
|
* @var string [a-z0-9_]
|
||||||
|
*/
|
||||||
|
protected $_code = 'Bitcoins';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Here are examples of flags that will determine functionality availability
|
* Here are examples of flags that will determine functionality availability
|
||||||
* of this module to be used by frontend and backend.
|
* of this module to be used by frontend and backend.
|
||||||
*
|
*
|
||||||
* @see all flags and their defaults in Mage_Payment_Model_Method_Abstract
|
* @see all flags and their defaults in Mage_Payment_Model_Method_Abstract
|
||||||
*
|
*
|
||||||
* It is possible to have a custom dynamic logic by overloading
|
* It is possible to have a custom dynamic logic by overloading
|
||||||
* public function can* for each flag respectively
|
* public function can* for each flag respectively
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is this payment method a gateway (online auth/charge) ?
|
* Is this payment method a gateway (online auth/charge) ?
|
||||||
*/
|
*/
|
||||||
protected $_isGateway = true;
|
protected $_isGateway = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Can authorize online?
|
* Can authorize online?
|
||||||
*/
|
*/
|
||||||
protected $_canAuthorize = true;
|
protected $_canAuthorize = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Can capture funds online?
|
* Can capture funds online?
|
||||||
*/
|
*/
|
||||||
protected $_canCapture = false;
|
protected $_canCapture = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Can capture partial amounts online?
|
* Can capture partial amounts online?
|
||||||
*/
|
*/
|
||||||
protected $_canCapturePartial = false;
|
protected $_canCapturePartial = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Can refund online?
|
* Can refund online?
|
||||||
*/
|
*/
|
||||||
protected $_canRefund = false;
|
protected $_canRefund = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Can void transactions online?
|
* Can void transactions online?
|
||||||
*/
|
*/
|
||||||
protected $_canVoid = false;
|
protected $_canVoid = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Can use this payment method in administration panel?
|
* Can use this payment method in administration panel?
|
||||||
*/
|
*/
|
||||||
protected $_canUseInternal = false;
|
protected $_canUseInternal = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Can show this payment method as an option on checkout payment page?
|
* Can show this payment method as an option on checkout payment page?
|
||||||
*/
|
*/
|
||||||
protected $_canUseCheckout = true;
|
protected $_canUseCheckout = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is this payment method suitable for multi-shipping checkout?
|
* Is this payment method suitable for multi-shipping checkout?
|
||||||
*/
|
*/
|
||||||
protected $_canUseForMultishipping = true;
|
protected $_canUseForMultishipping = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Can save credit card information for future processing?
|
* Can save credit card information for future processing?
|
||||||
*/
|
*/
|
||||||
protected $_canSaveCc = false;
|
protected $_canSaveCc = false;
|
||||||
|
|
||||||
//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');
|
||||||
{
|
|
||||||
|
if (!$secret or !strlen($secret)) {
|
||||||
$secret = Mage::getStoreConfig('payment/Bitcoins/api_key');
|
Mage::log('Bitpay/Bitcoins: API key not entered', null, 'bitpay.log');
|
||||||
if (!$secret or !strlen($secret))
|
return false;
|
||||||
{
|
}
|
||||||
Mage::log('Bitpay/Bitcoins: API key not entered', null, 'bitpay.log');
|
|
||||||
return false;
|
$speed = Mage::getStoreConfig('payment/Bitcoins/speed');
|
||||||
}
|
|
||||||
|
if (!$speed or !strlen($speed)) {
|
||||||
$speed = Mage::getStoreConfig('payment/Bitcoins/speed');
|
Mage::log('Bitpay/Bitcoins: Transaction Speed invalid', null, 'bitpay.log');
|
||||||
if (!$speed or !strlen($speed))
|
return false;
|
||||||
{
|
}
|
||||||
Mage::log('Bitpay/Bitcoins: Transaction Speed invalid', null, 'bitpay.log');
|
|
||||||
return false;
|
return $this->_canUseCheckout;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->_canUseCheckout;
|
public function authorize(Varien_Object $payment, $amount) {
|
||||||
|
if (!Mage::getStoreConfig('payment/Bitcoins/fullscreen'))
|
||||||
|
return $this->CheckForPayment($payment);
|
||||||
|
else
|
||||||
|
return $this->CreateInvoiceAndRedirect($payment, $amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
function CheckForPayment($payment) {
|
||||||
|
$quoteId = $payment->getOrder()->getQuoteId();
|
||||||
|
$ipn = Mage::getModel('Bitcoins/ipn');
|
||||||
|
|
||||||
|
if (!$ipn->GetQuotePaid($quoteId)) {
|
||||||
|
Mage::throwException("Order not paid for. Please pay first and then Place your Order.");
|
||||||
|
} else if (!$ipn->GetQuoteComplete($quoteId)) {
|
||||||
|
// order status will be PAYMENT_REVIEW instead of PROCESSING
|
||||||
|
$payment->setIsTransactionPending(true);
|
||||||
|
} else {
|
||||||
|
$this->MarkOrderPaid($payment->getOrder());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function authorize(Varien_Object $payment, $amount)
|
return $this;
|
||||||
{
|
}
|
||||||
if (!Mage::getStoreConfig('payment/Bitcoins/fullscreen'))
|
|
||||||
return $this->CheckForPayment($payment);
|
function MarkOrderPaid($order) {
|
||||||
else
|
$order->setState(Mage_Sales_Model_Order::STATE_PROCESSING, true)->save();
|
||||||
return $this->CreateInvoiceAndRedirect($payment, $amount);
|
|
||||||
|
|
||||||
}
|
if (!count($order->getInvoiceCollection())) {
|
||||||
|
$invoice = $order->prepareInvoice()
|
||||||
function CheckForPayment($payment)
|
->setTransactionId(1)
|
||||||
{
|
->addComment('Invoiced automatically by Bitpay/Bitcoins/controllers/IndexController.php')
|
||||||
$quoteId = $payment->getOrder()->getQuoteId();
|
->register()
|
||||||
$ipn = Mage::getModel('Bitcoins/ipn');
|
->pay();
|
||||||
if (!$ipn->GetQuotePaid($quoteId))
|
|
||||||
{
|
|
||||||
Mage::throwException("Order not paid for. Please pay first and then Place your Order.");
|
|
||||||
}
|
|
||||||
else if (!$ipn->GetQuoteComplete($quoteId))
|
|
||||||
{
|
|
||||||
// order status will be PAYMENT_REVIEW instead of PROCESSING
|
|
||||||
$payment->setIsTransactionPending(true);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$this->MarkOrderPaid($payment->getOrder());
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
function MarkOrderPaid($order)
|
|
||||||
{
|
|
||||||
$order->setState(Mage_Sales_Model_Order::STATE_PROCESSING, true)->save();
|
|
||||||
if (!count($order->getInvoiceCollection()))
|
|
||||||
{
|
|
||||||
$invoice = $order->prepareInvoice()
|
|
||||||
->setTransactionId(1)
|
|
||||||
->addComment('Invoiced automatically by Bitpay/Bitcoins/controllers/IndexController.php')
|
|
||||||
->register()
|
|
||||||
->pay();
|
|
||||||
|
|
||||||
$transactionSave = Mage::getModel('core/resource_transaction')
|
$transactionSave = Mage::getModel('core/resource_transaction')
|
||||||
->addObject($invoice)
|
->addObject($invoice)
|
||||||
->addObject($invoice->getOrder());
|
->addObject($invoice->getOrder());
|
||||||
$transactionSave->save();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// given Mage_Core_Model_Abstract, return api-friendly address
|
|
||||||
function ExtractAddress($address)
|
|
||||||
{
|
|
||||||
$options = array();
|
|
||||||
$options['buyerName'] = $address->getName();
|
|
||||||
if ($address->getCompany())
|
|
||||||
$options['buyerName'] = $options['buyerName'].' c/o '.$address->getCompany();
|
|
||||||
$options['buyerAddress1'] = $address->getStreet1();
|
|
||||||
$options['buyerAddress2'] = $address->getStreet2();
|
|
||||||
$options['buyerAddress3'] = $address->getStreet3();
|
|
||||||
$options['buyerAddress4'] = $address->getStreet4();
|
|
||||||
$options['buyerCity'] = $address->getCity();
|
|
||||||
$options['buyerState'] = $address->getRegionCode();
|
|
||||||
$options['buyerZip'] = $address->getPostcode();
|
|
||||||
$options['buyerCountry'] = $address->getCountry();
|
|
||||||
$options['buyerEmail'] = $address->getEmail();
|
|
||||||
$options['buyerPhone'] = $address->getTelephone();
|
|
||||||
// trim to fit API specs
|
|
||||||
foreach(array('buyerName', 'buyerAddress1', 'buyerAddress2', 'buyerAddress3', 'buyerAddress4', 'buyerCity', 'buyerState', 'buyerZip', 'buyerCountry', 'buyerEmail', 'buyerPhone') as $f)
|
|
||||||
$options[$f] = substr($options[$f], 0, 100);
|
|
||||||
return $options;
|
|
||||||
}
|
|
||||||
|
|
||||||
function CreateInvoiceAndRedirect($payment, $amount)
|
|
||||||
{
|
|
||||||
include Mage::getBaseDir('lib').'/bitpay/bp_lib.php';
|
|
||||||
|
|
||||||
$apiKey = Mage::getStoreConfig('payment/Bitcoins/api_key');
|
$transactionSave->save();
|
||||||
$speed = Mage::getStoreConfig('payment/Bitcoins/speed');
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// given Mage_Core_Model_Abstract, return api-friendly address
|
||||||
|
function ExtractAddress($address) {
|
||||||
|
$options = array();
|
||||||
|
$options['buyerName'] = $address->getName();
|
||||||
|
|
||||||
$order = $payment->getOrder();
|
if ($address->getCompany())
|
||||||
$orderId = $order->getIncrementId();
|
$options['buyerName'] = $options['buyerName'].' c/o '.$address->getCompany();
|
||||||
$options = array(
|
|
||||||
'currency' => $order->getBaseCurrencyCode(),
|
|
||||||
'buyerName' => $order->getCustomerFirstname().' '.$order->getCustomerLastname(),
|
|
||||||
'fullNotifications' => 'true',
|
|
||||||
'notificationURL' => Mage::getUrl('bitpay_callback'),
|
|
||||||
'redirectURL' => Mage::getUrl('checkout/onepage/success'),
|
|
||||||
'transactionSpeed' => $speed,
|
|
||||||
'apiKey' => $apiKey,
|
|
||||||
);
|
|
||||||
$options += $this->ExtractAddress($order->getShippingAddress());
|
|
||||||
|
|
||||||
$invoice = bpCreateInvoice($orderId, $amount, array('orderId' => $orderId), $options);
|
|
||||||
|
|
||||||
$payment->setIsTransactionPending(true); // status will be PAYMENT_REVIEW instead of PROCESSING
|
$options['buyerAddress1'] = $address->getStreet1();
|
||||||
|
$options['buyerAddress2'] = $address->getStreet2();
|
||||||
|
$options['buyerAddress3'] = $address->getStreet3();
|
||||||
|
$options['buyerAddress4'] = $address->getStreet4();
|
||||||
|
$options['buyerCity'] = $address->getCity();
|
||||||
|
$options['buyerState'] = $address->getRegionCode();
|
||||||
|
$options['buyerZip'] = $address->getPostcode();
|
||||||
|
$options['buyerCountry'] = $address->getCountry();
|
||||||
|
$options['buyerEmail'] = $address->getEmail();
|
||||||
|
$options['buyerPhone'] = $address->getTelephone();
|
||||||
|
|
||||||
if (array_key_exists('error', $invoice))
|
// trim to fit API specs
|
||||||
{
|
foreach(array('buyerName', 'buyerAddress1', 'buyerAddress2', 'buyerAddress3', 'buyerAddress4', 'buyerCity', 'buyerState', 'buyerZip', 'buyerCountry', 'buyerEmail', 'buyerPhone') as $f)
|
||||||
Mage::log('Error creating bitpay invoice', null, 'bitpay.log');
|
$options[$f] = substr($options[$f], 0, 100);
|
||||||
Mage::log($invoice['error'], null, 'bitpay.log');
|
|
||||||
Mage::throwException("Error creating bit-pay invoice. Please try again or use another payment option.");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$invoiceId = Mage::getModel('sales/order_invoice_api')->create($orderId, array());
|
|
||||||
Mage::getSingleton('customer/session')->setRedirectUrl($invoice['url']);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this;
|
return $options;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function CreateInvoiceAndRedirect($payment, $amount) {
|
||||||
|
include Mage::getBaseDir('lib').'/bitpay/bp_lib.php';
|
||||||
|
|
||||||
public function getOrderPlaceRedirectUrl()
|
$apiKey = Mage::getStoreConfig('payment/Bitcoins/api_key');
|
||||||
{
|
$speed = Mage::getStoreConfig('payment/Bitcoins/speed');
|
||||||
if (Mage::getStoreConfig('payment/Bitcoins/fullscreen'))
|
$order = $payment->getOrder();
|
||||||
return Mage::getSingleton('customer/session')->getRedirectUrl();
|
$orderId = $order->getIncrementId();
|
||||||
else
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
# computes a unique hash determined by the contents of the cart
|
|
||||||
public function getQuoteHash($quoteId)
|
|
||||||
{
|
|
||||||
$quote = Mage::getModel('sales/quote')->load($quoteId, 'entity_id');
|
|
||||||
if (!$quote)
|
|
||||||
{
|
|
||||||
Mage::log('getQuoteTimestamp: quote not found', NULL, 'bitpay.log');
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
#encode items
|
|
||||||
$items = $quote->getAllItems();
|
|
||||||
$latest = NULL;
|
|
||||||
$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
|
$options = array(
|
||||||
}
|
'currency' => $order->getBaseCurrencyCode(),
|
||||||
|
'buyerName' => $order->getCustomerFirstname().' '.$order->getCustomerLastname(),
|
||||||
$hash = base64_encode(hash_hmac('sha256', $description, $quoteId));
|
'fullNotifications' => 'true',
|
||||||
$hash = substr($hash, 0, 30); // fit it in posData maxlen
|
'notificationURL' => Mage::getUrl('bitpay_callback'),
|
||||||
|
'redirectURL' => Mage::getUrl('checkout/onepage/success'),
|
||||||
Mage::log("quote $quoteId descr $description hash $hash", NULL, 'bitpay.log');
|
'transactionSpeed' => $speed,
|
||||||
|
'apiKey' => $apiKey,
|
||||||
return $hash;
|
);
|
||||||
}
|
|
||||||
|
$options += $this->ExtractAddress($order->getShippingAddress());
|
||||||
|
$invoice = bpCreateInvoice($orderId, $amount, array('orderId' => $orderId), $options);
|
||||||
|
$payment->setIsTransactionPending(true); // status will be PAYMENT_REVIEW instead of PROCESSING
|
||||||
|
|
||||||
|
if (array_key_exists('error', $invoice)) {
|
||||||
|
Mage::log('Error creating bitpay invoice', 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.");
|
||||||
|
} else {
|
||||||
|
$invoiceId = Mage::getModel('sales/order_invoice_api')->create($orderId, array());
|
||||||
|
Mage::getSingleton('customer/session')->setRedirectUrl($invoice['url']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getOrderPlaceRedirectUrl() {
|
||||||
|
if (Mage::getStoreConfig('payment/Bitcoins/fullscreen'))
|
||||||
|
return Mage::getSingleton('customer/session')->getRedirectUrl();
|
||||||
|
else
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
// computes a unique hash determined by the contents of the cart
|
||||||
|
public function getQuoteHash($quoteId) {
|
||||||
|
$quote = Mage::getModel('sales/quote')->load($quoteId, 'entity_id');
|
||||||
|
if (!$quote) {
|
||||||
|
Mage::log('getQuoteTimestamp: quote not found', NULL, 'bitpay.log');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// encode items
|
||||||
|
$items = $quote->getAllItems();
|
||||||
|
$latest = NULL;
|
||||||
|
$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
|
||||||
|
}
|
||||||
|
|
||||||
|
$hash = base64_encode(hash_hmac('sha256', $description, $quoteId));
|
||||||
|
$hash = substr($hash, 0, 30); // fit it in posData maxlen
|
||||||
|
|
||||||
|
Mage::log("quote $quoteId descr $description hash $hash", NULL, 'bitpay.log');
|
||||||
|
|
||||||
|
return $hash;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
|
|
|
@ -1,11 +1,28 @@
|
||||||
<?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
|
||||||
$this->_init('Bitcoins/ipn', 'id');
|
* 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');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
|
|
@ -1,11 +1,28 @@
|
||||||
<?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
|
||||||
$this->_init('Bitcoins/ipn');
|
* 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');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
|
@ -1,24 +1,40 @@
|
||||||
<?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
|
||||||
return array(
|
* the bitpay.com service.
|
||||||
array(
|
*
|
||||||
'value' => 'low',
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
'label' => 'Low',
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
),
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
array(
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
'value' => 'medium',
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
'label' => 'Medium',
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
),
|
* THE SOFTWARE.
|
||||||
array(
|
*
|
||||||
'value' => 'high',
|
* Bitcoin payment plugin using the bitpay.com service.
|
||||||
'label' => 'High',
|
*
|
||||||
));
|
*/
|
||||||
}
|
|
||||||
|
class Bitpay_Bitcoins_Model_Source_Speed {
|
||||||
|
public function toOptionArray() {
|
||||||
|
return array(
|
||||||
|
array(
|
||||||
|
'value' => 'low',
|
||||||
|
'label' => 'Low',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'value' => 'medium',
|
||||||
|
'label' => 'Medium',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'value' => 'high',
|
||||||
|
'label' => 'High',
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
|
|
@ -1,53 +1,69 @@
|
||||||
<?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);
|
print json_encode(array('paid' => $paid));
|
||||||
print json_encode(array('paid' => $paid));
|
exit();
|
||||||
exit();
|
}
|
||||||
}
|
|
||||||
|
// 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');
|
||||||
|
$apiKey = Mage::getStoreConfig('payment/Bitcoins/api_key');
|
||||||
Mage::log(file_get_contents('php://input'), null, 'bitpay.log');
|
$invoice = bpVerifyNotification($apiKey);
|
||||||
|
|
||||||
$apiKey = Mage::getStoreConfig('payment/Bitcoins/api_key');
|
if (is_string($invoice))
|
||||||
$invoice = bpVerifyNotification($apiKey);
|
Mage::log("bitpay callback error: $invoice", null, 'bitpay.log');
|
||||||
|
else {
|
||||||
if (is_string($invoice))
|
// get the order
|
||||||
Mage::log("bitpay callback error: $invoice", null, 'bitpay.log');
|
if (isset($invoice['posData']['quoteId'])) {
|
||||||
else {
|
$quoteId = $invoice['posData']['quoteId'];
|
||||||
// get the order
|
$order = Mage::getModel('sales/order')->load($quoteId, 'quote_id');
|
||||||
if (isset($invoice['posData']['quoteId'])) {
|
} else {
|
||||||
$quoteId = $invoice['posData']['quoteId'];
|
$orderId = $invoice['posData']['orderId'];
|
||||||
$order = Mage::getModel('sales/order')->load($quoteId, 'quote_id');
|
$order = Mage::getModel('sales/order')->loadByIncrementId($orderId);
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
$orderId = $invoice['posData']['orderId'];
|
// save the ipn so that we can find it when the user clicks "Place Order"
|
||||||
$order = Mage::getModel('sales/order')->loadByIncrementId($orderId);
|
Mage::getModel('Bitcoins/ipn')->Record($invoice);
|
||||||
}
|
|
||||||
|
// update the order if it exists already
|
||||||
// save the ipn so that we can find it when the user clicks "Place Order"
|
if ($order->getId())
|
||||||
Mage::getModel('Bitcoins/ipn')->Record($invoice);
|
switch($invoice['status']) {
|
||||||
|
case 'confirmed':
|
||||||
// update the order if it exists already
|
case 'complete':
|
||||||
if ($order->getId())
|
$method = Mage::getModel('Bitcoins/paymentMethod');
|
||||||
switch($invoice['status']) {
|
$method->MarkOrderPaid($order);
|
||||||
case 'confirmed':
|
break;
|
||||||
case 'complete':
|
}
|
||||||
$method = Mage::getModel('Bitcoins/paymentMethod');
|
|
||||||
$method->MarkOrderPaid($order);
|
}
|
||||||
|
|
||||||
break;
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
|
|
|
@ -1,49 +1,70 @@
|
||||||
<?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';
|
||||||
|
|
||||||
function bpCurl($url, $apiKey, $post = false) {
|
function bpCurl($url, $apiKey, $post = false) {
|
||||||
global $bpOptions, $bpconfig;
|
global $bpOptions, $bpconfig;
|
||||||
|
|
||||||
$curl = curl_init($url);
|
|
||||||
$length = 0;
|
|
||||||
if ($post)
|
|
||||||
{
|
|
||||||
curl_setopt($curl, CURLOPT_POST, 1);
|
|
||||||
curl_setopt($curl, CURLOPT_POSTFIELDS, $post);
|
|
||||||
$length = strlen($post);
|
|
||||||
}
|
|
||||||
|
|
||||||
$uname = base64_encode($apiKey);
|
|
||||||
$header = array(
|
|
||||||
'Content-Type: application/json',
|
|
||||||
"Content-Length: $length",
|
|
||||||
"Authorization: Basic $uname",
|
|
||||||
);
|
|
||||||
|
|
||||||
curl_setopt($curl, CURLOPT_PORT, $bpconfig['port']);
|
$curl = curl_init($url);
|
||||||
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
|
$length = 0;
|
||||||
curl_setopt($curl, CURLOPT_TIMEOUT, 10);
|
|
||||||
curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC ) ;
|
if ($post) {
|
||||||
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, $bpconfig['ssl_verifypeer']); // verify certificate
|
curl_setopt($curl, CURLOPT_POST, 1);
|
||||||
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, $bpconfig['ssl_verifyhost']); // check existence of CN and verify that it matches hostname
|
curl_setopt($curl, CURLOPT_POSTFIELDS, $post);
|
||||||
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
|
$length = strlen($post);
|
||||||
curl_setopt($curl, CURLOPT_FORBID_REUSE, 1);
|
}
|
||||||
curl_setopt($curl, CURLOPT_FRESH_CONNECT, 1);
|
|
||||||
|
$uname = base64_encode($apiKey);
|
||||||
$responseString = curl_exec($curl);
|
$header = array(
|
||||||
|
'Content-Type: application/json',
|
||||||
if($responseString == false) {
|
'Content-Length: ' . $length,
|
||||||
$response = array('error' => curl_error($curl));
|
'Authorization: Basic ' . $uname,
|
||||||
} else {
|
);
|
||||||
$response = json_decode($responseString, true);
|
|
||||||
if (!$response)
|
curl_setopt($curl, CURLOPT_PORT, $bpconfig['port']);
|
||||||
$response = array('error' => 'invalid json: '.$responseString);
|
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
|
||||||
}
|
curl_setopt($curl, CURLOPT_TIMEOUT, 10);
|
||||||
curl_close($curl);
|
curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC ) ;
|
||||||
return $response;
|
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, $bpconfig['ssl_verifypeer']); // verify certificate
|
||||||
|
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, $bpconfig['ssl_verifyhost']); // check existence of CN and verify that it matches hostname
|
||||||
|
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
|
||||||
|
curl_setopt($curl, CURLOPT_FORBID_REUSE, 1);
|
||||||
|
curl_setopt($curl, CURLOPT_FRESH_CONNECT, 1);
|
||||||
|
|
||||||
|
$responseString = curl_exec($curl);
|
||||||
|
|
||||||
|
if($responseString == false) {
|
||||||
|
$response = array('error' => curl_error($curl));
|
||||||
|
} else {
|
||||||
|
$response = json_decode($responseString, true);
|
||||||
|
if (!$response)
|
||||||
|
$response = array('error' => 'invalid json: '.$responseString);
|
||||||
|
}
|
||||||
|
|
||||||
|
curl_close($curl);
|
||||||
|
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.
|
||||||
//
|
//
|
||||||
|
@ -61,71 +82,79 @@ function bpCurl($url, $apiKey, $post = false) {
|
||||||
// If a given option is not provided here, the value of that option will default to what is found in bp_options.php
|
// If a given option is not provided here, the value of that option will default to what is found in bp_options.php
|
||||||
// (see api documentation for information on these options).
|
// (see api documentation for information on these options).
|
||||||
function bpCreateInvoice($orderId, $price, $posData, $options = array()) {
|
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
|
|
||||||
|
|
||||||
$pos = array('posData' => $posData);
|
|
||||||
if ($bpOptions['verifyPos'])
|
|
||||||
$pos['hash'] = crypt(serialize($posData), $options['apiKey']);
|
|
||||||
$options['posData'] = json_encode($pos);
|
|
||||||
|
|
||||||
$options['orderID'] = $orderId;
|
|
||||||
$options['price'] = $price;
|
|
||||||
|
|
||||||
$postOptions = array('orderID', 'itemDesc', 'itemCode', 'notificationEmail', 'notificationURL', 'redirectURL',
|
|
||||||
'posData', 'price', 'currency', 'physical', 'fullNotifications', 'transactionSpeed', 'buyerName',
|
|
||||||
'buyerAddress1', 'buyerAddress2', 'buyerCity', 'buyerState', 'buyerZip', 'buyerEmail', 'buyerPhone');
|
|
||||||
foreach($postOptions as $o)
|
|
||||||
if (array_key_exists($o, $options))
|
|
||||||
$post[$o] = $options[$o];
|
|
||||||
$post = json_encode($post);
|
|
||||||
|
|
||||||
$response = bpCurl('https://'.$bpconfig['hostAndPort'].'/api/invoice/', $options['apiKey'], $post);
|
|
||||||
|
|
||||||
return $response;
|
$options = array_merge($bpOptions, $options); // $options override any options found in bp_options.php
|
||||||
|
$pos = array('posData' => $posData);
|
||||||
|
|
||||||
|
if ($bpOptions['verifyPos'])
|
||||||
|
$pos['hash'] = crypt(serialize($posData), $options['apiKey']);
|
||||||
|
|
||||||
|
$options['posData'] = json_encode($pos);
|
||||||
|
$options['orderID'] = $orderId;
|
||||||
|
$options['price'] = $price;
|
||||||
|
|
||||||
|
$postOptions = array('orderID', 'itemDesc', 'itemCode', 'notificationEmail', 'notificationURL', 'redirectURL',
|
||||||
|
'posData', 'price', 'currency', 'physical', 'fullNotifications', 'transactionSpeed', 'buyerName',
|
||||||
|
'buyerAddress1', 'buyerAddress2', 'buyerCity', 'buyerState', 'buyerZip', 'buyerEmail', 'buyerPhone');
|
||||||
|
|
||||||
|
foreach($postOptions as $o)
|
||||||
|
if (array_key_exists($o, $options))
|
||||||
|
$post[$o] = $options[$o];
|
||||||
|
|
||||||
|
$post = json_encode($post);
|
||||||
|
|
||||||
|
$response = bpCurl('https://'.$bpconfig['hostAndPort'].'/api/invoice/', $options['apiKey'], $post);
|
||||||
|
|
||||||
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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)
|
|
||||||
$apiKey = $bpOptions['apiKey'];
|
|
||||||
|
|
||||||
$post = file_get_contents("php://input");
|
|
||||||
if (!$post)
|
|
||||||
return 'No post data';
|
|
||||||
|
|
||||||
$json = json_decode($post, true);
|
|
||||||
|
|
||||||
if (is_string($json))
|
|
||||||
return $json; // error
|
|
||||||
|
|
||||||
if (!array_key_exists('posData', $json))
|
if (!$apiKey)
|
||||||
return 'no posData';
|
$apiKey = $bpOptions['apiKey'];
|
||||||
|
|
||||||
$posData = json_decode($json['posData'], true);
|
$post = file_get_contents("php://input");
|
||||||
if($bpOptions['verifyPos'] and $posData['hash'] != crypt(serialize($posData['posData']), $apiKey))
|
|
||||||
return 'authentication failed (bad hash)';
|
if (!$post)
|
||||||
$json['posData'] = $posData['posData'];
|
return 'No post data';
|
||||||
|
|
||||||
return $json;
|
$json = json_decode($post, true);
|
||||||
|
|
||||||
|
if (is_string($json))
|
||||||
|
return $json; // error
|
||||||
|
|
||||||
|
if (!array_key_exists('posData', $json))
|
||||||
|
return 'no posData';
|
||||||
|
|
||||||
|
$posData = json_decode($json['posData'], true);
|
||||||
|
|
||||||
|
if($bpOptions['verifyPos'] and $posData['hash'] != crypt(serialize($posData['posData']), $apiKey))
|
||||||
|
return 'authentication failed (bad hash)';
|
||||||
|
|
||||||
|
$json['posData'] = $posData['posData'];
|
||||||
|
|
||||||
|
return $json;
|
||||||
}
|
}
|
||||||
|
|
||||||
// $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)
|
|
||||||
$apiKey = $bpOptions['apiKey'];
|
|
||||||
|
|
||||||
$response = bpCurl('https://'.$bpconfig['hostAndPort'].'/api/invoice/'.$invoiceId, $apiKey);
|
if (!$apiKey)
|
||||||
if (is_string($response))
|
$apiKey = $bpOptions['apiKey'];
|
||||||
return $response; // error
|
|
||||||
$response['posData'] = json_decode($response['posData'], true);
|
|
||||||
$response['posData'] = $response['posData']['posData'];
|
|
||||||
|
|
||||||
return $response;
|
$response = bpCurl('https://'.$bpconfig['hostAndPort'].'/api/invoice/'.$invoiceId, $apiKey);
|
||||||
|
|
||||||
|
if (is_string($response))
|
||||||
|
return $response; // error
|
||||||
|
|
||||||
|
$response['posData'] = json_decode($response['posData'], true);
|
||||||
|
$response['posData'] = $response['posData']['posData'];
|
||||||
|
|
||||||
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
?>
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue