Iframe invoice will create order

- For merchants using an iframe BitPay invoice (set "Redirect Checkout"
  to "No")
  - Before this change:
    - When a user confirms the payment method, the BitPay invoice will
      be displayed and the Magento order will not yet be created.
    - The Magento order is only created if the user pays the invoice,
      leaves the checkout browser window open, and BitPay is able to see
the user's transaction and send the IPN successfully to the Magento
server.
    - The problem is when the customer sends a bitcoin transaction, but
      their transaction isn't relayed because the fee is too low or the
network is under high load.
    - Under this condition, the customer has paid, yet they have no
      order with the merchant. The merchant has a hard time serving
their customer under these conditions.
  After this change:
    - When the user confirms their payment method, the BitPay invoice
      will NOT be displayed until the user clicks "Place Order".
    - This will guarantee that an order is created BEFORE the customer
      is able to pay the BitPay invoice.
    - This will allow the merchant to self-serve their customer by being
      able to find their customer in their dashboard and issue a refund
or apply the transaction.
This commit is contained in:
Chris Kleeschulte 2016-07-09 17:08:17 -04:00
parent 98403f4353
commit d0a5152770
2 changed files with 61 additions and 28 deletions

View File

@ -46,19 +46,11 @@ class Bitpay_Core_Model_Method_Bitcoin extends Mage_Payment_Model_Method_Abstrac
$amount = $payment->getOrder()->getQuote()->getGrandTotal();
}
// Check if coming from iframe or submit button
// This means that this authorize method was called from a Magento checkout controller
// and not the iframe.phtml template while this plugin is in non-redirected checkout mode,
// therefore we shouldn't create a new invoice, we should just return the model
if ((!Mage::getStoreConfig('payment/bitpay/fullscreen') && $iframe === false)
|| (Mage::getStoreConfig('payment/bitpay/fullscreen') && $iframe === true)) {
$quoteId = $payment->getOrder()->getQuoteId();
$ipn = Mage::getModel('bitpay/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());
}
return $this;
}

View File

@ -1,6 +1,6 @@
<?php
/**
* @license Copyright 2011-2014 BitPay Inc., MIT License
* @license Copyright 2011-2016 BitPay Inc., MIT License
* @see https://github.com/bitpay/magento-plugin/blob/master/LICENSE
*/
@ -18,7 +18,7 @@ switch($url) {
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>';
echo '<iframe class="bitpay_invoice_iframe" src="'.$url.'" style="width:500px; height:150px; overflow:hidden; border:none; margin:auto; display:none;" scrolling="no" allowtransparency="true" frameborder="0"> </iframe>';
break;
}
$quoteId = $this->getQuote()->getId();
@ -27,23 +27,64 @@ $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=' . $quoteId; ?>",
if ($$('iframe.bitpay_invoice_iframe').length > 0) {
var bpListener = {
nextStep: function(transport) {
if (transport && transport.responseText) {
try{
response = eval('(' + transport.responseText + ')');
}
catch (e) {
response = {};
}
if (response.success) {
$$('iframe.bitpay_invoice_iframe')[0].setStyle({display:'block'});
$$('button.btn-checkout')[0].setStyle({display:'none'});
var ipnPoller = new PeriodicalExecuter(function() {
new Ajax.Request("<?php echo $url . '?quote=' . $quoteId; ?>",
{
asynchronous: true,
evalScripts: true,
onComplete: function(request, json) {
var data = request.responseText.evalJSON();
if (data.paid) {
review.save();
ipnPoller.stop();
review.nextStep(transport);
}
}
});
}, 5);
} else {
var msg = response.error_messages;
if (typeof(msg)=='object') {
msg = msg.join("\n");
}
if (msg) {
alert(msg);
}
}
if (response.update_section) {
$('checkout-'+response.update_section.name+'-load').update(response.update_section.html);
}
if (response.goto_section) {
checkout.gotoSection(response.goto_section, true);
}
}
}
);
}, 5);
};
var reviewCheck = new PeriodicalExecuter(function() {
if (review) {
reviewCheck.stop();
var originalSaveHandler = review.onSave;
review.onSave = bpListener.nextStep.bindAsEventListener(review);
}
}, 1);
}
//]]>
</script>