Skip to content

Commit 5077843

Browse files
authored
Merge pull request #40 from xendit/TPI-2541/admin-settings
Add new CC Installment payment method & admin setting
2 parents b2eafce + 4884bac commit 5077843

File tree

25 files changed

+346
-77
lines changed

25 files changed

+346
-77
lines changed

CHANGELOG.md

+6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# CHANGELOG
22

3+
## 2.1.0 (2020-09-04)
4+
5+
Features:
6+
7+
- Add Credit Card Installment payment method
8+
39
## 2.0.1 (2020-06-11)
410

511
Bugfix:

Xendit/M2Invoice/Controller/Checkout/CCMultishipping.php

+28-3
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,8 @@ public function execute()
7676
return $this->processFailedPayment($orderIds, $charge['failure_reason']);
7777
}
7878
}
79-
else if ($method === 'cchosted') {
80-
$requestData = [
79+
else if ($method === 'cchosted' || $method === 'cc_installment') {
80+
$requestData = array(
8181
'order_number' => $rawOrderIds,
8282
'amount' => $transactionAmount,
8383
'payment_type' => 'CREDIT_CARD',
@@ -86,7 +86,32 @@ public function execute()
8686
'success_redirect_url' => $this->getDataHelper()->getSuccessUrl(true),
8787
'failure_redirect_url' => $this->getDataHelper()->getFailureUrl($rawOrderIds, true),
8888
'platform_callback_url' => $this->_url->getUrl('xendit/checkout/cccallback') . '?order_ids=' . $rawOrderIds
89-
];
89+
);
90+
91+
if ($method === 'cc_installment') {
92+
$billingAddress = $orders[0]->getBillingAddress();
93+
$shippingAddress = $orders[0]->getShippingAddress();
94+
95+
$firstName = $billingAddress->getFirstname() ?: $shippingAddress->getFirstname();
96+
$country = $billingAddress->getCountryId() ?: $shippingAddress->getCountryId();
97+
$billingDetails = array(
98+
'given_names' => ($firstName ?: 'N/A'),
99+
'surname' => ($billingAddress->getLastname() ?: null),
100+
'email' => ($billingAddress->getEmail() ?: null),
101+
'phone_number' => ($billingAddress->getTelephone() ?: null),
102+
'address' => array(
103+
'country' => ($country ?: 'ID'),
104+
'street_line_1' => ($billingAddress->getStreetLine(1) ?: null),
105+
'street_line_2' => ($billingAddress->getStreetLine(2) ?: null),
106+
'city' => ($billingAddress->getCity() ?: null),
107+
'state' => ($billingAddress->getRegion() ?: null),
108+
'postal_code' => ($billingAddress->getPostcode() ?: null)
109+
)
110+
);
111+
112+
$requestData['is_installment'] = "true";
113+
$requestData['billing_details'] = json_encode($billingDetails, JSON_FORCE_OBJECT);
114+
}
90115

91116
$hostedPayment = $this->requestHostedPayment($requestData);
92117

Xendit/M2Invoice/Controller/Payment/OverviewPost.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ public function execute()
112112
$params = implode("-", $ids);
113113
$baseUrl = $this->_objectManager->get('\Magento\Store\Model\StoreManagerInterface')->getStore()->getBaseUrl();
114114

115-
if ($xenditPaymentMethod === 'cc' || $xenditPaymentMethod === 'cchosted') {
115+
if ($xenditPaymentMethod === 'cc' || $xenditPaymentMethod === 'cchosted' || $xenditPaymentMethod === 'cc_installment') {
116116
$redirect = $baseUrl . '/xendit/checkout/ccmultishipping?order_ids=' . $params . '&preferred_method=' . $xenditPaymentMethod;
117117
} else {
118118
$redirect = $baseUrl . '/xendit/checkout/invoicemultishipping?order_ids=' . $params.'&preferred_method='.$xenditPaymentMethod.'&billing_email='.$billingEmail;

Xendit/M2Invoice/Cron/CancelOrderCC.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ public function execute()
7171
if (strtotime($creationTime) < strtotime('-1 day')) {
7272
$order->setState(Order::STATE_CANCELED)
7373
->setStatus(Order::STATE_CANCELED)
74-
->addStatusHistoryComment("Xendit payment cancelled due to stuck on payment review for 30 days");
74+
->addStatusHistoryComment("Xendit payment cancelled due to stuck on payment review for 24 hours");
7575

7676
$bulkCancelData[] = array(
7777
'id' => $hosted3DSId,

Xendit/M2Invoice/Helper/Data.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -206,10 +206,11 @@ public function mapSalesRuleType($type)
206206

207207
public function xenditPaymentMethod( $payment ){
208208

209-
//methode name => frontend routing
209+
//method name => frontend routing
210210
$listPayment = [
211211
"cc" => "cc",
212212
"cchosted" => "cchosted",
213+
"cc_installment" => "cc_installment",
213214
"bcava" => "bca",
214215
"bniva" => "bni",
215216
"briva" => "bri",

Xendit/M2Invoice/Model/Adminhtml/Source/ChosenMethod.php

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ public function toOptionArray($isMultiselect = false)
2626
['value' => 'mandiriva', 'label' => __('Bank Transfer Mandiri')],
2727
['value' => 'permatava', 'label' => __('Bank Transfer Permata')],
2828
['value' => 'cc', 'label' => __('Credit Card')],
29+
['value' => 'cc_installment', 'label' => __('Credit Card Installment')],
2930
['value' => 'ovo', 'label' => __('OVO')],
3031
];
3132

Xendit/M2Invoice/Model/Payment/AbstractInvoice.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ public function isAvailable(\Magento\Quote\Api\Data\CartInterface $quote = null)
108108

109109
$cardPaymentType = $this->dataHelper->getCardPaymentType();
110110

111-
if ($cardPaymentType === 'popup' && $this->methodCode === 'CCHOSTED') {
111+
if (($cardPaymentType === 'popup' && $this->methodCode === 'CCHOSTED') || $this->methodCode === 'CC_INSTALLMENT') {
112112
return true;
113113
}
114114

Xendit/M2Invoice/Model/Payment/CCHosted.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ private function requestRefund($chargeId, $requestData)
152152
return $refund;
153153
}
154154

155-
private function requestHostedPayment($requestData)
155+
public function requestHostedPayment($requestData)
156156
{
157157
$hostedPaymentUrl = $this->dataHelper->getCheckoutUrl() . "/payment/xendit/hosted-payments";
158158
$hostedPaymentMethod = \Zend\Http\Request::METHOD_POST;
@@ -170,7 +170,7 @@ private function requestHostedPayment($requestData)
170170
return $hostedPayment;
171171
}
172172

173-
private function processFailedPayment($payment, $message)
173+
public function processFailedPayment($payment, $message)
174174
{
175175
$payment->setAdditionalInformation('xendit_failure_reason', $message);
176176
}
@@ -198,7 +198,7 @@ private function handleRefundResult($payment, $refund, $canRefundMore)
198198
);
199199
}
200200

201-
private function calculatePromo($order, $rawAmount)
201+
public function calculatePromo($order, $rawAmount)
202202
{
203203
$promo = [];
204204
$ruleIds = $order->getAppliedRuleIds();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
<?php
2+
3+
namespace Xendit\M2Invoice\Model\Payment;
4+
5+
use Magento\Framework\Api\ExtensionAttributesFactory;
6+
use Magento\Framework\Api\AttributeValueFactory;
7+
use Magento\Framework\App\Config\ScopeConfigInterface;
8+
use Magento\Framework\Model\Context;
9+
use Magento\Framework\Phrase;
10+
use Magento\Framework\Registry;
11+
use Magento\Payment\Helper\Data;
12+
use Magento\Payment\Model\Method\Logger;
13+
use Xendit\M2Invoice\Helper\ApiRequest;
14+
use Xendit\M2Invoice\Helper\LogDNA;
15+
use Xendit\M2Invoice\Enum\LogDNALevel;
16+
17+
class CCInstallment extends CCHosted
18+
{
19+
const PLATFORM_NAME = 'MAGENTO2';
20+
const PAYMENT_TYPE = 'CREDIT_CARD';
21+
/**
22+
* Payment code
23+
*
24+
* @var string
25+
*/
26+
protected $_code = 'cc_installment';
27+
protected $_minAmount = 10000;
28+
protected $_maxAmount = 10000000;
29+
protected $_canRefund = true;
30+
protected $methodCode = 'CC_INSTALLMENT';
31+
32+
/**
33+
* Override
34+
*/
35+
public function authorize(\Magento\Payment\Model\InfoInterface $payment, $amount)
36+
{
37+
$payment->setIsTransactionPending(true);
38+
39+
$order = $payment->getOrder();
40+
$quoteId = $order->getQuoteId();
41+
$quote = $this->quoteRepository->get($quoteId);
42+
43+
if ($quote->getIsMultiShipping()) {
44+
return $this;
45+
}
46+
47+
try {
48+
$orderId = $order->getRealOrderId();
49+
50+
$billingAddress = $order->getBillingAddress();
51+
$shippingAddress = $order->getShippingAddress();
52+
53+
$firstName = $billingAddress->getFirstname() ?: $shippingAddress->getFirstname();
54+
$country = $billingAddress->getCountryId() ?: $shippingAddress->getCountryId();
55+
$billingDetails = array(
56+
'given_names' => ($firstName ?: 'N/A'),
57+
'surname' => ($billingAddress->getLastname() ?: null),
58+
'email' => ($billingAddress->getEmail() ?: null),
59+
'phone_number' => ($billingAddress->getTelephone() ?: null),
60+
'address' => array(
61+
'country' => ($country ?: 'ID'),
62+
'street_line_1' => ($billingAddress->getStreetLine(1) ?: null),
63+
'street_line_2' => ($billingAddress->getStreetLine(2) ?: null),
64+
'city' => ($billingAddress->getCity() ?: null),
65+
'state' => ($billingAddress->getRegion() ?: null),
66+
'postal_code' => ($billingAddress->getPostcode() ?: null)
67+
)
68+
);
69+
70+
$rawAmount = ceil($order->getSubtotal() + $order->getShippingAmount());
71+
72+
$args = array(
73+
'order_number' => $orderId,
74+
'amount' => $amount,
75+
'payment_type' => self::PAYMENT_TYPE,
76+
'store_name' => $this->storeManager->getStore()->getName(),
77+
'platform_name' => self::PLATFORM_NAME,
78+
'is_installment' => "true",
79+
'billing_details' => json_encode($billingDetails, JSON_FORCE_OBJECT)
80+
);
81+
82+
$promo = $this->calculatePromo($order, $rawAmount);
83+
84+
if (!empty($promo)) {
85+
$args['promotions'] = json_encode($promo);
86+
$args['amount'] = $rawAmount;
87+
88+
$invalidDiscountAmount = $order->getBaseDiscountAmount();
89+
$order->setBaseDiscountAmount(0);
90+
$order->setBaseGrandTotal($order->getBaseGrandTotal() - $invalidDiscountAmount);
91+
92+
$invalidDiscountAmount = $order->getDiscountAmount();
93+
$order->setDiscountAmount(0);
94+
$order->setGrandTotal($order->getGrandTotal() - $invalidDiscountAmount);
95+
96+
$order->setBaseTotalDue($order->getBaseGrandTotal());
97+
$order->setTotalDue($order->getGrandTotal());
98+
99+
$payment->setBaseAmountOrdered($order->getBaseGrandTotal());
100+
$payment->setAmountOrdered($order->getGrandTotal());
101+
102+
$payment->setAmountAuthorized($order->getGrandTotal());
103+
$payment->setBaseAmountAuthorized($order->getBaseGrandTotal());
104+
}
105+
106+
$hostedPayment = $this->requestHostedPayment($args);
107+
108+
if (isset($hostedPayment['error_code'])) {
109+
$message = isset($hostedPayment['message']) ? $hostedPayment['message'] : $hostedPayment['error_code'];
110+
$this->processFailedPayment($payment, $message);
111+
112+
throw new \Magento\Framework\Exception\LocalizedException(
113+
new Phrase($message)
114+
);
115+
} elseif (isset($hostedPayment['id'])) {
116+
$hostedPaymentId = $hostedPayment['id'];
117+
$hostedPaymentToken = $hostedPayment['hp_token'];
118+
119+
$payment->setAdditionalInformation('xendit_hosted_payment_id', $hostedPaymentId);
120+
$payment->setAdditionalInformation('xendit_hosted_payment_token', $hostedPaymentToken);
121+
} else {
122+
$message = 'Error connecting to Xendit. Check your API key';
123+
$this->processFailedPayment($payment, $message);
124+
125+
throw new \Magento\Framework\Exception\LocalizedException(
126+
new Phrase($message)
127+
);
128+
}
129+
} catch (\Exception $e) {
130+
$errorMsg = $e->getMessage();
131+
throw new \Magento\Framework\Exception\LocalizedException(
132+
new Phrase($errorMsg)
133+
);
134+
}
135+
136+
return $this;
137+
}
138+
}

Xendit/M2Invoice/Model/Ui/ConfigProvider.php

+5-2
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,20 @@ public function __construct(
2828

2929
public function getConfig()
3030
{
31+
$defaultCCInstallmentDesc = "Bayar pesanan dengan cicilan kartu kredit anda melalui Xendit.\r\nBank yang tersedia: BCA, BRI";
32+
3133
$config = [
3234
'payment' => [
3335
Config::CODE => [
3436
'xendit_env' => $this->m2Invoice->getConfigData('xendit_env'),
3537
'test_prefix' => $this->m2Invoice->getConfigData('checkout_test_prefix'),
3638
'test_content' => $this->m2Invoice->getConfigData('checkout_test_content'),
3739
'public_api_key' => $this->m2Invoice->getPublicApiKey(),
38-
'availableTypes' => ['cc' => $this->ccConfig->getCcAvailableTypes()],
40+
'available_types' => ['cc' => $this->ccConfig->getCcAvailableTypes()],
3941
'months' => ['cc' => $this->ccConfig->getCcMonths()],
4042
'years' => ['cc' => $this->ccConfig->getCcYears()],
41-
'hasVerification' => $this->ccConfig->hasVerification()
43+
'has_verification' => $this->ccConfig->hasVerification(),
44+
'card_installment_description' => ($this->m2Invoice->getConfigData('card_installment_description') ?: $defaultCCInstallmentDesc)
4245
]
4346
]
4447
];

Xendit/M2Invoice/composer.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "xendit/m2invoice",
33
"description": "Xendit Payment Gateway Module",
44
"type": "magento2-module",
5-
"version": "2.0.1",
5+
"version": "2.1.0",
66
"license": [
77
"GPL-3.0"
88
],

Xendit/M2Invoice/etc/adminhtml/system.xml

+14-7
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@
102102
dynamicShow();
103103
shouldEnableSpecificMethod();
104104
specificSelection.prop('size', 6);
105+
jQuery("textarea[id*='m2invoice_card_installment_description']").attr("placeholder", "Bayar pesanan dengan cicilan kartu kredit anda melalui Xendit.\nBank yang tersedia: BCA, BRI");
106+
jQuery("textarea[id*='m2invoice_card_installment_description']").val("Bayar pesanan dengan cicilan kartu kredit anda melalui Xendit.\nBank yang tersedia: BCA, BRI");
105107
});
106108
</script>
107109
]]></comment>
@@ -113,38 +115,38 @@
113115
<label>Payment Mode</label>
114116
<source_model>Xendit\M2Invoice\Model\Adminhtml\Source\EnvRadioBtn</source_model>
115117
<comment>
116-
Choose live to have live transaction
118+
Choose live to perform real transaction
117119
</comment>
118120
<attribute type="shared">1</attribute>
119121
</field>
120122
<field id="test_public_key" translate="label" type="obscure" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="0">
121123
<label>Test - Public Key</label>
122124
<comment>
123-
Public API key that provided by Xendit Dashboard
125+
Public API key provided by Xendit Dashboard
124126
</comment>
125127
<attribute type="shared">1</attribute>
126128
<backend_model>Magento\Config\Model\Config\Backend\Encrypted</backend_model>
127129
</field>
128130
<field id="test_private_key" translate="label" type="obscure" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="0">
129131
<label>Test - Private Key</label>
130132
<comment>
131-
Secret API key that provided by Xendit Dashboard
133+
Secret API key provided by Xendit Dashboard
132134
</comment>
133135
<attribute type="shared">1</attribute>
134136
<backend_model>Magento\Config\Model\Config\Backend\Encrypted</backend_model>
135137
</field>
136138
<field id="public_key" translate="label" type="obscure" sortOrder="50" showInDefault="1" showInWebsite="1" showInStore="0">
137139
<label>Public Key</label>
138140
<comment>
139-
Public API key that provided by Xendit Dashboard
141+
Public API key provided by Xendit Dashboard
140142
</comment>
141143
<attribute type="shared">1</attribute>
142144
<backend_model>Magento\Config\Model\Config\Backend\Encrypted</backend_model>
143145
</field>
144146
<field id="private_key" translate="label" type="obscure" sortOrder="60" showInDefault="1" showInWebsite="1" showInStore="0">
145147
<label>Private Key</label>
146148
<comment>
147-
Secret API key that provided by Xendit Dashboard
149+
Secret API key provided by Xendit Dashboard
148150
</comment>
149151
<attribute type="shared">1</attribute>
150152
<backend_model>Magento\Config\Model\Config\Backend\Encrypted</backend_model>
@@ -156,7 +158,7 @@
156158
</comment>
157159
<source_model>Xendit\M2Invoice\Model\Adminhtml\Source\AllowedMethod</source_model>
158160
</field>
159-
<field id="chosen_methods" translate="label" type="multiselect" size="6" sortOrder="66" showInDefault="1" showInWebsite="1" showInStore="0">
161+
<field id="chosen_methods" translate="label" type="multiselect" sortOrder="66" showInDefault="1" showInWebsite="1" showInStore="0">
160162
<label>Specific Payment Method</label>
161163
<comment>
162164
Use all payment method that is provided by Xendit
@@ -167,11 +169,16 @@
167169
<field id="card_payment_type" translate="label" type="select" sortOrder="70" showInDefault="1" showInWebsite="1" showInStore="0">
168170
<label>Card Payment Type</label>
169171
<comment>
170-
Xendit provide card form to increase your order payment
172+
Choose popup if you don't want to hold sensitive card data on your site
171173
</comment>
172174
<source_model>Xendit\M2Invoice\Model\Adminhtml\Source\CardPaymentType</source_model>
173175
<attribute type="shared">1</attribute>
174176
</field>
177+
<field id="card_installment_description" translate="label" type="textarea" sortOrder="80" showInDefault="1" showInWebsite="1" showInStore="1">
178+
<label>Credit Card Installment Description</label>
179+
<comment>Customize your installment payment description on checkout page</comment>
180+
</field>
181+
175182
<group id="card_promo_bca" translate="label" showInDefault="1" showInWebsite="1" sortOrder="100">
176183
<label>Credit Card Promotion - BCA</label>
177184
<field id="card_promo_bca_active" translate="label comment" sortOrder="101" type="select" showInDefault="1" showInWebsite="1" showInStore="0">

0 commit comments

Comments
 (0)