diff --git a/Gateway/Request/APMBuilder.php b/Gateway/Request/APMBuilder.php
index 527cb21f..211ec941 100644
--- a/Gateway/Request/APMBuilder.php
+++ b/Gateway/Request/APMBuilder.php
@@ -375,16 +375,17 @@ private function getOrderItems($order)
$itemArray = [];
$items = $order->getItems();
$currency = $order->getCurrencyCode();
- foreach ($items as $itemObject) {
- $item = $itemObject->toArray();
+
+ foreach ($items as $item) {
+ $price = $item->getPrice();
+ if ((float) $price === 0.0) {
+ continue;
+ }
$itemArray[] = [
- 'sku' => $item['sku'],
- 'name' => $item['name'],
- 'amount' => $this->money->setAmountAndCurrency(
- $item['base_original_price'],
- $currency
- )->toSubunit(),
- 'quantity' => $item['qty_ordered'],
+ 'sku' => $item->getSku(),
+ 'name' => $item->getName(),
+ 'amount' => $this->money->setAmountAndCurrency($price, $currency)->toSubunit(),
+ 'quantity' => $item->getQtyOrdered(),
];
}
return $itemArray;
diff --git a/Gateway/Validator/APMRequestValidator.php b/Gateway/Validator/APMRequestValidator.php
index 06217b44..35b18d65 100644
--- a/Gateway/Validator/APMRequestValidator.php
+++ b/Gateway/Validator/APMRequestValidator.php
@@ -20,11 +20,12 @@ public function build(array $buildSubject)
$paymentDataObject = SubjectReader::readPayment($buildSubject);
$order = $paymentDataObject->getOrder();
$paymentInfo = $paymentDataObject->getPayment();
+ $subTotal = $paymentInfo->getOrder()->getSubTotal();
switch ($paymentInfo->getMethod()) {
case Atome::CODE:
- $this->validateAtomePhoneNumber($order, $paymentInfo);
- $this->validateAtomeAmount($order);
+ $this->validateAtomePhoneNumber($paymentInfo);
+ $this->validateAtomeAmount($order, $subTotal);
break;
default:
break;
@@ -41,7 +42,7 @@ public function build(array $buildSubject)
*
* @return void
*/
- private function validateAtomePhoneNumber($order, $info)
+ private function validateAtomePhoneNumber($info)
{
$number = $info->getAdditionalInformation(AtomeDataAssignObserver::PHONE_NUMBER);
$phonePattern = "/(\+)?([0-9]{10,13})/";
@@ -61,7 +62,7 @@ private function validateAtomePhoneNumber($order, $info)
*
* @return void
*/
- private function validateAtomeAmount($order)
+ private function validateAtomeAmount($order, $subTotal)
{
$limits = [
'THB' => [
@@ -81,6 +82,10 @@ private function validateAtomeAmount($order)
$currency = strtoupper($order->getCurrencyCode());
$amount = $order->getGrandTotalAmount();
+ if ((float) $subTotal === 0.0) {
+ throw new LocalizedException(__('Complimentary products cannot be billed'));
+ }
+
if (!isset($limits[$currency])) {
throw new LocalizedException(__('Currency not supported'));
}
diff --git a/Test/Mock/InfoMock.php b/Test/Mock/InfoMock.php
index 4f297213..be96c58f 100644
--- a/Test/Mock/InfoMock.php
+++ b/Test/Mock/InfoMock.php
@@ -41,4 +41,8 @@ public function getMethod()
public function getPayment()
{
}
+
+ public function getOrder()
+ {
+ }
}
diff --git a/Test/Mock/OrderMock.php b/Test/Mock/OrderMock.php
new file mode 100644
index 00000000..f3bca49d
--- /dev/null
+++ b/Test/Mock/OrderMock.php
@@ -0,0 +1,52 @@
+addressMock = $this->getMockBuilder(AddressInterface::class)->getMock();
+ $this->addressMock = $this->getMockBuilder(AddressAdapterInterface::class)->getMock();
$this->addressMock->method('getCountryId')->willReturn('TH');
- $this->orderMock = $this->getMockBuilder(OrderAdapterInterface::class)
- ->getMockForAbstractClass();
+ $this->orderMock = $this->getMockBuilder(OrderMock::class)->getMock();
$this->orderMock->method('getShippingAddress')->willReturn($this->addressMock);
$this->infoMock = $this->getMockBuilder(InfoMock::class)->getMock();
$this->infoMock->method('getMethod')->willReturn(Atome::CODE);
+ $this->infoMock->method('getOrder')->willReturn($this->orderMock);
- $this->paymentDataObject = new PaymentDataObject(
- $this->orderMock,
- $this->infoMock
- );
+ $this->paymentDataObjectMock = $this->getMockBuilder(PaymentDataObjectInterface::class)->getMock();
+ $this->paymentDataObjectMock->method('getOrder')->willReturn($this->orderMock);
+ $this->paymentDataObjectMock->method('getPayment')->willReturn($this->infoMock);
$this->model = new APMRequestValidator();
}
+ /**
+ * @covers Omise\Payment\Gateway\Validator\APMRequestValidator
+ */
+ public function testComplimentaryProducts()
+ {
+ $this->expectException(LocalizedException::class);
+ $this->expectExceptionMessage('Complimentary products cannot be billed');
+ $this->orderMock->method('getSubTotal')->willReturn(0.0);
+ $this->orderMock->method('getCurrencyCode')->willReturn("THB");
+ $this->infoMock->method('getAdditionalInformation')->willReturn('0987654321');
+ $this->model->build(['payment' => $this->paymentDataObjectMock]);
+ }
+
/**
* @covers Omise\Payment\Gateway\Validator\APMRequestValidator
*/
@@ -51,11 +63,9 @@ public function testCurrencyNotSupported()
$this->expectException(LocalizedException::class);
$this->expectExceptionMessage('Currency not supported');
$this->orderMock->method('getCurrencyCode')->willReturn("USD");
- $this->orderMock->method('getGrandTotalAmount')->willReturn(100);
+ $this->orderMock->method('getSubTotal')->willReturn(100);
$this->infoMock->method('getAdditionalInformation')->willReturn('0987654321');
- $this->model->build([
- 'payment' => $this->paymentDataObject,
- ]);
+ $this->model->build(['payment' => $this->paymentDataObjectMock]);
}
/**
@@ -67,10 +77,9 @@ public function testMinAmountShouldThrowError()
$this->expectExceptionMessage('Amount must be greater than 20.00 THB');
$this->orderMock->method('getCurrencyCode')->willReturn("THB");
$this->orderMock->method('getGrandTotalAmount')->willReturn(10);
+ $this->orderMock->method('getSubTotal')->willReturn(10);
$this->infoMock->method('getAdditionalInformation')->willReturn('0987654321');
- $this->model->build([
- 'payment' => $this->paymentDataObject,
- ]);
+ $this->model->build(['payment' => $this->paymentDataObjectMock]);
}
/**
@@ -81,10 +90,9 @@ public function testValidAmountShouldNotThrowError()
$this->expectNotToPerformAssertions();
$this->orderMock->method('getCurrencyCode')->willReturn("THB");
$this->orderMock->method('getGrandTotalAmount')->willReturn(20);
+ $this->orderMock->method('getSubTotal')->willReturn(20);
$this->infoMock->method('getAdditionalInformation')->willReturn('0987654321');
- $this->model->build([
- 'payment' => $this->paymentDataObject,
- ]);
+ $this->model->build(['payment' => $this->paymentDataObjectMock]);
}
/**
@@ -96,10 +104,9 @@ public function testMaxAmountShouldThrowError()
$this->expectExceptionMessage('Amount must be less than 150,000.00 THB');
$this->orderMock->method('getCurrencyCode')->willReturn("THB");
$this->orderMock->method('getGrandTotalAmount')->willReturn(200000);
+ $this->orderMock->method('getSubTotal')->willReturn(200000);
$this->infoMock->method('getAdditionalInformation')->willReturn('0987654321');
- $this->model->build([
- 'payment' => $this->paymentDataObject,
- ]);
+ $this->model->build(['payment' => $this->paymentDataObjectMock]);
}
/**
@@ -112,9 +119,8 @@ public function testInvalidAtomePhoneNumberValidation()
$this->infoMock->method('getAdditionalInformation')->willReturn('0987');
$this->orderMock->method('getCurrencyCode')->willReturn("THB");
$this->orderMock->method('getGrandTotalAmount')->willReturn(100);
- $this->model->build([
- 'payment' => $this->paymentDataObject,
- ]);
+ $this->orderMock->method('getSubTotal')->willReturn(100);
+ $this->model->build(['payment' => $this->paymentDataObjectMock]);
}
/**
@@ -126,8 +132,7 @@ public function testValidAtomePhoneNumberValidation()
$this->infoMock->method('getAdditionalInformation')->willReturn('+66987654321');
$this->orderMock->method('getCurrencyCode')->willReturn("THB");
$this->orderMock->method('getGrandTotalAmount')->willReturn(100);
- $this->model->build([
- 'payment' => $this->paymentDataObject,
- ]);
+ $this->orderMock->method('getSubTotal')->willReturn(100);
+ $this->model->build(['payment' => $this->paymentDataObjectMock]);
}
}
diff --git a/Test/Unit/AtomeAPMBuilderTest.php b/Test/Unit/AtomeAPMBuilderTest.php
new file mode 100644
index 00000000..cac89952
--- /dev/null
+++ b/Test/Unit/AtomeAPMBuilderTest.php
@@ -0,0 +1,117 @@
+itemMock = $this->getMockBuilder(OrderItemInterface::class)->getMock();
+ $this->addressMock = $this->getMockBuilder(AddressAdapterInterface::class)->getMock();
+ $this->helper = $this->getMockBuilder(OmiseHelper::class)->disableOriginalConstructor()->getMock();
+ $this->returnUrlHelper = $this->getMockBuilder(ReturnUrlHelper::class)->disableOriginalConstructor()->getMock();
+ $this->config = $this->getMockBuilder(Config::class)->disableOriginalConstructor()->getMock();
+ $this->capabilities = $this->getMockBuilder(Capabilities::class)->disableOriginalConstructor()->getMock();
+ $this->orderMock = $this->getMockBuilder(OrderAdapterInterface::class)->getMock();
+ $this->orderMock->method('getShippingAddress')->willReturn($this->addressMock);
+ $this->orderMock->method('getItems')->willReturn([$this->itemMock]);
+ $this->orderMock->method('getCurrencyCode')->willReturn('THB');
+ $this->infoMock = $this->getMockBuilder(InfoMock::class)->getMock();
+ }
+
+ /**
+ * @covers Omise\Payment\Gateway\Request\APMBuilder
+ * @covers Omise\Payment\Model\Config\Atome
+ */
+ public function testApmBuilderWithItemPriceZero()
+ {
+ $this->itemMock->method('getPrice')->willReturn(0.0);
+ $this->infoMock->method('getMethod')->willReturn(Atome::CODE);
+ $this->returnUrlHelper->method('create')->willReturn([
+ 'url' => 'https://omise.co/complete',
+ 'token' => '1234'
+ ]);
+
+ $this->builder = new APMBuilder(
+ $this->helper,
+ $this->returnUrlHelper,
+ $this->config,
+ $this->capabilities,
+ new OmiseMoney(),
+ );
+
+ $result = $this->builder->build(['payment' => new PaymentDataObject(
+ $this->orderMock,
+ $this->infoMock
+ )]);
+
+ $this->assertEquals(0, count($result['source']['items']));
+ $this->assertEquals('atome', $result['source']['type']);
+ $this->assertEquals('https://omise.co/complete', $result['return_uri']);
+ }
+
+ /**
+ * @covers Omise\Payment\Gateway\Request\APMBuilder
+ * @covers Omise\Payment\Model\Config\Atome
+ * @covers Omise\Payment\Helper\OmiseMoney
+ */
+ public function testApmBuilderWithItemPriceGreaterThanZero()
+ {
+ $this->itemMock->method('getPrice')->willReturn(100.0);
+ $this->infoMock->method('getMethod')->willReturn(Atome::CODE);
+ $this->returnUrlHelper->method('create')->willReturn([
+ 'url' => 'https://omise.co/complete',
+ 'token' => '1234'
+ ]);
+
+ $this->builder = new APMBuilder(
+ $this->helper,
+ $this->returnUrlHelper,
+ $this->config,
+ $this->capabilities,
+ new OmiseMoney(),
+ );
+
+ $result = $this->builder->build(['payment' => new PaymentDataObject(
+ $this->orderMock,
+ $this->infoMock
+ )]);
+
+ $this->assertEquals(1, count($result['source']['items']));
+ $this->assertEquals('atome', $result['source']['type']);
+ $this->assertEquals('https://omise.co/complete', $result['return_uri']);
+ }
+
+ /**
+ * @covers Omise\Payment\Model\Config\Atome
+ */
+ public function testConstants()
+ {
+ $this->assertEquals('omise_offsite_atome', Atome::CODE);
+ $this->assertEquals('atome', Atome::ID);
+ }
+}
diff --git a/i18n/ja_JP.csv b/i18n/ja_JP.csv
index bc607d6d..525a5e4c 100644
--- a/i18n/ja_JP.csv
+++ b/i18n/ja_JP.csv
@@ -14,3 +14,7 @@
"Card stolen or lost.", "このカードは紛失/盗難が報告されています"
"Payer did not take action before charge expiration.", "有効期限前に操作がありませんでした。"
"secure_form_banner_message", "Opn Payments : プラグインを最新バージョンにアップデートし、顧客情報の安全な管理に必要なSecure Formを有効にしてください。アップデート後、クレジットカードの決済フォームを再度カスタマイズする必要があります。Secure Formを有効にする方法はこちらをご確認ください。"
+"Complimentary products cannot be billed", "無償提供商品は課金の対象外です"
+"Currency not supported", "サポートされていない通貨です",
+"Amount must be greater than %1 %2", "金額は %1 %2を超える必要があります"
+"Amount must be less than %1 %2", "金額は %1 %2を下回る必要があります"
diff --git a/i18n/th_TH.csv b/i18n/th_TH.csv
index 7ef2562a..513831dc 100644
--- a/i18n/th_TH.csv
+++ b/i18n/th_TH.csv
@@ -37,3 +37,7 @@
"True Money Phone Number", "เบอร์โทรศัพท์ที่ใช้สมัครบัญชี TrueMoney Wallet"
"Use a new card", "ใช้บัตรใหม่"
"secure_form_banner_message", "Opn Payments : อัปเดตปลั๊กอินของคุณเป็นเวอร์ชันล่าสุดเพื่อเปิดใช้งาน Secure Form และมอบความปลอดภัยสูงสุดให้กับข้อมูลของลูกค้า โดยหลังจากทำการอัปเกรด คุณจะต้องปรับแต่งแบบฟอร์มการชำระเงินด้วยบัตรเครดิตใหม่อีกครั้ง เรียนรู้เพิ่มเติมเกี่ยวกับการเปิดใช้งาน Secure Form"
+"Complimentary products cannot be billed", "สินค้าที่ระลึกไม่สามารถเรียกเก็บเงินได้"
+"Currency not supported", "ระบบไม่รองรับสกุลเงินนี้",
+"Amount must be greater than %1 %2", "จำนวนเงินจะต้องมากกว่า %1 %2"
+"Amount must be less than %1 %2", "จำนวนเงินจะต้องไม่เกิน %1 %2"
diff --git a/view/frontend/web/images/atome.png b/view/frontend/web/images/atome.png
new file mode 100644
index 00000000..cc20d19c
Binary files /dev/null and b/view/frontend/web/images/atome.png differ
diff --git a/view/frontend/web/images/touchngo.png b/view/frontend/web/images/touchngo.png
index f8306d56..b15a1cec 100644
Binary files a/view/frontend/web/images/touchngo.png and b/view/frontend/web/images/touchngo.png differ
diff --git a/view/frontend/web/js/view/payment/method-renderer/omise-offsite-atome-method.js b/view/frontend/web/js/view/payment/method-renderer/omise-offsite-atome-method.js
index 02e4e418..77ed88cc 100644
--- a/view/frontend/web/js/view/payment/method-renderer/omise-offsite-atome-method.js
+++ b/view/frontend/web/js/view/payment/method-renderer/omise-offsite-atome-method.js
@@ -22,6 +22,12 @@ define(
code: 'omise_offsite_atome',
restrictedToCurrencies: ['thb', 'sgd', 'myr'],
+ logo: {
+ file: "images/atome.png",
+ width: "30",
+ height: "30",
+ name: "atome"
+ },
/**
* Initiate observable fields
diff --git a/view/frontend/web/js/view/payment/method-renderer/omise-offsite-touchngo-method.js b/view/frontend/web/js/view/payment/method-renderer/omise-offsite-touchngo-method.js
index 30ed9a89..6a5db0cf 100644
--- a/view/frontend/web/js/view/payment/method-renderer/omise-offsite-touchngo-method.js
+++ b/view/frontend/web/js/view/payment/method-renderer/omise-offsite-touchngo-method.js
@@ -24,7 +24,7 @@ define(
restrictedToCurrencies: ['sgd', 'myr'],
logo: {
file: "images/touchngo.png",
- width: "80",
+ width: "30",
height: "30",
name: "touchngo"
},
diff --git a/view/frontend/web/template/payment/offsite-atome-form.html b/view/frontend/web/template/payment/offsite-atome-form.html
index 69eaec0b..bb00cd15 100644
--- a/view/frontend/web/template/payment/offsite-atome-form.html
+++ b/view/frontend/web/template/payment/offsite-atome-form.html
@@ -9,8 +9,12 @@
click: selectPaymentMethod,
visible: isRadioButtonVisible(),
enable: isActive()" />
-