mirror of
https://github.com/woocommerce/woocommerce-paypal-payments.git
synced 2025-09-06 10:55:00 +08:00
Add card fields (WIP)
This commit is contained in:
parent
4edf9c1f46
commit
692d3672c4
11 changed files with 184 additions and 2516 deletions
|
@ -1,6 +1,5 @@
|
|||
import dccInputFactory from "../Helper/DccInputFactory";
|
||||
import {show} from "../Helper/Hiding";
|
||||
import Product from "../Entity/Product";
|
||||
|
||||
class CreditCardRenderer {
|
||||
|
||||
|
@ -25,141 +24,208 @@ class CreditCardRenderer {
|
|||
) {
|
||||
return;
|
||||
}
|
||||
if (
|
||||
typeof paypal.HostedFields === 'undefined'
|
||||
|| ! paypal.HostedFields.isEligible()
|
||||
) {
|
||||
const wrapperElement = document.querySelector(wrapper);
|
||||
wrapperElement.parentNode.removeChild(wrapperElement);
|
||||
|
||||
if (typeof paypal.HostedFields !== 'undefined' && paypal.HostedFields.isEligible()) {
|
||||
const buttonSelector = wrapper + ' button';
|
||||
|
||||
if (this.currentHostedFieldsInstance) {
|
||||
this.currentHostedFieldsInstance.teardown()
|
||||
.catch(err => console.error(`Hosted fields teardown error: ${err}`));
|
||||
this.currentHostedFieldsInstance = null;
|
||||
}
|
||||
|
||||
const gateWayBox = document.querySelector('.payment_box.payment_method_ppcp-credit-card-gateway');
|
||||
if(! gateWayBox) {
|
||||
return
|
||||
}
|
||||
const oldDisplayStyle = gateWayBox.style.display;
|
||||
gateWayBox.style.display = 'block';
|
||||
|
||||
const hideDccGateway = document.querySelector('#ppcp-hide-dcc');
|
||||
if (hideDccGateway) {
|
||||
hideDccGateway.parentNode.removeChild(hideDccGateway);
|
||||
}
|
||||
|
||||
const cardNumberField = document.querySelector('#ppcp-credit-card-gateway-card-number');
|
||||
|
||||
const stylesRaw = window.getComputedStyle(cardNumberField);
|
||||
let styles = {};
|
||||
Object.values(stylesRaw).forEach( (prop) => {
|
||||
if (! stylesRaw[prop]) {
|
||||
return;
|
||||
}
|
||||
styles[prop] = '' + stylesRaw[prop];
|
||||
});
|
||||
|
||||
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 (
|
||||
this.defaultConfig.enforce_vault
|
||||
&& document.querySelector(formWrapper + ' .ppcp-credit-card-vault')
|
||||
) {
|
||||
document.querySelector(formWrapper + ' .ppcp-credit-card-vault').checked = true;
|
||||
document.querySelector(formWrapper + ' .ppcp-credit-card-vault').setAttribute('disabled', true);
|
||||
}
|
||||
paypal.HostedFields.render({
|
||||
createOrder: contextConfig.createOrder,
|
||||
styles: {
|
||||
'input': styles
|
||||
},
|
||||
fields: {
|
||||
number: {
|
||||
selector: '#ppcp-credit-card-gateway-card-number',
|
||||
placeholder: this.defaultConfig.hosted_fields.labels.credit_card_number,
|
||||
},
|
||||
cvv: {
|
||||
selector: '#ppcp-credit-card-gateway-card-cvc',
|
||||
placeholder: this.defaultConfig.hosted_fields.labels.cvv,
|
||||
},
|
||||
expirationDate: {
|
||||
selector: '#ppcp-credit-card-gateway-card-expiry',
|
||||
placeholder: this.defaultConfig.hosted_fields.labels.mm_yy,
|
||||
}
|
||||
}
|
||||
}).then(hostedFields => {
|
||||
document.dispatchEvent(new CustomEvent("hosted_fields_loaded"));
|
||||
this.currentHostedFieldsInstance = hostedFields;
|
||||
|
||||
hostedFields.on('inputSubmitRequest', () => {
|
||||
this._submit(contextConfig);
|
||||
});
|
||||
hostedFields.on('cardTypeChange', (event) => {
|
||||
if ( ! event.cards.length ) {
|
||||
this.cardValid = false;
|
||||
return;
|
||||
}
|
||||
const validCards = this.defaultConfig.hosted_fields.valid_cards;
|
||||
this.cardValid = validCards.indexOf(event.cards[0].type) !== -1;
|
||||
|
||||
const className = this._cardNumberFiledCLassNameByCardType(event.cards[0].type);
|
||||
this._recreateElementClassAttribute(cardNumber, cardNumberField.className);
|
||||
if (event.cards.length === 1) {
|
||||
cardNumber.classList.add(className);
|
||||
}
|
||||
})
|
||||
hostedFields.on('validityChange', (event) => {
|
||||
this.formValid = Object.keys(event.fields).every(function (key) {
|
||||
return event.fields[key].isValid;
|
||||
});
|
||||
});
|
||||
hostedFields.on('empty', (event) => {
|
||||
this._recreateElementClassAttribute(cardNumber, cardNumberField.className);
|
||||
this.emptyFields.add(event.emittedBy);
|
||||
});
|
||||
hostedFields.on('notEmpty', (event) => {
|
||||
this.emptyFields.delete(event.emittedBy);
|
||||
});
|
||||
|
||||
show(buttonSelector);
|
||||
|
||||
if (document.querySelector(wrapper).getAttribute('data-ppcp-subscribed') !== true) {
|
||||
document.querySelector(buttonSelector).addEventListener(
|
||||
'click',
|
||||
event => {
|
||||
event.preventDefault();
|
||||
this._submit(contextConfig);
|
||||
}
|
||||
);
|
||||
|
||||
document.querySelector(wrapper).setAttribute('data-ppcp-subscribed', true);
|
||||
}
|
||||
});
|
||||
|
||||
document.querySelector('#payment_method_ppcp-credit-card-gateway').addEventListener(
|
||||
'click',
|
||||
() => {
|
||||
document.querySelector('label[for=ppcp-credit-card-gateway-card-number]').click();
|
||||
}
|
||||
)
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const buttonSelector = wrapper + ' button';
|
||||
if (typeof paypal.CardFields !== 'undefined') {
|
||||
const buttonSelector = wrapper + ' button';
|
||||
|
||||
if (this.currentHostedFieldsInstance) {
|
||||
this.currentHostedFieldsInstance.teardown()
|
||||
.catch(err => console.error(`Hosted fields teardown error: ${err}`));
|
||||
this.currentHostedFieldsInstance = null;
|
||||
}
|
||||
|
||||
const gateWayBox = document.querySelector('.payment_box.payment_method_ppcp-credit-card-gateway');
|
||||
if(! gateWayBox) {
|
||||
return
|
||||
}
|
||||
const oldDisplayStyle = gateWayBox.style.display;
|
||||
gateWayBox.style.display = 'block';
|
||||
|
||||
const hideDccGateway = document.querySelector('#ppcp-hide-dcc');
|
||||
if (hideDccGateway) {
|
||||
hideDccGateway.parentNode.removeChild(hideDccGateway);
|
||||
}
|
||||
|
||||
const cardNumberField = document.querySelector('#ppcp-credit-card-gateway-card-number');
|
||||
|
||||
const stylesRaw = window.getComputedStyle(cardNumberField);
|
||||
let styles = {};
|
||||
Object.values(stylesRaw).forEach( (prop) => {
|
||||
if (! stylesRaw[prop]) {
|
||||
return;
|
||||
const gateWayBox = document.querySelector('.payment_box.payment_method_ppcp-credit-card-gateway');
|
||||
if(! gateWayBox) {
|
||||
return
|
||||
}
|
||||
styles[prop] = '' + stylesRaw[prop];
|
||||
});
|
||||
const oldDisplayStyle = gateWayBox.style.display;
|
||||
gateWayBox.style.display = 'block';
|
||||
|
||||
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 (
|
||||
this.defaultConfig.enforce_vault
|
||||
&& document.querySelector(formWrapper + ' .ppcp-credit-card-vault')
|
||||
) {
|
||||
document.querySelector(formWrapper + ' .ppcp-credit-card-vault').checked = true;
|
||||
document.querySelector(formWrapper + ' .ppcp-credit-card-vault').setAttribute('disabled', true);
|
||||
}
|
||||
paypal.HostedFields.render({
|
||||
createOrder: contextConfig.createOrder,
|
||||
styles: {
|
||||
'input': styles
|
||||
},
|
||||
fields: {
|
||||
number: {
|
||||
selector: '#ppcp-credit-card-gateway-card-number',
|
||||
placeholder: this.defaultConfig.hosted_fields.labels.credit_card_number,
|
||||
},
|
||||
cvv: {
|
||||
selector: '#ppcp-credit-card-gateway-card-cvc',
|
||||
placeholder: this.defaultConfig.hosted_fields.labels.cvv,
|
||||
},
|
||||
expirationDate: {
|
||||
selector: '#ppcp-credit-card-gateway-card-expiry',
|
||||
placeholder: this.defaultConfig.hosted_fields.labels.mm_yy,
|
||||
}
|
||||
const hideDccGateway = document.querySelector('#ppcp-hide-dcc');
|
||||
if (hideDccGateway) {
|
||||
hideDccGateway.parentNode.removeChild(hideDccGateway);
|
||||
}
|
||||
}).then(hostedFields => {
|
||||
document.dispatchEvent(new CustomEvent("hosted_fields_loaded"));
|
||||
this.currentHostedFieldsInstance = hostedFields;
|
||||
|
||||
hostedFields.on('inputSubmitRequest', () => {
|
||||
this._submit(contextConfig);
|
||||
});
|
||||
hostedFields.on('cardTypeChange', (event) => {
|
||||
if ( ! event.cards.length ) {
|
||||
this.cardValid = false;
|
||||
const cardNumberField = document.querySelector('#ppcp-credit-card-gateway-card-number');
|
||||
const stylesRaw = window.getComputedStyle(cardNumberField);
|
||||
let styles = {};
|
||||
Object.values(stylesRaw).forEach( (prop) => {
|
||||
if (! stylesRaw[prop]) {
|
||||
return;
|
||||
}
|
||||
const validCards = this.defaultConfig.hosted_fields.valid_cards;
|
||||
this.cardValid = validCards.indexOf(event.cards[0].type) !== -1;
|
||||
styles[prop] = '' + stylesRaw[prop];
|
||||
});
|
||||
const cardNumber = dccInputFactory(cardNumberField);
|
||||
cardNumberField.parentNode.replaceChild(cardNumber, cardNumberField);
|
||||
|
||||
const className = this._cardNumberFiledCLassNameByCardType(event.cards[0].type);
|
||||
this._recreateElementClassAttribute(cardNumber, cardNumberField.className);
|
||||
if (event.cards.length === 1) {
|
||||
cardNumber.classList.add(className);
|
||||
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);
|
||||
|
||||
const cardField = paypal.CardFields({
|
||||
createOrder: contextConfig.createOrder,
|
||||
onApprove: function (data) {
|
||||
return contextConfig.onApprove(data);
|
||||
},
|
||||
onError: function (error) {
|
||||
console.error(error)
|
||||
}
|
||||
})
|
||||
hostedFields.on('validityChange', (event) => {
|
||||
this.formValid = Object.keys(event.fields).every(function (key) {
|
||||
return event.fields[key].isValid;
|
||||
});
|
||||
});
|
||||
hostedFields.on('empty', (event) => {
|
||||
this._recreateElementClassAttribute(cardNumber, cardNumberField.className);
|
||||
this.emptyFields.add(event.emittedBy);
|
||||
});
|
||||
hostedFields.on('notEmpty', (event) => {
|
||||
this.emptyFields.delete(event.emittedBy);
|
||||
});
|
||||
|
||||
if (cardField.isEligible()) {
|
||||
const numberField = cardField.NumberField();
|
||||
numberField.render('#ppcp-credit-card-gateway-card-number');
|
||||
|
||||
const cvvField = cardField.CVVField();
|
||||
cvvField.render('#ppcp-credit-card-gateway-card-cvc');
|
||||
|
||||
const expiryField = cardField.ExpiryField();
|
||||
expiryField.render('#ppcp-credit-card-gateway-card-expiry');
|
||||
}
|
||||
|
||||
gateWayBox.style.display = oldDisplayStyle;
|
||||
|
||||
show(buttonSelector);
|
||||
|
||||
if (document.querySelector(wrapper).getAttribute('data-ppcp-subscribed') !== true) {
|
||||
document.querySelector(buttonSelector).addEventListener(
|
||||
'click',
|
||||
event => {
|
||||
event.preventDefault();
|
||||
this._submit(contextConfig);
|
||||
}
|
||||
);
|
||||
document.querySelector(buttonSelector).addEventListener("click", (event) => {
|
||||
event.preventDefault();
|
||||
cardField.submit();
|
||||
});
|
||||
|
||||
document.querySelector(wrapper).setAttribute('data-ppcp-subscribed', true);
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
document.querySelector('#payment_method_ppcp-credit-card-gateway').addEventListener(
|
||||
'click',
|
||||
() => {
|
||||
document.querySelector('label[for=ppcp-credit-card-gateway-card-number]').click();
|
||||
}
|
||||
)
|
||||
const wrapperElement = document.querySelector(wrapper);
|
||||
wrapperElement.parentNode.removeChild(wrapperElement);
|
||||
}
|
||||
|
||||
disableFields() {
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
{
|
||||
"presets": [
|
||||
[
|
||||
"@babel/preset-env",
|
||||
{
|
||||
"useBuiltIns": "usage",
|
||||
"corejs": "3.25.0"
|
||||
}
|
||||
],
|
||||
[
|
||||
"@babel/preset-react"
|
||||
]
|
||||
]
|
||||
}
|
3
modules/ppcp-card-fields/.gitignore
vendored
3
modules/ppcp-card-fields/.gitignore
vendored
|
@ -1,3 +0,0 @@
|
|||
node_modules
|
||||
assets/js
|
||||
assets/css
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"name": "ppcp-card-fields",
|
||||
"version": "1.0.0",
|
||||
"license": "GPL-3.0-or-later",
|
||||
"browserslist": [
|
||||
"> 0.5%",
|
||||
"Safari >= 8",
|
||||
"Chrome >= 41",
|
||||
"Firefox >= 43",
|
||||
"Edge >= 14"
|
||||
],
|
||||
"dependencies": {
|
||||
"@paypal/paypal-js": "^6.0.0",
|
||||
"core-js": "^3.25.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.19",
|
||||
"@babel/preset-env": "^7.19",
|
||||
"@babel/preset-react": "^7.18.6",
|
||||
"@woocommerce/dependency-extraction-webpack-plugin": "^2.2.0",
|
||||
"babel-loader": "^8.2",
|
||||
"cross-env": "^7.0.3",
|
||||
"file-loader": "^6.2.0",
|
||||
"sass": "^1.42.1",
|
||||
"sass-loader": "^12.1.0",
|
||||
"webpack": "^5.76",
|
||||
"webpack-cli": "^4.10"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "cross-env BABEL_ENV=default NODE_ENV=production webpack",
|
||||
"watch": "cross-env BABEL_ENV=default NODE_ENV=production webpack --watch",
|
||||
"dev": "cross-env BABEL_ENV=default webpack --watch"
|
||||
}
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
class CardFieldsRenderer {
|
||||
|
||||
render(wrapper, contextConfig) {
|
||||
const cardField = paypal.CardFields({
|
||||
createOrder: function (data) {},
|
||||
onApprove: function (data) {},
|
||||
onError: function (error) {
|
||||
console.error(error)
|
||||
}
|
||||
});
|
||||
|
||||
if (cardField.isEligible()) {
|
||||
const numberField = cardField.NumberField();
|
||||
numberField.render('#ppcp-credit-card-gateway-card-number');
|
||||
|
||||
const cvvField = cardField.CVVField();
|
||||
cvvField.render('#ppcp-credit-card-gateway-card-cvc');
|
||||
|
||||
const expiryField = cardField.ExpiryField();
|
||||
expiryField.render('#ppcp-credit-card-gateway-card-expiry');
|
||||
};
|
||||
}
|
||||
|
||||
enableFields() {}
|
||||
}
|
||||
|
||||
export default CardFieldsRenderer;
|
|
@ -41,15 +41,4 @@ return array(
|
|||
)
|
||||
);
|
||||
},
|
||||
'card-fields.module.url' => static function ( ContainerInterface $container ): string {
|
||||
/**
|
||||
* The path cannot be false.
|
||||
*
|
||||
* @psalm-suppress PossiblyFalseArgument
|
||||
*/
|
||||
return plugins_url(
|
||||
'/modules/ppcp-card-fields/',
|
||||
dirname( realpath( __FILE__ ), 3 ) . '/woocommerce-paypal-payments.php'
|
||||
);
|
||||
},
|
||||
);
|
||||
|
|
|
@ -28,20 +28,6 @@ class CardFieldsModule implements ModuleInterface {
|
|||
return;
|
||||
}
|
||||
|
||||
add_action(
|
||||
'wp_enqueue_scripts',
|
||||
function () use ( $c ) {
|
||||
$module_url = $c->get( 'card-fields.module.url' );
|
||||
wp_enqueue_script(
|
||||
'ppcp-card-fields-boot',
|
||||
untrailingslashit( $module_url ) . '/assets/js/boot.js',
|
||||
array( 'jquery' ),
|
||||
$c->get( 'ppcp.asset-version' ),
|
||||
true
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* Param types removed to avoid third-party issues.
|
||||
*
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
const path = require('path');
|
||||
const isProduction = process.env.NODE_ENV === 'production';
|
||||
|
||||
const DependencyExtractionWebpackPlugin = require( '@woocommerce/dependency-extraction-webpack-plugin' );
|
||||
|
||||
module.exports = {
|
||||
devtool: isProduction ? 'source-map' : 'eval-source-map',
|
||||
mode: isProduction ? 'production' : 'development',
|
||||
target: 'web',
|
||||
plugins: [ new DependencyExtractionWebpackPlugin() ],
|
||||
entry: {
|
||||
'boot': path.resolve('./resources/js/boot.js'),
|
||||
},
|
||||
output: {
|
||||
path: path.resolve(__dirname, 'assets/'),
|
||||
filename: 'js/[name].js',
|
||||
},
|
||||
module: {
|
||||
rules: [{
|
||||
test: /\.js?$/,
|
||||
exclude: /node_modules/,
|
||||
loader: 'babel-loader',
|
||||
},
|
||||
{
|
||||
test: /\.scss$/,
|
||||
exclude: /node_modules/,
|
||||
use: [
|
||||
{
|
||||
loader: 'file-loader',
|
||||
options: {
|
||||
name: 'css/[name].css',
|
||||
}
|
||||
},
|
||||
{loader:'sass-loader'}
|
||||
]
|
||||
}]
|
||||
}
|
||||
};
|
File diff suppressed because it is too large
Load diff
|
@ -10,7 +10,6 @@
|
|||
"install:modules:ppcp-applepay": "cd modules/ppcp-applepay && yarn install",
|
||||
"install:modules:ppcp-blocks": "cd modules/ppcp-blocks && yarn install",
|
||||
"install:modules:ppcp-button": "cd modules/ppcp-button && yarn install",
|
||||
"install:modules:ppcp-card-fields": "cd modules/ppcp-card-fields && yarn install",
|
||||
"install:modules:ppcp-googlepay": "cd modules/ppcp-googlepay && yarn install",
|
||||
"install:modules:ppcp-wc-gateway": "cd modules/ppcp-wc-gateway && yarn install",
|
||||
"install:modules:ppcp-webhooks": "cd modules/ppcp-webhooks && yarn install",
|
||||
|
@ -22,7 +21,6 @@
|
|||
"build:modules:ppcp-applepay": "cd modules/ppcp-applepay && yarn run build",
|
||||
"build:modules:ppcp-blocks": "cd modules/ppcp-blocks && yarn run build",
|
||||
"build:modules:ppcp-button": "cd modules/ppcp-button && yarn run build",
|
||||
"build:modules:ppcp-card-fields": "cd modules/ppcp-card-fields && yarn run build",
|
||||
"build:modules:ppcp-googlepay": "cd modules/ppcp-googlepay && yarn run build",
|
||||
"build:modules:ppcp-wc-gateway": "cd modules/ppcp-wc-gateway && yarn run build",
|
||||
"build:modules:ppcp-webhooks": "cd modules/ppcp-webhooks && yarn run build",
|
||||
|
@ -35,7 +33,6 @@
|
|||
"watch:modules:ppcp-applepay": "cd modules/ppcp-applepay && yarn run watch",
|
||||
"watch:modules:ppcp-blocks": "cd modules/ppcp-blocks && yarn run watch",
|
||||
"watch:modules:ppcp-button": "cd modules/ppcp-button && yarn run watch",
|
||||
"watch:modules:ppcp-card-fields": "cd modules/ppcp-card-fields && yarn run watch",
|
||||
"watch:modules:ppcp-googlepay": "cd modules/ppcp-googlepay && yarn run watch",
|
||||
"watch:modules:ppcp-wc-gateway": "cd modules/ppcp-wc-gateway && yarn run watch",
|
||||
"watch:modules:ppcp-webhooks": "cd modules/ppcp-webhooks && yarn run watch",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue