Refactored and updated plugin to work with update API and to be able to

be packaged and distributed using more than just GitHub

Added a script to delete old extension, installing the new extension overrides the previous extension and the previous extensions does not function anymore, merchants should at least disable the previous plugin, the merchant will also need to also remove the extension from core_resource table

Updated to encrypt/decrypt keys to and from the database

Small bug fixes with the package script

Added instructions on how a previous merchant can upgrade to the new 2.x one
This commit is contained in:
Joshua Estes 2014-09-26 10:52:42 -04:00
parent 075e6f1154
commit 8371f89125
78 changed files with 2328 additions and 2692 deletions

3
.gitattributes vendored
View File

@ -1,6 +1,6 @@
# 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
@ -23,6 +23,7 @@
# These files/directories are not included when making
# an archive of this repository.
/build export-ignore
/scripts export-ignore
/tests export-ignore
.gitattributes export-ignore
.gitignore export-ignore

1
.gitignore vendored
View File

@ -24,6 +24,7 @@
lib/bitpay/bp_config.php
/bin/
/build/cache/
/build/dist/
/build/docs/
/build/logs/
/build/magento/

View File

@ -26,10 +26,15 @@ php:
- 5.3
install:
- composer install
script: ./bin/phing -verbose -propertyfile build/travis.properties build-travis
#script: ./bin/phing -verbose -propertyfile build/travis.properties build-travis
script: phpunit -c build/
cache:
directories:
- bin/
- build/cache/
- build/magento/
- vendor/
matrix:
fast_finish: true
allow_failures:
- php: 5.3

View File

@ -1,29 +1,5 @@
Version 6
* Updated BitPay logo in admin settings
* Tested & validated against latest 1.9.0.1
* Tested & validated with default one-page checkout settings
Version 5
* Added new HTTP header for version tracking
Version 4
* Improved README documentation.
* Additional testing performed against 1.8.1.0 and installation instructions updated to reflect differences.
* Added parameter to automatically create a shipment and mark orders complete (off by default).
* Version incremented, other bug fixes and enhancements (see commit notes).
Version 3
* Now gives the option to show an iframe on the checkout page instead of redirecting to bitpay.com.
Version 2
* Now supports API keys instead of SSL files. Tested against 1.7.0.2.
Version 1
* Initial version, tested against Magento 1.6.0.0
2.0.0
Initial release of the new Magento Extension that supports BitPay's new
cryptographically secure API. You can read more about the new API on the
blog at
http://blog.bitpay.com/2014/09/18/announcing-the-new-bitpay-api.html

View File

@ -1,6 +1,6 @@
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

229
README.md
View File

