55 */
66namespace Omnipay \Stripe \Message ;
77
8+ use Money \Formatter \DecimalMoneyFormatter ;
9+ use Omnipay \Common \Exception \InvalidRequestException ;
810use Omnipay \Common \ItemBag ;
11+ use Omnipay \Stripe \StripeItem ;
912use Omnipay \Stripe \StripeItemBag ;
10- use Money \Formatter \DecimalMoneyFormatter ;
1113
1214/**
1315 * Stripe Authorize Request.
@@ -155,7 +157,7 @@ public function setOnBehalfOf($value)
155157
156158 /**
157159 * @return string
158- * @throws \Omnipay\Common\Exception\ InvalidRequestException
160+ * @throws InvalidRequestException
159161 */
160162 public function getApplicationFee ()
161163 {
@@ -174,7 +176,7 @@ public function getApplicationFee()
174176 * Get the payment amount as an integer.
175177 *
176178 * @return integer
177- * @throws \Omnipay\Common\Exception\ InvalidRequestException
179+ * @throws InvalidRequestException
178180 */
179181 public function getApplicationFeeInteger ()
180182 {
@@ -231,7 +233,7 @@ public function setReceiptEmail($email)
231233 /**
232234 * A list of items in this order
233235 *
234- * @return ItemBag |null A bag containing items in this order
236+ * @return StripeItemBag|StripeItem[] |null A bag containing items in this order
235237 */
236238 public function getItems ()
237239 {
@@ -242,6 +244,7 @@ public function getItems()
242244 * Set the items in this order
243245 *
244246 * @param array $items An array of items in this order
247+ * @return AuthorizeRequest
245248 */
246249 public function setItems ($ items )
247250 {
@@ -265,11 +268,40 @@ public function getData()
265268 $ data ['capture ' ] = 'false ' ;
266269
267270 if ($ items = $ this ->getItems ()) {
268- $ itemDescriptions = [];
269- foreach ($ items as $ n => $ item ) {
270- $ itemDescriptions [] = $ item ->getDescription ();
271+ if (empty ($ this ->getDescription ())) {
272+ $ itemDescriptions = [];
273+ foreach ($ items as $ n => $ item ) {
274+ $ itemDescriptions [] = $ item ->getDescription ();
275+ }
276+ $ data ['description ' ] = implode (" + " , $ itemDescriptions );
277+ }
278+
279+ if ($ this ->validateLineItemsForLevel3 ($ items )) {
280+ $ lineItems = [];
281+ foreach ($ items as $ item ) {
282+ $ lineItem = [
283+ 'product_code ' => substr ($ item ->getName (), 0 , 12 ),
284+ 'product_description ' => substr ($ item ->getDescription (), 0 , 26 )
285+ ];
286+ if ($ item ->getPrice ()) {
287+ $ lineItem ['unit_cost ' ] = $ this ->getAmountWithCurrencyPrecision ($ item ->getPrice ());
288+ }
289+ if ($ item ->getQuantity ()) {
290+ $ lineItem ['quantity ' ] = $ item ->getQuantity ();
291+ }
292+ if ($ item ->getTaxes ()) {
293+ $ lineItem ['tax_amount ' ] = $ this ->getAmountWithCurrencyPrecision ($ item ->getTaxes ());
294+ }
295+ if ($ item ->getDiscount ()) {
296+ $ lineItem ['discount_amount ' ] = $ this ->getAmountWithCurrencyPrecision ($ item ->getDiscount ());
297+ }
298+ $ lineItems [] = $ lineItem ;
299+ }
300+ $ data ['level3 ' ] = [
301+ 'merchant_reference ' => $ this ->getTransactionId (),
302+ 'line_items ' => $ lineItems
303+ ];
271304 }
272- $ data ['description ' ] = implode (" + " , $ itemDescriptions );
273305 }
274306
275307 if ($ this ->getStatementDescriptor ()) {
@@ -319,8 +351,29 @@ public function getData()
319351 return $ data ;
320352 }
321353
354+ private function getAmountWithCurrencyPrecision ($ amount )
355+ {
356+ return (int )round ($ amount * pow (10 , $ this ->getCurrencyDecimalPlaces ()));
357+ }
358+
359+ /**
360+ * For Stripe to accept Level 3 data, the sum of all the line items should equal the request's `amount`. This
361+ * method validates that the summation adds up as expected.
362+ *
363+ * @param StripeItemBag $items
364+ * @return bool
365+ */
366+ private function validateLineItemsForLevel3 (StripeItemBag $ items )
367+ {
368+ $ actualAmount = 0 ;
369+ foreach ($ items as $ item ) {
370+ $ actualAmount += $ item ->getQuantity () * $ item ->getPrice () + $ item ->getTaxes () - $ item ->getDiscount ();
371+ }
372+ return (string )$ actualAmount == (string )$ this ->getAmount ();
373+ }
374+
322375 public function getEndpoint ()
323376 {
324- return $ this ->endpoint . '/charges ' ;
377+ return $ this ->endpoint . '/charges ' ;
325378 }
326379}
0 commit comments