public function Square::createPayment in Commerce Square Connect 8
Creates a payment.
Parameters
\Drupal\commerce_payment\Entity\PaymentInterface $payment: The payment.
bool $capture: Whether the created payment should be captured (VS authorized only). Allowed to be FALSE only if the plugin supports authorizations.
Throws
\InvalidArgumentException If $capture is FALSE but the plugin does not support authorizations.
\Drupal\commerce_payment\Exception\PaymentGatewayException Thrown when the transaction fails for any reason.
Overrides SupportsStoredPaymentMethodsInterface::createPayment
File
- src/
Plugin/ Commerce/ PaymentGateway/ Square.php, line 179
Class
- Square
- Provides the Square payment gateway.
Namespace
Drupal\commerce_square\Plugin\Commerce\PaymentGatewayCode
public function createPayment(PaymentInterface $payment, $capture = TRUE) {
$this
->assertPaymentState($payment, [
'new',
]);
$payment_method = $payment
->getPaymentMethod();
$this
->assertPaymentMethod($payment_method);
$paid_amount = $payment
->getAmount();
$rounder = \Drupal::getContainer()
->get('commerce_price.rounder');
/** @var \Drupal\commerce_price\Price $paid_amount */
$paid_amount = $rounder
->round($paid_amount);
$currency = $paid_amount
->getCurrencyCode();
// Square only accepts integers and not floats.
// @see https://docs.connect.squareup.com/api/connect/v2/#workingwithmonetaryamounts
$square_total_amount = $this
->toMinorUnits($paid_amount);
$billing = $payment_method
->getBillingProfile();
/** @var \Drupal\address\Plugin\Field\FieldType\AddressItem $address */
$address = $billing
->get('address')
->first();
$mode = $this
->getMode();
$order = new Order();
$order
->setReferenceId($payment
->getOrderId());
$order
->setLocationId($this->configuration[$mode . '_location_id']);
$line_items = [];
$line_item_total = 0;
foreach ($payment
->getOrder()
->getItems() as $item) {
$line_item = new OrderLineItem();
$base_price_money = new Money();
$square_amount = $this
->toMinorUnits($rounder
->round($item
->getUnitPrice()));
$base_price_money
->setAmount($square_amount);
$base_price_money
->setCurrency($currency);
$line_item
->setBasePriceMoney($base_price_money);
$square_amount = $this
->toMinorUnits($rounder
->round($item
->getTotalPrice()));
$line_item
->setName($item
->getTitle());
// Quantity needs to be a string integer.
$line_item
->setQuantity((string) (int) $item
->getQuantity());
$line_item_total += $square_amount;
$line_items[] = $line_item;
}
// Square requires the order total to match the payment amount.
if ($line_item_total != $square_total_amount) {
$diff = $square_total_amount - $line_item_total;
if ($diff < 0) {
$discount_money = new Money();
$discount_money
->setCurrency($currency);
$discount_money
->setAmount(-$diff);
$discount = new CreateOrderRequestDiscount();
$discount
->setAmountMoney($discount_money);
$discount
->setName('Adjustments');
}
else {
$line_item = new OrderLineItem();
$total_money = new Money();
$total_money
->setAmount((int) $diff);
$total_money
->setCurrency($currency);
$line_item
->setBasePriceMoney($total_money);
$line_item
->setName('Adjustments');
$line_item
->setQuantity("1");
$line_items[] = $line_item;
}
}
$order
->setLineItems($line_items);
if (isset($discount)) {
$order
->setDiscounts([
$discount,
]);
}
// @todo integration_id is not supported by the SDK.
// @see https://github.com/square/connect-php-sdk/issues/94
$charge_request = new IntegrationChargeRequest();
$charge_request
->setAmountMoney(new Money([
'amount' => $square_total_amount,
'currency' => $currency,
]));
if ($mode === 'live') {
$charge_request
->setIntegrationId('sqi_b6ff0cd7acc14f7ab24200041d066ba6');
}
$charge_request
->setDelayCapture(!$capture);
$charge_request
->setCardNonce($payment_method
->getRemoteId());
$charge_request
->setIdempotencyKey(uniqid('', TRUE));
$charge_request
->setBuyerEmailAddress($payment
->getOrder()
->getEmail());
$charge_request
->setBillingAddress(new Address([
'address_line_1' => $address
->getAddressLine1(),
'address_line_2' => $address
->getAddressLine2(),
'locality' => $address
->getLocality(),
'sublocality' => $address
->getDependentLocality(),
'administrative_district_level_1' => $address
->getAdministrativeArea(),
'postal_code' => $address
->getPostalCode(),
'country' => $address
->getCountryCode(),
'first_name' => $address
->getGivenName(),
'last_name' => $address
->getFamilyName(),
'organization' => $address
->getOrganization(),
]));
try {
$api_client = $this
->getApiClient();
// Create order.
$order_request = new CreateOrderRequest();
$order_request
->setIdempotencyKey(uniqid($payment
->getOrderId() . '-', TRUE));
$order_request
->setOrder($order);
$orders_api = new OrdersApi($api_client);
$result = $orders_api
->createOrder($this->configuration[$mode . '_location_id'], $order_request);
$charge_request
->setOrderId($result
->getOrder()
->getId());
$transactions_api = new TransactionsApi($api_client);
$result = $transactions_api
->charge($this->configuration[$mode . '_location_id'], $charge_request);
} catch (ApiException $e) {
throw ErrorHelper::convertException($e);
}
$transaction = $result
->getTransaction();
$tender = $transaction
->getTenders()[0];
$next_state = $capture ? 'completed' : 'authorization';
$payment
->setState($next_state);
$payment
->setRemoteId($transaction
->getId() . '|' . $tender
->getId());
$payment
->setAuthorizedTime($transaction
->getCreatedAt());
if ($capture) {
$payment
->setCompletedTime($result
->getTransaction()
->getCreatedAt());
}
else {
$expires = $this->time
->getRequestTime() + 3600 * 24 * 6 - 5;
$payment
->setExpiresTime($expires);
}
$payment
->save();
}