mirror of
https://github.com/woocommerce/woocommerce-paypal-payments.git
synced 2025-09-04 08:47:23 +08:00
relocate dcc fields to gateway description, use \WC_Payment_Gateway_CC, reutilize theme styles for dcc fields as much as possible
This commit is contained in:
parent
e4b6a412ea
commit
084eb2a908
8 changed files with 132 additions and 151 deletions
|
@ -1,50 +0,0 @@
|
||||||
.ppcp-card-icon {
|
|
||||||
max-width: 50px;
|
|
||||||
margin-left: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ppcp-hosted-fields {
|
|
||||||
|
|
||||||
.ppcp-dcc-credit-card-wrapper {
|
|
||||||
width: 100%;
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 55% 1fr 1fr;
|
|
||||||
grid-template-rows: 1fr 1fr auto;
|
|
||||||
grid-column-gap: 15px;
|
|
||||||
margin-bottom: 15px;
|
|
||||||
|
|
||||||
label, span {
|
|
||||||
height: 30px;
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
overflow: hidden;
|
|
||||||
position: relative;
|
|
||||||
vertical-align: bottom;
|
|
||||||
font-size: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
label {
|
|
||||||
grid-row: 1/2;
|
|
||||||
}
|
|
||||||
span {
|
|
||||||
grid-row: 2/3;
|
|
||||||
background:white;
|
|
||||||
border: 1px #666;
|
|
||||||
padding: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
button {
|
|
||||||
grid-row: 3/4;
|
|
||||||
grid-column: 1/4;
|
|
||||||
}
|
|
||||||
|
|
||||||
label {
|
|
||||||
line-height: 30px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
const dccInputFactory = (original) => {
|
||||||
|
const styles = window.getComputedStyle(original);
|
||||||
|
const newElement = document.createElement('span');
|
||||||
|
newElement.setAttribute('id', original.id);
|
||||||
|
Object.values(styles).forEach( (prop) => {
|
||||||
|
newElement.style[prop] = '' + styles[prop];
|
||||||
|
});
|
||||||
|
return newElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default dccInputFactory;
|
|
@ -1,3 +1,5 @@
|
||||||
|
import dccInputFactory from "../Helper/DccInputFactory";
|
||||||
|
|
||||||
class CreditCardRenderer {
|
class CreditCardRenderer {
|
||||||
|
|
||||||
constructor(defaultConfig, errorHandler) {
|
constructor(defaultConfig, errorHandler) {
|
||||||
|
@ -23,28 +25,46 @@ class CreditCardRenderer {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const gateWayBox = document.querySelector('.payment_box.payment_method_ppcp-credit-card-gateway');
|
||||||
|
const oldDisplayStyle = gateWayBox.style.display;
|
||||||
|
gateWayBox.style.display = 'block';
|
||||||
document.querySelector('#ppcp-hide-dcc').parentNode.removeChild(document.querySelector('#ppcp-hide-dcc'));
|
document.querySelector('#ppcp-hide-dcc').parentNode.removeChild(document.querySelector('#ppcp-hide-dcc'));
|
||||||
|
|
||||||
|
const cardNumberField = document.querySelector('#ppcp-credit-card-gateway-card-number');
|
||||||
|
const cardNumber = dccInputFactory(cardNumberField);
|
||||||
|
cardNumberField.parentNode.replaceChild(cardNumber, cardNumberField);
|
||||||
|
|
||||||
|
const cardExpiryField = document.querySelector('#ppcp-credit-card-gateway-card-expiry');
|
||||||
|
const cardExpiry = dccInputFactory(cardExpiryField);
|
||||||
|
cardExpiryField.parentNode.replaceChild(cardExpiry, cardExpiryField);
|
||||||
|
|
||||||
|
const cardCodeField = document.querySelector('#ppcp-credit-card-gateway-card-cvc');
|
||||||
|
const cardCode = dccInputFactory(cardCodeField);
|
||||||
|
cardCodeField.parentNode.replaceChild(cardCode, cardCodeField);
|
||||||
|
|
||||||
|
gateWayBox.style.display = oldDisplayStyle;
|
||||||
|
|
||||||
|
const formWrapper = '.payment_box payment_method_ppcp-credit-card-gateway';
|
||||||
if (
|
if (
|
||||||
this.defaultConfig.enforce_vault
|
this.defaultConfig.enforce_vault
|
||||||
&& document.querySelector(wrapper + ' .ppcp-credit-card-vault')
|
&& document.querySelector(formWrapper + ' .ppcp-credit-card-vault')
|
||||||
) {
|
) {
|
||||||
document.querySelector(wrapper + ' .ppcp-credit-card-vault').checked = true;
|
document.querySelector(formWrapper + ' .ppcp-credit-card-vault').checked = true;
|
||||||
document.querySelector(wrapper + ' .ppcp-credit-card-vault').setAttribute('disabled', true);
|
document.querySelector(formWrapper + ' .ppcp-credit-card-vault').setAttribute('disabled', true);
|
||||||
}
|
}
|
||||||
paypal.HostedFields.render({
|
paypal.HostedFields.render({
|
||||||
createOrder: contextConfig.createOrder,
|
createOrder: contextConfig.createOrder,
|
||||||
fields: {
|
fields: {
|
||||||
number: {
|
number: {
|
||||||
selector: wrapper + ' .ppcp-credit-card',
|
selector: '#ppcp-credit-card-gateway-card-number',
|
||||||
placeholder: this.defaultConfig.hosted_fields.labels.credit_card_number,
|
placeholder: this.defaultConfig.hosted_fields.labels.credit_card_number,
|
||||||
},
|
},
|
||||||
cvv: {
|
cvv: {
|
||||||
selector: wrapper + ' .ppcp-cvv',
|
selector: '#ppcp-credit-card-gateway-card-cvc',
|
||||||
placeholder: this.defaultConfig.hosted_fields.labels.cvv,
|
placeholder: this.defaultConfig.hosted_fields.labels.cvv,
|
||||||
},
|
},
|
||||||
expirationDate: {
|
expirationDate: {
|
||||||
selector: wrapper + ' .ppcp-expiration-date',
|
selector: '#ppcp-credit-card-gateway-card-expiry',
|
||||||
placeholder: this.defaultConfig.hosted_fields.labels.mm_yyyy,
|
placeholder: this.defaultConfig.hosted_fields.labels.mm_yyyy,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,8 +99,8 @@ class CreditCardRenderer {
|
||||||
hostedFields.on('inputSubmitRequest', function () {
|
hostedFields.on('inputSubmitRequest', function () {
|
||||||
submitEvent(null);
|
submitEvent(null);
|
||||||
});
|
});
|
||||||
document.querySelector(wrapper).addEventListener(
|
document.querySelector(wrapper + ' button').addEventListener(
|
||||||
'submit',
|
'click',
|
||||||
submitEvent
|
submitEvent
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -88,7 +108,7 @@ class CreditCardRenderer {
|
||||||
document.querySelector('#payment_method_ppcp-credit-card-gateway').addEventListener(
|
document.querySelector('#payment_method_ppcp-credit-card-gateway').addEventListener(
|
||||||
'click',
|
'click',
|
||||||
() => {
|
() => {
|
||||||
document.querySelector('label[for=ppcp-credit-card-ppcp-hosted-fields]').click();
|
document.querySelector('label[for=ppcp-credit-card-gateway-card-number]').click();
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -313,15 +313,6 @@ class SmartButton implements SmartButtonInterface {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( $this->settings->has( 'dcc_enabled' ) && $this->settings->get( 'dcc_enabled' ) ) {
|
|
||||||
wp_enqueue_style(
|
|
||||||
'ppcp-hosted-fields',
|
|
||||||
$this->module_url . '/assets/css/hosted-fields.css',
|
|
||||||
array(),
|
|
||||||
1
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
$load_script = false;
|
$load_script = false;
|
||||||
if ( is_checkout() && $this->settings->has( 'dcc_enabled' ) && $this->settings->get( 'dcc_enabled' ) ) {
|
if ( is_checkout() && $this->settings->has( 'dcc_enabled' ) && $this->settings->get( 'dcc_enabled' ) ) {
|
||||||
$load_script = true;
|
$load_script = true;
|
||||||
|
@ -498,21 +489,9 @@ class SmartButton implements SmartButtonInterface {
|
||||||
) : '';
|
) : '';
|
||||||
|
|
||||||
printf(
|
printf(
|
||||||
'<form id="%1$s">
|
'<div id="%1$s">
|
||||||
<div class="ppcp-dcc-credit-card-wrapper" style="display: none">
|
<button class="button alt">%6$s</button>
|
||||||
<label for="ppcp-credit-card-%1$s">%2$s</label>
|
</div><div id="payments-sdk__contingency-lightbox"></div><style id="ppcp-hide-dcc">.payment_method_ppcp-credit-card-gateway {display:none;}</style>',
|
||||||
<span id="ppcp-credit-card-%1$s" class="ppcp-credit-card"></span>
|
|
||||||
<label for="ppcp-expiration-date-%1$s">%3$s</label>
|
|
||||||
<span
|
|
||||||
id="ppcp-expiration-date-%1$s"
|
|
||||||
class="ppcp-expiration-date"
|
|
||||||
></span>
|
|
||||||
<label for="ppcp-cvv-%1$s">%4$s</label>
|
|
||||||
<span id="ppcp-cvv-%1$s" class="ppcp-cvv"></span>
|
|
||||||
%5$s
|
|
||||||
<button class="button alt">%6$s</button>
|
|
||||||
</div>
|
|
||||||
</form><div id="payments-sdk__contingency-lightbox"></div><style id="ppcp-hide-dcc">.payment_method_ppcp-credit-card-gateway {display:none;}</style>',
|
|
||||||
esc_attr( $id ),
|
esc_attr( $id ),
|
||||||
esc_html__( 'Credit Card number', 'paypal-payments-for-woocommerce' ),
|
esc_html__( 'Credit Card number', 'paypal-payments-for-woocommerce' ),
|
||||||
esc_html__( 'Expiration', 'paypal-payments-for-woocommerce' ),
|
esc_html__( 'Expiration', 'paypal-payments-for-woocommerce' ),
|
||||||
|
|
|
@ -6,8 +6,7 @@ module.exports = {
|
||||||
mode: isProduction ? 'production' : 'development',
|
mode: isProduction ? 'production' : 'development',
|
||||||
target: 'web',
|
target: 'web',
|
||||||
entry: {
|
entry: {
|
||||||
button: path.resolve('./resources/js/button.js'),
|
button: path.resolve('./resources/js/button.js')
|
||||||
hostedfields: path.resolve('./resources/css/hosted-fields.scss'),
|
|
||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
path: path.resolve(__dirname, 'assets/'),
|
path: path.resolve(__dirname, 'assets/'),
|
||||||
|
|
|
@ -19,7 +19,9 @@ use Psr\Container\ContainerInterface;
|
||||||
/**
|
/**
|
||||||
* Class CreditCardGateway
|
* Class CreditCardGateway
|
||||||
*/
|
*/
|
||||||
class CreditCardGateway extends PayPalGateway {
|
class CreditCardGateway extends \WC_Payment_Gateway_CC {
|
||||||
|
|
||||||
|
use ProcessPaymentTrait;
|
||||||
|
|
||||||
const ID = 'ppcp-credit-card-gateway';
|
const ID = 'ppcp-credit-card-gateway';
|
||||||
|
|
||||||
|
@ -76,6 +78,7 @@ class CreditCardGateway extends PayPalGateway {
|
||||||
'subscription_payment_method_change_customer',
|
'subscription_payment_method_change_customer',
|
||||||
'subscription_payment_method_change_admin',
|
'subscription_payment_method_change_admin',
|
||||||
'multiple_subscriptions',
|
'multiple_subscriptions',
|
||||||
|
'credit_card_form_cvc_on_saved_method',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,8 @@ use Psr\Container\ContainerInterface;
|
||||||
*/
|
*/
|
||||||
class PayPalGateway extends \WC_Payment_Gateway {
|
class PayPalGateway extends \WC_Payment_Gateway {
|
||||||
|
|
||||||
|
use ProcessPaymentTrait;
|
||||||
|
|
||||||
const ID = 'ppcp-gateway';
|
const ID = 'ppcp-gateway';
|
||||||
const CAPTURED_META_KEY = '_ppcp_paypal_captured';
|
const CAPTURED_META_KEY = '_ppcp_paypal_captured';
|
||||||
const INTENT_META_KEY = '_ppcp_paypal_intent';
|
const INTENT_META_KEY = '_ppcp_paypal_intent';
|
||||||
|
@ -168,71 +170,6 @@ class PayPalGateway extends \WC_Payment_Gateway {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Process a payment for an WooCommerce order.
|
|
||||||
*
|
|
||||||
* @param int $order_id The WooCommerce order id.
|
|
||||||
*
|
|
||||||
* @return array|null
|
|
||||||
*/
|
|
||||||
public function process_payment( $order_id ) {
|
|
||||||
global $woocommerce;
|
|
||||||
$wc_order = wc_get_order( $order_id );
|
|
||||||
if ( ! is_a( $wc_order, \WC_Order::class ) ) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If the WC_Order is payed through the approved webhook.
|
|
||||||
*/
|
|
||||||
//phpcs:disable WordPress.Security.NonceVerification.Recommended
|
|
||||||
if ( isset( $_REQUEST['ppcp-resume-order'] ) && $wc_order->has_status( 'processing' ) ) {
|
|
||||||
$this->session_handler->destroy_session_data();
|
|
||||||
return array(
|
|
||||||
'result' => 'success',
|
|
||||||
'redirect' => $this->get_return_url( $wc_order ),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
//phpcs:enable WordPress.Security.NonceVerification.Recommended
|
|
||||||
|
|
||||||
try {
|
|
||||||
if ( $this->order_processor->process( $wc_order, $woocommerce ) ) {
|
|
||||||
$this->session_handler->destroy_session_data();
|
|
||||||
return array(
|
|
||||||
'result' => 'success',
|
|
||||||
'redirect' => $this->get_return_url( $wc_order ),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} catch ( PayPalApiException $error ) {
|
|
||||||
if ( $error->has_detail( 'INSTRUMENT_DECLINED' ) ) {
|
|
||||||
$this->session_handler->increment_insufficient_funding_tries();
|
|
||||||
$host = $this->config->has( 'sandbox_on' ) && $this->config->get( 'sandbox_on' ) ?
|
|
||||||
'https://www.sandbox.paypal.com/' : 'https://www.paypal.com/';
|
|
||||||
$url = $host . 'checkoutnow?token=' . $this->session_handler->order()->id();
|
|
||||||
if ( $this->session_handler->insufficient_funding_tries() >= 3 ) {
|
|
||||||
$this->session_handler->destroy_session_data();
|
|
||||||
wc_add_notice(
|
|
||||||
__( 'Please use a different payment method.', 'paypal-payments-for-woocommerce' ),
|
|
||||||
'error'
|
|
||||||
);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return array(
|
|
||||||
'result' => 'success',
|
|
||||||
'redirect' => $url,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->session_handler->destroy_session_data();
|
|
||||||
}
|
|
||||||
wc_add_notice(
|
|
||||||
$this->order_processor->last_error(),
|
|
||||||
'error'
|
|
||||||
);
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Captures an authorized payment for an WooCommerce order.
|
* Captures an authorized payment for an WooCommerce order.
|
||||||
*
|
*
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* The process_payment functionality for the both gateways.
|
||||||
|
*
|
||||||
|
* @package WooCommerce\PayPalCommerce\WcGateway\Gateway
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare( strict_types=1 );
|
||||||
|
|
||||||
|
namespace WooCommerce\PayPalCommerce\WcGateway\Gateway;
|
||||||
|
|
||||||
|
use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Trait ProcessPaymentTrait
|
||||||
|
*/
|
||||||
|
trait ProcessPaymentTrait {
|
||||||
|
/**
|
||||||
|
* Process a payment for an WooCommerce order.
|
||||||
|
*
|
||||||
|
* @param int $order_id The WooCommerce order id.
|
||||||
|
*
|
||||||
|
* @return array|null
|
||||||
|
*/
|
||||||
|
public function process_payment( $order_id ) {
|
||||||
|
global $woocommerce;
|
||||||
|
$wc_order = wc_get_order( $order_id );
|
||||||
|
if ( ! is_a( $wc_order, \WC_Order::class ) ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the WC_Order is payed through the approved webhook.
|
||||||
|
*/
|
||||||
|
//phpcs:disable WordPress.Security.NonceVerification.Recommended
|
||||||
|
if ( isset( $_REQUEST['ppcp-resume-order'] ) && $wc_order->has_status( 'processing' ) ) {
|
||||||
|
$this->session_handler->destroy_session_data();
|
||||||
|
return array(
|
||||||
|
'result' => 'success',
|
||||||
|
'redirect' => $this->get_return_url( $wc_order ),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
//phpcs:enable WordPress.Security.NonceVerification.Recommended
|
||||||
|
|
||||||
|
try {
|
||||||
|
if ( $this->order_processor->process( $wc_order, $woocommerce ) ) {
|
||||||
|
$this->session_handler->destroy_session_data();
|
||||||
|
return array(
|
||||||
|
'result' => 'success',
|
||||||
|
'redirect' => $this->get_return_url( $wc_order ),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} catch ( PayPalApiException $error ) {
|
||||||
|
if ( $error->has_detail( 'INSTRUMENT_DECLINED' ) ) {
|
||||||
|
$this->session_handler->increment_insufficient_funding_tries();
|
||||||
|
$host = $this->config->has( 'sandbox_on' ) && $this->config->get( 'sandbox_on' ) ?
|
||||||
|
'https://www.sandbox.paypal.com/' : 'https://www.paypal.com/';
|
||||||
|
$url = $host . 'checkoutnow?token=' . $this->session_handler->order()->id();
|
||||||
|
if ( $this->session_handler->insufficient_funding_tries() >= 3 ) {
|
||||||
|
$this->session_handler->destroy_session_data();
|
||||||
|
wc_add_notice(
|
||||||
|
__( 'Please use a different payment method.', 'paypal-payments-for-woocommerce' ),
|
||||||
|
'error'
|
||||||
|
);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return array(
|
||||||
|
'result' => 'success',
|
||||||
|
'redirect' => $url,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->session_handler->destroy_session_data();
|
||||||
|
}
|
||||||
|
wc_add_notice(
|
||||||
|
$this->order_processor->last_error(),
|
||||||
|
'error'
|
||||||
|
);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue