mirror of
https://github.com/woocommerce/woocommerce-paypal-payments.git
synced 2025-08-31 06:52:50 +08:00
Merge branch 'trunk' into PCP-2347-new-feature-accelerated-checkout
# Conflicts: # modules.php
This commit is contained in:
commit
9cb63040d8
129 changed files with 7018 additions and 1124 deletions
2
.github/workflows/e2e.yml
vendored
2
.github/workflows/e2e.yml
vendored
|
@ -1,6 +1,6 @@
|
||||||
name: e2e tests
|
name: e2e tests
|
||||||
|
|
||||||
on: [push]
|
on: workflow_dispatch
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
|
|
|
@ -87,6 +87,32 @@ function ppcp_capture_order( WC_Order $wc_order ): void {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reauthorizes the PayPal order.
|
||||||
|
*
|
||||||
|
* @param WC_Order $wc_order The WC order.
|
||||||
|
* @throws InvalidArgumentException When the order cannot be captured.
|
||||||
|
* @throws Exception When the operation fails.
|
||||||
|
*/
|
||||||
|
function ppcp_reauthorize_order( WC_Order $wc_order ): void {
|
||||||
|
$intent = strtoupper( (string) $wc_order->get_meta( PayPalGateway::INTENT_META_KEY ) );
|
||||||
|
|
||||||
|
if ( $intent !== 'AUTHORIZE' ) {
|
||||||
|
throw new InvalidArgumentException( 'Only orders with "authorize" intent can be reauthorized.' );
|
||||||
|
}
|
||||||
|
$captured = wc_string_to_bool( $wc_order->get_meta( AuthorizedPaymentsProcessor::CAPTURED_META_KEY ) );
|
||||||
|
if ( $captured ) {
|
||||||
|
throw new InvalidArgumentException( 'The order is already captured.' );
|
||||||
|
}
|
||||||
|
|
||||||
|
$authorized_payment_processor = PPCP::container()->get( 'wcgateway.processor.authorized-payments' );
|
||||||
|
assert( $authorized_payment_processor instanceof AuthorizedPaymentsProcessor );
|
||||||
|
|
||||||
|
if ( $authorized_payment_processor->reauthorize_payment( $wc_order ) !== AuthorizedPaymentsProcessor::SUCCESSFUL ) {
|
||||||
|
throw new RuntimeException( $authorized_payment_processor->reauthorization_failure_reason() ?: 'Reauthorization failed.' );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Refunds the PayPal order.
|
* Refunds the PayPal order.
|
||||||
* Note that you can use wc_refund_payment() to trigger the refund in WC and PayPal.
|
* Note that you can use wc_refund_payment() to trigger the refund in WC and PayPal.
|
||||||
|
|
|
@ -1,5 +1,54 @@
|
||||||
*** Changelog ***
|
*** Changelog ***
|
||||||
|
|
||||||
|
= 2.6.1 - 2024-04-09 =
|
||||||
|
* Fix - Payment tokens fixes and adjustments #2106
|
||||||
|
* Fix - Pay upon Invoice: Add input validation to Experience Context fields #2092
|
||||||
|
* Fix - Disable markup in get_plugin_data() returns to fix an issue with wptexturize() #2094
|
||||||
|
* Fix - Problem changing the shipping option in block pages #2142
|
||||||
|
* Fix - Saved payment token deleted after payment with another saved payment token #2146
|
||||||
|
* Enhancement - Pay later messaging configurator improvements #2107
|
||||||
|
* Enhancement - Replace the middleware URL from connect.woocommerce.com to api.woocommerce.com/integrations #2130
|
||||||
|
* Enhancement - Remove all Sofort references as it has been deprecated #2124
|
||||||
|
* Enhancement - Improve funding source names #2118
|
||||||
|
* Enhancement - More fraud prevention capabilities by storing additional data in the order #2125
|
||||||
|
* Enhancement - Update ACDC currency eligibility for AMEX #2129
|
||||||
|
* Enhancement - Sync shipping options with Venmo when skipping final confirmation on Checkout #2108
|
||||||
|
* Enhancement - Card Fields: Add a filter for the CVC field and update the placeholder to match the label #2089
|
||||||
|
* Enhancement - Product Title: Sanitize before sending to PayPal #2090
|
||||||
|
* Enhancement - Add filter for disabling permit_multiple_payment_tokens vault attribute #2136
|
||||||
|
* Enhancement - Filter to hide PayPal email address not working on order detail #2137
|
||||||
|
|
||||||
|
= 2.6.0 - 2024-03-20 =
|
||||||
|
* Fix - invoice_id not included in API call when creating payment with saved card #2086
|
||||||
|
* Fix - Typo in SCA indicators for ACDC Vault transactions #2083
|
||||||
|
* Fix - Payments with saved card tokens use Capture intent when Authorize is configured #2069
|
||||||
|
* Fix - WooPayments multi-currency causing currency mismatch error on Block Cart & Checkout pages #2054
|
||||||
|
* Fix - "Must pass createSubscription with intent=subscription" error with PayPal Subscriptions mode #2058
|
||||||
|
* Fix - "Proceed to PayPal" button displayed for Free trial PayPal Subscription products when payment token is saved #2041
|
||||||
|
* Fix - ACDC payments with new credit card may fail when debugging is enabled (JSON malformed by warning) #2051
|
||||||
|
* Enhancement - Add Pay Later Messaging block #1897
|
||||||
|
* Enhancement - Submit the form instead of refreshing the page to show the save notice #2081
|
||||||
|
* Enhancement - Integrate pay later messaging block with the messaging configurator #2080
|
||||||
|
* Enhancement - Reauthorize authorized payments #2062
|
||||||
|
* Enhancement - Do not handle VAULT.PAYMENT-TOKEN.CREATED webhook for Vault v3 #2079
|
||||||
|
* Enhancement - Improve the messaging configurator styles #2053
|
||||||
|
* Enhancement - Ensure PayPal Vaulting is not selected as Subscriptions Mode when Reference Transactions are disabled #2057
|
||||||
|
* Enhancement - Pay later messaging configurator & messaging block adjustments #2096
|
||||||
|
|
||||||
|
= 2.5.4 - 2024-02-27 =
|
||||||
|
* Fix - Cannot enable Apple Pay when API credentials were manually created #2015
|
||||||
|
* Fix - Cart simulation type error #1943
|
||||||
|
* Enhancement - Apple Pay recurring payments #1986
|
||||||
|
* Enhancement - Real Time Account Updater (RTAU) integration #2027
|
||||||
|
* Enhancement - Prepare the SKU for sending to PayPal #2033
|
||||||
|
* Enhancement - Store the Card Brand in Address Verification Result instead of 3DS authentication result #2026
|
||||||
|
* Enhancement - Update country eligibility for AdvancedCard Processing, Apple Pay, Google Pay #2019
|
||||||
|
* Enhancement - Disable PayPal Vaulting setting instead of hiding it when Reference Transactions not available #2029
|
||||||
|
* Enhancement - Store three d secure enrollment status and authentication status responses in wc order #1980
|
||||||
|
* Enhancement - Add more checks to prevent "PayPal order ID not found" errors #2038
|
||||||
|
* Enhancement - Disable messaging configurator when vault is enabled #2042
|
||||||
|
* Feature preview - Pay Later Messaging configurator #1924
|
||||||
|
|
||||||
= 2.5.3 - 2024-02-06 =
|
= 2.5.3 - 2024-02-06 =
|
||||||
* Fix - Free trial subscription products using PayPal Vaulting when PayPal Subscriptions configured as Subscriptions Mode #1979
|
* Fix - Free trial subscription products using PayPal Vaulting when PayPal Subscriptions configured as Subscriptions Mode #1979
|
||||||
* Fix - Pay by link - Germany - PayPal buttons are not visible on Pay for order page #2014
|
* Fix - Pay by link - Germany - PayPal buttons are not visible on Pay for order page #2014
|
||||||
|
|
350
composer.lock
generated
350
composer.lock
generated
|
@ -8,20 +8,20 @@
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "container-interop/service-provider",
|
"name": "container-interop/service-provider",
|
||||||
"version": "v0.4.0",
|
"version": "v0.4.1",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/container-interop/service-provider.git",
|
"url": "https://github.com/container-interop/service-provider.git",
|
||||||
"reference": "4969b9e49460690b7430b3f1a87cab07be61418a"
|
"reference": "e04441ca21ef03e10dce70b0af29269281eec6dc"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/container-interop/service-provider/zipball/4969b9e49460690b7430b3f1a87cab07be61418a",
|
"url": "https://api.github.com/repos/container-interop/service-provider/zipball/e04441ca21ef03e10dce70b0af29269281eec6dc",
|
||||||
"reference": "4969b9e49460690b7430b3f1a87cab07be61418a",
|
"reference": "e04441ca21ef03e10dce70b0af29269281eec6dc",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"psr/container": "^1.0"
|
"psr/container": "^1.0 || ^2.0"
|
||||||
},
|
},
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"autoload": {
|
"autoload": {
|
||||||
|
@ -37,9 +37,9 @@
|
||||||
"homepage": "https://github.com/container-interop/service-provider",
|
"homepage": "https://github.com/container-interop/service-provider",
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/container-interop/service-provider/issues",
|
"issues": "https://github.com/container-interop/service-provider/issues",
|
||||||
"source": "https://github.com/container-interop/service-provider/tree/master"
|
"source": "https://github.com/container-interop/service-provider/tree/v0.4.1"
|
||||||
},
|
},
|
||||||
"time": "2017-09-20T14:13:36+00:00"
|
"time": "2023-12-14T14:50:12+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "dhii/human-readable-interface",
|
"name": "dhii/human-readable-interface",
|
||||||
|
@ -438,16 +438,16 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/polyfill-php80",
|
"name": "symfony/polyfill-php80",
|
||||||
"version": "v1.27.0",
|
"version": "v1.29.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/polyfill-php80.git",
|
"url": "https://github.com/symfony/polyfill-php80.git",
|
||||||
"reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936"
|
"reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936",
|
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/87b68208d5c1188808dd7839ee1e6c8ec3b02f1b",
|
||||||
"reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936",
|
"reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -455,9 +455,6 @@
|
||||||
},
|
},
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"extra": {
|
"extra": {
|
||||||
"branch-alias": {
|
|
||||||
"dev-main": "1.27-dev"
|
|
||||||
},
|
|
||||||
"thanks": {
|
"thanks": {
|
||||||
"name": "symfony/polyfill",
|
"name": "symfony/polyfill",
|
||||||
"url": "https://github.com/symfony/polyfill"
|
"url": "https://github.com/symfony/polyfill"
|
||||||
|
@ -501,7 +498,7 @@
|
||||||
"shim"
|
"shim"
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/polyfill-php80/tree/v1.27.0"
|
"source": "https://github.com/symfony/polyfill-php80/tree/v1.29.0"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
@ -517,7 +514,7 @@
|
||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2022-11-03T14:55:06+00:00"
|
"time": "2024-01-29T20:11:03+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "wikimedia/composer-merge-plugin",
|
"name": "wikimedia/composer-merge-plugin",
|
||||||
|
@ -797,16 +794,16 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "antecedent/patchwork",
|
"name": "antecedent/patchwork",
|
||||||
"version": "2.1.25",
|
"version": "2.1.28",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/antecedent/patchwork.git",
|
"url": "https://github.com/antecedent/patchwork.git",
|
||||||
"reference": "17314e042d45e0dacb0a494c2d1ef50e7621136a"
|
"reference": "6b30aff81ebadf0f2feb9268d3e08385cebcc08d"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/antecedent/patchwork/zipball/17314e042d45e0dacb0a494c2d1ef50e7621136a",
|
"url": "https://api.github.com/repos/antecedent/patchwork/zipball/6b30aff81ebadf0f2feb9268d3e08385cebcc08d",
|
||||||
"reference": "17314e042d45e0dacb0a494c2d1ef50e7621136a",
|
"reference": "6b30aff81ebadf0f2feb9268d3e08385cebcc08d",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -827,7 +824,7 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "Method redefinition (monkey-patching) functionality for PHP.",
|
"description": "Method redefinition (monkey-patching) functionality for PHP.",
|
||||||
"homepage": "http://patchwork2.org/",
|
"homepage": "https://antecedent.github.io/patchwork/",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"aop",
|
"aop",
|
||||||
"aspect",
|
"aspect",
|
||||||
|
@ -839,9 +836,9 @@
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/antecedent/patchwork/issues",
|
"issues": "https://github.com/antecedent/patchwork/issues",
|
||||||
"source": "https://github.com/antecedent/patchwork/tree/2.1.25"
|
"source": "https://github.com/antecedent/patchwork/tree/2.1.28"
|
||||||
},
|
},
|
||||||
"time": "2023-02-19T12:51:24+00:00"
|
"time": "2024-02-06T09:26:11+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "brain/monkey",
|
"name": "brain/monkey",
|
||||||
|
@ -988,16 +985,16 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "composer/pcre",
|
"name": "composer/pcre",
|
||||||
"version": "2.1.0",
|
"version": "2.1.1",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/composer/pcre.git",
|
"url": "https://github.com/composer/pcre.git",
|
||||||
"reference": "3fdb2807b31a78a40ad89570e30ec77466c98717"
|
"reference": "b439557066cd445732fa57cbc8d905394b4db8a0"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/composer/pcre/zipball/3fdb2807b31a78a40ad89570e30ec77466c98717",
|
"url": "https://api.github.com/repos/composer/pcre/zipball/b439557066cd445732fa57cbc8d905394b4db8a0",
|
||||||
"reference": "3fdb2807b31a78a40ad89570e30ec77466c98717",
|
"reference": "b439557066cd445732fa57cbc8d905394b4db8a0",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -1039,7 +1036,7 @@
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/composer/pcre/issues",
|
"issues": "https://github.com/composer/pcre/issues",
|
||||||
"source": "https://github.com/composer/pcre/tree/2.1.0"
|
"source": "https://github.com/composer/pcre/tree/2.1.1"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
@ -1055,20 +1052,20 @@
|
||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2022-11-16T18:32:04+00:00"
|
"time": "2023-10-11T07:10:55+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "composer/semver",
|
"name": "composer/semver",
|
||||||
"version": "3.3.2",
|
"version": "3.4.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/composer/semver.git",
|
"url": "https://github.com/composer/semver.git",
|
||||||
"reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9"
|
"reference": "35e8d0af4486141bc745f23a29cc2091eb624a32"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/composer/semver/zipball/3953f23262f2bff1919fc82183ad9acb13ff62c9",
|
"url": "https://api.github.com/repos/composer/semver/zipball/35e8d0af4486141bc745f23a29cc2091eb624a32",
|
||||||
"reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9",
|
"reference": "35e8d0af4486141bc745f23a29cc2091eb624a32",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -1118,9 +1115,9 @@
|
||||||
"versioning"
|
"versioning"
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"irc": "irc://irc.freenode.org/composer",
|
"irc": "ircs://irc.libera.chat:6697/composer",
|
||||||
"issues": "https://github.com/composer/semver/issues",
|
"issues": "https://github.com/composer/semver/issues",
|
||||||
"source": "https://github.com/composer/semver/tree/3.3.2"
|
"source": "https://github.com/composer/semver/tree/3.4.0"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
@ -1136,7 +1133,7 @@
|
||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2022-04-01T19:23:25+00:00"
|
"time": "2023-08-31T09:50:34+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "composer/xdebug-handler",
|
"name": "composer/xdebug-handler",
|
||||||
|
@ -1604,24 +1601,24 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "graham-campbell/result-type",
|
"name": "graham-campbell/result-type",
|
||||||
"version": "v1.1.1",
|
"version": "v1.1.2",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/GrahamCampbell/Result-Type.git",
|
"url": "https://github.com/GrahamCampbell/Result-Type.git",
|
||||||
"reference": "672eff8cf1d6fe1ef09ca0f89c4b287d6a3eb831"
|
"reference": "fbd48bce38f73f8a4ec8583362e732e4095e5862"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/672eff8cf1d6fe1ef09ca0f89c4b287d6a3eb831",
|
"url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/fbd48bce38f73f8a4ec8583362e732e4095e5862",
|
||||||
"reference": "672eff8cf1d6fe1ef09ca0f89c4b287d6a3eb831",
|
"reference": "fbd48bce38f73f8a4ec8583362e732e4095e5862",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"php": "^7.2.5 || ^8.0",
|
"php": "^7.2.5 || ^8.0",
|
||||||
"phpoption/phpoption": "^1.9.1"
|
"phpoption/phpoption": "^1.9.2"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpunit/phpunit": "^8.5.32 || ^9.6.3 || ^10.0.12"
|
"phpunit/phpunit": "^8.5.34 || ^9.6.13 || ^10.4.2"
|
||||||
},
|
},
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"autoload": {
|
"autoload": {
|
||||||
|
@ -1650,7 +1647,7 @@
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/GrahamCampbell/Result-Type/issues",
|
"issues": "https://github.com/GrahamCampbell/Result-Type/issues",
|
||||||
"source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.1.1"
|
"source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.1.2"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
@ -1662,7 +1659,7 @@
|
||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2023-02-25T20:23:15+00:00"
|
"time": "2023-11-12T22:16:48+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "hamcrest/hamcrest-php",
|
"name": "hamcrest/hamcrest-php",
|
||||||
|
@ -1845,16 +1842,16 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "netresearch/jsonmapper",
|
"name": "netresearch/jsonmapper",
|
||||||
"version": "v4.2.0",
|
"version": "v4.4.1",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/cweiske/jsonmapper.git",
|
"url": "https://github.com/cweiske/jsonmapper.git",
|
||||||
"reference": "f60565f8c0566a31acf06884cdaa591867ecc956"
|
"reference": "132c75c7dd83e45353ebb9c6c9f591952995bbf0"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/cweiske/jsonmapper/zipball/f60565f8c0566a31acf06884cdaa591867ecc956",
|
"url": "https://api.github.com/repos/cweiske/jsonmapper/zipball/132c75c7dd83e45353ebb9c6c9f591952995bbf0",
|
||||||
"reference": "f60565f8c0566a31acf06884cdaa591867ecc956",
|
"reference": "132c75c7dd83e45353ebb9c6c9f591952995bbf0",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -1865,7 +1862,7 @@
|
||||||
"php": ">=7.1"
|
"php": ">=7.1"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpunit/phpunit": "~7.5 || ~8.0 || ~9.0",
|
"phpunit/phpunit": "~7.5 || ~8.0 || ~9.0 || ~10.0",
|
||||||
"squizlabs/php_codesniffer": "~3.5"
|
"squizlabs/php_codesniffer": "~3.5"
|
||||||
},
|
},
|
||||||
"type": "library",
|
"type": "library",
|
||||||
|
@ -1890,22 +1887,22 @@
|
||||||
"support": {
|
"support": {
|
||||||
"email": "cweiske@cweiske.de",
|
"email": "cweiske@cweiske.de",
|
||||||
"issues": "https://github.com/cweiske/jsonmapper/issues",
|
"issues": "https://github.com/cweiske/jsonmapper/issues",
|
||||||
"source": "https://github.com/cweiske/jsonmapper/tree/v4.2.0"
|
"source": "https://github.com/cweiske/jsonmapper/tree/v4.4.1"
|
||||||
},
|
},
|
||||||
"time": "2023-04-09T17:37:40+00:00"
|
"time": "2024-01-31T06:18:54+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "nikic/php-parser",
|
"name": "nikic/php-parser",
|
||||||
"version": "v4.16.0",
|
"version": "v4.18.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/nikic/PHP-Parser.git",
|
"url": "https://github.com/nikic/PHP-Parser.git",
|
||||||
"reference": "19526a33fb561ef417e822e85f08a00db4059c17"
|
"reference": "1bcbb2179f97633e98bbbc87044ee2611c7d7999"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/19526a33fb561ef417e822e85f08a00db4059c17",
|
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/1bcbb2179f97633e98bbbc87044ee2611c7d7999",
|
||||||
"reference": "19526a33fb561ef417e822e85f08a00db4059c17",
|
"reference": "1bcbb2179f97633e98bbbc87044ee2611c7d7999",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -1946,9 +1943,9 @@
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/nikic/PHP-Parser/issues",
|
"issues": "https://github.com/nikic/PHP-Parser/issues",
|
||||||
"source": "https://github.com/nikic/PHP-Parser/tree/v4.16.0"
|
"source": "https://github.com/nikic/PHP-Parser/tree/v4.18.0"
|
||||||
},
|
},
|
||||||
"time": "2023-06-25T14:52:30+00:00"
|
"time": "2023-12-10T21:03:43+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "openlss/lib-array2xml",
|
"name": "openlss/lib-array2xml",
|
||||||
|
@ -2539,16 +2536,16 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "phpoption/phpoption",
|
"name": "phpoption/phpoption",
|
||||||
"version": "1.9.1",
|
"version": "1.9.2",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/schmittjoh/php-option.git",
|
"url": "https://github.com/schmittjoh/php-option.git",
|
||||||
"reference": "dd3a383e599f49777d8b628dadbb90cae435b87e"
|
"reference": "80735db690fe4fc5c76dfa7f9b770634285fa820"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/schmittjoh/php-option/zipball/dd3a383e599f49777d8b628dadbb90cae435b87e",
|
"url": "https://api.github.com/repos/schmittjoh/php-option/zipball/80735db690fe4fc5c76dfa7f9b770634285fa820",
|
||||||
"reference": "dd3a383e599f49777d8b628dadbb90cae435b87e",
|
"reference": "80735db690fe4fc5c76dfa7f9b770634285fa820",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -2556,7 +2553,7 @@
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"bamarni/composer-bin-plugin": "^1.8.2",
|
"bamarni/composer-bin-plugin": "^1.8.2",
|
||||||
"phpunit/phpunit": "^8.5.32 || ^9.6.3 || ^10.0.12"
|
"phpunit/phpunit": "^8.5.34 || ^9.6.13 || ^10.4.2"
|
||||||
},
|
},
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"extra": {
|
"extra": {
|
||||||
|
@ -2598,7 +2595,7 @@
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/schmittjoh/php-option/issues",
|
"issues": "https://github.com/schmittjoh/php-option/issues",
|
||||||
"source": "https://github.com/schmittjoh/php-option/tree/1.9.1"
|
"source": "https://github.com/schmittjoh/php-option/tree/1.9.2"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
@ -2610,7 +2607,7 @@
|
||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2023-02-25T19:38:58+00:00"
|
"time": "2023-11-12T21:59:55+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "phpunit/php-code-coverage",
|
"name": "phpunit/php-code-coverage",
|
||||||
|
@ -2911,16 +2908,16 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "phpunit/phpunit",
|
"name": "phpunit/phpunit",
|
||||||
"version": "8.5.33",
|
"version": "8.5.36",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/sebastianbergmann/phpunit.git",
|
"url": "https://github.com/sebastianbergmann/phpunit.git",
|
||||||
"reference": "7d1ff0e8c6b35db78ff13e3e05517d7cbf7aa32e"
|
"reference": "9652df58e06a681429d8cfdaec3c43d6de581d5a"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/7d1ff0e8c6b35db78ff13e3e05517d7cbf7aa32e",
|
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/9652df58e06a681429d8cfdaec3c43d6de581d5a",
|
||||||
"reference": "7d1ff0e8c6b35db78ff13e3e05517d7cbf7aa32e",
|
"reference": "9652df58e06a681429d8cfdaec3c43d6de581d5a",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -2950,9 +2947,9 @@
|
||||||
"sebastian/version": "^2.0.1"
|
"sebastian/version": "^2.0.1"
|
||||||
},
|
},
|
||||||
"suggest": {
|
"suggest": {
|
||||||
"ext-soap": "*",
|
"ext-soap": "To be able to generate mocks based on WSDL files",
|
||||||
"ext-xdebug": "*",
|
"ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage",
|
||||||
"phpunit/php-invoker": "^2.0.0"
|
"phpunit/php-invoker": "To allow enforcing time limits"
|
||||||
},
|
},
|
||||||
"bin": [
|
"bin": [
|
||||||
"phpunit"
|
"phpunit"
|
||||||
|
@ -2988,7 +2985,8 @@
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
|
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
|
||||||
"source": "https://github.com/sebastianbergmann/phpunit/tree/8.5.33"
|
"security": "https://github.com/sebastianbergmann/phpunit/security/policy",
|
||||||
|
"source": "https://github.com/sebastianbergmann/phpunit/tree/8.5.36"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
@ -3004,7 +3002,7 @@
|
||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2023-02-27T13:04:50+00:00"
|
"time": "2023-12-01T16:52:15+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "sebastian/code-unit-reverse-lookup",
|
"name": "sebastian/code-unit-reverse-lookup",
|
||||||
|
@ -3343,16 +3341,16 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "sebastian/global-state",
|
"name": "sebastian/global-state",
|
||||||
"version": "3.0.2",
|
"version": "3.0.3",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/sebastianbergmann/global-state.git",
|
"url": "https://github.com/sebastianbergmann/global-state.git",
|
||||||
"reference": "de036ec91d55d2a9e0db2ba975b512cdb1c23921"
|
"reference": "66783ce213de415b451b904bfef9dda0cf9aeae0"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/de036ec91d55d2a9e0db2ba975b512cdb1c23921",
|
"url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/66783ce213de415b451b904bfef9dda0cf9aeae0",
|
||||||
"reference": "de036ec91d55d2a9e0db2ba975b512cdb1c23921",
|
"reference": "66783ce213de415b451b904bfef9dda0cf9aeae0",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -3395,7 +3393,7 @@
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/sebastianbergmann/global-state/issues",
|
"issues": "https://github.com/sebastianbergmann/global-state/issues",
|
||||||
"source": "https://github.com/sebastianbergmann/global-state/tree/3.0.2"
|
"source": "https://github.com/sebastianbergmann/global-state/tree/3.0.3"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
@ -3403,7 +3401,7 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2022-02-10T06:55:38+00:00"
|
"time": "2023-08-02T09:23:32+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "sebastian/object-enumerator",
|
"name": "sebastian/object-enumerator",
|
||||||
|
@ -3737,16 +3735,16 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "squizlabs/php_codesniffer",
|
"name": "squizlabs/php_codesniffer",
|
||||||
"version": "3.7.2",
|
"version": "3.8.1",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/squizlabs/PHP_CodeSniffer.git",
|
"url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git",
|
||||||
"reference": "ed8e00df0a83aa96acf703f8c2979ff33341f879"
|
"reference": "14f5fff1e64118595db5408e946f3a22c75807f7"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/ed8e00df0a83aa96acf703f8c2979ff33341f879",
|
"url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/14f5fff1e64118595db5408e946f3a22c75807f7",
|
||||||
"reference": "ed8e00df0a83aa96acf703f8c2979ff33341f879",
|
"reference": "14f5fff1e64118595db5408e946f3a22c75807f7",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -3756,11 +3754,11 @@
|
||||||
"php": ">=5.4.0"
|
"php": ">=5.4.0"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0"
|
"phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.3.4"
|
||||||
},
|
},
|
||||||
"bin": [
|
"bin": [
|
||||||
"bin/phpcs",
|
"bin/phpcbf",
|
||||||
"bin/phpcbf"
|
"bin/phpcs"
|
||||||
],
|
],
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"extra": {
|
"extra": {
|
||||||
|
@ -3775,35 +3773,58 @@
|
||||||
"authors": [
|
"authors": [
|
||||||
{
|
{
|
||||||
"name": "Greg Sherwood",
|
"name": "Greg Sherwood",
|
||||||
"role": "lead"
|
"role": "Former lead"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Juliette Reinders Folmer",
|
||||||
|
"role": "Current lead"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Contributors",
|
||||||
|
"homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer/graphs/contributors"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.",
|
"description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.",
|
||||||
"homepage": "https://github.com/squizlabs/PHP_CodeSniffer",
|
"homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"phpcs",
|
"phpcs",
|
||||||
"standards",
|
"standards",
|
||||||
"static analysis"
|
"static analysis"
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues",
|
"issues": "https://github.com/PHPCSStandards/PHP_CodeSniffer/issues",
|
||||||
"source": "https://github.com/squizlabs/PHP_CodeSniffer",
|
"security": "https://github.com/PHPCSStandards/PHP_CodeSniffer/security/policy",
|
||||||
"wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki"
|
"source": "https://github.com/PHPCSStandards/PHP_CodeSniffer",
|
||||||
|
"wiki": "https://github.com/PHPCSStandards/PHP_CodeSniffer/wiki"
|
||||||
},
|
},
|
||||||
"time": "2023-02-22T23:07:41+00:00"
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://github.com/PHPCSStandards",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/jrfnl",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://opencollective.com/php_codesniffer",
|
||||||
|
"type": "open_collective"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2024-01-11T20:47:48+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/console",
|
"name": "symfony/console",
|
||||||
"version": "v5.4.26",
|
"version": "v5.4.35",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/console.git",
|
"url": "https://github.com/symfony/console.git",
|
||||||
"reference": "b504a3d266ad2bb632f196c0936ef2af5ff6e273"
|
"reference": "dbdf6adcb88d5f83790e1efb57ef4074309d3931"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/console/zipball/b504a3d266ad2bb632f196c0936ef2af5ff6e273",
|
"url": "https://api.github.com/repos/symfony/console/zipball/dbdf6adcb88d5f83790e1efb57ef4074309d3931",
|
||||||
"reference": "b504a3d266ad2bb632f196c0936ef2af5ff6e273",
|
"reference": "dbdf6adcb88d5f83790e1efb57ef4074309d3931",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -3873,7 +3894,7 @@
|
||||||
"terminal"
|
"terminal"
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/console/tree/v5.4.26"
|
"source": "https://github.com/symfony/console/tree/v5.4.35"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
@ -3889,7 +3910,7 @@
|
||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2023-07-19T20:11:33+00:00"
|
"time": "2024-01-23T14:28:09+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/deprecation-contracts",
|
"name": "symfony/deprecation-contracts",
|
||||||
|
@ -3960,16 +3981,16 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/polyfill-ctype",
|
"name": "symfony/polyfill-ctype",
|
||||||
"version": "v1.27.0",
|
"version": "v1.29.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/polyfill-ctype.git",
|
"url": "https://github.com/symfony/polyfill-ctype.git",
|
||||||
"reference": "5bbc823adecdae860bb64756d639ecfec17b050a"
|
"reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/5bbc823adecdae860bb64756d639ecfec17b050a",
|
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ef4d7e442ca910c4764bce785146269b30cb5fc4",
|
||||||
"reference": "5bbc823adecdae860bb64756d639ecfec17b050a",
|
"reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -3983,9 +4004,6 @@
|
||||||
},
|
},
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"extra": {
|
"extra": {
|
||||||
"branch-alias": {
|
|
||||||
"dev-main": "1.27-dev"
|
|
||||||
},
|
|
||||||
"thanks": {
|
"thanks": {
|
||||||
"name": "symfony/polyfill",
|
"name": "symfony/polyfill",
|
||||||
"url": "https://github.com/symfony/polyfill"
|
"url": "https://github.com/symfony/polyfill"
|
||||||
|
@ -4022,7 +4040,7 @@
|
||||||
"portable"
|
"portable"
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.27.0"
|
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.29.0"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
@ -4038,20 +4056,20 @@
|
||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2022-11-03T14:55:06+00:00"
|
"time": "2024-01-29T20:11:03+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/polyfill-intl-grapheme",
|
"name": "symfony/polyfill-intl-grapheme",
|
||||||
"version": "v1.27.0",
|
"version": "v1.29.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/polyfill-intl-grapheme.git",
|
"url": "https://github.com/symfony/polyfill-intl-grapheme.git",
|
||||||
"reference": "511a08c03c1960e08a883f4cffcacd219b758354"
|
"reference": "32a9da87d7b3245e09ac426c83d334ae9f06f80f"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/511a08c03c1960e08a883f4cffcacd219b758354",
|
"url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/32a9da87d7b3245e09ac426c83d334ae9f06f80f",
|
||||||
"reference": "511a08c03c1960e08a883f4cffcacd219b758354",
|
"reference": "32a9da87d7b3245e09ac426c83d334ae9f06f80f",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -4062,9 +4080,6 @@
|
||||||
},
|
},
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"extra": {
|
"extra": {
|
||||||
"branch-alias": {
|
|
||||||
"dev-main": "1.27-dev"
|
|
||||||
},
|
|
||||||
"thanks": {
|
"thanks": {
|
||||||
"name": "symfony/polyfill",
|
"name": "symfony/polyfill",
|
||||||
"url": "https://github.com/symfony/polyfill"
|
"url": "https://github.com/symfony/polyfill"
|
||||||
|
@ -4103,7 +4118,7 @@
|
||||||
"shim"
|
"shim"
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.27.0"
|
"source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.29.0"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
@ -4119,20 +4134,20 @@
|
||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2022-11-03T14:55:06+00:00"
|
"time": "2024-01-29T20:11:03+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/polyfill-intl-normalizer",
|
"name": "symfony/polyfill-intl-normalizer",
|
||||||
"version": "v1.27.0",
|
"version": "v1.29.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/polyfill-intl-normalizer.git",
|
"url": "https://github.com/symfony/polyfill-intl-normalizer.git",
|
||||||
"reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6"
|
"reference": "bc45c394692b948b4d383a08d7753968bed9a83d"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/19bd1e4fcd5b91116f14d8533c57831ed00571b6",
|
"url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/bc45c394692b948b4d383a08d7753968bed9a83d",
|
||||||
"reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6",
|
"reference": "bc45c394692b948b4d383a08d7753968bed9a83d",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -4143,9 +4158,6 @@
|
||||||
},
|
},
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"extra": {
|
"extra": {
|
||||||
"branch-alias": {
|
|
||||||
"dev-main": "1.27-dev"
|
|
||||||
},
|
|
||||||
"thanks": {
|
"thanks": {
|
||||||
"name": "symfony/polyfill",
|
"name": "symfony/polyfill",
|
||||||
"url": "https://github.com/symfony/polyfill"
|
"url": "https://github.com/symfony/polyfill"
|
||||||
|
@ -4187,7 +4199,7 @@
|
||||||
"shim"
|
"shim"
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.27.0"
|
"source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.29.0"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
@ -4203,20 +4215,20 @@
|
||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2022-11-03T14:55:06+00:00"
|
"time": "2024-01-29T20:11:03+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/polyfill-mbstring",
|
"name": "symfony/polyfill-mbstring",
|
||||||
"version": "v1.27.0",
|
"version": "v1.29.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/polyfill-mbstring.git",
|
"url": "https://github.com/symfony/polyfill-mbstring.git",
|
||||||
"reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534"
|
"reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8ad114f6b39e2c98a8b0e3bd907732c207c2b534",
|
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9773676c8a1bb1f8d4340a62efe641cf76eda7ec",
|
||||||
"reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534",
|
"reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -4230,9 +4242,6 @@
|
||||||
},
|
},
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"extra": {
|
"extra": {
|
||||||
"branch-alias": {
|
|
||||||
"dev-main": "1.27-dev"
|
|
||||||
},
|
|
||||||
"thanks": {
|
"thanks": {
|
||||||
"name": "symfony/polyfill",
|
"name": "symfony/polyfill",
|
||||||
"url": "https://github.com/symfony/polyfill"
|
"url": "https://github.com/symfony/polyfill"
|
||||||
|
@ -4270,7 +4279,7 @@
|
||||||
"shim"
|
"shim"
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.27.0"
|
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.29.0"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
@ -4286,20 +4295,20 @@
|
||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2022-11-03T14:55:06+00:00"
|
"time": "2024-01-29T20:11:03+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/polyfill-php73",
|
"name": "symfony/polyfill-php73",
|
||||||
"version": "v1.27.0",
|
"version": "v1.29.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/polyfill-php73.git",
|
"url": "https://github.com/symfony/polyfill-php73.git",
|
||||||
"reference": "9e8ecb5f92152187c4799efd3c96b78ccab18ff9"
|
"reference": "21bd091060673a1177ae842c0ef8fe30893114d2"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/9e8ecb5f92152187c4799efd3c96b78ccab18ff9",
|
"url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/21bd091060673a1177ae842c0ef8fe30893114d2",
|
||||||
"reference": "9e8ecb5f92152187c4799efd3c96b78ccab18ff9",
|
"reference": "21bd091060673a1177ae842c0ef8fe30893114d2",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -4307,9 +4316,6 @@
|
||||||
},
|
},
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"extra": {
|
"extra": {
|
||||||
"branch-alias": {
|
|
||||||
"dev-main": "1.27-dev"
|
|
||||||
},
|
|
||||||
"thanks": {
|
"thanks": {
|
||||||
"name": "symfony/polyfill",
|
"name": "symfony/polyfill",
|
||||||
"url": "https://github.com/symfony/polyfill"
|
"url": "https://github.com/symfony/polyfill"
|
||||||
|
@ -4349,7 +4355,7 @@
|
||||||
"shim"
|
"shim"
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/polyfill-php73/tree/v1.27.0"
|
"source": "https://github.com/symfony/polyfill-php73/tree/v1.29.0"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
@ -4365,7 +4371,7 @@
|
||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2022-11-03T14:55:06+00:00"
|
"time": "2024-01-29T20:11:03+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/service-contracts",
|
"name": "symfony/service-contracts",
|
||||||
|
@ -4452,16 +4458,16 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/string",
|
"name": "symfony/string",
|
||||||
"version": "v5.4.26",
|
"version": "v5.4.35",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/string.git",
|
"url": "https://github.com/symfony/string.git",
|
||||||
"reference": "1181fe9270e373537475e826873b5867b863883c"
|
"reference": "c209c4d0559acce1c9a2067612cfb5d35756edc2"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/string/zipball/1181fe9270e373537475e826873b5867b863883c",
|
"url": "https://api.github.com/repos/symfony/string/zipball/c209c4d0559acce1c9a2067612cfb5d35756edc2",
|
||||||
"reference": "1181fe9270e373537475e826873b5867b863883c",
|
"reference": "c209c4d0559acce1c9a2067612cfb5d35756edc2",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -4518,7 +4524,7 @@
|
||||||
"utf8"
|
"utf8"
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/string/tree/v5.4.26"
|
"source": "https://github.com/symfony/string/tree/v5.4.35"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
@ -4534,20 +4540,20 @@
|
||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2023-06-28T12:46:07+00:00"
|
"time": "2024-01-23T13:51:25+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "theseer/tokenizer",
|
"name": "theseer/tokenizer",
|
||||||
"version": "1.2.1",
|
"version": "1.2.2",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/theseer/tokenizer.git",
|
"url": "https://github.com/theseer/tokenizer.git",
|
||||||
"reference": "34a41e998c2183e22995f158c581e7b5e755ab9e"
|
"reference": "b2ad5003ca10d4ee50a12da31de12a5774ba6b96"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e",
|
"url": "https://api.github.com/repos/theseer/tokenizer/zipball/b2ad5003ca10d4ee50a12da31de12a5774ba6b96",
|
||||||
"reference": "34a41e998c2183e22995f158c581e7b5e755ab9e",
|
"reference": "b2ad5003ca10d4ee50a12da31de12a5774ba6b96",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -4576,7 +4582,7 @@
|
||||||
"description": "A small library for converting tokenized PHP source code into XML and potentially other formats",
|
"description": "A small library for converting tokenized PHP source code into XML and potentially other formats",
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/theseer/tokenizer/issues",
|
"issues": "https://github.com/theseer/tokenizer/issues",
|
||||||
"source": "https://github.com/theseer/tokenizer/tree/1.2.1"
|
"source": "https://github.com/theseer/tokenizer/tree/1.2.2"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
@ -4584,7 +4590,7 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2021-07-28T10:34:58+00:00"
|
"time": "2023-11-20T00:12:19+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "vimeo/psalm",
|
"name": "vimeo/psalm",
|
||||||
|
@ -4696,31 +4702,31 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "vlucas/phpdotenv",
|
"name": "vlucas/phpdotenv",
|
||||||
"version": "v5.5.0",
|
"version": "v5.6.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/vlucas/phpdotenv.git",
|
"url": "https://github.com/vlucas/phpdotenv.git",
|
||||||
"reference": "1a7ea2afc49c3ee6d87061f5a233e3a035d0eae7"
|
"reference": "2cf9fb6054c2bb1d59d1f3817706ecdb9d2934c4"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/1a7ea2afc49c3ee6d87061f5a233e3a035d0eae7",
|
"url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/2cf9fb6054c2bb1d59d1f3817706ecdb9d2934c4",
|
||||||
"reference": "1a7ea2afc49c3ee6d87061f5a233e3a035d0eae7",
|
"reference": "2cf9fb6054c2bb1d59d1f3817706ecdb9d2934c4",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"ext-pcre": "*",
|
"ext-pcre": "*",
|
||||||
"graham-campbell/result-type": "^1.0.2",
|
"graham-campbell/result-type": "^1.1.2",
|
||||||
"php": "^7.1.3 || ^8.0",
|
"php": "^7.2.5 || ^8.0",
|
||||||
"phpoption/phpoption": "^1.8",
|
"phpoption/phpoption": "^1.9.2",
|
||||||
"symfony/polyfill-ctype": "^1.23",
|
"symfony/polyfill-ctype": "^1.24",
|
||||||
"symfony/polyfill-mbstring": "^1.23.1",
|
"symfony/polyfill-mbstring": "^1.24",
|
||||||
"symfony/polyfill-php80": "^1.23.1"
|
"symfony/polyfill-php80": "^1.24"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"bamarni/composer-bin-plugin": "^1.4.1",
|
"bamarni/composer-bin-plugin": "^1.8.2",
|
||||||
"ext-filter": "*",
|
"ext-filter": "*",
|
||||||
"phpunit/phpunit": "^7.5.20 || ^8.5.30 || ^9.5.25"
|
"phpunit/phpunit": "^8.5.34 || ^9.6.13 || ^10.4.2"
|
||||||
},
|
},
|
||||||
"suggest": {
|
"suggest": {
|
||||||
"ext-filter": "Required to use the boolean validator."
|
"ext-filter": "Required to use the boolean validator."
|
||||||
|
@ -4732,7 +4738,7 @@
|
||||||
"forward-command": true
|
"forward-command": true
|
||||||
},
|
},
|
||||||
"branch-alias": {
|
"branch-alias": {
|
||||||
"dev-master": "5.5-dev"
|
"dev-master": "5.6-dev"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
|
@ -4764,7 +4770,7 @@
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/vlucas/phpdotenv/issues",
|
"issues": "https://github.com/vlucas/phpdotenv/issues",
|
||||||
"source": "https://github.com/vlucas/phpdotenv/tree/v5.5.0"
|
"source": "https://github.com/vlucas/phpdotenv/tree/v5.6.0"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
@ -4776,7 +4782,7 @@
|
||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2022-10-16T01:01:54+00:00"
|
"time": "2023-11-12T22:43:29+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "webmozart/assert",
|
"name": "webmozart/assert",
|
||||||
|
@ -4996,5 +5002,5 @@
|
||||||
"ext-json": "*"
|
"ext-json": "*"
|
||||||
},
|
},
|
||||||
"platform-dev": [],
|
"platform-dev": [],
|
||||||
"plugin-api-version": "2.3.0"
|
"plugin-api-version": "2.6.0"
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use WooCommerce\PayPalCommerce\PayLaterBlock\PayLaterBlockModule;
|
use WooCommerce\PayPalCommerce\PayLaterBlock\PayLaterBlockModule;
|
||||||
|
use WooCommerce\PayPalCommerce\PayLaterConfigurator\PayLaterConfiguratorModule;
|
||||||
use WooCommerce\PayPalCommerce\PluginModule;
|
use WooCommerce\PayPalCommerce\PluginModule;
|
||||||
|
|
||||||
return function ( string $root_dir ): iterable {
|
return function ( string $root_dir ): iterable {
|
||||||
|
@ -67,10 +68,14 @@ return function ( string $root_dir ): iterable {
|
||||||
$modules[] = ( require "$modules_dir/ppcp-save-payment-methods/module.php" )();
|
$modules[] = ( require "$modules_dir/ppcp-save-payment-methods/module.php" )();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( PayLaterBlockModule::is_enabled() ) {
|
if ( PayLaterBlockModule::is_module_loading_required() ) {
|
||||||
$modules[] = ( require "$modules_dir/ppcp-paylater-block/module.php" )();
|
$modules[] = ( require "$modules_dir/ppcp-paylater-block/module.php" )();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( PayLaterConfiguratorModule::is_enabled() ) {
|
||||||
|
$modules[] = ( require "$modules_dir/ppcp-paylater-configurator/module.php" )();
|
||||||
|
}
|
||||||
|
|
||||||
if ( apply_filters(
|
if ( apply_filters(
|
||||||
'woocommerce.feature-flags.woocommerce_paypal_payments.axo_enabled',
|
'woocommerce.feature-flags.woocommerce_paypal_payments.axo_enabled',
|
||||||
getenv( 'PCP_AXO_ENABLED' ) === '1'
|
getenv( 'PCP_AXO_ENABLED' ) === '1'
|
||||||
|
|
|
@ -9,6 +9,8 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace WooCommerce\PayPalCommerce\AdminNotices;
|
namespace WooCommerce\PayPalCommerce\AdminNotices;
|
||||||
|
|
||||||
|
use WooCommerce\PayPalCommerce\AdminNotices\Entity\Message;
|
||||||
|
use WooCommerce\PayPalCommerce\AdminNotices\Repository\Repository;
|
||||||
use WooCommerce\PayPalCommerce\Vendor\Dhii\Container\ServiceProvider;
|
use WooCommerce\PayPalCommerce\Vendor\Dhii\Container\ServiceProvider;
|
||||||
use WooCommerce\PayPalCommerce\Vendor\Dhii\Modular\Module\ModuleInterface;
|
use WooCommerce\PayPalCommerce\Vendor\Dhii\Modular\Module\ModuleInterface;
|
||||||
use WooCommerce\PayPalCommerce\Vendor\Interop\Container\ServiceProviderInterface;
|
use WooCommerce\PayPalCommerce\Vendor\Interop\Container\ServiceProviderInterface;
|
||||||
|
@ -40,6 +42,34 @@ class AdminNotices implements ModuleInterface {
|
||||||
$renderer->render();
|
$renderer->render();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
add_action(
|
||||||
|
Repository::NOTICES_FILTER,
|
||||||
|
/**
|
||||||
|
* Adds persisted notices to the notices array.
|
||||||
|
*
|
||||||
|
* @param array $notices The notices.
|
||||||
|
* @return array
|
||||||
|
*
|
||||||
|
* @psalm-suppress MissingClosureParamType
|
||||||
|
*/
|
||||||
|
function ( $notices ) use ( $c ) {
|
||||||
|
if ( ! is_array( $notices ) ) {
|
||||||
|
return $notices;
|
||||||
|
}
|
||||||
|
|
||||||
|
$admin_notices = $c->get( 'admin-notices.repository' );
|
||||||
|
assert( $admin_notices instanceof Repository );
|
||||||
|
|
||||||
|
$persisted_notices = $admin_notices->get_persisted_and_clear();
|
||||||
|
|
||||||
|
if ( $persisted_notices ) {
|
||||||
|
$notices = array_merge( $notices, $persisted_notices );
|
||||||
|
}
|
||||||
|
|
||||||
|
return $notices;
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -92,4 +92,18 @@ class Message {
|
||||||
public function wrapper(): string {
|
public function wrapper(): string {
|
||||||
return $this->wrapper;
|
return $this->wrapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the object as array.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function to_array(): array {
|
||||||
|
return array(
|
||||||
|
'type' => $this->type,
|
||||||
|
'message' => $this->message,
|
||||||
|
'dismissable' => $this->dismissable,
|
||||||
|
'wrapper' => $this->wrapper,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,8 @@ use WooCommerce\PayPalCommerce\AdminNotices\Entity\Message;
|
||||||
*/
|
*/
|
||||||
class Repository implements RepositoryInterface {
|
class Repository implements RepositoryInterface {
|
||||||
|
|
||||||
const NOTICES_FILTER = 'ppcp.admin-notices.current-notices';
|
const NOTICES_FILTER = 'ppcp.admin-notices.current-notices';
|
||||||
|
const PERSISTED_NOTICES_OPTION = 'woocommerce_ppcp-admin-notices';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the current messages.
|
* Returns the current messages.
|
||||||
|
@ -37,4 +38,40 @@ class Repository implements RepositoryInterface {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a message to persist between page reloads.
|
||||||
|
*
|
||||||
|
* @param Message $message The message.
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function persist( Message $message ): void {
|
||||||
|
$persisted_notices = get_option( self::PERSISTED_NOTICES_OPTION ) ?: array();
|
||||||
|
|
||||||
|
$persisted_notices[] = $message->to_array();
|
||||||
|
|
||||||
|
update_option( self::PERSISTED_NOTICES_OPTION, $persisted_notices );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a message to persist between page reloads.
|
||||||
|
*
|
||||||
|
* @return array|Message[]
|
||||||
|
*/
|
||||||
|
public function get_persisted_and_clear(): array {
|
||||||
|
$notices = array();
|
||||||
|
|
||||||
|
$persisted_data = get_option( self::PERSISTED_NOTICES_OPTION ) ?: array();
|
||||||
|
foreach ( $persisted_data as $notice_data ) {
|
||||||
|
$notices[] = new Message(
|
||||||
|
(string) ( $notice_data['message'] ?? '' ),
|
||||||
|
(string) ( $notice_data['type'] ?? '' ),
|
||||||
|
(bool) ( $notice_data['dismissable'] ?? true ),
|
||||||
|
(string) ( $notice_data['wrapper'] ?? '' )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
update_option( self::PERSISTED_NOTICES_OPTION, array(), true );
|
||||||
|
return $notices;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -417,7 +417,7 @@ return array(
|
||||||
return new PaymentsFactory( $authorizations_factory, $capture_factory, $refund_factory );
|
return new PaymentsFactory( $authorizations_factory, $capture_factory, $refund_factory );
|
||||||
},
|
},
|
||||||
'api.factory.authorization' => static function ( ContainerInterface $container ): AuthorizationFactory {
|
'api.factory.authorization' => static function ( ContainerInterface $container ): AuthorizationFactory {
|
||||||
return new AuthorizationFactory();
|
return new AuthorizationFactory( $container->get( 'api.factory.fraud-processor-response' ) );
|
||||||
},
|
},
|
||||||
'api.factory.exchange-rate' => static function ( ContainerInterface $container ): ExchangeRateFactory {
|
'api.factory.exchange-rate' => static function ( ContainerInterface $container ): ExchangeRateFactory {
|
||||||
return new ExchangeRateFactory();
|
return new ExchangeRateFactory();
|
||||||
|
@ -626,6 +626,30 @@ return array(
|
||||||
'TWD',
|
'TWD',
|
||||||
'USD',
|
'USD',
|
||||||
),
|
),
|
||||||
|
'AT' => array(
|
||||||
|
'AUD',
|
||||||
|
'BRL',
|
||||||
|
'CAD',
|
||||||
|
'CHF',
|
||||||
|
'CZK',
|
||||||
|
'DKK',
|
||||||
|
'EUR',
|
||||||
|
'GBP',
|
||||||
|
'HKD',
|
||||||
|
'HUF',
|
||||||
|
'ILS',
|
||||||
|
'JPY',
|
||||||
|
'MXN',
|
||||||
|
'NOK',
|
||||||
|
'NZD',
|
||||||
|
'PHP',
|
||||||
|
'PLN',
|
||||||
|
'SEK',
|
||||||
|
'SGD',
|
||||||
|
'THB',
|
||||||
|
'TWD',
|
||||||
|
'USD',
|
||||||
|
),
|
||||||
'BE' => array(
|
'BE' => array(
|
||||||
'AUD',
|
'AUD',
|
||||||
'BRL',
|
'BRL',
|
||||||
|
@ -914,6 +938,30 @@ return array(
|
||||||
'TWD',
|
'TWD',
|
||||||
'USD',
|
'USD',
|
||||||
),
|
),
|
||||||
|
'IE' => array(
|
||||||
|
'AUD',
|
||||||
|
'BRL',
|
||||||
|
'CAD',
|
||||||
|
'CHF',
|
||||||
|
'CZK',
|
||||||
|
'DKK',
|
||||||
|
'EUR',
|
||||||
|
'GBP',
|
||||||
|
'HKD',
|
||||||
|
'HUF',
|
||||||
|
'ILS',
|
||||||
|
'JPY',
|
||||||
|
'MXN',
|
||||||
|
'NOK',
|
||||||
|
'NZD',
|
||||||
|
'PHP',
|
||||||
|
'PLN',
|
||||||
|
'SEK',
|
||||||
|
'SGD',
|
||||||
|
'THB',
|
||||||
|
'TWD',
|
||||||
|
'USD',
|
||||||
|
),
|
||||||
'IT' => array(
|
'IT' => array(
|
||||||
'AUD',
|
'AUD',
|
||||||
'BRL',
|
'BRL',
|
||||||
|
@ -1310,11 +1358,28 @@ return array(
|
||||||
'USD',
|
'USD',
|
||||||
),
|
),
|
||||||
'NO' => array(
|
'NO' => array(
|
||||||
'EUR',
|
'AUD',
|
||||||
'USD',
|
'BRL',
|
||||||
'CAD',
|
'CAD',
|
||||||
|
'CHF',
|
||||||
|
'CZK',
|
||||||
|
'DKK',
|
||||||
|
'EUR',
|
||||||
'GBP',
|
'GBP',
|
||||||
|
'HKD',
|
||||||
|
'HUF',
|
||||||
|
'ILS',
|
||||||
|
'JPY',
|
||||||
|
'MXN',
|
||||||
'NOK',
|
'NOK',
|
||||||
|
'NZD',
|
||||||
|
'PHP',
|
||||||
|
'PLN',
|
||||||
|
'SEK',
|
||||||
|
'SGD',
|
||||||
|
'THB',
|
||||||
|
'TWD',
|
||||||
|
'USD',
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
@ -1335,35 +1400,40 @@ return array(
|
||||||
'visa' => array(),
|
'visa' => array(),
|
||||||
'amex' => array( 'AUD' ),
|
'amex' => array( 'AUD' ),
|
||||||
),
|
),
|
||||||
|
'AT' => array(
|
||||||
|
'mastercard' => array(),
|
||||||
|
'visa' => array(),
|
||||||
|
'amex' => array(),
|
||||||
|
),
|
||||||
'BE' => array(
|
'BE' => array(
|
||||||
'mastercard' => array(),
|
'mastercard' => array(),
|
||||||
'visa' => array(),
|
'visa' => array(),
|
||||||
'amex' => array( 'EUR', 'USD', 'CAD' ),
|
'amex' => array(),
|
||||||
),
|
),
|
||||||
'BG' => array(
|
'BG' => array(
|
||||||
'mastercard' => array(),
|
'mastercard' => array(),
|
||||||
'visa' => array(),
|
'visa' => array(),
|
||||||
'amex' => array( 'EUR' ),
|
'amex' => array(),
|
||||||
),
|
),
|
||||||
'CY' => array(
|
'CY' => array(
|
||||||
'mastercard' => array(),
|
'mastercard' => array(),
|
||||||
'visa' => array(),
|
'visa' => array(),
|
||||||
'amex' => array( 'EUR' ),
|
'amex' => array(),
|
||||||
),
|
),
|
||||||
'CZ' => array(
|
'CZ' => array(
|
||||||
'mastercard' => array(),
|
'mastercard' => array(),
|
||||||
'visa' => array(),
|
'visa' => array(),
|
||||||
'amex' => array( 'CZK' ),
|
'amex' => array(),
|
||||||
),
|
),
|
||||||
'DE' => array(
|
'DE' => array(
|
||||||
'mastercard' => array(),
|
'mastercard' => array(),
|
||||||
'visa' => array(),
|
'visa' => array(),
|
||||||
'amex' => array( 'EUR' ),
|
'amex' => array(),
|
||||||
),
|
),
|
||||||
'DK' => array(
|
'DK' => array(
|
||||||
'mastercard' => array(),
|
'mastercard' => array(),
|
||||||
'visa' => array(),
|
'visa' => array(),
|
||||||
'amex' => array( 'DKK' ),
|
'amex' => array(),
|
||||||
),
|
),
|
||||||
'EE' => array(
|
'EE' => array(
|
||||||
'mastercard' => array(),
|
'mastercard' => array(),
|
||||||
|
@ -1373,37 +1443,42 @@ return array(
|
||||||
'ES' => array(
|
'ES' => array(
|
||||||
'mastercard' => array(),
|
'mastercard' => array(),
|
||||||
'visa' => array(),
|
'visa' => array(),
|
||||||
'amex' => array( 'EUR' ),
|
'amex' => array(),
|
||||||
),
|
),
|
||||||
'FI' => array(
|
'FI' => array(
|
||||||
'mastercard' => array(),
|
'mastercard' => array(),
|
||||||
'visa' => array(),
|
'visa' => array(),
|
||||||
'amex' => array( 'EUR' ),
|
'amex' => array(),
|
||||||
),
|
),
|
||||||
'FR' => array(
|
'FR' => array(
|
||||||
'mastercard' => array(),
|
'mastercard' => array(),
|
||||||
'visa' => array(),
|
'visa' => array(),
|
||||||
'amex' => array( 'EUR' ),
|
'amex' => array(),
|
||||||
),
|
),
|
||||||
'GB' => array(
|
'GB' => array(
|
||||||
'mastercard' => array(),
|
'mastercard' => array(),
|
||||||
'visa' => array(),
|
'visa' => array(),
|
||||||
'amex' => array( 'GBP', 'USD' ),
|
'amex' => array(),
|
||||||
),
|
),
|
||||||
'GR' => array(
|
'GR' => array(
|
||||||
'mastercard' => array(),
|
'mastercard' => array(),
|
||||||
'visa' => array(),
|
'visa' => array(),
|
||||||
'amex' => array( 'EUR' ),
|
'amex' => array(),
|
||||||
),
|
),
|
||||||
'HU' => array(
|
'HU' => array(
|
||||||
'mastercard' => array(),
|
'mastercard' => array(),
|
||||||
'visa' => array(),
|
'visa' => array(),
|
||||||
'amex' => array( 'HUF' ),
|
'amex' => array(),
|
||||||
|
),
|
||||||
|
'IE' => array(
|
||||||
|
'mastercard' => array(),
|
||||||
|
'visa' => array(),
|
||||||
|
'amex' => array(),
|
||||||
),
|
),
|
||||||
'IT' => array(
|
'IT' => array(
|
||||||
'mastercard' => array(),
|
'mastercard' => array(),
|
||||||
'visa' => array(),
|
'visa' => array(),
|
||||||
'amex' => array( 'EUR' ),
|
'amex' => array(),
|
||||||
),
|
),
|
||||||
'US' => array(
|
'US' => array(
|
||||||
'mastercard' => array(),
|
'mastercard' => array(),
|
||||||
|
@ -1414,28 +1489,33 @@ return array(
|
||||||
'CA' => array(
|
'CA' => array(
|
||||||
'mastercard' => array(),
|
'mastercard' => array(),
|
||||||
'visa' => array(),
|
'visa' => array(),
|
||||||
'amex' => array( 'CAD' ),
|
'amex' => array( 'CAD', 'USD' ),
|
||||||
'jcb' => array( 'CAD' ),
|
'jcb' => array( 'CAD' ),
|
||||||
),
|
),
|
||||||
|
'LI' => array(
|
||||||
|
'mastercard' => array(),
|
||||||
|
'visa' => array(),
|
||||||
|
'amex' => array(),
|
||||||
|
),
|
||||||
'LT' => array(
|
'LT' => array(
|
||||||
'mastercard' => array(),
|
'mastercard' => array(),
|
||||||
'visa' => array(),
|
'visa' => array(),
|
||||||
'amex' => array( 'EUR' ),
|
'amex' => array(),
|
||||||
),
|
),
|
||||||
'LU' => array(
|
'LU' => array(
|
||||||
'mastercard' => array(),
|
'mastercard' => array(),
|
||||||
'visa' => array(),
|
'visa' => array(),
|
||||||
'amex' => array( 'EUR' ),
|
'amex' => array(),
|
||||||
),
|
),
|
||||||
'LV' => array(
|
'LV' => array(
|
||||||
'mastercard' => array(),
|
'mastercard' => array(),
|
||||||
'visa' => array(),
|
'visa' => array(),
|
||||||
'amex' => array( 'EUR', 'USD' ),
|
'amex' => array(),
|
||||||
),
|
),
|
||||||
'MT' => array(
|
'MT' => array(
|
||||||
'mastercard' => array(),
|
'mastercard' => array(),
|
||||||
'visa' => array(),
|
'visa' => array(),
|
||||||
'amex' => array( 'EUR' ),
|
'amex' => array(),
|
||||||
),
|
),
|
||||||
'MX' => array(
|
'MX' => array(
|
||||||
'mastercard' => array(),
|
'mastercard' => array(),
|
||||||
|
@ -1445,42 +1525,42 @@ return array(
|
||||||
'NL' => array(
|
'NL' => array(
|
||||||
'mastercard' => array(),
|
'mastercard' => array(),
|
||||||
'visa' => array(),
|
'visa' => array(),
|
||||||
'amex' => array( 'EUR', 'USD' ),
|
'amex' => array(),
|
||||||
),
|
),
|
||||||
'NO' => array(
|
'NO' => array(
|
||||||
'mastercard' => array(),
|
'mastercard' => array(),
|
||||||
'visa' => array(),
|
'visa' => array(),
|
||||||
'amex' => array( 'NOK' ),
|
'amex' => array(),
|
||||||
),
|
),
|
||||||
'PL' => array(
|
'PL' => array(
|
||||||
'mastercard' => array(),
|
'mastercard' => array(),
|
||||||
'visa' => array(),
|
'visa' => array(),
|
||||||
'amex' => array( 'EUR', 'USD', 'GBP', 'PLN' ),
|
'amex' => array(),
|
||||||
),
|
),
|
||||||
'PT' => array(
|
'PT' => array(
|
||||||
'mastercard' => array(),
|
'mastercard' => array(),
|
||||||
'visa' => array(),
|
'visa' => array(),
|
||||||
'amex' => array( 'EUR', 'USD', 'CAD', 'GBP' ),
|
'amex' => array(),
|
||||||
),
|
),
|
||||||
'RO' => array(
|
'RO' => array(
|
||||||
'mastercard' => array(),
|
'mastercard' => array(),
|
||||||
'visa' => array(),
|
'visa' => array(),
|
||||||
'amex' => array( 'EUR', 'USD' ),
|
'amex' => array(),
|
||||||
),
|
),
|
||||||
'SE' => array(
|
'SE' => array(
|
||||||
'mastercard' => array(),
|
'mastercard' => array(),
|
||||||
'visa' => array(),
|
'visa' => array(),
|
||||||
'amex' => array( 'EUR', 'SEK' ),
|
'amex' => array(),
|
||||||
),
|
),
|
||||||
'SI' => array(
|
'SI' => array(
|
||||||
'mastercard' => array(),
|
'mastercard' => array(),
|
||||||
'visa' => array(),
|
'visa' => array(),
|
||||||
'amex' => array( 'EUR' ),
|
'amex' => array(),
|
||||||
),
|
),
|
||||||
'SK' => array(
|
'SK' => array(
|
||||||
'mastercard' => array(),
|
'mastercard' => array(),
|
||||||
'visa' => array(),
|
'visa' => array(),
|
||||||
'amex' => array( 'EUR', 'GBP' ),
|
'amex' => array(),
|
||||||
),
|
),
|
||||||
'JP' => array(
|
'JP' => array(
|
||||||
'mastercard' => array(),
|
'mastercard' => array(),
|
||||||
|
|
|
@ -115,7 +115,7 @@ class PaymentMethodTokensEndpoint {
|
||||||
* @throws RuntimeException When something when wrong with the request.
|
* @throws RuntimeException When something when wrong with the request.
|
||||||
* @throws PayPalApiException When something when wrong setting up the token.
|
* @throws PayPalApiException When something when wrong setting up the token.
|
||||||
*/
|
*/
|
||||||
public function payment_tokens( PaymentSource $payment_source ): stdClass {
|
public function create_payment_token( PaymentSource $payment_source ): stdClass {
|
||||||
$data = array(
|
$data = array(
|
||||||
'payment_source' => array(
|
'payment_source' => array(
|
||||||
$payment_source->name() => $payment_source->properties(),
|
$payment_source->name() => $payment_source->properties(),
|
||||||
|
|
|
@ -11,6 +11,7 @@ namespace WooCommerce\PayPalCommerce\ApiClient\Endpoint;
|
||||||
|
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
use WooCommerce\PayPalCommerce\ApiClient\Authentication\Bearer;
|
use WooCommerce\PayPalCommerce\ApiClient\Authentication\Bearer;
|
||||||
|
use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentSource;
|
||||||
use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
|
use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
|
||||||
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||||
use WP_Error;
|
use WP_Error;
|
||||||
|
@ -92,4 +93,53 @@ class PaymentTokensEndpoint {
|
||||||
throw new PayPalApiException( $json, $status_code );
|
throw new PayPalApiException( $json, $status_code );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all payment tokens for the given customer.
|
||||||
|
*
|
||||||
|
* @param string $customer_id PayPal customer id.
|
||||||
|
* @return array
|
||||||
|
*
|
||||||
|
* @throws RuntimeException When something went wrong with the request.
|
||||||
|
* @throws PayPalApiException When something went wrong getting the payment tokens.
|
||||||
|
*/
|
||||||
|
public function payment_tokens_for_customer( string $customer_id ): array {
|
||||||
|
$bearer = $this->bearer->bearer();
|
||||||
|
$url = trailingslashit( $this->host ) . 'v3/vault/payment-tokens?customer_id=' . $customer_id;
|
||||||
|
$args = array(
|
||||||
|
'method' => 'GET',
|
||||||
|
'headers' => array(
|
||||||
|
'Authorization' => 'Bearer ' . $bearer->token(),
|
||||||
|
'Content-Type' => 'application/json',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
$response = $this->request( $url, $args );
|
||||||
|
if ( $response instanceof WP_Error ) {
|
||||||
|
throw new RuntimeException( $response->get_error_message() );
|
||||||
|
}
|
||||||
|
|
||||||
|
$json = json_decode( $response['body'] );
|
||||||
|
$status_code = (int) wp_remote_retrieve_response_code( $response );
|
||||||
|
if ( 200 !== $status_code ) {
|
||||||
|
throw new PayPalApiException( $json, $status_code );
|
||||||
|
}
|
||||||
|
|
||||||
|
$tokens = array();
|
||||||
|
$payment_tokens = $json->payment_tokens ?? array();
|
||||||
|
foreach ( $payment_tokens as $payment_token ) {
|
||||||
|
$name = array_key_first( (array) $payment_token->payment_source ) ?? '';
|
||||||
|
if ( $name ) {
|
||||||
|
$tokens[] = array(
|
||||||
|
'id' => $payment_token->id,
|
||||||
|
'payment_source' => new PaymentSource(
|
||||||
|
$name,
|
||||||
|
$payment_token->payment_source->$name
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $tokens;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -193,6 +193,53 @@ class PaymentsEndpoint {
|
||||||
return $this->capture_factory->from_paypal_response( $json );
|
return $this->capture_factory->from_paypal_response( $json );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reauthorizes an order.
|
||||||
|
*
|
||||||
|
* @param string $authorization_id The id.
|
||||||
|
* @param Money|null $amount The amount to capture. If not specified, the whole authorized amount is captured.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* @throws RuntimeException If the request fails.
|
||||||
|
* @throws PayPalApiException If the request fails.
|
||||||
|
*/
|
||||||
|
public function reauthorize( string $authorization_id, ?Money $amount = null ) : string {
|
||||||
|
$bearer = $this->bearer->bearer();
|
||||||
|
$url = trailingslashit( $this->host ) . 'v2/payments/authorizations/' . $authorization_id . '/reauthorize';
|
||||||
|
|
||||||
|
$data = array();
|
||||||
|
if ( $amount ) {
|
||||||
|
$data['amount'] = $amount->to_array();
|
||||||
|
}
|
||||||
|
|
||||||
|
$args = array(
|
||||||
|
'method' => 'POST',
|
||||||
|
'headers' => array(
|
||||||
|
'Authorization' => 'Bearer ' . $bearer->token(),
|
||||||
|
'Content-Type' => 'application/json',
|
||||||
|
'Prefer' => 'return=representation',
|
||||||
|
),
|
||||||
|
'body' => wp_json_encode( $data, JSON_FORCE_OBJECT ),
|
||||||
|
);
|
||||||
|
|
||||||
|
$response = $this->request( $url, $args );
|
||||||
|
$json = json_decode( $response['body'] );
|
||||||
|
|
||||||
|
if ( is_wp_error( $response ) ) {
|
||||||
|
throw new RuntimeException( 'Could not reauthorize authorized payment.' );
|
||||||
|
}
|
||||||
|
|
||||||
|
$status_code = (int) wp_remote_retrieve_response_code( $response );
|
||||||
|
if ( 201 !== $status_code || ! is_object( $json ) ) {
|
||||||
|
throw new PayPalApiException(
|
||||||
|
$json,
|
||||||
|
$status_code
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $json->id;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Refunds a payment.
|
* Refunds a payment.
|
||||||
*
|
*
|
||||||
|
|
|
@ -28,19 +28,29 @@ class Authorization {
|
||||||
*/
|
*/
|
||||||
private $authorization_status;
|
private $authorization_status;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The fraud processor response (AVS, CVV ...).
|
||||||
|
*
|
||||||
|
* @var FraudProcessorResponse|null
|
||||||
|
*/
|
||||||
|
protected $fraud_processor_response;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Authorization constructor.
|
* Authorization constructor.
|
||||||
*
|
*
|
||||||
* @param string $id The id.
|
* @param string $id The id.
|
||||||
* @param AuthorizationStatus $authorization_status The status.
|
* @param AuthorizationStatus $authorization_status The status.
|
||||||
|
* @param FraudProcessorResponse|null $fraud_processor_response The fraud processor response (AVS, CVV ...).
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
string $id,
|
string $id,
|
||||||
AuthorizationStatus $authorization_status
|
AuthorizationStatus $authorization_status,
|
||||||
|
?FraudProcessorResponse $fraud_processor_response
|
||||||
) {
|
) {
|
||||||
|
|
||||||
$this->id = $id;
|
$this->id = $id;
|
||||||
$this->authorization_status = $authorization_status;
|
$this->authorization_status = $authorization_status;
|
||||||
|
$this->fraud_processor_response = $fraud_processor_response;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -71,15 +81,30 @@ class Authorization {
|
||||||
$this->authorization_status->is( AuthorizationStatus::PENDING );
|
$this->authorization_status->is( AuthorizationStatus::PENDING );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the fraud processor response (AVS, CVV ...).
|
||||||
|
*
|
||||||
|
* @return FraudProcessorResponse|null
|
||||||
|
*/
|
||||||
|
public function fraud_processor_response() : ?FraudProcessorResponse {
|
||||||
|
return $this->fraud_processor_response;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the object as array.
|
* Returns the object as array.
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function to_array(): array {
|
public function to_array(): array {
|
||||||
return array(
|
$data = array(
|
||||||
'id' => $this->id,
|
'id' => $this->id,
|
||||||
'status' => $this->authorization_status->name(),
|
'status' => $this->authorization_status->name(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if ( $this->fraud_processor_response ) {
|
||||||
|
$data['fraud_processor_response'] = $this->fraud_processor_response->to_array();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,19 +21,37 @@ class SellerStatus {
|
||||||
*/
|
*/
|
||||||
private $products;
|
private $products;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The capabilities.
|
||||||
|
*
|
||||||
|
* @var SellerStatusCapability[]
|
||||||
|
*/
|
||||||
|
private $capabilities;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SellerStatus constructor.
|
* SellerStatus constructor.
|
||||||
*
|
*
|
||||||
* @param SellerStatusProduct[] $products The products.
|
* @param SellerStatusProduct[] $products The products.
|
||||||
|
* @param SellerStatusCapability[] $capabilities The capabilities.
|
||||||
|
*
|
||||||
|
* @psalm-suppress RedundantConditionGivenDocblockType
|
||||||
*/
|
*/
|
||||||
public function __construct( array $products ) {
|
public function __construct( array $products, array $capabilities ) {
|
||||||
foreach ( $products as $key => $product ) {
|
foreach ( $products as $key => $product ) {
|
||||||
if ( is_a( $product, SellerStatusProduct::class ) ) {
|
if ( is_a( $product, SellerStatusProduct::class ) ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
unset( $products[ $key ] );
|
unset( $products[ $key ] );
|
||||||
}
|
}
|
||||||
$this->products = $products;
|
foreach ( $capabilities as $key => $capability ) {
|
||||||
|
if ( is_a( $capability, SellerStatusCapability::class ) ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
unset( $capabilities[ $key ] );
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->products = $products;
|
||||||
|
$this->capabilities = $capabilities;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -45,6 +63,15 @@ class SellerStatus {
|
||||||
return $this->products;
|
return $this->products;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the capabilities.
|
||||||
|
*
|
||||||
|
* @return SellerStatusCapability[]
|
||||||
|
*/
|
||||||
|
public function capabilities() : array {
|
||||||
|
return $this->capabilities;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the enitity as array.
|
* Returns the enitity as array.
|
||||||
*
|
*
|
||||||
|
@ -58,8 +85,16 @@ class SellerStatus {
|
||||||
$this->products()
|
$this->products()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$capabilities = array_map(
|
||||||
|
function( SellerStatusCapability $capability ) : array {
|
||||||
|
return $capability->to_array();
|
||||||
|
},
|
||||||
|
$this->capabilities()
|
||||||
|
);
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
'products' => $products,
|
'products' => $products,
|
||||||
|
'capabilities' => $capabilities,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* The capabilities of a seller status.
|
||||||
|
*
|
||||||
|
* @package WooCommerce\PayPalCommerce\ApiClient\Entity
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare( strict_types=1 );
|
||||||
|
|
||||||
|
namespace WooCommerce\PayPalCommerce\ApiClient\Entity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class SellerStatusCapability
|
||||||
|
*/
|
||||||
|
class SellerStatusCapability {
|
||||||
|
|
||||||
|
const STATUS_ACTIVE = 'ACTIVE';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of the product.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The status of the capability.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $status;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SellerStatusCapability constructor.
|
||||||
|
*
|
||||||
|
* @param string $name The name of the product.
|
||||||
|
* @param string $status The status of the capability.
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
string $name,
|
||||||
|
string $status
|
||||||
|
) {
|
||||||
|
$this->name = $name;
|
||||||
|
$this->status = $status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the name of the product.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function name() : string {
|
||||||
|
return $this->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the status for this capability.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function status() : string {
|
||||||
|
return $this->status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the entity as array.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function to_array() : array {
|
||||||
|
return array(
|
||||||
|
'name' => $this->name(),
|
||||||
|
'status' => $this->status(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -19,6 +19,22 @@ use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||||
*/
|
*/
|
||||||
class AuthorizationFactory {
|
class AuthorizationFactory {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The FraudProcessorResponseFactory factory.
|
||||||
|
*
|
||||||
|
* @var FraudProcessorResponseFactory
|
||||||
|
*/
|
||||||
|
protected $fraud_processor_response_factory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AuthorizationFactory constructor.
|
||||||
|
*
|
||||||
|
* @param FraudProcessorResponseFactory $fraud_processor_response_factory The FraudProcessorResponseFactory factory.
|
||||||
|
*/
|
||||||
|
public function __construct( FraudProcessorResponseFactory $fraud_processor_response_factory ) {
|
||||||
|
$this->fraud_processor_response_factory = $fraud_processor_response_factory;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an Authorization based off a PayPal response.
|
* Returns an Authorization based off a PayPal response.
|
||||||
*
|
*
|
||||||
|
@ -42,12 +58,17 @@ class AuthorizationFactory {
|
||||||
|
|
||||||
$reason = $data->status_details->reason ?? null;
|
$reason = $data->status_details->reason ?? null;
|
||||||
|
|
||||||
|
$fraud_processor_response = isset( $data->processor_response ) ?
|
||||||
|
$this->fraud_processor_response_factory->from_paypal_response( $data->processor_response )
|
||||||
|
: null;
|
||||||
|
|
||||||
return new Authorization(
|
return new Authorization(
|
||||||
$data->id,
|
$data->id,
|
||||||
new AuthorizationStatus(
|
new AuthorizationStatus(
|
||||||
$data->status,
|
$data->status,
|
||||||
$reason ? new AuthorizationStatusDetails( $reason ) : null
|
$reason ? new AuthorizationStatusDetails( $reason ) : null
|
||||||
)
|
),
|
||||||
|
$fraud_processor_response
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,8 +25,8 @@ class FraudProcessorResponseFactory {
|
||||||
* @return FraudProcessorResponse
|
* @return FraudProcessorResponse
|
||||||
*/
|
*/
|
||||||
public function from_paypal_response( stdClass $data ): FraudProcessorResponse {
|
public function from_paypal_response( stdClass $data ): FraudProcessorResponse {
|
||||||
$avs_code = $data->avs_code ?: null;
|
$avs_code = ( $data->avs_code ?? null ) ?: null;
|
||||||
$cvv_code = $data->cvv_code ?: null;
|
$cvv_code = ( $data->cvv_code ?? null ) ?: null;
|
||||||
|
|
||||||
return new FraudProcessorResponse( $avs_code, $cvv_code );
|
return new FraudProcessorResponse( $avs_code, $cvv_code );
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,12 +61,12 @@ class ItemFactory {
|
||||||
|
|
||||||
$price = (float) $item['line_subtotal'] / (float) $item['quantity'];
|
$price = (float) $item['line_subtotal'] / (float) $item['quantity'];
|
||||||
return new Item(
|
return new Item(
|
||||||
mb_substr( $product->get_name(), 0, 127 ),
|
$this->prepare_item_string( $product->get_name() ),
|
||||||
new Money( $price, $this->currency ),
|
new Money( $price, $this->currency ),
|
||||||
$quantity,
|
$quantity,
|
||||||
$this->prepare_description( $product->get_description() ),
|
$this->prepare_item_string( $product->get_description() ),
|
||||||
null,
|
null,
|
||||||
$product->get_sku(),
|
$this->prepare_sku( $product->get_sku() ),
|
||||||
( $product->is_virtual() ) ? Item::DIGITAL_GOODS : Item::PHYSICAL_GOODS,
|
( $product->is_virtual() ) ? Item::DIGITAL_GOODS : Item::PHYSICAL_GOODS,
|
||||||
$product->get_permalink(),
|
$product->get_permalink(),
|
||||||
$image[0] ?? '',
|
$image[0] ?? '',
|
||||||
|
@ -138,12 +138,12 @@ class ItemFactory {
|
||||||
$image = $product instanceof WC_Product ? wp_get_attachment_image_src( (int) $product->get_image_id(), 'full' ) : '';
|
$image = $product instanceof WC_Product ? wp_get_attachment_image_src( (int) $product->get_image_id(), 'full' ) : '';
|
||||||
|
|
||||||
return new Item(
|
return new Item(
|
||||||
mb_substr( $item->get_name(), 0, 127 ),
|
$this->prepare_item_string( $item->get_name() ),
|
||||||
new Money( $price_without_tax_rounded, $currency ),
|
new Money( $price_without_tax_rounded, $currency ),
|
||||||
$quantity,
|
$quantity,
|
||||||
$product instanceof WC_Product ? $this->prepare_description( $product->get_description() ) : '',
|
$product instanceof WC_Product ? $this->prepare_item_string( $product->get_description() ) : '',
|
||||||
null,
|
null,
|
||||||
$product instanceof WC_Product ? $product->get_sku() : '',
|
$product instanceof WC_Product ? $this->prepare_sku( $product->get_sku() ) : '',
|
||||||
( $product instanceof WC_Product && $product->is_virtual() ) ? Item::DIGITAL_GOODS : Item::PHYSICAL_GOODS,
|
( $product instanceof WC_Product && $product->is_virtual() ) ? Item::DIGITAL_GOODS : Item::PHYSICAL_GOODS,
|
||||||
$product instanceof WC_Product ? $product->get_permalink() : '',
|
$product instanceof WC_Product ? $product->get_permalink() : '',
|
||||||
$image[0] ?? ''
|
$image[0] ?? ''
|
||||||
|
@ -160,7 +160,7 @@ class ItemFactory {
|
||||||
*/
|
*/
|
||||||
private function from_wc_order_fee( \WC_Order_Item_Fee $item, \WC_Order $order ): Item {
|
private function from_wc_order_fee( \WC_Order_Item_Fee $item, \WC_Order $order ): Item {
|
||||||
return new Item(
|
return new Item(
|
||||||
$item->get_name(),
|
$this->prepare_item_string( $item->get_name() ),
|
||||||
new Money( (float) $item->get_amount(), $order->get_currency() ),
|
new Money( (float) $item->get_amount(), $order->get_currency() ),
|
||||||
$item->get_quantity(),
|
$item->get_quantity(),
|
||||||
'',
|
'',
|
||||||
|
|
|
@ -11,6 +11,7 @@ namespace WooCommerce\PayPalCommerce\ApiClient\Factory;
|
||||||
|
|
||||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\SellerStatus;
|
use WooCommerce\PayPalCommerce\ApiClient\Entity\SellerStatus;
|
||||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\SellerStatusProduct;
|
use WooCommerce\PayPalCommerce\ApiClient\Entity\SellerStatusProduct;
|
||||||
|
use WooCommerce\PayPalCommerce\ApiClient\Entity\SellerStatusCapability;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class SellerStatusFactory
|
* Class SellerStatusFactory
|
||||||
|
@ -37,6 +38,17 @@ class SellerStatusFactory {
|
||||||
isset( $json->products ) ? (array) $json->products : array()
|
isset( $json->products ) ? (array) $json->products : array()
|
||||||
);
|
);
|
||||||
|
|
||||||
return new SellerStatus( $products );
|
$capabilities = array_map(
|
||||||
|
function( $json ) : SellerStatusCapability {
|
||||||
|
$capability = new SellerStatusCapability(
|
||||||
|
isset( $json->name ) ? (string) $json->name : '',
|
||||||
|
isset( $json->status ) ? (string) $json->status : ''
|
||||||
|
);
|
||||||
|
return $capability;
|
||||||
|
},
|
||||||
|
isset( $json->capabilities ) ? (array) $json->capabilities : array()
|
||||||
|
);
|
||||||
|
|
||||||
|
return new SellerStatus( $products, $capabilities );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,13 +12,23 @@ namespace WooCommerce\PayPalCommerce\ApiClient\Helper;
|
||||||
trait ItemTrait {
|
trait ItemTrait {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cleanups the description and prepares it for sending to PayPal.
|
* Cleans up item strings (title and description for example) and prepares them for sending to PayPal.
|
||||||
*
|
*
|
||||||
* @param string $description Item description.
|
* @param string $string Item string.
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
protected function prepare_description( string $description ): string {
|
protected function prepare_item_string( string $string ): string {
|
||||||
$description = strip_shortcodes( wp_strip_all_tags( $description ) );
|
$string = strip_shortcodes( wp_strip_all_tags( $string ) );
|
||||||
return substr( $description, 0, 127 ) ?: '';
|
return substr( $string, 0, 127 ) ?: '';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepares the sku for sending to PayPal.
|
||||||
|
*
|
||||||
|
* @param string $sku Item sku.
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function prepare_sku( string $sku ): string {
|
||||||
|
return substr( wp_strip_all_tags( $sku ), 0, 127 ) ?: '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,10 +70,6 @@ class ApplepayButton {
|
||||||
|
|
||||||
if (this.isEligible) {
|
if (this.isEligible) {
|
||||||
this.fetchTransactionInfo().then(() => {
|
this.fetchTransactionInfo().then(() => {
|
||||||
const isSubscriptionProduct = this.ppcpConfig?.data_client_id?.has_subscriptions === true;
|
|
||||||
if (isSubscriptionProduct) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.addButton();
|
this.addButton();
|
||||||
const id_minicart = "#apple-" + this.buttonConfig.button.mini_cart_wrapper;
|
const id_minicart = "#apple-" + this.buttonConfig.button.mini_cart_wrapper;
|
||||||
const id = "#apple-" + this.buttonConfig.button.wrapper;
|
const id = "#apple-" + this.buttonConfig.button.wrapper;
|
||||||
|
@ -214,6 +210,8 @@ class ApplepayButton {
|
||||||
|
|
||||||
const paymentRequest = this.paymentRequest();
|
const paymentRequest = this.paymentRequest();
|
||||||
|
|
||||||
|
window.ppcpFundingSource = 'apple_pay'; // Do this on another place like on create order endpoint handler.
|
||||||
|
|
||||||
// Trigger woocommerce validation if we are in the checkout page.
|
// Trigger woocommerce validation if we are in the checkout page.
|
||||||
if (this.context === 'checkout') {
|
if (this.context === 'checkout') {
|
||||||
const checkoutFormSelector = 'form.woocommerce-checkout';
|
const checkoutFormSelector = 'form.woocommerce-checkout';
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import ErrorHandler from "../../../../ppcp-button/resources/js/modules/ErrorHandler";
|
import ErrorHandler from "../../../../ppcp-button/resources/js/modules/ErrorHandler";
|
||||||
import CartActionHandler
|
import CartActionHandler
|
||||||
from "../../../../ppcp-button/resources/js/modules/ActionHandler/CartActionHandler";
|
from "../../../../ppcp-button/resources/js/modules/ActionHandler/CartActionHandler";
|
||||||
|
import {isPayPalSubscription} from "../../../../ppcp-blocks/resources/js/Helper/Subscription";
|
||||||
|
|
||||||
class BaseHandler {
|
class BaseHandler {
|
||||||
|
|
||||||
|
@ -9,9 +10,15 @@ class BaseHandler {
|
||||||
this.ppcpConfig = ppcpConfig;
|
this.ppcpConfig = ppcpConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isVaultV3Mode() {
|
||||||
|
return this.ppcpConfig?.save_payment_methods?.id_token // vault v3
|
||||||
|
&& ! this.ppcpConfig?.data_client_id?.paypal_subscriptions_enabled // not PayPal Subscriptions mode
|
||||||
|
&& this.ppcpConfig?.can_save_vault_token; // vault is enabled
|
||||||
|
}
|
||||||
|
|
||||||
validateContext() {
|
validateContext() {
|
||||||
if ( this.ppcpConfig?.locations_with_subscription_product?.cart ) {
|
if ( this.ppcpConfig?.locations_with_subscription_product?.cart ) {
|
||||||
return false;
|
return this.isVaultV3Mode();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ class PayNowHandler extends BaseHandler {
|
||||||
|
|
||||||
validateContext() {
|
validateContext() {
|
||||||
if ( this.ppcpConfig?.locations_with_subscription_product?.payorder ) {
|
if ( this.ppcpConfig?.locations_with_subscription_product?.payorder ) {
|
||||||
return false;
|
return this.isVaultV3Mode();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ class SingleProductHandler extends BaseHandler {
|
||||||
|
|
||||||
validateContext() {
|
validateContext() {
|
||||||
if ( this.ppcpConfig?.locations_with_subscription_product?.product ) {
|
if ( this.ppcpConfig?.locations_with_subscription_product?.product ) {
|
||||||
return false;
|
return this.isVaultV3Mode();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
import {useEffect, useState} from '@wordpress/element';
|
import {useEffect, useState} from '@wordpress/element';
|
||||||
import {registerExpressPaymentMethod, registerPaymentMethod} from '@woocommerce/blocks-registry';
|
import {registerExpressPaymentMethod} from '@woocommerce/blocks-registry';
|
||||||
import {loadPaypalScript} from '../../../ppcp-button/resources/js/modules/Helper/ScriptLoading'
|
import {loadPaypalScript} from '../../../ppcp-button/resources/js/modules/Helper/ScriptLoading'
|
||||||
|
import {cartHasSubscriptionProducts} from '../../../ppcp-blocks/resources/js/Helper/Subscription'
|
||||||
import ApplepayManager from "./ApplepayManager";
|
import ApplepayManager from "./ApplepayManager";
|
||||||
import {loadCustomScript} from "@paypal/paypal-js";
|
import {loadCustomScript} from "@paypal/paypal-js";
|
||||||
|
import CheckoutHandler from "./Context/CheckoutHandler";
|
||||||
|
|
||||||
const ppcpData = wc.wcSettings.getSetting('ppcp-gateway_data');
|
const ppcpData = wc.wcSettings.getSetting('ppcp-gateway_data');
|
||||||
const ppcpConfig = ppcpData.scriptData;
|
const ppcpConfig = ppcpData.scriptData;
|
||||||
|
@ -50,6 +52,13 @@ const ApplePayComponent = () => {
|
||||||
|
|
||||||
const features = ['products'];
|
const features = ['products'];
|
||||||
|
|
||||||
|
if (
|
||||||
|
cartHasSubscriptionProducts(ppcpConfig)
|
||||||
|
&& (new CheckoutHandler(buttonConfig, ppcpConfig)).isVaultV3Mode()
|
||||||
|
) {
|
||||||
|
features.push('subscriptions');
|
||||||
|
}
|
||||||
|
|
||||||
registerExpressPaymentMethod({
|
registerExpressPaymentMethod({
|
||||||
name: buttonData.id,
|
name: buttonData.id,
|
||||||
label: <div dangerouslySetInnerHTML={{__html: buttonData.title}}/>,
|
label: <div dangerouslySetInnerHTML={{__html: buttonData.title}}/>,
|
||||||
|
|
|
@ -18,6 +18,7 @@ use WooCommerce\PayPalCommerce\Applepay\Assets\BlocksPaymentMethod;
|
||||||
use WooCommerce\PayPalCommerce\Applepay\Assets\PropertiesDictionary;
|
use WooCommerce\PayPalCommerce\Applepay\Assets\PropertiesDictionary;
|
||||||
use WooCommerce\PayPalCommerce\Applepay\Helper\ApmApplies;
|
use WooCommerce\PayPalCommerce\Applepay\Helper\ApmApplies;
|
||||||
use WooCommerce\PayPalCommerce\Applepay\Helper\AvailabilityNotice;
|
use WooCommerce\PayPalCommerce\Applepay\Helper\AvailabilityNotice;
|
||||||
|
use WooCommerce\PayPalCommerce\Common\Pattern\SingletonDecorator;
|
||||||
use WooCommerce\PayPalCommerce\Onboarding\Environment;
|
use WooCommerce\PayPalCommerce\Onboarding\Environment;
|
||||||
use WooCommerce\PayPalCommerce\Onboarding\State;
|
use WooCommerce\PayPalCommerce\Onboarding\State;
|
||||||
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
|
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
|
||||||
|
@ -72,14 +73,16 @@ return array(
|
||||||
return $settings->has( 'applepay_validated' ) ? $settings->get( 'applepay_validated' ) === true : false;
|
return $settings->has( 'applepay_validated' ) ? $settings->get( 'applepay_validated' ) === true : false;
|
||||||
},
|
},
|
||||||
|
|
||||||
'applepay.apple-product-status' => static function( ContainerInterface $container ): AppleProductStatus {
|
'applepay.apple-product-status' => SingletonDecorator::make(
|
||||||
return new AppleProductStatus(
|
static function( ContainerInterface $container ): AppleProductStatus {
|
||||||
$container->get( 'wcgateway.settings' ),
|
return new AppleProductStatus(
|
||||||
$container->get( 'api.endpoint.partners' ),
|
$container->get( 'wcgateway.settings' ),
|
||||||
$container->get( 'onboarding.state' ),
|
$container->get( 'api.endpoint.partners' ),
|
||||||
$container->get( 'api.helper.failure-registry' )
|
$container->get( 'onboarding.state' ),
|
||||||
);
|
$container->get( 'api.helper.failure-registry' )
|
||||||
},
|
);
|
||||||
|
}
|
||||||
|
),
|
||||||
'applepay.available' => static function ( ContainerInterface $container ): bool {
|
'applepay.available' => static function ( ContainerInterface $container ): bool {
|
||||||
if ( apply_filters( 'woocommerce_paypal_payments_applepay_validate_product_status', true ) ) {
|
if ( apply_filters( 'woocommerce_paypal_payments_applepay_validate_product_status', true ) ) {
|
||||||
$status = $container->get( 'applepay.apple-product-status' );
|
$status = $container->get( 'applepay.apple-product-status' );
|
||||||
|
@ -195,6 +198,30 @@ return array(
|
||||||
'TWD',
|
'TWD',
|
||||||
'USD',
|
'USD',
|
||||||
),
|
),
|
||||||
|
'AT' => array(
|
||||||
|
'AUD',
|
||||||
|
'BRL',
|
||||||
|
'CAD',
|
||||||
|
'CHF',
|
||||||
|
'CZK',
|
||||||
|
'DKK',
|
||||||
|
'EUR',
|
||||||
|
'GBP',
|
||||||
|
'HKD',
|
||||||
|
'HUF',
|
||||||
|
'ILS',
|
||||||
|
'JPY',
|
||||||
|
'MXN',
|
||||||
|
'NOK',
|
||||||
|
'NZD',
|
||||||
|
'PHP',
|
||||||
|
'PLN',
|
||||||
|
'SEK',
|
||||||
|
'SGD',
|
||||||
|
'THB',
|
||||||
|
'TWD',
|
||||||
|
'USD',
|
||||||
|
),
|
||||||
'BE' => array(
|
'BE' => array(
|
||||||
'AUD',
|
'AUD',
|
||||||
'BRL',
|
'BRL',
|
||||||
|
@ -483,6 +510,30 @@ return array(
|
||||||
'TWD',
|
'TWD',
|
||||||
'USD',
|
'USD',
|
||||||
),
|
),
|
||||||
|
'IE' => array(
|
||||||
|
'AUD',
|
||||||
|
'BRL',
|
||||||
|
'CAD',
|
||||||
|
'CHF',
|
||||||
|
'CZK',
|
||||||
|
'DKK',
|
||||||
|
'EUR',
|
||||||
|
'GBP',
|
||||||
|
'HKD',
|
||||||
|
'HUF',
|
||||||
|
'ILS',
|
||||||
|
'JPY',
|
||||||
|
'MXN',
|
||||||
|
'NOK',
|
||||||
|
'NZD',
|
||||||
|
'PHP',
|
||||||
|
'PLN',
|
||||||
|
'SEK',
|
||||||
|
'SGD',
|
||||||
|
'THB',
|
||||||
|
'TWD',
|
||||||
|
'USD',
|
||||||
|
),
|
||||||
'IT' => array(
|
'IT' => array(
|
||||||
'AUD',
|
'AUD',
|
||||||
'BRL',
|
'BRL',
|
||||||
|
@ -531,6 +582,30 @@ return array(
|
||||||
'TWD',
|
'TWD',
|
||||||
'USD',
|
'USD',
|
||||||
),
|
),
|
||||||
|
'LI' => array(
|
||||||
|
'AUD',
|
||||||
|
'BRL',
|
||||||
|
'CAD',
|
||||||
|
'CHF',
|
||||||
|
'CZK',
|
||||||
|
'DKK',
|
||||||
|
'EUR',
|
||||||
|
'GBP',
|
||||||
|
'HKD',
|
||||||
|
'HUF',
|
||||||
|
'ILS',
|
||||||
|
'JPY',
|
||||||
|
'MXN',
|
||||||
|
'NOK',
|
||||||
|
'NZD',
|
||||||
|
'PHP',
|
||||||
|
'PLN',
|
||||||
|
'SEK',
|
||||||
|
'SGD',
|
||||||
|
'THB',
|
||||||
|
'TWD',
|
||||||
|
'USD',
|
||||||
|
),
|
||||||
'LT' => array(
|
'LT' => array(
|
||||||
'AUD',
|
'AUD',
|
||||||
'BRL',
|
'BRL',
|
||||||
|
@ -603,6 +678,30 @@ return array(
|
||||||
'TWD',
|
'TWD',
|
||||||
'USD',
|
'USD',
|
||||||
),
|
),
|
||||||
|
'NO' => array(
|
||||||
|
'AUD',
|
||||||
|
'BRL',
|
||||||
|
'CAD',
|
||||||
|
'CHF',
|
||||||
|
'CZK',
|
||||||
|
'DKK',
|
||||||
|
'EUR',
|
||||||
|
'GBP',
|
||||||
|
'HKD',
|
||||||
|
'HUF',
|
||||||
|
'ILS',
|
||||||
|
'JPY',
|
||||||
|
'MXN',
|
||||||
|
'NOK',
|
||||||
|
'NZD',
|
||||||
|
'PHP',
|
||||||
|
'PLN',
|
||||||
|
'SEK',
|
||||||
|
'SGD',
|
||||||
|
'THB',
|
||||||
|
'TWD',
|
||||||
|
'USD',
|
||||||
|
),
|
||||||
'NL' => array(
|
'NL' => array(
|
||||||
'AUD',
|
'AUD',
|
||||||
'BRL',
|
'BRL',
|
||||||
|
|
|
@ -11,6 +11,7 @@ namespace WooCommerce\PayPalCommerce\Applepay\Assets;
|
||||||
|
|
||||||
use Throwable;
|
use Throwable;
|
||||||
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PartnersEndpoint;
|
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PartnersEndpoint;
|
||||||
|
use WooCommerce\PayPalCommerce\ApiClient\Entity\SellerStatusCapability;
|
||||||
use WooCommerce\PayPalCommerce\ApiClient\Helper\FailureRegistry;
|
use WooCommerce\PayPalCommerce\ApiClient\Helper\FailureRegistry;
|
||||||
use WooCommerce\PayPalCommerce\Onboarding\State;
|
use WooCommerce\PayPalCommerce\Onboarding\State;
|
||||||
use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
|
use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
|
||||||
|
@ -100,6 +101,11 @@ class AppleProductStatus {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$status_override = apply_filters( 'woocommerce_paypal_payments_apple_pay_product_status', null );
|
||||||
|
if ( null !== $status_override ) {
|
||||||
|
return $status_override;
|
||||||
|
}
|
||||||
|
|
||||||
// If status was already checked on this request return the same result.
|
// If status was already checked on this request return the same result.
|
||||||
if ( null !== $this->current_status ) {
|
if ( null !== $this->current_status ) {
|
||||||
return $this->current_status;
|
return $this->current_status;
|
||||||
|
@ -128,21 +134,32 @@ class AppleProductStatus {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check the seller status for the intended capability.
|
// Check the seller status for the intended capability.
|
||||||
|
$has_capability = false;
|
||||||
foreach ( $seller_status->products() as $product ) {
|
foreach ( $seller_status->products() as $product ) {
|
||||||
if ( $product->name() !== 'PAYMENT_METHODS' ) {
|
if ( $product->name() !== 'PAYMENT_METHODS' ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( in_array( self::CAPABILITY_NAME, $product->capabilities(), true ) ) {
|
if ( in_array( self::CAPABILITY_NAME, $product->capabilities(), true ) ) {
|
||||||
// Capability found, persist status and return true.
|
$has_capability = true;
|
||||||
$this->settings->set( self::SETTINGS_KEY, self::SETTINGS_VALUE_ENABLED );
|
|
||||||
$this->settings->persist();
|
|
||||||
|
|
||||||
$this->current_status = true;
|
|
||||||
return $this->current_status;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach ( $seller_status->capabilities() as $capability ) {
|
||||||
|
if ( $capability->name() === self::CAPABILITY_NAME && $capability->status() === SellerStatusCapability::STATUS_ACTIVE ) {
|
||||||
|
$has_capability = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $has_capability ) {
|
||||||
|
// Capability found, persist status and return true.
|
||||||
|
$this->settings->set( self::SETTINGS_KEY, self::SETTINGS_VALUE_ENABLED );
|
||||||
|
$this->settings->persist();
|
||||||
|
|
||||||
|
$this->current_status = true;
|
||||||
|
return $this->current_status;
|
||||||
|
}
|
||||||
|
|
||||||
// Capability not found, persist status and return false.
|
// Capability not found, persist status and return false.
|
||||||
$this->settings->set( self::SETTINGS_KEY, self::SETTINGS_VALUE_DISABLED );
|
$this->settings->set( self::SETTINGS_KEY, self::SETTINGS_VALUE_DISABLED );
|
||||||
$this->settings->persist();
|
$this->settings->persist();
|
||||||
|
|
22
modules/ppcp-blocks/resources/js/Helper/Helper.js
Normal file
22
modules/ppcp-blocks/resources/js/Helper/Helper.js
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
/**
|
||||||
|
* @param str
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
export const toSnakeCase = (str) => {
|
||||||
|
return str.replace(/[\w]([A-Z])/g, function(m) {
|
||||||
|
return m[0] + "_" + m[1];
|
||||||
|
}).toLowerCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param obj
|
||||||
|
* @returns {{}}
|
||||||
|
*/
|
||||||
|
export const convertKeysToSnakeCase = (obj) => {
|
||||||
|
const newObj = {};
|
||||||
|
Object.keys(obj).forEach((key) => {
|
||||||
|
const newKey = toSnakeCase(key);
|
||||||
|
newObj[newKey] = obj[key];
|
||||||
|
});
|
||||||
|
return newObj;
|
||||||
|
}
|
|
@ -6,6 +6,9 @@ import {
|
||||||
paypalOrderToWcAddresses,
|
paypalOrderToWcAddresses,
|
||||||
paypalSubscriptionToWcAddresses
|
paypalSubscriptionToWcAddresses
|
||||||
} from "./Helper/Address";
|
} from "./Helper/Address";
|
||||||
|
import {
|
||||||
|
convertKeysToSnakeCase
|
||||||
|
} from "./Helper/Helper";
|
||||||
import {
|
import {
|
||||||
cartHasSubscriptionProducts,
|
cartHasSubscriptionProducts,
|
||||||
isPayPalSubscription
|
isPayPalSubscription
|
||||||
|
@ -18,6 +21,7 @@ import {
|
||||||
} from '../../../ppcp-button/resources/js/modules/Helper/Style'
|
} from '../../../ppcp-button/resources/js/modules/Helper/Style'
|
||||||
import buttonModuleWatcher from "../../../ppcp-button/resources/js/modules/ButtonModuleWatcher";
|
import buttonModuleWatcher from "../../../ppcp-button/resources/js/modules/ButtonModuleWatcher";
|
||||||
import BlockCheckoutMessagesBootstrap from "./Bootstrap/BlockCheckoutMessagesBootstrap";
|
import BlockCheckoutMessagesBootstrap from "./Bootstrap/BlockCheckoutMessagesBootstrap";
|
||||||
|
import {keysToCamelCase} from "../../../ppcp-button/resources/js/modules/Helper/Utils";
|
||||||
const config = wc.wcSettings.getSetting('ppcp-gateway_data');
|
const config = wc.wcSettings.getSetting('ppcp-gateway_data');
|
||||||
|
|
||||||
window.ppcpFundingSource = config.fundingSource;
|
window.ppcpFundingSource = config.fundingSource;
|
||||||
|
@ -87,6 +91,7 @@ const PayPalComponent = ({
|
||||||
bn_code: '',
|
bn_code: '',
|
||||||
context: config.scriptData.context,
|
context: config.scriptData.context,
|
||||||
payment_method: 'ppcp-gateway',
|
payment_method: 'ppcp-gateway',
|
||||||
|
funding_source: window.ppcpFundingSource ?? 'paypal',
|
||||||
createaccount: false
|
createaccount: false
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
@ -285,17 +290,43 @@ const PayPalComponent = ({
|
||||||
onClick();
|
onClick();
|
||||||
};
|
};
|
||||||
|
|
||||||
let handleShippingChange = null;
|
let handleShippingOptionsChange = null;
|
||||||
let handleSubscriptionShippingChange = null;
|
let handleShippingAddressChange = null;
|
||||||
|
let handleSubscriptionShippingOptionsChange = null;
|
||||||
|
let handleSubscriptionShippingAddressChange = null;
|
||||||
if (shippingData.needsShipping && !config.finalReviewEnabled) {
|
if (shippingData.needsShipping && !config.finalReviewEnabled) {
|
||||||
handleShippingChange = async (data, actions) => {
|
handleShippingOptionsChange = async (data, actions) => {
|
||||||
try {
|
try {
|
||||||
const shippingOptionId = data.selected_shipping_option?.id;
|
const shippingOptionId = data.selectedShippingOption?.id;
|
||||||
if (shippingOptionId) {
|
if (shippingOptionId) {
|
||||||
|
await wp.data.dispatch('wc/store/cart').selectShippingRate(shippingOptionId);
|
||||||
await shippingData.setSelectedRates(shippingOptionId);
|
await shippingData.setSelectedRates(shippingOptionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
const address = paypalAddressToWc(data.shipping_address);
|
const res = await fetch(config.ajax.update_shipping.endpoint, {
|
||||||
|
method: 'POST',
|
||||||
|
credentials: 'same-origin',
|
||||||
|
body: JSON.stringify({
|
||||||
|
nonce: config.ajax.update_shipping.nonce,
|
||||||
|
order_id: data.orderID,
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
const json = await res.json();
|
||||||
|
|
||||||
|
if (!json.success) {
|
||||||
|
throw new Error(json.data.message);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
|
||||||
|
actions.reject();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
handleShippingAddressChange = async (data, actions) => {
|
||||||
|
try {
|
||||||
|
const address = paypalAddressToWc(convertKeysToSnakeCase(data.shippingAddress));
|
||||||
|
|
||||||
await wp.data.dispatch('wc/store/cart').updateCustomerData({
|
await wp.data.dispatch('wc/store/cart').updateCustomerData({
|
||||||
shipping_address: address,
|
shipping_address: address,
|
||||||
|
@ -324,16 +355,23 @@ const PayPalComponent = ({
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
handleSubscriptionShippingChange = async (data, actions) => {
|
handleSubscriptionShippingOptionsChange = async (data, actions) => {
|
||||||
console.log('--- handleSubscriptionShippingChange', data, actions);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const shippingOptionId = data.selected_shipping_option?.id;
|
const shippingOptionId = data.selectedShippingOption?.id;
|
||||||
if (shippingOptionId) {
|
if (shippingOptionId) {
|
||||||
|
await wp.data.dispatch('wc/store/cart').selectShippingRate(shippingOptionId);
|
||||||
await shippingData.setSelectedRates(shippingOptionId);
|
await shippingData.setSelectedRates(shippingOptionId);
|
||||||
}
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
|
||||||
const address = paypalAddressToWc(data.shipping_address);
|
actions.reject();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
handleSubscriptionShippingAddressChange = async (data, actions) => {
|
||||||
|
try {
|
||||||
|
const address = paypalAddressToWc(convertKeysToSnakeCase(data.shippingAddress));
|
||||||
|
|
||||||
await wp.data.dispatch('wc/store/cart').updateCustomerData({
|
await wp.data.dispatch('wc/store/cart').updateCustomerData({
|
||||||
shipping_address: address,
|
shipping_address: address,
|
||||||
|
@ -443,7 +481,8 @@ const PayPalComponent = ({
|
||||||
onError={onClose}
|
onError={onClose}
|
||||||
createSubscription={createSubscription}
|
createSubscription={createSubscription}
|
||||||
onApprove={handleApproveSubscription}
|
onApprove={handleApproveSubscription}
|
||||||
onShippingChange={handleSubscriptionShippingChange}
|
onShippingOptionsChange={handleSubscriptionShippingOptionsChange}
|
||||||
|
onShippingAddressChange={handleSubscriptionShippingAddressChange}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -457,7 +496,8 @@ const PayPalComponent = ({
|
||||||
onError={onClose}
|
onError={onClose}
|
||||||
createOrder={createOrder}
|
createOrder={createOrder}
|
||||||
onApprove={handleApprove}
|
onApprove={handleApprove}
|
||||||
onShippingChange={handleShippingChange}
|
onShippingOptionsChange={handleShippingOptionsChange}
|
||||||
|
onShippingAddressChange={handleShippingAddressChange}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -476,6 +516,14 @@ if(cartHasSubscriptionProducts(config.scriptData)) {
|
||||||
block_enabled = false;
|
block_enabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Don't render if vaulting disabled and is in vault subscription mode
|
||||||
|
if(
|
||||||
|
! isPayPalSubscription(config.scriptData)
|
||||||
|
&& ! config.scriptData.can_save_vault_token
|
||||||
|
) {
|
||||||
|
block_enabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
// Don't render buttons if in subscription mode and product not associated with a PayPal subscription
|
// Don't render buttons if in subscription mode and product not associated with a PayPal subscription
|
||||||
if(
|
if(
|
||||||
isPayPalSubscription(config.scriptData)
|
isPayPalSubscription(config.scriptData)
|
||||||
|
|
|
@ -11,6 +11,7 @@ namespace WooCommerce\PayPalCommerce\Blocks;
|
||||||
|
|
||||||
use WooCommerce\PayPalCommerce\Blocks\Endpoint\UpdateShippingEndpoint;
|
use WooCommerce\PayPalCommerce\Blocks\Endpoint\UpdateShippingEndpoint;
|
||||||
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
|
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
|
||||||
|
use WooCommerce\PayPalCommerce\Button\Assets\SmartButtonInterface;
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
'blocks.url' => static function ( ContainerInterface $container ): string {
|
'blocks.url' => static function ( ContainerInterface $container ): string {
|
||||||
|
@ -28,7 +29,9 @@ return array(
|
||||||
return new PayPalPaymentMethod(
|
return new PayPalPaymentMethod(
|
||||||
$container->get( 'blocks.url' ),
|
$container->get( 'blocks.url' ),
|
||||||
$container->get( 'ppcp.asset-version' ),
|
$container->get( 'ppcp.asset-version' ),
|
||||||
$container->get( 'button.smart-button' ),
|
function () use ( $container ): SmartButtonInterface {
|
||||||
|
return $container->get( 'button.smart-button' );
|
||||||
|
},
|
||||||
$container->get( 'wcgateway.settings' ),
|
$container->get( 'wcgateway.settings' ),
|
||||||
$container->get( 'wcgateway.settings.status' ),
|
$container->get( 'wcgateway.settings.status' ),
|
||||||
$container->get( 'wcgateway.paypal-gateway' ),
|
$container->get( 'wcgateway.paypal-gateway' ),
|
||||||
|
|
|
@ -41,7 +41,7 @@ class PayPalPaymentMethod extends AbstractPaymentMethodType {
|
||||||
/**
|
/**
|
||||||
* The smart button script loading handler.
|
* The smart button script loading handler.
|
||||||
*
|
*
|
||||||
* @var SmartButtonInterface
|
* @var SmartButtonInterface|callable
|
||||||
*/
|
*/
|
||||||
private $smart_button;
|
private $smart_button;
|
||||||
|
|
||||||
|
@ -125,25 +125,25 @@ class PayPalPaymentMethod extends AbstractPaymentMethodType {
|
||||||
/**
|
/**
|
||||||
* Assets constructor.
|
* Assets constructor.
|
||||||
*
|
*
|
||||||
* @param string $module_url The url of this module.
|
* @param string $module_url The url of this module.
|
||||||
* @param string $version The assets version.
|
* @param string $version The assets version.
|
||||||
* @param SmartButtonInterface $smart_button The smart button script loading handler.
|
* @param SmartButtonInterface|callable $smart_button The smart button script loading handler.
|
||||||
* @param Settings $plugin_settings The settings.
|
* @param Settings $plugin_settings The settings.
|
||||||
* @param SettingsStatus $settings_status The Settings status helper.
|
* @param SettingsStatus $settings_status The Settings status helper.
|
||||||
* @param PayPalGateway $gateway The WC gateway.
|
* @param PayPalGateway $gateway The WC gateway.
|
||||||
* @param bool $final_review_enabled Whether the final review is enabled.
|
* @param bool $final_review_enabled Whether the final review is enabled.
|
||||||
* @param CancelView $cancellation_view The cancellation view.
|
* @param CancelView $cancellation_view The cancellation view.
|
||||||
* @param SessionHandler $session_handler The Session handler.
|
* @param SessionHandler $session_handler The Session handler.
|
||||||
* @param bool $add_place_order_method Whether to create a non-express method with the standard "Place order" button.
|
* @param bool $add_place_order_method Whether to create a non-express method with the standard "Place order" button.
|
||||||
* @param bool $use_place_order Whether to use the standard "Place order" button instead of PayPal buttons.
|
* @param bool $use_place_order Whether to use the standard "Place order" button instead of PayPal buttons.
|
||||||
* @param string $place_order_button_text The text for the standard "Place order" button.
|
* @param string $place_order_button_text The text for the standard "Place order" button.
|
||||||
* @param string $place_order_button_description The text for additional "Place order" description.
|
* @param string $place_order_button_description The text for additional "Place order" description.
|
||||||
* @param array $all_funding_sources All existing funding sources for PayPal buttons.
|
* @param array $all_funding_sources All existing funding sources for PayPal buttons.
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
string $module_url,
|
string $module_url,
|
||||||
string $version,
|
string $version,
|
||||||
SmartButtonInterface $smart_button,
|
$smart_button,
|
||||||
Settings $plugin_settings,
|
Settings $plugin_settings,
|
||||||
SettingsStatus $settings_status,
|
SettingsStatus $settings_status,
|
||||||
PayPalGateway $gateway,
|
PayPalGateway $gateway,
|
||||||
|
@ -209,7 +209,7 @@ class PayPalPaymentMethod extends AbstractPaymentMethodType {
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
public function get_payment_method_data() {
|
public function get_payment_method_data() {
|
||||||
$script_data = $this->smart_button->script_data();
|
$script_data = $this->smart_button()->script_data();
|
||||||
|
|
||||||
if ( isset( $script_data['continuation'] ) ) {
|
if ( isset( $script_data['continuation'] ) ) {
|
||||||
$url = add_query_arg( array( CancelController::NONCE => wp_create_nonce( CancelController::NONCE ) ), wc_get_checkout_url() );
|
$url = add_query_arg( array( CancelController::NONCE => wp_create_nonce( CancelController::NONCE ) ), wc_get_checkout_url() );
|
||||||
|
@ -267,4 +267,21 @@ class PayPalPaymentMethod extends AbstractPaymentMethodType {
|
||||||
$screen = get_current_screen();
|
$screen = get_current_screen();
|
||||||
return $screen && $screen->is_block_editor();
|
return $screen && $screen->is_block_editor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The smart button.
|
||||||
|
*
|
||||||
|
* @return SmartButtonInterface
|
||||||
|
*/
|
||||||
|
private function smart_button(): 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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -137,7 +137,12 @@ const bootstrap = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const isFreeTrial = PayPalCommerceGateway.is_free_trial_cart;
|
const isFreeTrial = PayPalCommerceGateway.is_free_trial_cart;
|
||||||
if (isFreeTrial && data.fundingSource !== 'card' && ! PayPalCommerceGateway.subscription_plan_id) {
|
if (
|
||||||
|
isFreeTrial
|
||||||
|
&& data.fundingSource !== 'card'
|
||||||
|
&& ! PayPalCommerceGateway.subscription_plan_id
|
||||||
|
&& ! PayPalCommerceGateway.vault_v3_enabled
|
||||||
|
) {
|
||||||
freeTrialHandler.handle();
|
freeTrialHandler.handle();
|
||||||
return actions.reject();
|
return actions.reject();
|
||||||
}
|
}
|
||||||
|
@ -241,7 +246,6 @@ document.addEventListener(
|
||||||
if (!typeof (PayPalCommerceGateway)) {
|
if (!typeof (PayPalCommerceGateway)) {
|
||||||
console.error('PayPal button could not be configured.');
|
console.error('PayPal button could not be configured.');
|
||||||
return;
|
return;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
|
|
@ -144,6 +144,54 @@ class CheckoutActionHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addPaymentMethodConfiguration() {
|
||||||
|
return {
|
||||||
|
createVaultSetupToken: async () => {
|
||||||
|
const response = await fetch(this.config.ajax.create_setup_token.endpoint, {
|
||||||
|
method: "POST",
|
||||||
|
credentials: 'same-origin',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
nonce: this.config.ajax.create_setup_token.nonce,
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await response.json()
|
||||||
|
if (result.data.id) {
|
||||||
|
return result.data.id
|
||||||
|
}
|
||||||
|
|
||||||
|
console.error(result)
|
||||||
|
},
|
||||||
|
onApprove: async ({vaultSetupToken}) => {
|
||||||
|
const response = await fetch(this.config.ajax.create_payment_token_for_guest.endpoint, {
|
||||||
|
method: "POST",
|
||||||
|
credentials: 'same-origin',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
nonce: this.config.ajax.create_payment_token_for_guest.nonce,
|
||||||
|
vault_setup_token: vaultSetupToken,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
const result = await response.json();
|
||||||
|
if (result.success === true) {
|
||||||
|
document.querySelector('#place_order').click()
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.error(result)
|
||||||
|
},
|
||||||
|
onError: (error) => {
|
||||||
|
console.error(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default CheckoutActionHandler;
|
export default CheckoutActionHandler;
|
||||||
|
|
|
@ -7,7 +7,6 @@ class ButtonModuleWatcher {
|
||||||
}
|
}
|
||||||
|
|
||||||
watchContextBootstrap(callable) {
|
watchContextBootstrap(callable) {
|
||||||
console.log('ButtonModuleWatcher.js: watchContextBootstrap', this.contextBootstrapRegistry)
|
|
||||||
this.contextBootstrapWatchers.push(callable);
|
this.contextBootstrapWatchers.push(callable);
|
||||||
Object.values(this.contextBootstrapRegistry).forEach(callable);
|
Object.values(this.contextBootstrapRegistry).forEach(callable);
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,6 +116,14 @@ class CheckoutBootstap {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(
|
||||||
|
PayPalCommerceGateway.is_free_trial_cart
|
||||||
|
&& PayPalCommerceGateway.vault_v3_enabled
|
||||||
|
) {
|
||||||
|
this.renderer.render(actionHandler.addPaymentMethodConfiguration(), {}, actionHandler.configuration());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.renderer.render(actionHandler.configuration(), {}, actionHandler.configuration());
|
this.renderer.render(actionHandler.configuration(), {}, actionHandler.configuration());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -127,19 +127,7 @@ class CardFieldsRenderer {
|
||||||
|
|
||||||
const paymentToken = document.querySelector('input[name="wc-ppcp-credit-card-gateway-payment-token"]:checked')?.value
|
const paymentToken = document.querySelector('input[name="wc-ppcp-credit-card-gateway-payment-token"]:checked')?.value
|
||||||
if(paymentToken && paymentToken !== 'new') {
|
if(paymentToken && paymentToken !== 'new') {
|
||||||
fetch(this.defaultConfig.ajax.capture_card_payment.endpoint, {
|
document.querySelector('#place_order').click();
|
||||||
method: 'POST',
|
|
||||||
credentials: 'same-origin',
|
|
||||||
body: JSON.stringify({
|
|
||||||
nonce: this.defaultConfig.ajax.capture_card_payment.nonce,
|
|
||||||
payment_token: paymentToken
|
|
||||||
})
|
|
||||||
}).then((res) => {
|
|
||||||
return res.json();
|
|
||||||
}).then((data) => {
|
|
||||||
document.querySelector('#place_order').click();
|
|
||||||
});
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -145,6 +145,8 @@ return array(
|
||||||
$container->get( 'button.early-wc-checkout-validation-enabled' ),
|
$container->get( 'button.early-wc-checkout-validation-enabled' ),
|
||||||
$container->get( 'button.pay-now-contexts' ),
|
$container->get( 'button.pay-now-contexts' ),
|
||||||
$container->get( 'wcgateway.funding-sources-without-redirect' ),
|
$container->get( 'wcgateway.funding-sources-without-redirect' ),
|
||||||
|
$container->get( 'vaulting.vault-v3-enabled' ),
|
||||||
|
$container->get( 'api.endpoint.payment-tokens' ),
|
||||||
$container->get( 'woocommerce.logger.woocommerce' )
|
$container->get( 'woocommerce.logger.woocommerce' )
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
|
@ -14,6 +14,7 @@ use Psr\Log\LoggerInterface;
|
||||||
use WC_Order;
|
use WC_Order;
|
||||||
use WC_Product;
|
use WC_Product;
|
||||||
use WC_Product_Variation;
|
use WC_Product_Variation;
|
||||||
|
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentTokensEndpoint;
|
||||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Money;
|
use WooCommerce\PayPalCommerce\ApiClient\Entity\Money;
|
||||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentToken;
|
use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentToken;
|
||||||
use WooCommerce\PayPalCommerce\ApiClient\Factory\PayerFactory;
|
use WooCommerce\PayPalCommerce\ApiClient\Factory\PayerFactory;
|
||||||
|
@ -33,6 +34,9 @@ use WooCommerce\PayPalCommerce\Button\Helper\ContextTrait;
|
||||||
use WooCommerce\PayPalCommerce\Button\Helper\MessagesApply;
|
use WooCommerce\PayPalCommerce\Button\Helper\MessagesApply;
|
||||||
use WooCommerce\PayPalCommerce\Onboarding\Environment;
|
use WooCommerce\PayPalCommerce\Onboarding\Environment;
|
||||||
use WooCommerce\PayPalCommerce\PayLaterBlock\PayLaterBlockModule;
|
use WooCommerce\PayPalCommerce\PayLaterBlock\PayLaterBlockModule;
|
||||||
|
use WooCommerce\PayPalCommerce\SavePaymentMethods\Endpoint\CreatePaymentToken;
|
||||||
|
use WooCommerce\PayPalCommerce\SavePaymentMethods\Endpoint\CreateSetupToken;
|
||||||
|
use WooCommerce\PayPalCommerce\SavePaymentMethods\Endpoint\CreatePaymentTokenForGuest;
|
||||||
use WooCommerce\PayPalCommerce\Session\SessionHandler;
|
use WooCommerce\PayPalCommerce\Session\SessionHandler;
|
||||||
use WooCommerce\PayPalCommerce\WcSubscriptions\FreeTrialHandlerTrait;
|
use WooCommerce\PayPalCommerce\WcSubscriptions\FreeTrialHandlerTrait;
|
||||||
use WooCommerce\PayPalCommerce\WcSubscriptions\Helper\SubscriptionHelper;
|
use WooCommerce\PayPalCommerce\WcSubscriptions\Helper\SubscriptionHelper;
|
||||||
|
@ -184,13 +188,6 @@ class SmartButton implements SmartButtonInterface {
|
||||||
*/
|
*/
|
||||||
private $funding_sources_without_redirect;
|
private $funding_sources_without_redirect;
|
||||||
|
|
||||||
/**
|
|
||||||
* The logger.
|
|
||||||
*
|
|
||||||
* @var LoggerInterface
|
|
||||||
*/
|
|
||||||
private $logger;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Session handler.
|
* Session handler.
|
||||||
*
|
*
|
||||||
|
@ -198,6 +195,27 @@ class SmartButton implements SmartButtonInterface {
|
||||||
*/
|
*/
|
||||||
private $session_handler;
|
private $session_handler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether Vault v3 module is enabled.
|
||||||
|
*
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
private $vault_v3_enabled;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Payment tokens endpoint.
|
||||||
|
*
|
||||||
|
* @var PaymentTokensEndpoint
|
||||||
|
*/
|
||||||
|
private $payment_tokens_endpoint;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The logger.
|
||||||
|
*
|
||||||
|
* @var LoggerInterface
|
||||||
|
*/
|
||||||
|
private $logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SmartButton constructor.
|
* SmartButton constructor.
|
||||||
*
|
*
|
||||||
|
@ -220,6 +238,8 @@ class SmartButton implements SmartButtonInterface {
|
||||||
* @param bool $early_validation_enabled Whether to execute WC validation of the checkout form.
|
* @param bool $early_validation_enabled Whether to execute WC validation of the checkout form.
|
||||||
* @param array $pay_now_contexts The contexts that should have the Pay Now button.
|
* @param array $pay_now_contexts The contexts that should have the Pay Now button.
|
||||||
* @param string[] $funding_sources_without_redirect The sources that do not cause issues about redirecting (on mobile, ...) and sometimes not returning back.
|
* @param string[] $funding_sources_without_redirect The sources that do not cause issues about redirecting (on mobile, ...) and sometimes not returning back.
|
||||||
|
* @param bool $vault_v3_enabled Whether Vault v3 module is enabled.
|
||||||
|
* @param PaymentTokensEndpoint $payment_tokens_endpoint Payment tokens endpoint.
|
||||||
* @param LoggerInterface $logger The logger.
|
* @param LoggerInterface $logger The logger.
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
|
@ -242,6 +262,8 @@ class SmartButton implements SmartButtonInterface {
|
||||||
bool $early_validation_enabled,
|
bool $early_validation_enabled,
|
||||||
array $pay_now_contexts,
|
array $pay_now_contexts,
|
||||||
array $funding_sources_without_redirect,
|
array $funding_sources_without_redirect,
|
||||||
|
bool $vault_v3_enabled,
|
||||||
|
PaymentTokensEndpoint $payment_tokens_endpoint,
|
||||||
LoggerInterface $logger
|
LoggerInterface $logger
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
@ -264,7 +286,9 @@ class SmartButton implements SmartButtonInterface {
|
||||||
$this->early_validation_enabled = $early_validation_enabled;
|
$this->early_validation_enabled = $early_validation_enabled;
|
||||||
$this->pay_now_contexts = $pay_now_contexts;
|
$this->pay_now_contexts = $pay_now_contexts;
|
||||||
$this->funding_sources_without_redirect = $funding_sources_without_redirect;
|
$this->funding_sources_without_redirect = $funding_sources_without_redirect;
|
||||||
|
$this->vault_v3_enabled = $vault_v3_enabled;
|
||||||
$this->logger = $logger;
|
$this->logger = $logger;
|
||||||
|
$this->payment_tokens_endpoint = $payment_tokens_endpoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -631,7 +655,7 @@ document.querySelector("#payment").before(document.querySelector("#ppcp-messages
|
||||||
|
|
||||||
$messaging_enabled_for_current_location = $this->settings_status->is_pay_later_messaging_enabled_for_location( $location );
|
$messaging_enabled_for_current_location = $this->settings_status->is_pay_later_messaging_enabled_for_location( $location );
|
||||||
|
|
||||||
$has_paylater_block = has_block( 'woocommerce-paypal-payments/paylater-messages' ) && PayLaterBlockModule::is_enabled();
|
$has_paylater_block = has_block( 'woocommerce-paypal-payments/paylater-messages' ) && PayLaterBlockModule::is_block_enabled( $this->settings_status );
|
||||||
|
|
||||||
switch ( $location ) {
|
switch ( $location ) {
|
||||||
case 'checkout':
|
case 'checkout':
|
||||||
|
@ -872,12 +896,13 @@ document.querySelector("#payment").before(document.querySelector("#ppcp-messages
|
||||||
$text_color = $this->settings->has( "{$setting_name_prefix}_color" ) ? $this->settings->get( "{$setting_name_prefix}_color" ) : 'black';
|
$text_color = $this->settings->has( "{$setting_name_prefix}_color" ) ? $this->settings->get( "{$setting_name_prefix}_color" ) : 'black';
|
||||||
$style_color = $this->settings->has( "{$setting_name_prefix}_flex_color" ) ? $this->settings->get( "{$setting_name_prefix}_flex_color" ) : 'blue';
|
$style_color = $this->settings->has( "{$setting_name_prefix}_flex_color" ) ? $this->settings->get( "{$setting_name_prefix}_flex_color" ) : 'blue';
|
||||||
$ratio = $this->settings->has( "{$setting_name_prefix}_flex_ratio" ) ? $this->settings->get( "{$setting_name_prefix}_flex_ratio" ) : '1x1';
|
$ratio = $this->settings->has( "{$setting_name_prefix}_flex_ratio" ) ? $this->settings->get( "{$setting_name_prefix}_flex_ratio" ) : '1x1';
|
||||||
|
$text_size = $this->settings->has( "{$setting_name_prefix}_text_size" ) ? $this->settings->get( "{$setting_name_prefix}_text_size" ) : '12';
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
'wrapper' => '#ppcp-messages',
|
'wrapper' => '#ppcp-messages',
|
||||||
'is_hidden' => ! $this->is_pay_later_filter_enabled_for_location( $this->context() ),
|
'is_hidden' => ! $this->is_pay_later_filter_enabled_for_location( $this->context() ),
|
||||||
'block' => array(
|
'block' => array(
|
||||||
'enabled' => PayLaterBlockModule::is_enabled(),
|
'enabled' => PayLaterBlockModule::is_block_enabled( $this->settings_status ),
|
||||||
),
|
),
|
||||||
'amount' => $amount,
|
'amount' => $amount,
|
||||||
'placement' => $placement,
|
'placement' => $placement,
|
||||||
|
@ -889,6 +914,7 @@ document.querySelector("#payment").before(document.querySelector("#ppcp-messages
|
||||||
),
|
),
|
||||||
'text' => array(
|
'text' => array(
|
||||||
'color' => $text_color,
|
'color' => $text_color,
|
||||||
|
'size' => $text_size,
|
||||||
),
|
),
|
||||||
'color' => $style_color,
|
'color' => $style_color,
|
||||||
'ratio' => $ratio,
|
'ratio' => $ratio,
|
||||||
|
@ -948,7 +974,10 @@ document.querySelector("#payment").before(document.querySelector("#ppcp-messages
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
private function has_subscriptions(): bool {
|
private function has_subscriptions(): bool {
|
||||||
if ( ! $this->subscription_helper->accept_only_automatic_payment_gateways() ) {
|
if (
|
||||||
|
! $this->subscription_helper->accept_only_automatic_payment_gateways()
|
||||||
|
&& $this->paypal_subscriptions_enabled() !== true
|
||||||
|
) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if ( is_product() ) {
|
if ( is_product() ) {
|
||||||
|
@ -985,11 +1014,21 @@ document.querySelector("#payment").before(document.querySelector("#ppcp-messages
|
||||||
if ( $this->settings->has( '3d_secure_contingency' ) ) {
|
if ( $this->settings->has( '3d_secure_contingency' ) ) {
|
||||||
$value = $this->settings->get( '3d_secure_contingency' );
|
$value = $this->settings->get( '3d_secure_contingency' );
|
||||||
if ( $value ) {
|
if ( $value ) {
|
||||||
return $value;
|
return $this->return_3ds_contingency( $value );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 'SCA_WHEN_REQUIRED';
|
return $this->return_3ds_contingency( 'SCA_WHEN_REQUIRED' );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Processes and returns the 3D Secure contingency.
|
||||||
|
*
|
||||||
|
* @param string $contingency The ThreeD secure contingency.
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private function return_3ds_contingency( string $contingency ): string {
|
||||||
|
return apply_filters( 'woocommerce_paypal_payments_three_d_secure_contingency', $contingency );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1020,44 +1059,57 @@ document.querySelector("#payment").before(document.querySelector("#ppcp-messages
|
||||||
'redirect' => wc_get_checkout_url(),
|
'redirect' => wc_get_checkout_url(),
|
||||||
'context' => $this->context(),
|
'context' => $this->context(),
|
||||||
'ajax' => array(
|
'ajax' => array(
|
||||||
'simulate_cart' => array(
|
'simulate_cart' => array(
|
||||||
'endpoint' => \WC_AJAX::get_endpoint( SimulateCartEndpoint::ENDPOINT ),
|
'endpoint' => \WC_AJAX::get_endpoint( SimulateCartEndpoint::ENDPOINT ),
|
||||||
'nonce' => wp_create_nonce( SimulateCartEndpoint::nonce() ),
|
'nonce' => wp_create_nonce( SimulateCartEndpoint::nonce() ),
|
||||||
),
|
),
|
||||||
'change_cart' => array(
|
'change_cart' => array(
|
||||||
'endpoint' => \WC_AJAX::get_endpoint( ChangeCartEndpoint::ENDPOINT ),
|
'endpoint' => \WC_AJAX::get_endpoint( ChangeCartEndpoint::ENDPOINT ),
|
||||||
'nonce' => wp_create_nonce( ChangeCartEndpoint::nonce() ),
|
'nonce' => wp_create_nonce( ChangeCartEndpoint::nonce() ),
|
||||||
),
|
),
|
||||||
'create_order' => array(
|
'create_order' => array(
|
||||||
'endpoint' => \WC_AJAX::get_endpoint( CreateOrderEndpoint::ENDPOINT ),
|
'endpoint' => \WC_AJAX::get_endpoint( CreateOrderEndpoint::ENDPOINT ),
|
||||||
'nonce' => wp_create_nonce( CreateOrderEndpoint::nonce() ),
|
'nonce' => wp_create_nonce( CreateOrderEndpoint::nonce() ),
|
||||||
),
|
),
|
||||||
'approve_order' => array(
|
'approve_order' => array(
|
||||||
'endpoint' => \WC_AJAX::get_endpoint( ApproveOrderEndpoint::ENDPOINT ),
|
'endpoint' => \WC_AJAX::get_endpoint( ApproveOrderEndpoint::ENDPOINT ),
|
||||||
'nonce' => wp_create_nonce( ApproveOrderEndpoint::nonce() ),
|
'nonce' => wp_create_nonce( ApproveOrderEndpoint::nonce() ),
|
||||||
),
|
),
|
||||||
'approve_subscription' => array(
|
'approve_subscription' => array(
|
||||||
'endpoint' => \WC_AJAX::get_endpoint( ApproveSubscriptionEndpoint::ENDPOINT ),
|
'endpoint' => \WC_AJAX::get_endpoint( ApproveSubscriptionEndpoint::ENDPOINT ),
|
||||||
'nonce' => wp_create_nonce( ApproveSubscriptionEndpoint::nonce() ),
|
'nonce' => wp_create_nonce( ApproveSubscriptionEndpoint::nonce() ),
|
||||||
),
|
),
|
||||||
'vault_paypal' => array(
|
'vault_paypal' => array(
|
||||||
'endpoint' => \WC_AJAX::get_endpoint( StartPayPalVaultingEndpoint::ENDPOINT ),
|
'endpoint' => \WC_AJAX::get_endpoint( StartPayPalVaultingEndpoint::ENDPOINT ),
|
||||||
'nonce' => wp_create_nonce( StartPayPalVaultingEndpoint::nonce() ),
|
'nonce' => wp_create_nonce( StartPayPalVaultingEndpoint::nonce() ),
|
||||||
),
|
),
|
||||||
'save_checkout_form' => array(
|
'save_checkout_form' => array(
|
||||||
'endpoint' => \WC_AJAX::get_endpoint( SaveCheckoutFormEndpoint::ENDPOINT ),
|
'endpoint' => \WC_AJAX::get_endpoint( SaveCheckoutFormEndpoint::ENDPOINT ),
|
||||||
'nonce' => wp_create_nonce( SaveCheckoutFormEndpoint::nonce() ),
|
'nonce' => wp_create_nonce( SaveCheckoutFormEndpoint::nonce() ),
|
||||||
),
|
),
|
||||||
'validate_checkout' => array(
|
'validate_checkout' => array(
|
||||||
'endpoint' => \WC_AJAX::get_endpoint( ValidateCheckoutEndpoint::ENDPOINT ),
|
'endpoint' => \WC_AJAX::get_endpoint( ValidateCheckoutEndpoint::ENDPOINT ),
|
||||||
'nonce' => wp_create_nonce( ValidateCheckoutEndpoint::nonce() ),
|
'nonce' => wp_create_nonce( ValidateCheckoutEndpoint::nonce() ),
|
||||||
),
|
),
|
||||||
'cart_script_params' => array(
|
'cart_script_params' => array(
|
||||||
'endpoint' => \WC_AJAX::get_endpoint( CartScriptParamsEndpoint::ENDPOINT ),
|
'endpoint' => \WC_AJAX::get_endpoint( CartScriptParamsEndpoint::ENDPOINT ),
|
||||||
),
|
),
|
||||||
|
'create_setup_token' => array(
|
||||||
|
'endpoint' => \WC_AJAX::get_endpoint( CreateSetupToken::ENDPOINT ),
|
||||||
|
'nonce' => wp_create_nonce( CreateSetupToken::nonce() ),
|
||||||
|
),
|
||||||
|
'create_payment_token' => array(
|
||||||
|
'endpoint' => \WC_AJAX::get_endpoint( CreatePaymentToken::ENDPOINT ),
|
||||||
|
'nonce' => wp_create_nonce( CreatePaymentToken::nonce() ),
|
||||||
|
),
|
||||||
|
'create_payment_token_for_guest' => array(
|
||||||
|
'endpoint' => \WC_AJAX::get_endpoint( CreatePaymentTokenForGuest::ENDPOINT ),
|
||||||
|
'nonce' => wp_create_nonce( CreatePaymentTokenForGuest::nonce() ),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
'cart_contains_subscription' => $this->subscription_helper->cart_contains_subscription(),
|
'cart_contains_subscription' => $this->subscription_helper->cart_contains_subscription(),
|
||||||
'subscription_plan_id' => $this->subscription_helper->paypal_subscription_id(),
|
'subscription_plan_id' => $this->subscription_helper->paypal_subscription_id(),
|
||||||
|
'vault_v3_enabled' => $this->vault_v3_enabled,
|
||||||
'variable_paypal_subscription_variations' => $this->subscription_helper->variable_paypal_subscription_variations(),
|
'variable_paypal_subscription_variations' => $this->subscription_helper->variable_paypal_subscription_variations(),
|
||||||
'subscription_product_allowed' => $this->subscription_helper->checkout_subscription_product_allowed(),
|
'subscription_product_allowed' => $this->subscription_helper->checkout_subscription_product_allowed(),
|
||||||
'locations_with_subscription_product' => $this->subscription_helper->locations_with_subscription_product(),
|
'locations_with_subscription_product' => $this->subscription_helper->locations_with_subscription_product(),
|
||||||
|
@ -1313,7 +1365,7 @@ document.querySelector("#payment").before(document.querySelector("#ppcp-messages
|
||||||
$disable_funding,
|
$disable_funding,
|
||||||
array_diff(
|
array_diff(
|
||||||
array_keys( $this->all_funding_sources ),
|
array_keys( $this->all_funding_sources ),
|
||||||
array( 'venmo', 'paylater' )
|
array( 'venmo', 'paylater', 'paypal' )
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1334,6 +1386,20 @@ document.querySelector("#payment").before(document.querySelector("#ppcp-messages
|
||||||
$disable_funding[] = 'paylater';
|
$disable_funding[] = 'paylater';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$disable_funding = array_filter(
|
||||||
|
$disable_funding,
|
||||||
|
/**
|
||||||
|
* Make sure paypal is not sent in disable funding.
|
||||||
|
*
|
||||||
|
* @param string $funding_source The funding_source.
|
||||||
|
*
|
||||||
|
* @psalm-suppress MissingClosureParamType
|
||||||
|
*/
|
||||||
|
function( $funding_source ) {
|
||||||
|
return $funding_source !== 'paypal';
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
if ( count( $disable_funding ) > 0 ) {
|
if ( count( $disable_funding ) > 0 ) {
|
||||||
$params['disable-funding'] = implode( ',', array_unique( $disable_funding ) );
|
$params['disable-funding'] = implode( ',', array_unique( $disable_funding ) );
|
||||||
}
|
}
|
||||||
|
@ -1875,8 +1941,18 @@ document.querySelector("#payment").before(document.querySelector("#ppcp-messages
|
||||||
*/
|
*/
|
||||||
private function get_vaulted_paypal_email(): string {
|
private function get_vaulted_paypal_email(): string {
|
||||||
try {
|
try {
|
||||||
$tokens = $this->get_payment_tokens();
|
$customer_id = get_user_meta( get_current_user_id(), '_ppcp_target_customer_id', true );
|
||||||
|
if ( $customer_id ) {
|
||||||
|
$customer_tokens = $this->payment_tokens_endpoint->payment_tokens_for_customer( $customer_id );
|
||||||
|
foreach ( $customer_tokens as $token ) {
|
||||||
|
$email_address = $token['payment_source']->properties()->email_address ?? '';
|
||||||
|
if ( $email_address ) {
|
||||||
|
return $email_address;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$tokens = $this->get_payment_tokens();
|
||||||
foreach ( $tokens as $token ) {
|
foreach ( $tokens as $token ) {
|
||||||
if ( isset( $token->source()->paypal ) ) {
|
if ( isset( $token->source()->paypal ) ) {
|
||||||
return $token->source()->paypal->payer->email_address;
|
return $token->source()->paypal->payer->email_address;
|
||||||
|
@ -1885,6 +1961,7 @@ document.querySelector("#payment").before(document.querySelector("#ppcp-messages
|
||||||
} catch ( Exception $exception ) {
|
} catch ( Exception $exception ) {
|
||||||
$this->logger->error( 'Failed to get PayPal vaulted email. ' . $exception->getMessage() );
|
$this->logger->error( 'Failed to get PayPal vaulted email. ' . $exception->getMessage() );
|
||||||
}
|
}
|
||||||
|
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ namespace WooCommerce\PayPalCommerce\Button\Endpoint;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
use Throwable;
|
use Throwable;
|
||||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Money;
|
use WooCommerce\PayPalCommerce\ApiClient\Entity\Money;
|
||||||
|
use WooCommerce\PayPalCommerce\Button\Assets\SmartButton;
|
||||||
use WooCommerce\PayPalCommerce\Button\Assets\SmartButtonInterface;
|
use WooCommerce\PayPalCommerce\Button\Assets\SmartButtonInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -66,6 +67,11 @@ class CartScriptParamsEndpoint implements EndpointInterface {
|
||||||
*/
|
*/
|
||||||
public function handle_request(): bool {
|
public function handle_request(): bool {
|
||||||
try {
|
try {
|
||||||
|
if ( ! $this->smart_button instanceof SmartButton ) {
|
||||||
|
wp_send_json_error();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if ( is_callable( 'wc_maybe_define_constant' ) ) {
|
if ( is_callable( 'wc_maybe_define_constant' ) ) {
|
||||||
wc_maybe_define_constant( 'WOOCOMMERCE_CART', true );
|
wc_maybe_define_constant( 'WOOCOMMERCE_CART', true );
|
||||||
}
|
}
|
||||||
|
|
|
@ -329,6 +329,21 @@ class CreateOrderEndpoint implements EndpointInterface {
|
||||||
if ( 'pay-now' === $data['context'] && is_a( $wc_order, \WC_Order::class ) ) {
|
if ( 'pay-now' === $data['context'] && is_a( $wc_order, \WC_Order::class ) ) {
|
||||||
$wc_order->update_meta_data( PayPalGateway::ORDER_ID_META_KEY, $order->id() );
|
$wc_order->update_meta_data( PayPalGateway::ORDER_ID_META_KEY, $order->id() );
|
||||||
$wc_order->update_meta_data( PayPalGateway::INTENT_META_KEY, $order->intent() );
|
$wc_order->update_meta_data( PayPalGateway::INTENT_META_KEY, $order->intent() );
|
||||||
|
|
||||||
|
$payment_source = $order->payment_source();
|
||||||
|
$payment_source_name = $payment_source ? $payment_source->name() : null;
|
||||||
|
$payer = $order->payer();
|
||||||
|
if (
|
||||||
|
$payer
|
||||||
|
&& $payment_source_name
|
||||||
|
&& in_array( $payment_source_name, PayPalGateway::PAYMENT_SOURCES_WITH_PAYER_EMAIL, true )
|
||||||
|
) {
|
||||||
|
$payer_email = $payer->email_address();
|
||||||
|
if ( $payer_email ) {
|
||||||
|
$wc_order->update_meta_data( PayPalGateway::ORDER_PAYER_EMAIL_META_KEY, $payer_email );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$wc_order->save_meta_data();
|
$wc_order->save_meta_data();
|
||||||
|
|
||||||
do_action( 'woocommerce_paypal_payments_woocommerce_order_created', $wc_order, $order );
|
do_action( 'woocommerce_paypal_payments_woocommerce_order_created', $wc_order, $order );
|
||||||
|
@ -422,6 +437,7 @@ class CreateOrderEndpoint implements EndpointInterface {
|
||||||
*
|
*
|
||||||
* @throws RuntimeException If create order request fails.
|
* @throws RuntimeException If create order request fails.
|
||||||
* @throws PayPalApiException If create order request fails.
|
* @throws PayPalApiException If create order request fails.
|
||||||
|
*
|
||||||
* phpcs:disable Squiz.Commenting.FunctionCommentThrowTag.WrongNumber
|
* phpcs:disable Squiz.Commenting.FunctionCommentThrowTag.WrongNumber
|
||||||
*/
|
*/
|
||||||
private function create_paypal_order( \WC_Order $wc_order = null, string $payment_method = '', array $data = array() ): Order {
|
private function create_paypal_order( \WC_Order $wc_order = null, string $payment_method = '', array $data = array() ): Order {
|
||||||
|
|
|
@ -13,6 +13,7 @@ use Exception;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Money;
|
use WooCommerce\PayPalCommerce\ApiClient\Entity\Money;
|
||||||
use WooCommerce\PayPalCommerce\Button\Assets\SmartButton;
|
use WooCommerce\PayPalCommerce\Button\Assets\SmartButton;
|
||||||
|
use WooCommerce\PayPalCommerce\Button\Assets\SmartButtonInterface;
|
||||||
use WooCommerce\PayPalCommerce\Button\Helper\CartProductsHelper;
|
use WooCommerce\PayPalCommerce\Button\Helper\CartProductsHelper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -25,7 +26,7 @@ class SimulateCartEndpoint extends AbstractCartEndpoint {
|
||||||
/**
|
/**
|
||||||
* The SmartButton.
|
* The SmartButton.
|
||||||
*
|
*
|
||||||
* @var SmartButton
|
* @var SmartButtonInterface
|
||||||
*/
|
*/
|
||||||
private $smart_button;
|
private $smart_button;
|
||||||
|
|
||||||
|
@ -39,14 +40,14 @@ class SimulateCartEndpoint extends AbstractCartEndpoint {
|
||||||
/**
|
/**
|
||||||
* ChangeCartEndpoint constructor.
|
* ChangeCartEndpoint constructor.
|
||||||
*
|
*
|
||||||
* @param SmartButton $smart_button The SmartButton.
|
* @param SmartButtonInterface $smart_button The SmartButton.
|
||||||
* @param \WC_Cart $cart The current WC cart object.
|
* @param \WC_Cart $cart The current WC cart object.
|
||||||
* @param RequestData $request_data The request data helper.
|
* @param RequestData $request_data The request data helper.
|
||||||
* @param CartProductsHelper $cart_products The cart products helper.
|
* @param CartProductsHelper $cart_products The cart products helper.
|
||||||
* @param LoggerInterface $logger The logger.
|
* @param LoggerInterface $logger The logger.
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
SmartButton $smart_button,
|
SmartButtonInterface $smart_button,
|
||||||
\WC_Cart $cart,
|
\WC_Cart $cart,
|
||||||
RequestData $request_data,
|
RequestData $request_data,
|
||||||
CartProductsHelper $cart_products,
|
CartProductsHelper $cart_products,
|
||||||
|
@ -68,6 +69,11 @@ class SimulateCartEndpoint extends AbstractCartEndpoint {
|
||||||
* @throws Exception On error.
|
* @throws Exception On error.
|
||||||
*/
|
*/
|
||||||
protected function handle_data(): bool {
|
protected function handle_data(): bool {
|
||||||
|
if ( ! $this->smart_button instanceof SmartButton ) {
|
||||||
|
wp_send_json_error();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
$products = $this->products_from_request();
|
$products = $this->products_from_request();
|
||||||
|
|
||||||
if ( ! $products ) {
|
if ( ! $products ) {
|
||||||
|
|
|
@ -159,6 +159,22 @@ class EarlyOrderHandler {
|
||||||
$wc_order = wc_get_order( $order_id );
|
$wc_order = wc_get_order( $order_id );
|
||||||
$wc_order->update_meta_data( PayPalGateway::ORDER_ID_META_KEY, $order->id() );
|
$wc_order->update_meta_data( PayPalGateway::ORDER_ID_META_KEY, $order->id() );
|
||||||
$wc_order->update_meta_data( PayPalGateway::INTENT_META_KEY, $order->intent() );
|
$wc_order->update_meta_data( PayPalGateway::INTENT_META_KEY, $order->intent() );
|
||||||
|
|
||||||
|
$payment_source = $order->payment_source();
|
||||||
|
$payment_source_name = $payment_source ? $payment_source->name() : null;
|
||||||
|
$payer = $order->payer();
|
||||||
|
if (
|
||||||
|
$payer
|
||||||
|
&& $payment_source_name
|
||||||
|
&& in_array( $payment_source_name, PayPalGateway::PAYMENT_SOURCES_WITH_PAYER_EMAIL, true )
|
||||||
|
&& $wc_order instanceof \WC_Order
|
||||||
|
) {
|
||||||
|
$payer_email = $payer->email_address();
|
||||||
|
if ( $payer_email ) {
|
||||||
|
$wc_order->update_meta_data( PayPalGateway::ORDER_PAYER_EMAIL_META_KEY, $payer_email );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$wc_order->save_meta_data();
|
$wc_order->save_meta_data();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -57,42 +57,58 @@ class ThreeDSecure {
|
||||||
*
|
*
|
||||||
* @link https://developer.paypal.com/docs/business/checkout/add-capabilities/3d-secure/#authenticationresult
|
* @link https://developer.paypal.com/docs/business/checkout/add-capabilities/3d-secure/#authenticationresult
|
||||||
*
|
*
|
||||||
* @param Order $order The order for which the decission is needed.
|
* @param Order $order The order for which the decision is needed.
|
||||||
*
|
*
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
public function proceed_with_order( Order $order ): int {
|
public function proceed_with_order( Order $order ): int {
|
||||||
|
|
||||||
|
do_action( 'woocommerce_paypal_payments_three_d_secure_before_check', $order );
|
||||||
|
|
||||||
$payment_source = $order->payment_source();
|
$payment_source = $order->payment_source();
|
||||||
if ( ! $payment_source ) {
|
if ( ! $payment_source ) {
|
||||||
return self::NO_DECISION;
|
return $this->return_decision( self::NO_DECISION, $order );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! $payment_source->properties()->brand ?? '' ) {
|
if ( ! ( $payment_source->properties()->brand ?? '' ) ) {
|
||||||
return self::NO_DECISION;
|
return $this->return_decision( self::NO_DECISION, $order );
|
||||||
}
|
}
|
||||||
if ( ! $payment_source->properties()->authentication_result ?? '' ) {
|
if ( ! ( $payment_source->properties()->authentication_result ?? '' ) ) {
|
||||||
return self::NO_DECISION;
|
return $this->return_decision( self::NO_DECISION, $order );
|
||||||
}
|
}
|
||||||
|
|
||||||
$authentication_result = $payment_source->properties()->authentication_result ?? null;
|
$authentication_result = $payment_source->properties()->authentication_result ?? null;
|
||||||
if ( $authentication_result ) {
|
if ( $authentication_result ) {
|
||||||
$result = $this->card_authentication_result_factory->from_paypal_response( $authentication_result );
|
$result = $this->card_authentication_result_factory->from_paypal_response( $authentication_result );
|
||||||
|
|
||||||
$this->logger->info( '3DS authentication result: ' . wc_print_r( $result->to_array(), true ) );
|
$this->logger->info( '3DS Authentication Result: ' . wc_print_r( $result->to_array(), true ) );
|
||||||
|
|
||||||
if ( $result->liability_shift() === AuthResult::LIABILITY_SHIFT_POSSIBLE ) {
|
if ( $result->liability_shift() === AuthResult::LIABILITY_SHIFT_POSSIBLE ) {
|
||||||
return self::PROCCEED;
|
return $this->return_decision( self::PROCCEED, $order );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( $result->liability_shift() === AuthResult::LIABILITY_SHIFT_UNKNOWN ) {
|
if ( $result->liability_shift() === AuthResult::LIABILITY_SHIFT_UNKNOWN ) {
|
||||||
return self::RETRY;
|
return $this->return_decision( self::RETRY, $order );
|
||||||
}
|
}
|
||||||
if ( $result->liability_shift() === AuthResult::LIABILITY_SHIFT_NO ) {
|
if ( $result->liability_shift() === AuthResult::LIABILITY_SHIFT_NO ) {
|
||||||
return $this->no_liability_shift( $result );
|
return $this->return_decision( $this->no_liability_shift( $result ), $order );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return self::NO_DECISION;
|
return $this->return_decision( self::NO_DECISION, $order );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Processes and returns a ThreeD secure decision.
|
||||||
|
*
|
||||||
|
* @param int $decision The ThreeD secure decision.
|
||||||
|
* @param Order $order The PayPal Order object.
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function return_decision( int $decision, Order $order ) {
|
||||||
|
$decision = apply_filters( 'woocommerce_paypal_payments_three_d_secure_decision', $decision, $order );
|
||||||
|
do_action( 'woocommerce_paypal_payments_three_d_secure_after_check', $order, $decision );
|
||||||
|
return $decision;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -54,6 +54,30 @@ return array(
|
||||||
'TWD',
|
'TWD',
|
||||||
'USD',
|
'USD',
|
||||||
),
|
),
|
||||||
|
'AT' => array(
|
||||||
|
'AUD',
|
||||||
|
'BRL',
|
||||||
|
'CAD',
|
||||||
|
'CHF',
|
||||||
|
'CZK',
|
||||||
|
'DKK',
|
||||||
|
'EUR',
|
||||||
|
'GBP',
|
||||||
|
'HKD',
|
||||||
|
'HUF',
|
||||||
|
'ILS',
|
||||||
|
'JPY',
|
||||||
|
'MXN',
|
||||||
|
'NOK',
|
||||||
|
'NZD',
|
||||||
|
'PHP',
|
||||||
|
'PLN',
|
||||||
|
'SEK',
|
||||||
|
'SGD',
|
||||||
|
'THB',
|
||||||
|
'TWD',
|
||||||
|
'USD',
|
||||||
|
),
|
||||||
'BE' => array(
|
'BE' => array(
|
||||||
'AUD',
|
'AUD',
|
||||||
'BRL',
|
'BRL',
|
||||||
|
@ -342,6 +366,30 @@ return array(
|
||||||
'TWD',
|
'TWD',
|
||||||
'USD',
|
'USD',
|
||||||
),
|
),
|
||||||
|
'IE' => array(
|
||||||
|
'AUD',
|
||||||
|
'BRL',
|
||||||
|
'CAD',
|
||||||
|
'CHF',
|
||||||
|
'CZK',
|
||||||
|
'DKK',
|
||||||
|
'EUR',
|
||||||
|
'GBP',
|
||||||
|
'HKD',
|
||||||
|
'HUF',
|
||||||
|
'ILS',
|
||||||
|
'JPY',
|
||||||
|
'MXN',
|
||||||
|
'NOK',
|
||||||
|
'NZD',
|
||||||
|
'PHP',
|
||||||
|
'PLN',
|
||||||
|
'SEK',
|
||||||
|
'SGD',
|
||||||
|
'THB',
|
||||||
|
'TWD',
|
||||||
|
'USD',
|
||||||
|
),
|
||||||
'IT' => array(
|
'IT' => array(
|
||||||
'AUD',
|
'AUD',
|
||||||
'BRL',
|
'BRL',
|
||||||
|
@ -390,6 +438,30 @@ return array(
|
||||||
'TWD',
|
'TWD',
|
||||||
'USD',
|
'USD',
|
||||||
),
|
),
|
||||||
|
'LI' => array(
|
||||||
|
'AUD',
|
||||||
|
'BRL',
|
||||||
|
'CAD',
|
||||||
|
'CHF',
|
||||||
|
'CZK',
|
||||||
|
'DKK',
|
||||||
|
'EUR',
|
||||||
|
'GBP',
|
||||||
|
'HKD',
|
||||||
|
'HUF',
|
||||||
|
'ILS',
|
||||||
|
'JPY',
|
||||||
|
'MXN',
|
||||||
|
'NOK',
|
||||||
|
'NZD',
|
||||||
|
'PHP',
|
||||||
|
'PLN',
|
||||||
|
'SEK',
|
||||||
|
'SGD',
|
||||||
|
'THB',
|
||||||
|
'TWD',
|
||||||
|
'USD',
|
||||||
|
),
|
||||||
'LT' => array(
|
'LT' => array(
|
||||||
'AUD',
|
'AUD',
|
||||||
'BRL',
|
'BRL',
|
||||||
|
@ -686,6 +758,30 @@ return array(
|
||||||
'JPY',
|
'JPY',
|
||||||
'USD',
|
'USD',
|
||||||
),
|
),
|
||||||
|
'NO' => array(
|
||||||
|
'AUD',
|
||||||
|
'BRL',
|
||||||
|
'CAD',
|
||||||
|
'CHF',
|
||||||
|
'CZK',
|
||||||
|
'DKK',
|
||||||
|
'EUR',
|
||||||
|
'GBP',
|
||||||
|
'HKD',
|
||||||
|
'HUF',
|
||||||
|
'ILS',
|
||||||
|
'JPY',
|
||||||
|
'MXN',
|
||||||
|
'NOK',
|
||||||
|
'NZD',
|
||||||
|
'PHP',
|
||||||
|
'PLN',
|
||||||
|
'SEK',
|
||||||
|
'SGD',
|
||||||
|
'THB',
|
||||||
|
'TWD',
|
||||||
|
'USD',
|
||||||
|
),
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
|
@ -115,17 +115,19 @@ class CardFieldsModule implements ModuleInterface {
|
||||||
$settings = $c->get( 'wcgateway.settings' );
|
$settings = $c->get( 'wcgateway.settings' );
|
||||||
assert( $settings instanceof Settings );
|
assert( $settings instanceof Settings );
|
||||||
|
|
||||||
|
$three_d_secure_contingency =
|
||||||
|
$settings->has( '3d_secure_contingency' )
|
||||||
|
? apply_filters( 'woocommerce_paypal_payments_three_d_secure_contingency', $settings->get( '3d_secure_contingency' ) )
|
||||||
|
: '';
|
||||||
|
|
||||||
if (
|
if (
|
||||||
$settings->has( '3d_secure_contingency' )
|
$three_d_secure_contingency === 'SCA_ALWAYS'
|
||||||
&& (
|
|| $three_d_secure_contingency === 'SCA_WHEN_REQUIRED'
|
||||||
$settings->get( '3d_secure_contingency' ) === 'SCA_ALWAYS'
|
|
||||||
|| $settings->get( '3d_secure_contingency' ) === 'SCA_WHEN_REQUIRED'
|
|
||||||
)
|
|
||||||
) {
|
) {
|
||||||
$data['payment_source']['card'] = array(
|
$data['payment_source']['card'] = array(
|
||||||
'attributes' => array(
|
'attributes' => array(
|
||||||
'verification' => array(
|
'verification' => array(
|
||||||
'method' => $settings->get( '3d_secure_contingency' ),
|
'method' => $three_d_secure_contingency,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
@ -114,6 +114,30 @@ return array(
|
||||||
'TWD',
|
'TWD',
|
||||||
'USD',
|
'USD',
|
||||||
),
|
),
|
||||||
|
'AT' => array(
|
||||||
|
'AUD',
|
||||||
|
'BRL',
|
||||||
|
'CAD',
|
||||||
|
'CHF',
|
||||||
|
'CZK',
|
||||||
|
'DKK',
|
||||||
|
'EUR',
|
||||||
|
'GBP',
|
||||||
|
'HKD',
|
||||||
|
'HUF',
|
||||||
|
'ILS',
|
||||||
|
'JPY',
|
||||||
|
'MXN',
|
||||||
|
'NOK',
|
||||||
|
'NZD',
|
||||||
|
'PHP',
|
||||||
|
'PLN',
|
||||||
|
'SEK',
|
||||||
|
'SGD',
|
||||||
|
'THB',
|
||||||
|
'TWD',
|
||||||
|
'USD',
|
||||||
|
),
|
||||||
'BE' => array(
|
'BE' => array(
|
||||||
'AUD',
|
'AUD',
|
||||||
'BRL',
|
'BRL',
|
||||||
|
@ -402,6 +426,30 @@ return array(
|
||||||
'TWD',
|
'TWD',
|
||||||
'USD',
|
'USD',
|
||||||
),
|
),
|
||||||
|
'IE' => array(
|
||||||
|
'AUD',
|
||||||
|
'BRL',
|
||||||
|
'CAD',
|
||||||
|
'CHF',
|
||||||
|
'CZK',
|
||||||
|
'DKK',
|
||||||
|
'EUR',
|
||||||
|
'GBP',
|
||||||
|
'HKD',
|
||||||
|
'HUF',
|
||||||
|
'ILS',
|
||||||
|
'JPY',
|
||||||
|
'MXN',
|
||||||
|
'NOK',
|
||||||
|
'NZD',
|
||||||
|
'PHP',
|
||||||
|
'PLN',
|
||||||
|
'SEK',
|
||||||
|
'SGD',
|
||||||
|
'THB',
|
||||||
|
'TWD',
|
||||||
|
'USD',
|
||||||
|
),
|
||||||
'IT' => array(
|
'IT' => array(
|
||||||
'AUD',
|
'AUD',
|
||||||
'BRL',
|
'BRL',
|
||||||
|
@ -450,6 +498,30 @@ return array(
|
||||||
'TWD',
|
'TWD',
|
||||||
'USD',
|
'USD',
|
||||||
),
|
),
|
||||||
|
'LI' => array(
|
||||||
|
'AUD',
|
||||||
|
'BRL',
|
||||||
|
'CAD',
|
||||||
|
'CHF',
|
||||||
|
'CZK',
|
||||||
|
'DKK',
|
||||||
|
'EUR',
|
||||||
|
'GBP',
|
||||||
|
'HKD',
|
||||||
|
'HUF',
|
||||||
|
'ILS',
|
||||||
|
'JPY',
|
||||||
|
'MXN',
|
||||||
|
'NOK',
|
||||||
|
'NZD',
|
||||||
|
'PHP',
|
||||||
|
'PLN',
|
||||||
|
'SEK',
|
||||||
|
'SGD',
|
||||||
|
'THB',
|
||||||
|
'TWD',
|
||||||
|
'USD',
|
||||||
|
),
|
||||||
'LT' => array(
|
'LT' => array(
|
||||||
'AUD',
|
'AUD',
|
||||||
'BRL',
|
'BRL',
|
||||||
|
@ -522,6 +594,30 @@ return array(
|
||||||
'TWD',
|
'TWD',
|
||||||
'USD',
|
'USD',
|
||||||
),
|
),
|
||||||
|
'NO' => array(
|
||||||
|
'AUD',
|
||||||
|
'BRL',
|
||||||
|
'CAD',
|
||||||
|
'CHF',
|
||||||
|
'CZK',
|
||||||
|
'DKK',
|
||||||
|
'EUR',
|
||||||
|
'GBP',
|
||||||
|
'HKD',
|
||||||
|
'HUF',
|
||||||
|
'ILS',
|
||||||
|
'JPY',
|
||||||
|
'MXN',
|
||||||
|
'NOK',
|
||||||
|
'NZD',
|
||||||
|
'PHP',
|
||||||
|
'PLN',
|
||||||
|
'SEK',
|
||||||
|
'SGD',
|
||||||
|
'THB',
|
||||||
|
'TWD',
|
||||||
|
'USD',
|
||||||
|
),
|
||||||
'NL' => array(
|
'NL' => array(
|
||||||
'AUD',
|
'AUD',
|
||||||
'BRL',
|
'BRL',
|
||||||
|
|
|
@ -11,6 +11,7 @@ namespace WooCommerce\PayPalCommerce\Googlepay\Helper;
|
||||||
|
|
||||||
use Throwable;
|
use Throwable;
|
||||||
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PartnersEndpoint;
|
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PartnersEndpoint;
|
||||||
|
use WooCommerce\PayPalCommerce\ApiClient\Entity\SellerStatusCapability;
|
||||||
use WooCommerce\PayPalCommerce\ApiClient\Helper\FailureRegistry;
|
use WooCommerce\PayPalCommerce\ApiClient\Helper\FailureRegistry;
|
||||||
use WooCommerce\PayPalCommerce\Onboarding\State;
|
use WooCommerce\PayPalCommerce\Onboarding\State;
|
||||||
use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
|
use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
|
||||||
|
@ -100,6 +101,11 @@ class ApmProductStatus {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$status_override = apply_filters( 'woocommerce_paypal_payments_google_pay_product_status', null );
|
||||||
|
if ( null !== $status_override ) {
|
||||||
|
return $status_override;
|
||||||
|
}
|
||||||
|
|
||||||
// If status was already checked on this request return the same result.
|
// If status was already checked on this request return the same result.
|
||||||
if ( null !== $this->current_status ) {
|
if ( null !== $this->current_status ) {
|
||||||
return $this->current_status;
|
return $this->current_status;
|
||||||
|
@ -128,21 +134,32 @@ class ApmProductStatus {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check the seller status for the intended capability.
|
// Check the seller status for the intended capability.
|
||||||
|
$has_capability = false;
|
||||||
foreach ( $seller_status->products() as $product ) {
|
foreach ( $seller_status->products() as $product ) {
|
||||||
if ( $product->name() !== 'PAYMENT_METHODS' ) {
|
if ( $product->name() !== 'PAYMENT_METHODS' ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( in_array( self::CAPABILITY_NAME, $product->capabilities(), true ) ) {
|
if ( in_array( self::CAPABILITY_NAME, $product->capabilities(), true ) ) {
|
||||||
// Capability found, persist status and return true.
|
$has_capability = true;
|
||||||
$this->settings->set( self::SETTINGS_KEY, self::SETTINGS_VALUE_ENABLED );
|
|
||||||
$this->settings->persist();
|
|
||||||
|
|
||||||
$this->current_status = true;
|
|
||||||
return $this->current_status;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach ( $seller_status->capabilities() as $capability ) {
|
||||||
|
if ( $capability->name() === self::CAPABILITY_NAME && $capability->status() === SellerStatusCapability::STATUS_ACTIVE ) {
|
||||||
|
$has_capability = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $has_capability ) {
|
||||||
|
// Capability found, persist status and return true.
|
||||||
|
$this->settings->set( self::SETTINGS_KEY, self::SETTINGS_VALUE_ENABLED );
|
||||||
|
$this->settings->persist();
|
||||||
|
|
||||||
|
$this->current_status = true;
|
||||||
|
return $this->current_status;
|
||||||
|
}
|
||||||
|
|
||||||
// Capability not found, persist status and return false.
|
// Capability not found, persist status and return false.
|
||||||
$this->settings->set( self::SETTINGS_KEY, self::SETTINGS_VALUE_DISABLED );
|
$this->settings->set( self::SETTINGS_KEY, self::SETTINGS_VALUE_DISABLED );
|
||||||
$this->settings->persist();
|
$this->settings->persist();
|
||||||
|
|
|
@ -359,6 +359,20 @@ document.addEventListener(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const referenceTransactionsCheck = () => {
|
||||||
|
if (
|
||||||
|
typeof PayPalCommerceGatewaySettings !== 'undefined'
|
||||||
|
&& PayPalCommerceGatewaySettings.reference_transaction_enabled !== '1'
|
||||||
|
) {
|
||||||
|
document.getElementById('ppcp-vault_enabled')?.setAttribute('disabled', 'disabled');
|
||||||
|
|
||||||
|
const description = document.getElementById('field-vault_enabled')?.getElementsByClassName('description')[0];
|
||||||
|
if (description) {
|
||||||
|
description.innerHTML = PayPalCommerceGatewaySettings.vaulting_must_enable_advanced_wallet_message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
(() => {
|
(() => {
|
||||||
removeDisabledCardIcons('select[name="ppcp[disable_cards][]"]', 'select[name="ppcp[card_icons][]"]');
|
removeDisabledCardIcons('select[name="ppcp[disable_cards][]"]', 'select[name="ppcp[card_icons][]"]');
|
||||||
|
|
||||||
|
@ -408,6 +422,8 @@ document.addEventListener(
|
||||||
);
|
);
|
||||||
|
|
||||||
togglePayLaterMessageFields();
|
togglePayLaterMessageFields();
|
||||||
|
|
||||||
|
referenceTransactionsCheck()
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
@ -14,6 +14,7 @@ use WC_Order_Item_Product;
|
||||||
use WC_Product;
|
use WC_Product;
|
||||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Item;
|
use WooCommerce\PayPalCommerce\ApiClient\Entity\Item;
|
||||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Money;
|
use WooCommerce\PayPalCommerce\ApiClient\Entity\Money;
|
||||||
|
use WooCommerce\PayPalCommerce\ApiClient\Helper\ItemTrait;
|
||||||
use WooCommerce\PayPalCommerce\OrderTracking\OrderTrackingModule;
|
use WooCommerce\PayPalCommerce\OrderTracking\OrderTrackingModule;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -21,6 +22,8 @@ use WooCommerce\PayPalCommerce\OrderTracking\OrderTrackingModule;
|
||||||
*/
|
*/
|
||||||
class Shipment implements ShipmentInterface {
|
class Shipment implements ShipmentInterface {
|
||||||
|
|
||||||
|
use ItemTrait;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The WC order ID.
|
* The WC order ID.
|
||||||
*
|
*
|
||||||
|
@ -166,12 +169,12 @@ class Shipment implements ShipmentInterface {
|
||||||
$image = wp_get_attachment_image_src( (int) $product->get_image_id(), 'full' );
|
$image = wp_get_attachment_image_src( (int) $product->get_image_id(), 'full' );
|
||||||
|
|
||||||
$ppcp_order_item = new Item(
|
$ppcp_order_item = new Item(
|
||||||
mb_substr( $item->get_name(), 0, 127 ),
|
$this->prepare_item_string( $item->get_name() ),
|
||||||
new Money( $price_without_tax_rounded, $currency ),
|
new Money( $price_without_tax_rounded, $currency ),
|
||||||
$quantity,
|
$quantity,
|
||||||
$this->prepare_description( $product->get_description() ),
|
$this->prepare_item_string( $product->get_description() ),
|
||||||
null,
|
null,
|
||||||
$product->get_sku(),
|
$this->prepare_sku( $product->get_sku() ),
|
||||||
$product->is_virtual() ? Item::DIGITAL_GOODS : Item::PHYSICAL_GOODS,
|
$product->is_virtual() ? Item::DIGITAL_GOODS : Item::PHYSICAL_GOODS,
|
||||||
$product->get_permalink(),
|
$product->get_permalink(),
|
||||||
$image[0] ?? ''
|
$image[0] ?? ''
|
||||||
|
@ -239,17 +242,6 @@ class Shipment implements ShipmentInterface {
|
||||||
return $shipment;
|
return $shipment;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Cleanups the description and prepares it for sending to PayPal.
|
|
||||||
*
|
|
||||||
* @param string $description Item description.
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
protected function prepare_description( string $description ): string {
|
|
||||||
$description = strip_shortcodes( wp_strip_all_tags( $description ) );
|
|
||||||
return substr( $description, 0, 127 ) ?: '';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renders the shipment line items info.
|
* Renders the shipment line items info.
|
||||||
*
|
*
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { loadPaypalScript } from '../../../ppcp-button/resources/js/modules/Help
|
||||||
import PayPalMessages from "./components/PayPalMessages";
|
import PayPalMessages from "./components/PayPalMessages";
|
||||||
|
|
||||||
export default function Edit( { attributes, clientId, setAttributes } ) {
|
export default function Edit( { attributes, clientId, setAttributes } ) {
|
||||||
const { layout, logo, position, color, flexColor, flexRatio, placement, id } = attributes;
|
const { layout, logo, position, color, size, flexColor, flexRatio, placement, id } = attributes;
|
||||||
const isFlex = layout === 'flex';
|
const isFlex = layout === 'flex';
|
||||||
|
|
||||||
const [paypalScriptState, setPaypalScriptState] = useState(null);
|
const [paypalScriptState, setPaypalScriptState] = useState(null);
|
||||||
|
@ -30,11 +30,12 @@ export default function Edit( { attributes, clientId, setAttributes } ) {
|
||||||
ratio: flexRatio,
|
ratio: flexRatio,
|
||||||
text: {
|
text: {
|
||||||
color,
|
color,
|
||||||
|
size
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let classes = ['ppcp-paylater-block-preview', 'ppcp-overlay-parent'];
|
let classes = ['ppcp-paylater-block-preview', 'ppcp-overlay-parent'];
|
||||||
if (PcpPayLaterBlock.vaultingEnabled) {
|
if (PcpPayLaterBlock.vaultingEnabled || !PcpPayLaterBlock.placementEnabled) {
|
||||||
classes = ['ppcp-paylater-block-preview', 'ppcp-paylater-unavailable', 'block-editor-warning'];
|
classes = ['ppcp-paylater-block-preview', 'ppcp-paylater-unavailable', 'block-editor-warning'];
|
||||||
}
|
}
|
||||||
const props = useBlockProps({className: classes});
|
const props = useBlockProps({className: classes});
|
||||||
|
@ -68,6 +69,27 @@ export default function Edit( { attributes, clientId, setAttributes } ) {
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!PcpPayLaterBlock.placementEnabled) {
|
||||||
|
return <div {...props}>
|
||||||
|
<div className={'block-editor-warning__contents'}>
|
||||||
|
<h3>{__('PayPal Pay Later Messaging', 'woocommerce-paypal-payments')}</h3>
|
||||||
|
<p className={'block-editor-warning__message'}>{__('Pay Later Messaging cannot be used while the “WooCommerce Block” messaging placement is disabled. Enable the placement in the PayPal Payments Pay Later settings to reactivate this block.', 'woocommerce-paypal-payments')}</p>
|
||||||
|
<div className={'class="block-editor-warning__actions"'}>
|
||||||
|
<span className={'block-editor-warning__action'}>
|
||||||
|
<a href={PcpPayLaterBlock.payLaterSettingsUrl} className={'components-button is-primary'}>
|
||||||
|
{__('PayPal Payments Settings', 'woocommerce-paypal-payments')}
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
<span className={'block-editor-warning__action'}>
|
||||||
|
<button onClick={() => wp.data.dispatch( 'core/block-editor' ).removeBlock(clientId)} type={'button'} className={'components-button is-secondary'}>
|
||||||
|
{__('Remove Block', 'woocommerce-paypal-payments')}
|
||||||
|
</button>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
let scriptParams = useScriptParams(PcpPayLaterBlock.ajax.cart_script_params);
|
let scriptParams = useScriptParams(PcpPayLaterBlock.ajax.cart_script_params);
|
||||||
if (scriptParams === null) {
|
if (scriptParams === null) {
|
||||||
return loadingElement;
|
return loadingElement;
|
||||||
|
@ -108,10 +130,10 @@ export default function Edit( { attributes, clientId, setAttributes } ) {
|
||||||
{ !isFlex && (<SelectControl
|
{ !isFlex && (<SelectControl
|
||||||
label={__('Logo', 'woocommerce-paypal-payments')}
|
label={__('Logo', 'woocommerce-paypal-payments')}
|
||||||
options={[
|
options={[
|
||||||
{ label: __('Primary', 'woocommerce-paypal-payments'), value: 'primary' },
|
{ label: __('Full logo', 'woocommerce-paypal-payments'), value: 'primary' },
|
||||||
{ label: __('Alternative', 'woocommerce-paypal-payments'), value: 'alternative' },
|
{ label: __('Monogram', 'woocommerce-paypal-payments'), value: 'alternative' },
|
||||||
{ label: __('Inline', 'woocommerce-paypal-payments'), value: 'inline' },
|
{ label: __('Inline', 'woocommerce-paypal-payments'), value: 'inline' },
|
||||||
{ label: __('None', 'woocommerce-paypal-payments'), value: 'none' },
|
{ label: __('Message only', 'woocommerce-paypal-payments'), value: 'none' },
|
||||||
]}
|
]}
|
||||||
value={logo}
|
value={logo}
|
||||||
onChange={(value) => setAttributes({logo: value})}
|
onChange={(value) => setAttributes({logo: value})}
|
||||||
|
@ -129,24 +151,31 @@ export default function Edit( { attributes, clientId, setAttributes } ) {
|
||||||
{ !isFlex && (<SelectControl
|
{ !isFlex && (<SelectControl
|
||||||
label={__('Text Color', 'woocommerce-paypal-payments')}
|
label={__('Text Color', 'woocommerce-paypal-payments')}
|
||||||
options={[
|
options={[
|
||||||
{ label: __( 'Black', 'woocommerce-paypal-payments' ), value: 'black' },
|
{ label: __( 'Black / Blue logo', 'woocommerce-paypal-payments' ), value: 'black' },
|
||||||
{ label: __( 'White', 'woocommerce-paypal-payments' ), value: 'white' },
|
{ label: __( 'White / White logo', 'woocommerce-paypal-payments' ), value: 'white' },
|
||||||
{ label: __( 'Monochrome', 'woocommerce-paypal-payments' ), value: 'monochrome' },
|
{ label: __( 'Monochrome', 'woocommerce-paypal-payments' ), value: 'monochrome' },
|
||||||
{ label: __( 'Grayscale', 'woocommerce-paypal-payments' ), value: 'grayscale' },
|
{ label: __( 'Black / Gray logo', 'woocommerce-paypal-payments' ), value: 'grayscale' },
|
||||||
]}
|
]}
|
||||||
value={color}
|
value={color}
|
||||||
onChange={(value) => setAttributes({color: value})}
|
onChange={(value) => setAttributes({color: value})}
|
||||||
/>)}
|
/>)}
|
||||||
|
{ !isFlex && (<SelectControl
|
||||||
|
label={__('Text Size', 'woocommerce-paypal-payments')}
|
||||||
|
options={[
|
||||||
|
{ label: __( 'Small', 'woocommerce-paypal-payments' ), value: '12' },
|
||||||
|
{ label: __( 'Medium', 'woocommerce-paypal-payments' ), value: '14' },
|
||||||
|
{ label: __( 'Large', 'woocommerce-paypal-payments' ), value: '16' },
|
||||||
|
]}
|
||||||
|
value={size}
|
||||||
|
onChange={(value) => setAttributes({size: value})}
|
||||||
|
/>)}
|
||||||
{ isFlex && (<SelectControl
|
{ isFlex && (<SelectControl
|
||||||
label={__('Color', 'woocommerce-paypal-payments')}
|
label={__('Color', 'woocommerce-paypal-payments')}
|
||||||
options={[
|
options={[
|
||||||
{ label: __( 'Blue', 'woocommerce-paypal-payments' ), value: 'blue' },
|
{ label: __( 'Blue', 'woocommerce-paypal-payments' ), value: 'blue' },
|
||||||
{ label: __( 'Black', 'woocommerce-paypal-payments' ), value: 'black' },
|
{ label: __( 'Black', 'woocommerce-paypal-payments' ), value: 'black' },
|
||||||
{ label: __( 'White', 'woocommerce-paypal-payments' ), value: 'white' },
|
{ label: __( 'White', 'woocommerce-paypal-payments' ), value: 'white' },
|
||||||
{ label: __( 'White no border', 'woocommerce-paypal-payments' ), value: 'white-no-border' },
|
{ label: __( 'White (no border)', 'woocommerce-paypal-payments' ), value: 'white-no-border' },
|
||||||
{ label: __( 'Gray', 'woocommerce-paypal-payments' ), value: 'gray' },
|
|
||||||
{ label: __( 'Monochrome', 'woocommerce-paypal-payments' ), value: 'monochrome' },
|
|
||||||
{ label: __( 'Grayscale', 'woocommerce-paypal-payments' ), value: 'grayscale' },
|
|
||||||
]}
|
]}
|
||||||
value={flexColor}
|
value={flexColor}
|
||||||
onChange={(value) => setAttributes({flexColor: value})}
|
onChange={(value) => setAttributes({flexColor: value})}
|
||||||
|
@ -154,8 +183,6 @@ export default function Edit( { attributes, clientId, setAttributes } ) {
|
||||||
{ isFlex && (<SelectControl
|
{ isFlex && (<SelectControl
|
||||||
label={__('Ratio', 'woocommerce-paypal-payments')}
|
label={__('Ratio', 'woocommerce-paypal-payments')}
|
||||||
options={[
|
options={[
|
||||||
{ label: __( '1x1', 'woocommerce-paypal-payments' ), value: '1x1' },
|
|
||||||
{ label: __( '1x4', 'woocommerce-paypal-payments' ), value: '1x4' },
|
|
||||||
{ label: __( '8x1', 'woocommerce-paypal-payments' ), value: '8x1' },
|
{ label: __( '8x1', 'woocommerce-paypal-payments' ), value: '8x1' },
|
||||||
{ label: __( '20x1', 'woocommerce-paypal-payments' ), value: '20x1' },
|
{ label: __( '20x1', 'woocommerce-paypal-payments' ), value: '20x1' },
|
||||||
]}
|
]}
|
||||||
|
@ -167,12 +194,11 @@ export default function Edit( { attributes, clientId, setAttributes } ) {
|
||||||
help={ __( 'Used for the analytics dashboard in the merchant account.', 'woocommerce-paypal-payments' ) }
|
help={ __( 'Used for the analytics dashboard in the merchant account.', 'woocommerce-paypal-payments' ) }
|
||||||
options={ [
|
options={ [
|
||||||
{ label: __( 'Detect automatically', 'woocommerce-paypal-payments' ), value: 'auto' },
|
{ label: __( 'Detect automatically', 'woocommerce-paypal-payments' ), value: 'auto' },
|
||||||
|
{ label: __( 'Product Page', 'woocommerce-paypal-payments' ), value: 'product' },
|
||||||
{ label: __( 'Cart', 'woocommerce-paypal-payments' ), value: 'cart' },
|
{ label: __( 'Cart', 'woocommerce-paypal-payments' ), value: 'cart' },
|
||||||
{ label: __( 'Payment', 'woocommerce-paypal-payments' ), value: 'payment' },
|
{ label: __( 'Checkout', 'woocommerce-paypal-payments' ), value: 'checkout' },
|
||||||
{ label: __( 'Product', 'woocommerce-paypal-payments' ), value: 'product' },
|
|
||||||
{ label: __( 'Product list', 'woocommerce-paypal-payments' ), value: 'product-list' },
|
|
||||||
{ label: __( 'Home', 'woocommerce-paypal-payments' ), value: 'home' },
|
{ label: __( 'Home', 'woocommerce-paypal-payments' ), value: 'home' },
|
||||||
{ label: __( 'Category', 'woocommerce-paypal-payments' ), value: 'category' },
|
{ label: __( 'Shop', 'woocommerce-paypal-payments' ), value: 'shop' },
|
||||||
] }
|
] }
|
||||||
value={ placement }
|
value={ placement }
|
||||||
onChange={ ( value ) => setAttributes( { placement: value } ) }
|
onChange={ ( value ) => setAttributes( { placement: value } ) }
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { useBlockProps } from '@wordpress/block-editor';
|
import { useBlockProps } from '@wordpress/block-editor';
|
||||||
|
|
||||||
export default function save( { attributes } ) {
|
export default function save( { attributes } ) {
|
||||||
const { layout, logo, position, color, flexColor, flexRatio, placement, id } = attributes;
|
const { layout, logo, position, color, size, flexColor, flexRatio, placement, id } = attributes;
|
||||||
const paypalAttributes = layout === 'flex' ? {
|
const paypalAttributes = layout === 'flex' ? {
|
||||||
'data-pp-style-layout': 'flex',
|
'data-pp-style-layout': 'flex',
|
||||||
'data-pp-style-color': flexColor,
|
'data-pp-style-color': flexColor,
|
||||||
|
@ -11,6 +11,7 @@ export default function save( { attributes } ) {
|
||||||
'data-pp-style-logo-type': logo,
|
'data-pp-style-logo-type': logo,
|
||||||
'data-pp-style-logo-position': position,
|
'data-pp-style-logo-position': position,
|
||||||
'data-pp-style-text-color': color,
|
'data-pp-style-text-color': color,
|
||||||
|
'data-pp-style-text-size': size,
|
||||||
};
|
};
|
||||||
if (placement && placement !== 'auto') {
|
if (placement && placement !== 'auto') {
|
||||||
paypalAttributes['data-pp-placement'] = placement;
|
paypalAttributes['data-pp-placement'] = placement;
|
||||||
|
|
|
@ -15,6 +15,7 @@ use WooCommerce\PayPalCommerce\Vendor\Dhii\Container\ServiceProvider;
|
||||||
use WooCommerce\PayPalCommerce\Vendor\Dhii\Modular\Module\ModuleInterface;
|
use WooCommerce\PayPalCommerce\Vendor\Dhii\Modular\Module\ModuleInterface;
|
||||||
use WooCommerce\PayPalCommerce\Vendor\Interop\Container\ServiceProviderInterface;
|
use WooCommerce\PayPalCommerce\Vendor\Interop\Container\ServiceProviderInterface;
|
||||||
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
|
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
|
||||||
|
use WooCommerce\PayPalCommerce\WcGateway\Helper\SettingsStatus;
|
||||||
use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
|
use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -22,16 +23,26 @@ use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
|
||||||
*/
|
*/
|
||||||
class PayLaterBlockModule implements ModuleInterface {
|
class PayLaterBlockModule implements ModuleInterface {
|
||||||
/**
|
/**
|
||||||
* Returns whether the block should be loaded.
|
* Returns whether the block module should be loaded.
|
||||||
*/
|
*/
|
||||||
public static function is_enabled(): bool {
|
public static function is_module_loading_required(): bool {
|
||||||
return apply_filters(
|
return apply_filters(
|
||||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
|
// phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
|
||||||
'woocommerce.feature-flags.woocommerce_paypal_payments.paylater_block_enabled',
|
'woocommerce.feature-flags.woocommerce_paypal_payments.paylater_block_enabled',
|
||||||
getenv( 'PCP_PAYLATER_BLOCK' ) === '1'
|
getenv( 'PCP_PAYLATER_BLOCK' ) !== '0'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the block is enabled.
|
||||||
|
*
|
||||||
|
* @param SettingsStatus $settings_status The Settings status helper.
|
||||||
|
* @return bool true if the block is enabled, otherwise false.
|
||||||
|
*/
|
||||||
|
public static function is_block_enabled( SettingsStatus $settings_status ): bool {
|
||||||
|
return self::is_module_loading_required() && $settings_status->is_pay_later_messaging_enabled_for_location( 'custom_placement' );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
|
@ -71,13 +82,15 @@ class PayLaterBlockModule implements ModuleInterface {
|
||||||
$script_handle,
|
$script_handle,
|
||||||
'PcpPayLaterBlock',
|
'PcpPayLaterBlock',
|
||||||
array(
|
array(
|
||||||
'ajax' => array(
|
'ajax' => array(
|
||||||
'cart_script_params' => array(
|
'cart_script_params' => array(
|
||||||
'endpoint' => \WC_AJAX::get_endpoint( CartScriptParamsEndpoint::ENDPOINT ),
|
'endpoint' => \WC_AJAX::get_endpoint( CartScriptParamsEndpoint::ENDPOINT ),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
'settingsUrl' => admin_url( 'admin.php?page=wc-settings&tab=checkout§ion=ppcp-gateway' ),
|
'settingsUrl' => admin_url( 'admin.php?page=wc-settings&tab=checkout§ion=ppcp-gateway' ),
|
||||||
'vaultingEnabled' => $settings->has( 'vault_enabled' ) && $settings->get( 'vault_enabled' ),
|
'vaultingEnabled' => $settings->has( 'vault_enabled' ) && $settings->get( 'vault_enabled' ),
|
||||||
|
'placementEnabled' => self::is_block_enabled( $c->get( 'wcgateway.settings.status' ) ),
|
||||||
|
'payLaterSettingsUrl' => admin_url( 'admin.php?page=wc-settings&tab=checkout§ion=ppcp-gateway&ppcp-tab=ppcp-pay-later' ),
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
14
modules/ppcp-paylater-configurator/.babelrc
Normal file
14
modules/ppcp-paylater-configurator/.babelrc
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
{
|
||||||
|
"presets": [
|
||||||
|
[
|
||||||
|
"@babel/preset-env",
|
||||||
|
{
|
||||||
|
"useBuiltIns": "usage",
|
||||||
|
"corejs": "3.25.0"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"@babel/preset-react"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
3
modules/ppcp-paylater-configurator/.gitignore
vendored
Normal file
3
modules/ppcp-paylater-configurator/.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
node_modules
|
||||||
|
assets/js
|
||||||
|
assets/css
|
17
modules/ppcp-paylater-configurator/composer.json
Normal file
17
modules/ppcp-paylater-configurator/composer.json
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
{
|
||||||
|
"name": "woocommerce/ppcp-paylater-configurator",
|
||||||
|
"type": "dhii-mod",
|
||||||
|
"description": "Pay Later Messaging configurator module for PPCP",
|
||||||
|
"license": "GPL-2.0",
|
||||||
|
"require": {
|
||||||
|
"php": "^7.2 | ^8.0",
|
||||||
|
"dhii/module-interface": "^0.3.0-alpha1"
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"WooCommerce\\PayPalCommerce\\PayLaterConfigurator\\": "src"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"minimum-stability": "dev",
|
||||||
|
"prefer-stable": true
|
||||||
|
}
|
83
modules/ppcp-paylater-configurator/extensions.php
Normal file
83
modules/ppcp-paylater-configurator/extensions.php
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* The Pay Later configurator module extensions.
|
||||||
|
*
|
||||||
|
* @package WooCommerce\PayPalCommerce\PayLaterConfigurator
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace WooCommerce\PayPalCommerce\PayLaterConfigurator;
|
||||||
|
|
||||||
|
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
|
||||||
|
use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
|
||||||
|
|
||||||
|
return array(
|
||||||
|
'wcgateway.settings.fields' => function ( ContainerInterface $container, array $fields ): array {
|
||||||
|
$old_fields = array(
|
||||||
|
'pay_later_messaging_locations',
|
||||||
|
'pay_later_enable_styling_per_messaging_location',
|
||||||
|
'pay_later_general_message_layout',
|
||||||
|
'pay_later_general_message_logo',
|
||||||
|
'pay_later_general_message_position',
|
||||||
|
'pay_later_general_message_color',
|
||||||
|
'pay_later_general_message_flex_color',
|
||||||
|
'pay_later_general_message_flex_ratio',
|
||||||
|
'pay_later_general_message_preview',
|
||||||
|
'pay_later_product_messaging_heading',
|
||||||
|
'pay_later_product_message_layout',
|
||||||
|
'pay_later_product_message_logo',
|
||||||
|
'pay_later_product_message_position',
|
||||||
|
'pay_later_product_message_color',
|
||||||
|
'pay_later_product_message_flex_color',
|
||||||
|
'pay_later_product_message_flex_ratio',
|
||||||
|
'pay_later_product_message_preview',
|
||||||
|
'pay_later_cart_messaging_heading',
|
||||||
|
'pay_later_cart_message_layout',
|
||||||
|
'pay_later_cart_message_logo',
|
||||||
|
'pay_later_cart_message_position',
|
||||||
|
'pay_later_cart_message_color',
|
||||||
|
'pay_later_cart_message_flex_color',
|
||||||
|
'pay_later_cart_message_flex_ratio',
|
||||||
|
'pay_later_cart_message_preview',
|
||||||
|
'pay_later_checkout_messaging_heading',
|
||||||
|
'pay_later_checkout_message_layout',
|
||||||
|
'pay_later_checkout_message_logo',
|
||||||
|
'pay_later_checkout_message_position',
|
||||||
|
'pay_later_checkout_message_color',
|
||||||
|
'pay_later_checkout_message_flex_color',
|
||||||
|
'pay_later_checkout_message_flex_ratio',
|
||||||
|
'pay_later_checkout_message_preview',
|
||||||
|
'pay_later_shop_messaging_heading',
|
||||||
|
'pay_later_shop_message_layout',
|
||||||
|
'pay_later_shop_message_logo',
|
||||||
|
'pay_later_shop_message_position',
|
||||||
|
'pay_later_shop_message_color',
|
||||||
|
'pay_later_shop_message_flex_color',
|
||||||
|
'pay_later_shop_message_flex_ratio',
|
||||||
|
'pay_later_shop_message_preview',
|
||||||
|
'pay_later_home_messaging_heading',
|
||||||
|
'pay_later_home_message_layout',
|
||||||
|
'pay_later_home_message_logo',
|
||||||
|
'pay_later_home_message_position',
|
||||||
|
'pay_later_home_message_color',
|
||||||
|
'pay_later_home_message_flex_color',
|
||||||
|
'pay_later_home_message_flex_ratio',
|
||||||
|
'pay_later_home_message_preview',
|
||||||
|
);
|
||||||
|
|
||||||
|
$settings = $container->get( 'wcgateway.settings' );
|
||||||
|
assert( $settings instanceof Settings );
|
||||||
|
$vault_enabled = $settings->has( 'vault_enabled' ) && $settings->get( 'vault_enabled' );
|
||||||
|
|
||||||
|
if ( ! $vault_enabled ) {
|
||||||
|
$old_fields[] = 'pay_later_messaging_enabled';
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ( $old_fields as $old_field ) {
|
||||||
|
unset( $fields[ $old_field ] );
|
||||||
|
}
|
||||||
|
|
||||||
|
return $fields;
|
||||||
|
},
|
||||||
|
);
|
16
modules/ppcp-paylater-configurator/module.php
Normal file
16
modules/ppcp-paylater-configurator/module.php
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* The Pay Later configurator module.
|
||||||
|
*
|
||||||
|
* @package WooCommerce\PayPalCommerce\PayLaterConfigurator
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace WooCommerce\PayPalCommerce\PayLaterConfigurator;
|
||||||
|
|
||||||
|
use WooCommerce\PayPalCommerce\Vendor\Dhii\Modular\Module\ModuleInterface;
|
||||||
|
|
||||||
|
return static function (): ModuleInterface {
|
||||||
|
return new PayLaterConfiguratorModule();
|
||||||
|
};
|
33
modules/ppcp-paylater-configurator/package.json
Normal file
33
modules/ppcp-paylater-configurator/package.json
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
{
|
||||||
|
"name": "ppcp-paylater-configurator",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"license": "GPL-3.0-or-later",
|
||||||
|
"browserslist": [
|
||||||
|
"> 0.5%",
|
||||||
|
"Safari >= 8",
|
||||||
|
"Chrome >= 41",
|
||||||
|
"Firefox >= 43",
|
||||||
|
"Edge >= 14"
|
||||||
|
],
|
||||||
|
"dependencies": {
|
||||||
|
"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"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
#messaging-configurator {
|
||||||
|
& > div {
|
||||||
|
justify-content: left;
|
||||||
|
margin: 0;
|
||||||
|
|
||||||
|
& > div {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.ppcp-paylater-configurator-publishButton {
|
||||||
|
display:none;
|
||||||
|
}
|
||||||
|
.ppcp-paylater-configurator-header {
|
||||||
|
font-size: 1.3em;
|
||||||
|
color: #1d2327;
|
||||||
|
margin: 1em 0;
|
||||||
|
font-weight: 600;
|
||||||
|
font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;
|
||||||
|
line-height: 1.3;
|
||||||
|
}
|
||||||
|
#configurator-eligibleContainer div:has(.ppcp-paylater-configurator-header#configurator-headerText) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.ppcp-paylater-configurator-subheader {
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 1.5;
|
||||||
|
color: #3c434a;
|
||||||
|
font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;
|
||||||
|
|
||||||
|
a {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.css-dpyjrq-text_body, .css-dpyjrq-text_body a {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
button.css-104jwuk {
|
||||||
|
background: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.css-1yo2lxy-text_body_strong, span.css-16jt5za-text_body, span.css-1yo2lxy-text_body_strong, span {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr {
|
||||||
|
margin-right: 16px;
|
||||||
|
border-top-color: #B1B7BD;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#field-pay_later_messaging_heading h3{
|
||||||
|
margin-bottom: 0px;
|
||||||
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
document.addEventListener( 'DOMContentLoaded', () => {
|
||||||
|
const form = document.querySelector('#mainform');
|
||||||
|
const table = form.querySelector('.form-table');
|
||||||
|
const headingRow = table.querySelector('#field-pay_later_messaging_heading');
|
||||||
|
const saveChangesButton = form.querySelector('.woocommerce-save-button');
|
||||||
|
const publishButtonClassName = PcpPayLaterConfigurator.publishButtonClassName;
|
||||||
|
|
||||||
|
const tempContainer = document.createElement('div');
|
||||||
|
tempContainer.innerHTML = `<div id='messaging-configurator'></div>`;
|
||||||
|
|
||||||
|
// Get the new row element from the container
|
||||||
|
const newRow = tempContainer.firstChild;
|
||||||
|
|
||||||
|
// Insert the new row after the headingRow
|
||||||
|
headingRow.parentNode.insertBefore(newRow, headingRow.nextSibling);
|
||||||
|
|
||||||
|
|
||||||
|
let isSaving = false; // Flag variable to track whether saving is in progress
|
||||||
|
|
||||||
|
saveChangesButton.addEventListener('click', () => {
|
||||||
|
// Check if saving is not already in progress
|
||||||
|
if (!isSaving) {
|
||||||
|
isSaving = true; // Set flag to indicate saving is in progress
|
||||||
|
|
||||||
|
// Trigger the click event on the publish button
|
||||||
|
form.querySelector('.' + publishButtonClassName).click();
|
||||||
|
|
||||||
|
// Trigger click event on saveChangesButton after a short delay
|
||||||
|
setTimeout(() => {
|
||||||
|
saveChangesButton.click(); // Trigger click event on saveChangesButton
|
||||||
|
isSaving = false; // Reset flag when saving is complete
|
||||||
|
}, 1000); // Adjust the delay as needed
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
merchantConfigurators.Messaging({
|
||||||
|
config: PcpPayLaterConfigurator.config,
|
||||||
|
merchantClientId: PcpPayLaterConfigurator.merchantClientId,
|
||||||
|
partnerClientId: PcpPayLaterConfigurator.partnerClientId,
|
||||||
|
partnerName: 'WooCommerce',
|
||||||
|
bnCode: 'Woo_PPCP',
|
||||||
|
placements: ['cart', 'checkout', 'product', 'shop', 'home', 'custom_placement'],
|
||||||
|
styleOverrides: {
|
||||||
|
button: publishButtonClassName,
|
||||||
|
header: PcpPayLaterConfigurator.headerClassName,
|
||||||
|
subheader: PcpPayLaterConfigurator.subheaderClassName
|
||||||
|
},
|
||||||
|
onSave: data => {
|
||||||
|
fetch(PcpPayLaterConfigurator.ajax.save_config.endpoint, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
credentials: 'same-origin',
|
||||||
|
body: JSON.stringify({
|
||||||
|
nonce: PcpPayLaterConfigurator.ajax.save_config.nonce,
|
||||||
|
config: data,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} );
|
38
modules/ppcp-paylater-configurator/services.php
Normal file
38
modules/ppcp-paylater-configurator/services.php
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* The Pay Later configurator module services.
|
||||||
|
*
|
||||||
|
* @package WooCommerce\PayPalCommerce\PayLaterConfigurator
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace WooCommerce\PayPalCommerce\PayLaterConfigurator;
|
||||||
|
|
||||||
|
use WooCommerce\PayPalCommerce\PayLaterConfigurator\Endpoint\SaveConfig;
|
||||||
|
use WooCommerce\PayPalCommerce\PayLaterConfigurator\Factory\ConfigFactory;
|
||||||
|
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
|
||||||
|
|
||||||
|
return array(
|
||||||
|
'paylater-configurator.url' => static function ( ContainerInterface $container ): string {
|
||||||
|
/**
|
||||||
|
* Cannot return false for this path.
|
||||||
|
*
|
||||||
|
* @psalm-suppress PossiblyFalseArgument
|
||||||
|
*/
|
||||||
|
return plugins_url(
|
||||||
|
'/modules/ppcp-paylater-configurator/',
|
||||||
|
dirname( realpath( __FILE__ ), 3 ) . '/woocommerce-paypal-payments.php'
|
||||||
|
);
|
||||||
|
},
|
||||||
|
'paylater-configurator.factory.config' => static function ( ContainerInterface $container ): ConfigFactory {
|
||||||
|
return new ConfigFactory();
|
||||||
|
},
|
||||||
|
'paylater-configurator.endpoint.save-config' => static function ( ContainerInterface $container ): SaveConfig {
|
||||||
|
return new SaveConfig(
|
||||||
|
$container->get( 'wcgateway.settings' ),
|
||||||
|
$container->get( 'button.request-data' ),
|
||||||
|
$container->get( 'woocommerce.logger.woocommerce' )
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
150
modules/ppcp-paylater-configurator/src/Endpoint/SaveConfig.php
Normal file
150
modules/ppcp-paylater-configurator/src/Endpoint/SaveConfig.php
Normal file
|
@ -0,0 +1,150 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* The endpoint for saving the Pay Later messaging config from the configurator.
|
||||||
|
*
|
||||||
|
* @package WooCommerce\PayPalCommerce\PayLaterConfigurator\Endpoint
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace WooCommerce\PayPalCommerce\PayLaterConfigurator\Endpoint;
|
||||||
|
|
||||||
|
use Psr\Log\LoggerInterface;
|
||||||
|
use Throwable;
|
||||||
|
use WooCommerce\PayPalCommerce\Button\Endpoint\RequestData;
|
||||||
|
use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class SaveConfig.
|
||||||
|
*/
|
||||||
|
class SaveConfig {
|
||||||
|
const ENDPOINT = 'ppc-save-message-config';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The settings.
|
||||||
|
*
|
||||||
|
* @var Settings
|
||||||
|
*/
|
||||||
|
protected $settings;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The request data.
|
||||||
|
*
|
||||||
|
* @var RequestData
|
||||||
|
*/
|
||||||
|
protected $request_data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The logger.
|
||||||
|
*
|
||||||
|
* @var LoggerInterface
|
||||||
|
*/
|
||||||
|
private $logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SaveConfig constructor.
|
||||||
|
*
|
||||||
|
* @param Settings $settings The settings.
|
||||||
|
* @param RequestData $request_data The request data.
|
||||||
|
* @param LoggerInterface $logger The logger.
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
Settings $settings,
|
||||||
|
RequestData $request_data,
|
||||||
|
LoggerInterface $logger
|
||||||
|
) {
|
||||||
|
$this->settings = $settings;
|
||||||
|
$this->request_data = $request_data;
|
||||||
|
$this->logger = $logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the nonce.
|
||||||
|
*/
|
||||||
|
public static function nonce(): string {
|
||||||
|
return self::ENDPOINT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the request.
|
||||||
|
*/
|
||||||
|
public function handle_request(): bool {
|
||||||
|
if ( ! current_user_can( 'manage_woocommerce' ) ) {
|
||||||
|
wp_send_json_error( 'Not admin.', 403 );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$data = $this->request_data->read_request( $this->nonce() );
|
||||||
|
|
||||||
|
$this->save_config( $data['config']['config'] );
|
||||||
|
|
||||||
|
wp_send_json_success();
|
||||||
|
return true;
|
||||||
|
} catch ( Throwable $error ) {
|
||||||
|
$this->logger->error( "SaveConfig execution failed. {$error->getMessage()} {$error->getFile()}:{$error->getLine()}" );
|
||||||
|
|
||||||
|
wp_send_json_error();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves the config into the old settings.
|
||||||
|
*
|
||||||
|
* @param array $config The configurator config.
|
||||||
|
*/
|
||||||
|
private function save_config( array $config ): void {
|
||||||
|
$this->settings->set( 'pay_later_enable_styling_per_messaging_location', true );
|
||||||
|
$this->settings->set( 'pay_later_messaging_enabled', true );
|
||||||
|
|
||||||
|
$enabled_locations = array();
|
||||||
|
foreach ( $config as $placement => $data ) {
|
||||||
|
$this->save_config_for_location( $data, $placement );
|
||||||
|
|
||||||
|
if ( $placement === 'custom_placement' ) {
|
||||||
|
$data = $data[0] ?? array();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $data['status'] === 'enabled' ) {
|
||||||
|
$enabled_locations[] = $placement;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->settings->set( 'pay_later_messaging_locations', $enabled_locations );
|
||||||
|
|
||||||
|
$this->settings->persist();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves the config for a location into the old settings.
|
||||||
|
*
|
||||||
|
* @param array $config The configurator config for a location.
|
||||||
|
* @param string $location The location name in the old settings.
|
||||||
|
*/
|
||||||
|
private function save_config_for_location( array $config, string $location ): void {
|
||||||
|
$this->set_value_if_present( $config, 'layout', "pay_later_{$location}_message_layout" );
|
||||||
|
|
||||||
|
$this->set_value_if_present( $config, 'color', "pay_later_{$location}_message_flex_color" );
|
||||||
|
$this->set_value_if_present( $config, 'ratio', "pay_later_{$location}_message_flex_ratio" );
|
||||||
|
|
||||||
|
$this->set_value_if_present( $config, 'logo-position', "pay_later_{$location}_message_position" );
|
||||||
|
$this->set_value_if_present( $config, 'logo-type', "pay_later_{$location}_message_logo" );
|
||||||
|
$this->set_value_if_present( $config, 'logo-color', "pay_later_{$location}_message_color" );
|
||||||
|
$this->set_value_if_present( $config, 'text-size', "pay_later_{$location}_message_text_size" );
|
||||||
|
$this->set_value_if_present( $config, 'text-color', "pay_later_{$location}_message_color" );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the value in the settings if it is available in the config.
|
||||||
|
*
|
||||||
|
* @param array $config The configurator config.
|
||||||
|
* @param string $key The key in the config.
|
||||||
|
* @param string $settings_key The key in the settings.
|
||||||
|
*/
|
||||||
|
private function set_value_if_present( array $config, string $key, string $settings_key ): void {
|
||||||
|
if ( isset( $config[ $key ] ) ) {
|
||||||
|
$this->settings->set( $settings_key, $config[ $key ] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
145
modules/ppcp-paylater-configurator/src/Factory/ConfigFactory.php
Normal file
145
modules/ppcp-paylater-configurator/src/Factory/ConfigFactory.php
Normal file
|
@ -0,0 +1,145 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* The factory the Pay Later messaging configurator configs.
|
||||||
|
*
|
||||||
|
* @package WooCommerce\PayPalCommerce\PayLaterConfigurator\Endpoint
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace WooCommerce\PayPalCommerce\PayLaterConfigurator\Factory;
|
||||||
|
|
||||||
|
use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class ConfigFactory.
|
||||||
|
*/
|
||||||
|
class ConfigFactory {
|
||||||
|
/**
|
||||||
|
* Returns the configurator config for the given old settings.
|
||||||
|
*
|
||||||
|
* @param Settings $settings The settings.
|
||||||
|
*/
|
||||||
|
public function from_settings( Settings $settings ): array {
|
||||||
|
return array(
|
||||||
|
'cart' => $this->for_location( $settings, 'cart' ),
|
||||||
|
'checkout' => $this->for_location( $settings, 'checkout' ),
|
||||||
|
'product' => $this->for_location( $settings, 'product' ),
|
||||||
|
'shop' => $this->for_location( $settings, 'shop' ),
|
||||||
|
'home' => $this->for_location( $settings, 'home' ),
|
||||||
|
'custom_placement' => array( $this->for_location( $settings, 'woocommerceBlock' ) ),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the configurator config for a location.
|
||||||
|
*
|
||||||
|
* @param Settings $settings The settings.
|
||||||
|
* @param string $location The location name in the old settings.
|
||||||
|
*/
|
||||||
|
private function for_location( Settings $settings, string $location ): array {
|
||||||
|
$selected_locations = $settings->has( 'pay_later_messaging_locations' ) ? $settings->get( 'pay_later_messaging_locations' ) : array();
|
||||||
|
|
||||||
|
switch ( $location ) {
|
||||||
|
case 'shop':
|
||||||
|
case 'home':
|
||||||
|
$config = $this->for_shop_or_home( $settings, $location, $selected_locations );
|
||||||
|
break;
|
||||||
|
case 'woocommerceBlock':
|
||||||
|
$config = $this->for_woocommerce_block( $selected_locations );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$config = $this->for_default_location( $settings, $location, $selected_locations );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $config;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the configurator config for shop, home locations.
|
||||||
|
*
|
||||||
|
* @param Settings $settings The settings.
|
||||||
|
* @param string $location The location.
|
||||||
|
* @param string[] $selected_locations The list of selected locations.
|
||||||
|
* @return array{
|
||||||
|
* layout: string,
|
||||||
|
* color: string,
|
||||||
|
* ratio: string,
|
||||||
|
* status: "disabled"|"enabled",
|
||||||
|
* placement: string
|
||||||
|
* } The configurator config map.
|
||||||
|
*/
|
||||||
|
private function for_shop_or_home( Settings $settings, string $location, array $selected_locations ): array {
|
||||||
|
return array(
|
||||||
|
'layout' => $this->get_or_default( $settings, "pay_later_{$location}_message_layout", 'flex' ),
|
||||||
|
'color' => $this->get_or_default( $settings, "pay_later_{$location}_message_flex_color", 'black' ),
|
||||||
|
'ratio' => $this->get_or_default( $settings, "pay_later_{$location}_message_flex_ratio", '8x1' ),
|
||||||
|
'status' => in_array( $location, $selected_locations, true ) ? 'enabled' : 'disabled',
|
||||||
|
'placement' => $location,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the configurator config for woocommerceBlock location.
|
||||||
|
*
|
||||||
|
* @param array $selected_locations The list of selected locations.
|
||||||
|
* @return array{
|
||||||
|
* status: "disabled"|"enabled",
|
||||||
|
* message_reference: string
|
||||||
|
* } The configurator config map.
|
||||||
|
*/
|
||||||
|
private function for_woocommerce_block( array $selected_locations ): array {
|
||||||
|
return array(
|
||||||
|
'status' => in_array( 'custom_placement', $selected_locations, true ) ? 'enabled' : 'disabled',
|
||||||
|
'message_reference' => 'woocommerceBlock',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the configurator config for default locations.
|
||||||
|
*
|
||||||
|
* @param Settings $settings The settings.
|
||||||
|
* @param string $location The location.
|
||||||
|
* @param string[] $selected_locations The list of selected locations.
|
||||||
|
* @return array{
|
||||||
|
* layout: string,
|
||||||
|
* logo-position: string,
|
||||||
|
* logo-type: string,
|
||||||
|
* text-color: string,
|
||||||
|
* text-size: string,
|
||||||
|
* status: "disabled"|"enabled",
|
||||||
|
* placement: string
|
||||||
|
* } The configurator config map.
|
||||||
|
*/
|
||||||
|
private function for_default_location( Settings $settings, string $location, array $selected_locations ): array {
|
||||||
|
return array(
|
||||||
|
'layout' => $this->get_or_default( $settings, "pay_later_{$location}_message_layout", 'text' ),
|
||||||
|
'logo-position' => $this->get_or_default( $settings, "pay_later_{$location}_message_position", 'left' ),
|
||||||
|
'logo-type' => $this->get_or_default( $settings, "pay_later_{$location}_message_logo", 'inline' ),
|
||||||
|
'text-color' => $this->get_or_default( $settings, "pay_later_{$location}_message_color", 'black' ),
|
||||||
|
'text-size' => $this->get_or_default( $settings, "pay_later_{$location}_message_text_size", '12' ),
|
||||||
|
'status' => in_array( $location, $selected_locations, true ) ? 'enabled' : 'disabled',
|
||||||
|
'placement' => $location,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the settings value or default, if does not exist or not allowed value.
|
||||||
|
*
|
||||||
|
* @param Settings $settings The settings.
|
||||||
|
* @param string $key The key.
|
||||||
|
* @param mixed $default The default value.
|
||||||
|
* @param array|null $allowed_values The list of allowed values, or null if all values are allowed.
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private function get_or_default( Settings $settings, string $key, $default, ?array $allowed_values = null ): string {
|
||||||
|
if ( $settings->has( $key ) ) {
|
||||||
|
$value = $settings->get( $key );
|
||||||
|
if ( ! $allowed_values || in_array( $value, $allowed_values, true ) ) {
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $default;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,135 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* The Pay Later configurator module.
|
||||||
|
*
|
||||||
|
* @package WooCommerce\PayPalCommerce\PayLaterConfigurator
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace WooCommerce\PayPalCommerce\PayLaterConfigurator;
|
||||||
|
|
||||||
|
use WooCommerce\PayPalCommerce\Button\Helper\MessagesApply;
|
||||||
|
use WooCommerce\PayPalCommerce\PayLaterConfigurator\Endpoint\SaveConfig;
|
||||||
|
use WooCommerce\PayPalCommerce\PayLaterConfigurator\Factory\ConfigFactory;
|
||||||
|
use WooCommerce\PayPalCommerce\Vendor\Dhii\Container\ServiceProvider;
|
||||||
|
use WooCommerce\PayPalCommerce\Vendor\Dhii\Modular\Module\ModuleInterface;
|
||||||
|
use WooCommerce\PayPalCommerce\Vendor\Interop\Container\ServiceProviderInterface;
|
||||||
|
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
|
||||||
|
use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class PayLaterConfiguratorModule
|
||||||
|
*/
|
||||||
|
class PayLaterConfiguratorModule implements ModuleInterface {
|
||||||
|
/**
|
||||||
|
* Returns whether the module should be loaded.
|
||||||
|
*/
|
||||||
|
public static function is_enabled(): bool {
|
||||||
|
return apply_filters(
|
||||||
|
// phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
|
||||||
|
'woocommerce.feature-flags.woocommerce_paypal_payments.paylater_configurator_enabled',
|
||||||
|
getenv( 'PCP_PAYLATER_CONFIGURATOR' ) !== '0'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function setup(): ServiceProviderInterface {
|
||||||
|
return new ServiceProvider(
|
||||||
|
require __DIR__ . '/../services.php',
|
||||||
|
require __DIR__ . '/../extensions.php'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function run( ContainerInterface $c ): void {
|
||||||
|
$messages_apply = $c->get( 'button.helper.messages-apply' );
|
||||||
|
assert( $messages_apply instanceof MessagesApply );
|
||||||
|
|
||||||
|
$settings = $c->get( 'wcgateway.settings' );
|
||||||
|
assert( $settings instanceof Settings );
|
||||||
|
|
||||||
|
$vault_enabled = $settings->has( 'vault_enabled' ) && $settings->get( 'vault_enabled' );
|
||||||
|
|
||||||
|
if ( $vault_enabled || ! $messages_apply->for_country() ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
add_action(
|
||||||
|
'wc_ajax_' . SaveConfig::ENDPOINT,
|
||||||
|
static function () use ( $c ) {
|
||||||
|
$endpoint = $c->get( 'paylater-configurator.endpoint.save-config' );
|
||||||
|
assert( $endpoint instanceof SaveConfig );
|
||||||
|
$endpoint->handle_request();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
$current_page_id = $c->get( 'wcgateway.current-ppcp-settings-page-id' );
|
||||||
|
|
||||||
|
if ( $current_page_id !== Settings::PAY_LATER_TAB_ID ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
add_action(
|
||||||
|
'init',
|
||||||
|
static function () use ( $c, $settings ) {
|
||||||
|
wp_enqueue_script(
|
||||||
|
'ppcp-paylater-configurator-lib',
|
||||||
|
'https://www.paypalobjects.com/merchant-library/merchant-configurator.js',
|
||||||
|
array(),
|
||||||
|
$c->get( 'ppcp.asset-version' ),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
wp_enqueue_script(
|
||||||
|
'ppcp-paylater-configurator',
|
||||||
|
$c->get( 'paylater-configurator.url' ) . '/assets/js/paylater-configurator.js',
|
||||||
|
array(),
|
||||||
|
$c->get( 'ppcp.asset-version' ),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
wp_enqueue_style(
|
||||||
|
'ppcp-paylater-configurator-style',
|
||||||
|
$c->get( 'paylater-configurator.url' ) . '/assets/css/paylater-configurator.css',
|
||||||
|
array(),
|
||||||
|
$c->get( 'ppcp.asset-version' )
|
||||||
|
);
|
||||||
|
|
||||||
|
$config_factory = $c->get( 'paylater-configurator.factory.config' );
|
||||||
|
assert( $config_factory instanceof ConfigFactory );
|
||||||
|
|
||||||
|
wp_localize_script(
|
||||||
|
'ppcp-paylater-configurator',
|
||||||
|
'PcpPayLaterConfigurator',
|
||||||
|
array(
|
||||||
|
'ajax' => array(
|
||||||
|
'save_config' => array(
|
||||||
|
'endpoint' => \WC_AJAX::get_endpoint( SaveConfig::ENDPOINT ),
|
||||||
|
'nonce' => wp_create_nonce( SaveConfig::nonce() ),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'config' => $config_factory->from_settings( $settings ),
|
||||||
|
'merchantClientId' => $settings->get( 'client_id' ),
|
||||||
|
'partnerClientId' => $c->get( 'api.partner_merchant_id' ),
|
||||||
|
'publishButtonClassName' => 'ppcp-paylater-configurator-publishButton',
|
||||||
|
'headerClassName' => 'ppcp-paylater-configurator-header',
|
||||||
|
'subheaderClassName' => 'ppcp-paylater-configurator-subheader',
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the key for the module.
|
||||||
|
*
|
||||||
|
* @return string|void
|
||||||
|
*/
|
||||||
|
public function getKey() {
|
||||||
|
}
|
||||||
|
}
|
39
modules/ppcp-paylater-configurator/webpack.config.js
Normal file
39
modules/ppcp-paylater-configurator/webpack.config.js
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
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: {
|
||||||
|
'paylater-configurator': path.resolve('./resources/js/paylater-configurator.js'),
|
||||||
|
'paylater-configurator-style': path.resolve('./resources/css/paylater-configurator.scss'),
|
||||||
|
},
|
||||||
|
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'}
|
||||||
|
]
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
};
|
2201
modules/ppcp-paylater-configurator/yarn.lock
Normal file
2201
modules/ppcp-paylater-configurator/yarn.lock
Normal file
File diff suppressed because it is too large
Load diff
|
@ -196,7 +196,7 @@ class PayPalSubscriptionsModule implements ModuleInterface {
|
||||||
*
|
*
|
||||||
* @psalm-suppress MissingClosureParamType
|
* @psalm-suppress MissingClosureParamType
|
||||||
*/
|
*/
|
||||||
function( $actions, $subscription ): array {
|
function( $actions, $subscription = null ): array {
|
||||||
if ( ! is_array( $actions ) || ! is_a( $subscription, WC_Subscription::class ) ) {
|
if ( ! is_array( $actions ) || ! is_a( $subscription, WC_Subscription::class ) ) {
|
||||||
return $actions;
|
return $actions;
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,7 +114,7 @@ class SubscriptionsApiHandler {
|
||||||
*/
|
*/
|
||||||
public function create_product( WC_Product $product ) {
|
public function create_product( WC_Product $product ) {
|
||||||
try {
|
try {
|
||||||
$subscription_product = $this->products_endpoint->create( $product->get_title(), $this->prepare_description( $product->get_description() ) );
|
$subscription_product = $this->products_endpoint->create( $this->prepare_item_string( $product->get_title() ), $this->prepare_item_string( $product->get_description() ) );
|
||||||
$product->update_meta_data( 'ppcp_subscription_product', $subscription_product->to_array() );
|
$product->update_meta_data( 'ppcp_subscription_product', $subscription_product->to_array() );
|
||||||
$product->save();
|
$product->save();
|
||||||
} catch ( RuntimeException $exception ) {
|
} catch ( RuntimeException $exception ) {
|
||||||
|
@ -169,7 +169,7 @@ class SubscriptionsApiHandler {
|
||||||
$catalog_product_name = $catalog_product->name() ?: '';
|
$catalog_product_name = $catalog_product->name() ?: '';
|
||||||
$catalog_product_description = $catalog_product->description() ?: '';
|
$catalog_product_description = $catalog_product->description() ?: '';
|
||||||
|
|
||||||
$wc_product_description = $this->prepare_description( $product->get_description() ) ?: $product->get_title();
|
$wc_product_description = $this->prepare_item_string( $product->get_description() ) ?: $this->prepare_item_string( $product->get_title() );
|
||||||
|
|
||||||
if ( $catalog_product_name !== $product->get_title() || $catalog_product_description !== $wc_product_description ) {
|
if ( $catalog_product_name !== $product->get_title() || $catalog_product_description !== $wc_product_description ) {
|
||||||
$data = array();
|
$data = array();
|
||||||
|
|
|
@ -12,7 +12,7 @@ import ErrorHandler from "../../../ppcp-button/resources/js/modules/ErrorHandler
|
||||||
import {cardFieldStyles} from "../../../ppcp-button/resources/js/modules/Helper/CardFieldsHelper";
|
import {cardFieldStyles} from "../../../ppcp-button/resources/js/modules/Helper/CardFieldsHelper";
|
||||||
|
|
||||||
const errorHandler = new ErrorHandler(
|
const errorHandler = new ErrorHandler(
|
||||||
PayPalCommerceGateway.labels.error.generic,
|
ppcp_add_payment_method.labels.error.generic,
|
||||||
document.querySelector('.woocommerce-notices-wrapper')
|
document.querySelector('.woocommerce-notices-wrapper')
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -9,9 +9,9 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace WooCommerce\PayPalCommerce\SavePaymentMethods;
|
namespace WooCommerce\PayPalCommerce\SavePaymentMethods;
|
||||||
|
|
||||||
use WooCommerce\PayPalCommerce\SavePaymentMethods\Endpoint\CaptureCardPayment;
|
|
||||||
use WooCommerce\PayPalCommerce\SavePaymentMethods\Endpoint\CreatePaymentToken;
|
use WooCommerce\PayPalCommerce\SavePaymentMethods\Endpoint\CreatePaymentToken;
|
||||||
use WooCommerce\PayPalCommerce\SavePaymentMethods\Endpoint\CreateSetupToken;
|
use WooCommerce\PayPalCommerce\SavePaymentMethods\Endpoint\CreateSetupToken;
|
||||||
|
use WooCommerce\PayPalCommerce\SavePaymentMethods\Endpoint\CreatePaymentTokenForGuest;
|
||||||
use WooCommerce\PayPalCommerce\SavePaymentMethods\Helper\SavePaymentMethodsApplies;
|
use WooCommerce\PayPalCommerce\SavePaymentMethods\Helper\SavePaymentMethodsApplies;
|
||||||
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
|
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
|
||||||
|
|
||||||
|
@ -57,6 +57,30 @@ return array(
|
||||||
'TWD',
|
'TWD',
|
||||||
'USD',
|
'USD',
|
||||||
),
|
),
|
||||||
|
'AT' => array(
|
||||||
|
'AUD',
|
||||||
|
'BRL',
|
||||||
|
'CAD',
|
||||||
|
'CHF',
|
||||||
|
'CZK',
|
||||||
|
'DKK',
|
||||||
|
'EUR',
|
||||||
|
'GBP',
|
||||||
|
'HKD',
|
||||||
|
'HUF',
|
||||||
|
'ILS',
|
||||||
|
'JPY',
|
||||||
|
'MXN',
|
||||||
|
'NOK',
|
||||||
|
'NZD',
|
||||||
|
'PHP',
|
||||||
|
'PLN',
|
||||||
|
'SEK',
|
||||||
|
'SGD',
|
||||||
|
'THB',
|
||||||
|
'TWD',
|
||||||
|
'USD',
|
||||||
|
),
|
||||||
'BE' => array(
|
'BE' => array(
|
||||||
'AUD',
|
'AUD',
|
||||||
'BRL',
|
'BRL',
|
||||||
|
@ -345,6 +369,30 @@ return array(
|
||||||
'TWD',
|
'TWD',
|
||||||
'USD',
|
'USD',
|
||||||
),
|
),
|
||||||
|
'IE' => array(
|
||||||
|
'AUD',
|
||||||
|
'BRL',
|
||||||
|
'CAD',
|
||||||
|
'CHF',
|
||||||
|
'CZK',
|
||||||
|
'DKK',
|
||||||
|
'EUR',
|
||||||
|
'GBP',
|
||||||
|
'HKD',
|
||||||
|
'HUF',
|
||||||
|
'ILS',
|
||||||
|
'JPY',
|
||||||
|
'MXN',
|
||||||
|
'NOK',
|
||||||
|
'NZD',
|
||||||
|
'PHP',
|
||||||
|
'PLN',
|
||||||
|
'SEK',
|
||||||
|
'SGD',
|
||||||
|
'THB',
|
||||||
|
'TWD',
|
||||||
|
'USD',
|
||||||
|
),
|
||||||
'IT' => array(
|
'IT' => array(
|
||||||
'AUD',
|
'AUD',
|
||||||
'BRL',
|
'BRL',
|
||||||
|
@ -393,6 +441,30 @@ return array(
|
||||||
'TWD',
|
'TWD',
|
||||||
'USD',
|
'USD',
|
||||||
),
|
),
|
||||||
|
'LI' => array(
|
||||||
|
'AUD',
|
||||||
|
'BRL',
|
||||||
|
'CAD',
|
||||||
|
'CHF',
|
||||||
|
'CZK',
|
||||||
|
'DKK',
|
||||||
|
'EUR',
|
||||||
|
'GBP',
|
||||||
|
'HKD',
|
||||||
|
'HUF',
|
||||||
|
'ILS',
|
||||||
|
'JPY',
|
||||||
|
'MXN',
|
||||||
|
'NOK',
|
||||||
|
'NZD',
|
||||||
|
'PHP',
|
||||||
|
'PLN',
|
||||||
|
'SEK',
|
||||||
|
'SGD',
|
||||||
|
'THB',
|
||||||
|
'TWD',
|
||||||
|
'USD',
|
||||||
|
),
|
||||||
'LT' => array(
|
'LT' => array(
|
||||||
'AUD',
|
'AUD',
|
||||||
'BRL',
|
'BRL',
|
||||||
|
@ -465,6 +537,30 @@ return array(
|
||||||
'TWD',
|
'TWD',
|
||||||
'USD',
|
'USD',
|
||||||
),
|
),
|
||||||
|
'NO' => array(
|
||||||
|
'AUD',
|
||||||
|
'BRL',
|
||||||
|
'CAD',
|
||||||
|
'CHF',
|
||||||
|
'CZK',
|
||||||
|
'DKK',
|
||||||
|
'EUR',
|
||||||
|
'GBP',
|
||||||
|
'HKD',
|
||||||
|
'HUF',
|
||||||
|
'ILS',
|
||||||
|
'JPY',
|
||||||
|
'MXN',
|
||||||
|
'NOK',
|
||||||
|
'NZD',
|
||||||
|
'PHP',
|
||||||
|
'PLN',
|
||||||
|
'SEK',
|
||||||
|
'SGD',
|
||||||
|
'THB',
|
||||||
|
'TWD',
|
||||||
|
'USD',
|
||||||
|
),
|
||||||
'NL' => array(
|
'NL' => array(
|
||||||
'AUD',
|
'AUD',
|
||||||
'BRL',
|
'BRL',
|
||||||
|
@ -709,30 +805,17 @@ return array(
|
||||||
$container->get( 'api.endpoint.payment-method-tokens' )
|
$container->get( 'api.endpoint.payment-method-tokens' )
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
'save-payment-methods.wc-payment-tokens' => static function( ContainerInterface $container ): WooCommercePaymentTokens {
|
|
||||||
return new WooCommercePaymentTokens(
|
|
||||||
$container->get( 'vaulting.payment-token-helper' ),
|
|
||||||
$container->get( 'vaulting.payment-token-factory' ),
|
|
||||||
$container->get( 'woocommerce.logger.woocommerce' )
|
|
||||||
);
|
|
||||||
},
|
|
||||||
'save-payment-methods.endpoint.create-payment-token' => static function ( ContainerInterface $container ): CreatePaymentToken {
|
'save-payment-methods.endpoint.create-payment-token' => static function ( ContainerInterface $container ): CreatePaymentToken {
|
||||||
return new CreatePaymentToken(
|
return new CreatePaymentToken(
|
||||||
$container->get( 'button.request-data' ),
|
$container->get( 'button.request-data' ),
|
||||||
$container->get( 'api.endpoint.payment-method-tokens' ),
|
$container->get( 'api.endpoint.payment-method-tokens' ),
|
||||||
$container->get( 'save-payment-methods.wc-payment-tokens' )
|
$container->get( 'vaulting.wc-payment-tokens' )
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
'save-payment-methods.endpoint.capture-card-payment' => static function( ContainerInterface $container ): CaptureCardPayment {
|
'save-payment-methods.endpoint.create-payment-token-for-guest' => static function ( ContainerInterface $container ): CreatePaymentTokenForGuest {
|
||||||
return new CaptureCardPayment(
|
return new CreatePaymentTokenForGuest(
|
||||||
$container->get( 'button.request-data' ),
|
$container->get( 'button.request-data' ),
|
||||||
$container->get( 'api.host' ),
|
$container->get( 'api.endpoint.payment-method-tokens' )
|
||||||
$container->get( 'api.bearer' ),
|
|
||||||
$container->get( 'api.factory.order' ),
|
|
||||||
$container->get( 'api.factory.purchase-unit' ),
|
|
||||||
$container->get( 'api.endpoint.order' ),
|
|
||||||
$container->get( 'session.handler' ),
|
|
||||||
$container->get( 'woocommerce.logger.woocommerce' )
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,219 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* The Capture Card Payment endpoint.
|
|
||||||
*
|
|
||||||
* @package WooCommerce\PayPalCommerce\ApiClient\Endpoint
|
|
||||||
*/
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace WooCommerce\PayPalCommerce\SavePaymentMethods\Endpoint;
|
|
||||||
|
|
||||||
use Psr\Log\LoggerInterface;
|
|
||||||
use RuntimeException;
|
|
||||||
use stdClass;
|
|
||||||
use WC_Payment_Tokens;
|
|
||||||
use WooCommerce\PayPalCommerce\ApiClient\Authentication\Bearer;
|
|
||||||
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
|
|
||||||
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\RequestTrait;
|
|
||||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\PurchaseUnit;
|
|
||||||
use WooCommerce\PayPalCommerce\ApiClient\Factory\OrderFactory;
|
|
||||||
use WooCommerce\PayPalCommerce\ApiClient\Factory\PurchaseUnitFactory;
|
|
||||||
use WooCommerce\PayPalCommerce\Button\Endpoint\EndpointInterface;
|
|
||||||
use WooCommerce\PayPalCommerce\Button\Endpoint\RequestData;
|
|
||||||
use WooCommerce\PayPalCommerce\Session\SessionHandler;
|
|
||||||
use WP_Error;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class CaptureCardPayment
|
|
||||||
*/
|
|
||||||
class CaptureCardPayment implements EndpointInterface {
|
|
||||||
|
|
||||||
use RequestTrait;
|
|
||||||
|
|
||||||
const ENDPOINT = 'ppc-capture-card-payment';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The request data.
|
|
||||||
*
|
|
||||||
* @var RequestData
|
|
||||||
*/
|
|
||||||
private $request_data;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The host.
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
private $host;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The bearer.
|
|
||||||
*
|
|
||||||
* @var Bearer
|
|
||||||
*/
|
|
||||||
private $bearer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The order factory.
|
|
||||||
*
|
|
||||||
* @var OrderFactory
|
|
||||||
*/
|
|
||||||
private $order_factory;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The purchase unit factory.
|
|
||||||
*
|
|
||||||
* @var PurchaseUnitFactory
|
|
||||||
*/
|
|
||||||
private $purchase_unit_factory;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The order endpoint.
|
|
||||||
*
|
|
||||||
* @var OrderEndpoint
|
|
||||||
*/
|
|
||||||
private $order_endpoint;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The session handler.
|
|
||||||
*
|
|
||||||
* @var SessionHandler
|
|
||||||
*/
|
|
||||||
private $session_handler;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The logger.
|
|
||||||
*
|
|
||||||
* @var LoggerInterface
|
|
||||||
*/
|
|
||||||
private $logger;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* CaptureCardPayment constructor.
|
|
||||||
*
|
|
||||||
* @param RequestData $request_data The request data.
|
|
||||||
* @param string $host The host.
|
|
||||||
* @param Bearer $bearer The bearer.
|
|
||||||
* @param OrderFactory $order_factory The order factory.
|
|
||||||
* @param PurchaseUnitFactory $purchase_unit_factory The purchase unit factory.
|
|
||||||
* @param OrderEndpoint $order_endpoint The order endpoint.
|
|
||||||
* @param SessionHandler $session_handler The session handler.
|
|
||||||
* @param LoggerInterface $logger The logger.
|
|
||||||
*/
|
|
||||||
public function __construct(
|
|
||||||
RequestData $request_data,
|
|
||||||
string $host,
|
|
||||||
Bearer $bearer,
|
|
||||||
OrderFactory $order_factory,
|
|
||||||
PurchaseUnitFactory $purchase_unit_factory,
|
|
||||||
OrderEndpoint $order_endpoint,
|
|
||||||
SessionHandler $session_handler,
|
|
||||||
LoggerInterface $logger
|
|
||||||
) {
|
|
||||||
$this->request_data = $request_data;
|
|
||||||
$this->host = $host;
|
|
||||||
$this->bearer = $bearer;
|
|
||||||
$this->order_factory = $order_factory;
|
|
||||||
$this->purchase_unit_factory = $purchase_unit_factory;
|
|
||||||
$this->order_endpoint = $order_endpoint;
|
|
||||||
$this->logger = $logger;
|
|
||||||
$this->session_handler = $session_handler;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the nonce.
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public static function nonce(): string {
|
|
||||||
return self::ENDPOINT;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles the request.
|
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function handle_request(): bool {
|
|
||||||
$data = $this->request_data->read_request( $this->nonce() );
|
|
||||||
|
|
||||||
$tokens = WC_Payment_Tokens::get_customer_tokens( get_current_user_id() );
|
|
||||||
foreach ( $tokens as $token ) {
|
|
||||||
if ( $token->get_id() === (int) $data['payment_token'] ) {
|
|
||||||
try {
|
|
||||||
$order = $this->create_order( $token->get_token() );
|
|
||||||
|
|
||||||
$id = $order->id ?? '';
|
|
||||||
$status = $order->status ?? '';
|
|
||||||
$payment_source = isset( $order->payment_source->card ) ? 'card' : '';
|
|
||||||
if ( $id && $status && $payment_source ) {
|
|
||||||
WC()->session->set(
|
|
||||||
'ppcp_saved_payment_card',
|
|
||||||
array(
|
|
||||||
'order_id' => $id,
|
|
||||||
'status' => $status,
|
|
||||||
'payment_source' => $payment_source,
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
wp_send_json_success();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} catch ( RuntimeException $exception ) {
|
|
||||||
wp_send_json_error();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
wp_send_json_error();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates PayPal order from the given card vault id.
|
|
||||||
*
|
|
||||||
* @param string $vault_id Vault id.
|
|
||||||
* @return stdClass
|
|
||||||
* @throws RuntimeException When request fails.
|
|
||||||
*/
|
|
||||||
private function create_order( string $vault_id ): stdClass {
|
|
||||||
$items = array( $this->purchase_unit_factory->from_wc_cart() );
|
|
||||||
|
|
||||||
$data = array(
|
|
||||||
'intent' => 'CAPTURE',
|
|
||||||
'purchase_units' => array_map(
|
|
||||||
static function ( PurchaseUnit $item ): array {
|
|
||||||
return $item->to_array( true, false );
|
|
||||||
},
|
|
||||||
$items
|
|
||||||
),
|
|
||||||
'payment_source' => array(
|
|
||||||
'card' => array(
|
|
||||||
'vault_id' => $vault_id,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
$bearer = $this->bearer->bearer();
|
|
||||||
$url = trailingslashit( $this->host ) . 'v2/checkout/orders';
|
|
||||||
$args = array(
|
|
||||||
'method' => 'POST',
|
|
||||||
'headers' => array(
|
|
||||||
'Authorization' => 'Bearer ' . $bearer->token(),
|
|
||||||
'Content-Type' => 'application/json',
|
|
||||||
'PayPal-Request-Id' => uniqid( 'ppcp-', true ),
|
|
||||||
),
|
|
||||||
'body' => wp_json_encode( $data ),
|
|
||||||
);
|
|
||||||
|
|
||||||
$response = $this->request( $url, $args );
|
|
||||||
if ( $response instanceof WP_Error ) {
|
|
||||||
throw new RuntimeException( $response->get_error_message() );
|
|
||||||
}
|
|
||||||
|
|
||||||
return json_decode( $response['body'] );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -14,9 +14,7 @@ use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentMethodTokensEndpoint;
|
||||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentSource;
|
use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentSource;
|
||||||
use WooCommerce\PayPalCommerce\Button\Endpoint\EndpointInterface;
|
use WooCommerce\PayPalCommerce\Button\Endpoint\EndpointInterface;
|
||||||
use WooCommerce\PayPalCommerce\Button\Endpoint\RequestData;
|
use WooCommerce\PayPalCommerce\Button\Endpoint\RequestData;
|
||||||
use WooCommerce\PayPalCommerce\SavePaymentMethods\WooCommercePaymentTokens;
|
use WooCommerce\PayPalCommerce\Vaulting\WooCommercePaymentTokens;
|
||||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway;
|
|
||||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class CreatePaymentToken
|
* Class CreatePaymentToken
|
||||||
|
@ -96,7 +94,7 @@ class CreatePaymentToken implements EndpointInterface {
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
$result = $this->payment_method_tokens_endpoint->payment_tokens( $payment_source );
|
$result = $this->payment_method_tokens_endpoint->create_payment_token( $payment_source );
|
||||||
|
|
||||||
if ( is_user_logged_in() && isset( $result->customer->id ) ) {
|
if ( is_user_logged_in() && isset( $result->customer->id ) ) {
|
||||||
$current_user_id = get_current_user_id();
|
$current_user_id = get_current_user_id();
|
||||||
|
|
|
@ -0,0 +1,90 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Create payment token for guest user.
|
||||||
|
*
|
||||||
|
* @package WooCommerce\PayPalCommerce\ApiClient\Endpoint
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace WooCommerce\PayPalCommerce\SavePaymentMethods\Endpoint;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
|
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentMethodTokensEndpoint;
|
||||||
|
use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentSource;
|
||||||
|
use WooCommerce\PayPalCommerce\Button\Endpoint\EndpointInterface;
|
||||||
|
use WooCommerce\PayPalCommerce\Button\Endpoint\RequestData;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class UpdateCustomerId
|
||||||
|
*/
|
||||||
|
class CreatePaymentTokenForGuest implements EndpointInterface {
|
||||||
|
|
||||||
|
const ENDPOINT = 'ppc-update-customer-id';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The request data.
|
||||||
|
*
|
||||||
|
* @var RequestData
|
||||||
|
*/
|
||||||
|
private $request_data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The payment method tokens endpoint.
|
||||||
|
*
|
||||||
|
* @var PaymentMethodTokensEndpoint
|
||||||
|
*/
|
||||||
|
private $payment_method_tokens_endpoint;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CreatePaymentToken constructor.
|
||||||
|
*
|
||||||
|
* @param RequestData $request_data The request data.
|
||||||
|
* @param PaymentMethodTokensEndpoint $payment_method_tokens_endpoint The payment method tokens endpoint.
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
RequestData $request_data,
|
||||||
|
PaymentMethodTokensEndpoint $payment_method_tokens_endpoint
|
||||||
|
) {
|
||||||
|
$this->request_data = $request_data;
|
||||||
|
$this->payment_method_tokens_endpoint = $payment_method_tokens_endpoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the nonce.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function nonce(): string {
|
||||||
|
return self::ENDPOINT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the request.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @throws Exception On Error.
|
||||||
|
*/
|
||||||
|
public function handle_request(): bool {
|
||||||
|
$data = $this->request_data->read_request( $this->nonce() );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Suppress ArgumentTypeCoercion
|
||||||
|
*
|
||||||
|
* @psalm-suppress ArgumentTypeCoercion
|
||||||
|
*/
|
||||||
|
$payment_source = new PaymentSource(
|
||||||
|
'token',
|
||||||
|
(object) array(
|
||||||
|
'id' => $data['vault_setup_token'],
|
||||||
|
'type' => 'SETUP_TOKEN',
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$result = $this->payment_method_tokens_endpoint->create_payment_token( $payment_source );
|
||||||
|
WC()->session->set( 'ppcp_guest_payment_for_free_trial', $result );
|
||||||
|
|
||||||
|
wp_send_json_success();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,9 +19,10 @@ use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentSource;
|
||||||
use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
|
use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
|
||||||
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||||
use WooCommerce\PayPalCommerce\Button\Helper\ContextTrait;
|
use WooCommerce\PayPalCommerce\Button\Helper\ContextTrait;
|
||||||
use WooCommerce\PayPalCommerce\SavePaymentMethods\Endpoint\CaptureCardPayment;
|
|
||||||
use WooCommerce\PayPalCommerce\SavePaymentMethods\Endpoint\CreatePaymentToken;
|
use WooCommerce\PayPalCommerce\SavePaymentMethods\Endpoint\CreatePaymentToken;
|
||||||
|
use WooCommerce\PayPalCommerce\SavePaymentMethods\Endpoint\CreatePaymentTokenForGuest;
|
||||||
use WooCommerce\PayPalCommerce\SavePaymentMethods\Endpoint\CreateSetupToken;
|
use WooCommerce\PayPalCommerce\SavePaymentMethods\Endpoint\CreateSetupToken;
|
||||||
|
use WooCommerce\PayPalCommerce\Vaulting\WooCommercePaymentTokens;
|
||||||
use WooCommerce\PayPalCommerce\Vendor\Dhii\Container\ServiceProvider;
|
use WooCommerce\PayPalCommerce\Vendor\Dhii\Container\ServiceProvider;
|
||||||
use WooCommerce\PayPalCommerce\Vendor\Dhii\Modular\Module\ModuleInterface;
|
use WooCommerce\PayPalCommerce\Vendor\Dhii\Modular\Module\ModuleInterface;
|
||||||
use WooCommerce\PayPalCommerce\Vendor\Interop\Container\ServiceProviderInterface;
|
use WooCommerce\PayPalCommerce\Vendor\Interop\Container\ServiceProviderInterface;
|
||||||
|
@ -89,14 +90,7 @@ class SavePaymentMethodsModule implements ModuleInterface {
|
||||||
$logger = $c->get( 'woocommerce.logger.woocommerce' );
|
$logger = $c->get( 'woocommerce.logger.woocommerce' );
|
||||||
assert( $logger instanceof LoggerInterface );
|
assert( $logger instanceof LoggerInterface );
|
||||||
|
|
||||||
$localized_script_data = $this->add_id_token_to_script_data( $api, $logger, $localized_script_data );
|
return $this->add_id_token_to_script_data( $api, $logger, $localized_script_data );
|
||||||
|
|
||||||
$localized_script_data['ajax']['capture_card_payment'] = array(
|
|
||||||
'endpoint' => \WC_AJAX::get_endpoint( CaptureCardPayment::ENDPOINT ),
|
|
||||||
'nonce' => wp_create_nonce( CaptureCardPayment::nonce() ),
|
|
||||||
);
|
|
||||||
|
|
||||||
return $localized_script_data;
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -148,6 +142,21 @@ class SavePaymentMethodsModule implements ModuleInterface {
|
||||||
'vault' => array(
|
'vault' => array(
|
||||||
'store_in_vault' => 'ON_SUCCESS',
|
'store_in_vault' => 'ON_SUCCESS',
|
||||||
'usage_type' => 'MERCHANT',
|
'usage_type' => 'MERCHANT',
|
||||||
|
'permit_multiple_payment_tokens' => apply_filters( 'woocommerce_paypal_payments_permit_multiple_payment_tokens', false ),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} elseif ( $funding_source && $funding_source === 'apple_pay' ) {
|
||||||
|
$data['payment_source'] = array(
|
||||||
|
'apple_pay' => array(
|
||||||
|
'stored_credential' => array(
|
||||||
|
'payment_initiator' => 'CUSTOMER',
|
||||||
|
'payment_type' => 'RECURRING',
|
||||||
|
),
|
||||||
|
'attributes' => array(
|
||||||
|
'vault' => array(
|
||||||
|
'store_in_vault' => 'ON_SUCCESS',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -159,6 +168,7 @@ class SavePaymentMethodsModule implements ModuleInterface {
|
||||||
'vault' => array(
|
'vault' => array(
|
||||||
'store_in_vault' => 'ON_SUCCESS',
|
'store_in_vault' => 'ON_SUCCESS',
|
||||||
'usage_type' => 'MERCHANT',
|
'usage_type' => 'MERCHANT',
|
||||||
|
'permit_multiple_payment_tokens' => apply_filters( 'woocommerce_paypal_payments_permit_multiple_payment_tokens', false ),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -188,7 +198,7 @@ class SavePaymentMethodsModule implements ModuleInterface {
|
||||||
|
|
||||||
update_user_meta( $wc_order->get_customer_id(), '_ppcp_target_customer_id', $customer_id );
|
update_user_meta( $wc_order->get_customer_id(), '_ppcp_target_customer_id', $customer_id );
|
||||||
|
|
||||||
$wc_payment_tokens = $c->get( 'save-payment-methods.wc-payment-tokens' );
|
$wc_payment_tokens = $c->get( 'vaulting.wc-payment-tokens' );
|
||||||
assert( $wc_payment_tokens instanceof WooCommercePaymentTokens );
|
assert( $wc_payment_tokens instanceof WooCommercePaymentTokens );
|
||||||
|
|
||||||
if ( $wc_order->get_payment_method() === CreditCardGateway::ID ) {
|
if ( $wc_order->get_payment_method() === CreditCardGateway::ID ) {
|
||||||
|
@ -207,11 +217,29 @@ class SavePaymentMethodsModule implements ModuleInterface {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( $wc_order->get_payment_method() === PayPalGateway::ID ) {
|
if ( $wc_order->get_payment_method() === PayPalGateway::ID ) {
|
||||||
$wc_payment_tokens->create_payment_token_paypal(
|
switch ( $payment_source->name() ) {
|
||||||
$wc_order->get_customer_id(),
|
case 'venmo':
|
||||||
$token_id,
|
$wc_payment_tokens->create_payment_token_venmo(
|
||||||
$payment_source->properties()->email_address ?? ''
|
$wc_order->get_customer_id(),
|
||||||
);
|
$token_id,
|
||||||
|
$payment_source->properties()->email_address ?? ''
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 'apple_pay':
|
||||||
|
$wc_payment_tokens->create_payment_token_applepay(
|
||||||
|
$wc_order->get_customer_id(),
|
||||||
|
$token_id
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 'paypal':
|
||||||
|
default:
|
||||||
|
$wc_payment_tokens->create_payment_token_paypal(
|
||||||
|
$wc_order->get_customer_id(),
|
||||||
|
$token_id,
|
||||||
|
$payment_source->properties()->email_address ?? ''
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -254,7 +282,11 @@ class SavePaymentMethodsModule implements ModuleInterface {
|
||||||
|
|
||||||
$settings = $c->get( 'wcgateway.settings' );
|
$settings = $c->get( 'wcgateway.settings' );
|
||||||
assert( $settings instanceof Settings );
|
assert( $settings instanceof Settings );
|
||||||
$verification_method = $settings->has( '3d_secure_contingency' ) ? $settings->get( '3d_secure_contingency' ) : '';
|
|
||||||
|
$verification_method =
|
||||||
|
$settings->has( '3d_secure_contingency' )
|
||||||
|
? apply_filters( 'woocommerce_paypal_payments_three_d_secure_contingency', $settings->get( '3d_secure_contingency' ) )
|
||||||
|
: '';
|
||||||
|
|
||||||
$change_payment_method = wc_clean( wp_unslash( $_GET['change_payment_method'] ?? '' ) ); // phpcs:ignore WordPress.Security.NonceVerification
|
$change_payment_method = wc_clean( wp_unslash( $_GET['change_payment_method'] ?? '' ) ); // phpcs:ignore WordPress.Security.NonceVerification
|
||||||
|
|
||||||
|
@ -285,6 +317,14 @@ class SavePaymentMethodsModule implements ModuleInterface {
|
||||||
'nonce' => wp_create_nonce( SubscriptionChangePaymentMethod::nonce() ),
|
'nonce' => wp_create_nonce( SubscriptionChangePaymentMethod::nonce() ),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
'labels' => array(
|
||||||
|
'error' => array(
|
||||||
|
'generic' => __(
|
||||||
|
'Something went wrong. Please try again or choose another payment source.',
|
||||||
|
'woocommerce-paypal-payments'
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
} catch ( RuntimeException $exception ) {
|
} catch ( RuntimeException $exception ) {
|
||||||
|
@ -332,6 +372,16 @@ class SavePaymentMethodsModule implements ModuleInterface {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
add_action(
|
||||||
|
'wc_ajax_' . CreatePaymentTokenForGuest::ENDPOINT,
|
||||||
|
static function () use ( $c ) {
|
||||||
|
$endpoint = $c->get( 'save-payment-methods.endpoint.create-payment-token-for-guest' );
|
||||||
|
assert( $endpoint instanceof CreatePaymentTokenForGuest );
|
||||||
|
|
||||||
|
$endpoint->handle_request();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
add_action(
|
add_action(
|
||||||
'woocommerce_paypal_payments_before_delete_payment_token',
|
'woocommerce_paypal_payments_before_delete_payment_token',
|
||||||
function( string $token_id ) use ( $c ) {
|
function( string $token_id ) use ( $c ) {
|
||||||
|
@ -368,16 +418,6 @@ class SavePaymentMethodsModule implements ModuleInterface {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
add_action(
|
|
||||||
'wc_ajax_' . CaptureCardPayment::ENDPOINT,
|
|
||||||
static function () use ( $c ) {
|
|
||||||
$endpoint = $c->get( 'save-payment-methods.endpoint.capture-card-payment' );
|
|
||||||
assert( $endpoint instanceof CaptureCardPayment );
|
|
||||||
|
|
||||||
$endpoint->handle_request();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
add_filter(
|
add_filter(
|
||||||
'woocommerce_paypal_payments_save_payment_methods_eligible',
|
'woocommerce_paypal_payments_save_payment_methods_eligible',
|
||||||
function() {
|
function() {
|
||||||
|
|
|
@ -1,148 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* Service to create WC Payment Tokens.
|
|
||||||
*
|
|
||||||
* @package WooCommerce\PayPalCommerce\Applepay
|
|
||||||
*/
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace WooCommerce\PayPalCommerce\SavePaymentMethods;
|
|
||||||
|
|
||||||
use Exception;
|
|
||||||
use Psr\Log\LoggerInterface;
|
|
||||||
use stdClass;
|
|
||||||
use WC_Payment_Token_CC;
|
|
||||||
use WC_Payment_Tokens;
|
|
||||||
use WooCommerce\PayPalCommerce\Vaulting\PaymentTokenFactory;
|
|
||||||
use WooCommerce\PayPalCommerce\Vaulting\PaymentTokenHelper;
|
|
||||||
use WooCommerce\PayPalCommerce\Vaulting\PaymentTokenPayPal;
|
|
||||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway;
|
|
||||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class WooCommercePaymentTokens
|
|
||||||
*/
|
|
||||||
class WooCommercePaymentTokens {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The payment token helper.
|
|
||||||
*
|
|
||||||
* @var PaymentTokenHelper
|
|
||||||
*/
|
|
||||||
private $payment_token_helper;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The payment token factory.
|
|
||||||
*
|
|
||||||
* @var PaymentTokenFactory
|
|
||||||
*/
|
|
||||||
private $payment_token_factory;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The logger.
|
|
||||||
*
|
|
||||||
* @var LoggerInterface
|
|
||||||
*/
|
|
||||||
private $logger;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* WooCommercePaymentTokens constructor.
|
|
||||||
*
|
|
||||||
* @param PaymentTokenHelper $payment_token_helper The payment token helper.
|
|
||||||
* @param PaymentTokenFactory $payment_token_factory The payment token factory.
|
|
||||||
* @param LoggerInterface $logger The logger.
|
|
||||||
*/
|
|
||||||
public function __construct(
|
|
||||||
PaymentTokenHelper $payment_token_helper,
|
|
||||||
PaymentTokenFactory $payment_token_factory,
|
|
||||||
LoggerInterface $logger
|
|
||||||
) {
|
|
||||||
$this->payment_token_helper = $payment_token_helper;
|
|
||||||
$this->payment_token_factory = $payment_token_factory;
|
|
||||||
$this->logger = $logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a WC Payment Token for PayPal payment.
|
|
||||||
*
|
|
||||||
* @param int $customer_id The WC customer ID.
|
|
||||||
* @param string $token The PayPal payment token.
|
|
||||||
* @param string $email The PayPal customer email.
|
|
||||||
*
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function create_payment_token_paypal(
|
|
||||||
int $customer_id,
|
|
||||||
string $token,
|
|
||||||
string $email
|
|
||||||
): int {
|
|
||||||
|
|
||||||
$wc_tokens = WC_Payment_Tokens::get_customer_tokens( $customer_id, PayPalGateway::ID );
|
|
||||||
if ( $this->payment_token_helper->token_exist( $wc_tokens, $token ) ) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
$payment_token_paypal = $this->payment_token_factory->create( 'paypal' );
|
|
||||||
assert( $payment_token_paypal instanceof PaymentTokenPayPal );
|
|
||||||
|
|
||||||
$payment_token_paypal->set_token( $token );
|
|
||||||
$payment_token_paypal->set_user_id( $customer_id );
|
|
||||||
$payment_token_paypal->set_gateway_id( PayPalGateway::ID );
|
|
||||||
|
|
||||||
if ( $email && is_email( $email ) ) {
|
|
||||||
$payment_token_paypal->set_email( $email );
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
$payment_token_paypal->save();
|
|
||||||
} catch ( Exception $exception ) {
|
|
||||||
$this->logger->error(
|
|
||||||
"Could not create WC payment token PayPal for customer {$customer_id}. " . $exception->getMessage()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $payment_token_paypal->get_id();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a WC Payment Token for Credit Card payment.
|
|
||||||
*
|
|
||||||
* @param int $customer_id The WC customer ID.
|
|
||||||
* @param stdClass $payment_token The Credit Card payment token.
|
|
||||||
*
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function create_payment_token_card( int $customer_id, stdClass $payment_token ): int {
|
|
||||||
$wc_tokens = WC_Payment_Tokens::get_customer_tokens( $customer_id, CreditCardGateway::ID );
|
|
||||||
if ( $this->payment_token_helper->token_exist( $wc_tokens, $payment_token->id ) ) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
$token = new WC_Payment_Token_CC();
|
|
||||||
$token->set_token( $payment_token->id );
|
|
||||||
$token->set_user_id( get_current_user_id() );
|
|
||||||
$token->set_gateway_id( CreditCardGateway::ID );
|
|
||||||
|
|
||||||
$token->set_last4( $payment_token->payment_source->card->last_digits ?? '' );
|
|
||||||
$expiry = explode( '-', $payment_token->payment_source->card->expiry ?? '' );
|
|
||||||
$token->set_expiry_year( $expiry[0] ?? '' );
|
|
||||||
$token->set_expiry_month( $expiry[1] ?? '' );
|
|
||||||
|
|
||||||
$brand = $payment_token->payment_source->card->brand ?? __( 'N/A', 'woocommerce-paypal-payments' );
|
|
||||||
if ( $brand ) {
|
|
||||||
$token->set_card_type( $brand );
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
$token->save();
|
|
||||||
} catch ( Exception $exception ) {
|
|
||||||
$this->logger->error(
|
|
||||||
"Could not create WC payment token card for customer {$customer_id}. " . $exception->getMessage()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
$token->save();
|
|
||||||
return $token->get_id();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -126,6 +126,10 @@ class PaymentTokenChecker {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( ! in_array( $wc_order->get_payment_method(), array( PayPalGateway::ID, CreditCardGateway::ID, CardButtonGateway::ID ), true ) ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if ( $wc_order->get_status() === 'processing' || 'capture' !== $intent ) {
|
if ( $wc_order->get_status() === 'processing' || 'capture' !== $intent ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,6 +78,8 @@ class StatusReportModule implements ModuleInterface {
|
||||||
|
|
||||||
$had_ppec_plugin = PPECHelper::is_plugin_configured();
|
$had_ppec_plugin = PPECHelper::is_plugin_configured();
|
||||||
|
|
||||||
|
$subscription_mode_options = $c->get( 'wcgateway.settings.fields.subscriptions_mode_options' );
|
||||||
|
|
||||||
$items = array(
|
$items = array(
|
||||||
array(
|
array(
|
||||||
'label' => esc_html__( 'Onboarded', 'woocommerce-paypal-payments' ),
|
'label' => esc_html__( 'Onboarded', 'woocommerce-paypal-payments' ),
|
||||||
|
@ -169,7 +171,7 @@ class StatusReportModule implements ModuleInterface {
|
||||||
'description' => esc_html__( 'Whether subscriptions are active and their mode.', 'woocommerce-paypal-payments' ),
|
'description' => esc_html__( 'Whether subscriptions are active and their mode.', 'woocommerce-paypal-payments' ),
|
||||||
'value' => $this->subscriptions_mode_text(
|
'value' => $this->subscriptions_mode_text(
|
||||||
$subscription_helper->plugin_is_active(),
|
$subscription_helper->plugin_is_active(),
|
||||||
$settings->has( 'subscriptions_mode' ) ? (string) $settings->get( 'subscriptions_mode' ) : '',
|
$settings->has( 'subscriptions_mode' ) ? (string) $subscription_mode_options[ $settings->get( 'subscriptions_mode' ) ] : '',
|
||||||
$subscriptions_mode_settings
|
$subscriptions_mode_settings
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -56,4 +56,15 @@ return array(
|
||||||
$container->get( 'woocommerce.logger.woocommerce' )
|
$container->get( 'woocommerce.logger.woocommerce' )
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
'vaulting.wc-payment-tokens' => static function( ContainerInterface $container ): WooCommercePaymentTokens {
|
||||||
|
return new WooCommercePaymentTokens(
|
||||||
|
$container->get( 'vaulting.payment-token-helper' ),
|
||||||
|
$container->get( 'vaulting.payment-token-factory' ),
|
||||||
|
$container->get( 'api.endpoint.payment-tokens' ),
|
||||||
|
$container->get( 'woocommerce.logger.woocommerce' )
|
||||||
|
);
|
||||||
|
},
|
||||||
|
'vaulting.vault-v3-enabled' => static function( ContainerInterface $container ): bool {
|
||||||
|
return $container->has( 'save-payment-methods.eligible' ) && $container->get( 'save-payment-methods.eligible' );
|
||||||
|
},
|
||||||
);
|
);
|
||||||
|
|
31
modules/ppcp-vaulting/src/PaymentTokenApplePay.php
Normal file
31
modules/ppcp-vaulting/src/PaymentTokenApplePay.php
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* WooCommerce Payment token for ApplePay.
|
||||||
|
*
|
||||||
|
* @package WooCommerce\PayPalCommerce\Vaulting
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace WooCommerce\PayPalCommerce\Vaulting;
|
||||||
|
|
||||||
|
use WC_Payment_Token;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class PaymentTokenApplePay
|
||||||
|
*/
|
||||||
|
class PaymentTokenApplePay extends WC_Payment_Token {
|
||||||
|
/**
|
||||||
|
* Token Type String.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $type = 'ApplePay';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extra data.
|
||||||
|
*
|
||||||
|
* @var string[]
|
||||||
|
*/
|
||||||
|
protected $extra_data = array();
|
||||||
|
}
|
|
@ -19,12 +19,16 @@ class PaymentTokenFactory {
|
||||||
*
|
*
|
||||||
* @param string $type The type of WC payment token.
|
* @param string $type The type of WC payment token.
|
||||||
*
|
*
|
||||||
* @return void|PaymentTokenPayPal
|
* @return void|PaymentTokenPayPal|PaymentTokenVenmo|PaymentTokenApplePay
|
||||||
*/
|
*/
|
||||||
public function create( string $type ) {
|
public function create( string $type ) {
|
||||||
switch ( $type ) {
|
switch ( $type ) {
|
||||||
case 'paypal':
|
case 'paypal':
|
||||||
return new PaymentTokenPayPal();
|
return new PaymentTokenPayPal();
|
||||||
|
case 'venmo':
|
||||||
|
return new PaymentTokenVenmo();
|
||||||
|
case 'apple_pay':
|
||||||
|
return new PaymentTokenApplePay();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,15 +21,39 @@ class PaymentTokenHelper {
|
||||||
*
|
*
|
||||||
* @param WC_Payment_Token[] $wc_tokens WC Payment Tokens.
|
* @param WC_Payment_Token[] $wc_tokens WC Payment Tokens.
|
||||||
* @param string $token_id Payment Token ID.
|
* @param string $token_id Payment Token ID.
|
||||||
|
* @param ?string $class_name Class name of the token.
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function token_exist( array $wc_tokens, string $token_id ): bool {
|
public function token_exist( array $wc_tokens, string $token_id, string $class_name = null ): bool {
|
||||||
foreach ( $wc_tokens as $wc_token ) {
|
foreach ( $wc_tokens as $wc_token ) {
|
||||||
if ( $wc_token->get_token() === $token_id ) {
|
if ( $wc_token->get_token() === $token_id ) {
|
||||||
return true;
|
if ( null !== $class_name ) {
|
||||||
|
if ( $wc_token instanceof $class_name ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if given token exist as WC Payment Token.
|
||||||
|
*
|
||||||
|
* @param array $wc_tokens WC Payment Tokens.
|
||||||
|
* @param string $class_name Class name of the token.
|
||||||
|
* @return null|WC_Payment_Token
|
||||||
|
*/
|
||||||
|
public function first_token_of_type( array $wc_tokens, string $class_name ) {
|
||||||
|
foreach ( $wc_tokens as $wc_token ) {
|
||||||
|
if ( $wc_token instanceof $class_name ) {
|
||||||
|
return $wc_token;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
51
modules/ppcp-vaulting/src/PaymentTokenVenmo.php
Normal file
51
modules/ppcp-vaulting/src/PaymentTokenVenmo.php
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* WooCommerce Payment token for Venmo.
|
||||||
|
*
|
||||||
|
* @package WooCommerce\PayPalCommerce\Vaulting
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace WooCommerce\PayPalCommerce\Vaulting;
|
||||||
|
|
||||||
|
use WC_Payment_Token;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class PaymentTokenVenmo
|
||||||
|
*/
|
||||||
|
class PaymentTokenVenmo extends WC_Payment_Token {
|
||||||
|
/**
|
||||||
|
* Token Type String.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $type = 'Venmo';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extra data.
|
||||||
|
*
|
||||||
|
* @var string[]
|
||||||
|
*/
|
||||||
|
protected $extra_data = array(
|
||||||
|
'email' => '',
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get PayPal account email.
|
||||||
|
*
|
||||||
|
* @return string PayPal account email.
|
||||||
|
*/
|
||||||
|
public function get_email() {
|
||||||
|
return $this->get_meta( 'email' );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set PayPal account email.
|
||||||
|
*
|
||||||
|
* @param string $email PayPal account email.
|
||||||
|
*/
|
||||||
|
public function set_email( $email ) {
|
||||||
|
$this->add_meta_data( 'email', $email, true );
|
||||||
|
}
|
||||||
|
}
|
|
@ -107,7 +107,7 @@ class PaymentTokensMigration {
|
||||||
}
|
}
|
||||||
} elseif ( $token->source()->paypal ) {
|
} elseif ( $token->source()->paypal ) {
|
||||||
$wc_tokens = WC_Payment_Tokens::get_customer_tokens( $id, PayPalGateway::ID );
|
$wc_tokens = WC_Payment_Tokens::get_customer_tokens( $id, PayPalGateway::ID );
|
||||||
if ( $this->payment_token_helper->token_exist( $wc_tokens, $token->id() ) ) {
|
if ( $this->payment_token_helper->token_exist( $wc_tokens, $token->id(), PaymentTokenPayPal::class ) ) {
|
||||||
$this->logger->info( 'Token already exist for user ' . (string) $id );
|
$this->logger->info( 'Token already exist for user ' . (string) $id );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,11 +81,50 @@ class VaultingModule implements ModuleInterface {
|
||||||
if ( $type === 'WC_Payment_Token_PayPal' ) {
|
if ( $type === 'WC_Payment_Token_PayPal' ) {
|
||||||
return PaymentTokenPayPal::class;
|
return PaymentTokenPayPal::class;
|
||||||
}
|
}
|
||||||
|
if ( $type === 'WC_Payment_Token_Venmo' ) {
|
||||||
|
return PaymentTokenVenmo::class;
|
||||||
|
}
|
||||||
|
if ( $type === 'WC_Payment_Token_ApplePay' ) {
|
||||||
|
return PaymentTokenApplePay::class;
|
||||||
|
}
|
||||||
|
|
||||||
return $type;
|
return $type;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
add_filter(
|
||||||
|
'woocommerce_get_customer_payment_tokens',
|
||||||
|
/**
|
||||||
|
* Filter available payment tokens depending on context.
|
||||||
|
*
|
||||||
|
* @psalm-suppress MissingClosureParamType
|
||||||
|
* @psalm-suppress MissingClosureReturnType
|
||||||
|
*/
|
||||||
|
function( $tokens, $customer_id, $gateway_id ) {
|
||||||
|
if ( ! is_array( $tokens ) ) {
|
||||||
|
return $tokens;
|
||||||
|
}
|
||||||
|
|
||||||
|
$is_post = isset( $_SERVER['REQUEST_METHOD'] ) && $_SERVER['REQUEST_METHOD'] === 'POST';
|
||||||
|
|
||||||
|
// Exclude ApplePay tokens from payment pages.
|
||||||
|
if (
|
||||||
|
( is_checkout() || is_cart() || is_product() )
|
||||||
|
&& ! $is_post // Don't check on POST so we have all payment methods on form submissions.
|
||||||
|
) {
|
||||||
|
foreach ( $tokens as $index => $token ) {
|
||||||
|
if ( $token instanceof PaymentTokenApplePay ) {
|
||||||
|
unset( $tokens[ $index ] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $tokens;
|
||||||
|
},
|
||||||
|
10,
|
||||||
|
3
|
||||||
|
);
|
||||||
|
|
||||||
add_filter(
|
add_filter(
|
||||||
'woocommerce_payment_methods_list_item',
|
'woocommerce_payment_methods_list_item',
|
||||||
/**
|
/**
|
||||||
|
@ -98,10 +137,18 @@ class VaultingModule implements ModuleInterface {
|
||||||
return $item;
|
return $item;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( strtolower( $payment_token->get_type() ) === 'paypal' ) {
|
if ( $payment_token instanceof PaymentTokenPayPal ) {
|
||||||
assert( $payment_token instanceof PaymentTokenPayPal );
|
$item['method']['brand'] = 'PayPal / ' . $payment_token->get_email();
|
||||||
$item['method']['brand'] = $payment_token->get_email();
|
return $item;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $payment_token instanceof PaymentTokenVenmo ) {
|
||||||
|
$item['method']['brand'] = 'Venmo / ' . $payment_token->get_email();
|
||||||
|
return $item;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $payment_token instanceof PaymentTokenApplePay ) {
|
||||||
|
$item['method']['brand'] = 'ApplePay #' . ( (string) $payment_token->get_id() );
|
||||||
return $item;
|
return $item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
326
modules/ppcp-vaulting/src/WooCommercePaymentTokens.php
Normal file
326
modules/ppcp-vaulting/src/WooCommercePaymentTokens.php
Normal file
|
@ -0,0 +1,326 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Service to create WC Payment Tokens.
|
||||||
|
*
|
||||||
|
* @package WooCommerce\PayPalCommerce\Applepay
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace WooCommerce\PayPalCommerce\Vaulting;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
|
use Psr\Log\LoggerInterface;
|
||||||
|
use stdClass;
|
||||||
|
use WC_Payment_Token_CC;
|
||||||
|
use WC_Payment_Tokens;
|
||||||
|
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentTokensEndpoint;
|
||||||
|
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||||
|
use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway;
|
||||||
|
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class WooCommercePaymentTokens
|
||||||
|
*/
|
||||||
|
class WooCommercePaymentTokens {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The payment token helper.
|
||||||
|
*
|
||||||
|
* @var PaymentTokenHelper
|
||||||
|
*/
|
||||||
|
private $payment_token_helper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The payment token factory.
|
||||||
|
*
|
||||||
|
* @var PaymentTokenFactory
|
||||||
|
*/
|
||||||
|
private $payment_token_factory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Payment tokens endpoint.
|
||||||
|
*
|
||||||
|
* @var PaymentTokensEndpoint
|
||||||
|
*/
|
||||||
|
private $payment_tokens_endpoint;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The logger.
|
||||||
|
*
|
||||||
|
* @var LoggerInterface
|
||||||
|
*/
|
||||||
|
private $logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* WooCommercePaymentTokens constructor.
|
||||||
|
*
|
||||||
|
* @param PaymentTokenHelper $payment_token_helper The payment token helper.
|
||||||
|
* @param PaymentTokenFactory $payment_token_factory The payment token factory.
|
||||||
|
* @param PaymentTokensEndpoint $payment_tokens_endpoint Payment tokens endpoint.
|
||||||
|
* @param LoggerInterface $logger The logger.
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
PaymentTokenHelper $payment_token_helper,
|
||||||
|
PaymentTokenFactory $payment_token_factory,
|
||||||
|
PaymentTokensEndpoint $payment_tokens_endpoint,
|
||||||
|
LoggerInterface $logger
|
||||||
|
) {
|
||||||
|
$this->payment_token_helper = $payment_token_helper;
|
||||||
|
$this->payment_token_factory = $payment_token_factory;
|
||||||
|
$this->payment_tokens_endpoint = $payment_tokens_endpoint;
|
||||||
|
$this->logger = $logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a WC Payment Token for PayPal payment.
|
||||||
|
*
|
||||||
|
* @param int $customer_id The WC customer ID.
|
||||||
|
* @param string $token The PayPal payment token.
|
||||||
|
* @param string $email The PayPal customer email.
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function create_payment_token_paypal(
|
||||||
|
int $customer_id,
|
||||||
|
string $token,
|
||||||
|
string $email
|
||||||
|
): int {
|
||||||
|
|
||||||
|
if ( $customer_id === 0 ) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
$wc_tokens = WC_Payment_Tokens::get_customer_tokens( $customer_id, PayPalGateway::ID );
|
||||||
|
if ( $this->payment_token_helper->token_exist( $wc_tokens, $token, PaymentTokenPayPal::class ) ) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to update existing token of type before creating a new one.
|
||||||
|
$payment_token_paypal = $this->payment_token_helper->first_token_of_type( $wc_tokens, PaymentTokenPayPal::class );
|
||||||
|
|
||||||
|
if ( ! $payment_token_paypal ) {
|
||||||
|
$payment_token_paypal = $this->payment_token_factory->create( 'paypal' );
|
||||||
|
}
|
||||||
|
|
||||||
|
assert( $payment_token_paypal instanceof PaymentTokenPayPal );
|
||||||
|
|
||||||
|
$payment_token_paypal->set_token( $token );
|
||||||
|
$payment_token_paypal->set_user_id( $customer_id );
|
||||||
|
$payment_token_paypal->set_gateway_id( PayPalGateway::ID );
|
||||||
|
|
||||||
|
if ( $email && is_email( $email ) ) {
|
||||||
|
$payment_token_paypal->set_email( $email );
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$payment_token_paypal->save();
|
||||||
|
} catch ( Exception $exception ) {
|
||||||
|
$this->logger->error(
|
||||||
|
"Could not create WC payment token PayPal for customer {$customer_id}. " . $exception->getMessage()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $payment_token_paypal->get_id();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a WC Payment Token for Venmo payment.
|
||||||
|
*
|
||||||
|
* @param int $customer_id The WC customer ID.
|
||||||
|
* @param string $token The Venmo payment token.
|
||||||
|
* @param string $email The Venmo customer email.
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function create_payment_token_venmo(
|
||||||
|
int $customer_id,
|
||||||
|
string $token,
|
||||||
|
string $email
|
||||||
|
): int {
|
||||||
|
|
||||||
|
if ( $customer_id === 0 ) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
$wc_tokens = WC_Payment_Tokens::get_customer_tokens( $customer_id, PayPalGateway::ID );
|
||||||
|
if ( $this->payment_token_helper->token_exist( $wc_tokens, $token, PaymentTokenVenmo::class ) ) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to update existing token of type before creating a new one.
|
||||||
|
$payment_token_venmo = $this->payment_token_helper->first_token_of_type( $wc_tokens, PaymentTokenVenmo::class );
|
||||||
|
|
||||||
|
if ( ! $payment_token_venmo ) {
|
||||||
|
$payment_token_venmo = $this->payment_token_factory->create( 'venmo' );
|
||||||
|
}
|
||||||
|
|
||||||
|
assert( $payment_token_venmo instanceof PaymentTokenVenmo );
|
||||||
|
|
||||||
|
$payment_token_venmo->set_token( $token );
|
||||||
|
$payment_token_venmo->set_user_id( $customer_id );
|
||||||
|
$payment_token_venmo->set_gateway_id( PayPalGateway::ID );
|
||||||
|
|
||||||
|
if ( $email && is_email( $email ) ) {
|
||||||
|
$payment_token_venmo->set_email( $email );
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$payment_token_venmo->save();
|
||||||
|
} catch ( Exception $exception ) {
|
||||||
|
$this->logger->error(
|
||||||
|
"Could not create WC payment token Venmo for customer {$customer_id}. " . $exception->getMessage()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $payment_token_venmo->get_id();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a WC Payment Token for ApplePay payment.
|
||||||
|
*
|
||||||
|
* @param int $customer_id The WC customer ID.
|
||||||
|
* @param string $token The ApplePay payment token.
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function create_payment_token_applepay(
|
||||||
|
int $customer_id,
|
||||||
|
string $token
|
||||||
|
): int {
|
||||||
|
|
||||||
|
if ( $customer_id === 0 ) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
$wc_tokens = WC_Payment_Tokens::get_customer_tokens( $customer_id, PayPalGateway::ID );
|
||||||
|
if ( $this->payment_token_helper->token_exist( $wc_tokens, $token, PaymentTokenApplePay::class ) ) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to update existing token of type before creating a new one.
|
||||||
|
$payment_token_applepay = $this->payment_token_helper->first_token_of_type( $wc_tokens, PaymentTokenApplePay::class );
|
||||||
|
|
||||||
|
if ( ! $payment_token_applepay ) {
|
||||||
|
$payment_token_applepay = $this->payment_token_factory->create( 'apple_pay' );
|
||||||
|
}
|
||||||
|
|
||||||
|
assert( $payment_token_applepay instanceof PaymentTokenApplePay );
|
||||||
|
|
||||||
|
$payment_token_applepay->set_token( $token );
|
||||||
|
$payment_token_applepay->set_user_id( $customer_id );
|
||||||
|
$payment_token_applepay->set_gateway_id( PayPalGateway::ID );
|
||||||
|
|
||||||
|
try {
|
||||||
|
$payment_token_applepay->save();
|
||||||
|
} catch ( Exception $exception ) {
|
||||||
|
$this->logger->error(
|
||||||
|
"Could not create WC payment token ApplePay for customer {$customer_id}. " . $exception->getMessage()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $payment_token_applepay->get_id();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a WC Payment Token for Credit Card payment.
|
||||||
|
*
|
||||||
|
* @param int $customer_id The WC customer ID.
|
||||||
|
* @param stdClass $payment_token The Credit Card payment token.
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function create_payment_token_card( int $customer_id, stdClass $payment_token ): int {
|
||||||
|
if ( $customer_id === 0 ) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
$wc_tokens = WC_Payment_Tokens::get_customer_tokens( $customer_id, CreditCardGateway::ID );
|
||||||
|
if ( $this->payment_token_helper->token_exist( $wc_tokens, $payment_token->id ) ) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
$token = new WC_Payment_Token_CC();
|
||||||
|
$token->set_token( $payment_token->id );
|
||||||
|
$token->set_user_id( $customer_id );
|
||||||
|
$token->set_gateway_id( CreditCardGateway::ID );
|
||||||
|
|
||||||
|
$token->set_last4( $payment_token->payment_source->card->last_digits ?? '' );
|
||||||
|
$expiry = explode( '-', $payment_token->payment_source->card->expiry ?? '' );
|
||||||
|
$token->set_expiry_year( $expiry[0] ?? '' );
|
||||||
|
$token->set_expiry_month( $expiry[1] ?? '' );
|
||||||
|
|
||||||
|
$brand = $payment_token->payment_source->card->brand ?? __( 'N/A', 'woocommerce-paypal-payments' );
|
||||||
|
if ( $brand ) {
|
||||||
|
$token->set_card_type( $brand );
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$token->save();
|
||||||
|
} catch ( Exception $exception ) {
|
||||||
|
$this->logger->error(
|
||||||
|
"Could not create WC payment token card for customer {$customer_id}. " . $exception->getMessage()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$token->save();
|
||||||
|
return $token->get_id();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns PayPal payment tokens for the given WP user id.
|
||||||
|
*
|
||||||
|
* @param int $user_id WP user id.
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function customer_tokens( int $user_id ): array {
|
||||||
|
$customer_id = get_user_meta( $user_id, '_ppcp_target_customer_id', true );
|
||||||
|
if ( ! $customer_id ) {
|
||||||
|
$customer_id = get_user_meta( $user_id, 'ppcp_customer_id', true );
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$customer_tokens = $this->payment_tokens_endpoint->payment_tokens_for_customer( $customer_id );
|
||||||
|
} catch ( RuntimeException $exception ) {
|
||||||
|
$customer_tokens = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $customer_tokens;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates WC payment tokens for the given WP user id using PayPal payment tokens as source.
|
||||||
|
*
|
||||||
|
* @param array $customer_tokens PayPal customer payment tokens.
|
||||||
|
* @param int $user_id WP user id.
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function create_wc_tokens( array $customer_tokens, int $user_id ): void {
|
||||||
|
foreach ( $customer_tokens as $customer_token ) {
|
||||||
|
if ( $customer_token['payment_source']->name() === 'paypal' ) {
|
||||||
|
$this->create_payment_token_paypal(
|
||||||
|
$user_id,
|
||||||
|
$customer_token['id'],
|
||||||
|
$customer_token['payment_source']->properties()->email_address ?? ''
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $customer_token['payment_source']->name() === 'card' ) {
|
||||||
|
/**
|
||||||
|
* Suppress ArgumentTypeCoercion
|
||||||
|
*
|
||||||
|
* @psalm-suppress ArgumentTypeCoercion
|
||||||
|
*/
|
||||||
|
$this->create_payment_token_card(
|
||||||
|
$user_id,
|
||||||
|
(object) array(
|
||||||
|
'id' => $customer_token['id'],
|
||||||
|
'payment_source' => (object) array(
|
||||||
|
$customer_token['payment_source']->name() => $customer_token['payment_source']->properties(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,6 +23,8 @@ use WooCommerce\PayPalCommerce\Common\Pattern\SingletonDecorator;
|
||||||
use WooCommerce\PayPalCommerce\Onboarding\Environment;
|
use WooCommerce\PayPalCommerce\Onboarding\Environment;
|
||||||
use WooCommerce\PayPalCommerce\Onboarding\Render\OnboardingOptionsRenderer;
|
use WooCommerce\PayPalCommerce\Onboarding\Render\OnboardingOptionsRenderer;
|
||||||
use WooCommerce\PayPalCommerce\Onboarding\State;
|
use WooCommerce\PayPalCommerce\Onboarding\State;
|
||||||
|
use WooCommerce\PayPalCommerce\WcGateway\Admin\RenderReauthorizeAction;
|
||||||
|
use WooCommerce\PayPalCommerce\WcGateway\Endpoint\CaptureCardPayment;
|
||||||
use WooCommerce\PayPalCommerce\WcGateway\Endpoint\RefreshFeatureStatusEndpoint;
|
use WooCommerce\PayPalCommerce\WcGateway\Endpoint\RefreshFeatureStatusEndpoint;
|
||||||
use WooCommerce\PayPalCommerce\WcSubscriptions\Helper\SubscriptionHelper;
|
use WooCommerce\PayPalCommerce\WcSubscriptions\Helper\SubscriptionHelper;
|
||||||
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
|
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
|
||||||
|
@ -102,7 +104,10 @@ return array(
|
||||||
$api_shop_country,
|
$api_shop_country,
|
||||||
$container->get( 'api.endpoint.order' ),
|
$container->get( 'api.endpoint.order' ),
|
||||||
$container->get( 'api.factory.paypal-checkout-url' ),
|
$container->get( 'api.factory.paypal-checkout-url' ),
|
||||||
$container->get( 'wcgateway.place-order-button-text' )
|
$container->get( 'wcgateway.place-order-button-text' ),
|
||||||
|
$container->get( 'api.endpoint.payment-tokens' ),
|
||||||
|
$container->get( 'vaulting.vault-v3-enabled' ),
|
||||||
|
$container->get( 'vaulting.wc-payment-tokens' )
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
'wcgateway.credit-card-gateway' => static function ( ContainerInterface $container ): CreditCardGateway {
|
'wcgateway.credit-card-gateway' => static function ( ContainerInterface $container ): CreditCardGateway {
|
||||||
|
@ -128,9 +133,15 @@ return array(
|
||||||
$state,
|
$state,
|
||||||
$transaction_url_provider,
|
$transaction_url_provider,
|
||||||
$subscription_helper,
|
$subscription_helper,
|
||||||
$logger,
|
|
||||||
$payments_endpoint,
|
$payments_endpoint,
|
||||||
$vaulted_credit_card_handler
|
$vaulted_credit_card_handler,
|
||||||
|
$container->get( 'onboarding.environment' ),
|
||||||
|
$container->get( 'api.endpoint.order' ),
|
||||||
|
$container->get( 'wcgateway.endpoint.capture-card-payment' ),
|
||||||
|
$container->get( 'api.prefix' ),
|
||||||
|
$container->get( 'api.endpoint.payment-tokens' ),
|
||||||
|
$container->get( 'vaulting.wc-payment-tokens' ),
|
||||||
|
$logger
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
'wcgateway.card-button-gateway' => static function ( ContainerInterface $container ): CardButtonGateway {
|
'wcgateway.card-button-gateway' => static function ( ContainerInterface $container ): CardButtonGateway {
|
||||||
|
@ -381,19 +392,25 @@ return array(
|
||||||
$notice = $container->get( 'wcgateway.notice.authorize-order-action' );
|
$notice = $container->get( 'wcgateway.notice.authorize-order-action' );
|
||||||
$settings = $container->get( 'wcgateway.settings' );
|
$settings = $container->get( 'wcgateway.settings' );
|
||||||
$subscription_helper = $container->get( 'wc-subscriptions.helper' );
|
$subscription_helper = $container->get( 'wc-subscriptions.helper' );
|
||||||
|
$amount_factory = $container->get( 'api.factory.amount' );
|
||||||
return new AuthorizedPaymentsProcessor(
|
return new AuthorizedPaymentsProcessor(
|
||||||
$order_endpoint,
|
$order_endpoint,
|
||||||
$payments_endpoint,
|
$payments_endpoint,
|
||||||
$logger,
|
$logger,
|
||||||
$notice,
|
$notice,
|
||||||
$settings,
|
$settings,
|
||||||
$subscription_helper
|
$subscription_helper,
|
||||||
|
$amount_factory
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
'wcgateway.admin.render-authorize-action' => static function ( ContainerInterface $container ): RenderAuthorizeAction {
|
'wcgateway.admin.render-authorize-action' => static function ( ContainerInterface $container ): RenderAuthorizeAction {
|
||||||
$column = $container->get( 'wcgateway.admin.orders-payment-status-column' );
|
$column = $container->get( 'wcgateway.admin.orders-payment-status-column' );
|
||||||
return new RenderAuthorizeAction( $column );
|
return new RenderAuthorizeAction( $column );
|
||||||
},
|
},
|
||||||
|
'wcgateway.admin.render-reauthorize-action' => static function ( ContainerInterface $container ): RenderReauthorizeAction {
|
||||||
|
$column = $container->get( 'wcgateway.admin.orders-payment-status-column' );
|
||||||
|
return new RenderReauthorizeAction( $column );
|
||||||
|
},
|
||||||
'wcgateway.admin.order-payment-status' => static function ( ContainerInterface $container ): PaymentStatusOrderDetail {
|
'wcgateway.admin.order-payment-status' => static function ( ContainerInterface $container ): PaymentStatusOrderDetail {
|
||||||
$column = $container->get( 'wcgateway.admin.orders-payment-status-column' );
|
$column = $container->get( 'wcgateway.admin.orders-payment-status-column' );
|
||||||
return new PaymentStatusOrderDetail( $column );
|
return new PaymentStatusOrderDetail( $column );
|
||||||
|
@ -405,7 +422,6 @@ return array(
|
||||||
'wcgateway.admin.fees-renderer' => static function ( ContainerInterface $container ): FeesRenderer {
|
'wcgateway.admin.fees-renderer' => static function ( ContainerInterface $container ): FeesRenderer {
|
||||||
return new FeesRenderer();
|
return new FeesRenderer();
|
||||||
},
|
},
|
||||||
|
|
||||||
'wcgateway.settings.should-render-settings' => static function ( ContainerInterface $container ): bool {
|
'wcgateway.settings.should-render-settings' => static function ( ContainerInterface $container ): bool {
|
||||||
|
|
||||||
$sections = array(
|
$sections = array(
|
||||||
|
@ -420,13 +436,15 @@ return array(
|
||||||
|
|
||||||
return array_key_exists( $current_page_id, $sections );
|
return array_key_exists( $current_page_id, $sections );
|
||||||
},
|
},
|
||||||
|
'wcgateway.settings.fields.subscriptions_mode_options' => static function ( ContainerInterface $container ): array {
|
||||||
'wcgateway.settings.fields.subscriptions_mode' => static function ( ContainerInterface $container ): array {
|
return array(
|
||||||
$subscription_mode_options = array(
|
|
||||||
'vaulting_api' => __( 'PayPal Vaulting', 'woocommerce-paypal-payments' ),
|
'vaulting_api' => __( 'PayPal Vaulting', 'woocommerce-paypal-payments' ),
|
||||||
'subscriptions_api' => __( 'PayPal Subscriptions', 'woocommerce-paypal-payments' ),
|
'subscriptions_api' => __( 'PayPal Subscriptions', 'woocommerce-paypal-payments' ),
|
||||||
'disable_paypal_subscriptions' => __( 'Disable PayPal for subscriptions', 'woocommerce-paypal-payments' ),
|
'disable_paypal_subscriptions' => __( 'Disable PayPal for subscriptions', 'woocommerce-paypal-payments' ),
|
||||||
);
|
);
|
||||||
|
},
|
||||||
|
'wcgateway.settings.fields.subscriptions_mode' => static function ( ContainerInterface $container ): array {
|
||||||
|
$subscription_mode_options = $container->get( 'wcgateway.settings.fields.subscriptions_mode_options' );
|
||||||
|
|
||||||
$billing_agreements_endpoint = $container->get( 'api.endpoint.billing-agreements' );
|
$billing_agreements_endpoint = $container->get( 'api.endpoint.billing-agreements' );
|
||||||
$reference_transaction_enabled = $billing_agreements_endpoint->reference_transaction_enabled();
|
$reference_transaction_enabled = $billing_agreements_endpoint->reference_transaction_enabled();
|
||||||
|
@ -441,7 +459,7 @@ return array(
|
||||||
'input_class' => array( 'wc-enhanced-select' ),
|
'input_class' => array( 'wc-enhanced-select' ),
|
||||||
'desc_tip' => true,
|
'desc_tip' => true,
|
||||||
'description' => __( 'Utilize PayPal Vaulting for flexible subscription processing with saved payment methods, create “PayPal Subscriptions” to bill customers at regular intervals, or disable PayPal for subscription-type products.', 'woocommerce-paypal-payments' ),
|
'description' => __( 'Utilize PayPal Vaulting for flexible subscription processing with saved payment methods, create “PayPal Subscriptions” to bill customers at regular intervals, or disable PayPal for subscription-type products.', 'woocommerce-paypal-payments' ),
|
||||||
'default' => 'vaulting_api',
|
'default' => array_key_first( $subscription_mode_options ),
|
||||||
'options' => $subscription_mode_options,
|
'options' => $subscription_mode_options,
|
||||||
'screens' => array(
|
'screens' => array(
|
||||||
State::STATE_ONBOARDED,
|
State::STATE_ONBOARDED,
|
||||||
|
@ -964,11 +982,6 @@ return array(
|
||||||
unset( $fields['subscriptions_mode'] );
|
unset( $fields['subscriptions_mode'] );
|
||||||
}
|
}
|
||||||
|
|
||||||
$billing_agreements_endpoint = $container->get( 'api.endpoint.billing-agreements' );
|
|
||||||
if ( ! $billing_agreements_endpoint->reference_transaction_enabled() ) {
|
|
||||||
unset( $fields['vault_enabled'] );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Depending on your store location, some credit cards can't be used.
|
* Depending on your store location, some credit cards can't be used.
|
||||||
* Here, we filter them out.
|
* Here, we filter them out.
|
||||||
|
@ -1006,10 +1019,10 @@ return array(
|
||||||
'ideal' => _x( 'iDEAL', 'Name of payment method', 'woocommerce-paypal-payments' ),
|
'ideal' => _x( 'iDEAL', 'Name of payment method', 'woocommerce-paypal-payments' ),
|
||||||
'mybank' => _x( 'MyBank', 'Name of payment method', 'woocommerce-paypal-payments' ),
|
'mybank' => _x( 'MyBank', 'Name of payment method', 'woocommerce-paypal-payments' ),
|
||||||
'p24' => _x( 'Przelewy24', 'Name of payment method', 'woocommerce-paypal-payments' ),
|
'p24' => _x( 'Przelewy24', 'Name of payment method', 'woocommerce-paypal-payments' ),
|
||||||
'sofort' => _x( 'Sofort', 'Name of payment method', 'woocommerce-paypal-payments' ),
|
|
||||||
'venmo' => _x( 'Venmo', 'Name of payment method', 'woocommerce-paypal-payments' ),
|
'venmo' => _x( 'Venmo', 'Name of payment method', 'woocommerce-paypal-payments' ),
|
||||||
'trustly' => _x( 'Trustly', 'Name of payment method', 'woocommerce-paypal-payments' ),
|
'trustly' => _x( 'Trustly', 'Name of payment method', 'woocommerce-paypal-payments' ),
|
||||||
'paylater' => _x( 'Pay Later', 'Name of payment method', 'woocommerce-paypal-payments' ),
|
'paylater' => _x( 'PayPal Pay Later', 'Name of payment method', 'woocommerce-paypal-payments' ),
|
||||||
|
'paypal' => _x( 'PayPal', 'Name of payment method', 'woocommerce-paypal-payments' ),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -1032,6 +1045,7 @@ return array(
|
||||||
array_flip(
|
array_flip(
|
||||||
array(
|
array(
|
||||||
'paylater',
|
'paylater',
|
||||||
|
'paypal',
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
@ -1634,4 +1648,17 @@ return array(
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
'wcgateway.endpoint.capture-card-payment' => static function( ContainerInterface $container ): CaptureCardPayment {
|
||||||
|
return new CaptureCardPayment(
|
||||||
|
$container->get( 'api.host' ),
|
||||||
|
$container->get( 'api.bearer' ),
|
||||||
|
$container->get( 'api.factory.order' ),
|
||||||
|
$container->get( 'api.factory.purchase-unit' ),
|
||||||
|
$container->get( 'api.endpoint.order' ),
|
||||||
|
$container->get( 'session.handler' ),
|
||||||
|
$container->get( 'wc-subscriptions.helpers.real-time-account-updater' ),
|
||||||
|
$container->get( 'wcgateway.settings' ),
|
||||||
|
$container->get( 'woocommerce.logger.woocommerce' )
|
||||||
|
);
|
||||||
|
},
|
||||||
);
|
);
|
||||||
|
|
|
@ -9,9 +9,6 @@ declare( strict_types=1 );
|
||||||
|
|
||||||
namespace WooCommerce\PayPalCommerce\WcGateway\Admin;
|
namespace WooCommerce\PayPalCommerce\WcGateway\Admin;
|
||||||
|
|
||||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
|
||||||
use WooCommerce\PayPalCommerce\WcGateway\Processor\AuthorizedPaymentsProcessor;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class RenderAuthorizeAction
|
* Class RenderAuthorizeAction
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Renders the order action "Reauthorize PayPal payment"
|
||||||
|
*
|
||||||
|
* @package WooCommerce\PayPalCommerce\WcGateway\Admin
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare( strict_types=1 );
|
||||||
|
|
||||||
|
namespace WooCommerce\PayPalCommerce\WcGateway\Admin;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class RenderReauthorizeAction
|
||||||
|
*/
|
||||||
|
class RenderReauthorizeAction {
|
||||||
|
/**
|
||||||
|
* The capture info column.
|
||||||
|
*
|
||||||
|
* @var OrderTablePaymentStatusColumn
|
||||||
|
*/
|
||||||
|
private $column;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PaymentStatusOrderDetail constructor.
|
||||||
|
*
|
||||||
|
* @param OrderTablePaymentStatusColumn $column The capture info column.
|
||||||
|
*/
|
||||||
|
public function __construct( OrderTablePaymentStatusColumn $column ) {
|
||||||
|
$this->column = $column;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders the action into the $order_actions array based on the WooCommerce order.
|
||||||
|
*
|
||||||
|
* @param array $order_actions The actions to render into.
|
||||||
|
* @param \WC_Order $wc_order The order for which to render the action.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function render( array $order_actions, \WC_Order $wc_order ) : array {
|
||||||
|
|
||||||
|
if ( ! $this->should_render_for_order( $wc_order ) ) {
|
||||||
|
return $order_actions;
|
||||||
|
}
|
||||||
|
|
||||||
|
$order_actions['ppcp_reauthorize_order'] = esc_html__(
|
||||||
|
'Reauthorize PayPal payment',
|
||||||
|
'woocommerce-paypal-payments'
|
||||||
|
);
|
||||||
|
return $order_actions;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the action should be rendered for a certain WooCommerce order.
|
||||||
|
*
|
||||||
|
* @param \WC_Order $order The Woocommerce order.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
private function should_render_for_order( \WC_Order $order ) : bool {
|
||||||
|
$status = $order->get_status();
|
||||||
|
$not_allowed_statuses = array( 'refunded', 'cancelled', 'failed' );
|
||||||
|
return $this->column->should_render_for_order( $order ) &&
|
||||||
|
! $this->column->is_captured( $order ) &&
|
||||||
|
! in_array( $status, $not_allowed_statuses, true );
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,12 +9,12 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace WooCommerce\PayPalCommerce\WcGateway\Assets;
|
namespace WooCommerce\PayPalCommerce\WcGateway\Assets;
|
||||||
|
|
||||||
|
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\BillingAgreementsEndpoint;
|
||||||
use WooCommerce\PayPalCommerce\Onboarding\Environment;
|
use WooCommerce\PayPalCommerce\Onboarding\Environment;
|
||||||
use WooCommerce\PayPalCommerce\WcGateway\Endpoint\RefreshFeatureStatusEndpoint;
|
use WooCommerce\PayPalCommerce\WcGateway\Endpoint\RefreshFeatureStatusEndpoint;
|
||||||
use WooCommerce\PayPalCommerce\WcSubscriptions\Helper\SubscriptionHelper;
|
use WooCommerce\PayPalCommerce\WcSubscriptions\Helper\SubscriptionHelper;
|
||||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\CardButtonGateway;
|
use WooCommerce\PayPalCommerce\WcGateway\Gateway\CardButtonGateway;
|
||||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
||||||
use WooCommerce\PayPalCommerce\Webhooks\Endpoint\ResubscribeEndpoint;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class SettingsPageAssets
|
* Class SettingsPageAssets
|
||||||
|
@ -105,21 +105,29 @@ class SettingsPageAssets {
|
||||||
*/
|
*/
|
||||||
private $is_acdc_enabled;
|
private $is_acdc_enabled;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Billing Agreements endpoint.
|
||||||
|
*
|
||||||
|
* @var BillingAgreementsEndpoint
|
||||||
|
*/
|
||||||
|
private $billing_agreements_endpoint;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Assets constructor.
|
* Assets constructor.
|
||||||
*
|
*
|
||||||
* @param string $module_url The url of this module.
|
* @param string $module_url The url of this module.
|
||||||
* @param string $version The assets version.
|
* @param string $version The assets version.
|
||||||
* @param SubscriptionHelper $subscription_helper The subscription helper.
|
* @param SubscriptionHelper $subscription_helper The subscription helper.
|
||||||
* @param string $client_id The PayPal SDK client ID.
|
* @param string $client_id The PayPal SDK client ID.
|
||||||
* @param string $currency 3-letter currency code of the shop.
|
* @param string $currency 3-letter currency code of the shop.
|
||||||
* @param string $country 2-letter country code of the shop.
|
* @param string $country 2-letter country code of the shop.
|
||||||
* @param Environment $environment The environment object.
|
* @param Environment $environment The environment object.
|
||||||
* @param bool $is_pay_later_button_enabled Whether Pay Later button is enabled either for checkout, cart or product page.
|
* @param bool $is_pay_later_button_enabled Whether Pay Later button is enabled either for checkout, cart or product page.
|
||||||
* @param array $disabled_sources The list of disabled funding sources.
|
* @param array $disabled_sources The list of disabled funding sources.
|
||||||
* @param array $all_funding_sources The list of all existing funding sources.
|
* @param array $all_funding_sources The list of all existing funding sources.
|
||||||
* @param bool $is_settings_page Whether it's a settings page of this plugin.
|
* @param bool $is_settings_page Whether it's a settings page of this plugin.
|
||||||
* @param bool $is_acdc_enabled Whether the ACDC gateway is enabled.
|
* @param bool $is_acdc_enabled Whether the ACDC gateway is enabled.
|
||||||
|
* @param BillingAgreementsEndpoint $billing_agreements_endpoint Billing Agreements endpoint.
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
string $module_url,
|
string $module_url,
|
||||||
|
@ -133,7 +141,8 @@ class SettingsPageAssets {
|
||||||
array $disabled_sources,
|
array $disabled_sources,
|
||||||
array $all_funding_sources,
|
array $all_funding_sources,
|
||||||
bool $is_settings_page,
|
bool $is_settings_page,
|
||||||
bool $is_acdc_enabled
|
bool $is_acdc_enabled,
|
||||||
|
BillingAgreementsEndpoint $billing_agreements_endpoint
|
||||||
) {
|
) {
|
||||||
$this->module_url = $module_url;
|
$this->module_url = $module_url;
|
||||||
$this->version = $version;
|
$this->version = $version;
|
||||||
|
@ -147,6 +156,7 @@ class SettingsPageAssets {
|
||||||
$this->all_funding_sources = $all_funding_sources;
|
$this->all_funding_sources = $all_funding_sources;
|
||||||
$this->is_settings_page = $is_settings_page;
|
$this->is_settings_page = $is_settings_page;
|
||||||
$this->is_acdc_enabled = $is_acdc_enabled;
|
$this->is_acdc_enabled = $is_acdc_enabled;
|
||||||
|
$this->billing_agreements_endpoint = $billing_agreements_endpoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -250,6 +260,13 @@ class SettingsPageAssets {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
'reference_transaction_enabled' => $this->billing_agreements_endpoint->reference_transaction_enabled(),
|
||||||
|
'vaulting_must_enable_advanced_wallet_message' => sprintf(
|
||||||
|
// translators: %1$s and %2$s are the opening and closing of HTML <a> tag.
|
||||||
|
esc_html__( 'Your PayPal account must be enabled for the %1$sAdvanced PayPal Wallet%2$s to use PayPal Vaulting.', 'woocommerce-paypal-payments' ),
|
||||||
|
'<a href="/wp-admin/admin.php?page=wc-settings&tab=checkout§ion=ppcp-gateway&ppcp-tab=ppcp-connection#field-credentials_feature_onboarding_heading">',
|
||||||
|
'</a>'
|
||||||
|
),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
186
modules/ppcp-wc-gateway/src/Endpoint/CaptureCardPayment.php
Normal file
186
modules/ppcp-wc-gateway/src/Endpoint/CaptureCardPayment.php
Normal file
|
@ -0,0 +1,186 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* The Capture Card Payment endpoint.
|
||||||
|
*
|
||||||
|
* @package WooCommerce\PayPalCommerce\ApiClient\Endpoint
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace WooCommerce\PayPalCommerce\WcGateway\Endpoint;
|
||||||
|
|
||||||
|
use Psr\Log\LoggerInterface;
|
||||||
|
use RuntimeException;
|
||||||
|
use stdClass;
|
||||||
|
use WooCommerce\PayPalCommerce\ApiClient\Authentication\Bearer;
|
||||||
|
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
|
||||||
|
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\RequestTrait;
|
||||||
|
use WooCommerce\PayPalCommerce\ApiClient\Entity\PurchaseUnit;
|
||||||
|
use WooCommerce\PayPalCommerce\ApiClient\Factory\OrderFactory;
|
||||||
|
use WooCommerce\PayPalCommerce\ApiClient\Factory\PurchaseUnitFactory;
|
||||||
|
use WooCommerce\PayPalCommerce\Session\SessionHandler;
|
||||||
|
use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
|
||||||
|
use WooCommerce\PayPalCommerce\WcSubscriptions\Helper\RealTimeAccountUpdaterHelper;
|
||||||
|
use WP_Error;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class CaptureCardPayment
|
||||||
|
*/
|
||||||
|
class CaptureCardPayment {
|
||||||
|
|
||||||
|
use RequestTrait;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The host.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $host;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The bearer.
|
||||||
|
*
|
||||||
|
* @var Bearer
|
||||||
|
*/
|
||||||
|
private $bearer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The order factory.
|
||||||
|
*
|
||||||
|
* @var OrderFactory
|
||||||
|
*/
|
||||||
|
private $order_factory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The purchase unit factory.
|
||||||
|
*
|
||||||
|
* @var PurchaseUnitFactory
|
||||||
|
*/
|
||||||
|
private $purchase_unit_factory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The order endpoint.
|
||||||
|
*
|
||||||
|
* @var OrderEndpoint
|
||||||
|
*/
|
||||||
|
private $order_endpoint;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The session handler.
|
||||||
|
*
|
||||||
|
* @var SessionHandler
|
||||||
|
*/
|
||||||
|
private $session_handler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Real Time Account Updater helper.
|
||||||
|
*
|
||||||
|
* @var RealTimeAccountUpdaterHelper
|
||||||
|
*/
|
||||||
|
private $real_time_account_updater_helper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The settings.
|
||||||
|
*
|
||||||
|
* @var Settings
|
||||||
|
*/
|
||||||
|
private $settings;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The logger.
|
||||||
|
*
|
||||||
|
* @var LoggerInterface
|
||||||
|
*/
|
||||||
|
private $logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CaptureCardPayment constructor.
|
||||||
|
*
|
||||||
|
* @param string $host The host.
|
||||||
|
* @param Bearer $bearer The bearer.
|
||||||
|
* @param OrderFactory $order_factory The order factory.
|
||||||
|
* @param PurchaseUnitFactory $purchase_unit_factory The purchase unit factory.
|
||||||
|
* @param OrderEndpoint $order_endpoint The order endpoint.
|
||||||
|
* @param SessionHandler $session_handler The session handler.
|
||||||
|
* @param RealTimeAccountUpdaterHelper $real_time_account_updater_helper Real Time Account Updater helper.
|
||||||
|
* @param Settings $settings The settings.
|
||||||
|
* @param LoggerInterface $logger The logger.
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
string $host,
|
||||||
|
Bearer $bearer,
|
||||||
|
OrderFactory $order_factory,
|
||||||
|
PurchaseUnitFactory $purchase_unit_factory,
|
||||||
|
OrderEndpoint $order_endpoint,
|
||||||
|
SessionHandler $session_handler,
|
||||||
|
RealTimeAccountUpdaterHelper $real_time_account_updater_helper,
|
||||||
|
Settings $settings,
|
||||||
|
LoggerInterface $logger
|
||||||
|
) {
|
||||||
|
$this->host = $host;
|
||||||
|
$this->bearer = $bearer;
|
||||||
|
$this->order_factory = $order_factory;
|
||||||
|
$this->purchase_unit_factory = $purchase_unit_factory;
|
||||||
|
$this->order_endpoint = $order_endpoint;
|
||||||
|
$this->session_handler = $session_handler;
|
||||||
|
$this->real_time_account_updater_helper = $real_time_account_updater_helper;
|
||||||
|
$this->settings = $settings;
|
||||||
|
$this->logger = $logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates PayPal order from the given card vault id.
|
||||||
|
*
|
||||||
|
* @param string $vault_id Vault id.
|
||||||
|
* @param string $custom_id Custom id.
|
||||||
|
* @param string $invoice_id Invoice id.
|
||||||
|
* @return stdClass
|
||||||
|
* @throws RuntimeException When request fails.
|
||||||
|
*/
|
||||||
|
public function create_order( string $vault_id, string $custom_id, string $invoice_id ): stdClass {
|
||||||
|
$intent = $this->settings->has( 'intent' ) && strtoupper( (string) $this->settings->get( 'intent' ) ) === 'AUTHORIZE' ? 'AUTHORIZE' : 'CAPTURE';
|
||||||
|
$items = array( $this->purchase_unit_factory->from_wc_cart() );
|
||||||
|
|
||||||
|
$data = array(
|
||||||
|
'intent' => $intent,
|
||||||
|
'purchase_units' => array_map(
|
||||||
|
static function ( PurchaseUnit $item ): array {
|
||||||
|
return $item->to_array( true, false );
|
||||||
|
},
|
||||||
|
$items
|
||||||
|
),
|
||||||
|
'payment_source' => array(
|
||||||
|
'card' => array(
|
||||||
|
'vault_id' => $vault_id,
|
||||||
|
'stored_credential' => array(
|
||||||
|
'payment_initiator' => 'CUSTOMER',
|
||||||
|
'payment_type' => 'UNSCHEDULED',
|
||||||
|
'usage' => 'SUBSEQUENT',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'custom_id' => $custom_id,
|
||||||
|
'invoice_id' => $invoice_id,
|
||||||
|
);
|
||||||
|
|
||||||
|
$bearer = $this->bearer->bearer();
|
||||||
|
$url = trailingslashit( $this->host ) . 'v2/checkout/orders';
|
||||||
|
$args = array(
|
||||||
|
'method' => 'POST',
|
||||||
|
'headers' => array(
|
||||||
|
'Authorization' => 'Bearer ' . $bearer->token(),
|
||||||
|
'Content-Type' => 'application/json',
|
||||||
|
'PayPal-Request-Id' => uniqid( 'ppcp-', true ),
|
||||||
|
),
|
||||||
|
'body' => wp_json_encode( $data ),
|
||||||
|
);
|
||||||
|
|
||||||
|
$response = $this->request( $url, $args );
|
||||||
|
if ( $response instanceof WP_Error ) {
|
||||||
|
throw new RuntimeException( $response->get_error_message() );
|
||||||
|
}
|
||||||
|
|
||||||
|
return json_decode( $response['body'] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@ class FundingSourceRenderer {
|
||||||
*
|
*
|
||||||
* @var string[]
|
* @var string[]
|
||||||
*/
|
*/
|
||||||
protected $own_funding_sources = array( 'venmo', 'paylater' );
|
protected $own_funding_sources = array( 'venmo', 'paylater', 'paypal' );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* FundingSourceRenderer constructor.
|
* FundingSourceRenderer constructor.
|
||||||
|
@ -56,12 +56,14 @@ class FundingSourceRenderer {
|
||||||
* @param string $id The ID of the funding source, such as 'venmo'.
|
* @param string $id The ID of the funding source, such as 'venmo'.
|
||||||
*/
|
*/
|
||||||
public function render_name( string $id ): string {
|
public function render_name( string $id ): string {
|
||||||
|
$id = $this->sanitize_id( $id );
|
||||||
|
|
||||||
if ( array_key_exists( $id, $this->funding_sources ) ) {
|
if ( array_key_exists( $id, $this->funding_sources ) ) {
|
||||||
if ( in_array( $id, $this->own_funding_sources, true ) ) {
|
if ( in_array( $id, $this->own_funding_sources, true ) ) {
|
||||||
return $this->funding_sources[ $id ];
|
return $this->funding_sources[ $id ];
|
||||||
}
|
}
|
||||||
return sprintf(
|
return sprintf(
|
||||||
/* translators: %s - Sofort, BLIK, iDeal, Mercado Pago, etc. */
|
/* translators: %s - BLIK, iDeal, Mercado Pago, etc. */
|
||||||
__( '%s (via PayPal)', 'woocommerce-paypal-payments' ),
|
__( '%s (via PayPal)', 'woocommerce-paypal-payments' ),
|
||||||
$this->funding_sources[ $id ]
|
$this->funding_sources[ $id ]
|
||||||
);
|
);
|
||||||
|
@ -78,9 +80,11 @@ class FundingSourceRenderer {
|
||||||
* @param string $id The ID of the funding source, such as 'venmo'.
|
* @param string $id The ID of the funding source, such as 'venmo'.
|
||||||
*/
|
*/
|
||||||
public function render_description( string $id ): string {
|
public function render_description( string $id ): string {
|
||||||
|
$id = $this->sanitize_id( $id );
|
||||||
|
|
||||||
if ( array_key_exists( $id, $this->funding_sources ) ) {
|
if ( array_key_exists( $id, $this->funding_sources ) ) {
|
||||||
return sprintf(
|
return sprintf(
|
||||||
/* translators: %s - Sofort, BLIK, iDeal, Mercado Pago, etc. */
|
/* translators: %s - BLIK, iDeal, Mercado Pago, etc. */
|
||||||
__( 'Pay via %s.', 'woocommerce-paypal-payments' ),
|
__( 'Pay via %s.', 'woocommerce-paypal-payments' ),
|
||||||
$this->funding_sources[ $id ]
|
$this->funding_sources[ $id ]
|
||||||
);
|
);
|
||||||
|
@ -90,4 +94,14 @@ class FundingSourceRenderer {
|
||||||
$this->settings->get( 'description' )
|
$this->settings->get( 'description' )
|
||||||
: __( 'Pay via PayPal.', 'woocommerce-paypal-payments' );
|
: __( 'Pay via PayPal.', 'woocommerce-paypal-payments' );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sanitizes the id to a standard format.
|
||||||
|
*
|
||||||
|
* @param string $id The funding source id.
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private function sanitize_id( string $id ): string {
|
||||||
|
return str_replace( '_', '', strtolower( $id ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,27 +13,35 @@ use Exception;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
use WC_Order;
|
use WC_Order;
|
||||||
use WC_Payment_Tokens;
|
use WC_Payment_Tokens;
|
||||||
|
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
|
||||||
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentsEndpoint;
|
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentsEndpoint;
|
||||||
|
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentTokensEndpoint;
|
||||||
use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
|
use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
|
||||||
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||||
|
use WooCommerce\PayPalCommerce\Onboarding\Environment;
|
||||||
use WooCommerce\PayPalCommerce\Onboarding\State;
|
use WooCommerce\PayPalCommerce\Onboarding\State;
|
||||||
use WooCommerce\PayPalCommerce\Session\SessionHandler;
|
use WooCommerce\PayPalCommerce\Session\SessionHandler;
|
||||||
use WooCommerce\PayPalCommerce\WcGateway\Processor\TransactionIdHandlingTrait;
|
|
||||||
use WooCommerce\PayPalCommerce\WcSubscriptions\Helper\SubscriptionHelper;
|
|
||||||
use WooCommerce\PayPalCommerce\Vaulting\PaymentTokenRepository;
|
use WooCommerce\PayPalCommerce\Vaulting\PaymentTokenRepository;
|
||||||
use WooCommerce\PayPalCommerce\Vaulting\VaultedCreditCardHandler;
|
use WooCommerce\PayPalCommerce\Vaulting\VaultedCreditCardHandler;
|
||||||
use WooCommerce\PayPalCommerce\WcGateway\Exception\GatewayGenericException;
|
use WooCommerce\PayPalCommerce\Vaulting\WooCommercePaymentTokens;
|
||||||
use WooCommerce\PayPalCommerce\WcGateway\Processor\OrderProcessor;
|
|
||||||
use WooCommerce\PayPalCommerce\WcGateway\Processor\RefundProcessor;
|
|
||||||
use WooCommerce\PayPalCommerce\WcGateway\Settings\SettingsRenderer;
|
|
||||||
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
|
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
|
||||||
|
use WooCommerce\PayPalCommerce\WcGateway\Endpoint\CaptureCardPayment;
|
||||||
|
use WooCommerce\PayPalCommerce\WcGateway\Exception\GatewayGenericException;
|
||||||
|
use WooCommerce\PayPalCommerce\WcGateway\Processor\AuthorizedPaymentsProcessor;
|
||||||
|
use WooCommerce\PayPalCommerce\WcGateway\Processor\OrderProcessor;
|
||||||
|
use WooCommerce\PayPalCommerce\WcGateway\Processor\PaymentsStatusHandlingTrait;
|
||||||
|
use WooCommerce\PayPalCommerce\WcGateway\Processor\RefundProcessor;
|
||||||
|
use WooCommerce\PayPalCommerce\WcGateway\Processor\TransactionIdHandlingTrait;
|
||||||
|
use WooCommerce\PayPalCommerce\WcGateway\Settings\SettingsRenderer;
|
||||||
|
use WooCommerce\PayPalCommerce\WcSubscriptions\FreeTrialHandlerTrait;
|
||||||
|
use WooCommerce\PayPalCommerce\WcSubscriptions\Helper\SubscriptionHelper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class CreditCardGateway
|
* Class CreditCardGateway
|
||||||
*/
|
*/
|
||||||
class CreditCardGateway extends \WC_Payment_Gateway_CC {
|
class CreditCardGateway extends \WC_Payment_Gateway_CC {
|
||||||
|
|
||||||
use ProcessPaymentTrait, GatewaySettingsRendererTrait, TransactionIdHandlingTrait;
|
use ProcessPaymentTrait, GatewaySettingsRendererTrait, TransactionIdHandlingTrait, PaymentsStatusHandlingTrait, FreeTrialHandlerTrait;
|
||||||
|
|
||||||
const ID = 'ppcp-credit-card-gateway';
|
const ID = 'ppcp-credit-card-gateway';
|
||||||
|
|
||||||
|
@ -114,13 +122,6 @@ class CreditCardGateway extends \WC_Payment_Gateway_CC {
|
||||||
*/
|
*/
|
||||||
protected $subscription_helper;
|
protected $subscription_helper;
|
||||||
|
|
||||||
/**
|
|
||||||
* The logger.
|
|
||||||
*
|
|
||||||
* @var LoggerInterface
|
|
||||||
*/
|
|
||||||
protected $logger;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The payments endpoint
|
* The payments endpoint
|
||||||
*
|
*
|
||||||
|
@ -128,6 +129,55 @@ class CreditCardGateway extends \WC_Payment_Gateway_CC {
|
||||||
*/
|
*/
|
||||||
protected $payments_endpoint;
|
protected $payments_endpoint;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The environment.
|
||||||
|
*
|
||||||
|
* @var Environment
|
||||||
|
*/
|
||||||
|
private $environment;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The order endpoint.
|
||||||
|
*
|
||||||
|
* @var OrderEndpoint
|
||||||
|
*/
|
||||||
|
private $order_endpoint;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Capture card payment.
|
||||||
|
*
|
||||||
|
* @var CaptureCardPayment
|
||||||
|
*/
|
||||||
|
private $capture_card_payment;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The prefix.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $prefix;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Payment tokens endpoint.
|
||||||
|
*
|
||||||
|
* @var PaymentTokensEndpoint
|
||||||
|
*/
|
||||||
|
private $payment_tokens_endpoint;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* WooCommerce payment tokens factory.
|
||||||
|
*
|
||||||
|
* @var WooCommercePaymentTokens
|
||||||
|
*/
|
||||||
|
private $wc_payment_tokens;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The logger.
|
||||||
|
*
|
||||||
|
* @var LoggerInterface
|
||||||
|
*/
|
||||||
|
protected $logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CreditCardGateway constructor.
|
* CreditCardGateway constructor.
|
||||||
*
|
*
|
||||||
|
@ -140,9 +190,15 @@ class CreditCardGateway extends \WC_Payment_Gateway_CC {
|
||||||
* @param State $state The state.
|
* @param State $state The state.
|
||||||
* @param TransactionUrlProvider $transaction_url_provider Service able to provide view transaction url base.
|
* @param TransactionUrlProvider $transaction_url_provider Service able to provide view transaction url base.
|
||||||
* @param SubscriptionHelper $subscription_helper The subscription helper.
|
* @param SubscriptionHelper $subscription_helper The subscription helper.
|
||||||
* @param LoggerInterface $logger The logger.
|
|
||||||
* @param PaymentsEndpoint $payments_endpoint The payments endpoint.
|
* @param PaymentsEndpoint $payments_endpoint The payments endpoint.
|
||||||
* @param VaultedCreditCardHandler $vaulted_credit_card_handler The vaulted credit card handler.
|
* @param VaultedCreditCardHandler $vaulted_credit_card_handler The vaulted credit card handler.
|
||||||
|
* @param Environment $environment The environment.
|
||||||
|
* @param OrderEndpoint $order_endpoint The order endpoint.
|
||||||
|
* @param CaptureCardPayment $capture_card_payment Capture card payment.
|
||||||
|
* @param string $prefix The prefix.
|
||||||
|
* @param PaymentTokensEndpoint $payment_tokens_endpoint Payment tokens endpoint.
|
||||||
|
* @param WooCommercePaymentTokens $wc_payment_tokens WooCommerce payment tokens factory.
|
||||||
|
* @param LoggerInterface $logger The logger.
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
SettingsRenderer $settings_renderer,
|
SettingsRenderer $settings_renderer,
|
||||||
|
@ -154,9 +210,15 @@ class CreditCardGateway extends \WC_Payment_Gateway_CC {
|
||||||
State $state,
|
State $state,
|
||||||
TransactionUrlProvider $transaction_url_provider,
|
TransactionUrlProvider $transaction_url_provider,
|
||||||
SubscriptionHelper $subscription_helper,
|
SubscriptionHelper $subscription_helper,
|
||||||
LoggerInterface $logger,
|
|
||||||
PaymentsEndpoint $payments_endpoint,
|
PaymentsEndpoint $payments_endpoint,
|
||||||
VaultedCreditCardHandler $vaulted_credit_card_handler
|
VaultedCreditCardHandler $vaulted_credit_card_handler,
|
||||||
|
Environment $environment,
|
||||||
|
OrderEndpoint $order_endpoint,
|
||||||
|
CaptureCardPayment $capture_card_payment,
|
||||||
|
string $prefix,
|
||||||
|
PaymentTokensEndpoint $payment_tokens_endpoint,
|
||||||
|
WooCommercePaymentTokens $wc_payment_tokens,
|
||||||
|
LoggerInterface $logger
|
||||||
) {
|
) {
|
||||||
$this->id = self::ID;
|
$this->id = self::ID;
|
||||||
$this->settings_renderer = $settings_renderer;
|
$this->settings_renderer = $settings_renderer;
|
||||||
|
@ -168,9 +230,15 @@ class CreditCardGateway extends \WC_Payment_Gateway_CC {
|
||||||
$this->state = $state;
|
$this->state = $state;
|
||||||
$this->transaction_url_provider = $transaction_url_provider;
|
$this->transaction_url_provider = $transaction_url_provider;
|
||||||
$this->subscription_helper = $subscription_helper;
|
$this->subscription_helper = $subscription_helper;
|
||||||
$this->logger = $logger;
|
|
||||||
$this->payments_endpoint = $payments_endpoint;
|
$this->payments_endpoint = $payments_endpoint;
|
||||||
$this->vaulted_credit_card_handler = $vaulted_credit_card_handler;
|
$this->vaulted_credit_card_handler = $vaulted_credit_card_handler;
|
||||||
|
$this->environment = $environment;
|
||||||
|
$this->order_endpoint = $order_endpoint;
|
||||||
|
$this->capture_card_payment = $capture_card_payment;
|
||||||
|
$this->prefix = $prefix;
|
||||||
|
$this->payment_tokens_endpoint = $payment_tokens_endpoint;
|
||||||
|
$this->wc_payment_tokens = $wc_payment_tokens;
|
||||||
|
$this->logger = $logger;
|
||||||
|
|
||||||
if ( $state->current_state() === State::STATE_ONBOARDED ) {
|
if ( $state->current_state() === State::STATE_ONBOARDED ) {
|
||||||
$this->supports = array( 'refunds' );
|
$this->supports = array( 'refunds' );
|
||||||
|
@ -246,8 +314,10 @@ class CreditCardGateway extends \WC_Payment_Gateway_CC {
|
||||||
*/
|
*/
|
||||||
public function form() {
|
public function form() {
|
||||||
add_action( 'gettext', array( $this, 'replace_credit_card_cvv_label' ), 10, 3 );
|
add_action( 'gettext', array( $this, 'replace_credit_card_cvv_label' ), 10, 3 );
|
||||||
|
add_action( 'gettext', array( $this, 'replace_credit_card_cvv_placeholder' ), 10, 3 );
|
||||||
parent::form();
|
parent::form();
|
||||||
remove_action( 'gettext', 'replace_credit_card_cvv_label' );
|
remove_action( 'gettext', 'replace_credit_card_cvv_label' );
|
||||||
|
remove_action( 'gettext', 'replace_credit_card_cvv_placeholder' );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -267,6 +337,23 @@ class CreditCardGateway extends \WC_Payment_Gateway_CC {
|
||||||
return __( 'CVV', 'woocommerce-paypal-payments' );
|
return __( 'CVV', 'woocommerce-paypal-payments' );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace WooCommerce credit card CVV field placeholder.
|
||||||
|
*
|
||||||
|
* @param string $translation Translated text.
|
||||||
|
* @param string $text Original text to translate.
|
||||||
|
* @param string $domain Text domain.
|
||||||
|
*
|
||||||
|
* @return string Translated field.
|
||||||
|
*/
|
||||||
|
public function replace_credit_card_cvv_placeholder( string $translation, string $text, string $domain ): string {
|
||||||
|
if ( 'woocommerce' !== $domain || 'CVC' !== $text || ! apply_filters( 'woocommerce_paypal_payments_card_fields_translate_card_cvv', true ) ) {
|
||||||
|
return $translation;
|
||||||
|
}
|
||||||
|
|
||||||
|
return __( 'CVV', 'woocommerce-paypal-payments' );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the icons of the gateway.
|
* Returns the icons of the gateway.
|
||||||
*
|
*
|
||||||
|
@ -366,17 +453,67 @@ class CreditCardGateway extends \WC_Payment_Gateway_CC {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$saved_payment_card = WC()->session->get( 'ppcp_saved_payment_card' );
|
// phpcs:ignore WordPress.Security.NonceVerification.Missing
|
||||||
if ( $saved_payment_card ) {
|
$card_payment_token_id = wc_clean( wp_unslash( $_POST['wc-ppcp-credit-card-gateway-payment-token'] ?? '' ) );
|
||||||
if ( $saved_payment_card['payment_source'] === 'card' && $saved_payment_card['status'] === 'COMPLETED' ) {
|
|
||||||
$wc_order->update_meta_data( PayPalGateway::ORDER_ID_META_KEY, $saved_payment_card['order_id'] );
|
|
||||||
$wc_order->save_meta_data();
|
|
||||||
|
|
||||||
$this->update_transaction_id( $saved_payment_card['order_id'], $wc_order );
|
if ( $this->is_free_trial_order( $wc_order ) && $card_payment_token_id ) {
|
||||||
$wc_order->payment_complete();
|
$customer_tokens = $this->wc_payment_tokens->customer_tokens( get_current_user_id() );
|
||||||
WC()->session->set( 'ppcp_saved_payment_card', null );
|
foreach ( $customer_tokens as $token ) {
|
||||||
|
if ( $token['payment_source']->name() === 'card' ) {
|
||||||
|
$wc_order->payment_complete();
|
||||||
|
return $this->handle_payment_success( $wc_order );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return $this->handle_payment_success( $wc_order );
|
if ( $card_payment_token_id ) {
|
||||||
|
$customer_tokens = $this->wc_payment_tokens->customer_tokens( get_current_user_id() );
|
||||||
|
|
||||||
|
$wc_tokens = WC_Payment_Tokens::get_customer_tokens( get_current_user_id(), self::ID );
|
||||||
|
|
||||||
|
if ( $customer_tokens && empty( $wc_tokens ) ) {
|
||||||
|
$this->wc_payment_tokens->create_wc_tokens( $customer_tokens, get_current_user_id() );
|
||||||
|
}
|
||||||
|
|
||||||
|
$customer_token_ids = array();
|
||||||
|
foreach ( $customer_tokens as $customer_token ) {
|
||||||
|
$customer_token_ids[] = $customer_token['id'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$tokens = WC_Payment_Tokens::get_customer_tokens( get_current_user_id() );
|
||||||
|
foreach ( $tokens as $token ) {
|
||||||
|
if ( $token->get_id() === (int) $card_payment_token_id ) {
|
||||||
|
if ( ! in_array( $token->get_token(), $customer_token_ids, true ) ) {
|
||||||
|
$token->delete();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$custom_id = $wc_order->get_order_number();
|
||||||
|
$invoice_id = $this->prefix . $wc_order->get_order_number();
|
||||||
|
$create_order = $this->capture_card_payment->create_order( $token->get_token(), $custom_id, $invoice_id );
|
||||||
|
|
||||||
|
$order = $this->order_endpoint->order( $create_order->id );
|
||||||
|
$wc_order->update_meta_data( PayPalGateway::INTENT_META_KEY, $order->intent() );
|
||||||
|
|
||||||
|
if ( $order->intent() === 'AUTHORIZE' ) {
|
||||||
|
$order = $this->order_endpoint->authorize( $order );
|
||||||
|
|
||||||
|
$wc_order->update_meta_data( AuthorizedPaymentsProcessor::CAPTURED_META_KEY, 'false' );
|
||||||
|
|
||||||
|
if ( $this->subscription_helper->has_subscription( $wc_order->get_id() ) ) {
|
||||||
|
$wc_order->update_meta_data( '_ppcp_captured_vault_webhook', 'false' );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$transaction_id = $this->get_paypal_order_transaction_id( $order );
|
||||||
|
if ( $transaction_id ) {
|
||||||
|
$this->update_transaction_id( $transaction_id, $wc_order );
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->handle_new_order_status( $order, $wc_order );
|
||||||
|
|
||||||
|
return $this->handle_payment_success( $wc_order );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,12 +14,14 @@ use Psr\Log\LoggerInterface;
|
||||||
use WC_Order;
|
use WC_Order;
|
||||||
use WC_Payment_Tokens;
|
use WC_Payment_Tokens;
|
||||||
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
|
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
|
||||||
|
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentTokensEndpoint;
|
||||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\OrderStatus;
|
use WooCommerce\PayPalCommerce\ApiClient\Entity\OrderStatus;
|
||||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentToken;
|
use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentToken;
|
||||||
use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
|
use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
|
||||||
use WooCommerce\PayPalCommerce\Onboarding\Environment;
|
use WooCommerce\PayPalCommerce\Onboarding\Environment;
|
||||||
use WooCommerce\PayPalCommerce\Onboarding\State;
|
use WooCommerce\PayPalCommerce\Onboarding\State;
|
||||||
use WooCommerce\PayPalCommerce\Session\SessionHandler;
|
use WooCommerce\PayPalCommerce\Session\SessionHandler;
|
||||||
|
use WooCommerce\PayPalCommerce\Vaulting\WooCommercePaymentTokens;
|
||||||
use WooCommerce\PayPalCommerce\WcSubscriptions\FreeTrialHandlerTrait;
|
use WooCommerce\PayPalCommerce\WcSubscriptions\FreeTrialHandlerTrait;
|
||||||
use WooCommerce\PayPalCommerce\WcSubscriptions\Helper\SubscriptionHelper;
|
use WooCommerce\PayPalCommerce\WcSubscriptions\Helper\SubscriptionHelper;
|
||||||
use WooCommerce\PayPalCommerce\Vaulting\PaymentTokenRepository;
|
use WooCommerce\PayPalCommerce\Vaulting\PaymentTokenRepository;
|
||||||
|
@ -48,9 +50,17 @@ class PayPalGateway extends \WC_Payment_Gateway {
|
||||||
const ORDER_ID_META_KEY = '_ppcp_paypal_order_id';
|
const ORDER_ID_META_KEY = '_ppcp_paypal_order_id';
|
||||||
const ORDER_PAYMENT_MODE_META_KEY = '_ppcp_paypal_payment_mode';
|
const ORDER_PAYMENT_MODE_META_KEY = '_ppcp_paypal_payment_mode';
|
||||||
const ORDER_PAYMENT_SOURCE_META_KEY = '_ppcp_paypal_payment_source';
|
const ORDER_PAYMENT_SOURCE_META_KEY = '_ppcp_paypal_payment_source';
|
||||||
|
const ORDER_PAYER_EMAIL_META_KEY = '_ppcp_paypal_payer_email';
|
||||||
const FEES_META_KEY = '_ppcp_paypal_fees';
|
const FEES_META_KEY = '_ppcp_paypal_fees';
|
||||||
const REFUND_FEES_META_KEY = '_ppcp_paypal_refund_fees';
|
const REFUND_FEES_META_KEY = '_ppcp_paypal_refund_fees';
|
||||||
const REFUNDS_META_KEY = '_ppcp_refunds';
|
const REFUNDS_META_KEY = '_ppcp_refunds';
|
||||||
|
const THREE_D_AUTH_RESULT_META_KEY = '_ppcp_paypal_3DS_auth_result';
|
||||||
|
const FRAUD_RESULT_META_KEY = '_ppcp_paypal_fraud_result';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of payment sources wich we are expected to store the payer email in the WC Order metadata.
|
||||||
|
*/
|
||||||
|
const PAYMENT_SOURCES_WITH_PAYER_EMAIL = array( 'paypal', 'paylater', 'venmo' );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Settings Renderer.
|
* The Settings Renderer.
|
||||||
|
@ -171,26 +181,50 @@ class PayPalGateway extends \WC_Payment_Gateway {
|
||||||
*/
|
*/
|
||||||
private $paypal_checkout_url_factory;
|
private $paypal_checkout_url_factory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Payment tokens endpoint.
|
||||||
|
*
|
||||||
|
* @var PaymentTokensEndpoint
|
||||||
|
*/
|
||||||
|
private $payment_tokens_endpoint;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether Vault v3 module is enabled.
|
||||||
|
*
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
private $vault_v3_enabled;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* WooCommerce payment tokens.
|
||||||
|
*
|
||||||
|
* @var WooCommercePaymentTokens
|
||||||
|
*/
|
||||||
|
private $wc_payment_tokens;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PayPalGateway constructor.
|
* PayPalGateway constructor.
|
||||||
*
|
*
|
||||||
* @param SettingsRenderer $settings_renderer The Settings Renderer.
|
* @param SettingsRenderer $settings_renderer The Settings Renderer.
|
||||||
* @param FundingSourceRenderer $funding_source_renderer The funding source renderer.
|
* @param FundingSourceRenderer $funding_source_renderer The funding source renderer.
|
||||||
* @param OrderProcessor $order_processor The Order Processor.
|
* @param OrderProcessor $order_processor The Order Processor.
|
||||||
* @param ContainerInterface $config The settings.
|
* @param ContainerInterface $config The settings.
|
||||||
* @param SessionHandler $session_handler The Session Handler.
|
* @param SessionHandler $session_handler The Session Handler.
|
||||||
* @param RefundProcessor $refund_processor The Refund Processor.
|
* @param RefundProcessor $refund_processor The Refund Processor.
|
||||||
* @param State $state The state.
|
* @param State $state The state.
|
||||||
* @param TransactionUrlProvider $transaction_url_provider Service providing transaction view URL based on order.
|
* @param TransactionUrlProvider $transaction_url_provider Service providing transaction view URL based on order.
|
||||||
* @param SubscriptionHelper $subscription_helper The subscription helper.
|
* @param SubscriptionHelper $subscription_helper The subscription helper.
|
||||||
* @param string $page_id ID of the current PPCP gateway settings page, or empty if it is not such page.
|
* @param string $page_id ID of the current PPCP gateway settings page, or empty if it is not such page.
|
||||||
* @param Environment $environment The environment.
|
* @param Environment $environment The environment.
|
||||||
* @param PaymentTokenRepository $payment_token_repository The payment token repository.
|
* @param PaymentTokenRepository $payment_token_repository The payment token repository.
|
||||||
* @param LoggerInterface $logger The logger.
|
* @param LoggerInterface $logger The logger.
|
||||||
* @param string $api_shop_country The api shop country.
|
* @param string $api_shop_country The api shop country.
|
||||||
* @param OrderEndpoint $order_endpoint The order endpoint.
|
* @param OrderEndpoint $order_endpoint The order endpoint.
|
||||||
* @param callable(string):string $paypal_checkout_url_factory The function return the PayPal checkout URL for the given order ID.
|
* @param callable(string):string $paypal_checkout_url_factory The function return the PayPal checkout URL for the given order ID.
|
||||||
* @param string $place_order_button_text The text for the standard "Place order" button.
|
* @param string $place_order_button_text The text for the standard "Place order" button.
|
||||||
|
* @param PaymentTokensEndpoint $payment_tokens_endpoint Payment tokens endpoint.
|
||||||
|
* @param bool $vault_v3_enabled Whether Vault v3 module is enabled.
|
||||||
|
* @param WooCommercePaymentTokens $wc_payment_tokens WooCommerce payment tokens.
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
SettingsRenderer $settings_renderer,
|
SettingsRenderer $settings_renderer,
|
||||||
|
@ -209,7 +243,10 @@ class PayPalGateway extends \WC_Payment_Gateway {
|
||||||
string $api_shop_country,
|
string $api_shop_country,
|
||||||
OrderEndpoint $order_endpoint,
|
OrderEndpoint $order_endpoint,
|
||||||
callable $paypal_checkout_url_factory,
|
callable $paypal_checkout_url_factory,
|
||||||
string $place_order_button_text
|
string $place_order_button_text,
|
||||||
|
PaymentTokensEndpoint $payment_tokens_endpoint,
|
||||||
|
bool $vault_v3_enabled,
|
||||||
|
WooCommercePaymentTokens $wc_payment_tokens
|
||||||
) {
|
) {
|
||||||
$this->id = self::ID;
|
$this->id = self::ID;
|
||||||
$this->settings_renderer = $settings_renderer;
|
$this->settings_renderer = $settings_renderer;
|
||||||
|
@ -229,6 +266,10 @@ class PayPalGateway extends \WC_Payment_Gateway {
|
||||||
$this->api_shop_country = $api_shop_country;
|
$this->api_shop_country = $api_shop_country;
|
||||||
$this->paypal_checkout_url_factory = $paypal_checkout_url_factory;
|
$this->paypal_checkout_url_factory = $paypal_checkout_url_factory;
|
||||||
$this->order_button_text = $place_order_button_text;
|
$this->order_button_text = $place_order_button_text;
|
||||||
|
$this->order_endpoint = $order_endpoint;
|
||||||
|
$this->payment_tokens_endpoint = $payment_tokens_endpoint;
|
||||||
|
$this->vault_v3_enabled = $vault_v3_enabled;
|
||||||
|
$this->wc_payment_tokens = $wc_payment_tokens;
|
||||||
|
|
||||||
if ( $this->onboarded ) {
|
if ( $this->onboarded ) {
|
||||||
$this->supports = array( 'refunds', 'tokenization' );
|
$this->supports = array( 'refunds', 'tokenization' );
|
||||||
|
@ -291,8 +332,6 @@ class PayPalGateway extends \WC_Payment_Gateway {
|
||||||
'process_admin_options',
|
'process_admin_options',
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->order_endpoint = $order_endpoint;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -394,13 +433,7 @@ class PayPalGateway extends \WC_Payment_Gateway {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( $this->is_pay_later_tab() ) {
|
if ( $this->is_pay_later_tab() ) {
|
||||||
return sprintf(
|
return '';
|
||||||
// translators: %1$s is </ br> HTML tag and %2$s, %3$s are the opening and closing of HTML <i> tag.
|
|
||||||
__( 'Let customers pay over time while you get paid up front — at no additional cost.%1$sPayPal’s pay later options are boosting merchant conversion rates and increasing cart sizes by 39%%. %2$s(PayPal Q2 Earnings-2021.)%3$s', 'woocommerce-paypal-payments' ),
|
|
||||||
'</ br>',
|
|
||||||
'<i>',
|
|
||||||
'</ i>'
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( is_admin() ) {
|
if ( is_admin() ) {
|
||||||
|
@ -498,7 +531,49 @@ class PayPalGateway extends \WC_Payment_Gateway {
|
||||||
$wc_order->save();
|
$wc_order->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( 'card' !== $funding_source && $this->is_free_trial_order( $wc_order ) && ! $this->subscription_helper->paypal_subscription_id() ) {
|
if (
|
||||||
|
'card' !== $funding_source
|
||||||
|
&& $this->is_free_trial_order( $wc_order )
|
||||||
|
&& ! $this->subscription_helper->paypal_subscription_id()
|
||||||
|
) {
|
||||||
|
$ppcp_guest_payment_for_free_trial = WC()->session->get( 'ppcp_guest_payment_for_free_trial' ) ?? null;
|
||||||
|
if ( $this->vault_v3_enabled && $ppcp_guest_payment_for_free_trial ) {
|
||||||
|
$customer_id = $ppcp_guest_payment_for_free_trial->customer->id ?? '';
|
||||||
|
if ( $customer_id ) {
|
||||||
|
update_user_meta( $wc_order->get_customer_id(), '_ppcp_target_customer_id', $customer_id );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( isset( $ppcp_guest_payment_for_free_trial->payment_source->paypal ) ) {
|
||||||
|
$email = '';
|
||||||
|
if ( isset( $ppcp_guest_payment_for_free_trial->payment_source->paypal->email_address ) ) {
|
||||||
|
$email = $ppcp_guest_payment_for_free_trial->payment_source->paypal->email_address;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->wc_payment_tokens->create_payment_token_paypal(
|
||||||
|
$wc_order->get_customer_id(),
|
||||||
|
$ppcp_guest_payment_for_free_trial->id,
|
||||||
|
$email
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
WC()->session->set( 'ppcp_guest_payment_for_free_trial', null );
|
||||||
|
|
||||||
|
$wc_order->payment_complete();
|
||||||
|
return $this->handle_payment_success( $wc_order );
|
||||||
|
}
|
||||||
|
|
||||||
|
$customer_id = get_user_meta( $wc_order->get_customer_id(), '_ppcp_target_customer_id', true );
|
||||||
|
if ( $customer_id ) {
|
||||||
|
$customer_tokens = $this->payment_tokens_endpoint->payment_tokens_for_customer( $customer_id );
|
||||||
|
foreach ( $customer_tokens as $token ) {
|
||||||
|
$payment_source_name = $token['payment_source']->name() ?? '';
|
||||||
|
if ( $payment_source_name === 'paypal' || $payment_source_name === 'venmo' ) {
|
||||||
|
$wc_order->payment_complete();
|
||||||
|
return $this->handle_payment_success( $wc_order );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$user_id = (int) $wc_order->get_customer_id();
|
$user_id = (int) $wc_order->get_customer_id();
|
||||||
$tokens = $this->payment_token_repository->all_for_user_id( $user_id );
|
$tokens = $this->payment_token_repository->all_for_user_id( $user_id );
|
||||||
if ( ! array_filter(
|
if ( ! array_filter(
|
||||||
|
@ -511,7 +586,6 @@ class PayPalGateway extends \WC_Payment_Gateway {
|
||||||
}
|
}
|
||||||
|
|
||||||
$wc_order->payment_complete();
|
$wc_order->payment_complete();
|
||||||
|
|
||||||
return $this->handle_payment_success( $wc_order );
|
return $this->handle_payment_success( $wc_order );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -198,25 +198,41 @@ class PayUponInvoiceGateway extends WC_Payment_Gateway {
|
||||||
'description' => __( "Specify brand name, logo and customer service instructions to be presented on Ratepay's payment instructions.", 'woocommerce-paypal-payments' ),
|
'description' => __( "Specify brand name, logo and customer service instructions to be presented on Ratepay's payment instructions.", 'woocommerce-paypal-payments' ),
|
||||||
),
|
),
|
||||||
'brand_name' => array(
|
'brand_name' => array(
|
||||||
'title' => __( 'Brand name', 'woocommerce-paypal-payments' ),
|
'title' => __( 'Brand name', 'woocommerce-paypal-payments' ),
|
||||||
'type' => 'text',
|
'type' => 'text',
|
||||||
'default' => get_bloginfo( 'name' ) ?? '',
|
'default' => get_bloginfo( 'name' ) ?? '',
|
||||||
'desc_tip' => true,
|
'desc_tip' => true,
|
||||||
'description' => __( 'Merchant name displayed in Ratepay\'s payment instructions.', 'woocommerce-paypal-payments' ),
|
'description' => __( 'Merchant name displayed in Ratepay\'s payment instructions. Should not exceed 127 characters.', 'woocommerce-paypal-payments' ),
|
||||||
|
'maxlength' => 127,
|
||||||
|
'custom_attributes' => array(
|
||||||
|
'pattern' => '.{1,127}',
|
||||||
|
'autocomplete' => 'off',
|
||||||
|
'required' => '',
|
||||||
|
),
|
||||||
),
|
),
|
||||||
'logo_url' => array(
|
'logo_url' => array(
|
||||||
'title' => __( 'Logo URL', 'woocommerce-paypal-payments' ),
|
'title' => __( 'Logo URL', 'woocommerce-paypal-payments' ),
|
||||||
'type' => 'url',
|
'type' => 'url',
|
||||||
'default' => '',
|
'default' => '',
|
||||||
'desc_tip' => true,
|
'desc_tip' => true,
|
||||||
'description' => __( 'Logo to be presented on Ratepay\'s payment instructions.', 'woocommerce-paypal-payments' ),
|
'description' => __( 'Logo to be presented on Ratepay\'s payment instructions.', 'woocommerce-paypal-payments' ),
|
||||||
|
'custom_attributes' => array(
|
||||||
|
'pattern' => '.+',
|
||||||
|
'autocomplete' => 'off',
|
||||||
|
'required' => '',
|
||||||
|
),
|
||||||
),
|
),
|
||||||
'customer_service_instructions' => array(
|
'customer_service_instructions' => array(
|
||||||
'title' => __( 'Customer service instructions', 'woocommerce-paypal-payments' ),
|
'title' => __( 'Customer service instructions', 'woocommerce-paypal-payments' ),
|
||||||
'type' => 'text',
|
'type' => 'text',
|
||||||
'default' => '',
|
'default' => '',
|
||||||
'desc_tip' => true,
|
'desc_tip' => true,
|
||||||
'description' => __( 'Customer service instructions to be presented on Ratepay\'s payment instructions.', 'woocommerce-paypal-payments' ),
|
'description' => __( 'Customer service instructions to be presented on Ratepay\'s payment instructions.', 'woocommerce-paypal-payments' ),
|
||||||
|
'custom_attributes' => array(
|
||||||
|
'pattern' => '.+',
|
||||||
|
'autocomplete' => 'off',
|
||||||
|
'required' => '',
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,8 @@ declare(strict_types=1);
|
||||||
namespace WooCommerce\PayPalCommerce\WcGateway\Processor;
|
namespace WooCommerce\PayPalCommerce\WcGateway\Processor;
|
||||||
|
|
||||||
use Exception;
|
use Exception;
|
||||||
|
use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
|
||||||
|
use WooCommerce\PayPalCommerce\ApiClient\Factory\AmountFactory;
|
||||||
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
|
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
use WC_Order;
|
use WC_Order;
|
||||||
|
@ -91,6 +93,20 @@ class AuthorizedPaymentsProcessor {
|
||||||
*/
|
*/
|
||||||
private $subscription_helper;
|
private $subscription_helper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The amount factory.
|
||||||
|
*
|
||||||
|
* @var AmountFactory
|
||||||
|
*/
|
||||||
|
private $amount_factory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The reauthorization failure reason.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $reauthorization_failure_reason = '';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AuthorizedPaymentsProcessor constructor.
|
* AuthorizedPaymentsProcessor constructor.
|
||||||
*
|
*
|
||||||
|
@ -100,6 +116,7 @@ class AuthorizedPaymentsProcessor {
|
||||||
* @param AuthorizeOrderActionNotice $notice The notice.
|
* @param AuthorizeOrderActionNotice $notice The notice.
|
||||||
* @param ContainerInterface $config The settings.
|
* @param ContainerInterface $config The settings.
|
||||||
* @param SubscriptionHelper $subscription_helper The subscription helper.
|
* @param SubscriptionHelper $subscription_helper The subscription helper.
|
||||||
|
* @param AmountFactory $amount_factory The amount factory.
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
OrderEndpoint $order_endpoint,
|
OrderEndpoint $order_endpoint,
|
||||||
|
@ -107,7 +124,8 @@ class AuthorizedPaymentsProcessor {
|
||||||
LoggerInterface $logger,
|
LoggerInterface $logger,
|
||||||
AuthorizeOrderActionNotice $notice,
|
AuthorizeOrderActionNotice $notice,
|
||||||
ContainerInterface $config,
|
ContainerInterface $config,
|
||||||
SubscriptionHelper $subscription_helper
|
SubscriptionHelper $subscription_helper,
|
||||||
|
AmountFactory $amount_factory
|
||||||
) {
|
) {
|
||||||
|
|
||||||
$this->order_endpoint = $order_endpoint;
|
$this->order_endpoint = $order_endpoint;
|
||||||
|
@ -116,6 +134,7 @@ class AuthorizedPaymentsProcessor {
|
||||||
$this->notice = $notice;
|
$this->notice = $notice;
|
||||||
$this->config = $config;
|
$this->config = $config;
|
||||||
$this->subscription_helper = $subscription_helper;
|
$this->subscription_helper = $subscription_helper;
|
||||||
|
$this->amount_factory = $amount_factory;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -249,6 +268,67 @@ class AuthorizedPaymentsProcessor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reauthorizes an authorized payment for an WooCommerce order.
|
||||||
|
*
|
||||||
|
* @param WC_Order $wc_order The WooCommerce order.
|
||||||
|
*
|
||||||
|
* @return string The status or reauthorization id.
|
||||||
|
*/
|
||||||
|
public function reauthorize_payment( WC_Order $wc_order ): string {
|
||||||
|
$this->reauthorization_failure_reason = '';
|
||||||
|
|
||||||
|
try {
|
||||||
|
$order = $this->paypal_order_from_wc_order( $wc_order );
|
||||||
|
} catch ( Exception $exception ) {
|
||||||
|
$this->logger->error( 'Could not get PayPal order from WC order: ' . $exception->getMessage() );
|
||||||
|
if ( $exception->getCode() === 404 ) {
|
||||||
|
return self::NOT_FOUND;
|
||||||
|
}
|
||||||
|
return self::INACCESSIBLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
$amount = $this->amount_factory->from_wc_order( $wc_order );
|
||||||
|
|
||||||
|
$authorizations = $this->all_authorizations( $order );
|
||||||
|
$uncaptured_authorizations = $this->authorizations_to_capture( ...$authorizations );
|
||||||
|
|
||||||
|
if ( ! $uncaptured_authorizations ) {
|
||||||
|
if ( $this->captured_authorizations( ...$authorizations ) ) {
|
||||||
|
$this->logger->info( 'Authorizations already captured.' );
|
||||||
|
return self::ALREADY_CAPTURED;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->logger->info( 'Bad authorization.' );
|
||||||
|
return self::BAD_AUTHORIZATION;
|
||||||
|
}
|
||||||
|
|
||||||
|
$authorization = end( $uncaptured_authorizations );
|
||||||
|
|
||||||
|
try {
|
||||||
|
$this->payments_endpoint->reauthorize( $authorization->id(), new Money( $amount->value(), $amount->currency_code() ) );
|
||||||
|
} catch ( PayPalApiException $exception ) {
|
||||||
|
$this->reauthorization_failure_reason = $exception->details()[0]->description ?? null;
|
||||||
|
$this->logger->error( 'Reauthorization failed: ' . $exception->name() . ' | ' . $this->reauthorization_failure_reason );
|
||||||
|
return self::FAILED;
|
||||||
|
|
||||||
|
} catch ( Exception $exception ) {
|
||||||
|
$this->logger->error( 'Failed to capture authorization: ' . $exception->getMessage() );
|
||||||
|
return self::FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::SUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The reason for a failed reauthorization.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function reauthorization_failure_reason(): string {
|
||||||
|
return $this->reauthorization_failure_reason;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Voids authorizations for the given PayPal order.
|
* Voids authorizations for the given PayPal order.
|
||||||
*
|
*
|
||||||
|
@ -392,4 +472,5 @@ class AuthorizedPaymentsProcessor {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,158 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Common operations performed for handling the ACDC order info.
|
||||||
|
*
|
||||||
|
* @package WooCommerce\PayPalCommerce\WcGateway\Processor
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace WooCommerce\PayPalCommerce\WcGateway\Processor;
|
||||||
|
|
||||||
|
use WC_Order;
|
||||||
|
use WooCommerce\PayPalCommerce\ApiClient\Entity\FraudProcessorResponse;
|
||||||
|
use WooCommerce\PayPalCommerce\ApiClient\Entity\Order;
|
||||||
|
use WooCommerce\PayPalCommerce\ApiClient\Factory\CardAuthenticationResultFactory;
|
||||||
|
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Trait CreditCardOrderInfoHandlingTrait.
|
||||||
|
*/
|
||||||
|
trait CreditCardOrderInfoHandlingTrait {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the 3DS details.
|
||||||
|
*
|
||||||
|
* Adds the order note with 3DS details.
|
||||||
|
* Adds the order meta with 3DS details.
|
||||||
|
*
|
||||||
|
* @param Order $order The PayPal order.
|
||||||
|
* @param WC_Order $wc_order The WC order.
|
||||||
|
*/
|
||||||
|
protected function handle_three_d_secure(
|
||||||
|
Order $order,
|
||||||
|
WC_Order $wc_order
|
||||||
|
): void {
|
||||||
|
|
||||||
|
$payment_source = $order->payment_source();
|
||||||
|
if ( ! $payment_source || $payment_source->name() !== 'card' ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$authentication_result = $payment_source->properties()->authentication_result ?? null;
|
||||||
|
|
||||||
|
if ( $authentication_result ) {
|
||||||
|
$card_authentication_result_factory = new CardAuthenticationResultFactory();
|
||||||
|
$result = $card_authentication_result_factory->from_paypal_response( $authentication_result );
|
||||||
|
|
||||||
|
$three_d_response_order_note_title = __( '3DS Authentication Result', 'woocommerce-paypal-payments' );
|
||||||
|
/* translators: %1$s is 3DS order note title, %2$s is 3DS order note result markup */
|
||||||
|
$three_d_response_order_note_format = __( '%1$s %2$s', 'woocommerce-paypal-payments' );
|
||||||
|
$three_d_response_order_note_result_format = '<ul class="ppcp_3ds_result">
|
||||||
|
<li>%1$s</li>
|
||||||
|
<li>%2$s</li>
|
||||||
|
<li>%3$s</li>
|
||||||
|
</ul>';
|
||||||
|
$three_d_response_order_note_result = sprintf(
|
||||||
|
$three_d_response_order_note_result_format,
|
||||||
|
/* translators: %s is liability shift */
|
||||||
|
sprintf( __( 'Liability Shift: %s', 'woocommerce-paypal-payments' ), esc_html( $result->liability_shift() ) ),
|
||||||
|
/* translators: %s is enrollment status */
|
||||||
|
sprintf( __( 'Enrollment Status: %s', 'woocommerce-paypal-payments' ), esc_html( $result->enrollment_status() ) ),
|
||||||
|
/* translators: %s is authentication status */
|
||||||
|
sprintf( __( 'Authentication Status: %s', 'woocommerce-paypal-payments' ), esc_html( $result->authentication_result() ) )
|
||||||
|
);
|
||||||
|
$three_d_response_order_note = sprintf(
|
||||||
|
$three_d_response_order_note_format,
|
||||||
|
esc_html( $three_d_response_order_note_title ),
|
||||||
|
wp_kses_post( $three_d_response_order_note_result )
|
||||||
|
);
|
||||||
|
|
||||||
|
$wc_order->add_order_note( $three_d_response_order_note );
|
||||||
|
|
||||||
|
$wc_order->update_meta_data( PayPalGateway::THREE_D_AUTH_RESULT_META_KEY, $result->to_array() );
|
||||||
|
$wc_order->save_meta_data();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fired when the 3DS information is added to WC order.
|
||||||
|
*/
|
||||||
|
do_action( 'woocommerce_paypal_payments_three_d_secure_added', $wc_order, $order );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the fraud processor response details.
|
||||||
|
*
|
||||||
|
* Adds the order note with the fraud processor response details.
|
||||||
|
* Adds the order meta with the fraud processor response details.
|
||||||
|
*
|
||||||
|
* @param FraudProcessorResponse $fraud The fraud processor response (AVS, CVV ...).
|
||||||
|
* @param Order $order The PayPal order.
|
||||||
|
* @param WC_Order $wc_order The WC order.
|
||||||
|
*/
|
||||||
|
protected function handle_fraud( FraudProcessorResponse $fraud, Order $order, WC_Order $wc_order ): void {
|
||||||
|
$payment_source = $order->payment_source();
|
||||||
|
if ( ! $payment_source || $payment_source->name() !== 'card' ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$fraud_responses = $fraud->to_array();
|
||||||
|
$card_brand = $payment_source->properties()->brand ?? __( 'N/A', 'woocommerce-paypal-payments' );
|
||||||
|
$card_last_digits = $payment_source->properties()->last_digits ?? __( 'N/A', 'woocommerce-paypal-payments' );
|
||||||
|
|
||||||
|
$avs_response_order_note_title = __( 'Address Verification Result', 'woocommerce-paypal-payments' );
|
||||||
|
/* translators: %1$s is AVS order note title, %2$s is AVS order note result markup */
|
||||||
|
$avs_response_order_note_format = __( '%1$s %2$s', 'woocommerce-paypal-payments' );
|
||||||
|
$avs_response_order_note_result_format = '<ul class="ppcp_avs_result">
|
||||||
|
<li>%1$s</li>
|
||||||
|
<ul class="ppcp_avs_result_inner">
|
||||||
|
<li>%2$s</li>
|
||||||
|
<li>%3$s</li>
|
||||||
|
</ul>
|
||||||
|
<li>%4$s</li>
|
||||||
|
<li>%5$s</li>
|
||||||
|
</ul>';
|
||||||
|
$avs_response_order_note_result = sprintf(
|
||||||
|
$avs_response_order_note_result_format,
|
||||||
|
/* translators: %s is fraud AVS code */
|
||||||
|
sprintf( __( 'AVS: %s', 'woocommerce-paypal-payments' ), esc_html( $fraud_responses['avs_code'] ) ),
|
||||||
|
/* translators: %s is fraud AVS address match */
|
||||||
|
sprintf( __( 'Address Match: %s', 'woocommerce-paypal-payments' ), esc_html( $fraud_responses['address_match'] ) ),
|
||||||
|
/* translators: %s is fraud AVS postal match */
|
||||||
|
sprintf( __( 'Postal Match: %s', 'woocommerce-paypal-payments' ), esc_html( $fraud_responses['postal_match'] ) ),
|
||||||
|
/* translators: %s is card brand */
|
||||||
|
sprintf( __( 'Card Brand: %s', 'woocommerce-paypal-payments' ), esc_html( $card_brand ) ),
|
||||||
|
/* translators: %s card last digits */
|
||||||
|
sprintf( __( 'Card Last Digits: %s', 'woocommerce-paypal-payments' ), esc_html( $card_last_digits ) )
|
||||||
|
);
|
||||||
|
$avs_response_order_note = sprintf(
|
||||||
|
$avs_response_order_note_format,
|
||||||
|
esc_html( $avs_response_order_note_title ),
|
||||||
|
wp_kses_post( $avs_response_order_note_result )
|
||||||
|
);
|
||||||
|
$wc_order->add_order_note( $avs_response_order_note );
|
||||||
|
|
||||||
|
$cvv_response_order_note_format = '<ul class="ppcp_cvv_result"><li>%1$s</li></ul>';
|
||||||
|
$cvv_response_order_note = sprintf(
|
||||||
|
$cvv_response_order_note_format,
|
||||||
|
/* translators: %s is fraud CVV match */
|
||||||
|
sprintf( __( 'CVV2 Match: %s', 'woocommerce-paypal-payments' ), esc_html( $fraud_responses['cvv_match'] ) )
|
||||||
|
);
|
||||||
|
$wc_order->add_order_note( $cvv_response_order_note );
|
||||||
|
|
||||||
|
$meta_details = array_merge(
|
||||||
|
$fraud_responses,
|
||||||
|
array(
|
||||||
|
'card_brand' => $card_brand,
|
||||||
|
'card_last_digits' => $card_last_digits,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$wc_order->update_meta_data( PayPalGateway::FRAUD_RESULT_META_KEY, $meta_details );
|
||||||
|
$wc_order->save_meta_data();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fired when the fraud result information is added to WC order.
|
||||||
|
*/
|
||||||
|
do_action( 'woocommerce_paypal_payments_fraud_result_added', $wc_order, $order );
|
||||||
|
}
|
||||||
|
}
|
|
@ -45,6 +45,18 @@ trait OrderMetaTrait {
|
||||||
$wc_order->update_meta_data( PayPalGateway::ORDER_PAYMENT_SOURCE_META_KEY, $payment_source );
|
$wc_order->update_meta_data( PayPalGateway::ORDER_PAYMENT_SOURCE_META_KEY, $payment_source );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$payer = $order->payer();
|
||||||
|
if (
|
||||||
|
$payer
|
||||||
|
&& $payment_source
|
||||||
|
&& in_array( $payment_source, PayPalGateway::PAYMENT_SOURCES_WITH_PAYER_EMAIL, true )
|
||||||
|
) {
|
||||||
|
$payer_email = $payer->email_address();
|
||||||
|
if ( $payer_email ) {
|
||||||
|
$wc_order->update_meta_data( PayPalGateway::ORDER_PAYER_EMAIL_META_KEY, $payer_email );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$wc_order->save();
|
$wc_order->save();
|
||||||
|
|
||||||
do_action( 'woocommerce_paypal_payments_woocommerce_order_created', $wc_order, $order );
|
do_action( 'woocommerce_paypal_payments_woocommerce_order_created', $wc_order, $order );
|
||||||
|
|
|
@ -112,6 +112,10 @@ trait PaymentsStatusHandlingTrait {
|
||||||
'on-hold',
|
'on-hold',
|
||||||
__( 'Awaiting payment.', 'woocommerce-paypal-payments' )
|
__( 'Awaiting payment.', 'woocommerce-paypal-payments' )
|
||||||
);
|
);
|
||||||
|
/**
|
||||||
|
* Fired when PayPal order is authorized.
|
||||||
|
*/
|
||||||
|
do_action( 'woocommerce_paypal_payments_order_authorized', $wc_order, $authorization );
|
||||||
break;
|
break;
|
||||||
case AuthorizationStatus::DENIED:
|
case AuthorizationStatus::DENIED:
|
||||||
$wc_order->update_status(
|
$wc_order->update_status(
|
||||||
|
|
|
@ -22,6 +22,8 @@ use WooCommerce\PayPalCommerce\ApiClient\Entity\Order;
|
||||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Payments;
|
use WooCommerce\PayPalCommerce\ApiClient\Entity\Payments;
|
||||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\RefundCapture;
|
use WooCommerce\PayPalCommerce\ApiClient\Entity\RefundCapture;
|
||||||
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||||
|
use WooCommerce\PayPalCommerce\WcGateway\Gateway\CardButtonGateway;
|
||||||
|
use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway;
|
||||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
||||||
use WooCommerce\PayPalCommerce\WcGateway\Helper\RefundFeesUpdater;
|
use WooCommerce\PayPalCommerce\WcGateway\Helper\RefundFeesUpdater;
|
||||||
|
|
||||||
|
@ -107,6 +109,10 @@ class RefundProcessor {
|
||||||
*/
|
*/
|
||||||
public function process( WC_Order $wc_order, float $amount = null, string $reason = '' ) : bool {
|
public function process( WC_Order $wc_order, float $amount = null, string $reason = '' ) : bool {
|
||||||
try {
|
try {
|
||||||
|
if ( ! in_array( $wc_order->get_payment_method(), array( PayPalGateway::ID, CreditCardGateway::ID, CardButtonGateway::ID ), true ) ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
$order_id = $wc_order->get_meta( PayPalGateway::ORDER_ID_META_KEY );
|
$order_id = $wc_order->get_meta( PayPalGateway::ORDER_ID_META_KEY );
|
||||||
if ( ! $order_id ) {
|
if ( ! $order_id ) {
|
||||||
throw new RuntimeException( 'PayPal order ID not found in meta.' );
|
throw new RuntimeException( 'PayPal order ID not found in meta.' );
|
||||||
|
|
|
@ -65,7 +65,7 @@ return function ( ContainerInterface $container, array $fields ): array {
|
||||||
<a href="https://woo.com/document/woocommerce-paypal-payments/#paypal-card-processing-acdc" target="_blank"><img alt="American Express" src="' . esc_url( $module_url ) . 'assets/images/amex.svg"/></a>
|
<a href="https://woo.com/document/woocommerce-paypal-payments/#paypal-card-processing-acdc" target="_blank"><img alt="American Express" src="' . esc_url( $module_url ) . 'assets/images/amex.svg"/></a>
|
||||||
<a href="https://woo.com/document/woocommerce-paypal-payments/#paypal-card-processing-acdc" target="_blank"><img alt="Discover" src="' . esc_url( $module_url ) . 'assets/images/discover.svg"/></a>
|
<a href="https://woo.com/document/woocommerce-paypal-payments/#paypal-card-processing-acdc" target="_blank"><img alt="Discover" src="' . esc_url( $module_url ) . 'assets/images/discover.svg"/></a>
|
||||||
<a href="https://woo.com/document/woocommerce-paypal-payments/#alternative-payment-methods" target="_blank"><img alt="iDEAL" src="' . esc_url( $module_url ) . 'assets/images/ideal-dark.svg"/></a>
|
<a href="https://woo.com/document/woocommerce-paypal-payments/#alternative-payment-methods" target="_blank"><img alt="iDEAL" src="' . esc_url( $module_url ) . 'assets/images/ideal-dark.svg"/></a>
|
||||||
<a href="https://woo.com/document/woocommerce-paypal-payments/#alternative-payment-methods" target="_blank"><img alt="Sofort" src="' . esc_url( $module_url ) . 'assets/images/sofort.svg"/></a>
|
<a href="https://woo.com/document/woocommerce-paypal-payments/#alternative-payment-methods" target="_blank"><img alt="BLIK" src="' . esc_url( $module_url ) . 'assets/images/blik.svg"/></a>
|
||||||
</div>
|
</div>
|
||||||
<div class="ppcp-onboarding-header-apm-logos">
|
<div class="ppcp-onboarding-header-apm-logos">
|
||||||
<a href="https://woo.com/document/woocommerce-paypal-payments/#apple-pay" target="_blank"><img alt="Apple Pay" src="' . esc_url( $module_url ) . 'assets/images/button-Apple-Pay.png"/></a>
|
<a href="https://woo.com/document/woocommerce-paypal-payments/#apple-pay" target="_blank"><img alt="Apple Pay" src="' . esc_url( $module_url ) . 'assets/images/button-Apple-Pay.png"/></a>
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue