Skip to content

Commit 4f38e48

Browse files
Get payment status on thank you page (#124)
1 parent 7231f76 commit 4f38e48

File tree

6 files changed

+189
-76
lines changed

6 files changed

+189
-76
lines changed

.travis.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,14 @@ deploy:
55
provider: releases
66
api_key:
77
secure: EIIa6wnMPvcs5qNtn+ggdC8vJCjAV7JOWGeM1EyFOhonD2vaKdPOC0VQd6ifxA03U87K5SlydFtpdqDMG0GSW71x2wo+ABZO3n/2rtAhnlynW6vJ2TUbqYyAa/O47lugGLp8MZ893jIgSSSZ29MT92Tw5FE9jmUtvSUTfzbi4SeDvaT6Api19IcqzCE5yl9crRnTvLej5wsgaBNDFj1dW9SGQ+pWRw8heLEZxxksysv1MqCCNGuB3htpbHXrdPJfaNKKYIJWZQUh2v0agnUBdCQtCRXkp8qObWbt59cw0dTFlBq6v6ApJy2tNMD7RMSPPDy5Gkffg0nRKyrSBkF4b2t9eKgaLcg9pdpg0r7fnSijS13BXTYpVJX4UqlhQL2s9QBdtK5wpfeUr0042QlWR+VzjP13n2Lxuutz4+0QKBbVKoM2NmS8lHlzDF2pNOqOS0n1Wkc98nYdEPzS5k3iXI16GIcQHSUWKbICHIEEPqC7fK9x2arJfTQu5OoUWvQzwpLNDcD6u9PoI/6jbHT0R8qM+kh6ck15V61xs1o5z+2/8cGyDC16IacSa/hv2KnWHWQTVwVu1TEQAgjw0AAAXpkyGqajEh/9JxrqlAURLr9QNoE9gwfO2bBdFGjKxbUueqY4PdS0lx/8B5UFnEkMtWbKx1cLOTcuU2wQlvBRk/o=
8-
file: pay-by-paynow-pl.zip
8+
file: ./dist/pay-by-paynow-pl.zip
99
skip_cleanup: true
1010
on:
1111
repo: pay-now/paynow-woocommerce
1212
branch: master
1313
tags: true
1414

1515
after_deploy:
16-
- cd ..
1716
- bash ./scripts/deploy_to_wp_svn.sh
1817

1918
script: skip

src/includes/abstract/abstract-wc-gateway-pay-by-paynow-pl.php

Lines changed: 136 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
}
77

88
use Paynow\Exception\PaynowException;
9+
use Paynow\Model\Payment\Status;
910

1011
abstract class WC_Gateway_Pay_By_Paynow_PL extends WC_Payment_Gateway {
1112
protected $payment_method_id;
@@ -260,7 +261,7 @@ public function is_available() {
260261
if ( ! is_admin() ) {
261262
$available = true;
262263
try {
263-
WC_Pay_By_Paynow_PL_Helper::validate_minimum_payment_amount( WC()->cart->total );
264+
WC_Pay_By_Paynow_PL_Helper::validate_minimum_payment_amount( WC_Pay_By_Paynow_PL_Helper::get_payment_amount() );
264265
} catch ( PaynowException $exception ) {
265266
$available = false;
266267
}
@@ -271,8 +272,142 @@ public function is_available() {
271272
return parent::is_available();
272273
}
273274

275+
/**
276+
* @param WC_order $order
277+
* @param string $paymentId
278+
* @param string $notification_status
279+
* @throws Exception
280+
*/
281+
public function process_order_status_change( WC_order $order, string $paymentId, string $notification_status ) {
282+
283+
if ( ! $this->is_correct_status( $order->get_status(), $notification_status ) ) {
284+
throw new Exception( 'Order status transition from '. $order->get_status() . ' to ' . $notification_status .' is incorrect');
285+
}
286+
287+
WC_Pay_By_Paynow_PL_Logger::info( 'Order status transition is correct {orderId={}, paymentId={}, orderStatus={}, paymentStatus={}}', [
288+
WC_Pay_By_Paynow_PL_Helper::get_order_id($order),
289+
$order->get_transaction_id(),
290+
$order->get_status(),
291+
$notification_status
292+
] );
293+
294+
switch ( $notification_status ) {
295+
case Status::STATUS_NEW:
296+
$order->add_order_note( sprintf( __( 'Awaiting payment authorization - %s.', 'pay-by-paynow-pl' ), $order->get_transaction_id() ) );
297+
break;
298+
case Status::STATUS_REJECTED:
299+
$order->update_status( 'failed', sprintf( __( 'Payment has not been authorized by the buyer - %s.', 'pay-by-paynow-pl' ), $order->get_transaction_id() ) );
300+
break;
301+
case Status::STATUS_CONFIRMED:
302+
$order->payment_complete( $paymentId );
303+
$order->add_order_note( sprintf( __( 'Payment has been authorized by the buyer - %s.', 'pay-by-paynow-pl' ), $order->get_transaction_id() ) );
304+
break;
305+
case Status::STATUS_ERROR:
306+
$order->update_status( 'failed', sprintf( __( 'Error occurred during the payment process and the payment could not be completed - %s.', 'pay-by-paynow-pl' ), $order->get_transaction_id() ) );
307+
break;
308+
case Status::STATUS_EXPIRED:
309+
$order->update_status( 'failed', sprintf( __( 'Payment has been expired - %s.', 'pay-by-paynow-pl' ), $order->get_transaction_id() ) );
310+
break;
311+
}
312+
}
313+
314+
/**
315+
* @param $previous_status
316+
* @param $next_status
317+
*
318+
* @return bool
319+
*/
320+
public static function is_correct_status( $previous_status, $next_status ) {
321+
$payment_status_flow = [
322+
'pending' => [
323+
Status::STATUS_NEW,
324+
Status::STATUS_PENDING,
325+
Status::STATUS_ERROR,
326+
Status::STATUS_CONFIRMED,
327+
Status::STATUS_REJECTED,
328+
Status::STATUS_EXPIRED
329+
],
330+
'failed' => [
331+
Status::STATUS_NEW,
332+
Status::STATUS_CONFIRMED,
333+
Status::STATUS_ERROR,
334+
Status::STATUS_REJECTED
335+
]
336+
];
337+
$previous_status_exists = isset( $payment_status_flow[ $previous_status ] );
338+
$is_change_possible = in_array( $next_status, $payment_status_flow[ $previous_status ] );
339+
340+
return $previous_status_exists && $is_change_possible;
341+
}
342+
343+
function redirect_order_received_page(){
344+
345+
if( !is_wc_endpoint_url( 'order-received' ) || empty( $_GET['key'] ) || empty( $_GET['paymentId'] ) || empty( $_GET['paymentStatus'] ) ) {
346+
return;
347+
}
348+
349+
$order_id = wc_get_order_id_by_order_key( $_GET['key'] );
350+
$order = wc_get_order( $order_id );
351+
352+
if( WC_Pay_By_Paynow_PL_Helper::is_paynow_order( $order )) {
353+
$paymentId = $order->get_transaction_id();
354+
try {
355+
$status = $this->gateway->payment_status( $paymentId )->getStatus();
356+
WC_Pay_By_Paynow_PL_Logger::info( 'Received payment status from API {orderId={}, paymentId={}, status={}}', [
357+
$order->get_id(),
358+
$paymentId,
359+
$status
360+
] );
361+
if ( ! $order->has_status( wc_get_is_paid_statuses() ) && $order->get_transaction_id() === $paymentId ) {
362+
$this->process_order_status_change( $order, $paymentId, $status );
363+
} else {
364+
WC_Pay_By_Paynow_PL_Logger::info( 'Order has one of paid statuses. Skipped notification processing {orderId={}, orderStatus={}, payment={}}', [
365+
$order->get_id(),
366+
$order->get_status(),
367+
$paymentId
368+
] );
369+
}
370+
} catch ( Exception $exception ) {
371+
WC_Pay_By_Paynow_PL_Logger::error(
372+
$exception->getMessage() . ' {orderId={}, paymentId={}}',
373+
[
374+
$order_id,
375+
$paymentId
376+
]
377+
);
378+
exit();
379+
}
380+
wp_redirect( $order->get_checkout_order_received_url() );
381+
exit();
382+
}
383+
return;
384+
}
385+
386+
function allow_payment_without_login( $allcaps, $caps, $args ) {
387+
if ( !isset( $caps[0] ) || $caps[0] != 'pay_for_order' )
388+
return $allcaps;
389+
if ( !isset( $_GET['key'] ) )
390+
return $allcaps;
391+
392+
$order = wc_get_order( $args[2] );
393+
if( !$order ){
394+
return $allcaps;
395+
}
396+
397+
$order_key = $order->get_order_key();
398+
$order_key_check = $_GET['key'];
399+
400+
if( $order_key == $order_key_check && WC_Pay_By_Paynow_PL_Helper::is_paynow_order($order) ){
401+
$allcaps['pay_for_order'] = true;
402+
}
403+
404+
return $allcaps;
405+
}
406+
274407
protected function hooks() {
275408
add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, [ $this, 'process_admin_options' ] );
409+
add_action( 'template_redirect', [$this, 'redirect_order_received_page'] );
410+
add_filter( 'user_has_cap', [$this, 'allow_payment_without_login' ], 10, 3 );
276411
}
277412

278413
private function get_api_option_key_name() {

src/includes/class-pay-by-paynow-pl-manager.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ public function __construct() {
1818
add_action( 'plugins_loaded', [ $this, 'plugins_loaded' ], 10 );
1919
add_action( 'woocommerce_init', [ $this, 'woocommerce_dependencies' ] );
2020
add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_admin_scripts' ] );
21-
}
21+
}
2222

2323
public function plugins_loaded() {
2424
load_plugin_textdomain( 'pay-by-paynow-pl', false, dirname( plugin_basename( __FILE__ ) ) . '/../languages' );
@@ -54,7 +54,6 @@ public function enqueue_admin_scripts($hook)
5454
wp_enqueue_script( 'settings', WC_PAY_BY_PAYNOW_PL_PLUGIN_ASSETS . 'js/settings.js', ['jquery'], wc_pay_by_paynow_pl_plugin_version() );
5555
}
5656

57-
5857
public function payment_gateways() {
5958
return $this->payment_gateways;
6059
}

src/includes/class-paynow-gateway.php

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,20 @@ public function payment_methods() {
164164
}
165165
$payment = new Payment( $this->client );
166166

167-
return $payment->getPaymentMethods( get_woocommerce_currency(), WC_Pay_By_Paynow_PL_Helper::get_amount( WC()->cart->total ) );
167+
return $payment->getPaymentMethods( get_woocommerce_currency(), WC_Pay_By_Paynow_PL_Helper::get_amount( WC_Pay_By_Paynow_PL_Helper::get_payment_amount() ) );
168168
}
169+
170+
/**
171+
* @param $payment_id
172+
* @return \Paynow\Response\Payment\Status|void
173+
* @throws PaynowException
174+
*/
175+
public function payment_status( $payment_id ) {
176+
if ( ! $this->client ) {
177+
return;
178+
}
179+
$payment = new Payment( $this->client );
180+
181+
return $payment->status( $payment_id );
182+
}
169183
}

src/includes/class-wc-pay-by-paynow-pl-helper.php

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
defined( 'ABSPATH' ) || exit();
33

44
use Paynow\Exception\PaynowException;
5+
use Paynow\Model\Payment\Status;
56

67
/**
78
* Provides static methods as helpers.
@@ -101,4 +102,38 @@ public static function get_product_categories( $product_id ) {
101102

102103
return implode( ', ', $categories );
103104
}
105+
106+
/**
107+
* @return int
108+
*/
109+
public static function get_payment_amount() {
110+
$amount = 0;
111+
112+
//checkout page
113+
if ( isset(WC()->cart) ) {
114+
$amount = WC()->cart->total;
115+
}
116+
117+
//order-pay page
118+
if ( get_query_var('order-pay') ) {
119+
$order = new WC_Order(get_query_var('order-pay'));
120+
$amount = $order->get_total();
121+
}
122+
123+
return $amount;
124+
}
125+
126+
/**
127+
* @param $order
128+
* @return bool
129+
*/
130+
public static function is_paynow_order( $order ) {
131+
if( WC_Pay_By_Paynow_PL_Helper::is_old_wc_version() ){
132+
$paymentMethod = get_post_meta( $order->id, '_payment_method', true );
133+
} else {
134+
$paymentMethod = $order->get_payment_method();
135+
}
136+
137+
return str_contains($paymentMethod, WC_PAY_BY_PAYNOW_PL_PLUGIN_PREFIX );
138+
}
104139
}

src/includes/class-wc-pay-by-paynow-pl-notification-handler.php

Lines changed: 1 addition & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ public function handle_notification() {
5555
}
5656

5757
if ( ! $order->has_status( wc_get_is_paid_statuses() ) && $order->get_transaction_id() === $notification_data['paymentId'] ) {
58-
$this->process_notification( $order, $notification_data );
58+
$this->process_order_status_change( $order, $notification_data['paymentId'], $notification_data['status'] );
5959
} else {
6060
WC_Pay_By_Paynow_PL_Logger::info( 'Order has one of paid statuses. Skipped notification processing {orderId={}, orderStatus={}, payment={}}', [
6161
$notification_data['externalId'],
@@ -78,75 +78,6 @@ public function handle_notification() {
7878
status_header( 202 );
7979
exit;
8080
}
81-
82-
/**
83-
* @param WC_order $order
84-
* @param array $notification_data
85-
*
86-
* @throws Exception
87-
*/
88-
private function process_notification( WC_order $order, array $notification_data ) {
89-
$notification_status = $notification_data['status'];
90-
91-
if ( ! $this->is_correct_status( $order->get_status(), $notification_status ) ) {
92-
throw new Exception( 'Order status transition from '. $order->get_status() . ' to ' . $notification_status .' is incorrect');
93-
}
94-
95-
WC_Pay_By_Paynow_PL_Logger::info( 'Order status transition is correct {orderId={}, paymentId={}, orderStatus={}, paymentStatus={}}', [
96-
$notification_data['externalId'],
97-
$order->get_transaction_id(),
98-
$order->get_status(),
99-
$notification_status
100-
] );
101-
102-
switch ( $notification_status ) {
103-
case Status::STATUS_NEW:
104-
$order->add_order_note( sprintf( __( 'Awaiting payment authorization - %s.', 'pay-by-paynow-pl' ), $order->get_transaction_id() ) );
105-
break;
106-
case Status::STATUS_REJECTED:
107-
$order->update_status( 'failed', sprintf( __( 'Payment has not been authorized by the buyer - %s.', 'pay-by-paynow-pl' ), $order->get_transaction_id() ) );
108-
break;
109-
case Status::STATUS_CONFIRMED:
110-
$order->payment_complete( $notification_data['paymentId'] );
111-
$order->add_order_note( sprintf( __( 'Payment has been authorized by the buyer - %s.', 'pay-by-paynow-pl' ), $order->get_transaction_id() ) );
112-
break;
113-
case Status::STATUS_ERROR:
114-
$order->update_status( 'failed', sprintf( __( 'Error occurred during the payment process and the payment could not be completed - %s.', 'pay-by-paynow-pl' ), $order->get_transaction_id() ) );
115-
break;
116-
case Status::STATUS_EXPIRED:
117-
$order->update_status( 'failed', sprintf( __( 'Payment has been expired - %s.', 'pay-by-paynow-pl' ), $order->get_transaction_id() ) );
118-
break;
119-
}
120-
}
121-
122-
/**
123-
* @param $previous_status
124-
* @param $next_status
125-
*
126-
* @return bool
127-
*/
128-
private function is_correct_status( $previous_status, $next_status ) {
129-
$payment_status_flow = [
130-
'pending' => [
131-
Status::STATUS_NEW,
132-
Status::STATUS_PENDING,
133-
Status::STATUS_ERROR,
134-
Status::STATUS_CONFIRMED,
135-
Status::STATUS_REJECTED,
136-
Status::STATUS_EXPIRED
137-
],
138-
'failed' => [
139-
Status::STATUS_NEW,
140-
Status::STATUS_CONFIRMED,
141-
Status::STATUS_ERROR,
142-
Status::STATUS_REJECTED
143-
]
144-
];
145-
$previous_status_exists = isset( $payment_status_flow[ $previous_status ] );
146-
$is_change_possible = in_array( $next_status, $payment_status_flow[ $previous_status ] );
147-
148-
return $previous_status_exists && $is_change_possible;
149-
}
15081
}
15182

15283
new WC_Gateway_Pay_By_Paynow_PL_Notification_Handler();

0 commit comments

Comments
 (0)