@ -1,118 +1,134 @@
bitpay/magento-plugin
=========================
=====================
# Status
# Build Status
[![Build Status](https://travis-ci.org/bitpay/magento-plugin.svg?branch=master)](https://travis-ci.org/bitpay/magento-plugin)
# Brief Description
BitPay has the most powerful bitcoin infrastructure on the planet and is trusted by over 40,000 merchants.
# Detail Description
Bitcoin is a powerful new peer-to-peer platform for the next generation of
financial technology. The decentralized nature of the Bitcoin network allows
for a highly resilient value transfer infrastructure, and this allows merchants
to gain greater profits.
This is because there are little to no fees for transferring Bitcoins from one
person to another. Unlike other payment methods, Bitcoin payments cannot be
reversed, so once you are paid you can ship! No waiting days for a payment to
clear.
# Requirements
* [Magento](http://magento.com/resources/system-requirements) >= 1.9.0.1 (Older version will work, but we do not test against those)
* [GMP](http://us2.php.net/gmp) You may have to install this as most servers do not come with it.
* [mcrypt](http://us2.php.net/mcrypt) Magento requires this so you're fine
* [OpenSSL](http://us2.php.net/openssl) Must be compiled with PHP
* PHP >= 5.4
# Upgrade From Version 1.x to 2.x
Merchants who have previous been using the BitPay Magento plugin will need to remove
previous plugin. This can be done by using the [scripts/delete](https://github.com/bitpay/magento-plugin/blob/master/scripts/delete)
script before installing the new plugin.
# Installation
## Magento Connect Manager
Goto [http://www.magentocommerce.com/magento-connect/bitpay-payment-method.html](http://www.magentocommerce.com/magento-connect/bitpay-payment-method.html)
and click the *Install Now* link which will give you the *Extension Key* needed
for the next step.
Once you have the key, log into you Magento Store's Admin Panel and navigate to
**System > Magento Connect > Magento Connect Manager**.
***NOTE*** It may ask you to log in again using the same credentials that you use
to log into the Admin Panel.
All you need to do is paste the extension key and click on the *Install* button.
***WARNING*** It is good practice to backup your database before installing
extensions. Please make sure you Create Backups.
## Download
<strong>1.</strong> [Download](https://github.com/bitpay/magento-plugin/archive/master.zip) and Unzip this archive and copy the files to the location of your
[Magento CE](http://magento.com/) installation on your web server. For Ubuntu-based servers, the default
location for website files is the `/var/www` folder. Your web hosting provider may
use a different location for storing your website files so check with them if the
`/var/www` folder does not exist or your Magento files are in an otherwise unknown
location.
Many web hosting accounts have a graphical, web-based control panel for your server.
This is the easiest method for copying the [BitPay Magento Plugin](https://github.com/bitpay/magento-plugin) files to your Magenento
CE directory. If your provider has one of these graphical control panels, log into
your hosting account and move the files using that tool. However, if that is not
an option and you can only access your web server using a shell account via SSH,
open a new connection and issue these commands:
Visit the [Releases](https://github.com/bitpay/magento-plugin/releases) page of
this repository and download the latest version. Once this is done, you can just
unzip the contents and use any method you want to put them on your server. The
contents will mirror the Magento directory structure.
```bash
bitpay@bitpay:~$ unzip magento-plugin-master.zip
bitpay@bitpay:~$ cd magento-plugin-master
bitpay@bitpay:~$ cp -R ./* /location/of/your/magento/installation/
```
<strong>Note:</strong> You may need to have superuser privileges to copy files
to `/var/www` on Ubuntu-based servers. If you receive “Permission denied” errors
when using the cp command above, use sudo before the cp command and specify the
superuser password when asked:
***NOTE*** These files can also up uploaded using the *Magento Connect Manager*
that comes with your Magento Store
```bash
bitpay@bitpay:~$ sudo cp -R ./* /location/of/your/magento/installation/
[sudo] password for (username):
```
<strong>2.</strong> Verify the files have been copied correctly by checking
your Magento CE installation folder for one or more of them. You can choose
to check for any of the files present in the BitPay plugin archive. The file
Im looking for in this example should be in the `/var/www/magento/app/code/community/Bitpay/Bitcoins/Model`
directory along with the `Ipn.php` file on my Ubuntu server:
```bash
bitpay@bitpay:~$ ls -l /var/www/magento/app/code/community/Bitpay/Bitcoins/Model/
total 24
-rw-r--r-- 1 root root 3097 Mar 25 14:06 Ipn.php
-rw-r--r-- 1 root root 10786 Mar 25 14:06 PaymentMethod.php
drwxr-xr-x 3 root root 4096 Mar 25 13:54 Resource
drwxr-xr-x 2 root root 4096 Mar 25 13:54 Source
```
If the files were copied correctly and are present in the directory, you should
see the files listed when you issue the ls command. If you do not see any files
listed, try the cp command again to retry the copying procedure. However, if
you still do not see any files listed or you receive an error copying the files,
contact your web hosting support for assistance.
***WARNING*** It is good practice to backup your database before installing
extensions. Please make sure you Create Backups.
## modman
Using [modman](https://github.com/colinmollenhour/modman) you can
install the BitPay Magento Plugin. Once
you have modman installed, run `modman init` if you have not already done so. Next
just run `modman clone https://github.com/bitpay/magento-plugin.git` in the root
of the Magento installation. In this case it is `/var/www/magento`.
# Magento CE 1.8.x - 1.9.x Installation Tips
In some instances for merchants using Magento CE version 1.8.x, the BitPay
Bitcoins payment plugin might not appear in the Payment Methods configuration
section even though all plugin files have been correctly installed. To
resolve this issue, log into your admin control panel and choose the
System -> Cache Management configuration screen. Click the check box next
to the Configuration cache type and choose the Disable action from the Actions
drop-down list box. Click the Submit button to disable this cache.
## Development
Next, click both the Flush Magento Cache and Flush Cache Storage buttons (Clicked
"Ok" when the pop-up box is displayed) to remove the stale configuration cache files.
For developers wanting to contribute to this project, it is assumed you have a
stable Magento environment to work with, and are familiar with developing for
Magento. You will need to clone this repository or fork and clone the repository
you created.
Finally, log completely out of the administrative control panel and then log back
in. The Bitcoins option is now correctly displaying under Payment Methods in the
configuration screen. The BitPay plugin parameters are exactly the same on Magento
CE 1.8.x as on older Magento CE releases.
Once you have cloned the repository, you will need to run [composer install](https://getcomposer.org/doc/00-intro.md#using-composer).
Using and setting up composer is outside the scope, however you will find the
documentation on their site comprehensive.
Once you are done, you can then run the ``scripts/package`` script to create a
distribution files which you can find in ``build/dist``. This is the file that
you can upload to your server to unzip or do with what you will.
If you encounter any issues or implement any updates or changes, please open an
[issue](https://github.com/bitpay/magento-plugin/issues) or submit a Pull Request.
***NOTE*** The ``scripts/package`` file contains some configuration settings that
will need to change for different releases. If you are using this script to build
files that are for distribution, these will need to be updated.
# Configuration
<strong>NOTE:</strong> SSL is <em>required</em> for use of the BitPay plugin for Magento CE.
1. Create an API key at bitpay.com by clicking My Account > API Access Keys > Add New API Key.
2. In Admin panel under "System > Configuration > Sales > Payment Methods > Bitcoins":
- Verify that the module is enabled.
- Enter your API key.
- Select a transaction speed. The **high** speed will send a confirmation as
soon as a transaction is received in the bitcoin network (usually a few
seconds). A **medium** speed setting will typically take 10 minutes.
The **low** speed setting usually takes around 1 hour. See the bitpay.com
merchant documentation for a full description of the transaction speed settings.
- Verify that the currencies option includes your store's currencies. If it
doesn't, check bitpay.com to see if they support your desired currency. If
so, you may simply add the currency to the list using this setting. If not,
you will not be able to use that currency.
- (optional) Adjust the "Fullscreen Invoice" setting. "No" means that payment
instructions are embedded in the checkout page. "Yes" means that the buyer
will be redirected to bitpay.com to pay their order. The default setting is
"No".
Configuration can be done using the Administrator section of your Megento store.
Once Logged in, you will find the configuration settings under **System > Configuration > Sales > Payment Methods**.
![BitPay Magento Settings](https://raw.githubusercontent.com/bitpay/magento-plugin/master/docs/MagentoSettings.png "BitPay Megento Settings")
Here your will need to create a [pairing code](https://bitpay.com/api-tokens) using
your BitPay merchant account. Once you have a Pairing Code, put the code in the
Pairing Code field. This will take care of the rest for you.
***NOTE*** Pairing Codes are only valid for a short period of time. If it expires
before you get to use it, you can always create a new one an use the new one.
***NOTE*** You will only need to do this once since each time you do this, the
extension will generate public and private keys that are used to identify you
when using the API.
You are also able to configure how BitPay's IPN (Instant Payment Notifications)
changes the order in your Magento store.
![BitPay Invoice Settings](https://raw.githubusercontent.com/bitpay/magento-plugin/master/docs/MagentoInvoiceSettings.png "BitPay Invoice Settings")
# Usage
When a shopper chooses the Bitcoin payment method, they will be presented with an
order summary as the next step (prices are shown in whatever currency they've
selected for shopping). If the fullscreen option is disabled, they can pay for
their order using the address shown on the screen. Otherwise they will place
their order and be redirected to bitpay.com to pay.
The order status in the admin panel will be "Processing" if payment has been confirmed.
Once enabled, your customers will be given the option to pay with Bitcoins. Once
they checkout they are redirected to a full screen BitPay invoice to pay for
the order.
Note: This extension does not provide a means of automatically pulling a current BTC
exchange rate for presenting BTC prices to shoppers.
As a merchant, the orders in your Magento store can be treated as any other
order. You may need to adjust the Invoice Settings depending on your order
fulfillment.
# Support
@ -131,18 +147,33 @@ exchange rate for presenting BTC prices to shoppers.
# Troubleshooting
1. Ensure a valid SSL certificate is installed on your server. Also ensure your root CA cert is updated. If your CA cert is not current, you will see curl SSL verification errors.
2. Verify that your web server is not blocking POSTs from servers it may not recognize. Double check this on your firewall as well, if one is being used.
3. Check the `bitpay.log` file for any errors during BitPay payment attempts. If you contact BitPay support, they will ask to see the log file to help diagnose the problem. The log file will be found inside your Magento's `var/log/` directory.
4. Check the version of this plugin against the official plugin repository to ensure you are using the latest version. Your issue might have been addressed in a newer version!
5. If all else fails, send an email describing your issue *in detail* to support@bitpay.com
1. Ensure a valid SSL certificate is installed on your server. Also ensure your
root CA cert is updated. If your CA cert is not current, you will see curl
SSL verification errors.
2. Verify that your web server is not blocking POSTs from servers it may not
recognize. Double check this on your firewall as well, if one is being used.
3. Check the `payment_bitpay.log` file for any errors during BitPay payment attempts.
If you contact BitPay support, they will ask to see the log file to help
diagnose the problem. The log file will be found inside your Magento's
`var/log/` directory. ***NOTE*** You will need to enable the debugging
setting for the extension to output information into the log file.
4. Check the version of this plugin against the official plugin repository to
ensure you are using the latest version. Your issue might have been
addressed in a newer version! See the [Releases](https://github.com/bitpay/magento-plugin/releases)
page for the latest.
5. If all else fails, send an email describing your issue **in detail** to
support@bitpay.com
NOTE: When contacting support it will help us is you provide:
* Magento Version
* Other plugins you have installed
* Some configuration settings such as:
* Transaction Speed
* Set order complete with "complete" IPN
***TIP***: When contacting support it will help us is you provide:
* Magento Version (Found at the bottom page in the Administration section)
* Other extensions you have installed
* Some extensions do not play nice
* Configuration settings for the extension (Most merchants take screen grabs)
* Any log files that will help
* web server error logs
* enabled debugging for this extension and send us `var/log/payment_bitpay.log`
* Screen grabs of error message if applicable.
# Contribute
@ -152,7 +183,7 @@ To contribute to this project, please fork and submit a pull request.
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

View File

@ -1,120 +0,0 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2011-2014 BitPay LLC
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
class Bitpay_Bitcoins_Block_Iframe extends Mage_Checkout_Block_Onepage_Payment
{
/**
*/
protected function _construct()
{
$this->setTemplate('bitcoins/iframe.phtml');
parent::_construct();
}
/**
* @return string
*/
public function GetQuoteId()
{
$quote = $this->getQuote();
$quoteId = $quote->getId();
return $quoteId;
}
/**
* create an invoice and return the url so that iframe.phtml can display it
*
* @return string
*/
public function GetIframeUrl()
{
// are they using bitpay?
// @todo refactor this
if (!($quote = Mage::getSingleton('checkout/session')->getQuote())
or !($payment = $quote->getPayment())
or !$payment->getMethod()
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);
$invoice = bpCreateInvoice($quoteId, $price, array('quoteId' => $quoteId, 'quoteHash' => $hash), $options);
if (array_key_exists('error', $invoice))
{
Mage::log('Error creating bitpay invoice', null, Mage::helper('bitpay')->getLogFile());
Mage::log($invoice['error'], null, Mage::helper('bitpay')->getLogFile());
Mage::throwException("Error creating bit-pay invoice. Please try again or use another payment option.");
return false;
}
return $invoice['url'].'&view=iframe';
}
}

View File

@ -1,173 +0,0 @@
<?php
/**
* The MIT License (MIT)
*
* 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
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
class Bitpay_Bitcoins_Helper_Data extends Mage_Core_Helper_Abstract
{
/**
* File that is used to put all logging information in.
*
* @var string
*/
const LOG_FILE = 'bitpay.log';
/**
* Returns the file used for logging
*
* @return string
*/
public function getLogFile()
{
return self::LOG_FILE;
}
/**
* Returns true if the merchant has set their api key
*
* @return boolean
*/
public function hasApiKey()
{
$key = Mage::getStoreConfig('payment/Bitcoins/api_key');
return !empty($key);
}
/**
* Returns true if Transaction Speed has been configured
*
* @return boolean
*/
public function hasTransactionSpeed()
{
$speed = Mage::getStoreConfig('payment/Bitcoins/speed');
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;
}
}

View File

@ -1,256 +0,0 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2011-2014 BitPay LLC
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
class Bitpay_Bitcoins_Model_Ipn extends Mage_Core_Model_Abstract
{
/**
*/
function _construct()
{
parent::_construct();
$this->_init('Bitcoins/ipn');
}
/**
* @param $invoice
*
* @return
*/
function Record($invoice)
{
return $this
->setQuoteId(isset($invoice['posData']['quoteId']) ? $invoice['posData']['quoteId'] : NULL)
->setOrderId(isset($invoice['posData']['orderId']) ? $invoice['posData']['orderId'] : NULL)
->setPosData(json_encode($invoice['posData']))
->setInvoiceId($invoice['id'])
->setUrl($invoice['url'])
->setStatus($invoice['status'])
->setBtcPrice($invoice['btcPrice'])
->setPrice($invoice['price'])
->setCurrency($invoice['currency'])
->setInvoiceTime(intval($invoice['invoiceTime']/1000.0))
->setExpirationTime(intval($invoice['expirationTime']/1000.0))
->setCurrentTime(intval($invoice['currentTime']/1000.0))
->save();
}
/**
* @param string $quoteId
* @param array $statuses
*
* @return boolean
*/
function GetStatusReceived($quoteId, $statuses)
{
if (!$quoteId)
{
return false;
}
$quote = Mage::getModel('sales/quote')->load($quoteId, 'entity_id');
if (!$quote)
{
Mage::log('quote not found', Zend_Log::WARN, 'bitpay.log');
return false;
}
$quoteHash = Mage::getModel('Bitcoins/paymentMethod')->getQuoteHash($quoteId);
if (!$quoteHash)
{
Mage::log('Could not find quote hash for quote '.$quoteId, Zend_Log::WARN, 'bitpay.log');
return false;
}
$collection = $this->getCollection()->AddFilter('quote_id', $quoteId);
foreach ($collection as $i)
{
if (in_array($i->getStatus(), $statuses))
{
// check that quote data was not updated after IPN sent
$posData = json_decode($i->getPosData());
if (!$posData)
{
continue;
}
if ($quoteHash == $posData->quoteHash)
{
return true;
}
}
}
return false;
}
/**
* @param string $quoteId
*
* @return boolean
*/
function GetQuotePaid($quoteId)
{
return $this->GetStatusReceived($quoteId, array('paid', 'confirmed', 'complete'));
}
/**
* @param string $quoteId
*
* @return boolean
*/
function GetQuoteComplete($quoteId)
{
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();
}
}

View File

@ -1,95 +0,0 @@
<?php
/**
* The MIT License (MIT)
*
* 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
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
class Bitpay_Bitcoins_Model_Observer
{
/**
* Queries BitPay to update the order states in magento to make sure that
* open orders are closed/canceled if the BitPay invoice expires or becomes
* invalid.
*/
public function updateOrderStates()
{
Mage::log(
'cronjob: started',
Zend_Log::DEBUG,
Mage::helper('bitpay')->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();
}
}

View File

@ -1,549 +0,0 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2011-2014 BitPay LLC
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
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
* of this module to be used by frontend and backend.
*
* @see all flags and their defaults in Mage_Payment_Model_Method_Abstract
*
* It is possible to have a custom dynamic logic by overloading
* public function can* for each flag respectively
*/
/**
* Is this payment method a gateway (online auth/charge) ?
*/
protected $_isGateway = true;
/**
* Can authorize online?
*/
protected $_canAuthorize = true;
/**
* Can capture funds online?
*/
protected $_canCapture = true;
/**
* Can capture partial amounts online?
*/
protected $_canCapturePartial = false;
/**
* Can refund online?
*/
protected $_canRefund = false;
/**
* Can void transactions online?
*/
protected $_canVoid = false;
/**
* Can use this payment method in administration panel?
*/
protected $_canUseInternal = false;
/**
* Can show this payment method as an option on checkout payment page?
*/
protected $_canUseCheckout = true;
/**
* Is this payment method suitable for multi-shipping checkout?
*/
protected $_canUseForMultishipping = true;
/**
* Can save credit card information for future processing?
*/
protected $_canSaveCc = false;
/**
* BitPay - create shipment automatically after completing order?
*/
protected $_bpCreateShipment = false;
//protected $_formBlockType = 'bitcoins/form';
//protected $_infoBlockType = 'bitcoins/info';
/**
* Check method for processing with base currency
* @see Mage_Payment_Model_Method_Abstract::canUseForCurrency()
*
* @param string $currencyCode
* @return boolean
*/
public function canUseForCurrency($currencyCode)
{
Mage::log(
sprintf('Checking if can use currency "%s"', $currencyCode),
Zend_Log::DEBUG,
Mage::helper('bitpay')->getLogFile()
);
$currencies = Mage::getStoreConfig('payment/Bitcoins/currencies');
$currencies = array_map('trim', explode(',', $currencies));
return array_search($currencyCode, $currencies) !== false;
}
/**
* Can be used in regular checkout
* @see Mage_Payment_Model_Method_Abstract::canUseCheckout()
*
* @return bool
*/
public function canUseCheckout()
{
$helper = Mage::helper('bitpay');
if (!$helper->hasApiKey())
{
Mage::log(
'Bitpay/Bitcoins: API key not entered',
Zend_Log::ERR,
Mage::helper('bitpay')->getLogFile()
);
return false;
}
if (!$helper->hasTransactionSpeed())
{
Mage::log(
'Bitpay/Bitcoins: Transaction Speed has not been set',
Zend_Log::ERR,
Mage::helper('bitpay')->getLogFile()
);
return false;
}
return $this->_canUseCheckout;
}
/**
* Authorize payment method
*
* @param Varien_Object $payment
* @param float $amount
*
* @return Bitpay_Bitcoins_Model_PaymentMethod
*/
public function authorize(Varien_Object $payment, $amount)
{
Mage::log(
sprintf('Authorizing payment'),
Zend_Log::DEBUG,
Mage::helper('bitpay')->getLogFile()
);
if (!Mage::getStoreConfig('payment/Bitcoins/fullscreen'))
{
return $this->CheckForPayment($payment);
}
else
{
return $this->CreateInvoiceAndRedirect($payment, $amount);
}
}
/**
* @param Varien_Object $payment
*
* @return Bitpay_Bitcoins_Model_PaymentMethod
*/
public function CheckForPayment($payment)
{
Mage::log(
sprintf('Checking for payment'),
Zend_Log::DEBUG,
Mage::helper('bitpay')->getLogFile()
);
$quoteId = $payment->getOrder()->getQuoteId();
$ipn = Mage::getModel('Bitcoins/ipn');
if (!$ipn->GetQuotePaid($quoteId))
{
// This is the error that is displayed to the customer during checkout.
Mage::throwException("Order not paid for. Please pay first and then Place your Order.");
Mage::log('Order not paid for. Please pay first and then Place Your Order.', Zend_Log::CRIT, Mage::helper('bitpay')->getLogFile());
}
else if (!$ipn->GetQuoteComplete($quoteId))
{
// order status will be PAYMENT_REVIEW instead of PROCESSING
$payment->setIsTransactionPending(true);
} else {
$this->MarkOrderPaid($payment->getOrder());
}
return $this;
}
/**
* @param Varien_Object $order
*/
public function invoiceOrder($order)
{
Mage::log(
sprintf('Invoicing order'),
Zend_Log::DEBUG,
Mage::helper('bitpay')->getLogFile()
);
try
{
if (!$order->canInvoice())
{
Mage::throwException(Mage::helper('core')->__('Cannot create an invoice.'));
}
$invoice = $order->prepareInvoice()
->setTransactionId(1)
->addComment('Invoiced automatically by Bitpay/Bitcoins/controllers/IndexController.php')
->register()
->pay();
$transactionSave = Mage::getModel('core/resource_transaction')
->addObject($invoice)
->addObject($invoice->getOrder());
$transactionSave->save();
}
catch (Exception $e)
{
Mage::log($e->getMessage(), Zend_Log::EMERG, Mage::helper('bitpay')->getLogFile());
Mage::logException($e);
}
}
/**
* @param $order
*/
public function MarkOrderPaid($order)
{
Mage::log(
sprintf('Marking order paid'),
Zend_Log::DEBUG,
Mage::helper('bitpay')->getLogFile()
);
$order->setState(Mage_Sales_Model_Order::STATE_PROCESSING, true)->save();
if ($order->getTotalDue() > 0)
{
if (!count($order->getInvoiceCollection()))
{
$this->invoiceOrder($order);
}
}
else
{
Mage::log('MarkOrderPaid called but order '. $order->getId() .' does not have a balance due.', Zend_Log::WARN, Mage::helper('bitpay')->getLogFile());
}
}
/**
* @param $order
*/
public function MarkOrderComplete($order)
{
Mage::log(
sprintf('Marking order paid'),
Zend_Log::DEBUG,
Mage::helper('bitpay')->getLogFile()
);
if ($order->getTotalDue() >= 0 && $order->canInvoice())
{
if ($order->hasInvoices())
{
foreach ($order->getInvoiceCollection() as $_eachInvoice)
{
try
{
$_eachInvoice->setRequestedCaptureCase(Mage_Sales_Model_Order_Invoice::CAPTURE_ONLINE);
$_eachInvoice->capture()->save();
}
catch (Exception $e)
{
Mage::log($e->getMessage(), Zend_Log::EMERG, Mage::helper('bitpay')->getLogFile());
Mage::logException($e);
}
}
}
}
// If the $_bpCreateShipment option is set to true above, this code will
// programmatically create a shipment for you. By design, this will mark
// the entire order as 'complete'.
if(isset($_bpCreateShipment) && $_bpCreateShipment == true)
{
try
{
$shipment = $order->prepareShipment();
if ($shipment)
{
$shipment->register();
$order->setIsInProcess(true);
$transaction_save = Mage::getModel('core/resource_transaction')
->addObject($shipment)
->addObject($shipment->getOrder())
->save();
}
}
catch (Exception $e)
{
Mage::log('Error creating shipment for order '. $order->getId() .'.', Zend_Log::ERR, Mage::helper('bitpay')->getLogFile());
Mage::logException($e);
}
}
try
{
if((isset($_bpCreateShipment) && $_bpCreateShipment == true) || Mage::getStoreConfig('payment/Bitcoins/order_disposition'))
{
$order->setState('Complete', 'complete', 'Completed by BitPay payments.', true);
}
else
{
$order->setState(Mage_Sales_Model_Order::STATE_PROCESSING, 'processing', 'BitPay has confirmed the payment.', false);
}
if(!$order->getEmailSent())
{
$order->sendNewOrderEmail();
}
$order->save();
}
catch (Exception $e)
{
Mage::log($e->getMessage(), Zend_Log::EMERG, Mage::helper('bitpay')->getLogFile());
Mage::logException($e);
}
}
/**
* @param $order
*/
public function MarkOrderCancelled($order)
{
Mage::log(
sprintf('Marking order cancelled'),
Zend_Log::DEBUG,
Mage::helper('bitpay')->getLogFile()
);
try
{
$order->setState(Mage_Sales_Model_Order::STATE_CANCELED, true)->save();
}
catch (Exception $e)
{
Mage::log('Could not cancel order '. $order->getId() .'.', null, Mage::helper('bitpay')->getLogFile());
Mage::logException($e);
}
}
/**
* given Mage_Core_Model_Abstract, return api-friendly address
*
* @param $address
*
* @return array
*/
public function ExtractAddress($address)
{
Mage::log(
sprintf('Extracting addess'),
Zend_Log::DEBUG,
Mage::helper('bitpay')->getLogFile()
);
$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;
}
/**
* @param $payment
* @param $amount
*
* @return Bitpay_Bitcoins_Model_PaymentMethod
*/
public function CreateInvoiceAndRedirect($payment, $amount)
{
Mage::log(
sprintf('Creating invoice and redirecting'),
Zend_Log::DEBUG,
Mage::helper('bitpay')->getLogFile()
);
include Mage::getBaseDir('lib').'/bitpay/bp_lib.php';
$apiKey = Mage::getStoreConfig('payment/Bitcoins/api_key');
$speed = Mage::getStoreConfig('payment/Bitcoins/speed');
$order = $payment->getOrder();
$orderId = $order->getIncrementId();
$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,
);
/**
* Some merchants are using custom extensions where the shipping
* address may not be set, this will only extract the shipping
* address if there is one already set.
*/
if ($order->getShippingAddress()) {
$options = array_merge(
$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', Zend_Log::CRIT, Mage::helper('bitpay')->getLogFile());
Mage::log($invoice['error'], Zend_Log::CRIT, Mage::helper('bitpay')->getLogFile());
Mage::throwException("Error creating BitPay 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 string
*/
public function getOrderPlaceRedirectUrl()
{
Mage::log(
sprintf('Getting order place redirect url'),
Zend_Log::DEBUG,
Mage::helper('bitpay')->getLogFile()
);
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
*
* @param string $quoteId
*
* @return boolean|string
*/
public function getQuoteHash($quoteId)
{
Mage::log(
sprintf('Getting the quote hash'),
Zend_Log::DEBUG,
Mage::helper('bitpay')->getLogFile()
);
$quote = Mage::getModel('sales/quote')->load($quoteId, 'entity_id');
if (!$quote)
{
Mage::log('getQuoteTimestamp: quote not found', Zend_Log::ERR, Mage::helper('bitpay')->getLogFile());
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
return $hash;
}
}

View File

@ -1,33 +0,0 @@
<?php
/**
* The MIT License (MIT)
*
* 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
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
class Bitpay_Bitcoins_Model_Resource_Ipn extends Mage_Core_Model_Mysql4_Abstract
{
protected function _construct()
{
$this->_init('Bitcoins/ipn', 'id');
}
}

View File

@ -1,44 +0,0 @@
<?php
/**
* The MIT License (MIT)
*
* 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
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
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();
}
}
}

View File

@ -1,50 +0,0 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2011-2014 BitPay LLC
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
class Bitpay_Bitcoins_Model_Source_Speed
{
/**
* @return array
*/
public function toOptionArray()
{
return array(
array(
'value' => 'low',
'label' => 'Low',
),
array(
'value' => 'medium',
'label' => 'Medium',
),
array(
'value' => 'high',
'label' => 'High',
)
);
}
}

View File

@ -1,118 +0,0 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2011-2014 BitPay LLC
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
// callback controller
class Bitpay_Bitcoins_IndexController extends Mage_Core_Controller_Front_Action
{
/**
*/
public function checkForPaymentAction()
{
$params = $this->getRequest()->getParams();
$quoteId = $params['quote'];
$paid = Mage::getModel('Bitcoins/ipn')->GetQuotePaid($quoteId);
print json_encode(array('paid' => $paid));
exit();
}
/**
* bitpay's IPN lands here
*/
public function indexAction() {
Mage::log(
sprintf('Incoming IPN from bitpay'),
Zend_Log::DEBUG,
Mage::helper('bitpay')->getLogFile()
);
require Mage::getBaseDir('lib').'/bitpay/bp_lib.php';
$apiKey = Mage::getStoreConfig('payment/Bitcoins/api_key');
$invoice = bpVerifyNotification($apiKey);
if (is_string($invoice))
{
Mage::log("bitpay callback error: $invoice", Zend_Log::ERR, Mage::helper('bitpay')->getLogFile());
throw new Exception('Bitpay callback error:' . $invoice);
}
// get the order
if (isset($invoice['posData']['quoteId']))
{
$quoteId = $invoice['posData']['quoteId'];
$order = Mage::getModel('sales/order')->load($quoteId, 'quote_id');
}
elseif (isset($invoice['posData']['orderId']))
{
$orderId = $invoice['posData']['orderId'];
$order = Mage::getModel('sales/order')->loadByIncrementId($orderId);
}
else
{
Mage::log('Invalid posData, does not contain quoteId or orderId.', Zend_Log::ERR, Mage::helper('bitpay')->getLogFile());
throw new Exception('Invalid Bitpay IPN received.');
}
// save the ipn so that we can find it when the user clicks "Place Order"
Mage::getModel('Bitcoins/ipn')->Record($invoice);
if (!$order->getId())
{
Mage::log('Order object does not contain an ID', Zend_Log::ERR, Mage::helper('bitpay')->getLogFile());
throw new Exception('Order object does not contain an ID');
}
// update the order if it exists already
// BitPay Statuses
// new, paid, confirmed, complete, expired, invalid
Mage::log('Received IPN with "' . $invoice['status'] . '" status', Zend_Log::DEBUG, Mage::helper('bitpay')->getLogFile());
switch($invoice['status'])
{
// Map to Magento state Processing
case 'paid':
// Mark paid if there is an outstanding total
$method = Mage::getModel('Bitcoins/paymentMethod');
$method->MarkOrderPaid($order);
break;
// Map to Magento status Complete
case 'confirmed':
case 'complete':
// Mark confirmed/complete if the order has been paid
$method = Mage::getModel('Bitcoins/paymentMethod');
$method->MarkOrderComplete($order);
//Mage::log('Received a ' . $invoice['status'] . ' notification from BitPay but this order is not paid yet. Possible internal error with Magento. Check order status to confirm.', Zend_Log::ERR, Mage::helper('bitpay')->getLogFile());
break;
// Map to Magento State Closed
case 'invalid':
$method = Mage::getModel('Bitcoins/paymentMethod');
$method->MarkOrderCancelled($order);
break;
}
}
}

View File

@ -1,136 +0,0 @@
<?xml version="1.0"?>
<!--
/**
* The MIT License (MIT)
*
* 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
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
-->
<config>
<frontend>
<routers>
<bitpay_callback>
<use>standard</use>
<args>
<module>Bitpay_Bitcoins</module>
<frontName>bitpay_callback</frontName>
</args>
</bitpay_callback>
</routers>
<layout>
<updates>
<bitcoins>
<file>bitcoins.xml</file>
</bitcoins>
</updates>
</layout>
</frontend>
<modules>
<Bitpay_Bitcoins>
<!-- for database updates -->
<version>1.1.0</version>
</Bitpay_Bitcoins>
</modules>
<global>
<blocks>
<bitcoins>
<class>Bitpay_Bitcoins_Block</class>
</bitcoins>
</blocks>
<helpers>
<bitpay>
<class>Bitpay_Bitcoins_Helper</class>
</bitpay>
</helpers>
<models>
<Bitcoins>
<class>Bitpay_Bitcoins_Model</class>
<resourceModel>Bitcoins_resource</resourceModel>
</Bitcoins>
<Bitcoins_resource>
<class>Bitpay_Bitcoins_Model_Resource</class>
<entities>
<ipn>
<table>bitpay_ipns</table>
</ipn>
</entities>
</Bitcoins_resource>
</models>
<resources>
<Bitcoins_setup> <!-- keep this uppercase or you'll get duplicate errors -->
<setup>
<!-- which module to look for install/upgrade files in -->
<module>Bitpay_Bitcoins</module>
</setup>
<connection>
<use>core_setup</use>
</connection>
</Bitcoins_setup>
<Bitcoins_write>
<connection>
<use>core_write</use>
</connection>
</Bitcoins_write>
<Bitcoins_read>
<connection>
<use>core_read</use>
</connection>
</Bitcoins_read>
</resources>
</global>
<crontab>
<jobs>
<!--
This will clean up all the expired IPNs in the database and
will also updated the magento order to cancelled
-->
<bitpay_clean_expired>
<schedule>
<!-- Run every 30 minutes -->
<cron_expr>*/30 * * * *</cron_expr>
</schedule>
<run>
<model>Bitcoins/Observer::cleanExpired</model>
</run>
</bitpay_clean_expired>
</jobs>
</crontab>
<default>
<payment>
<Bitcoins>
<active>1</active>
<model>Bitcoins/paymentMethod</model>
<title>Bitcoins</title>
<speed>low</speed>
<fullscreen>0</fullscreen>
<currencies>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</currencies>
<payment_action>authorize</payment_action>
</Bitcoins>
</payment>
</default>
</config>

View File

@ -1,122 +0,0 @@
<?xml version="1.0"?>
<!--
/**
* The MIT License (MIT)
*
* Copyright (c) 2011-2014 BitPay LLC
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
-->
<config>
<sections>
<payment>
<groups>
<Bitcoins translate="label" module="paygate">
<label>Bitcoins</label>
<sort_order>670</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>0</show_in_store>
<comment><![CDATA[<img src="https://raw.githubusercontent.com/bitpay/bitpay-brand/master/bitpay-logo-inverse.png" alt="BitPay" height="73" width="123" /><br /><strong>To log into your merchant account or download the latest version of this plugin, visit our website: <a href="https://bitpay.com/" target="_blank">https://bitpay.com/</a></strong><br />]]></comment>
<fields>
<active translate="label">
<label>Enabled</label>
<frontend_type>select</frontend_type>
<source_model>adminhtml/system_config_source_yesno</source_model>
<sort_order>0</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>0</show_in_store>
</active>
<title translate="label">
<label>Title</label>
<frontend_type>text</frontend_type>
<sort_order>1</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>0</show_in_store>
</title>
<fullscreen translate="label">
<label>Fullscreen invoice</label>
<frontend_type>select</frontend_type>
<source_model>adminhtml/system_config_source_yesno</source_model>
<sort_order>2</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>0</show_in_store>
</fullscreen>
<api_key translate="label">
<label>API key</label>
<frontend_type>text</frontend_type>
<sort_order>3</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>0</show_in_store>
</api_key>
<speed translate="label">
<label>Transaction Speed</label>
<frontend_type>select</frontend_type>
<source_model>Bitpay_Bitcoins_Model_Source_Speed</source_model>
<sort_order>5</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>0</show_in_store>
<comment><![CDATA[Determines when a BitPay payment confirmation is sent.<br /><strong>High:</strong> an invoice is confirmed immediately when payment received.<br /><strong>Medium:</strong> an invoice is confirmed after 1 block confirmation by the network (~10 mins).<br /><strong>Low:</strong> an invoice is confirmed after 6 block confirmations by the network (~1 hour).<br />The default and safest setting is "Low". A "High" setting is quicker to generate a payment confirmation but is riskier since the transaction could have not been officially confirmed by the Bitcoin network itself.]]></comment>
</speed>
<currencies translate="label">
<label>Currencies accepted by BitPay</label>
<frontend_type>text</frontend_type>
<sort_order>6</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>0</show_in_store>
</currencies>
<sort_order translate="label">
<label>Sort Order</label>
<frontend_type>text</frontend_type>
<sort_order>7</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>0</show_in_store>
</sort_order>
<order_disposition translate="label">
<label>Set order complete with "complete" IPN</label>
<frontend_type>select</frontend_type>
<source_model>adminhtml/system_config_source_yesno</source_model>
<sort_order>8</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>0</show_in_store>
<comment>If you want to automatically set an order's state to complete when BitPay sends a completed payment notification, change this option to "Yes". The default setting of "No" will keep the order in a processing state for you to update as needed. Invoices contained within the order will be paid regardless of this setting.</comment>
</order_disposition>
</fields>
</Bitcoins>
</groups>
</payment>
</sections>
</config>

View File

@ -1,50 +0,0 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2011-2014 BitPay LLC
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
$installer = $this;
$installer->startSetup();
$installer->run("
CREATE TABLE IF NOT EXISTS `{$installer->getTable('Bitcoins/ipn')}` (
`id` int(10) unsigned NOT NULL auto_increment,
`quote_id` int(10) unsigned default NULL,
`order_id` int(10) unsigned default NULL,
`invoice_id` varchar(200) NOT NULL,
`url` varchar(400) NOT NULL,
`status` varchar(20) NOT NULL,
`btc_price` decimal(16,8) NOT NULL,
`price` decimal(16,8) NOT NULL,
`currency` varchar(10) NOT NULL,
`invoice_time` int(11) unsigned NOT NULL,
`expiration_time` int(11) unsigned NOT NULL,
`current_time` int(11) unsigned NOT NULL,
PRIMARY KEY (`id`),
KEY `quote_id` (`quote_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ;
");
$installer->endSetup();

View File

@ -1,32 +0,0 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2011-2014 BitPay LLC
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
$installer = $this;
$installer->startSetup();
$installer->run("ALTER TABLE `{$installer->getTable('Bitcoins/ipn')}` ADD `pos_data` VARCHAR( 256 ) NOT NULL AFTER `url`;");
$installer->endSetup();

View File

@ -0,0 +1,26 @@
<?php
/**
* @license Copyright 2011-2014 BitPay Inc., MIT License
* @see https://github.com/bitpay/magento-plugin/blob/master/LICENSE
*/
/**
* This is used to display php extensions and if they are installed or not
*/
class Bitpay_Core_Block_Adminhtml_System_Config_Form_Field_Extension extends Mage_Adminhtml_Block_System_Config_Form_Field
{
/**
* @param Varien_Data_Form_Element_Abstract $element
* @return string
*/
protected function _getElementHtml(Varien_Data_Form_Element_Abstract $element)
{
$phpExtension = $element->getFieldConfig()->php_extension;
if (in_array($phpExtension, get_loaded_extensions())) {
return 'Installed';
}
return 'Not Installed';
}
}

View File

@ -0,0 +1,28 @@
<?php
/**
* @license Copyright 2011-2014 BitPay Inc., MIT License
* @see https://github.com/bitpay/magento-plugin/blob/master/LICENSE
*/
/**
* Used to display header on the admin configuration page
*/
class Bitpay_Core_Block_Adminhtml_System_Config_Form_Field_Header extends Mage_Adminhtml_Block_Abstract implements Varien_Data_Form_Element_Renderer_Interface
{
/**
* This is the location of the template used to display the output
* on the page. Please modifiy the template.
*
* @var string
*/
protected $_template = 'bitpay/system/config/field/header.phtml';
/**
* @param Varien_Data_Form_Element_Abstract $element
* @return string
*/
public function render(Varien_Data_Form_Element_Abstract $element)
{
return $this->toHtml();
}
}

View File

@ -0,0 +1,14 @@
<?php
/**
* @license Copyright 2011-2014 BitPay Inc., MIT License
* @see https://github.com/bitpay/magento-plugin/blob/master/LICENSE
*/
class Bitpay_Core_Block_Form_Bitpay extends Mage_Payment_Block_Form
{
protected function _construct()
{
parent::_construct();
$this->setTemplate('bitpay/form/bitpay.phtml');
}
}

View File

@ -0,0 +1,68 @@
<?php
/**
* @license Copyright 2011-2014 BitPay Inc., MIT License
* @see https://github.com/bitpay/magento-plugin/blob/master/LICENSE
*/
class Bitpay_Core_Block_Iframe extends Mage_Checkout_Block_Onepage_Payment
{
/**
*/
protected function _construct()
{
parent::_construct();
$this->setTemplate('bitpay/iframe.phtml');
}
/**
* create an invoice and return the url so that iframe.phtml can display it
*
* @return string
*/
public function getIframeUrl()
{
if (Mage::getModel('bitpay/ipn')->getQuotePaid($this->getQuote()->getId())) {
return 'paid'; // quote's already paid, so don't show the iframe
}
/*** @var Bitpay_Core_Model_PaymentMethod ***/
$method = $this->getQuote()->getPayment()->getMethodInstance();
$options = array_merge(
array(
'currency' => $this->getQuote()->getQuoteCurrencyCode(),
'fullNotifications' => 'true',
'notificationURL' => Mage::getUrl('bitpay/ipn'),
'redirectURL' => Mage::getUrl('checkout/onepage/success'),
'transactionSpeed' => Mage::getStoreConfig('payment/bitpay/speed'),
),
$method->extractAddress($this->getQuote()->getShippingAddress())
);
Mage::helper('bitpay')->debugData($options);
// 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($this->getQuote()->getGrandTotal(), 4);
//serialize info about the quote to detect changes
$hash = $method->getQuoteHash($this->getQuote()->getId());
Mage::helper('bitpay')->registerAutoloader();
//$invoice = bpCreateInvoice($quoteId, $price, array('quoteId' => $quoteId, 'quoteHash' => $hash), $options);
$invoice = array('url' => 'https://test.bitpay.com/invoice?id=5NxFkXcJbCSivtQRJa4kHP');
if (array_key_exists('error', $invoice)) {
Mage::helper('bitpay')->debugData(
array(
'Error creating bitpay invoice',
$invoice['error'],
)
);
Mage::throwException("Error creating BitPay invoice. Please try again or use another payment option.");
return false;
}
return $invoice['url'].'&view=iframe';
}
}

View File

@ -0,0 +1,26 @@
<?php
/**
* @license Copyright 2011-2014 BitPay Inc., MIT License
* @see https://github.com/bitpay/magento-plugin/blob/master/LICENSE
*/
class Bitpay_Core_Block_Info extends Mage_Payment_Block_Info
{
public function _construct()
{
parent::_construct();
$this->setTemplate('bitpay/info/default.phtml');
}
public function getBitpayInvoiceUrl()
{
$order = $this->getInfo()->getOrder();
$incrementId = $order->getIncrementId();
$bitpayInvoice = Mage::getModel('bitpay/invoice')->load($incrementId, 'increment_id');
if ($bitpayInvoice) {
return $bitpayInvoice->getUrl();
}
}
}

View File

@ -0,0 +1,265 @@
<?php
/**
* @license Copyright 2011-2014 BitPay Inc., MIT License
* @see https://github.com/bitpay/magento-plugin/blob/master/LICENSE
*/
/**
*/
class Bitpay_Core_Helper_Data extends Mage_Core_Helper_Abstract
{
protected $_autoloaderRegistered;
protected $_bitpay;
protected $_sin;
protected $_publicKey;
protected $_privateKey;
protected $_keyManager;
protected $_client;
/**
* @param mixed $debugData
*/
public function debugData($debugData)
{
Mage::getModel('bitpay/method_bitcoin')->debugData($debugData);
}
/**
* @return boolean
*/
public function isDebug()
{
return (boolean) Mage::getStoreConfig('payment/bitpay/debug');
}
/**
* Returns true if Transaction Speed has been configured
*
* @return boolean
*/
public function hasTransactionSpeed()
{
$speed = Mage::getStoreConfig('payment/bitpay/speed');
return !empty($speed);
}
/**
* Returns the URL where the IPN's are sent
*
* @return string
*/
public function getNotificationUrl()
{
return Mage::getUrl(Mage::getStoreConfig('payment/bitpay/notification_url'));
}
/**
* Returns the URL where customers are redirected
*
* @return string
*/
public function getRedirectUrl()
{
return Mage::getUrl(Mage::getStoreConfig('payment/bitpay/redirect_url'));
}
/**
* Registers the BitPay autoloader to run before Magento's. This MUST be
* called before using any bitpay classes.
*/
public function registerAutoloader()
{
if (null === $this->_autoloaderRegistered) {
require_once Mage::getBaseDir('lib').'/Bitpay/Autoloader.php';
\Bitpay\Autoloader::register();
$this->_autoloaderRegistered = true;
$this->debugData('BitPay Autoloader has been registered');
}
}
/**
* This function will generate keys that will need to be paired with BitPay
* using
*/
public function generateAndSaveKeys()
{
$this->debugData('Generating Keys');
$this->registerAutoloader();
$this->_privateKey = new Bitpay\PrivateKey('payment/bitpay/private_key');
$this->_privateKey->generate();
$this->_publicKey = new Bitpay\PublicKey('payment/bitpay/public_key');
$this->_publicKey
->setPrivateKey($this->_privateKey)
->generate();
$this->getKeyManager()->persist($this->_publicKey);
$this->getKeyManager()->persist($this->_privateKey);
$this->debugData('Keys persisted to database');
}
/**
* Send a pairing request to BitPay to receive a Token
*/
public function sendPairingRequest($pairingCode)
{
$this->debugData(
sprintf('Sending Paring Request with pairing code "%s"', $pairingCode)
);
// Generate/Regenerate keys
$this->generateAndSaveKeys();
$sin = $this->getSinKey();
$this->debugData(
sprintf('Sending Pairing Request for SIN "%s"', (string) $sin)
);
$token = $this->getBitpayClient()->createToken(
array(
'id' => (string) $sin,
'pairingCode' => $pairingCode,
'label' => sprintf('[Magento Store] %s', Mage::app()->getStore()->getName()),
)
);
$this->debugData('Token Obtained');
$config = new \Mage_Core_Model_Config();
$config->saveConfig('payment/bitpay/token', $token->getToken());
$this->debugData('Token Persisted persisted to database');
}
/**
* @return Bitpay\SinKey
*/
public function getSinKey()
{
if (null !== $this->_sin) {
return $this->_sin;
}
$this->debugData('Getting SIN Key');
$this->registerAutoloader();
$this->_sin = new Bitpay\SinKey();
$this->_sin
->setPublicKey($this->getPublicKey())
->generate();
return $this->_sin;
}
public function getPublicKey()
{
if (null !== $this->_publicKey) {
return $this->_publicKey;
}
$this->debugData('Getting Public Key');
$this->_publicKey = $this->getKeyManager()->load('payment/bitpay/public_key');
if (!$this->_publicKey) {
$this->generateAndSaveKeys();
}
return $this->_publicKey;
}
public function getPrivateKey()
{
if (null !== $this->_privateKey) {
return $this->_privateKey;
}
$this->debugData('Getting Private Key');
$this->_privateKey = $this->getKeyManager()->load('payment/bitpay/private_key');
if (!$this->_publicKey) {
$this->generateAndSaveKeys();
}
return $this->_privateKey;
}
/**
* @return Bitpay\KeyManager
*/
public function getKeyManager()
{
if (null == $this->_keyManager) {
$this->registerAutoloader();
$this->debugData('Creating instance of KeyManager');
$this->_keyManager = new Bitpay\KeyManager(new Bitpay\Storage\MagentoStorage());
}
return $this->_keyManager;
}
/**
* Initialize an instance of Bitpay or return the one that has already
* been created.
*
* @return Bitpay\Bitpay
*/
public function getBitpay()
{
if (null === $this->_bitpay) {
$this->registerAutoloader();
$this->_bitpay = new Bitpay\Bitpay(array('bitpay' => $this->getBitpayConfig()));
}
return $this->_bitpay;
}
/**
* Sets up the bitpay container with settings for magento
*
* @return array
*/
protected function getBitpayConfig()
{
return array(
'public_key' => 'payment/bitpay/public_key',
'private_key' => 'payment/bitpay/private_key',
'network' => Mage::getStoreConfig('payment/bitpay/network'),
'key_storage' => '\\Bitpay\\Storage\\MagentoStorage',
);
}
/**
* @return Bitpay\Client
*/
public function getBitpayClient()
{
if (null !== $this->_client) {
return $this->_client;
}
$this->registerAutoloader();
$this->_client = new Bitpay\Client\Client();
$this->_client->setPublicKey($this->getPublicKey());
$this->_client->setPrivateKey($this->getPrivateKey());
$this->_client->setNetwork($this->getBitpay()->get('network'));
$this->_client->setAdapter($this->getBitpay()->get('adapter'));
$this->_client->setToken($this->getToken());
return $this->_client;
}
public function getToken()
{
$this->registerAutoloader();
$token = new Bitpay\Token();
$token->setToken(Mage::getStoreConfig('payment/bitpay/token'));
return $token;
}
}

View File

@ -0,0 +1,47 @@
<?php
/**
* @license Copyright 2011-2014 BitPay Inc., MIT License
* @see https://github.com/bitpay/magento-plugin/blob/master/LICENSE
*/
/**
* This class will take the pairing code the merchant entered and pair it with
* BitPay's API.
*/
class Bitpay_Core_Model_Config_PairingCode extends Mage_Core_Model_Config_Data
{
/**
* @inheritdoc
*/
public function save()
{
/**
* If the user has put a paring code into the text field, we want to
* pair the magento store to the stores keys. If the merchant is just
* updating a configuration setting, we could care less about the
* pairing code.
*/
$pairingCode = trim($this->getValue());
if (empty($pairingCode)) {
return;
}
Mage::helper('bitpay')->debugData('Attempting Pair Code');
try {
Mage::helper('bitpay')->sendPairingRequest($pairingCode);
} catch (Exception $e) {
Mage::helper('bitpay')->debugData(
sprintf('Error Pairing Code "%s"', $e->getMessage())
);
Mage::getSingleton('core/session')->addError(
'There was an error while trying to pair the pairing code. Please try again or enabled debug mode and send the "payment_bitpay.log" file to support.'
);
return;
}
Mage::getSingleton('core/session')->addSuccess('Pairing Code was successful.');
}
}

View File

@ -0,0 +1,70 @@
<?php
/**
* @license Copyright 2011-2014 BitPay Inc., MIT License
* @see https://github.com/bitpay/magento-plugin/blob/master/LICENSE
*/
/**
*/
class Bitpay_Core_Model_Invoice extends Mage_Core_Model_Abstract
{
/**
*/
protected function _construct()
{
$this->_init('bitpay/invoice');
}
/**
* Adds data to model based on an Invoice that has been retrieved from
* BitPay's API
*
* @param Bitpay\Invoice $invoice
* @return Bitpay_Core_Model_Invoice
*/
public function prepareWithBitpayInvoice($invoice)
{
$this->addData(
array(
'id' => $invoice->getId(),
//'updated_at' => 'NOW()',
'url' => $invoice->getUrl(),
'pos_data' => $invoice->getPosData(),
'status' => $invoice->getStatus(),
'btc_price' => $invoice->getBtcPrice(),
//'btc_due' => $invoice->getBtcDue(),
'price' => $invoice->getPrice(),
'currency' => $invoice->getCurrency()->getCode(),
//'ex_rates' => $invoice->getExRates(),
'order_id' => $invoice->getOrderId(),
'invoice_time' => $invoice->getInvoiceTime(),
'expiration_time' => $invoice->getExpirationTime(),
'current_time' => $invoice->getCurrentTime(),
'btc_paid' => $invoice->getBtcPaid(),
'rate' => $invoice->getRate(),
'exception_status' => $invoice->getExceptionStatus(),
//'token' => $invoice->getToken(),
)
);
return $this;
}
/**
* Adds information to based on the order object inside magento
*
* @param Mage_Sales_Model_Order $order
* @return Bitpay_Core_Model_Invoice
*/
public function prepateWithOrder($order)
{
$this->addData(
array(
'quote_id' => $order->getQuoteId(),
'increment_id' => $order->getIncrementId(),
)
);
return $this;
}
}

View File

@ -0,0 +1,17 @@
<?php
/**
* @license Copyright 2011-2014 BitPay Inc., MIT License
* @see https://github.com/bitpay/magento-plugin/blob/master/LICENSE
*/
/**
*/
class Bitpay_Core_Model_Ipn extends Mage_Core_Model_Abstract
{
/**
*/
protected function _construct()
{
$this->_init('bitpay/ipn');
}
}

View File

@ -0,0 +1,262 @@
<?php
/**
* @license Copyright 2011-2014 BitPay Inc., MIT License
* @see https://github.com/bitpay/magento-plugin/blob/master/LICENSE
*/
/**
* Bitcoin payment method support by BitPay
*/
class Bitpay_Core_Model_Method_Bitcoin extends Mage_Payment_Model_Method_Abstract
{
protected $_code = 'bitpay';
protected $_formBlockType = 'bitpay/form_bitpay';
protected $_infoBlockType = 'bitpay/info';
protected $_isGateway = true;
protected $_canAuthorize = true;
protected $_canCapture = false;
protected $_canUseInternal = false;
protected $_isInitializeNeeded = false;
protected $_canFetchTransactionInfo = false;
protected $_canManagerRecurringProfiles = false;
//protected $_canUseCheckout = true;
//protected $_canUseForMultishipping = true;
//protected $_canCapturePartial = false;
//protected $_canRefund = false;
//protected $_canVoid = false;
protected $_debugReplacePrivateDataKeys = array();
protected static $_redirectUrl;
/**
* @param Mage_Sales_Model_Order_Payment $payment
* @param float $amount
* @return Bitpay_Core_Model_PaymentMethod
*/
public function authorize(Varien_Object $payment, $amount)
{
$this->debugData('authorizing new order');
// Create BitPay Invoice
$invoice = $this->initializeInvoice();
$invoice = $this->prepareInvoice($invoice, $payment, $amount);
try {
$bitpayInvoice = Mage::helper('bitpay')->getBitpayClient()->createInvoice($invoice);
} catch (Exception $e) {
$this->debugData($e->getMessage());
$this->debugData(
array(
Mage::helper('bitpay')->getBitpayClient()->getRequest()->getBody(),
Mage::helper('bitpay')->getBitpayClient()->getResponse()->getBody(),
)
);
Mage::throwException('Could not authorize transaction.');
}
self::$_redirectUrl = $bitpayInvoice->getUrl();
$this->debugData(
array(
'BitPay Invoice created',
sprintf('Invoice URL: "%s"', $bitpayInvoice->getUrl()),
)
);
// Save BitPay Invoice in database for reference
$mirrorInvoice = Mage::getModel('bitpay/invoice')
->prepareWithBitpayInvoice($bitpayInvoice)
->prepateWithOrder($payment->getOrder())
->save();
$this->debugData($bitpayInvoice->getId());
return $this;
}
/**
* This makes sure that the merchant has setup the extension correctly
* and if they have not, it will not show up on the checkout.
*
* @see Mage_Payment_Model_Method_Abstract::canUseCheckout()
* @return bool
*/
public function canUseCheckout()
{
$token = Mage::getStoreConfig('payment/bitpay/token');
if (empty($token)) {
/**
* Merchant must goto their account and create a pairing code to
* enter in.
*/
$this->debugData('Magento store does not have a BitPay token.');
return false;
}
return true;
}
/**
* Fetchs an invoice from BitPay
*
* @param string $id
* @return Bitpay\Invoice
*/
public function fetchInvoice($id)
{
Mage::helper('bitpay')->registerAutoloader();
$client = Mage::helper('bitpay')->getBitpayClient();
$invoice = $client->getInvoice($id);
return $invoice;
}
/**
* given Mage_Core_Model_Abstract, return api-friendly address
*
* @param $address
*
* @return array
*/
public function extractAddress($address)
{
$this->debugData(
sprintf('Extracting addess')
);
$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;
}
/**
* This is called when a user clicks the `Place Order` button
*
* @return string
*/
public function getOrderPlaceRedirectUrl()
{
$this->debugData(
'Customer wants to place the order. Create invoice and redirect user to invoice'
);
return self::$_redirectUrl;
}
/**
* Create a new invoice with as much info already added. It should add
* some basic info and setup the invoice object.
*
* @return Bitpay\Invoice
*/
private function initializeInvoice()
{
Mage::helper('bitpay')->registerAutoloader();
$invoice = new Bitpay\Invoice();
$invoice->setFullNotifications(true);
$invoice->setTransactionSpeed(Mage::getStoreConfig('payment/bitpay/speed'));
$invoice->setNotificationUrl(Mage::getUrl(Mage::getStoreConfig('payment/bitpay/notification_url')));
$invoice->setRedirectUrl(Mage::getUrl(Mage::getStoreConfig('payment/bitpay/redirect_url')));
return $invoice;
}
/**
* Prepares the invoice object to be sent to BitPay's API. This method sets
* all the other info that we have to rely on other objects for.
*
* @param Bitpay\Invoice $invoice
* @param Mage_Sales_Model_Order_Payment $payment
* @param float $amount
* @return Bitpay\Invoice
*/
private function prepareInvoice($invoice, $payment, $amount)
{
$invoice->setOrderId($payment->getOrder()->getIncrementId());
$invoice->setPosData(
json_encode(
array(
'id' => $payment->getOrder()->getIncrementId(),
)
)
);
$invoice = $this->addCurrencyInfo($invoice, $payment->getOrder());
$invoice = $this->addPriceInfo($invoice, $amount);
$invoice = $this->addBuyerInfo($invoice, $payment->getOrder());
return $invoice;
}
/**
* This adds the buyer information to the invoice.
*
* @param Bitpay\Invoice $invoice
* @param Mage_Sales_Model_Order $order
* @return Bitpay\Invoice
*/
private function addBuyerInfo($invoice, $order)
{
$buyer = new Bitpay\Buyer();
$buyer->setFirstName($order->getCustomerFirstname());
$buyer->setLastName($order->getCustomerLastname());
$invoice->setBuyer($buyer);
return $invoice;
}
/**
* Adds currency information to the invoice
*
* @param Bitpay\Invoice $invoice
* @param Mage_Sales_Model_Order $order
* @return Bitpay\Invoice
*/
private function addCurrencyInfo($invoice, $order)
{
$currency = new Bitpay\Currency();
$currency->setCode($order->getBaseCurrencyCode());
$invoice->setCurrency($currency);
return $invoice;
}
/**
* Adds pricing information to the invoice
*
* @param Bitpay\Invoice invoice
* @param float $amount
* @return Bitpay\Invoice
*/
private function addPriceInfo($invoice, $amount)
{
$item = new \Bitpay\Item();
$item->setPrice($amount);
$invoice->setItem($item);
return $invoice;
}
}

View File

@ -0,0 +1,19 @@
<?php
/**
* @license Copyright 2011-2014 BitPay Inc., MIT License
* @see https://github.com/bitpay/magento-plugin/blob/master/LICENSE
*/
/**
*/
class Bitpay_Core_Model_Mysql4_Invoice extends Mage_Core_Model_Mysql4_Abstract
{
protected $_isPkAutoIncrement = false;
/**
*/
protected function _construct()
{
$this->_init('bitpay/invoice', 'id');
}
}

View File

@ -0,0 +1,19 @@
<?php
/**
* @license Copyright 2011-2014 BitPay Inc., MIT License
* @see https://github.com/bitpay/magento-plugin/blob/master/LICENSE
*/
/**
*/
class Bitpay_Core_Model_Mysql4_Invoice_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract
{
protected $_isPkAutoIncrement = false;
/**
*/
protected function _construct()
{
$this->_init('bitpay/invoice');
}
}

View File

@ -0,0 +1,17 @@
<?php
/**
* @license Copyright 2011-2014 BitPay Inc., MIT License
* @see https://github.com/bitpay/magento-plugin/blob/master/LICENSE
*/
/**
*/
class Bitpay_Core_Model_Mysql4_Ipn extends Mage_Core_Model_Mysql4_Abstract
{
/**
*/
protected function _construct()
{
$this->_init('bitpay/ipn', 'id');
}
}

View File

@ -0,0 +1,16 @@
<?php
/**
* @license Copyright 2011-2014 BitPay Inc., MIT License
* @see https://github.com/bitpay/magento-plugin/blob/master/LICENSE
*/
class Bitpay_Core_Model_Mysql4_Ipn_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract
{
/**
*/
protected function _construct()
{
parent::_construct();
$this->_init('bitpay/ipn');
}
}

View File

@ -0,0 +1,25 @@
<?php
/**
* @license Copyright 2011-2014 BitPay Inc., MIT License
* @see https://github.com/bitpay/magento-plugin/blob/master/LICENSE
*/
/**
* Used to display bitcoin networks
*/
class Bitpay_Core_Model_Network
{
const NETWORK_LIVENET = 'livenet';
const NETWORK_TESTNET = 'testnet';
/**
* @return array
*/
public function toOptionArray()
{
return array(
array('value' => self::NETWORK_LIVENET, 'label' => Mage::helper('bitpay')->__('Livenet')),
array('value' => self::NETWORK_TESTNET, 'label' => Mage::helper('bitpay')->__('Testnet')),
);
}
}

View File

@ -0,0 +1,74 @@
<?php
/**
* @license Copyright 2011-2014 BitPay Inc., MIT License
* @see https://github.com/bitpay/magento-plugin/blob/master/LICENSE
*/
class Bitpay_Core_Model_Observer
{
/**
*/
public function checkForRequest($observer)
{
}
/**
* Queries BitPay to update the order states in magento to make sure that
* open orders are closed/canceled if the BitPay invoice expires or becomes
* invalid.
*/
public function updateOrderStates()
{
Mage::helper('bitpay')->debugData(
'cronjob: started'
);
$apiKey = Mage::getStoreConfig('payment/bitpay/api_key');
if (empty($apiKey)) {
Mage::helper('bitpay')->debugData(
'cronjob: Api Key not set.'
);
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('bitpay/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::helper('bitpay')->debugData(
'cronjob: end'
);
}
/**
* Method that is called via the magento cron to update orders if the
* invoice has expired
*/
public function cleanExpired()
{
Mage::helper('bitpay')->cleanExpired();
}
}

View File

@ -0,0 +1,11 @@
<?php
/**
* @license Copyright 2011-2014 BitPay Inc., MIT License
* @see https://github.com/bitpay/magento-plugin/blob/master/LICENSE
*/
/**
*/
class Bitpay_Core_Model_Resource_Mysql4_Setup extends Mage_Core_Model_Resource_Setup
{
}

View File

@ -0,0 +1,30 @@
<?php
/**
* @license Copyright 2011-2014 BitPay Inc., MIT License
* @see https://github.com/bitpay/magento-plugin/blob/master/LICENSE
*/
class Bitpay_Core_Model_Status
{
const STATUS_NEW = 'new';
const STATUS_PAID = 'paid';
const STATUS_CONFIRMED = 'confirmed';
const STATUS_COMPLETE = 'complete';
const STATUS_EXPIRED = 'expired';
const STATUS_INVALID = 'invalid';
/**
* @return array
*/
public function toOptionArray()
{
return array(
array('value' => self::STATUS_NEW, 'label' => Mage::helper('bitpay')->__('New')),
array('value' => self::STATUS_PAID, 'label' => Mage::helper('bitpay')->__('Paid')),
array('value' => self::STATUS_CONFIRMED, 'label' => Mage::helper('bitpay')->__('Confirmed')),
array('value' => self::STATUS_COMPLETE, 'label' => Mage::helper('bitpay')->__('Complete')),
array('value' => self::STATUS_EXPIRED, 'label' => Mage::helper('bitpay')->__('Expired')),
array('value' => self::STATUS_INVALID, 'label' => Mage::helper('bitpay')->__('Invalid')),
);
}
}

View File

@ -0,0 +1,24 @@
<?php
/**
* @license Copyright 2011-2014 BitPay Inc., MIT License
* @see https://github.com/bitpay/magento-plugin/blob/master/LICENSE
*/
class Bitpay_Core_Model_TransactionSpeed
{
const SPEED_LOW = 'low';
const SPEED_MEDIUM = 'medium';
const SPEED_HIGH = 'high';
/**
* @return array
*/
public function toOptionArray()
{
return array(
array('value' => self::SPEED_LOW, 'label' => Mage::helper('bitpay')->__('Low')),
array('value' => self::SPEED_MEDIUM, 'label' => Mage::helper('bitpay')->__('Medium')),
array('value' => self::SPEED_HIGH, 'label' => Mage::helper('bitpay')->__('High')),
);
}
}

View File

@ -0,0 +1,34 @@
<?php
/**
* @license Copyright 2011-2014 BitPay Inc., MIT License
* @see https://github.com/bitpay/magento-plugin/blob/master/LICENSE
*/
/**
* @route bitpay/index/
*/
class Bitpay_Core_IndexController extends Mage_Core_Controller_Front_Action
{
/**
* @route bitpay/index/index?quote=n
*/
public function indexAction()
{
$params = $this->getRequest()->getParams();
$paid = false;
if (isset($params['paid'])) {
Mage::helper('bitpay')->registerAutoloader();
Mage::helper('bitpay')->debugData(
$params
);
//$quoteId = $params['quote'];
//$paid = Mage::getModel('bitpay/ipn')->getQuotePaid($quoteId);
}
$this->loadLayout();
$this->getResponse()->setHeader('Content-type', 'application/json');
$this->getResponse()->setBody(
json_encode(array('paid' => $paid))
);
}
}

View File

@ -0,0 +1,103 @@
<?php
/**
* @license Copyright 2011-2014 BitPay Inc., MIT License
* @see https://github.com/bitpay/magento-plugin/blob/master/LICENSE
*/
/**
* @route /bitpay/ipn
*/
class Bitpay_Core_IpnController extends Mage_Core_Controller_Front_Action
{
/**
* bitpay's IPN lands here
*
* @route /bitpay/ipn
* @route /bitpay/ipn/index
*/
public function indexAction()
{
Mage::helper('bitpay')->registerAutoloader();
Mage::helper('bitpay')->debugData(
array(
sprintf('Incoming IPN from bitpay'),
getallheaders(),
file_get_contents('php://input'),
)
);
// Magento doesn't seem to have a way to get the Request body
$ipn = json_decode(file_get_contents('php://input'));
$ipn->posData = is_string($ipn->posData) ? json_decode($ipn->posData) : $ipn->posData;
$ipn->buyerFields = isset($ipn->buyerFields) ? $ipn->buyerFields : new stdClass();
Mage::helper('bitpay')->debugData($ipn);
// Log IPN
$mageIpn = Mage::getModel('bitpay/ipn')->addData(
array(
'invoice_id' => isset($ipn->id) ? $ipn->id : '',
'url' => isset($ipn->url) ? $ipn->url : '',
'pos_data' => json_encode($ipn->posData),
'status' => isset($ipn->status) ? $ipn->status : '',
'btc_price' => isset($ipn->btcPrice) ? $ipn->btcPrice : '',
'price' => isset($ipn->price) ? $ipn->price : '',
'currency' => isset($ipn->currency) ? $ipn->currency : '',
'invoice_time' => isset($ipn->invoiceTime) ? $ipn->invoiceTime : '',
'expiration_time' => isset($ipn->expirationTime) ? $ipn->expirationTime : '',
'current_time' => isset($ipn->currentTime) ? $ipn->currentTime : '',
'btc_paid' => isset($ipn->btcPaid) ? $ipn->btcPaid : '',
'rate' => isset($ipn->rate) ? $ipn->rate : '',
'exception_status' => isset($ipn->exceptionStatus) ? $ipn->exceptionStatus : '',
)
)->save();
if (empty($ipn->id) || !isset($ipn->posData->id)) {
Mage::helper('bitpay')->debugData(
sprintf('Did not receive order id in IPN. See IPN "%s" in database.', $mageIpn->getId())
);
throw new Exception('Invalid Bitpay IPN received.');
}
$order = Mage::getModel('sales/order')->loadByIncrementId($ipn->posData->id);
if (!$order->getId()) {
Mage::helper('bitpay')->debugData('Invalid Bitpay IPN received.');
Mage::throwException('Invalid Bitpay IPN received.');
}
/**
* Ask BitPay to retreive the invoice so we can make sure the invoices
* match up and no one is using an automated tool to post IPN's to merchants
* store.
*/
$invoice = Mage::getModel('bitpay/method_bitcoin')->fetchInvoice($ipn->id);
// Does the status match?
if ($invoice && $invoice->getStatus() != $ipn->status) {
Mage::getModel('bitpay/method_bitcoin')->debugData('IPN status and status from BitPay are different');
Mage::throwException('There was an error processing the ipn');
}
// Does the price match?
if ($invoice && $invoice->getPrice() != $ipn->price) {
Mage::getModel('bitpay/method_bitcoin')>debugData('Price difference');
Mage::throwException('There was an error processing the ipn');
}
// Update the order to notifiy that it has been paid
if (in_array($invoice->getStatus(), array('paid', 'confirmed', 'complete'))) {
$payment = Mage::getModel('sales/order_payment')->setOrder($order);
$payment->registerCaptureNotification($invoice->getPrice());
$order->addPayment($payment)->save();
}
// use state as defined by Merchant
$state = Mage::getStoreConfig(sprintf('payment/bitpay/invoice_%s', $invoice->getStatus()));
$order->addStatusToHistory(
$state,
sprintf('Incoming IPN status "%s" updateded order state to "%s"', $invoice->getStatus(), $state)
)->save();
}
}

View File

@ -0,0 +1,47 @@
<?xml version="1.0"?>
<!--
/**
* @license Copyright 2011-2014 BitPay Inc., MIT License
* @see https://github.com/bitpay/magento-plugin/blob/master/LICENSE
*/
-->
<config>
<acl>
<resources>
<admin>
<children>
<bitpay translate="title" module="bitpay">
<title>BitPay</title>
</bitpay>
<system>
<children>
<config>
<children>
<bitpay translate="title" module="bitpay">
<title>BitPay Settings</title>
</bitpay>
</children>
</config>
</children>
</system>
</children>
</admin>
</resources>
</acl>
<layout>
<updates>
<bitpay>
<file>bitpay.xml</file>
</bitpay>
</updates>
</layout>
<translate>
<modules>
<bitpay>
<files>
<default>Bitpay_Core.csv</default>
</files>
</bitpay>
</modules>
</translate>
</config>

View File

@ -0,0 +1,130 @@
<?xml version="1.0"?>
<!--
/**
* @license Copyright 2011-2014 BitPay Inc., MIT License
* @see https://github.com/bitpay/magento-plugin/blob/master/LICENSE
*/
-->
<config>
<modules>
<Bitpay_Core>
<version>2.0.0</version>
</Bitpay_Core>
</modules>
<frontend>
<routers>
<bitpay>
<use>standard</use>
<args>
<module>Bitpay_Core</module>
<frontName>bitpay</frontName>
</args>
</bitpay>
</routers>
<layout>
<updates>
<bitpay>
<file>bitpay.xml</file>
</bitpay>
</updates>
</layout>
<translate>
<modules>
<bitpay>
<files>
<default>Bitpay_Core.csv</default>
</files>
</bitpay>
</modules>
</translate>
</frontend>
<admin>
<routers>
<adminhtml>
<args>
<modules>
<bitpay before="Mage_Adminhtml">Bitpay_Core_Adminhtml</bitpay>
</modules>
</args>
</adminhtml>
</routers>
</admin>
<global>
<blocks>
<bitpay>
<class>Bitpay_Core_Block</class>
</bitpay>
</blocks>
<helpers>
<bitpay>
<class>Bitpay_Core_Helper</class>
</bitpay>
</helpers>
<models>
<bitpay>
<class>Bitpay_Core_Model</class>
<resourceModel>bitpay_mysql4</resourceModel>
</bitpay>
<bitpay_mysql4>
<class>Bitpay_Core_Model_Mysql4</class>
<entities>
<invoice>
<table>bitpay_invoices</table>
</invoice>
<ipn>
<table>bitpay_ipns</table>
</ipn>
</entities>
</bitpay_mysql4>
</models>
<resources>
<bitpay_write>
<connection>
<use>core_write</use>
</connection>
</bitpay_write>
<bitpay_read>
<connection>
<use>core_read</use>
</connection>
</bitpay_read>
<bitpay_setup>
<setup>
<module>Bitpay_Core</module>
<class>Bitpay_Core_Model_Resource_Mysql4_Setup</class>
</setup>
<connection>
<use>core_setup</use>
</connection>
</bitpay_setup>
</resources>
</global>
<default>
<payment>
<bitpay>
<model>bitpay/method_bitcoin</model>
<order_status>new</order_status>
<payment_action>authorize</payment_action>
<active>0</active>
<title>Bitcoin</title>
<network>testnet</network>
<debug>0</debug>
<notification_url>bitpay/ipn</notification_url>
<redirect_url>checkout/onepage/success</redirect_url>
<speed>medium</speed>
<invoice_new>new</invoice_new>
<invoice_paid>processing</invoice_paid>
<invoice_confirmed>processing</invoice_confirmed>
<invoice_complete>complete</invoice_complete>
<invoice_expired>canceled</invoice_expired>
<invoice_invalid>canceled</invoice_invalid>
</bitpay>
</payment>
</default>
</config>

View File

@ -0,0 +1,274 @@
<?xml version="1.0"?>
<!--
/**
* @license Copyright 2011-2014 BitPay Inc., MIT License
* @see https://github.com/bitpay/magento-plugin/blob/master/LICENSE
*/
-->
<config>
<sections>
<payment>
<groups>
<bitpay translate="label" module="bitpay">
<label>Bitpay</label>
<sort_order>670</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
<fields>
<header>
<label>BitPay</label>
<frontend_class>complex</frontend_class>
<frontend_model>bitpay/adminhtml_system_config_form_field_header</frontend_model>
<sort_order>0</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
</header>
<pairing_code translate="label">
<label>Pairing Code</label>
<comment>
<![CDATA[Create a pairing code for your account at <a href="https://bitpay.com/api-tokens">https://bitpay.com/api-tokens</a> and put
the code that was generated in this field. Once you have paired your Mangento store you can begin accepted Bitcoins as payment
on your store.]]>
</comment>
<frontend_type>text</frontend_type>
<backend_model>bitpay/config_pairingCode</backend_model>
<sort_order>1</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
</pairing_code>
<active translate="label">
<label>Enabled</label>
<frontend_type>select</frontend_type>
<source_model>adminhtml/system_config_source_yesno</source_model>
<sort_order>10</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
</active>
<title translate="label">
<label>Title</label>
<comment>
What your customers will see during their checkout
experience.
</comment>
<frontend_type>text</frontend_type>
<sort_order>20</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
</title>
<network translate="label">
<label>Network</label>
<comment>
<![CDATA[You can sign up for a test account at <a href="https://test.bitpay.com">test.bitpay.com</a>.]]>
</comment>
<frontend_type>select</frontend_type>
<source_model>bitpay/network</source_model>
<sort_order>30</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
</network>
<debug translate="label">
<label>Debug</label>
<comment>By enabling this, it will output more verbose information in log files.</comment>
<frontend_type>select</frontend_type>
<source_model>adminhtml/system_config_source_yesno</source_model>
<sort_order>40</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
</debug>
<notification_url translate="label">
<label>Notification URL</label>
<frontend_type>text</frontend_type>
<sort_order>50</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
</notification_url>
<redirect_url translate="label">
<label>Redirect URL</label>
<frontend_type>text</frontend_type>
<sort_order>60</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
</redirect_url>
<speed translate="label">
<label>Transaction Speed</label>
<frontend_type>select</frontend_type>
<source_model>bitpay/transactionSpeed</source_model>
<sort_order>70</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
<comment><![CDATA[Determines when a BitPay payment confirmation is sent.<br /><strong>High:</strong> an invoice is confirmed immediately when payment received.<br /><strong>Medium:</strong> an invoice is confirmed after 1 block confirmation by the network (~10 mins).<br /><strong>Low:</strong> an invoice is confirmed after 6 block confirmations by the network (~1 hour).<br />The default and safest setting is "Low". A "High" setting is quicker to generate a payment confirmation but is riskier since the transaction could have not been officially confirmed by the Bitcoin network itself.]]></comment>
</speed>
<mage_settings_heading>
<label>Magento Specific Settings</label>
<frontend_model>adminhtml/system_config_form_field_heading</frontend_model>
<sort_order>75</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
</mage_settings_heading>
<allowspecific translate="label">
<label>Payment from Applicable Countries</label>
<frontend_type>allowspecific</frontend_type>
<sort_order>76</sort_order>
<source_model>adminhtml/system_config_source_payment_allspecificcountries</source_model>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>0</show_in_store>
</allowspecific>
<specificcountry translate="label">
<label>Payment from Specific Countries</label>
<frontend_type>multiselect</frontend_type>
<sort_order>77</sort_order>
<source_model>adminhtml/system_config_source_country</source_model>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>0</show_in_store>
</specificcountry>
<min_order_total translate="label">
<label>Minimum Order Total</label>
<frontend_type>text</frontend_type>
<sort_order>80</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>0</show_in_store>
</min_order_total>
<max_order_total translate="label">
<label>Maximum Order Total</label>
<frontend_type>text</frontend_type>
<sort_order>90</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>0</show_in_store>
</max_order_total>
<sort_order translate="label">
<label>Sort Order</label>
<frontend_type>text</frontend_type>
<sort_order>99</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>0</show_in_store>
<frontend_class>validate-number</frontend_class>
</sort_order>
<invoice>
<label>Invoice Settings</label>
<frontend_model>adminhtml/system_config_form_field_heading</frontend_model>
<sort_order>100</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
</invoice>
<!--
<invoice_new translate="label">
<label>New</label>
<frontend_type>select</frontend_type>
<source_model>adminhtml/system_config_source_order_status</source_model>
<sort_order>110</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
</invoice_new>
-->
<invoice_paid translate="label">
<label>Paid</label>
<comment>
An invoice is considered "paid" when the bitcoin
network sees a transaction.
</comment>
<frontend_type>select</frontend_type>
<source_model>adminhtml/system_config_source_order_status</source_model>
<sort_order>120</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
</invoice_paid>
<invoice_confirmed translate="label">
<label>Confirmed</label>
<comment>
A confirmed invoice means that the Bitcoin network
has approved the transaction.
</comment>
<frontend_type>select</frontend_type>
<source_model>adminhtml/system_config_source_order_status</source_model>
<sort_order>130</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
</invoice_confirmed>
<invoice_complete translate="label">
<label>Complete</label>
<comment>
Complete invoices mean that you have gotten credit
for the payment in your BitPay merchant account.
</comment>
<frontend_type>select</frontend_type>
<source_model>adminhtml/system_config_source_order_status</source_model>
<sort_order>140</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
</invoice_complete>
<!--
<invoice_expired translate="label">
<label>Expired</label>
<frontend_type>select</frontend_type>
<source_model>adminhtml/system_config_source_order_status</source_model>
<sort_order>150</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
</invoice_expired>
<invoice_invalid translate="label">
<label>Invalid</label>
<frontend_type>select</frontend_type>
<source_model>adminhtml/system_config_source_order_status</source_model>
<sort_order>160</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
</invoice_invalid>
-->
<requirements>
<label>Requirements</label>
<frontend_model>adminhtml/system_config_form_field_heading</frontend_model>
<comment>
<![CDATA[If you do not meet the requirements, this extension will fail to work.]]>
</comment>
<sort_order>500</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
</requirements>
<has_gmp>
<label>GMP</label>
<php_extension>gmp</php_extension>
<frontend_model>bitpay/adminhtml_system_config_form_field_extension</frontend_model>
<sort_order>510</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
</has_gmp>
<has_openssl>
<label>OpenSSL</label>
<php_extension>openssl</php_extension>
<frontend_model>bitpay/adminhtml_system_config_form_field_extension</frontend_model>
<sort_order>510</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
</has_openssl>
</fields>
</bitpay>
</groups>
</payment>
</sections>
</config>

View File

@ -0,0 +1,64 @@
<?php
/**
* @license Copyright 2011-2014 BitPay Inc., MIT License
* @see https://github.com/bitpay/magento-plugin/blob/master/LICENSE
*/
$this->startSetup();
/**
* IPN Log Table, used to keep track of incoiming IPNs
*/
$this->run(sprintf('DROP TABLE IF EXISTS `%s`;', $this->getTable('bitpay/ipn')));
$ipnTable = new Varien_Db_Ddl_Table();
$ipnTable->setName($this->getTable('bitpay/ipn'));
$ipnTable->addColumn('id', Varien_Db_Ddl_Table::TYPE_INTEGER, 11, array('auto_increment' => true, 'nullable' => false, 'primary' => true,));
$ipnTable->addColumn('invoice_id', Varien_Db_Ddl_Table::TYPE_TEXT, 200);
$ipnTable->addColumn('url', Varien_Db_Ddl_Table::TYPE_TEXT, 400);
$ipnTable->addColumn('status', Varien_Db_Ddl_Table::TYPE_TEXT, 20);
$ipnTable->addColumn('btc_price', Varien_Db_Ddl_Table::TYPE_DECIMAL, array(16, 8));
$ipnTable->addColumn('price', Varien_Db_Ddl_Table::TYPE_DECIMAL, array(16, 8));
$ipnTable->addColumn('currency', Varien_Db_Ddl_Table::TYPE_TEXT, 10);
$ipnTable->addColumn('invoice_time', Varien_Db_Ddl_Table::TYPE_INTEGER, 11);
$ipnTable->addColumn('expiration_time', Varien_Db_Ddl_Table::TYPE_INTEGER, 11);
$ipnTable->addColumn('curent_time', Varien_Db_Ddl_Table::TYPE_INTEGER, 11);
$ipnTable->addColumn('pos_data', Varien_Db_Ddl_Table::TYPE_TEXT, 255);
$ipnTable->addColumn('btc_paid', Varien_Db_Ddl_Table::TYPE_DECIMAL, array(16, 8));
$ipnTable->addColumn('rate', Varien_Db_Ddl_Table::TYPE_DECIMAL, array(16, 8));
$ipnTable->addColumn('exception_status', Varien_Db_Ddl_Table::TYPE_TEXT, 255);
$ipnTable->setOption('type', 'InnoDB');
$ipnTable->setOption('charset', 'utf8');
$this->getConnection()->createTable($ipnTable);
/**
* Table used to keep track of invoices that have been created. The
* IPNs that are received are used to update this table.
*/
$this->run(sprintf('DROP TABLE IF EXISTS `%s`;', $this->getTable('bitpay/invoice')));
$invoiceTable = new Varien_Db_Ddl_Table();
$invoiceTable->setName($this->getTable('bitpay/invoice'));
$invoiceTable->addColumn('id', Varien_Db_Ddl_Table::TYPE_TEXT, 64, array('nullable' => false, 'primary' => true));
$invoiceTable->addColumn('quote_id', Varien_Db_Ddl_Table::TYPE_INTEGER, 11);
$invoiceTable->addColumn('increment_id', Varien_Db_Ddl_Table::TYPE_INTEGER, 11);
$invoiceTable->addColumn('updated_at', Varien_Db_Ddl_Table::TYPE_TIMESTAMP);
$invoiceTable->addColumn('url', Varien_Db_Ddl_Table::TYPE_TEXT, 200);
$invoiceTable->addColumn('pos_data', Varien_Db_Ddl_Table::TYPE_TEXT, 255);
$invoiceTable->addColumn('status', Varien_Db_Ddl_Table::TYPE_TEXT, 20);
$invoiceTable->addColumn('btc_price', Varien_Db_Ddl_Table::TYPE_DECIMAL, array(16, 8));
$invoiceTable->addColumn('btc_due', Varien_Db_Ddl_Table::TYPE_DECIMAL, array(16, 8));
$invoiceTable->addColumn('price', Varien_Db_Ddl_Table::TYPE_DECIMAL, array(16, 8));
$invoiceTable->addColumn('currency', Varien_Db_Ddl_Table::TYPE_TEXT, 10);
$invoiceTable->addColumn('ex_rates', Varien_Db_Ddl_Table::TYPE_TEXT, 255);
$invoiceTable->addColumn('order_id', Varien_Db_Ddl_Table::TYPE_TEXT, 64);
$invoiceTable->addColumn('invoice_time', Varien_Db_Ddl_Table::TYPE_INTEGER, 11);
$invoiceTable->addColumn('expiration_time', Varien_Db_Ddl_Table::TYPE_INTEGER, 11);
$invoiceTable->addColumn('current_time', Varien_Db_Ddl_Table::TYPE_INTEGER, 11);
$invoiceTable->addColumn('btc_paid', Varien_Db_Ddl_Table::TYPE_DECIMAL, array(16, 8));
$invoiceTable->addColumn('rate', Varien_Db_Ddl_Table::TYPE_DECIMAL, array(16, 8));
$invoiceTable->addColumn('exception_status', Varien_Db_Ddl_Table::TYPE_TEXT, 255);
$invoiceTable->addColumn('token', Varien_Db_Ddl_Table::TYPE_TEXT, 164);
$invoiceTable->setOption('type', 'InnoDB');
$invoiceTable->setOption('charset', 'utf8');
$this->getConnection()->createTable($invoiceTable);
$this->endSetup();

View File

@ -0,0 +1,9 @@
<?xml version="1.0"?>
<!--
/**
* @license Copyright 2011-2014 BitPay Inc., MIT License
* @see https://github.com/bitpay/magento-plugin/blob/master/LICENSE
*/
-->
<layout>
</layout>

View File

@ -0,0 +1,18 @@
<?php
/**
* @license Copyright 2011-2014 BitPay Inc., MIT License
* @see https://github.com/bitpay/magento-plugin/blob/master/LICENSE
*/
?>
<?php
/**
* @see Bitpay_Core_Block_Info
*/
?>
<h3>Ordered with BitPay</h3>
<?php if ($url = $this->getBitpayInvoiceUrl()): ?>
<p>
<a href="<?php echo $url; ?>" target="_new">View Invoice</a>
</p>
<?php endif; ?>

View File

@ -0,0 +1,17 @@
<?php
/**
* @license Copyright 2011-2014 BitPay Inc., MIT License
* @see https://github.com/bitpay/magento-plugin/blob/master/LICENSE
*/
?>
<?php
/**
* @see Bitpay_Core_Block_Adminhtml_System_Config_Form_Field_Header
*/
?>
<div style="background-color:#002855;padding:5px;color:#ffffff">
<img src="https://raw.githubusercontent.com/bitpay/bitpay-brand/master/bitpay-logo-primary.png" alt="BitPay" witdth="113" height="44" />
<a style="color:#ffffff;font-family:'Ubuntu',sans-serif;text-decoration:none;margin:15px" href="https://support.bitpay.com/?ref=magento" target="_new">Support</a>
<a style="color:#ffffff;font-family:'Ubuntu',sans-serif;text-decoration:none;margin:15px" href="https://bitpay.com/start?ref=magento" target="_new">Sign Up</a>
<a style="color:#ffffff;font-family:'Ubuntu',sans-serif;text-decoration:none;margin:15px" href="https://bitpay.com/merchant-login?ref=magento" target="_new">Login</a>
</div>

View File

@ -1,33 +0,0 @@
<?xml version="1.0"?>
<!--
/**
* The MIT License (MIT)
*
* Copyright (c) 2011-2014 BitPay LLC
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
-->
<layout>
<checkout_onepage_review>
<reference name="checkout.onepage.review.info.items.after">
<block name="iframe" type="bitcoins/iframe"/>
</reference>
</checkout_onepage_review>
</layout>

View File

@ -0,0 +1,9 @@
<?xml version="1.0"?>
<!--
/**
* @license Copyright 2011-2014 BitPay Inc., MIT License
* @see https://github.com/bitpay/magento-plugin/blob/master/LICENSE
*/
-->
<layout>
</layout>

View File

@ -1,67 +0,0 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2011-2014 BitPay LLC
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
$url = $this->GetIframeUrl();
switch($url)
{
case 'notbitpay':
break; // customer is using another payment method
case 'paid':
echo 'Order payment received. Place Order to complete.';
break;
case 'disabled':
echo 'Please click Place Order to continue to bitpay.com.';
break;
case false:
echo 'Error creating invoice. Please try again or try another payment solution.';
break;
default:
echo '<iframe src="'.$url.'" style="width:500px; height:150px; overflow:hidden; border:none; margin:auto; display:block;" scrolling="no" allowtransparency="true" frameborder="0"> </iframe>';
break;
}
$quoteId = $this->GetQuoteId();
?>
<?php
$request = Mage::app()->getRequest();
$url = Mage::getUrl('bitpay_callback/index/checkForPayment/');
if ($request->getScheme() == 'https')
{
$url = str_replace('http://', 'https://', $url);
}
?>
<script type="text/javascript">
//<![CDATA[
new PeriodicalExecuter(function() {new Ajax.Request("<?php echo $url; ?>?quote=<?php echo $quoteId; ?>", {asynchronous:true, evalScripts:true, onComplete:function(request, json) {
data = request.responseText.evalJSON();
if (data.paid) {
buttons = $$("button.btn-checkout");
buttons.each(function(btn) { btn.click(); })
}
}})}, 5);
//]]>
</script>

View File

@ -0,0 +1,19 @@
<?php
/**
* @license Copyright 2011-2014 BitPay Inc., MIT License
* @see https://github.com/bitpay/magento-plugin/blob/master/LICENSE
*/
?>
<?php
/**
* @see Bitpay_Core_Block_Form_Bitpay
*/
?>
<?php $_code = $this->getMethodCode() ?>
<ul class="form-list" id="payment_form_<?php echo $_code ?>" style="display:none;">
<li>
When paying with this payment method, once you click on the `Place Order` button
you will be transfered to <a href="https://bitpay.com" target="_new">BitPay</a>
to complete your purchase.
</li>
</ul>

View File

@ -0,0 +1,50 @@
<?php
/**
* @license Copyright 2011-2014 BitPay Inc., MIT License
* @see https://github.com/bitpay/magento-plugin/blob/master/LICENSE
*/
$url = $this->getIframeUrl();
switch($url) {
case 'notbitpay':
break; // customer is using another payment method
case 'paid':
echo 'Order payment received. Place Order to complete.';
break;
case 'disabled':
echo 'Please click Place Order to continue to bitpay.com.';
break;
case false:
echo 'Error creating invoice. Please try again or try another payment solution.';
break;
default:
echo '<iframe src="'.$url.'" style="width:500px; height:150px; overflow:hidden; border:none; margin:auto; display:block;" scrolling="no" allowtransparency="true" frameborder="0"> </iframe>';
break;
}
$quoteId = $this->getQuote()->getId();
$request = Mage::app()->getRequest();
$url = Mage::getUrl('bitpay/index/index/');
if ($request->getScheme() == 'https') {
$url = str_replace('http://', 'https://', $url);
}
?>
<script type="text/javascript">
//<![CDATA[
new PeriodicalExecuter(function() {
new Ajax.Request(
"<?php echo $url; ?>?quote=<?php echo $quoteId; ?>",
{
asynchronous: true,
evalScripts: true,
onComplete: function(request, json) {
data = request.responseText.evalJSON();
if (data.paid) {
buttons = $$("button.btn-checkout");
buttons.each(function(btn) { btn.click(); })
}
}
}
)
}, 5);
//]]>
</script>

View File

@ -0,0 +1,9 @@
<?php
/**
* @license Copyright 2011-2014 BitPay Inc., MIT License
* @see https://github.com/bitpay/magento-plugin/blob/master/LICENSE
*/
?>
<p><strong><?php echo $this->escapeHtml($this->getMethod()->getTitle()) ?></strong></p>
<?php echo $this->getChildHtml()?>

View File

@ -0,0 +1,9 @@
<?php
/**
* @license Copyright 2011-2014 BitPay Inc., MIT License
* @see https://github.com/bitpay/magento-plugin/blob/master/LICENSE
*/
?>
{
"paid": <?php echo $this->isPaid(); ?>
}

View File

@ -1,36 +0,0 @@
<!--
/**
* The MIT License (MIT)
*
* Copyright (c) 2011-2014 BitPay LLC
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
-->
<config>
<modules>
<Bitpay_Bitcoins>
<active>true</active>
<codePool>community</codePool>
<depends>
<Mage_Payment />
</depends>
</Bitpay_Bitcoins>
</modules>
</config>

View File

@ -0,0 +1,18 @@
<?xml version="1.0"?>
<!--
/**
* @license Copyright 2011-2014 BitPay Inc., MIT License
* @see https://github.com/bitpay/magento-plugin/blob/master/LICENSE
*/
-->
<config>
<modules>
<Bitpay_Core>
<active>true</active>
<codePool>community</codePool>
<depends>
<Mage_Payment />
</depends>
</Bitpay_Core>
</modules>
</config>

View File

@ -0,0 +1,15 @@
"Enabled","Enabled"
"Title","Title"
"Network","Network"
"Debug","Debug"
"New","New"
"Paid","Paid"
"Confirmed","Confirmed"
"Complete","Complete"
"Expired","Expired"
"Invalid","Invalid"
"Low","Low"
"Medium","Medium"
"High","High"
"Livenet","Livenet"
"Testnet","Testnet"
1 Enabled Enabled
2 Title Title
3 Network Network
4 Debug Debug
5 New New
6 Paid Paid
7 Confirmed Confirmed
8 Complete Complete
9 Expired Expired
10 Invalid Invalid
11 Low Low
12 Medium Medium
13 High High
14 Livenet Livenet
15 Testnet Testnet

View File

@ -1,27 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
/**
* The MIT License (MIT)
*
* Copyright (c) 2011-2014 BitPay
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
* @license Copyright 2011-2014 BitPay Inc., MIT License
* @see https://github.com/bitpay/magento-plugin/blob/master/LICENSE
*/
-->
<project name="bitpay/magento-plugin" default="build">

View File

@ -1,6 +1,6 @@
# 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

View File

@ -1,6 +1,6 @@
# 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

View File

@ -45,10 +45,10 @@
<filter>
<whitelist>
<directory>../app/code/community/Bitpay/Bitcoins/</directory>
<directory>../app/code/community/Bitpay/Core/</directory>
<directory>../shell</directory>
<exclude>
<directory>../app/code/community/Bitpay/Bitcoins/sql</directory>
<directory>../app/code/community/Bitpay/Core/sql</directory>
</exclude>
</whitelist>
</filter>

View File

@ -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

View File

@ -1,6 +1,6 @@
# 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

View File

@ -2,7 +2,7 @@
"name": "bitpay/magento-plugin",
"description": "Bitcoin payment module using the bitpay.com service",
"keywords": ["magento","bitcoin"],
"minimum-stability": "dev",
"minimum-stability": "stable",
"type": "magento-plugin",
"homepage": "https://github.com/bitpay/magento-plugin",
"license": "MIT",
@ -12,25 +12,27 @@
"source": "https://github.com/bitpay/magento-plugin"
},
"require": {
"composer/installers": "~1.0"
"composer/installers": "~1.0",
"bitpay/php-client": "~2.0@dev"
},
"require-dev": {
"n98/magerun": "*",
"phpmd/phpmd": "*",
"phpdocumentor/phpdocumentor": "*",
"phing/phing": "*",
"pdepend/pdepend" : "1.1.0",
"squizlabs/php_codesniffer": "*",
"phpunit/phpunit": "*",
"phploc/phploc": "*",
"fzaninotto/faker": "*"
"symfony/finder": "~2.3",
"symfony/process": "~2.3",
"phpmd/phpmd": "~2.1",
"phpdocumentor/phpdocumentor": "~2.7",
"daedalus/daedalus": "~1.0@dev",
"pdepend/pdepend" : "~2.0",
"squizlabs/php_codesniffer": "~1.5",
"phpunit/phpunit": "~3.7",
"phploc/phploc": "~2.0",
"fzaninotto/faker": "~1.3"
},
"config": {
"bin-dir": "bin"
},
"extra": {
"branch-alias": {
"dev-master": "6.0.x-dev"
"dev-master": "2.0.x-dev"
}
},
"archive": {

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

BIN
docs/MagentoSettings.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

View File

@ -0,0 +1,59 @@
<?php
/**
* @license Copyright 2011-2014 BitPay Inc., MIT License
* @see https://github.com/bitpay/magento-plugin/blob/master/LICENSE
*/
namespace Bitpay\Storage;
/**
* This is part of the magento plugin. This is responsible for saving and loading
* keys for magento.
*/
class MagentoStorage implements StorageInterface
{
/**
* @var array
*/
protected $_keys;
/**
* @inheritdoc
*/
public function persist(\Bitpay\KeyInterface $key)
{
$this->_keys[$key->getId()] = $key;
$data = serialize($key);
$encryptedData = \Mage::helper('core')->encrypt($data);
$config = new \Mage_Core_Model_Config();
$config->saveConfig($key->getId(), $encryptedData);
}
/**
* @inheritdoc
*/
public function load($id)
{
if (isset($this->_keys[$id])) {
return $this->_keys[$id];
}
$entity = \Mage::getStoreConfig($id);
/**
* Not in database
*/
if (empty($entity)) {
return false;
}
$decodedEntity = unserialize(\Mage::helper('core')->decrypt($entity));
if (empty($decodedEntity)) {
return false;
}
return $decodedEntity;
}
}

View File

@ -1,5 +0,0 @@
<Files ~ "^.*\.(LOG|log|back|bak|bk|lock|lck|LCK|txt|text|backup|pem|PEM|TXT)">
Order allow,deny
Deny from all
Satisfy All
</Files>

View File

@ -1,49 +0,0 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2011-2014 BitPay LLC
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
global $bpconfig;
$bpconfig['host'] = "bitpay.com";
$bpconfig['port'] = 443;
$bpconfig['hostAndPort'] = $bpconfig['host'];
if ($bpconfig['port'] != 443)
{
$bpconfig['hostAndPort'] .= ":".$bpconfig['host'];
}
$bpconfig['ssl_verifypeer'] = 1;
$bpconfig['ssl_verifyhost'] = 2;
//include custom config overrides if it exists
try
{
include 'bp_config.php';
}
catch (Exception $e)
{
// do nothing
}

View File

@ -1,232 +0,0 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2011-2014 BitPay LLC
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
require_once 'bp_config_default.php';
require_once 'bp_options.php';
/**
* @param string $url
* @param string $apiKey
* @param string $post
*
* @return array
*/
function bpCurl($url, $apiKey, $post = null)
{
global $bpOptions, $bpconfig;
$curl = curl_init($url);
$length = 0;
if (null !== $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,
'X-BitPay-Plugin-Info: magento5',
);
curl_setopt($curl, CURLOPT_PORT, $bpconfig['port']);
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
curl_setopt($curl, CURLOPT_TIMEOUT, 10);
curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC ) ;
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
* identify a ledger entry if present.
*
* $price: by default, $price is expressed in the currency you set in bp_options.php. The currency can be
* changed in $options.
*
* $posData: this field is included in status updates or requests to get an invoice. It is intended to be used by
* the merchant to uniquely identify an order associated with an invoice in their system. Aside from that, Bit-Pay does
* not use the data in this field. The data in this field can be anything that is meaningful to the merchant.
*
* $options keys can include any of:
* ('itemDesc', 'itemCode', 'notificationEmail', 'notificationURL', 'redirectURL', 'apiKey'
* 'currency', 'physical', 'fullNotifications', 'transactionSpeed', 'buyerName',
* 'buyerAddress1', 'buyerAddress2', 'buyerCity', 'buyerState', 'buyerZip', 'buyerEmail', 'buyerPhone')
* 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).
*
* @param string $orderId
* @param string $price
* @param string $posData
* @param array $options
*
* @return array
*/
function bpCreateInvoice($orderId, $price, $posData, $options = array())
{
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;
$post = array();
$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
*
* @param boolean|string $apiKey
*
* @return string|array
*/
function bpVerifyNotification($apiKey = false)
{
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))
{
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'];
if (!array_key_exists('id', $json))
{
return 'Cannot find invoice ID';
}
return bpGetInvoice($json['id'], $apiKey);
}
/**
* $options can include ('apiKey')
*
* @param string $invoiceId
* @param boolean|string $apiKey
*
* @return string|array
*/
function bpGetInvoice($invoiceId, $apiKey=false)
{
global $bpOptions, $bpconfig;
if (!$apiKey)
{
$apiKey = $bpOptions['apiKey'];
}
$response = bpCurl('https://'.$bpconfig['hostAndPort'].'/api/invoice/'.$invoiceId, $apiKey);
if (is_string($response))
{
return $response; // error
}
$response['posData'] = json_decode($response['posData'], true);
if($bpOptions['verifyPos'])
{
$response['posData'] = $response['posData']['posData'];
}
return $response;
}

View File

@ -1,42 +0,0 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2011-2014 BitPay LLC
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
global $bpOptions;
// do not edit this file
// all values are set via config settings or upon use
$bpOptions['SSLcert'] = '';
$bpOptions['SSLkey'] = '';
$bpOptions['secret'] = '';
$bpOptions['verifyPos'] = true;
$bpOptions['notificationEmail'] = '';
$bpOptions['notificationURL'] = '';
$bpOptions['redirectURL'] = '';
$bpOptions['currency'] = '';
$bpOptions['physical'] = 'true';
$bpOptions['fullNotifications'] = 'true';
$bpOptions['transactionSpeed'] = 'low';

14
modman
View File

@ -1,6 +1,6 @@
# 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
@ -20,9 +20,9 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
app/code/community/Bitpay/Bitcoins app/code/community/Bitpay/Bitcoins
app/design/frontend/base/default/layout/bitcoins.xml app/design/frontend/base/default/layout/bitcoins.xml
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
app/code/community/Bitpay/Core app/code/community/Bitpay/Core
app/design/frontend/base/default/layout/bitpay.xml app/design/frontend/base/default/layout/bitpay.xml
app/design/frontend/base/default/template/bitpay app/design/frontend/base/default/template/bitpay
app/etc/modules/Bitpay_Core.xml app/etc/modules/Bitpay_Core.xml
lib/Bitpay lib/Bitpay
lib/Symfony lib/Symfony

10
scripts/delete Executable file
View File

@ -0,0 +1,10 @@
#!/usr/bin/env sh
####
#
# Script that removes old BitPay extension
#
rm -vrf app/code/community/Bitpay/Bitcoins
rm -v app/design/frontend/base/default/layout/bitcoins.xml
rm -vrf app/etc/modules/Bitpay_Bitcoins.xml
rm -vrf lib/bitpay
rm -v shell/bitpay.php

144
scripts/package Executable file
View File

@ -0,0 +1,144 @@
#!/usr/bin/env php
<?php
/**
* @license Copyright 2011-2014 BitPay Inc., MIT License
* @see https://github.com/bitpay/magento-plugin/blob/master/LICENSE
*/
error_reporting(E_ALL | E_STRICT);
ini_set('display_errors', 1);
date_default_timezone_set('America/New_York'); // Main Office is in Eastern Timezone
/**
* Various Configuration Settings
*/
$version = '2.0.0';
$vendorDir = __DIR__ . '/../vendor';
$distDir = __DIR__ . '/../build/dist';
$tmpDistDir = $distDir . '/tmp'; // Files will be placed here temporarly so we can zip/tar them.
$distFile = $distDir . '/Bitpay_Core-'.$version; // Without extension
require_once $vendorDir . '/autoload.php';
$filesystem = new \Symfony\Component\Filesystem\Filesystem();
/**
* Copy all required files to temp. distribution directory
*/
$finder = new \Symfony\Component\Finder\Finder();
$finder
->files()
->in($vendorDir . '/bitpay/php-client/src')
->in($vendorDir . '/symfony/config/')
->in($vendorDir . '/symfony/filesystem/')
->in($vendorDir . '/symfony/dependency-injection/')
->exclude('Tests');
foreach ($finder as $file) {
$path = $file->getRelativePathname();
$filesystem->mkdir(
sprintf(
'%s/lib/%s',
$tmpDistDir,
dirname($file->getRelativePathname())
)
);
$filesystem->copy(
$file->getRealPath(),
sprintf(
'%s/lib/%s',
$tmpDistDir,
$file->getRelativePathname()
),
true
);
}
$filesystem->mirror('app/', sprintf('%s/app/', $tmpDistDir));
$filesystem->mirror('lib/', sprintf('%s/lib/', $tmpDistDir));
$filesystem->copy('LICENSE', sprintf('%s/app/code/community/Bitpay/Core/LICENSE', $tmpDistDir));
$filesystem->copy('README.md', sprintf('%s/app/code/community/Bitpay/Core/README.md', $tmpDistDir));
// All required files are in the temp. distribution directory
/**
* Need to create the package.xml file required by Magento
*/
$xml = simplexml_load_string('<package/>');
$xml->addChild('name', 'Bitpay_Core');
$xml->addChild('version', $version);
$xml->addChild('stability', 'stable');
$xml->addChild('license', 'MIT')
->addAttribute('uri', 'https://github.com/bitpay/magento-plugin/blob/master/LICENSE');
$xml->addChild('channel', 'community');
$xml->addChild('extends');
$xml->addChild('summary');
$xml->addChild('description');
$xml->addChild('notes');
$authorsNode = $xml->addChild('authors');
$authors = array(
array(
'Joshua Estes', // Name
'BitPayJoshua', // Magento Connect Username
'support@bitpay.com', // Email
),
);
foreach ($authors as $author) {
$authorNode = $authorsNode->addChild('author');
$authorNode->addChild('name', $author[0]);
$authorNode->addChild('user', $author[1]);
$authorNode->addChild('email', $author[2]);
}
$xml->addChild('date', date('Y-m-d'));
$xml->addChild('time', date('G:i:s'));
$xml->addChild('compatible');
$xml->addChild('dependencies');
$requiredNode = $xml->addChild('required', 'php');
$requiredNode->addAttribute('php_min', '5.4.0');
$requiredNode->addAttribute('php_max', '6.0.0');
$extensionsNode = $xml->addChild('extensions');
foreach (array('gmp', 'openssl', 'mcrypt') as $ext) {
$extNode = $extensionsNode->addChild('name', $ext);
$extNode->addChild('min');
$extNode->addChild('max');
}
$targetNode = $xml->addChild('contents')->addChild('target');
$targetNode->addAttribute('name', 'mage');
$finder = new \Symfony\Component\Finder\Finder();
$finder
->files()
->in($tmpDistDir);
foreach ($finder as $file) {
$node = $targetNode;
$directories = explode('/', $file->getRelativePathname());
$filename = array_pop($directories);
for ($i = 1; $i <= count($directories); $i++) {
$dir = $directories[$i - 1];
$nodes = $node->xpath('dir[@name="' . $dir . '"]');
if (count($nodes)) {
$node = array_pop($nodes);
} else {
$node = $node->addChild('dir');
$node->addAttribute('name', $dir);
}
}
$fileNode = $node->addChild('file');
$fileNode->addAttribute('name', $file->getBaseName());
$fileNode->addAttribute('hash', md5_file($file->getRealPath()));
}
$xml->asXml($tmpDistDir . '/package.xml');
// package.xml created, just need to tar/zip everything
$filesystem->remove($distFile.'.zip');
$filesystem->remove($distFile.'.tgz');
$process = new \Symfony\Component\Process\Process(
sprintf('cd %s; zip -r %s .', $tmpDistDir, $distFile.'.zip')
);
$process->run();
$process = new \Symfony\Component\Process\Process(
sprintf('cd %s; tar -czf %s *', $tmpDistDir, $distFile.'.tgz')
);
$process->run();
// Cleanup
$filesystem->remove($tmpDistDir);

View File

@ -1,92 +0,0 @@
<?php
/**
* The MIT License (MIT)
*
* 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
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
require_once 'abstract.php';
/**
* This class is used to work with the bitpay api via the command line and to
* debug issues
*/
class Bitpay_Shell_Bitpay extends Mage_Shell_Abstract
{
public function run()
{
if ($clean = $this->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 <<<USAGE
{$figlet->render('BitPay')}
Usage: php -f bitpay.php
--clean <status> Delete all IPN records based on <status>
List of Statuses:
expired
USAGE;
}
}
$shell = new Bitpay_Shell_Bitpay();
$shell->run();

View File

@ -1,102 +0,0 @@
<?php
/**
* The MIT License (MIT)
*
* 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
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
class Bitpay_Bitcoins_Model_PaymentMethodTest extends PHPUnit_Framework_TestCase
{
public function testCanUseForCurrency()
{
$paymentMethod = Mage::getModel('Bitcoins/paymentMethod');
$this->assertTrue($paymentMethod->canUseForCurrency('USD'));
$this->assertFalse($paymentMethod->canUseForCurrency('ASDF'));
}
public function testCanUseCheckout()
{
$this->markTestIncomplete();
}
public function testIsApiKeyConfigured()
{
$this->markTestIncomplete();
}
public function testIsTransactionSpeedConfigured()
{
$this->markTestIncomplete();
}
public function testAuthorize()
{
$this->markTestIncomplete();
}
public function testCheckForPayment()
{
$this->markTestIncomplete();
}
public function testInvoiceOrder()
{
$this->markTestIncomplete();
}
public function testMarkOrderPaid()
{
$this->markTestIncomplete();
}
public function testMarkOrderComplete()
{
$this->markTestIncomplete();
}
public function testMarkOrderCancelled()
{
$this->markTestIncomplete();
}
public function testExtractAddress()
{
$this->markTestIncomplete();
}
public function testCreateInvoiceAndRedirect()
{
$this->markTestIncomplete();
}
public function testGetOrderPlaceRedirectUrl()
{
$this->markTestIncomplete();
}
public function testGetQuoteHash()
{
$this->markTestIncomplete();
}
}

View File

@ -1,32 +1,11 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2011-2014 BitPay
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
* @license Copyright 2011-2014 BitPay Inc., MIT License
* @see https://github.com/bitpay/magento-plugin/blob/master/LICENSE
*/
class Bitpay_Bitcoins_Helper_DataTest extends PHPUnit_Framework_TestCase
class Bitpay_Core_Helper_DataTest extends PHPUnit_Framework_TestCase
{
protected static $faker;
public static function setUpBeforeClass()
@ -34,62 +13,82 @@ class Bitpay_Bitcoins_Helper_DataTest extends PHPUnit_Framework_TestCase
self::$faker = Faker\Factory::create();
}
public function testHasApiKeyFalse()
public function testGetLogFile()
{
Mage::app()->getStore()->setConfig('payment/Bitcoins/api_key', null);
$this->assertFalse(Mage::helper('bitpay')->hasApiKey());
$this->assertSame(
'payment_bitpay.log',
Mage::helper('bitpay')->getLogFile()
);
}
public function testHasApiKeyTrue()
public function testDebugData()
{
Mage::app()->getStore()->setConfig('payment/Bitcoins/api_key', 'ThisIsMyApiKey');
Mage::helper('bitpay')->debugData('Testing');
}
$this->assertTrue(Mage::helper('bitpay')->hasApiKey());
public function testIsDebugMode()
{
Mage::app()->getStore()->setConfig('payment/bitpay/debug', null);
$this->assertFalse(Mage::helper('bitpay')->isDebug());
Mage::app()->getStore()->setConfig('payment/bitpay/debug', false);
$this->assertFalse(Mage::helper('bitpay')->isDebug());
Mage::app()->getStore()->setConfig('payment/bitpay/debug', true);
$this->assertTrue(Mage::helper('bitpay')->isDebug());
}
public function testHasTransactionSpeedFalse()
{
Mage::app()->getStore()->setConfig('payment/Bitcoins/speed', null);
Mage::app()->getStore()->setConfig('payment/bitpay/speed', null);
$this->assertFalse(Mage::helper('bitpay')->hasTransactionSpeed());
}
public function testHasTransactionSpeedTrue()
{
Mage::app()->getStore()->setConfig('payment/Bitcoins/speed', 'low');
Mage::app()->getStore()->setConfig('payment/bitpay/speed', 'low');
$this->assertTrue(Mage::helper('bitpay')->hasTransactionSpeed());
}
public function testCleanExpired()
/**
* Location where BitPay IPNs will go
*/
public function testGetNotificationUrl()
{
// Create a few expired/invalid ipns
$invalidIpn = $this->createInvalidIpn();
$expiredIpn = $this->createExpiredIpn();
$this->assertSame(
'http://www.localhost.com/bitpay/ipn/',
Mage::helper('bitpay')->getNotificationUrl()
);
}
// 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);
public function testGetRedirectUrl()
{
$this->assertSame(
'http://www.localhost.com/checkout/onepage/success/',
Mage::helper('bitpay')->getRedirectUrl()
);
}
// clean them
Mage::helper('bitpay')->cleanExpired();
public function testRegisterAutoloader()
{
Mage::helper('bitpay')->registerAutoloader();
}
// 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);
public function testGenerateAndSaveKeys()
{
Mage::helper('bitpay')->generateAndSaveKeys();
}
public function testGetSinKey()
{
Mage::helper('bitpay')->getSinKey();
}
private function createInvalidIpn()
{
$ipn = new Bitpay_Bitcoins_Model_Ipn();
$ipn = new Bitpay_Core_Model_Ipn();
$ipn->setData(
array(
'quote_id' => '',
@ -115,7 +114,7 @@ class Bitpay_Bitcoins_Helper_DataTest extends PHPUnit_Framework_TestCase
private function createExpiredIpn()
{
$order = $this->createOrder();
$ipn = new Bitpay_Bitcoins_Model_Ipn();
$ipn = new Bitpay_Core_Model_Ipn();
$ipn->setData(
array(
'quote_id' => '',
@ -166,7 +165,7 @@ class Bitpay_Bitcoins_Helper_DataTest extends PHPUnit_Framework_TestCase
'save_in_address_book' => 0,
'use_for_shipping' => 1,
'street' => array(
self::$faker->streetAddress
self::$faker->streetAddress,
),
);

View File

@ -1,30 +1,10 @@
<?php
/**
* The MIT License (MIT)
*
* 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
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
* @license Copyright 2011-2014 BitPay Inc., MIT License
* @see https://github.com/bitpay/magento-plugin/blob/master/LICENSE
*/
if ($mage = realpath(__DIR__ . '/../build/magento/app/Mage.php')) {
if ($mage = realpath(__DIR__.'/../build/magento/app/Mage.php')) {
require_once $mage;
//Mage::setIsDeveloperMode(true);
Mage::app();
@ -32,7 +12,7 @@ if ($mage = realpath(__DIR__ . '/../build/magento/app/Mage.php')) {
exit('Could not find Mage.php');
}
if ($composer = realpath(__DIR__ . '/../vendor/autoload.php')) {
if ($composer = realpath(__DIR__.'/../vendor/autoload.php')) {
require_once $composer;
} else {
exit('Composer not found');