Skip to content

Commit

Permalink
[MIT-1911] Whitelabel installment
Browse files Browse the repository at this point in the history
  • Loading branch information
mmkittisak committed Jun 21, 2024
1 parent 4d72485 commit 234b58c
Show file tree
Hide file tree
Showing 5 changed files with 233 additions and 17 deletions.
21 changes: 14 additions & 7 deletions Gateway/Request/APMBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@

class APMBuilder implements BuilderInterface
{
/**
* @var string
*/
const CARD = 'card';

/**
* @var string
*/
Expand Down Expand Up @@ -187,13 +192,15 @@ public function build(array $buildSubject)
];
break;
case Installment::CODE:
$installmentId = $method->getAdditionalInformation(InstallmentDataAssignObserver::OFFSITE);
$paymentInfo[self::SOURCE] = [
self::SOURCE_TYPE => $installmentId,
self::SOURCE_INSTALLMENT_TERMS => $method->getAdditionalInformation(
InstallmentDataAssignObserver::TERMS
)
];
$card = $method->getAdditionalInformation(InstallmentDataAssignObserver::CARD);
if ($card !== null) {
$paymentInfo[self::CARD] = $card;
}

$source = $method->getAdditionalInformation(InstallmentDataAssignObserver::SOURCE);
if ($source !== null) {
$paymentInfo[self::SOURCE] = $source;
}
break;
case Truemoney::CODE:
$paymentInfo[self::SOURCE] = $this->getTruemoneySourceData($method);
Expand Down
12 changes: 12 additions & 0 deletions Gateway/Request/PaymentDataBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,18 @@ public function build(array $buildSubject)
$requestBody[self::METADATA]['secure_form_enabled'] = $this->ccConfig->getSecureForm();
}

if (Installment::CODE === $method->getMethod()) {
$card = $method->getAdditionalInformation(InstallmentDataAssignObserver::CARD);
if ($card !== null) {
$requestBody['card'] = $card;
}

$source = $method->getAdditionalInformation(InstallmentDataAssignObserver::SOURCE);
if ($source !== null) {
$requestBody['source'] = $source;
}
}

return $requestBody;
}

Expand Down
6 changes: 5 additions & 1 deletion Observer/InstallmentDataAssignObserver.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,16 @@ class InstallmentDataAssignObserver extends OffsiteDataAssignObserver
* @var string
*/
const TERMS = 'terms';
const CARD = 'card';
const SOURCE = 'source';

/**
* @var array
*/
protected $additionalInformationList = [
self::OFFSITE,
self::TERMS
self::TERMS,
self::CARD,
self::SOURCE,
];
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,18 @@ define(
'Magento_Checkout/js/view/payment/default',
'Magento_Checkout/js/model/quote',
'Magento_Catalog/js/price-utils',
'Magento_Checkout/js/model/full-screen-loader',
'mage/storage',
],
function (
$,
ko,
Base,
Component,
quote,
priceUtils
priceUtils,
fullScreenLoader,
storage
) {
'use strict';
const CAPTION = $.mage.__('Choose number of monthly payments');
Expand Down Expand Up @@ -83,15 +87,28 @@ define(
},
]

function convertToCents(dollarAmount) {
return Math.round(parseFloat(dollarAmount) * 100);
}

return Component.extend(Base).extend({
defaults: {
template: 'Omise_Payment/payment/offsite-installment-form'
},
code: 'omise_offsite_installment',
restrictedToCurrencies: ['thb', 'myr'],

isPlaceOrderActionAllowed: ko.observable(quote.billingAddress() != null),
capabilities: null,
billingAddressCountries: ["US", "GB", "CA"],

/**
* Get Omise public key
*
* @return {string}
*/
getPublicKey: function () {
return window.checkoutConfig.payment.omise_cc.publicKey
},
/**
* Initiate observable fields
*
Expand All @@ -110,16 +127,133 @@ define(
'installmentTermsUOB',
'installmentTermsMBB',
'installmentTermsTTB',
'omiseInstallmentError',
'omiseInstallmentToken',
'omiseInstallmentSource',
]);

this.capabilities = checkoutConfig.omise_payment_list[this.code];

// filter provider for checkout page
this.providers = this.get_available_providers()

this.openOmiseJs();
return this;
},

selectPaymentMethod: function () {
this._super();
OmiseCard.destroy();
setTimeout(() => this.openOmiseJs(), 1000);
return this
},

openOmiseJs: function () {
const self = this
ko.bindingHandlers.omiseInstallmentForm = {
init: function (element) {
const iframeHeightMatching = {
'40px': 258,
'44px': 270,
'48px': 282,
'52px': 295,
}

const localeMatching = {
en_US: 'en',
ja_JP: 'ja',
th_TH: 'th'
}

const { theme, locale, formDesign } = window.checkoutConfig.payment.omise_cc
const { font, input, checkbox } = formDesign
let iframeElementHeight = iframeHeightMatching[input.height]
element.style.height = 500 + 'px';

OmiseCard.configure({
publicKey: self.getPublicKey(),
amount: convertToCents(window.checkoutConfig.quoteData.grand_total),
element,
iframeAppId: 'omise-checkout-installment-form',
customCardForm: false,
customInstallmentForm: true,
locale: localeMatching[locale] ?? 'en',
defaultPaymentMethod: 'installment'
});

OmiseCard.open({
onCreateSuccess: (payload) => {
console.log('payload: ', payload);
self.createOrder(self, payload)
},
onError: (err) => {
if (err.length > 0) {
self.omiseInstallmentError(err.length == 1 ? err[0] : 'Please enter required card information.')
}
else {
self.omiseInstallmentError('Something went wrong. Please refresh the page and try again.')
}
self.stopPerformingPlaceOrderAction()
}
});
}
}
},

createOrder: function (self, payload) {
console.log('in createOrder');
self.omiseInstallmentToken(payload.token)
self.omiseInstallmentSource(payload.source)
const failHandler = self.buildFailHandler(this, 300)
self.getPlaceOrderDeferredObject()
.fail(failHandler)
.done((order_id) => {
let serviceUrl = self.getMagentoReturnUrl(order_id)
storage.get(serviceUrl, false)
.fail(failHandler)
.done(function (response) {
if (response) {
$.mage.redirect(response.authorize_uri)
} else {
failHandler(response)
}
})
})
},

/**
* Hook the placeOrder function.
* Original source: placeOrder(data, event); @ module-checkout/view/frontend/web/js/view/payment/default.js
*
* @return {boolean}
*/
placeOrder: function (data, event) {
this.omiseInstallmentError(null)
event && event.preventDefault()

if (typeof Omise === 'undefined') {
alert($.mage.__('Unable to process the payment, loading the external card processing library is failed. Please contact the merchant.'))
return false
}

this.generateTokenWithEmbeddedFormAndPerformPlaceOrderAction()
return true
},

/**
* Generate Omise token with embedded form before proceed the placeOrder process.
*
* @return {void}
*/
generateTokenWithEmbeddedFormAndPerformPlaceOrderAction: function () {
this.startPerformingPlaceOrderAction()
let billingAddress = {}
let selectedBillingAddress = quote.billingAddress()
if (this.billingAddressCountries.indexOf(selectedBillingAddress.countryId) > -1) {
Object.assign(billingAddress, this.getSelectedTokenBillingAddress(selectedBillingAddress))
}
OmiseCard.requestCardToken(billingAddress)
},

/**
* Get installment min amount from capability
*
Expand Down Expand Up @@ -312,11 +446,12 @@ define(
* @return {Object}
*/
getData: function () {
console.log('in get data', this.item.method, this.omiseInstallmentToken(), this.omiseInstallmentSource());
return {
'method': this.item.method,
'additional_data': {
'offsite': this.omiseOffsite(),
'terms': this.getTerms()
'card': this.omiseInstallmentToken(),
'source': this.omiseInstallmentSource()
}
};
},
Expand Down Expand Up @@ -380,8 +515,42 @@ define(
}
}
)))
}
},

/**
* Start performing place order action,
* by disable a place order button and show full screen loader component.
*/
startPerformingPlaceOrderAction: function () {
this.isPlaceOrderActionAllowed(false)
fullScreenLoader.startLoader()
},

/**
* Stop performing place order action,
* by disable a place order button and show full screen loader component.
*/
stopPerformingPlaceOrderAction: function () {
fullScreenLoader.stopLoader()
this.isPlaceOrderActionAllowed(true)
},

getSelectedTokenBillingAddress: function (selectedBillingAddress) {
let address = {
state: selectedBillingAddress.region,
postal_code: selectedBillingAddress.postcode,
phone_number: selectedBillingAddress.telephone,
country: selectedBillingAddress.countryId,
city: selectedBillingAddress.city,
street1: selectedBillingAddress.street[0]
}

if (selectedBillingAddress.street[1]) {
address.street2 = selectedBillingAddress.street[1]
}

return address
}
});
}
);
30 changes: 27 additions & 3 deletions view/frontend/web/template/payment/offsite-installment-form.html
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,17 @@
<!-- /ko -->
<!--/ko-->
</div>

<!-- ko if: omiseInstallmentError() -->
<div class="omise-card-error-container">
<div aria-atomic="true" role="alert" class="message message-error error">
<div data-ui-id="checkout-cart-validationmessages-message-error" data-bind="text: omiseInstallmentError()"></div>
</div>
</div>
<!-- /ko -->

<!-- ko if: providers().length -->
<div class="omise-banking-fee-warn" data-bind="i18n: 'Choose your installment terms'"></div>
<!-- <div class="omise-banking-fee-warn" data-bind="i18n: 'Choose your installment terms'"></div>
<form class="form" data-bind="attr: {
id: getCode() + 'Form',
}">
Expand Down Expand Up @@ -83,7 +92,22 @@
</li>
</ul>
</fieldset>
</form>
</form> -->
<input type="hidden"
name="payment[omise_token]"
data-bind="attr: {
'id': getCode() + 'InstallmentToken',
'data-container': getCode() + '-cc-token',
},
value: omiseInstallmentToken"/>
<input type="hidden"
name="payment[omise_source]"
data-bind="attr: {
'id': getCode() + 'InstallmentSource',
'data-container': getCode() + '-cc-source',
},
value: omiseInstallmentSource"/>
<div class="omise-installment-form" data-bind="omiseInstallmentForm: true"></div>
<div class="checkout-agreements-block">
<!-- ko foreach: $parent.getRegion('before-place-order') -->
<!-- ko template: getTemplate() -->
Expand All @@ -96,7 +120,7 @@
click: placeOrder,
attr: {title: $t('Place Order')},
css: {disabled: !isPlaceOrderActionAllowed()},
enable: (getCode() == isChecked()) && omiseOffsite() && getTerms() ">
enable: (getCode() == isChecked())">
<span data-bind="i18n: 'Place Order'"></span>
</button>
</div>
Expand Down

0 comments on commit 234b58c

Please sign in to comment.