Skip to content

Commit b2eafce

Browse files
authored
Merge pull request #39 from xendit/bugfix/multishipping
Bugfix/multishipping
2 parents a3968d2 + aa6ddcd commit b2eafce

File tree

13 files changed

+132
-64
lines changed

13 files changed

+132
-64
lines changed

CHANGELOG.md

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

3+
## 2.0.1 (2020-06-11)
4+
5+
Bugfix:
6+
7+
- Support order ID with prefix (single and multishipping)
8+
- Fix OVO callback for single checkout
9+
310
## 2.0.0 (2020-06-01)
411

512
Features:

Xendit/M2Invoice/Controller/Checkout/CCMultishipping.php

+18-15
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ public function execute()
1616
$orderIds = explode("-", $rawOrderIds);
1717

1818
$transactionAmount = 0;
19-
$incrementIds = [];
2019
$tokenId = '';
2120
$orders = [];
2221

@@ -41,42 +40,40 @@ public function execute()
4140
}
4241

4342
$transactionAmount += (int)$order->getTotalDue();
44-
$incrementIds[] = $order->getIncrementId();
4543
}
4644

4745
if ($method === 'cc') {
48-
$externalIdSuffix = implode("-", $incrementIds);
4946
$requestData = array(
5047
'token_id' => $tokenId,
5148
'card_cvn' => $cvn,
5249
'amount' => $transactionAmount,
53-
'external_id' => $this->getDataHelper()->getExternalId($externalIdSuffix),
54-
'return_url' => $this->getDataHelper()->getThreeDSResultUrl($externalIdSuffix)
50+
'external_id' => $this->getDataHelper()->getExternalId($rawOrderIds),
51+
'return_url' => $this->getDataHelper()->getThreeDSResultUrl($rawOrderIds, true)
5552
);
5653

5754
$charge = $this->requestCharge($requestData);
5855

5956
$chargeError = isset($charge['error_code']) ? $charge['error_code'] : null;
6057
if ($chargeError == 'EXTERNAL_ID_ALREADY_USED_ERROR') {
6158
$newRequestData = array_replace($requestData, array(
62-
'external_id' => $this->getDataHelper()->getExternalId($externalIdSuffix, true)
59+
'external_id' => $this->getDataHelper()->getExternalId($rawOrderIds, true)
6360
));
6461
$charge = $this->requestCharge($newRequestData);
6562
}
6663

6764
$chargeError = isset($charge['error_code']) ? $charge['error_code'] : null;
6865
if ($chargeError == 'AUTHENTICATION_ID_MISSING_ERROR') {
69-
return $this->handle3DSFlow($requestData, $payment, $incrementIds, $orders);
66+
return $this->handle3DSFlow($requestData, $payment, $orderIds, $orders);
7067
}
7168

7269
if ($chargeError !== null) {
73-
return $this->processFailedPayment($incrementIds, $chargeError);
70+
return $this->processFailedPayment($orderIds, $chargeError);
7471
}
7572

7673
if ($charge['status'] === 'CAPTURED') {
7774
return $this->processSuccessfulPayment($orders, $payment, $charge);
7875
} else {
79-
return $this->processFailedPayment($incrementIds, $charge['failure_reason']);
76+
return $this->processFailedPayment($orderIds, $charge['failure_reason']);
8077
}
8178
}
8279
else if ($method === 'cchosted') {
@@ -87,7 +84,7 @@ public function execute()
8784
'store_name' => $this->getStoreManager()->getStore()->getName(),
8885
'platform_name' => 'MAGENTO2',
8986
'success_redirect_url' => $this->getDataHelper()->getSuccessUrl(true),
90-
'failure_redirect_url' => $this->getDataHelper()->getFailureUrl($rawOrderIds),
87+
'failure_redirect_url' => $this->getDataHelper()->getFailureUrl($rawOrderIds, true),
9188
'platform_callback_url' => $this->_url->getUrl('xendit/checkout/cccallback') . '?order_ids=' . $rawOrderIds
9289
];
9390

@@ -96,7 +93,7 @@ public function execute()
9693
if (isset($hostedPayment['error_code'])) {
9794
$message = isset($hostedPayment['message']) ? $hostedPayment['message'] : $hostedPayment['error_code'];
9895

99-
return $this->processFailedPayment($incrementIds, $message);
96+
return $this->processFailedPayment($orderIds, $message);
10097
} else if (isset($hostedPayment['id'])) {
10198
$hostedPaymentId = $hostedPayment['id'];
10299
$hostedPaymentToken = $hostedPayment['hp_token'];
@@ -112,7 +109,7 @@ public function execute()
112109
} else {
113110
$message = 'Error connecting to Xendit. Please check your API key.';
114111

115-
return $this->processFailedPayment($incrementIds, $message);
112+
return $this->processFailedPayment($orderIds, $message);
116113
}
117114
}
118115
} catch (\Exception $e) {
@@ -163,6 +160,9 @@ private function addCCHostedData($orders, $data)
163160
}
164161
}
165162

163+
/**
164+
* $orderIds = prefixless order IDs
165+
*/
166166
private function handle3DSFlow($requestData, $payment, $orderIds, $orders)
167167
{
168168
unset($requestData['card_cvn']);
@@ -183,9 +183,9 @@ private function handle3DSFlow($requestData, $payment, $orderIds, $orders)
183183
$payment->setAdditionalInformation('xendit_hosted_3ds_id', $hostedId);
184184

185185
foreach ($orderIds as $key => $value) {
186-
$order = $this->getOrderById($value);
187-
188-
$order->addStatusHistoryComment("Xendit payment waiting for authentication. 3DS id: $hostedId");
186+
$order = $this->getOrderFactory()->create();
187+
$order->load($value);
188+
$order->addStatusHistoryComment("Xendit payment waiting for authentication. 3DS ID: $hostedId");
189189
$order->save();
190190
}
191191

@@ -210,6 +210,9 @@ private function handle3DSFlow($requestData, $payment, $orderIds, $orders)
210210
return $this->processFailedPayment($orderIds);
211211
}
212212

213+
/**
214+
* $orderIds = prefixless order IDs
215+
*/
213216
private function processFailedPayment($orderIds, $failureReason = 'Unexpected Error with empty charge')
214217
{
215218
$this->getCheckoutHelper()->processOrdersFailedPayment($orderIds, $failureReason);

Xendit/M2Invoice/Controller/Checkout/Failure.php

+3-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@ class Failure extends AbstractAction {
66
public function execute()
77
{
88
$orderIds = explode('-', $this->getRequest()->get('order_id'));
9+
$type = $this->getRequest()->get('type');
910

10-
if (count($orderIds) > 1) { //multishipping
11+
if ($type == 'multishipping') {
1112
foreach ($orderIds as $orderId) {
1213
$order = $this->getOrderFactory()->create();
1314
$order ->load($orderId);
@@ -23,7 +24,7 @@ public function execute()
2324
}
2425
}
2526
} else { //onepage
26-
$order = $this->getOrderById($orderIds[0]);
27+
$order = $this->getOrderById($this->getRequest()->get('order_id'));
2728

2829
if ($order) {
2930
$this->getLogger()->debug('Requested order cancelled by customer. OrderId: ' . $order->getIncrementId());

Xendit/M2Invoice/Controller/Checkout/Invoice.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ private function getApiRequestData($order)
5555
return;
5656
}
5757

58-
$orderId = $order->getRealOrderId();
58+
$orderId = $order->getEntityId();
5959
$preferredMethod = $this->getRequest()->getParam('preferred_method');
6060

6161
$requestData = [

Xendit/M2Invoice/Controller/Checkout/InvoiceMultishipping.php

+3-6
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ public function execute()
1717
$orderIds = explode("-", $rawOrderIds);
1818

1919
$transactionAmount = 0;
20-
$incrementIds = [];
2120

2221
$orders = [];
2322
foreach ($orderIds as $key => $value) {
@@ -33,17 +32,15 @@ public function execute()
3332
$order->save();
3433

3534
$transactionAmount += (int)$order->getTotalDue();
36-
$incrementIds[] = $order->getIncrementId();
3735
}
3836

39-
$externalIdSuffix = implode("-", $incrementIds);
4037
$preferredMethod = $this->getRequest()->getParam('preferred_method');
4138
$requestData = [
4239
'success_redirect_url' => $this->getDataHelper()->getSuccessUrl(true),
43-
'failure_redirect_url' => $this->getDataHelper()->getFailureUrl($rawOrderIds),
40+
'failure_redirect_url' => $this->getDataHelper()->getFailureUrl($rawOrderIds, true),
4441
'amount' => $transactionAmount,
45-
'external_id' => $this->getDataHelper()->getExternalId($externalIdSuffix),
46-
'description' => $externalIdSuffix,
42+
'external_id' => $this->getDataHelper()->getExternalId($rawOrderIds),
43+
'description' => $rawOrderIds,
4744
'payer_email' => $billingEmail,
4845
'preferred_method' => $preferredMethod,
4946
'should_send_email' => "true",

Xendit/M2Invoice/Controller/Checkout/Notification.m22.php

+16-6
Original file line numberDiff line numberDiff line change
@@ -83,19 +83,26 @@ public function execute()
8383
return $result;
8484
}
8585

86-
$orderId = $decodedPost['description'];
87-
$transactionId = $decodedPost['id'];
88-
$orderIds = explode("-", $orderId);
89-
90-
$isMultishipping = (count($orderIds) > 1) ? true : false;
9186
if ($isEwallet) {
9287
// default code if API doesn't send failure_code
9388
$failureCode = 'UNKNOWN_ERROR';
9489
if (isset($decodedPost['failure_code'])) {
9590
$failureCode = $decodedPost['failure_code'];
9691
}
92+
93+
$extIdPrefix = $this->dataHelper->getExternalIdPrefix();
94+
$orderId = ltrim($decodedPost['external_id'], $extIdPrefix);
95+
96+
// standalone OVO can only be single checkout
97+
$orderIds = [$orderId];
98+
} else {
99+
$orderId = $decodedPost['description'];
100+
$orderIds = explode("-", $orderId);
97101
}
98102

103+
$transactionId = $decodedPost['id'];
104+
$isMultishipping = (count($orderIds) > 1) ? true : false;
105+
99106
if (!empty($callbackToken)) {
100107
$result = $this->jsonResultFactory->create();
101108
/** You may introduce your own constants for this custom REST API */
@@ -136,7 +143,8 @@ public function execute()
136143
}
137144

138145
private function checkOrder($orderId, $isEwallet, $decodedPost, $invoice, $callbackDescription) {
139-
$order = $this->getOrderById($orderId);
146+
$order = $this->orderFactory->create();
147+
$order->load($orderId);
140148
$transactionId = $decodedPost['id'];
141149

142150
if (!$order) {
@@ -152,6 +160,8 @@ private function checkOrder($orderId, $isEwallet, $decodedPost, $invoice, $callb
152160
}
153161

154162
if ($isEwallet) {
163+
$order = $this->getOrderById($orderId);
164+
155165
if ($order->getState() === Order::STATE_PENDING_PAYMENT || $order->getState() === Order::STATE_PAYMENT_REVIEW) {
156166
//get ewallet payment status
157167
$paymentStatus = $this->getEwalletStatus($decodedPost['ewallet_type'], $decodedPost['external_id']);

Xendit/M2Invoice/Controller/Checkout/Notification.m23.php

+17-7
Original file line numberDiff line numberDiff line change
@@ -93,20 +93,27 @@ public function execute()
9393

9494
return $result;
9595
}
96-
97-
$orderId = $decodedPost['description'];
98-
$transactionId = $decodedPost['id'];
99-
$orderIds = explode("-", $orderId);
100-
101-
$isMultishipping = (count($orderIds) > 1) ? true : false;
96+
10297
if ($isEwallet) {
10398
// default code if API doesn't send failure_code
10499
$failureCode = 'UNKNOWN_ERROR';
105100
if (isset($decodedPost['failure_code'])) {
106101
$failureCode = $decodedPost['failure_code'];
107102
}
103+
104+
$extIdPrefix = $this->dataHelper->getExternalIdPrefix();
105+
$orderId = ltrim($decodedPost['external_id'], $extIdPrefix);
106+
107+
// standalone OVO can only be single checkout
108+
$orderIds = [$orderId];
109+
} else {
110+
$orderId = $decodedPost['description'];
111+
$orderIds = explode("-", $orderId);
108112
}
109113

114+
$transactionId = $decodedPost['id'];
115+
$isMultishipping = (count($orderIds) > 1) ? true : false;
116+
110117
if (!empty($callbackToken)) {
111118
$result = $this->jsonResultFactory->create();
112119
/** You may introduce your own constants for this custom REST API */
@@ -147,7 +154,8 @@ public function execute()
147154
}
148155

149156
private function checkOrder($orderId, $isEwallet, $decodedPost, $invoice, $callbackDescription) {
150-
$order = $this->getOrderById($orderId);
157+
$order = $this->orderFactory->create();
158+
$order->load($orderId);
151159
$transactionId = $decodedPost['id'];
152160

153161
if (!$order) {
@@ -163,6 +171,8 @@ private function checkOrder($orderId, $isEwallet, $decodedPost, $invoice, $callb
163171
}
164172

165173
if ($isEwallet) {
174+
$order = $this->getOrderById($orderId);
175+
166176
if ($order->getState() === Order::STATE_PENDING_PAYMENT || $order->getState() === Order::STATE_PAYMENT_REVIEW) {
167177
//get ewallet payment status
168178
$paymentStatus = $this->getEwalletStatus($decodedPost['ewallet_type'], $decodedPost['external_id']);

Xendit/M2Invoice/Controller/Checkout/ThreeDSResult.php

+32-11
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,32 @@ public function execute()
1111
{
1212
$orderId = $this->getRequest()->get('order_id');
1313
$hosted3DSId = $this->getRequest()->get('hosted_3ds_id');
14+
$isMultishipping = ($this->getRequest()->get('type') == 'multishipping' ? true : false);
1415

15-
$orderIds = explode('-', $orderId);
1616
$orders = [];
17-
18-
foreach ($orderIds as $key => $value) {
19-
$order = $this->getOrderById($value);
17+
$orderIds = [];
18+
19+
if ($isMultishipping) {
20+
$orderIds = explode('-', $orderId);
21+
22+
foreach ($orderIds as $key => $value) {
23+
$order = $this->getOrderFactory()->create();
24+
$order->load($value);
25+
26+
if (!is_object($order)) {
27+
return;
28+
}
29+
30+
if ($order->getState() !== Order::STATE_PENDING_PAYMENT) {
31+
return;
32+
}
33+
34+
$orders[] = $order;
35+
}
36+
} else {
37+
$order = $this->getOrderFactory()->create()->loadByIncrementId($orderId);
38+
$orderId = $order->getId(); //replace increment $orderId with prefixless order ID
39+
$orderIds[] = $orderId;
2040

2141
if (!is_object($order)) {
2242
return;
@@ -43,18 +63,18 @@ public function execute()
4363
$charge = $this->createCharge($hosted3DS, $orderId, true);
4464
}
4565

46-
return $this->processXenditPayment($charge, $orders, $orderIds);
66+
return $this->processXenditPayment($charge, $orders, $orderIds, $isMultishipping);
4767
} catch (\Magento\Framework\Exception\LocalizedException $e) {
4868
$message = 'Exception caught on xendit/checkout/threedsresult: ' . $e->getMessage();
4969
$this->getLogDNA()->log(LogDNALevel::ERROR, $message);
70+
5071
return $this->processFailedPayment($orderIds);
5172
}
5273
}
5374

5475
private function getThreeDSResult($hosted3DSId)
5576
{
56-
$hosted3DSUrl = $this->getDataHelper()->getCheckoutUrl()
57-
. "/payment/xendit/credit-card/hosted-3ds/$hosted3DSId";
77+
$hosted3DSUrl = $this->getDataHelper()->getCheckoutUrl() . "/payment/xendit/credit-card/hosted-3ds/$hosted3DSId";
5878
$hosted3DSMethod = \Zend\Http\Request::METHOD_GET;
5979

6080
try {
@@ -92,7 +112,7 @@ private function createCharge($hosted3DS, $orderId, $duplicate = false)
92112
return $charge;
93113
}
94114

95-
private function processXenditPayment($charge, $orders, $orderIds)
115+
private function processXenditPayment($charge, $orders, $orderIds, $isMultishipping = false)
96116
{
97117
if ($charge['status'] === 'CAPTURED') {
98118
$transactionId = $charge['id'];
@@ -112,14 +132,15 @@ private function processXenditPayment($charge, $orders, $orderIds)
112132
$this->invoiceOrder($order, $transactionId);
113133
}
114134

115-
$isMultishipping = (count($orderIds) > 1);
116-
117-
$this->_redirect($this->getDataHelper()->getSuccessUrl(true));
135+
$this->_redirect($this->getDataHelper()->getSuccessUrl($isMultishipping));
118136
} else {
119137
$this->processFailedPayment($orderIds, $charge['failure_reason']);
120138
}
121139
}
122140

141+
/**
142+
* $orderIds = prefixless order IDs
143+
*/
123144
private function processFailedPayment($orderIds, $failureReason = 'Unexpected Error')
124145
{
125146
$this->getCheckoutHelper()->processOrdersFailedPayment($orderIds, $failureReason);

0 commit comments

Comments
 (0)