Payment_Adaptive_Simple::execute_payment()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 0
cts 2
cp 0
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 2
1
<?php
2
3
namespace OpenBuildings\PayPal;
4
5
/**
6
 * Simple payments
7
 * 
8
 * @author Haralan Dobrev <[email protected]>
9
 * @copyright 2013 OpenBuildings, Inc.
10
 * @license http://spdx.org/licenses/BSD-3-Clause
11
 */
12
class Payment_Adaptive_Simple extends Payment_Adaptive {
13
	
14
	const WEBAPPS_ENDPOINT_END = 'paypal.com/webapps/adaptivepayment/flow/pay';
15
16
	const API_OPERATION_PAY = 'Pay';
17
18
	const API_OPERATION_EXECUTE_PAYMENT = 'ExecutePayment';
19
20
	/**
21
	 * Use this option if you are not using the Pay request
22
	 * in combination with ExecutePayment
23
	 */
24
	const ACTION_TYPE_PAY = 'PAY';
25
26
	/**
27
	 *  Use this option to set up the payment instructions with SetPaymentOptions
28
	 *  and then execute the payment at a later time with the ExecutePayment.
29
	 */
30
	const ACTION_TYPE_CREATE = 'CREATE';
31
32
	/**
33
	 * For chained payments only, specify this value to delay payments to
34
	 * the secondary receivers.
35
	 * Only the payment to the primary receiver is processed.
36
	 */
37
	const ACTION_TYPE_PAY_PRIMARY = 'PAY_PRIMARY';
38
39
	/**
40
	 * Sender pays all fees (for personal, implicit simple/parallel payments; do not use for chained or unilateral payments)
41
	 */
42
	const FEES_PAYER_SENDER = 'SENDER';
43
44
	/**
45
	 * Primary receiver pays all fees (chained payments only)
46
	 */
47
	const FEES_PAYER_PRIMARYRECEIVER = 'PRIMARYRECEIVER';
48
49
	/**
50
	 * Each receiver pays their own fee (default, personal and unilateral payments)
51
	 */
52
	const FEES_PAYER_EACHRECEIVER = 'EACHRECEIVER';
53
54
	/**
55
	 * Secondary receivers pay all fees
56
	 * (use only for chained payments with one secondary receiver)
57
	 */
58
	const FEES_PAYER_SECONDARYONLY = 'SECONDARYONLY';
59
60
	// This is a payment for non-digital goods
61
	const PAYMENT_TYPE_GOODS = 'GOODS';
62
63
	// This is a payment for services (default)
64
	const PAYMENT_TYPE_SERVICE = 'SERVICE';
65
66
	// This is a person-to-person payment
67
	// Person-to-person payments are valid only for parallel payments
68
	// that have the feesPayer field set to EACHRECEIVER or SENDER
69
	const PAYMENT_TYPE_PERSONAL = 'PERSONAL';
70
71
	// This is a person-to-person payment for a cash advance
72
	const PAYMENT_TYPE_CASHADVANCE = 'CASHADVANCE';
73
74
	// This is a payment for digital goods
75
	const PAYMENT_TYPE_DIGITALGOODS = 'DIGITALGOODS';
76
77
	// This is a person-to-person payment for bank withdrawals,
78
	// available only with special permission
79
	const PAYMENT_TYPE_BANK_MANAGED_WITHDRAWAL = 'BANK_MANAGED_WITHDRAWAL';
80
81
	protected static $_allowed_action_types = array(
82
		self::ACTION_TYPE_PAY,
83
		self::ACTION_TYPE_CREATE,
84
	);
85
86
	protected static $_allowed_fees_payer_types = array(
87
		self::FEES_PAYER_SENDER,
88
		self::FEES_PAYER_PRIMARYRECEIVER,
89
		self::FEES_PAYER_EACHRECEIVER,
90
	);
91
92
	protected static $_allowed_payment_types = array(
93
		self::PAYMENT_TYPE_GOODS,
94
		self::PAYMENT_TYPE_SERVICE,
95
		self::PAYMENT_TYPE_SERVICE,
96
		self::PAYMENT_TYPE_PERSONAL,
97
		self::PAYMENT_TYPE_CASHADVANCE,
98
		self::PAYMENT_TYPE_DIGITALGOODS,
99
		self::PAYMENT_TYPE_BANK_MANAGED_WITHDRAWAL,
100
	);
101
102 1
	public static function approve_url($pay_key, $mobile = FALSE)
103
	{
104 1
		if ($mobile)
105 1
			return static::webapps_url(array(
106 1
				'paykey' => $pay_key
107 1
			), TRUE);
108
109 1
		return Payment::webscr_url('_ap-payment', array(
0 ignored issues
show
Documentation introduced by
'_ap-payment' is of type string, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
110 1
			'paykey' => $pay_key
111
		));
112
	}
113
114
	protected $_implicit_approval = FALSE;
115
116
	protected $_action_type = 'PAY';
117
118
	/**
119
	 * Get the NVP fields array fusion from the order and the configuration
120
	 * @return array
121
	 */
122 4
	public function fields()
123
	{
124 4
		$order = $this->order();
125
126
		$fields = array(
127 4
			'returnUrl' => $this->return_url(),
128 4
			'cancelUrl' => $this->cancel_url(),
129 4
			'actionType' => $this->action_type(),
130 4
			'currencyCode' => $this->config('currency'),
131 4
			'reverseAllParallelPaymentsOnError' => $this->config('reverse_on_error')
132
				? 'true'
133 4
				: 'false'
134
		);
135
136
		// Backwards compatibility: you can set a "receiver" field
137
		// for a single receiver
138 4
		if (isset($order['receiver']))
139
		{
140 4
			$order['receivers'] = array($order['receiver']);
141
		}
142
143 4
		$fields['receiverList'] = Util::receiver_list($order['receivers'], $this instanceof Payment_Adaptive_Chained);
144
145 4
		if ($this->implicit_approval())
146
		{
147 1
			if (($sender_email = $this->config('email')))
148
			{
149 1
				$fields['senderEmail'] = $sender_email;
150
			}
151
			elseif (($sender_account_id = $this->config('accountId')))
152
			{
153
				$fields['sender']['accountId'] = $sender_account_id;
154
			}
155
		}
156
157 4
		if ( ! in_array($this->config('fees_payer'), self::$_allowed_fees_payer_types))
158 1
			throw new Exception('Fees payer type ":feesPayer" is not allowed!', array(
159 1
				':feesPayer' => $this->config('fees_payer')
160
			));
161
162 3
		$fields['feesPayer'] = $this->config('fees_payer');
163
164 3
		if ( ! empty($order['order_number']))
165
		{
166 1
			$fields['trackingId'] = $order['order_number'];
167
		}
168
169 3
		if ($this->notify_url())
170
		{
171 2
			$fields['ipnNotificationUrl'] = $this->notify_url();
172
		}
173
174 3
		$fields = $this->_set_payment_type($fields);
175
176 3
		return $fields;
177
	}
178
179
	protected function _set_payment_type(array $fields)
180
	{
181
		$payment_type = $this->config('payment_type');
182
183
		if (isset($payment_type['secondary']))
184
		{
185
			$payment_type = $payment_type['secondary'];
186
		}
187
		elseif ( ! $payment_type AND ! is_string($payment_type))
188
		{
189
			return $fields;
190
		}
191
192
		foreach ($fields['receiverList'] as $index => $receiver)
193
		{
194
			$fields['receiverList'][$index]['paymentType'] = $payment_type;
195
		}
196
197
		return $fields;
198
	}
199
200
	/**
201
	 * Get or set whether this is an implicitly approved payment
202
	 *
203
	 * @param  boolean $implicit_approval
204
	 * @return boolean|$this
205
	 */
206 1
	public function implicit_approval($implicit_approval = NULL)
207
	{
208 1
		if ($implicit_approval === NULL)
209 1
			return $this->_implicit_approval;
210
211 1
		$this->_implicit_approval = (bool) $implicit_approval;
212
213 1
		return $this;
214
	}
215
216
	/**
217
	 * Get or set the action type
218
	 *
219
	 * @param  string $action_type See Payment_Adaptive::$_allowed_action_types
220
	 * @return string|$this
221
	 */
222 1
	public function action_type($action_type = NULL)
223
	{
224 1
		if ($action_type === NULL)
225 1
			return $this->_action_type;
226
227 1
		$this->_action_type = $action_type;
228
229 1
		return $this;
230
	}
231
232
	public function do_payment()
233
	{
234
		$fields = $this->fields();
235
236
		if ( ! empty($fields['receiverList']))
237
		{
238
			$receiver_list = Util::array_to_nvp($fields, 'receiverList', 'receiver');
239
			unset($fields['receiverList']);
240
			$fields = array_merge_recursive($fields, $receiver_list);
241
		}
242
243
		return $this->pay($fields);
244
	}
245
246
	/**
247
	 * Perform low-level Pay API request.
248
	 */
249
	public function pay($data)
250
	{
251
		return $this->_request(self::API_OPERATION_PAY, $data);
252
	}
253
254
	/**
255
	 * Perform a low-level ExecutePayment API request.
256
	 */
257
	public function execute_payment($data)
258
	{
259
		return $this->_request(self::API_OPERATION_EXECUTE_PAYMENT, $data);
260
	}
261
}
262