mirror of
https://github.com/woocommerce/woocommerce-paypal-payments.git
synced 2025-09-05 08:59:14 +08:00
🔀 Merge branch 'trunk'
This commit is contained in:
commit
a01f1ea77f
12 changed files with 339 additions and 14 deletions
|
@ -10,7 +10,7 @@
|
|||
"Edge >= 14"
|
||||
],
|
||||
"dependencies": {
|
||||
"@paypal/react-paypal-js": "^8.2.0",
|
||||
"@paypal/react-paypal-js": "^8.3.0",
|
||||
"core-js": "^3.25.0",
|
||||
"react": "^17.0.0",
|
||||
"react-dom": "^17.0.0"
|
||||
|
|
79
modules/ppcp-blocks/resources/js/Components/card-fields.js
Normal file
79
modules/ppcp-blocks/resources/js/Components/card-fields.js
Normal file
|
@ -0,0 +1,79 @@
|
|||
import {useEffect, useState} from '@wordpress/element';
|
||||
|
||||
import {
|
||||
PayPalScriptProvider,
|
||||
PayPalCardFieldsProvider,
|
||||
PayPalCardFieldsForm,
|
||||
} from "@paypal/react-paypal-js";
|
||||
|
||||
import {CheckoutHandler} from "./checkout-handler";
|
||||
import {createOrder, onApprove} from "../card-fields-config";
|
||||
import {cartHasSubscriptionProducts} from "../Helper/Subscription";
|
||||
|
||||
export function CardFields({config, eventRegistration, emitResponse, components}) {
|
||||
const {onPaymentSetup} = eventRegistration;
|
||||
const {responseTypes} = emitResponse;
|
||||
const { PaymentMethodIcons } = components;
|
||||
|
||||
const [cardFieldsForm, setCardFieldsForm] = useState();
|
||||
const getCardFieldsForm = (cardFieldsForm) => {
|
||||
setCardFieldsForm(cardFieldsForm)
|
||||
}
|
||||
|
||||
const getSavePayment = (savePayment) => {
|
||||
localStorage.setItem('ppcp-save-card-payment', savePayment);
|
||||
}
|
||||
|
||||
const hasSubscriptionProducts = cartHasSubscriptionProducts(config.scriptData);
|
||||
|
||||
useEffect(
|
||||
() =>
|
||||
onPaymentSetup(() => {
|
||||
async function handlePaymentProcessing() {
|
||||
await cardFieldsForm.submit()
|
||||
.catch((error) => {
|
||||
return {
|
||||
type: responseTypes.ERROR,
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
type: responseTypes.SUCCESS,
|
||||
}
|
||||
}
|
||||
|
||||
return handlePaymentProcessing();
|
||||
}),
|
||||
[onPaymentSetup, cardFieldsForm]
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<PayPalScriptProvider
|
||||
options={{
|
||||
clientId: config.scriptData.client_id,
|
||||
components: "card-fields",
|
||||
dataNamespace: 'ppcp-block-card-fields',
|
||||
}}
|
||||
>
|
||||
<PayPalCardFieldsProvider
|
||||
createOrder={createOrder}
|
||||
onApprove={onApprove}
|
||||
onError={(err) => {
|
||||
console.error(err);
|
||||
}}
|
||||
>
|
||||
<PayPalCardFieldsForm/>
|
||||
<PaymentMethodIcons icons={config.card_icons} align="left" />
|
||||
<CheckoutHandler
|
||||
getCardFieldsForm={getCardFieldsForm}
|
||||
getSavePayment={getSavePayment}
|
||||
hasSubscriptionProducts={hasSubscriptionProducts}
|
||||
saveCardText={config.save_card_text}
|
||||
is_vaulting_enabled={config.is_vaulting_enabled}
|
||||
/>
|
||||
</PayPalCardFieldsProvider>
|
||||
</PayPalScriptProvider>
|
||||
</>
|
||||
)
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
import {useEffect} from '@wordpress/element';
|
||||
import {usePayPalCardFields} from "@paypal/react-paypal-js";
|
||||
|
||||
export const CheckoutHandler = ({getCardFieldsForm, getSavePayment, hasSubscriptionProducts, saveCardText, is_vaulting_enabled}) => {
|
||||
const {cardFieldsForm} = usePayPalCardFields();
|
||||
|
||||
useEffect(() => {
|
||||
getCardFieldsForm(cardFieldsForm)
|
||||
}, []);
|
||||
|
||||
if (!is_vaulting_enabled) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<input
|
||||
type="checkbox"
|
||||
id="save"
|
||||
name="save"
|
||||
onChange={(e) => getSavePayment(e.target.checked)}
|
||||
defaultChecked={hasSubscriptionProducts}
|
||||
disabled={hasSubscriptionProducts}
|
||||
/>
|
||||
<label htmlFor="save">{saveCardText}</label>
|
||||
</>
|
||||
)
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
import { registerPaymentMethod } from '@woocommerce/blocks-registry';
|
||||
import {CardFields} from "./Components/card-fields";
|
||||
|
||||
const config = wc.wcSettings.getSetting('ppcp-credit-card-gateway_data');
|
||||
|
||||
registerPaymentMethod({
|
||||
name: config.id,
|
||||
label: <div dangerouslySetInnerHTML={{__html: config.title}}/>,
|
||||
content: <CardFields config={config}/>,
|
||||
edit: <div></div>,
|
||||
ariaLabel: config.title,
|
||||
canMakePayment: () => {return true},
|
||||
supports: {
|
||||
showSavedCards: true,
|
||||
features: config.supports
|
||||
}
|
||||
})
|
44
modules/ppcp-blocks/resources/js/card-fields-config.js
Normal file
44
modules/ppcp-blocks/resources/js/card-fields-config.js
Normal file
|
@ -0,0 +1,44 @@
|
|||
const config = wc.wcSettings.getSetting('ppcp-credit-card-gateway_data');
|
||||
|
||||
export async function createOrder() {
|
||||
return fetch(config.scriptData.ajax.create_order.endpoint, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
nonce: config.scriptData.ajax.create_order.nonce,
|
||||
context: config.scriptData.context,
|
||||
payment_method: 'ppcp-credit-card-gateway',
|
||||
save_payment_method: localStorage.getItem('ppcp-save-card-payment') === 'true',
|
||||
}),
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then((order) => {
|
||||
return order.data.id;
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
});
|
||||
}
|
||||
|
||||
export async function onApprove(data) {
|
||||
return fetch(config.scriptData.ajax.approve_order.endpoint, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
order_id: data.orderID,
|
||||
nonce: config.scriptData.ajax.approve_order.nonce,
|
||||
}),
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then((data) => {
|
||||
console.log(data)
|
||||
localStorage.removeItem('ppcp-save-card-payment');
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
});
|
||||
}
|
|
@ -9,6 +9,7 @@ declare(strict_types=1);
|
|||
|
||||
namespace WooCommerce\PayPalCommerce\Blocks;
|
||||
|
||||
use WooCommerce\PayPalCommerce\Blocks\Endpoint\GetPayPalOrderFromSession;
|
||||
use WooCommerce\PayPalCommerce\Blocks\Endpoint\UpdateShippingEndpoint;
|
||||
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
|
||||
use WooCommerce\PayPalCommerce\Button\Assets\SmartButtonInterface;
|
||||
|
@ -45,6 +46,17 @@ return array(
|
|||
$container->get( 'wcgateway.all-funding-sources' )
|
||||
);
|
||||
},
|
||||
'blocks.advanced-card-method' => static function( ContainerInterface $container ): AdvancedCardPaymentMethod {
|
||||
return new AdvancedCardPaymentMethod(
|
||||
$container->get( 'blocks.url' ),
|
||||
$container->get( 'ppcp.asset-version' ),
|
||||
$container->get( 'wcgateway.credit-card-gateway' ),
|
||||
function () use ( $container ): SmartButtonInterface {
|
||||
return $container->get( 'button.smart-button' );
|
||||
},
|
||||
$container->get( 'wcgateway.settings' )
|
||||
);
|
||||
},
|
||||
'blocks.settings.final_review_enabled' => static function ( ContainerInterface $container ): bool {
|
||||
$settings = $container->get( 'wcgateway.settings' );
|
||||
assert( $settings instanceof ContainerInterface );
|
||||
|
|
142
modules/ppcp-blocks/src/AdvancedCardPaymentMethod.php
Normal file
142
modules/ppcp-blocks/src/AdvancedCardPaymentMethod.php
Normal file
|
@ -0,0 +1,142 @@
|
|||
<?php
|
||||
/**
|
||||
* Advanced card payment method.
|
||||
*
|
||||
* @package WooCommerce\PayPalCommerce\Blocks
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\Blocks;
|
||||
|
||||
use Automattic\WooCommerce\Blocks\Payments\Integrations\AbstractPaymentMethodType;
|
||||
use WooCommerce\PayPalCommerce\Button\Assets\SmartButtonInterface;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
|
||||
|
||||
/**
|
||||
* Class AdvancedCardPaymentMethod
|
||||
*/
|
||||
class AdvancedCardPaymentMethod extends AbstractPaymentMethodType {
|
||||
|
||||
/**
|
||||
* The URL of this module.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $module_url;
|
||||
|
||||
/**
|
||||
* The assets version.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $version;
|
||||
|
||||
/**
|
||||
* Credit card gateway.
|
||||
*
|
||||
* @var CreditCardGateway
|
||||
*/
|
||||
private $gateway;
|
||||
|
||||
/**
|
||||
* The smart button script loading handler.
|
||||
*
|
||||
* @var SmartButtonInterface|callable
|
||||
*/
|
||||
private $smart_button;
|
||||
|
||||
/**
|
||||
* The settings.
|
||||
*
|
||||
* @var Settings
|
||||
*/
|
||||
protected $settings;
|
||||
|
||||
/**
|
||||
* AdvancedCardPaymentMethod constructor.
|
||||
*
|
||||
* @param string $module_url The URL of this module.
|
||||
* @param string $version The assets version.
|
||||
* @param CreditCardGateway $gateway Credit card gateway.
|
||||
* @param SmartButtonInterface|callable $smart_button The smart button script loading handler.
|
||||
* @param Settings $settings The settings.
|
||||
*/
|
||||
public function __construct(
|
||||
string $module_url,
|
||||
string $version,
|
||||
CreditCardGateway $gateway,
|
||||
$smart_button,
|
||||
Settings $settings
|
||||
) {
|
||||
$this->name = CreditCardGateway::ID;
|
||||
$this->module_url = $module_url;
|
||||
$this->version = $version;
|
||||
$this->gateway = $gateway;
|
||||
$this->smart_button = $smart_button;
|
||||
$this->settings = $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function initialize() {}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function is_active() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function get_payment_method_script_handles() {
|
||||
wp_register_script(
|
||||
'ppcp-advanced-card-checkout-block',
|
||||
trailingslashit( $this->module_url ) . 'assets/js/advanced-card-checkout-block.js',
|
||||
array(),
|
||||
$this->version,
|
||||
true
|
||||
);
|
||||
|
||||
return array( 'ppcp-advanced-card-checkout-block' );
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function get_payment_method_data() {
|
||||
$script_data = $this->smart_button_instance()->script_data();
|
||||
|
||||
return array(
|
||||
'id' => $this->name,
|
||||
'title' => $this->gateway->title,
|
||||
'description' => $this->gateway->description,
|
||||
'scriptData' => $script_data,
|
||||
'supports' => $this->gateway->supports,
|
||||
'save_card_text' => esc_html__( 'Save your card', 'woocommerce-paypal-payments' ),
|
||||
'is_vaulting_enabled' => $this->settings->has( 'vault_enabled_dcc' ) && $this->settings->get( 'vault_enabled_dcc' ),
|
||||
'card_icons' => $this->settings->has( 'card_icons' ) ? (array) $this->settings->get( 'card_icons' ) : array(),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* The smart button.
|
||||
*
|
||||
* @return SmartButtonInterface
|
||||
*/
|
||||
private function smart_button_instance(): SmartButtonInterface {
|
||||
if ( $this->smart_button instanceof SmartButtonInterface ) {
|
||||
return $this->smart_button;
|
||||
}
|
||||
|
||||
if ( is_callable( $this->smart_button ) ) {
|
||||
$this->smart_button = ( $this->smart_button )();
|
||||
}
|
||||
|
||||
return $this->smart_button;
|
||||
}
|
||||
}
|
|
@ -61,6 +61,7 @@ class BlocksModule implements ModuleInterface {
|
|||
'woocommerce_blocks_payment_method_type_registration',
|
||||
function( PaymentMethodRegistry $payment_method_registry ) use ( $c ): void {
|
||||
$payment_method_registry->register( $c->get( 'blocks.method' ) );
|
||||
$payment_method_registry->register( $c->get( 'blocks.advanced-card-method' ) );
|
||||
}
|
||||
);
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ module.exports = {
|
|||
plugins: [ new DependencyExtractionWebpackPlugin() ],
|
||||
entry: {
|
||||
'checkout-block': path.resolve('./resources/js/checkout-block.js'),
|
||||
'advanced-card-checkout-block': path.resolve('./resources/js/advanced-card-checkout-block.js'),
|
||||
"gateway": path.resolve('./resources/css/gateway.scss')
|
||||
},
|
||||
output: {
|
||||
|
|
|
@ -1005,19 +1005,19 @@
|
|||
"@jridgewell/resolve-uri" "3.1.0"
|
||||
"@jridgewell/sourcemap-codec" "1.4.14"
|
||||
|
||||
"@paypal/paypal-js@^8.0.4":
|
||||
version "8.0.4"
|
||||
resolved "https://registry.yarnpkg.com/@paypal/paypal-js/-/paypal-js-8.0.4.tgz#abe9f40f519b1d2c306adddfbe733be03eb26ce5"
|
||||
integrity sha512-91g5fhRBHGEBoikDzQT6uBn3PzlJQ75g0c3MvqVJqN0XRm5kHa9wz+6+Uaq8QQuxRzz5C2x55Zg057CW6EuwpQ==
|
||||
"@paypal/paypal-js@^8.0.5":
|
||||
version "8.0.5"
|
||||
resolved "https://registry.yarnpkg.com/@paypal/paypal-js/-/paypal-js-8.0.5.tgz#77bc461b4d1e5a2c6f081269e3ef0b2e3331a68c"
|
||||
integrity sha512-yQNV7rOILeaVCNU4aVDRPqEnbIlzfxgQfFsxzsBuZW1ouqRD/4kYBWJDzczCiscSr2xOeA/Pkm7e3a9fRfnuMQ==
|
||||
dependencies:
|
||||
promise-polyfill "^8.3.0"
|
||||
|
||||
"@paypal/react-paypal-js@^8.2.0":
|
||||
version "8.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@paypal/react-paypal-js/-/react-paypal-js-8.2.0.tgz#4b1a142bbb68e62dca4a92da4a6b5568f54901f0"
|
||||
integrity sha512-SworUfu0BNNcqoh0O53Ke4MFpx2m3qJRu3hayXvlluEEXJpKqGSV5aaSGFhbsZqi8hnbsx/hZR7BQbmqsggiGQ==
|
||||
"@paypal/react-paypal-js@^8.3.0":
|
||||
version "8.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@paypal/react-paypal-js/-/react-paypal-js-8.3.0.tgz#a103080b752766b8ff59b8620887abf802e1a01b"
|
||||
integrity sha512-SX17d2h1CMNFGI+wtjb329AEDaBR8Ziy2LCV076eDcY1Q0MFKRkfQ/v0HOAvZtk3sJoydRmYez2pq47BRblwqQ==
|
||||
dependencies:
|
||||
"@paypal/paypal-js" "^8.0.4"
|
||||
"@paypal/paypal-js" "^8.0.5"
|
||||
"@paypal/sdk-constants" "^1.0.122"
|
||||
|
||||
"@paypal/sdk-constants@^1.0.122":
|
||||
|
|
|
@ -1421,7 +1421,7 @@ document.querySelector("#payment").before(document.querySelector(".ppcp-messages
|
|||
$disable_funding,
|
||||
array_diff(
|
||||
array_keys( $this->all_funding_sources ),
|
||||
array( 'venmo', 'paylater', 'paypal' )
|
||||
array( 'venmo', 'paylater', 'paypal', 'card' )
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
|
@ -105,9 +105,8 @@ class CardFieldsModule implements ModuleInterface {
|
|||
|
||||
add_filter(
|
||||
'ppcp_create_order_request_body_data',
|
||||
function( array $data ) use ( $c ): array {
|
||||
function( array $data, string $payment_method ) use ( $c ): array {
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Missing
|
||||
$payment_method = wc_clean( wp_unslash( $_POST['payment_method'] ?? '' ) );
|
||||
if ( $payment_method !== CreditCardGateway::ID ) {
|
||||
return $data;
|
||||
}
|
||||
|
@ -134,7 +133,9 @@ class CardFieldsModule implements ModuleInterface {
|
|||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
},
|
||||
10,
|
||||
2
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue