1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Never5\DownloadMonitor\Shop\Ajax; |
4
|
|
|
|
5
|
|
|
use Never5\DownloadMonitor\Shop\Order; |
6
|
|
|
use Never5\DownloadMonitor\Shop\Services\Services; |
7
|
|
|
|
8
|
|
|
class PlaceOrder extends Ajax { |
9
|
|
|
|
10
|
|
|
/** |
11
|
|
|
* Constructor |
12
|
|
|
*/ |
13
|
|
|
public function __construct() { |
14
|
|
|
parent::__construct( 'place_order' ); |
15
|
|
|
} |
16
|
|
|
|
17
|
|
|
/** |
18
|
|
|
* Calling this method will return a negative success to the browser |
19
|
|
|
* |
20
|
|
|
* @param string $error_message |
21
|
|
|
*/ |
22
|
|
|
private function failed( $error_message ) { |
23
|
|
|
wp_send_json( array( 'success' => false, 'error' => $error_message ) ); |
|
|
|
|
24
|
|
|
exit; |
|
|
|
|
25
|
|
|
} |
26
|
|
|
|
27
|
|
|
/** |
28
|
|
|
* Parse and complete raw customer post data |
29
|
|
|
* |
30
|
|
|
* @return array |
31
|
|
|
*/ |
32
|
|
|
private function parse_customer_post_data() { |
33
|
|
|
return array( |
34
|
|
|
'first_name' => isset( $_POST['customer']['first_name'] ) ? $_POST['customer']['first_name'] : '', |
35
|
|
|
'last_name' => isset( $_POST['customer']['last_name'] ) ? $_POST['customer']['last_name'] : '', |
36
|
|
|
'company' => isset( $_POST['customer']['company'] ) ? $_POST['customer']['company'] : '', |
37
|
|
|
'email' => isset( $_POST['customer']['email'] ) ? $_POST['customer']['email'] : '', |
38
|
|
|
'address_1' => isset( $_POST['customer']['address_1'] ) ? $_POST['customer']['address_1'] : '', |
39
|
|
|
'address_2' => isset( $_POST['customer']['address_2'] ) ? $_POST['customer']['address_2'] : '', |
40
|
|
|
'postcode' => isset( $_POST['customer']['postcode'] ) ? $_POST['customer']['postcode'] : '', |
41
|
|
|
'city' => isset( $_POST['customer']['city'] ) ? $_POST['customer']['city'] : '', |
42
|
|
|
'state' => isset( $_POST['customer']['state'] ) ? $_POST['customer']['state'] : '', |
43
|
|
|
'country' => isset( $_POST['customer']['country'] ) ? $_POST['customer']['country'] : '', |
44
|
|
|
'phone' => isset( $_POST['customer']['phone'] ) ? $_POST['customer']['phone'] : '', |
45
|
|
|
'ip_address' => isset( $_SERVER['REMOTE_ADDR'] ) ? $_SERVER['REMOTE_ADDR'] : '' |
46
|
|
|
); |
47
|
|
|
} |
48
|
|
|
|
49
|
|
|
/** |
50
|
|
|
* @param bool $success |
51
|
|
|
* @param string $redirect |
52
|
|
|
* @param string $error |
53
|
|
|
*/ |
54
|
|
|
private function response( $success, $redirect, $error ) { |
55
|
|
|
wp_send_json( array( 'success' => $success, 'redirect' => $redirect, 'error' => $error ) ); |
|
|
|
|
56
|
|
|
exit; |
|
|
|
|
57
|
|
|
} |
58
|
|
|
|
59
|
|
|
/** |
60
|
|
|
* AJAX callback method |
61
|
|
|
* |
62
|
|
|
* @return void |
63
|
|
|
*/ |
64
|
|
|
public function run() { |
65
|
|
|
|
66
|
|
|
// check nonce |
67
|
|
|
$this->check_nonce(); |
68
|
|
|
|
69
|
|
|
// |
70
|
|
|
$customer_post = $this->parse_customer_post_data(); |
71
|
|
|
|
72
|
|
|
// get gateway |
73
|
|
|
$enabled_gateways = Services::get()->service( 'payment_gateway' )->get_enabled_gateways(); |
74
|
|
|
|
75
|
|
|
/** @var \Never5\DownloadMonitor\Shop\Checkout\PaymentGateway\PaymentGateway $gateway */ |
76
|
|
|
$gateway = ( isset( $_POST['payment_gateway'] ) && isset( $enabled_gateways[ $_POST['payment_gateway'] ] ) ? $enabled_gateways[ $_POST['payment_gateway'] ] : null ); |
77
|
|
|
|
78
|
|
|
/** |
79
|
|
|
* Check if all required fields are set |
80
|
|
|
*/ |
81
|
|
|
$required_fields = Services::get()->service( 'checkout_field' )->get_required_fields(); |
82
|
|
|
foreach ( $required_fields as $required_field ) { |
83
|
|
|
if ( ! isset( $customer_post[ $required_field ] ) || $customer_post[ $required_field ] === "" ) { |
84
|
|
|
$this->failed( __( 'Not all required fields are set', 'download-monitor' ) ); |
|
|
|
|
85
|
|
|
} |
86
|
|
|
} |
87
|
|
|
|
88
|
|
|
// check if gateway is valid |
89
|
|
|
if ( is_null( $gateway ) ) { |
90
|
|
|
$this->failed( __( 'Invalid Payment Gateway', 'download-monitor' ) ); |
91
|
|
|
} |
92
|
|
|
|
93
|
|
|
// check if we need to create an order or fetch one based on id and hash |
94
|
|
|
$order_id = absint( ( isset( $_POST['order_id'] ) ) ? $_POST['order_id'] : 0 ); |
|
|
|
|
95
|
|
|
$order_hash = ( isset( $_POST['order_hash'] ) ? $_POST['order_hash'] : '' ); |
96
|
|
|
$order = null; |
97
|
|
|
$is_new_order = true; |
98
|
|
|
|
99
|
|
|
if ( $order_id > 0 && ! empty( $order_hash ) ) { |
100
|
|
|
/** @var \Never5\DownloadMonitor\Shop\Order\WordPressRepository $op */ |
101
|
|
|
try { |
102
|
|
|
$op = Services::get()->service( 'order_repository' ); |
103
|
|
|
$tmp_order = $op->retrieve_single( $order_id ); |
104
|
|
|
|
105
|
|
|
// check order hashes |
106
|
|
|
if ( $order_hash !== $tmp_order->get_hash() ) { |
107
|
|
|
throw new \Exception( 'Order hash incorrect' ); |
108
|
|
|
} |
109
|
|
|
|
110
|
|
|
if ( $tmp_order->get_status()->get_key() !== 'pending-payment' ) { |
111
|
|
|
throw new \Exception( 'Order status not pending payment' ); |
112
|
|
|
} |
113
|
|
|
|
114
|
|
|
$order = $tmp_order; |
115
|
|
|
$is_new_order = false; |
116
|
|
|
|
117
|
|
|
} catch ( \Exception $e ) { |
118
|
|
|
$order = null; |
119
|
|
|
} |
120
|
|
|
} |
121
|
|
|
|
122
|
|
|
// create order if no order is set at this point |
123
|
|
|
if ( null === $order ) { |
124
|
|
|
/** @var Order\Order $order */ |
125
|
|
|
$order = Services::get()->service( 'order_factory' )->make(); |
126
|
|
|
} |
127
|
|
|
|
128
|
|
|
/** |
129
|
|
|
* Create OrderCustomer |
130
|
|
|
*/ |
131
|
|
|
$order->set_customer( new Order\OrderCustomer( |
132
|
|
|
$customer_post['first_name'], |
133
|
|
|
$customer_post['last_name'], |
134
|
|
|
$customer_post['company'], |
135
|
|
|
$customer_post['address_1'], |
136
|
|
|
$customer_post['address_2'], |
137
|
|
|
$customer_post['city'], |
138
|
|
|
$customer_post['state'], |
139
|
|
|
$customer_post['postcode'], |
140
|
|
|
$customer_post['country'], |
141
|
|
|
$customer_post['email'], |
142
|
|
|
$customer_post['phone'], |
143
|
|
|
$customer_post['ip_address'] |
144
|
|
|
) ); |
145
|
|
|
|
146
|
|
|
// build array with order items based on current cart if this is a new order |
147
|
|
|
if ( $is_new_order ) { |
148
|
|
|
$order->set_items( Services::get()->service( 'order' )->build_order_items_from_cart() ); |
149
|
|
|
} |
150
|
|
|
|
151
|
|
|
// persist order |
152
|
|
|
try { |
153
|
|
|
Services::get()->service( 'order_repository' )->persist( $order ); |
154
|
|
|
} catch ( \Exception $exception ) { |
155
|
|
|
$this->response( false, '', $exception->getMessage() ); |
156
|
|
|
} |
157
|
|
|
|
158
|
|
|
// run gateway |
159
|
|
|
$gateway_result = $gateway->process( $order ); |
160
|
|
|
|
161
|
|
|
// exit if gateway was not successful |
162
|
|
|
if ( ! $gateway_result->is_success() ) { |
163
|
|
|
$this->response( false, '', sprintf( __( 'Payment gateway error: %s', 'download-monitor' ), $gateway_result->get_error_message() ) ); |
164
|
|
|
} |
165
|
|
|
|
166
|
|
|
// order is in DB, gateway did what it had to do -> clear the cart |
167
|
|
|
Services::get()->service( 'cart' )->destroy_cart(); |
168
|
|
|
|
169
|
|
|
// we good, send response with redirect |
170
|
|
|
$this->response( true, $gateway_result->get_redirect(), '' ); |
171
|
|
|
|
172
|
|
|
// bye |
173
|
|
|
exit; |
|
|
|
|
174
|
|
|
} |
175
|
|
|
|
176
|
|
|
} |