mirror of
https://github.com/woocommerce/woocommerce-paypal-payments.git
synced 2025-08-30 05:00:51 +08:00
Add apple transaction in product with auth
This commit is contained in:
parent
3ae22b3356
commit
10613711b9
10 changed files with 1247 additions and 299 deletions
|
@ -15,6 +15,18 @@ use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
|
|||
|
||||
return array(
|
||||
'wcgateway.settings.fields' => static function ( ContainerInterface $container, array $fields ): array {
|
||||
$fields['applepay_heading'] = array(
|
||||
'heading' => __( 'Apple Pay', 'woocommerce-paypal-payments' ),
|
||||
'description' =>
|
||||
__(
|
||||
'Customize the behaviour of the ApplePay button.',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
'type' => 'ppcp-heading',
|
||||
'screens' => array( State::STATE_ONBOARDED ),
|
||||
'requirements' => array(),
|
||||
'gateway' => 'paypal',
|
||||
);
|
||||
$fields['applepay_button_enabled_product'] = array(
|
||||
'title' => __( 'Apple Pay Button on Product Page', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'checkbox',
|
||||
|
@ -33,6 +45,26 @@ return array(
|
|||
'gateway' => 'paypal',
|
||||
'requirements' => array(),
|
||||
);
|
||||
$fields['applepay_live_validation_file'] = array(
|
||||
'title' => __( 'Apple Pay Live Validation File', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'textarea',
|
||||
'label' => __( 'Paste here the validation file content', 'woocommerce-paypal-payments' ),
|
||||
'default' => null,
|
||||
'screens' => array( State::STATE_ONBOARDED ),
|
||||
'gateway' => 'paypal',
|
||||
'requirements' => array(),
|
||||
);
|
||||
$fields['applepay_sandbox_validation_file'] = array(
|
||||
'title' => __( 'Apple Pay Sandbox Validation File', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'textarea',
|
||||
'label' => __( 'Paste here the validation file content', 'woocommerce-paypal-payments' ),
|
||||
'default' => null,
|
||||
'screens' => array( State::STATE_ONBOARDED ),
|
||||
'gateway' => 'paypal',
|
||||
'requirements' => array(),
|
||||
);
|
||||
|
||||
|
||||
|
||||
return $fields;
|
||||
},
|
||||
|
|
|
@ -1,23 +1,29 @@
|
|||
//import {useEffect, useState} from '@wordpress/element';
|
||||
import {createAppleErrors} from './Helper/applePayError.js';
|
||||
import {maybeShowButton} from './Helper/maybeShowApplePayButton.js';
|
||||
import {request} from './Helper/applePayRequest.js';
|
||||
import {buttonID, endpoints} from "./Helper/utils";
|
||||
import {loadPaypalScript} from '../../../ppcp-button/resources/js/modules/Helper/ScriptLoading'
|
||||
import ErrorHandler from '../../../ppcp-button/resources/js/modules/ErrorHandler';
|
||||
import SingleProductActionHandler
|
||||
from '../../../ppcp-button/resources/js/modules/ActionHandler/SingleProductActionHandler';
|
||||
import UpdateCart from '../../../ppcp-button/resources/js/modules/Helper/UpdateCart';
|
||||
import {loadPaypalScript} from '../../../ppcp-button/resources/js/modules/Helper/ScriptLoading';
|
||||
|
||||
(
|
||||
function ({ wc_ppcp_applepay, jQuery}) {
|
||||
function ({wc_ppcp_applepay, jQuery}) {
|
||||
document.addEventListener(
|
||||
'DOMContentLoaded',
|
||||
() => {
|
||||
if (PayPalCommerceGateway) {
|
||||
let bootstrapped = false;
|
||||
const {product: {id, needShipping = true, isVariation = false, price, stock}, shop: {countryCode, currencyCode = 'EUR', totalLabel = ''}, ajaxUrl} = wc_ppcp_applepay
|
||||
const {
|
||||
product: {id, needShipping = true, isVariation = false, price, stock},
|
||||
shop: {countryCode, currencyCode = 'EUR', totalLabel = ''},
|
||||
ajaxUrl
|
||||
} = wc_ppcp_applepay
|
||||
|
||||
if (!id || !price || !countryCode || !ajaxUrl) {
|
||||
return
|
||||
}
|
||||
let outOfStock = stock === 'outofstock'
|
||||
if(outOfStock || !maybeShowButton()){
|
||||
if (outOfStock || !maybeShowButton()) {
|
||||
return;
|
||||
}
|
||||
const nonce = document.getElementById('woocommerce-process-checkout-nonce').value
|
||||
|
@ -29,14 +35,17 @@ import {loadPaypalScript} from '../../../ppcp-button/resources/js/modules/Helper
|
|||
document.querySelector('input.qty').addEventListener('change', event => {
|
||||
productQuantity = event.currentTarget.value
|
||||
})
|
||||
|
||||
function disableButton(appleButton) {
|
||||
appleButton.disabled = true;
|
||||
appleButton.classList.add("buttonDisabled");
|
||||
}
|
||||
|
||||
function enableButton(appleButton) {
|
||||
appleButton.disabled = false;
|
||||
appleButton.classList.remove("buttonDisabled");
|
||||
}
|
||||
|
||||
if (isVariation) {
|
||||
let appleButton = document.querySelector('#applepay-container');
|
||||
jQuery('.single_variation_wrap').on('hide_variation', function (event, variation) {
|
||||
|
@ -58,20 +67,20 @@ import {loadPaypalScript} from '../../../ppcp-button/resources/js/modules/Helper
|
|||
disableButton(appleButton);
|
||||
}
|
||||
const amountWithoutTax = productQuantity * price
|
||||
|
||||
|
||||
loadPaypalScript(PayPalCommerceGateway, () => {
|
||||
bootstrapped = true;
|
||||
//print the button
|
||||
const applepay = paypal.Applepay();
|
||||
console.log(applepay)
|
||||
applepay.config()
|
||||
.then(applepayConfig => {
|
||||
const appleContainer = document.getElementById("applepay-container");
|
||||
if (applepayConfig.isEligible) {
|
||||
appleContainer.innerHTML = '<apple-pay-button id="btn-appl"buttonstyle="black" type="buy" locale="en">';
|
||||
//handle transaction
|
||||
appleContainer.innerHTML = '<apple-pay-button id="btn-appl" buttonstyle="black" type="buy" locale="en">';
|
||||
const paymentRequest = {
|
||||
countryCode: applepayConfig.countryCode,
|
||||
merchantCapabilities:
|
||||
applepayConfig.merchantCapabilities,
|
||||
merchantCapabilities: applepayConfig.merchantCapabilities,
|
||||
supportedNetworks: applepayConfig.supportedNetworks,
|
||||
currencyCode: currencyCode,
|
||||
requiredShippingContactFields: ["name", "phone",
|
||||
|
@ -82,13 +91,13 @@ import {loadPaypalScript} from '../../../ppcp-button/resources/js/modules/Helper
|
|||
label: totalLabel,
|
||||
type: "final",
|
||||
amount: amountWithoutTax,
|
||||
}}
|
||||
console.log(paymentRequest)
|
||||
console.log(wc_ppcp_applepay)
|
||||
}
|
||||
}
|
||||
let applePaySession = () => {
|
||||
const session = new ApplePaySession(4, paymentRequest)
|
||||
session.begin()
|
||||
if(needShipping){
|
||||
console.log(session)
|
||||
if (needShipping) {
|
||||
session.onshippingmethodselected = function (event) {
|
||||
jQuery.ajax({
|
||||
url: ajaxUrl,
|
||||
|
@ -155,6 +164,7 @@ import {loadPaypalScript} from '../../../ppcp-button/resources/js/modules/Helper
|
|||
selectedShippingMethod = response.newShippingMethods[0]
|
||||
}
|
||||
this.completeShippingContactSelection(response)
|
||||
|
||||
},
|
||||
error: (jqXHR, textStatus, errorThrown) => {
|
||||
console.warn(textStatus, errorThrown)
|
||||
|
@ -169,89 +179,152 @@ import {loadPaypalScript} from '../../../ppcp-button/resources/js/modules/Helper
|
|||
})
|
||||
.then(validateResult => {
|
||||
session.completeMerchantValidation(validateResult.merchantSession);
|
||||
//call backend to update validation to true
|
||||
console.log('validated')
|
||||
})
|
||||
.catch(validateError => {
|
||||
console.error(validateError);
|
||||
//call backend to update validation to false
|
||||
session.abort();
|
||||
});
|
||||
};
|
||||
/*session.onpaymentauthorized = (ApplePayPayment) => {
|
||||
const {billingContact, shippingContact } = ApplePayPayment.payment
|
||||
session.onpaymentauthorized = (event) => {
|
||||
function form() {
|
||||
return document.querySelector('form.cart');
|
||||
}
|
||||
const errorHandler = new ErrorHandler(
|
||||
PayPalCommerceGateway.labels.error.generic,
|
||||
document.querySelector('.woocommerce-notices-wrapper')
|
||||
);
|
||||
const actionHandler = new SingleProductActionHandler(
|
||||
PayPalCommerceGateway,
|
||||
new UpdateCart(
|
||||
PayPalCommerceGateway.ajax.change_cart.endpoint,
|
||||
PayPalCommerceGateway.ajax.change_cart.nonce,
|
||||
),
|
||||
form(),
|
||||
errorHandler,
|
||||
);
|
||||
|
||||
jQuery.ajax({
|
||||
url: ajaxUrl,
|
||||
method: 'POST',
|
||||
data: {
|
||||
action: 'mollie_apple_pay_create_order',
|
||||
productId: productId,
|
||||
productQuantity: productQuantity,
|
||||
shippingContact: ApplePayPayment.payment.shippingContact,
|
||||
billingContact: ApplePayPayment.payment.billingContact,
|
||||
token: ApplePayPayment.payment.token,
|
||||
shippingMethod: selectedShippingMethod,
|
||||
'mollie-payments-for-woocommerce_issuer_applepay': 'applepay',
|
||||
'woocommerce-process-checkout-nonce': nonce,
|
||||
'billing_first_name': billingContact.givenName || '',
|
||||
'billing_last_name' : billingContact.familyName || '',
|
||||
'billing_company': '',
|
||||
'billing_country' : billingContact.countryCode || '',
|
||||
'billing_address_1' : billingContact.addressLines[0] || '',
|
||||
'billing_address_2' : billingContact.addressLines[1] || '',
|
||||
'billing_postcode' : billingContact.postalCode || '',
|
||||
'billing_city': billingContact.locality || '',
|
||||
'billing_state' : billingContact.administrativeArea || '',
|
||||
'billing_phone' : billingContact.phoneNumber || '000000000000',
|
||||
'billing_email' : shippingContact.emailAddress || '',
|
||||
'shipping_first_name': shippingContact.givenName || '',
|
||||
'shipping_last_name' : shippingContact.familyName || '',
|
||||
'shipping_company': '',
|
||||
'shipping_country' : shippingContact.countryCode || '',
|
||||
'shipping_address_1' : shippingContact.addressLines[0] || '',
|
||||
'shipping_address_2' : shippingContact.addressLines[1] || '',
|
||||
'shipping_postcode' : shippingContact.postalCode || '',
|
||||
'shipping_city': shippingContact.locality || '',
|
||||
'shipping_state' : shippingContact.administrativeArea || '',
|
||||
'shipping_phone' : shippingContact.phoneNumber || '000000000000',
|
||||
'shipping_email' : shippingContact.emailAddress || '',
|
||||
'order_comments' : '',
|
||||
'payment_method' : 'mollie_wc_gateway_applepay',
|
||||
'_wp_http_referer' : '/?wc-ajax=update_order_review'
|
||||
},
|
||||
complete: (jqXHR, textStatus) => {
|
||||
},
|
||||
success: (authorizationResult, textStatus, jqXHR) => {
|
||||
let result = authorizationResult.data
|
||||
let createOrderInPayPal = actionHandler.createOrder()
|
||||
const processInWooAndCapture = async (data) => {
|
||||
try {
|
||||
const billingContact = data.billing_contact
|
||||
const shippingContact = data.shipping_contact
|
||||
jQuery.ajax({
|
||||
url: ajaxUrl,
|
||||
method: 'POST',
|
||||
data: {
|
||||
action: 'ppcp_create_order',
|
||||
'product_id': productId,
|
||||
'product_quantity': productQuantity,
|
||||
'shipping_contact': shippingContact,
|
||||
'billing_contact': billingContact,
|
||||
'token': event.payment.token,
|
||||
'shipping_method': selectedShippingMethod,
|
||||
'mollie-payments-for-woocommerce_issuer_applepay': 'applepay',
|
||||
'woocommerce-process-checkout-nonce': nonce,
|
||||
'billing_first_name': billingContact.givenName || '',
|
||||
'billing_last_name': billingContact.familyName || '',
|
||||
'billing_company': '',
|
||||
'billing_country': billingContact.countryCode || '',
|
||||
'billing_address_1': billingContact.addressLines[0] || '',
|
||||
'billing_address_2': billingContact.addressLines[1] || '',
|
||||
'billing_postcode': billingContact.postalCode || '',
|
||||
'billing_city': billingContact.locality || '',
|
||||
'billing_state': billingContact.administrativeArea || '',
|
||||
'billing_phone': billingContact.phoneNumber || '000000000000',
|
||||
'billing_email': shippingContact.emailAddress || '',
|
||||
'shipping_first_name': shippingContact.givenName || '',
|
||||
'shipping_last_name': shippingContact.familyName || '',
|
||||
'shipping_company': '',
|
||||
'shipping_country': shippingContact.countryCode || '',
|
||||
'shipping_address_1': shippingContact.addressLines[0] || '',
|
||||
'shipping_address_2': shippingContact.addressLines[1] || '',
|
||||
'shipping_postcode': shippingContact.postalCode || '',
|
||||
'shipping_city': shippingContact.locality || '',
|
||||
'shipping_state': shippingContact.administrativeArea || '',
|
||||
'shipping_phone': shippingContact.phoneNumber || '000000000000',
|
||||
'shipping_email': shippingContact.emailAddress || '',
|
||||
'order_comments': '',
|
||||
'payment_method': 'ppcp-gateway',
|
||||
'funding_source': 'applepay',
|
||||
'_wp_http_referer': '/?wc-ajax=update_order_review',
|
||||
'paypal_order_id': data.paypal_order_id,
|
||||
},
|
||||
complete: (jqXHR, textStatus) => {
|
||||
},
|
||||
success: (authorizationResult, textStatus, jqXHR) => {
|
||||
let result = authorizationResult.data
|
||||
|
||||
if (authorizationResult.success === true) {
|
||||
redirectionUrl = result['returnUrl'];
|
||||
session.completePayment(result['responseToApple'])
|
||||
window.location.href = redirectionUrl
|
||||
} else {
|
||||
result.errors = createAppleErrors(result.errors)
|
||||
session.completePayment(result)
|
||||
if (authorizationResult.success === true) {
|
||||
redirectionUrl = result['returnUrl'];
|
||||
session.completePayment(result['responseToApple'])
|
||||
window.location.href = redirectionUrl
|
||||
} else {
|
||||
result.errors = createAppleErrors(result.errors)
|
||||
session.completePayment(result)
|
||||
}
|
||||
},
|
||||
error: (jqXHR, textStatus, errorThrown) => {
|
||||
console.warn(textStatus, errorThrown)
|
||||
session.abort()
|
||||
},
|
||||
})
|
||||
} catch (error) {
|
||||
console.log(error) // handle error
|
||||
}
|
||||
}
|
||||
createOrderInPayPal([], []).then((orderId) => {
|
||||
applepay.confirmOrder(
|
||||
{
|
||||
orderId: orderId,
|
||||
token: event.payment.token,
|
||||
billingContact: event.payment.billingContact
|
||||
}
|
||||
},
|
||||
error: (jqXHR, textStatus, errorThrown) => {
|
||||
console.warn(textStatus, errorThrown)
|
||||
session.abort()
|
||||
},
|
||||
).then(
|
||||
confirmResult => {
|
||||
session.completePayment(ApplePaySession.STATUS_SUCCESS);
|
||||
let data = {
|
||||
billing_contact: event.payment.billingContact,
|
||||
shipping_contact: event.payment.shippingContact,
|
||||
paypal_order_id: orderId
|
||||
}
|
||||
processInWooAndCapture(data).then(
|
||||
() => {
|
||||
console.log('done in woo and capture')
|
||||
let result = confirmResult.data
|
||||
redirectionUrl = result['returnUrl'];
|
||||
session.completePayment(result['responseToApple'])
|
||||
window.location.href = redirectionUrl
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
.catch(err => {
|
||||
session.completePayment(ApplePaySession.STATUS_FAILURE);
|
||||
console.error('Error confirming order with applepay token');
|
||||
console.error(err);
|
||||
}
|
||||
);
|
||||
}).catch((error) => {
|
||||
console.log(error)
|
||||
session.abort()
|
||||
})
|
||||
}*/
|
||||
};
|
||||
}
|
||||
document.querySelector('#btn-appl').addEventListener('click', (evt) => {
|
||||
evt.preventDefault()
|
||||
applePaySession()
|
||||
})
|
||||
} })
|
||||
}
|
||||
})
|
||||
.catch(applepayConfigError => {
|
||||
console.error(applepayConfigError)
|
||||
console.error('Error while fetching Apple Pay configuration.');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
})
|
||||
}
|
||||
)(window)
|
||||
|
|
|
@ -9,15 +9,19 @@ declare(strict_types=1);
|
|||
|
||||
namespace WooCommerce\PayPalCommerce\Applepay;
|
||||
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Helper\Cache;
|
||||
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
|
||||
|
||||
return array(
|
||||
'apple.status-cache' => static function( ContainerInterface $container ): Cache {
|
||||
return new Cache( 'ppcp-paypal-apple-status-cache' );
|
||||
},
|
||||
'applepay.apple-product-status' => static function( ContainerInterface $container ): AppleProductStatus {
|
||||
return new AppleProductStatus(
|
||||
$container->get( 'wcgateway.settings' ),
|
||||
$container->get( 'api.endpoint.partners' ),
|
||||
$container->get( 'pui.status-cache' ),
|
||||
$container->get( 'apple.status-cache' ),
|
||||
$container->get( 'onboarding.state' )
|
||||
);
|
||||
},
|
||||
|
@ -41,8 +45,9 @@ return array(
|
|||
'applepay.payment_method' => static function ( ContainerInterface $container ): ApplepayPaymentMethod {
|
||||
$settings = $container->get( 'wcgateway.settings' );
|
||||
$logger = $container->get( 'woocommerce.logger.woocommerce' );
|
||||
$order_processor = $container->get( 'wcgateway.order-processor' );
|
||||
|
||||
return new ApplepayPaymentMethod( $settings, $logger );
|
||||
return new ApplepayPaymentMethod( $settings, $logger, $order_processor );
|
||||
},
|
||||
'applepay.url' => static function ( ContainerInterface $container ): string {
|
||||
$path = realpath( __FILE__ );
|
||||
|
@ -60,7 +65,7 @@ return array(
|
|||
'applepay.script_url' => static function ( ContainerInterface $container ): string {
|
||||
return trailingslashit( $container->get( 'applepay.url' ) ) . '/assets/js/applePayDirect.js';
|
||||
},
|
||||
'applepay.style_url' => static function ( ContainerInterface $container ): string {
|
||||
'applepay.style_url' => static function ( ContainerInterface $container ): string {
|
||||
return trailingslashit( $container->get( 'applepay.url' ) ) . '/assets/css/applepaydirect.css';
|
||||
},
|
||||
'applepay.setting_button_enabled_product' => static function ( ContainerInterface $container ): bool {
|
||||
|
@ -79,7 +84,7 @@ return array(
|
|||
(bool) $settings->get( 'applepay_button_enabled_cart' ) :
|
||||
false;
|
||||
},
|
||||
'applepay.data_to_scripts' => static function ( ContainerInterface $container ): DataToAppleButtonScripts {
|
||||
'applepay.data_to_scripts' => static function ( ContainerInterface $container ): DataToAppleButtonScripts {
|
||||
return new DataToAppleButtonScripts();
|
||||
},
|
||||
);
|
||||
|
|
548
modules/ppcp-applepay/src/ApplePayDataObjectHttp.php
Normal file
548
modules/ppcp-applepay/src/ApplePayDataObjectHttp.php
Normal file
|
@ -0,0 +1,548 @@
|
|||
<?php
|
||||
/**
|
||||
* Builds the object containing the data to send to Apple.
|
||||
*
|
||||
* @package WooCommerce\PayPalCommerce\Applepay
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\Applepay;
|
||||
|
||||
use Psr\Log\LoggerInterface as Logger;
|
||||
|
||||
/**
|
||||
* Class ApplePayDataObjectHttp
|
||||
*/
|
||||
class ApplePayDataObjectHttp {
|
||||
|
||||
/**
|
||||
* The nonce of the request.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $nonce;
|
||||
|
||||
/**
|
||||
* The contact with less fields.
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
protected $simplified_contact;
|
||||
|
||||
/**
|
||||
* If the product needs shipping.
|
||||
*
|
||||
* @var mixed|null
|
||||
*/
|
||||
protected $need_shipping;
|
||||
|
||||
/**
|
||||
* The product id.
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
protected $product_id;
|
||||
|
||||
/**
|
||||
* The product quantity.
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
protected $product_quantity;
|
||||
|
||||
/**
|
||||
* The shipping methods.
|
||||
*
|
||||
* @var array|mixed
|
||||
*/
|
||||
protected $shipping_method = array();
|
||||
|
||||
/**
|
||||
* The billing address.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $billing_address = array();
|
||||
|
||||
/**
|
||||
* The shipping address.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $shipping_address = array();
|
||||
|
||||
/**
|
||||
* The list of errors.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $errors = array();
|
||||
|
||||
/**
|
||||
* The logger.
|
||||
*
|
||||
* @var Logger
|
||||
*/
|
||||
protected $logger;
|
||||
|
||||
/**
|
||||
* ApplePayDataObjectHttp constructor.
|
||||
*
|
||||
* @param Logger $logger The logger.
|
||||
*/
|
||||
public function __construct( Logger $logger ) {
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the errors array
|
||||
*/
|
||||
protected function reset_errors() {
|
||||
$this->errors = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if the object has any errors
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function has_errors() {
|
||||
return ! empty( $this->errors );
|
||||
}
|
||||
/**
|
||||
* Returns errors
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function errors(): array {
|
||||
return $this->errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the object with the data relevant to ApplePay on update shipping contact
|
||||
* Required data depends on callerPage
|
||||
*/
|
||||
public function update_contact_data() {
|
||||
$nonce = filter_input( INPUT_POST, 'woocommerce-process-checkout-nonce', FILTER_SANITIZE_SPECIAL_CHARS );
|
||||
$is_nonce_valid = wp_verify_nonce(
|
||||
$nonce,
|
||||
'woocommerce-process_checkout'
|
||||
);
|
||||
if ( ! $is_nonce_valid ) {
|
||||
return;
|
||||
}
|
||||
$data = $this->get_filtered_request_data();
|
||||
|
||||
$result = $this->update_required_data(
|
||||
$data,
|
||||
PropertiesDictionary::UPDATE_CONTACT_SINGLE_PROD_REQUIRED_FIELDS,
|
||||
PropertiesDictionary::UPDATE_CONTACT_CART_REQUIRED_FIELDS
|
||||
);
|
||||
if ( ! $result ) {
|
||||
return;
|
||||
}
|
||||
$this->update_simplified_contact( $data[ PropertiesDictionary::SIMPLIFIED_CONTACT ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the object with the data relevant to ApplePay on update shipping method
|
||||
* Required data depends on callerPage
|
||||
*/
|
||||
public function update_method_data() {
|
||||
$nonce = filter_input( INPUT_POST, 'woocommerce-process-checkout-nonce', FILTER_SANITIZE_SPECIAL_CHARS );
|
||||
$is_nonce_valid = wp_verify_nonce(
|
||||
$nonce,
|
||||
'woocommerce-process_checkout'
|
||||
);
|
||||
if ( ! $is_nonce_valid ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$data = $this->get_filtered_request_data();
|
||||
$result = $this->update_required_data(
|
||||
$data,
|
||||
PropertiesDictionary::UPDATE_METHOD_SINGLE_PROD_REQUIRED_FIELDS,
|
||||
PropertiesDictionary::UPDATE_METHOD_CART_REQUIRED_FIELDS
|
||||
);
|
||||
if ( ! $result ) {
|
||||
return;
|
||||
}
|
||||
$this->update_simplified_contact( $data[ PropertiesDictionary::SIMPLIFIED_CONTACT ] );
|
||||
$this->update_shipping_method( $data );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the object with the data relevant to ApplePay on authorized order
|
||||
* Required data depends on callerPage
|
||||
*
|
||||
* @param string $caller_page The caller page.
|
||||
*/
|
||||
public function order_data( string $caller_page ) {
|
||||
$nonce = filter_input( INPUT_POST, 'woocommerce-process-checkout-nonce', FILTER_SANITIZE_SPECIAL_CHARS );
|
||||
$is_nonce_valid = wp_verify_nonce(
|
||||
$nonce,
|
||||
'woocommerce-process_checkout'
|
||||
);
|
||||
if ( ! $is_nonce_valid ) {
|
||||
return;
|
||||
}
|
||||
$data = filter_var_array( $_POST, FILTER_SANITIZE_SPECIAL_CHARS );
|
||||
$data[ PropertiesDictionary::CALLER_PAGE ] = $caller_page;
|
||||
$result = $this->update_required_data(
|
||||
$data,
|
||||
PropertiesDictionary::CREATE_ORDER_SINGLE_PROD_REQUIRED_FIELDS,
|
||||
PropertiesDictionary::CREATE_ORDER_CART_REQUIRED_FIELDS
|
||||
);
|
||||
if ( ! $result ) {
|
||||
return;
|
||||
}
|
||||
if (
|
||||
! array_key_exists( 'emailAddress', $data[ PropertiesDictionary::SHIPPING_CONTACT ] )
|
||||
|| ! $data[ PropertiesDictionary::SHIPPING_CONTACT ]['emailAddress']
|
||||
) {
|
||||
$this->errors[] = array(
|
||||
'errorCode' => PropertiesDictionary::SHIPPING_CONTACT_INVALID,
|
||||
'contactField' => 'emailAddress',
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$filtered_shipping_contact = $data[ PropertiesDictionary::SHIPPING_CONTACT ];
|
||||
$this->shipping_address = $this->complete_address(
|
||||
$filtered_shipping_contact,
|
||||
PropertiesDictionary::SHIPPING_CONTACT_INVALID
|
||||
);
|
||||
$filtered_billing_contact = $data[ PropertiesDictionary::BILLING_CONTACT ];
|
||||
$this->billing_address = $this->complete_address(
|
||||
$filtered_billing_contact,
|
||||
PropertiesDictionary::BILLING_CONTACT_INVALID
|
||||
);
|
||||
$this->update_shipping_method( $data );
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the array contains all required fields and if those
|
||||
* are not empty.
|
||||
* If not it adds an unkown error to the object's error list, as this errors
|
||||
* are not supported by ApplePay.
|
||||
*
|
||||
* @param array $data The data.
|
||||
* @param array $required The required fields.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function has_required_fields_values_or_error( array $data, array $required ) {
|
||||
foreach ( $required as $required_field ) {
|
||||
if ( ! array_key_exists( $required_field, $data ) ) {
|
||||
$this->logger->debug(
|
||||
sprintf( 'ApplePay Data Error: Missing index %s', $required_field )
|
||||
);
|
||||
|
||||
$this->errors[] = array( 'errorCode' => 'unknown' );
|
||||
continue;
|
||||
}
|
||||
if ( $data[ $required_field ] === null || $data[ $required_field ] === '' ) {
|
||||
$this->logger->debug(
|
||||
sprintf( 'ApplePay Data Error: Missing value for %s', $required_field )
|
||||
);
|
||||
$this->errors[] = array( 'errorCode' => 'unknown' );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return ! $this->has_errors();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value to the appropriate field in the object.
|
||||
*
|
||||
* @param array $data The data.
|
||||
*/
|
||||
protected function assign_data_object_values( array $data ) {
|
||||
foreach ( $data as $key => $value ) {
|
||||
if ( $key === 'woocommerce-process-checkout-nonce' ) {
|
||||
$key = 'nonce';
|
||||
}
|
||||
$this->$key = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the address details used in pre-authorization steps.
|
||||
*
|
||||
* @param array $contact_info
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
protected function simplified_address( array $contact_info ) {
|
||||
$required = array(
|
||||
'locality' => 'locality',
|
||||
'postalCode' => 'postalCode',
|
||||
'countryCode' => 'countryCode',
|
||||
);
|
||||
if (
|
||||
! $this->address_has_required_fields_values(
|
||||
$contact_info,
|
||||
$required,
|
||||
PropertiesDictionary::SHIPPING_CONTACT_INVALID
|
||||
)
|
||||
) {
|
||||
return array();
|
||||
}
|
||||
return array(
|
||||
'city' => $contact_info['locality'],
|
||||
'postcode' => $contact_info['postalCode'],
|
||||
'country' => strtoupper( $contact_info['countryCode'] ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the address array contains all required fields and if those
|
||||
* are not empty.
|
||||
* If not it adds a contacField error to the object's error list.
|
||||
*
|
||||
* @param array $post The address to check
|
||||
* @param array $required The required fields for the given address
|
||||
* @param string $error_code Either shipping or billing kind
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function address_has_required_fields_values(
|
||||
array $post,
|
||||
array $required,
|
||||
string $error_code
|
||||
) {
|
||||
|
||||
foreach ( $required as $required_field => $error_value ) {
|
||||
if ( ! array_key_exists( $required_field, $post ) ) {
|
||||
$this->logger->debug(
|
||||
sprintf( 'ApplePay Data Error: Missing index %s', $required_field )
|
||||
);
|
||||
|
||||
$this->errors[] = array( 'errorCode' => 'unknown' );
|
||||
continue;
|
||||
}
|
||||
if ( ! $post[ $required_field ] ) {
|
||||
$this->logger->debug(
|
||||
sprintf( 'ApplePay Data Error: Missing value for %s', $required_field )
|
||||
);
|
||||
$this->errors[]
|
||||
= array(
|
||||
'errorCode' => $error_code,
|
||||
'contactField' => $error_value,
|
||||
);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return ! $this->has_errors();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the address details for after authorization steps.
|
||||
*
|
||||
* @param array $data The data.
|
||||
* @param string $error_code differentiates between billing and shipping information
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
protected function complete_address( array $data, string $error_code ): array {
|
||||
$required = array(
|
||||
'givenName' => 'name',
|
||||
'familyName' => 'name',
|
||||
'addressLines' => 'addressLines',
|
||||
'locality' => 'locality',
|
||||
'postalCode' => 'postalCode',
|
||||
'countryCode' => 'countryCode',
|
||||
);
|
||||
if (
|
||||
! $this->address_has_required_fields_values(
|
||||
$data,
|
||||
$required,
|
||||
$error_code
|
||||
)
|
||||
) {
|
||||
return array();
|
||||
}
|
||||
|
||||
return array(
|
||||
'first_name' => $data['givenName'],
|
||||
'last_name' => $data['familyName'],
|
||||
'email' => $data['emailAddress'] ?? '',
|
||||
'phone' => $data['phoneNumber'] ?? '',
|
||||
'address_1' => $data['addressLines'][0] ?? '',
|
||||
'address_2' => $data['addressLines'][1] ?? '',
|
||||
'city' => $data['locality'],
|
||||
'state' => $data['administrativeArea'],
|
||||
'postcode' => $data['postalCode'],
|
||||
'country' => strtoupper( $data['countryCode'] ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the object with the required data.
|
||||
*
|
||||
* @param array $data The data.
|
||||
* @param array $required_product_fields
|
||||
* @param array $required_cart_fields
|
||||
* @return bool
|
||||
*/
|
||||
protected function update_required_data( array $data, array $required_product_fields, array $required_cart_fields ) {
|
||||
$this->reset_errors();
|
||||
$required_fields = $required_product_fields;
|
||||
if (
|
||||
isset( $data[ PropertiesDictionary::CALLER_PAGE ] )
|
||||
&& $data[ PropertiesDictionary::CALLER_PAGE ] === 'cart'
|
||||
) {
|
||||
$required_fields = $required_cart_fields;
|
||||
}
|
||||
$has_required_fields_values = $this->has_required_fields_values_or_error(
|
||||
$data,
|
||||
$required_fields
|
||||
);
|
||||
if ( ! $has_required_fields_values ) {
|
||||
return false;
|
||||
}
|
||||
$this->assign_data_object_values( $data );
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the data object with the contact values from the request.
|
||||
*
|
||||
* @param array $data The data.
|
||||
* @return void
|
||||
*/
|
||||
protected function update_simplified_contact( array $data ) : void {
|
||||
$simplified_contact_info = array_map( 'sanitize_text_field', $data );
|
||||
$this->simplified_contact = $this->simplified_address(
|
||||
$simplified_contact_info
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the data object with the shipping values from the request.
|
||||
*
|
||||
* @param array $data The data.
|
||||
* @return void
|
||||
*/
|
||||
protected function update_shipping_method( array $data ): void {
|
||||
if (
|
||||
array_key_exists(
|
||||
PropertiesDictionary::SHIPPING_METHOD,
|
||||
$data
|
||||
)
|
||||
) {
|
||||
$this->shipping_method = filter_var_array(
|
||||
$data[ PropertiesDictionary::SHIPPING_METHOD ],
|
||||
FILTER_SANITIZE_SPECIAL_CHARS
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the billing address.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function billing_address(): array {
|
||||
return $this->billing_address;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the shipping address.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function shipping_address(): array {
|
||||
return $this->shipping_address;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the shipping method.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function shipping_method(): array {
|
||||
return $this->shipping_method ?? array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if the shipping is needed.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function need_shipping(): bool {
|
||||
return $this->need_shipping ?? false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the product id.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function product_id(): string {
|
||||
return $this->product_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the product quantity.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function product_quantity(): string {
|
||||
return $this->product_quantity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the nonce.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function nonce() {
|
||||
return $this->nonce;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the simplified contact.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function simplified_contact() {
|
||||
return $this->simplified_contact;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the filtered request data.
|
||||
*
|
||||
* @return array|false|null
|
||||
*/
|
||||
public function get_filtered_request_data() {
|
||||
return filter_input_array(
|
||||
INPUT_POST,
|
||||
array(
|
||||
PropertiesDictionary::CALLER_PAGE => FILTER_SANITIZE_SPECIAL_CHARS,
|
||||
'woocommerce-process-checkout-nonce' => FILTER_SANITIZE_SPECIAL_CHARS,
|
||||
PropertiesDictionary::NEED_SHIPPING => FILTER_VALIDATE_BOOLEAN,
|
||||
PropertiesDictionary::SIMPLIFIED_CONTACT => array(
|
||||
'filter' => FILTER_SANITIZE_SPECIAL_CHARS,
|
||||
'flags' => FILTER_REQUIRE_ARRAY,
|
||||
),
|
||||
PropertiesDictionary::SHIPPING_CONTACT => array(
|
||||
'filter' => FILTER_SANITIZE_SPECIAL_CHARS,
|
||||
'flags' => FILTER_REQUIRE_ARRAY,
|
||||
),
|
||||
PropertiesDictionary::BILLING_CONTACT => array(
|
||||
'filter' => FILTER_SANITIZE_SPECIAL_CHARS,
|
||||
'flags' => FILTER_REQUIRE_ARRAY,
|
||||
),
|
||||
PropertiesDictionary::SHIPPING_METHOD => array(
|
||||
'filter' => FILTER_SANITIZE_SPECIAL_CHARS,
|
||||
'flags' => FILTER_REQUIRE_ARRAY,
|
||||
),
|
||||
PropertiesDictionary::PRODUCT_ID => FILTER_SANITIZE_NUMBER_INT,
|
||||
PropertiesDictionary::PRODUCT_QUANTITY => FILTER_SANITIZE_NUMBER_INT,
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
|
@ -21,7 +21,7 @@ use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
|
|||
*/
|
||||
class AppleProductStatus {
|
||||
|
||||
const APPLE_STATUS_CACHE_KEY = 'apple_pay_status_cache';
|
||||
const APPLE_STATUS_CACHE_KEY = 'apple_status_cache';
|
||||
|
||||
/**
|
||||
* The Cache.
|
||||
|
|
|
@ -79,7 +79,7 @@ class ApplepayModule implements ModuleInterface {
|
|||
}
|
||||
$this->load_assets( $c );
|
||||
$env = $c->get( 'onboarding.environment' );
|
||||
assert($env instanceof Environment);
|
||||
assert( $env instanceof Environment );
|
||||
$is_sandobx = $env->current_environment_is( Environment::SANDBOX );
|
||||
$this->load_domain_association_file( $is_sandobx );
|
||||
$this->render_buttons( $c );
|
||||
|
@ -100,7 +100,7 @@ class ApplepayModule implements ModuleInterface {
|
|||
*
|
||||
* @param boolean $is_sandbox The environment for this merchant.
|
||||
*/
|
||||
protected function load_domain_association_file($is_sandbox ): void {
|
||||
protected function load_domain_association_file( $is_sandbox ): void {
|
||||
if ( ! isset( $_SERVER['REQUEST_URI'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
@ -121,7 +121,7 @@ class ApplepayModule implements ModuleInterface {
|
|||
* @param ContainerInterface $c The container.
|
||||
* @return void
|
||||
*/
|
||||
public function load_assets(ContainerInterface $c ): void {
|
||||
public function load_assets( ContainerInterface $c ): void {
|
||||
add_action(
|
||||
'wp',
|
||||
function () use ( $c ) {
|
||||
|
@ -146,9 +146,9 @@ class ApplepayModule implements ModuleInterface {
|
|||
array(),
|
||||
$c->get( 'ppcp.asset-version' )
|
||||
);
|
||||
wp_enqueue_style( 'wc-ppcp-applepay');
|
||||
wp_enqueue_style( 'wc-ppcp-applepay' );
|
||||
wp_enqueue_script( 'wc-ppcp-applepay' );
|
||||
$data = $c->get( 'applepay.data_to_scripts' )->applePayScriptData();
|
||||
$data = $c->get( 'applepay.data_to_scripts' )->apple_pay_script_data();
|
||||
wp_localize_script(
|
||||
'wc-ppcp-applepay',
|
||||
'wc_ppcp_applepay',
|
||||
|
@ -177,13 +177,16 @@ class ApplepayModule implements ModuleInterface {
|
|||
* @param ContainerInterface $c The container.
|
||||
* @return void
|
||||
*/
|
||||
public function render_buttons(ContainerInterface $c ): void {
|
||||
public function render_buttons( ContainerInterface $c ): void {
|
||||
$button_enabled_product = $c->get( 'applepay.setting_button_enabled_product' );
|
||||
$button_enabled_cart = $c->get( 'applepay.setting_button_enabled_cart' );
|
||||
add_filter('woocommerce_paypal_payments_sdk_components_hook', function($components) {
|
||||
$components[] = 'applepay';
|
||||
return $components;
|
||||
});
|
||||
add_filter(
|
||||
'woocommerce_paypal_payments_sdk_components_hook',
|
||||
function( $components ) {
|
||||
$components[] = 'applepay';
|
||||
return $components;
|
||||
}
|
||||
);
|
||||
if ( $button_enabled_product ) {
|
||||
$render_placeholder = apply_filters( 'woocommerce_paypal_payments_applepay_render_hook_product', 'woocommerce_after_add_to_cart_form' );
|
||||
$render_placeholder = is_string( $render_placeholder ) ? $render_placeholder : 'woocommerce_after_add_to_cart_form';
|
||||
|
|
|
@ -10,14 +10,25 @@ declare(strict_types=1);
|
|||
namespace WooCommerce\PayPalCommerce\Applepay;
|
||||
|
||||
use Psr\Log\LoggerInterface;
|
||||
use WC_Cart;
|
||||
use WC_Checkout;
|
||||
use WC_Order;
|
||||
use WC_Session_Handler;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\OrderStatus;
|
||||
use WooCommerce\PayPalCommerce\Session\MemoryWcSession;
|
||||
use WooCommerce\PayPalCommerce\Session\SessionHandler;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Processor\OrderProcessor;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
|
||||
use WooCommerce\PayPalCommerce\Webhooks\Handler\RequestHandlerTrait;
|
||||
|
||||
/**
|
||||
* Class PayPalPaymentMethod
|
||||
*/
|
||||
class ApplepayPaymentMethod {
|
||||
|
||||
use RequestHandlerTrait;
|
||||
/**
|
||||
* The settings.
|
||||
*
|
||||
|
@ -34,20 +45,53 @@ class ApplepayPaymentMethod {
|
|||
* @var ResponsesToApple
|
||||
*/
|
||||
private $response_templates;
|
||||
|
||||
/**
|
||||
* @var array The old cart contents.
|
||||
*/
|
||||
private $old_cart_contents;
|
||||
|
||||
/**
|
||||
* The method id.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $id;
|
||||
/**
|
||||
* The method title.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $method_title;
|
||||
/**
|
||||
* The processor for orders.
|
||||
*
|
||||
* @var OrderProcessor
|
||||
*/
|
||||
protected $order_processor;
|
||||
/**
|
||||
* @var bool Whether to reload the cart after the order is processed.
|
||||
*/
|
||||
protected $reload_cart = false;
|
||||
|
||||
/**
|
||||
* PayPalPaymentMethod constructor.
|
||||
*
|
||||
* @param Settings $plugin_settings The settings.
|
||||
* @param LoggerInterface $logger The logger.
|
||||
* @param OrderProcessor $order_processor The Order processor.
|
||||
*/
|
||||
public function __construct(
|
||||
Settings $plugin_settings,
|
||||
LoggerInterface $logger
|
||||
LoggerInterface $logger,
|
||||
OrderProcessor $order_processor
|
||||
) {
|
||||
$this->plugin_settings = $plugin_settings;
|
||||
$this->plugin_settings = $plugin_settings;
|
||||
$this->response_templates = new ResponsesToApple();
|
||||
$this->logger = $logger;
|
||||
$this->logger = $logger;
|
||||
$this->id = 'applepay';
|
||||
$this->method_title = __( 'Apple Pay', 'woocommerce-paypal-payments' );
|
||||
$this->order_processor = $order_processor;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -73,7 +117,7 @@ class ApplepayPaymentMethod {
|
|||
$data['products'][0] = 'PAYMENT_METHODS';
|
||||
}
|
||||
$data['capabilities'][] = 'APPLE_PAY';
|
||||
$nonce = $data['operations'][0]['api_integration_preference']['rest_api_integration']['first_party_details']['seller_nonce'];
|
||||
$nonce = $data['operations'][0]['api_integration_preference']['rest_api_integration']['first_party_details']['seller_nonce'];
|
||||
$data['operations'][] = array(
|
||||
'operation' => 'API_INTEGRATION',
|
||||
'api_integration_preference' => array(
|
||||
|
@ -85,7 +129,7 @@ class ApplepayPaymentMethod {
|
|||
'PAYMENT',
|
||||
'REFUND',
|
||||
),
|
||||
'seller_nonce' => $nonce
|
||||
'seller_nonce' => $nonce,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -163,26 +207,27 @@ class ApplepayPaymentMethod {
|
|||
* It updates the amount paying information if needed
|
||||
* On error returns an array of errors to be handled by the script
|
||||
* On success returns the new contact data
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function update_shipping_contact(): void {
|
||||
$applepay_request_data_object = $this->applepay_data_object_http();
|
||||
if (!$this->is_nonce_valid()) {
|
||||
if ( ! $this->is_nonce_valid() ) {
|
||||
return;
|
||||
}
|
||||
$applepay_request_data_object->update_contact_data();
|
||||
if ($applepay_request_data_object->has_errors()) {
|
||||
$this->response_templates->response_with_data_errors($applepay_request_data_object->errors());
|
||||
if ( $applepay_request_data_object->has_errors() ) {
|
||||
$this->response_templates->response_with_data_errors( $applepay_request_data_object->errors() );
|
||||
return;
|
||||
}
|
||||
|
||||
if (!class_exists('WC_Countries')) {
|
||||
if ( ! class_exists( 'WC_Countries' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$countries = $this->create_wc_countries();
|
||||
$allowed_selling_countries = $countries->get_allowed_countries();
|
||||
$countries = $this->create_wc_countries();
|
||||
$allowed_selling_countries = $countries->get_allowed_countries();
|
||||
$allowed_shipping_countries = $countries->get_shipping_countries();
|
||||
$user_country = $applepay_request_data_object->simplified_contact()['country'];
|
||||
$user_country = $applepay_request_data_object->simplified_contact()['country'];
|
||||
$is_allowed_selling_country = array_key_exists(
|
||||
$user_country,
|
||||
$allowed_selling_countries
|
||||
|
@ -192,24 +237,27 @@ class ApplepayPaymentMethod {
|
|||
$user_country,
|
||||
$allowed_shipping_countries
|
||||
);
|
||||
$product_need_shipping = $applepay_request_data_object->need_shipping();
|
||||
$product_need_shipping = $applepay_request_data_object->need_shipping();
|
||||
|
||||
if (!$is_allowed_selling_country) {
|
||||
if ( ! $is_allowed_selling_country ) {
|
||||
$this->response_templates->response_with_data_errors(
|
||||
[['errorCode' => 'addressUnserviceable']]
|
||||
array( array( 'errorCode' => 'addressUnserviceable' ) )
|
||||
);
|
||||
return;
|
||||
}
|
||||
if ($product_need_shipping && !$is_allowed_shipping_country) {
|
||||
if ( $product_need_shipping && ! $is_allowed_shipping_country ) {
|
||||
$this->response_templates->response_with_data_errors(
|
||||
[['errorCode' => 'addressUnserviceable']]
|
||||
array( array( 'errorCode' => 'addressUnserviceable' ) )
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
$payment_details = $this->which_calculate_totals($applepay_request_data_object);
|
||||
$response = $this->response_templates->apple_formatted_response($payment_details);
|
||||
$this->response_templates->response_success($response);
|
||||
$cart_item_key = $this->prepare_cart($applepay_request_data_object);
|
||||
$cart = WC()->cart;
|
||||
$payment_details = $this->which_calculate_totals( $cart, $applepay_request_data_object );
|
||||
$this->clear_current_cart($cart, $cart_item_key);
|
||||
$this->reload_cart( $cart );
|
||||
$response = $this->response_templates->apple_formatted_response( $payment_details );
|
||||
$this->response_templates->response_success( $response );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -217,27 +265,55 @@ class ApplepayPaymentMethod {
|
|||
* It updates the amount paying information if needed
|
||||
* On error returns an array of errors to be handled by the script
|
||||
* On success returns the new contact data
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function update_shipping_method(): void {
|
||||
$applepay_request_data_object = $this->applepay_data_object_http();
|
||||
if (!$this->is_nonce_valid()) {
|
||||
if ( ! $this->is_nonce_valid() ) {
|
||||
return;
|
||||
}
|
||||
$applepay_request_data_object->update_method_data();
|
||||
if ($applepay_request_data_object->has_errors()) {
|
||||
$this->response_templates->response_with_data_errors($applepay_request_data_object->errors());
|
||||
if ( $applepay_request_data_object->has_errors() ) {
|
||||
$this->response_templates->response_with_data_errors( $applepay_request_data_object->errors() );
|
||||
}
|
||||
$paymentDetails = $this->which_calculate_totals($applepay_request_data_object);
|
||||
$response = $this->response_templates->apple_formatted_response($paymentDetails);
|
||||
$this->response_templates->response_success($response);
|
||||
$cart_item_key = $this->prepare_cart($applepay_request_data_object);
|
||||
$cart = WC()->cart;
|
||||
$payment_details = $this->which_calculate_totals( $cart, $applepay_request_data_object );
|
||||
$this->clear_current_cart($cart, $cart_item_key);
|
||||
$this->reload_cart( $cart );
|
||||
$response = $this->response_templates->apple_formatted_response( $payment_details );
|
||||
$this->response_templates->response_success( $response );
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to create a WC order from the data received from the ApplePay JS
|
||||
* On error returns an array of errors to be handled by the script
|
||||
* On success returns the new order data
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function create_wc_order(): void {
|
||||
public function create_wc_order() {
|
||||
$this->response_after_successful_result();
|
||||
$applepay_request_data_object = $this->applepay_data_object_http();
|
||||
$applepay_request_data_object->order_data('productDetail');
|
||||
$cart_item_key = $this->prepare_cart($applepay_request_data_object);
|
||||
$cart = WC()->cart;
|
||||
$this->which_calculate_totals($cart, $applepay_request_data_object );
|
||||
if (! $cart_item_key) {
|
||||
$this->response_templates->response_with_data_errors(
|
||||
array(
|
||||
array(
|
||||
'errorCode' => 'unableToProcess',
|
||||
'message' => 'Unable to process the order',
|
||||
),
|
||||
)
|
||||
);
|
||||
return;
|
||||
}
|
||||
$this->add_addresses_to_order($applepay_request_data_object);
|
||||
//add_action('woocommerce_checkout_order_processed', array($this, 'process_order_as_paid'), 10, 3);
|
||||
WC()->checkout()->process_checkout();
|
||||
$this->clear_current_cart($cart, $cart_item_key);
|
||||
$this->reload_cart( $cart );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -269,9 +345,8 @@ class ApplepayPaymentMethod {
|
|||
* Data Object to collect and validate all needed data collected
|
||||
* through HTTP
|
||||
*/
|
||||
protected function applepay_data_object_http(): ApplePayDataObjectHttp
|
||||
{
|
||||
return new ApplePayDataObjectHttp($this->logger);
|
||||
protected function applepay_data_object_http(): ApplePayDataObjectHttp {
|
||||
return new ApplePayDataObjectHttp( $this->logger );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -279,8 +354,7 @@ class ApplepayPaymentMethod {
|
|||
*
|
||||
* @return \WC_Countries
|
||||
*/
|
||||
protected function create_wc_countries()
|
||||
{
|
||||
protected function create_wc_countries() {
|
||||
return new \WC_Countries();
|
||||
}
|
||||
|
||||
|
@ -292,20 +366,23 @@ class ApplepayPaymentMethod {
|
|||
* @return array|bool
|
||||
*/
|
||||
protected function which_calculate_totals(
|
||||
$cart,
|
||||
$applepay_request_data_object
|
||||
) {
|
||||
|
||||
if ($applepay_request_data_object->caller_page === 'productDetail') {
|
||||
$address = $applepay_request_data_object->shipping_address() ?? $applepay_request_data_object->simplified_contact();
|
||||
if ( $applepay_request_data_object->caller_page === 'productDetail' ) {
|
||||
if (! assert($cart instanceof WC_Cart)) {
|
||||
return false;
|
||||
}
|
||||
return $this->calculate_totals_single_product(
|
||||
$applepay_request_data_object->product_id(),
|
||||
$applepay_request_data_object->product_quantity(),
|
||||
$applepay_request_data_object->simplified_contact(),
|
||||
$cart,
|
||||
$address,
|
||||
$applepay_request_data_object->shipping_method()
|
||||
);
|
||||
}
|
||||
if ($applepay_request_data_object->caller_page === 'cart') {
|
||||
if ( $applepay_request_data_object->caller_page === 'cart' ) {
|
||||
return $this->calculate_totals_cart_page(
|
||||
$applepay_request_data_object->simplified_contact(),
|
||||
$address,
|
||||
$applepay_request_data_object->shipping_method()
|
||||
);
|
||||
}
|
||||
|
@ -321,50 +398,37 @@ class ApplepayPaymentMethod {
|
|||
* @param $product_id
|
||||
* @param $product_quantity
|
||||
* @param $customer_address
|
||||
* @param null $shipping_method
|
||||
* @param null $shipping_method
|
||||
*/
|
||||
protected function calculate_totals_single_product(
|
||||
$product_id,
|
||||
$product_quantity,
|
||||
$cart,
|
||||
$customer_address,
|
||||
$shipping_method = null
|
||||
): array {
|
||||
|
||||
$results = [];
|
||||
$reload_cart = false;
|
||||
if (!WC()->cart->is_empty()) {
|
||||
$old_cart_contents = WC()->cart->get_cart_contents();
|
||||
foreach (array_keys($old_cart_contents) as $cart_item_key) {
|
||||
WC()->cart->remove_cart_item($cart_item_key);
|
||||
}
|
||||
$reload_cart = true;
|
||||
}
|
||||
$results = array();
|
||||
try {
|
||||
//I just care about apple address details
|
||||
$shipping_method_id = '';
|
||||
$shipping_methods_array = [];
|
||||
$selected_shipping_method = [];
|
||||
$this->customer_address($customer_address);
|
||||
$cart = WC()->cart;
|
||||
if ($shipping_method) {
|
||||
// I just care about apple address details
|
||||
$shipping_method_id = '';
|
||||
$shipping_methods_array = array();
|
||||
$selected_shipping_method = array();
|
||||
$this->customer_address( $customer_address );
|
||||
if ( $shipping_method ) {
|
||||
$shipping_method_id = $shipping_method['identifier'];
|
||||
WC()->session->set(
|
||||
'chosen_shipping_methods',
|
||||
[$shipping_method_id]
|
||||
array( $shipping_method_id )
|
||||
);
|
||||
}
|
||||
$cart_item_key = $cart->add_to_cart($product_id, $product_quantity);
|
||||
if ($cart->needs_shipping()) {
|
||||
if ( $cart->needs_shipping() ) {
|
||||
list(
|
||||
$shipping_methods_array, $selected_shipping_method
|
||||
) = $this->cart_shipping_methods(
|
||||
$cart,
|
||||
$customer_address,
|
||||
$shipping_method,
|
||||
$shipping_method_id
|
||||
);
|
||||
$cart,
|
||||
$customer_address,
|
||||
$shipping_method,
|
||||
$shipping_method_id
|
||||
);
|
||||
}
|
||||
|
||||
$cart->calculate_shipping();
|
||||
$cart->calculate_fees();
|
||||
$cart->calculate_totals();
|
||||
|
@ -374,15 +438,7 @@ class ApplepayPaymentMethod {
|
|||
$selected_shipping_method,
|
||||
$shipping_methods_array
|
||||
);
|
||||
|
||||
$cart->remove_cart_item($cart_item_key);
|
||||
$this->customer_address();
|
||||
if ($reload_cart) {
|
||||
foreach (array_keys($old_cart_contents) as $cart_item_key) {
|
||||
$cart->restore_cart_item($cart_item_key);
|
||||
}
|
||||
}
|
||||
} catch (Exception $exception) {
|
||||
} catch ( Exception $exception ) {
|
||||
}
|
||||
return $results;
|
||||
}
|
||||
|
@ -392,9 +448,8 @@ class ApplepayPaymentMethod {
|
|||
* calculations
|
||||
* If no parameter passed then it resets the customer to shop details
|
||||
*/
|
||||
protected function customer_address(array $address = [])
|
||||
{
|
||||
$base_location = wc_get_base_location();
|
||||
protected function customer_address( array $address = array() ) {
|
||||
$base_location = wc_get_base_location();
|
||||
$shop_country_code = $base_location['country'];
|
||||
WC()->customer->set_shipping_country(
|
||||
$address['country'] ?? $shop_country_code
|
||||
|
@ -425,62 +480,62 @@ class ApplepayPaymentMethod {
|
|||
$shipping_method_id
|
||||
): array {
|
||||
|
||||
$shipping_methods_array = [];
|
||||
$shipping_methods = WC()->shipping->calculate_shipping(
|
||||
$shipping_methods_array = array();
|
||||
$shipping_methods = WC()->shipping->calculate_shipping(
|
||||
$this->getShippingPackages(
|
||||
$customer_address,
|
||||
$cart->get_total('edit')
|
||||
$cart->get_total( 'edit' )
|
||||
)
|
||||
);
|
||||
$done = false;
|
||||
foreach ($shipping_methods[0]['rates'] as $rate) {
|
||||
$shipping_methods_array[] = [
|
||||
"label" => $rate->get_label(),
|
||||
"detail" => "",
|
||||
"amount" => $rate->get_cost(),
|
||||
"identifier" => $rate->get_id(),
|
||||
];
|
||||
if (!$done) {
|
||||
$done = true;
|
||||
$done = false;
|
||||
foreach ( $shipping_methods[0]['rates'] as $rate ) {
|
||||
$shipping_methods_array[] = array(
|
||||
'label' => $rate->get_label(),
|
||||
'detail' => '',
|
||||
'amount' => $rate->get_cost(),
|
||||
'identifier' => $rate->get_id(),
|
||||
);
|
||||
if ( ! $done ) {
|
||||
$done = true;
|
||||
$shipping_method_id = $shipping_method ? $shipping_method_id
|
||||
: $rate->get_id();
|
||||
WC()->session->set(
|
||||
'chosen_shipping_methods',
|
||||
[$shipping_method_id]
|
||||
array( $shipping_method_id )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$selected_shipping_method = $shipping_methods_array[0];
|
||||
if ($shipping_method) {
|
||||
if ( $shipping_method ) {
|
||||
$selected_shipping_method = $shipping_method;
|
||||
}
|
||||
|
||||
return [$shipping_methods_array, $selected_shipping_method];
|
||||
return array( $shipping_methods_array, $selected_shipping_method );
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets shipping packages for correct calculations
|
||||
*
|
||||
* @param $customer_address
|
||||
* @param $total
|
||||
*
|
||||
* @return mixed|void|null
|
||||
*/
|
||||
protected function getShippingPackages($customer_address, $total)
|
||||
{
|
||||
protected function getShippingPackages( $customer_address, $total ) {
|
||||
// Packages array for storing 'carts'
|
||||
$packages = [];
|
||||
$packages[0]['contents'] = WC()->cart->cart_contents;
|
||||
$packages[0]['contents_cost'] = $total;
|
||||
$packages[0]['applied_coupons'] = WC()->session->applied_coupon;
|
||||
$packages[0]['destination']['country'] = $customer_address['country'];
|
||||
$packages[0]['destination']['state'] = '';
|
||||
$packages[0]['destination']['postcode'] = $customer_address['postcode'];
|
||||
$packages[0]['destination']['city'] = $customer_address['city'];
|
||||
$packages[0]['destination']['address'] = '';
|
||||
$packages = array();
|
||||
$packages[0]['contents'] = WC()->cart->cart_contents;
|
||||
$packages[0]['contents_cost'] = $total;
|
||||
$packages[0]['applied_coupons'] = WC()->session->applied_coupon;
|
||||
$packages[0]['destination']['country'] = $customer_address['country'];
|
||||
$packages[0]['destination']['state'] = '';
|
||||
$packages[0]['destination']['postcode'] = $customer_address['postcode'];
|
||||
$packages[0]['destination']['city'] = $customer_address['city'];
|
||||
$packages[0]['destination']['address'] = '';
|
||||
$packages[0]['destination']['address_2'] = '';
|
||||
|
||||
return apply_filters('woocommerce_cart_shipping_packages', $packages);
|
||||
return apply_filters( 'woocommerce_cart_shipping_packages', $packages );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -495,22 +550,22 @@ class ApplepayPaymentMethod {
|
|||
$selected_shipping_method,
|
||||
$shipping_methods_array
|
||||
): array {
|
||||
$total = $cart->get_total('edit');
|
||||
$total = round($total, 2);
|
||||
return [
|
||||
'subtotal' => $cart->get_subtotal(),
|
||||
'shipping' => [
|
||||
$total = $cart->get_total( 'edit' );
|
||||
$total = round( $total, 2 );
|
||||
return array(
|
||||
'subtotal' => $cart->get_subtotal(),
|
||||
'shipping' => array(
|
||||
'amount' => $cart->needs_shipping()
|
||||
? $cart->get_shipping_total() : null,
|
||||
'label' => $cart->needs_shipping()
|
||||
'label' => $cart->needs_shipping()
|
||||
? $selected_shipping_method['label'] : null,
|
||||
],
|
||||
),
|
||||
|
||||
'shippingMethods' => $cart->needs_shipping()
|
||||
? $shipping_methods_array : null,
|
||||
'taxes' => $cart->get_total_tax(),
|
||||
'total' => $total,
|
||||
];
|
||||
'taxes' => $cart->get_total_tax(),
|
||||
'total' => $total,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -519,39 +574,39 @@ class ApplepayPaymentMethod {
|
|||
* method
|
||||
*
|
||||
* @param $customer_address
|
||||
* @param null $shipping_method
|
||||
* @param null $shipping_method
|
||||
*/
|
||||
protected function calculate_totals_cart_page(
|
||||
$customer_address = null,
|
||||
$shipping_method = null
|
||||
): array {
|
||||
|
||||
$results = [];
|
||||
if (WC()->cart->is_empty()) {
|
||||
return [];
|
||||
$results = array();
|
||||
if ( WC()->cart->is_empty() ) {
|
||||
return array();
|
||||
}
|
||||
try {
|
||||
$shipping_methods_array = [];
|
||||
$selected_shipping_method = [];
|
||||
//I just care about apple address details
|
||||
$this->customer_address($customer_address);
|
||||
$shipping_methods_array = array();
|
||||
$selected_shipping_method = array();
|
||||
// I just care about apple address details
|
||||
$this->customer_address( $customer_address );
|
||||
$cart = WC()->cart;
|
||||
if ($shipping_method) {
|
||||
if ( $shipping_method ) {
|
||||
WC()->session->set(
|
||||
'chosen_shipping_methods',
|
||||
[$shipping_method['identifier']]
|
||||
array( $shipping_method['identifier'] )
|
||||
);
|
||||
}
|
||||
|
||||
if ($cart->needs_shipping()) {
|
||||
if ( $cart->needs_shipping() ) {
|
||||
list(
|
||||
$shipping_methods_array, $selected_shipping_method
|
||||
) = $this->cart_shipping_methods(
|
||||
$cart,
|
||||
$customer_address,
|
||||
$shipping_method,
|
||||
$shipping_method['identifier']
|
||||
);
|
||||
$cart,
|
||||
$customer_address,
|
||||
$shipping_method,
|
||||
$shipping_method['identifier']
|
||||
);
|
||||
}
|
||||
$cart->calculate_shipping();
|
||||
$cart->calculate_fees();
|
||||
|
@ -564,7 +619,7 @@ class ApplepayPaymentMethod {
|
|||
);
|
||||
|
||||
$this->customer_address();
|
||||
} catch (Exception $e) {
|
||||
} catch ( Exception $e ) {
|
||||
}
|
||||
|
||||
return $results;
|
||||
|
@ -575,24 +630,22 @@ class ApplepayPaymentMethod {
|
|||
*
|
||||
* @param ApplePayDataObjectHttp $applepay_request_data_object
|
||||
* @param $order
|
||||
*
|
||||
*/
|
||||
protected function addAddressesToOrder(
|
||||
protected function add_addresses_to_order(
|
||||
ApplePayDataObjectHttp $applepay_request_data_object
|
||||
) {
|
||||
|
||||
add_action(
|
||||
'woocommerce_checkout_create_order',
|
||||
static function ($order, $data) use ($applepay_request_data_object) {
|
||||
if ($applepay_request_data_object->shipping_method() !== null) {
|
||||
$billing_address = $applepay_request_data_object->billing_address();
|
||||
static function ( $order, $data ) use ( $applepay_request_data_object ) {
|
||||
if ( $applepay_request_data_object->shipping_method() !== null ) {
|
||||
$billing_address = $applepay_request_data_object->billing_address();
|
||||
$shipping_address = $applepay_request_data_object->shipping_address();
|
||||
//apple puts email in shipping_address while we get it from WC's billing_address
|
||||
// apple puts email in shipping_address while we get it from WC's billing_address
|
||||
$billing_address['email'] = $shipping_address['email'];
|
||||
$billing_address['phone'] = $shipping_address['phone'];
|
||||
|
||||
$order->set_address($billing_address, 'billing');
|
||||
$order->set_address($shipping_address, 'shipping');
|
||||
$order->set_address( $billing_address, 'billing' );
|
||||
$order->set_address( $shipping_address, 'shipping' );
|
||||
}
|
||||
},
|
||||
10,
|
||||
|
@ -603,10 +656,14 @@ class ApplepayPaymentMethod {
|
|||
* Empty the cart to use for calculations
|
||||
* while saving its contents in a field
|
||||
*/
|
||||
protected function empty_current_cart()
|
||||
{
|
||||
foreach ($this->old_cart_contents as $cart_item_key => $value) {
|
||||
WC()->cart->remove_cart_item($cart_item_key);
|
||||
protected function save_old_cart() {
|
||||
$cart = WC()->cart;
|
||||
if ( $cart->is_empty() || ! assert($cart instanceof WC_Cart)) {
|
||||
return;
|
||||
}
|
||||
$this->old_cart_contents = $cart->get_cart_contents();
|
||||
foreach ( $this->old_cart_contents as $cart_item_key => $value ) {
|
||||
$cart->remove_cart_item( $cart_item_key );
|
||||
}
|
||||
$this->reload_cart = true;
|
||||
}
|
||||
|
@ -614,20 +671,21 @@ class ApplepayPaymentMethod {
|
|||
/**
|
||||
* @param WC_Cart $cart
|
||||
*/
|
||||
protected function reload_cart(WC_Cart $cart): void
|
||||
{
|
||||
foreach ($this->old_cart_contents as $cart_item_key => $value) {
|
||||
$cart->restore_cart_item($cart_item_key);
|
||||
protected function reload_cart( WC_Cart $cart ): void {
|
||||
if ( ! $this->reload_cart ) {
|
||||
return;
|
||||
}
|
||||
foreach ( $this->old_cart_contents as $cart_item_key => $value ) {
|
||||
$cart->restore_cart_item( $cart_item_key );
|
||||
}
|
||||
}
|
||||
|
||||
protected function response_after_successful_result(): void
|
||||
{
|
||||
protected function response_after_successful_result(): void {
|
||||
add_filter(
|
||||
'woocommerce_payment_successful_result',
|
||||
function ($result, $order_id) {
|
||||
function ( $result, $order_id ) {
|
||||
if (
|
||||
isset($result['result'])
|
||||
isset( $result['result'] )
|
||||
&& 'success' === $result['result']
|
||||
) {
|
||||
$this->response_templates->response_success(
|
||||
|
@ -641,7 +699,7 @@ class ApplepayPaymentMethod {
|
|||
$this->response_templates->authorization_result_response(
|
||||
'STATUS_FAILURE',
|
||||
0,
|
||||
[['errorCode' => 'unknown']]
|
||||
array( array( 'errorCode' => 'unknown' ) )
|
||||
)
|
||||
);
|
||||
}
|
||||
|
@ -651,4 +709,41 @@ class ApplepayPaymentMethod {
|
|||
2
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WC_Cart|null $cart
|
||||
* @param $cart_item_key
|
||||
* @return void
|
||||
*/
|
||||
public function clear_current_cart(?WC_Cart $cart, $cart_item_key): void
|
||||
{
|
||||
$cart->remove_cart_item($cart_item_key);
|
||||
$this->customer_address();
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the old cart, saves it, and creates a new one
|
||||
* @param ApplePayDataObjectHttp $applepay_request_data_object
|
||||
* @return bool | string The cart item key after adding to the new cart
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function prepare_cart(ApplePayDataObjectHttp $applepay_request_data_object): string
|
||||
{
|
||||
$this->save_old_cart();
|
||||
$cart = WC()->cart;
|
||||
return $cart->add_to_cart(
|
||||
(int) $applepay_request_data_object->product_id(),
|
||||
(int) $applepay_request_data_object->product_quantity());
|
||||
}
|
||||
|
||||
public function process_order_as_paid($order_id): void
|
||||
{
|
||||
$order = wc_get_order($order_id);
|
||||
if (!assert($order instanceof WC_Order)) {
|
||||
return;
|
||||
}
|
||||
$order->payment_complete();
|
||||
wc_reduce_stock_levels($order_id);
|
||||
$order->save();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,34 +1,43 @@
|
|||
<?php
|
||||
/**
|
||||
* Prepares the necessary data for the Apple button script.
|
||||
*
|
||||
* @package WooCommerce\PayPalCommerce\Applepay
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\Applepay;
|
||||
|
||||
/**
|
||||
* Class DataToAppleButtonScripts
|
||||
*/
|
||||
class DataToAppleButtonScripts {
|
||||
|
||||
/**
|
||||
* Sets the appropriate data to send to ApplePay script
|
||||
* Data differs between product page and cart page
|
||||
*
|
||||
* @param bool $is_block
|
||||
* @return array
|
||||
*/
|
||||
public function applePayScriptData( bool $isBlock = false ): array {
|
||||
public function apple_pay_script_data( bool $is_block = false ): array {
|
||||
$base_location = wc_get_base_location();
|
||||
$shopCountryCode = $base_location['country'];
|
||||
$currencyCode = get_woocommerce_currency();
|
||||
$totalLabel = get_bloginfo( 'name' );
|
||||
$shop_country_code = $base_location['country'];
|
||||
$currency_code = get_woocommerce_currency();
|
||||
$total_label = get_bloginfo( 'name' );
|
||||
if ( is_product() ) {
|
||||
return $this->dataForProductPage(
|
||||
$shopCountryCode,
|
||||
$currencyCode,
|
||||
$totalLabel
|
||||
return $this->data_for_product_page(
|
||||
$shop_country_code,
|
||||
$currency_code,
|
||||
$total_label
|
||||
);
|
||||
}
|
||||
if ( is_cart() || $isBlock ) {
|
||||
return $this->dataForCartPage(
|
||||
$shopCountryCode,
|
||||
$currencyCode,
|
||||
$totalLabel
|
||||
if ( is_cart() || $is_block ) {
|
||||
return $this->data_for_cart_page(
|
||||
$shop_country_code,
|
||||
$currency_code,
|
||||
$total_label
|
||||
);
|
||||
}
|
||||
return array();
|
||||
|
@ -41,7 +50,7 @@ class DataToAppleButtonScripts {
|
|||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function checkIfNeedShipping( $product ) {
|
||||
protected function check_if_need_shipping($product ) {
|
||||
if (
|
||||
! wc_shipping_enabled()
|
||||
|| 0 === wc_get_shipping_method_count(
|
||||
|
@ -60,64 +69,64 @@ class DataToAppleButtonScripts {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param $shopCountryCode
|
||||
* @param $currencyCode
|
||||
* @param $totalLabel
|
||||
* @param $shop_country_code
|
||||
* @param $currency_code
|
||||
* @param $tota_label
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function dataForProductPage(
|
||||
$shopCountryCode,
|
||||
$currencyCode,
|
||||
$totalLabel
|
||||
protected function data_for_product_page(
|
||||
$shop_country_code,
|
||||
$currency_code,
|
||||
$total_label
|
||||
) {
|
||||
|
||||
$product = wc_get_product( get_the_id() );
|
||||
if ( ! $product ) {
|
||||
return array();
|
||||
}
|
||||
$isVariation = false;
|
||||
$is_variation = false;
|
||||
if ( $product->get_type() === 'variable' || $product->get_type() === 'variable-subscription' ) {
|
||||
$isVariation = true;
|
||||
$is_variation = true;
|
||||
}
|
||||
$productNeedShipping = $this->checkIfNeedShipping( $product );
|
||||
$productId = get_the_id();
|
||||
$productPrice = $product->get_price();
|
||||
$productStock = $product->get_stock_status();
|
||||
$product_need_shipping = $this->check_if_need_shipping( $product );
|
||||
$product_id = get_the_id();
|
||||
$product_price = $product->get_price();
|
||||
$product_stock = $product->get_stock_status();
|
||||
|
||||
return array(
|
||||
'product' => array(
|
||||
'needShipping' => $productNeedShipping,
|
||||
'id' => $productId,
|
||||
'price' => $productPrice,
|
||||
'isVariation' => $isVariation,
|
||||
'stock' => $productStock,
|
||||
'needShipping' => $product_need_shipping,
|
||||
'id' => $product_id,
|
||||
'price' => $product_price,
|
||||
'isVariation' => $is_variation,
|
||||
'stock' => $product_stock,
|
||||
),
|
||||
'shop' => array(
|
||||
'countryCode' => $shopCountryCode,
|
||||
'currencyCode' => $currencyCode,
|
||||
'totalLabel' => $totalLabel,
|
||||
'countryCode' => $shop_country_code,
|
||||
'currencyCode' => $currency_code,
|
||||
'totalLabel' => $total_label,
|
||||
),
|
||||
'ajaxUrl' => admin_url( 'admin-ajax.php' ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $shopCountryCode
|
||||
* @param $currencyCode
|
||||
* @param $totalLabel
|
||||
* @param $shop_country_code
|
||||
* @param $currency_code
|
||||
* @param $total_label
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function dataForCartPage(
|
||||
$shopCountryCode,
|
||||
$currencyCode,
|
||||
$totalLabel
|
||||
protected function data_for_cart_page(
|
||||
$shop_country_code,
|
||||
$currency_code,
|
||||
$total_label
|
||||
) {
|
||||
|
||||
$cart = WC()->cart;
|
||||
$nonce = wp_nonce_field( 'woocommerce-process_checkout', 'woocommerce-process-checkout-nonce' );
|
||||
$buttonMarkup =
|
||||
$button_markup =
|
||||
'<div id="applepay-container">'
|
||||
. $nonce
|
||||
. '</div>';
|
||||
|
@ -127,12 +136,12 @@ class DataToAppleButtonScripts {
|
|||
'subtotal' => $cart->get_subtotal(),
|
||||
),
|
||||
'shop' => array(
|
||||
'countryCode' => $shopCountryCode,
|
||||
'currencyCode' => $currencyCode,
|
||||
'totalLabel' => $totalLabel,
|
||||
'countryCode' => $shop_country_code,
|
||||
'currencyCode' => $currency_code,
|
||||
'totalLabel' => $total_label,
|
||||
),
|
||||
'ajaxUrl' => admin_url( 'admin-ajax.php' ),
|
||||
'buttonMarkup' => $buttonMarkup,
|
||||
'buttonMarkup' => $button_markup,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
176
modules/ppcp-applepay/src/ResponsesToApple.php
Normal file
176
modules/ppcp-applepay/src/ResponsesToApple.php
Normal file
|
@ -0,0 +1,176 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\Applepay;
|
||||
|
||||
use Psr\Log\LoggerInterface;
|
||||
use WC_Payment_Gateway;
|
||||
|
||||
class ResponsesToApple {
|
||||
|
||||
/**
|
||||
* Returns the authorization response with according success/fail status
|
||||
* Adds the error list if provided to be handled by the script
|
||||
* On success it adds the redirection url
|
||||
*
|
||||
* @param $status 0 => success, 1 => error
|
||||
* @param string $order_id
|
||||
* @param array $error_list
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function authorization_result_response(
|
||||
$status,
|
||||
$order_id = '',
|
||||
$error_list = array(),
|
||||
$return_url = ''
|
||||
) {
|
||||
|
||||
$response = array();
|
||||
if ( $status === 'STATUS_SUCCESS' ) {
|
||||
$response['returnUrl'] = $return_url;
|
||||
$response['responseToApple'] = array( 'status' => 0 );
|
||||
} else {
|
||||
$response = array(
|
||||
'status' => 1,
|
||||
'errors' => $this->apple_pay_error( $error_list ),
|
||||
);
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an error response to be handled by the script
|
||||
*
|
||||
* @param array $errorList [['errorCode'=>required, 'contactField'=>'']]
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function response_with_data_errors( $errorList ) {
|
||||
$response = array();
|
||||
$response['errors'] = $this->apple_pay_error( $errorList );
|
||||
$response['newTotal'] = $this->apple_new_total_response(
|
||||
0,
|
||||
'pending'
|
||||
);
|
||||
wp_send_json_error( $response );
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a response formatted for ApplePay
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function apple_formatted_response( array $payment_details ) {
|
||||
$response = array();
|
||||
if ( $payment_details['shippingMethods'] ) {
|
||||
$response['newShippingMethods'] = $payment_details['shippingMethods'];
|
||||
}
|
||||
|
||||
$response['newLineItems'] = $this->apple_new_line_items_response(
|
||||
$payment_details
|
||||
);
|
||||
|
||||
$response['newTotal'] = $this->apple_new_total_response(
|
||||
$payment_details['total']
|
||||
);
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a success response to be handled by the script
|
||||
*/
|
||||
public function response_success( array $response ) {
|
||||
wp_send_json_success( $response );
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an array of errors formatted
|
||||
*
|
||||
* @param array $error_list
|
||||
* @param array $errors
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function apple_pay_error( $error_list, $errors = array() ) {
|
||||
foreach ( $error_list as $error ) {
|
||||
$errors[] = array(
|
||||
'code' => $error['errorCode'],
|
||||
'contactField' => $error['contactField'] ?? null,
|
||||
'message' => array_key_exists( 'contactField', $error )
|
||||
? sprintf( 'Missing %s', $error['contactField'] ) : '',
|
||||
);
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates NewTotals line
|
||||
*
|
||||
* @param $total
|
||||
*
|
||||
* @param string $type
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function apple_new_total_response( $total, string $type = 'final' ): array {
|
||||
return $this->apple_item_format(
|
||||
get_bloginfo( 'name' ),
|
||||
$total,
|
||||
$type
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates item line
|
||||
*
|
||||
* @param $subtotal_label
|
||||
* @param $subtotal
|
||||
* @param $type
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function apple_item_format( $subtotal_label, $subtotal, $type ): array {
|
||||
return array(
|
||||
'label' => $subtotal_label,
|
||||
'amount' => $subtotal,
|
||||
'type' => $type,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates NewLineItems line
|
||||
*
|
||||
* @return array[]
|
||||
*/
|
||||
protected function apple_new_line_items_response( array $payment_details ): array {
|
||||
$type = 'final';
|
||||
$response = array();
|
||||
$response[] = $this->apple_item_format(
|
||||
'Subtotal',
|
||||
round( floatval( $payment_details['subtotal'] ), 2 ),
|
||||
$type
|
||||
);
|
||||
|
||||
if ( $payment_details['shipping']['amount'] ) {
|
||||
$response[] = $this->apple_item_format(
|
||||
$payment_details['shipping']['label'] ?: '',
|
||||
round( floatval( $payment_details['shipping']['amount'] ), 2 ),
|
||||
$type
|
||||
);
|
||||
}
|
||||
$isset_fee_amount = isset( $payment_details['fee'] ) && isset( $payment_details['fee']['amount'] );
|
||||
if ( $isset_fee_amount ) {
|
||||
$response[] = $this->apple_item_format(
|
||||
$payment_details['fee']['label'] ?: '',
|
||||
round( floatval( $payment_details['fee']['amount'] ), 2 ),
|
||||
$type
|
||||
);
|
||||
}
|
||||
$response[] = $this->apple_item_format( 'Estimated Tax', round( floatval( $payment_details['taxes'] ), 2 ), $type );
|
||||
return $response;
|
||||
}
|
||||
}
|
|
@ -1162,7 +1162,14 @@ class SmartButton implements SmartButtonInterface {
|
|||
if ( $this->dcc_is_enabled() ) {
|
||||
$components[] = 'hosted-fields';
|
||||
}
|
||||
//return filterable array of components
|
||||
/**
|
||||
* Filter to add further components from the extensions.
|
||||
*
|
||||
* @internal Matches filter name in ApplePay extension.
|
||||
* @since TODO
|
||||
*
|
||||
* @param array $components The array of components already registered.
|
||||
*/
|
||||
return apply_filters( 'woocommerce_paypal_payments_sdk_components_hook', $components );
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue