| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275 |
- <?php
- namespace Longyi\Pay\Applepay\Payment;
- use GuzzleHttp\Client;
- use Webkul\Payment\Payment\Payment;
- use Webkul\Sales\Models\Order;
- use Webkul\Sales\Repositories\OrderRepository;
- use Webkul\Sales\Repositories\InvoiceRepository;
- class Applepay extends Payment
- {
- /**
- * Payment method code
- *
- * @var string
- */
- protected $code = 'applepay';
- protected $clientId;
- protected $apikey;
- protected $webhookId;
- protected $currentOrder;
- protected $prefix = 'QQS';
- public $createOrderApi = 'https://api-m.sandbox.paypal.com/v2/checkout/orders';
- public $captureOrderApi = 'https://api-m.sandbox.paypal.com/v2/checkout/orders/{id}/capture';
- public $detailOrderApi = 'https://api-m.sandbox.paypal.com/v2/checkout/orders/{id}';
- public $updateOrderApi = 'https://api-m.sandbox.paypal.com/v2/checkout/orders/{id}';
- public $sigApi = 'https://api-m.sandbox.paypal.com/v1/notifications/verify-webhook-signature';
- public $orderTrackApi = 'https://api-m.sandbox.paypal.com/v2/checkout/orders/{id}/track';
- public $addTrackApi = 'https://api-m.sandbox.paypal.com/v1/shipping/trackers-batch';
- public function __construct(
- protected InvoiceRepository $invoiceRepository,
- protected OrderRepository $orderRepository,
- )
- {
- if ($this->getConfigData('mode') == 'live') {
- $this->createOrderApi = 'https://api-m.paypal.com/v2/checkout/orders';
- $this->captureOrderApi = 'https://api-m.paypal.com/v2/checkout/orders/{id}/capture';
- $this->detailOrderApi = 'https://api-m.paypal.com/v2/checkout/orders/{id}';
- $this->updateOrderApi = 'https://api-m.paypal.com/v2/checkout/orders/{id}';
- $this->sigApi = 'https://api-m.paypal.com/v1/notifications/verify-webhook-signature';
- $this->orderTrackApi = 'https://api-m.paypal.com/v2/checkout/orders/{id}/track';
- $this->addTrackApi = 'https://api-m.paypal.com/v1/shipping/trackers-batch';
- }
- $this->clientId = $this->getConfigData('client_id');
- $this->apikey = $this->getConfigData('secret_id');
- $this->webhookId = $this->getConfigData('webhook_id');
- }
- /**
- * Get redirect url.
- */
- public function getRedirectUrl()
- {
- }
- public function setOrder($order = null): self
- {
- $this->currentOrder = $order;
- return $this;
- }
- public function getOrder()
- {
- return $this->currentOrder;
- }
- public function createGatewayOrder()
- {
- return $this->createOrder($this->getOrder(), ['merchantOrderId' => $this->getOrder()->increment_id]);
- }
- public function createOrder($order, $override)
- {
- $billingAddressLines = $this->getAddressLines($order->billing_address->address);
- $data = [
- 'intent' => 'AUTHORIZE',
- 'purchase_units' => [
- [
- 'reference_id' => $override['merchantOrderId'],
- 'amount' => [
- 'currency_code' => $order->order_currency_code,
- 'value' => $this->formatCurrencyValue((float) $order->sub_total + $order->tax_total + ($order->selected_shipping_rate ? $order->selected_shipping_rate->price : 0) - $order->discount_amount),
- 'breakdown' => [
- 'item_total' => [
- 'currency_code' => $order->order_currency_code,
- 'value' => $this->formatCurrencyValue((float) $order->sub_total),
- ],
- 'shipping' => [
- 'currency_code' => $order->order_currency_code,
- 'value' => $this->formatCurrencyValue((float) ($order->selected_shipping_rate ? $order->selected_shipping_rate->price : 0)),
- ],
- 'tax_total' => [
- 'currency_code' => $order->order_currency_code,
- 'value' => $this->formatCurrencyValue((float) $order->tax_total),
- ],
- 'discount' => [
- 'currency_code' => $order->order_currency_code,
- 'value' => $this->formatCurrencyValue((float) $order->discount_amount),
- ],
- ],
- ],
- 'items' => $this->getLineItems($order),
- 'shipping' => [
- 'address' => [
- 'address_line_1' => current($billingAddressLines),
- 'address_line_2' => last($billingAddressLines),
- 'admin_area_2' => $order->shipping_address->city,
- 'admin_area_1' => $order->shipping_address->state,
- 'postal_code' => $order->shipping_address->postcode,
- 'country_code' => $order->shipping_address->country,
- ],
- ],
- ]
- ],
- 'payment_source' => [
- 'apple_pay' => [
- 'name' => $order->customer_full_name,
- 'email_address' => $order->customer_email
- ]
- ]
- ];
- $client = new Client();
- $response = $client->request('POST', $this->createOrderApi, [
- 'headers' => [
- 'Accept' => 'application/json',
- 'Content-Type' => 'application/json',
- 'Authorization' => 'Basic '.base64_encode("{$this->clientId}:{$this->apikey}")
- ],
- 'json' => $data,
- 'timeout' => 30,
- 'verify' => false
- ]);
- $resultObject = json_decode($response->getBody()->getContents());
- return $resultObject->id;
- }
- /**
- * Return cart items.
- *
- * @param string $cart
- * @return array
- */
- protected function getLineItems($order)
- {
- $lineItems = [];
- foreach ($order->items as $item) {
- $lineItems[] = [
- 'unit_amount' => [
- 'currency_code' => $order->order_currency_code,
- 'value' => $this->formatCurrencyValue((float) $item->price),
- ],
- 'quantity' => $item->qty_ordered,
- 'name' => $item->name,
- 'sku' => $item->sku,
- 'category' => $item->getTypeInstance()->isStockable() ? 'PHYSICAL_GOODS' : 'DIGITAL_GOODS',
- ];
- }
- return $lineItems;
- }
- public function webhookSignature($header, $data)
- {
- $data = [
- 'transmission_id' => $header['Paypal-Transmission-Id'],
- 'transmission_time' => $header['Paypal-Transmission-Time'],
- 'cert_url' => $header['Paypal-Cert-Url'],
- 'auth_algo' => $header['Paypal-Auth-Algo'],
- 'transmission_sig' => $header['Paypal-Transmission-Sig'],
- 'webhook_id' => $this->webhookId,
- 'webhook_event' => $data
- ];
- $client = new Client();
- $response = $client->request('POST', $this->sigApi, [
- 'headers' => [
- 'Accept' => 'application/json',
- 'Content-Type' => 'application/json',
- 'Authorization' => 'Basic '. base64_encode("{$this->apikey}:{$this->secret}")
- ],
- 'json' => $data,
- 'timeout' => 30,
- 'verify' => false
- ]);
- $resultObject = json_decode($response->getBody()->getContents());
- if ($resultObject->verification_status == 'SUCCESS') {
- return true;
- } else {
- return false;
- }
- }
- //成功修改状态
- public function paymentSucceeded($orderId, $transactionId)
- {
- $order = $this->orderRepository->findByField('increment_id', $orderId);
- if (!$order->id) {
- return false;
- }
- if ($order->status != Order::STATUS_PENDING) {
- return false;
- }
- $order->status = Order::STATUS_PROCESSING;
- $order->save();
- if ($order->payment) {
- $additional = $order->payment->additional;
- $additional['transaction_id'] = $transactionId;
- $order->payment->additional = $additional;
- $order->payment->save();
- }
- if ($order->canInvoice()) {
- $this->invoiceRepository->create($this->prepareInvoiceData($order));
- }
- }
- /**
- * Prepares order's invoice data for creation.
- */
- protected function prepareInvoiceData($order): array
- {
- $invoiceData = [
- 'order_id' => $order->id,
- 'invoice' => ['items' => []],
- ];
- foreach ($order->items as $item) {
- $invoiceData['invoice']['items'][$item->id] = $item->qty_to_invoice;
- }
- return $invoiceData;
- }
- protected function getAddressLines($address)
- {
- $address = explode(PHP_EOL, $address, 2);
- $addressLines = [current($address)];
- if (isset($address[1])) {
- $addressLines[] = str_replace(["\r\n", "\r", "\n"], ' ', last($address));
- } else {
- $addressLines[] = '';
- }
- return $addressLines;
- }
- public function formatCurrencyValue($number): float
- {
- return round((float) $number, 2);
- }
- public function isAvailable()
- {
- if (! parent::isAvailable()) {
- return false;
- }
- $userAgent = request()->header('User-Agent');
- if (! $userAgent) {
- return false;
- }
- $appleDevices = [
- 'iPhone',
- 'iPad',
- 'iPod',
- 'Macintosh',
- 'Mac OS X',
- ];
- foreach ($appleDevices as $device) {
- if (strpos($userAgent, $device) !== false) {
- return true;
- }
- }
- return true;
- }
- }
|