Skip to content

Commit

Permalink
add inline checkout (#58)
Browse files Browse the repository at this point in the history
* add inline checkout

* Update inline-checkout.js
  • Loading branch information
kkong87 committed Mar 12, 2021
1 parent 2f66cc2 commit 4da38a7
Show file tree
Hide file tree
Showing 11 changed files with 387 additions and 8 deletions.
37 changes: 37 additions & 0 deletions Api/InlineCheckoutInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

/**
* Astound
* NOTICE OF LICENSE
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to [email protected] so we can send you a copy immediately.
*
* @category Affirm
* @package Astound_Affirm
* @copyright Copyright (c) 2016 Astound, Inc. (http://www.astoundcommerce.com)
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
*/

namespace Astound\Affirm\Api;

/**
* Interface OrderServiceManagerInterface
*
* @package Astound\Affirm\Api
* @api
*/
interface InlineCheckoutInterface
{
/**
* Init checkout and get retrieve increment id
* form affirm checkout
*
* @return string
*/
public function initInline();
}
197 changes: 197 additions & 0 deletions Model/InlineCheckout.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
<?php
namespace Astound\Affirm\Model;

use Astound\Affirm\Gateway\Helper\Util;
use Magento\Checkout\Model\Session;
use Astound\Affirm\Api\InlineCheckoutInterface;
use Magento\Framework\App\ProductMetadataInterface;
use Magento\Framework\Module\ResourceInterface;
use Magento\Framework\UrlInterface;
use Magento\Quote\Model\QuoteValidator;
use Magento\Framework\Exception\LocalizedException;

/**
* Class InlineCheckout
*
* @package Astound\Affirm\Model
*/
class InlineCheckout implements InlineCheckoutInterface
{
/**
* @var Session
*/
private $session;
/**
* @var \Magento\Quote\Api\Data\CartInterface|\Magento\Quote\Model\Quote
*/
private $quote;
/**
* @var UrlInterface
*/
private $urlBuilder;
/**
* @var ResourceInterface
*/
private $moduleResource;
/**
* @var ProductMetadataInterface
*/
private $productMetadata;

/**
* @var Astound\Affirm\Gateway\Helper\Util
*/
private $util;
/**
* @var QuoteValidator
*/
private $quoteValidator;

public function __construct(
Session $checkoutSession,
UrlInterface $urlInterface,
ResourceInterface $moduleResource,
ProductMetadataInterface $productMetadata,
Util $util,
QuoteValidator $quoteValidator
){
$this->session = $checkoutSession;
$this->quote = $checkoutSession->getQuote();
$this->urlBuilder = $urlInterface;
$this->moduleResource = $moduleResource;
$this->productMetadata = $productMetadata;
$this->util = $util;
$this->quoteValidator = $quoteValidator;
}

public function initInline(){
$quote = $this->quote;
$quote->collectTotals();

if(!$quote->getReservedOrderId()) {
$quote->reserveOrderId();
}

try{
$this->quoteValidator->validateBeforeSubmit($quote);
} catch (LocalizedException $e) {
return json_encode(array(
'merchant' => array(
'user_confirmation_url' => $this->urlBuilder
->getUrl('affirm/payment/confirm', ['_secure' => true]),
'user_cancel_url' => $this->urlBuilder
->getUrl('affirm/payment/cancel', ['_secure' => true]),
'user_confirmation_url_action' => 'POST',
),
'order_id' => $quote->getReservedOrderId(),
'total' => $this->util->formatToCents($quote->getGrandTotal())
));

}catch (\Exception $e) {

}

$checkoutObject = array(
'merchant' => array(
'user_confirmation_url' => $this->urlBuilder
->getUrl('affirm/payment/confirm', ['_secure' => true]),
'user_cancel_url' => $this->urlBuilder
->getUrl('affirm/payment/cancel', ['_secure' => true]),
'user_confirmation_url_action' => 'POST',
),
'order_id' => $quote->getReservedOrderId(),
'shipping_amount' => $this->util->formatToCents($quote->getShippingAddress()->getShippingAmount()),
'total' => $this->util->formatToCents($quote->getGrandTotal()),
'tax_amount' => $this->util->formatToCents($quote->getShippingAddress()->getTaxAmount()),
'metadata' => array(
'platform_type' => $this->productMetadata->getName() . ' 2',
'platform_version' => $this->productMetadata->getVersion() . ' ' . $this->productMetadata->getEdition(),
'platform_affirm' => $this->moduleResource->getDbVersion('Astound_Affirm'),
'mode' => 'inline'
)
);

if($items = $this->formatItems($quote->getAllVisibleItems())) {
$checkoutObject['items'] = $items;
}

if ($shippingAddress = $this->formatAddress($quote->getShippingAddress())) {
$checkoutObject['shipping'] = $shippingAddress;
}

if ($billingAddress = $this->formatAddress($quote->getBillingAddress())) {
$checkoutObject['billing'] = $billingAddress;
}

$discountAmount = $this->quote->getBaseSubtotal() - $this->quote->getBaseSubtotalWithDiscount();
if ($discountAmount > 0.001) {
$checkoutObject['discounts']['discount'] = [
'discount_amount' => Util::formatToCents($discountAmount)
];
}

if ($this->productMetadata->getEdition() == 'Enterprise') {
$giftWrapperItemsManager = $this->objectManager->create('Astound\Affirm\Api\GiftWrapManagerInterface');
$wrapped = $giftWrapperItemsManager->getWrapItems();
if ($wrapped) {
$checkoutObject['wrapped_items'] = $wrapped;
}
$giftCards = $this->quote->getGiftCards();
if ($giftCards) {
$giftCards = json_decode($giftCards);
foreach ($giftCards as $giftCard) {
$giftCardDiscountDescription = sprintf(__('Gift Card (%s)'), $giftCard[self::ID]);
$checkoutObject['discounts'][$giftCardDiscountDescription] = [
'discount_amount' => Util::formatToCents($giftCard[self::AMOUNT])
];
}
}
}

return json_encode($checkoutObject);
}

private function formatAddress($address){
$formattedAddress = false;
if($address->getCity()) {
$street = $address->getStreet();
$formattedAddress = array(
'name' => array(
'first' => $address->getFirstName(),
'last' => $address->getLastName(),
),
'address' => array(
'line1' => $street[0] ? $street[0] : '',
'line2' => $street[1] ? $street[1] : '',
'city' => $address->getCity(),
'state' => $address->getRegion(),
'zipcode' => $address->getPostcode(),
'country' => $address->getCountryId()
),
'phone_number' => $address->getTelephone() ? $address->getTelephone() : '',
'email' => $address->getEmail() ? $address->getEmail() : ''
);
}

return $formattedAddress;
}

private function formatItems($items) {
$formattedItems = array();
foreach ( (object)$items as $item) {
if( is_object($item)){
$product = $item->getProduct();

$formattedItems[] = array(
'display_name' => $item->getName(),
'sku' => $item->getSku(),
'unit_price' => $item->getPrice(),
'qty' => $item->getQty(),
'item_image_url' => $product->getData('thumbnail'),
'item_url' => $product->getUrlModel()->getUrl($product)
);
}
}
return $formattedItems;
}
}
3 changes: 2 additions & 1 deletion Model/Ui/ConfigProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,8 @@ public function getConfig()
'afterAffirmConf' => $this->config->getValue('after_affirm_conf'),
'logoSrc' => $this->config->getValue('icon'),
'info' => $this->config->getValue('info'),
'visibleType' => $this->config->getValue('control') ? true: false
'visibleType' => $this->config->getValue('control') ? true: false,
'edu' => $this->config->getValue('edu') ? true : false
]
]
];
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "affirm/magento2",
"description": "Affirm's extension for the Magento 2 https://www.affirm.com/",
"type": "magento2-module",
"version": "3.0.8",
"version": "3.0.10",
"license": [
"BSD-3-Clause"
],
Expand Down
5 changes: 5 additions & 0 deletions etc/adminhtml/system.xml
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,11 @@
<label>Checkout Flow Type</label>
<source_model>Astound\Affirm\Model\Adminhtml\Source\PaymentCheckoutFlow</source_model>
</field>
<field id="edu" translate="label" type="select" sortOrder="180" showInDefault="1" showInWebsite="1" showInStore="0">
<label>Inline Checkout Messaging</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
<comment>Enable/Disable Inline checkout value props on the checkout page when Affirm is selected as a payment method</comment>
</field>
<group id="notification" translate="label" type="text" sortOrder="180" showInDefault="1" showInWebsite="1" showInStore="0">
<label>Notification</label>
<field id="notification_update" translate="label" type="select" sortOrder="170" showInDefault="1" showInWebsite="1" showInStore="0">
Expand Down
1 change: 1 addition & 0 deletions etc/di.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
<preference for="Astound\Affirm\Api\AffirmCheckoutManagerInterface" type="Astound\Affirm\Model\AffirmCheckoutManager" />
<preference for="Astound\Affirm\Api\CheckoutPaymentManagerInterface" type="Astound\Affirm\Model\CheckoutPaymentManager" />
<preference for="Astound\Affirm\Api\GiftWrapManagerInterface" type="Astound\Affirm\Model\GiftWrapManager" />
<preference for="Astound\Affirm\Api\InlineCheckoutInterface" type="Astound\Affirm\Model\InlineCheckout" />

<!-- Payment Method Facade configuration -->
<virtualType name="OnePicaAffirmGatewayFacade" type="Magento\Payment\Model\Method\Adapter">
Expand Down
2 changes: 1 addition & 1 deletion etc/module.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="Astound_Affirm" setup_version="3.0.8">
<module name="Astound_Affirm" setup_version="3.0.10">
<sequence>
<module name="Magento_Checkout"/>
<module name="Magento_Sales"/>
Expand Down
6 changes: 6 additions & 0 deletions etc/webapi.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,10 @@
<resource ref="anonymous" />
</resources>
</route>
<route url="/V1/affirm/checkout/inline" method="GET">
<service class="Astound\Affirm\Api\InlineCheckoutInterface" method="initInline"/>
<resources>
<resource ref="anonymous" />
</resources>
</route>
</routes>
79 changes: 79 additions & 0 deletions view/frontend/web/js/action/inline-checkout.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/**
* Copyright © 2016 Magento. All rights reserved.
* See COPYING.txt for license details.
*/
/*jshint browser:true jquery:true*/
/*global alert*/
define([
'jquery',
'mage/storage',
'Magento_Checkout/js/model/url-builder',
], function ($,storage, urlBuilder) {
'use strict';
var configData = window.checkoutConfig.payment['affirm_gateway'];
var checkoutObject
var initAffirmInline = true
return {
inlineCheckout: function(){
let serviceUrl = urlBuilder.createUrl('/affirm/checkout/inline', {}), result;
storage.get(
serviceUrl
).done(
function(response) {
if(!(checkoutObject == response)) {
affirm.ui.ready(function() {
affirm.checkout(JSON.parse(response))
affirm.checkout.inline({
merchant: {
inline_container: "affirm-inline-checkout"
},
});
})
initAffirmInline = false
} else {
affirm.checkout.inline({
container: "affirm-inline-checkout",
data: JSON.parse(response),
});
}
checkoutObject = response
}
).fail(
function (response) {
console.log(response)
}
)
},

updateInlineCheckout : function(){
var _self = this;
let serviceUrl = urlBuilder.createUrl('/affirm/checkout/inline', {}), result;
storage.get(
serviceUrl
).done(
function(response) {
setTimeout(function(){
$('.action-apply').click(function(){
_self.updateInlineCheckout()
})
$('.action-cancel').click(function(){
_self.updateInlineCheckout()
})
$('.action-update').click(function(){
_self.updateInlineCheckout()
})
},
3000);
affirm.checkout.inline({
container: "affirm-inline-checkout",
data: JSON.parse(response),
});
}
).fail(
function (response) {
console.log(response)
}
)
}
}
})
Loading

0 comments on commit 4da38a7

Please sign in to comment.