mirror of
https://github.com/woocommerce/woocommerce-paypal-payments.git
synced 2025-09-06 18:16:38 +08:00
Merge branch 'trunk' into fix/PCP-696-improve-error-message
This commit is contained in:
commit
027def77b4
126 changed files with 9521 additions and 789 deletions
|
@ -9,6 +9,14 @@ declare(strict_types=1);
|
|||
|
||||
namespace WooCommerce\PayPalCommerce\ApiClient;
|
||||
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\BillingSubscriptions;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\CatalogProducts;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\BillingPlans;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Factory\BillingCycleFactory;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Factory\PaymentPreferencesFactory;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Factory\PlanFactory;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Factory\ProductFactory;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Factory\ShippingOptionFactory;
|
||||
use WooCommerce\PayPalCommerce\Session\SessionHandler;
|
||||
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Authentication\Bearer;
|
||||
|
@ -209,6 +217,30 @@ return array(
|
|||
$container->get( 'woocommerce.logger.woocommerce' )
|
||||
);
|
||||
},
|
||||
'api.endpoint.catalog-products' => static function ( ContainerInterface $container ): CatalogProducts {
|
||||
return new CatalogProducts(
|
||||
$container->get( 'api.host' ),
|
||||
$container->get( 'api.bearer' ),
|
||||
$container->get( 'api.factory.product' ),
|
||||
$container->get( 'woocommerce.logger.woocommerce' )
|
||||
);
|
||||
},
|
||||
'api.endpoint.billing-plans' => static function( ContainerInterface $container ): BillingPlans {
|
||||
return new BillingPlans(
|
||||
$container->get( 'api.host' ),
|
||||
$container->get( 'api.bearer' ),
|
||||
$container->get( 'api.factory.billing-cycle' ),
|
||||
$container->get( 'api.factory.plan' ),
|
||||
$container->get( 'woocommerce.logger.woocommerce' )
|
||||
);
|
||||
},
|
||||
'api.endpoint.billing-subscriptions' => static function( ContainerInterface $container ): BillingSubscriptions {
|
||||
return new BillingSubscriptions(
|
||||
$container->get( 'api.host' ),
|
||||
$container->get( 'api.bearer' ),
|
||||
$container->get( 'woocommerce.logger.woocommerce' )
|
||||
);
|
||||
},
|
||||
'api.repository.application-context' => static function( ContainerInterface $container ) : ApplicationContextRepository {
|
||||
|
||||
$settings = $container->get( 'wcgateway.settings' );
|
||||
|
@ -289,12 +321,19 @@ return array(
|
|||
);
|
||||
},
|
||||
'api.factory.shipping' => static function ( ContainerInterface $container ): ShippingFactory {
|
||||
$address_factory = $container->get( 'api.factory.address' );
|
||||
return new ShippingFactory( $address_factory );
|
||||
return new ShippingFactory(
|
||||
$container->get( 'api.factory.address' ),
|
||||
$container->get( 'api.factory.shipping-option' )
|
||||
);
|
||||
},
|
||||
'api.factory.shipping-preference' => static function ( ContainerInterface $container ): ShippingPreferenceFactory {
|
||||
return new ShippingPreferenceFactory();
|
||||
},
|
||||
'api.factory.shipping-option' => static function ( ContainerInterface $container ): ShippingOptionFactory {
|
||||
return new ShippingOptionFactory(
|
||||
$container->get( 'api.factory.money' )
|
||||
);
|
||||
},
|
||||
'api.factory.amount' => static function ( ContainerInterface $container ): AmountFactory {
|
||||
$item_factory = $container->get( 'api.factory.item' );
|
||||
return new AmountFactory(
|
||||
|
@ -357,6 +396,21 @@ return array(
|
|||
'api.factory.fraud-processor-response' => static function ( ContainerInterface $container ): FraudProcessorResponseFactory {
|
||||
return new FraudProcessorResponseFactory();
|
||||
},
|
||||
'api.factory.product' => static function( ContainerInterface $container ): ProductFactory {
|
||||
return new ProductFactory();
|
||||
},
|
||||
'api.factory.billing-cycle' => static function( ContainerInterface $container ): BillingCycleFactory {
|
||||
return new BillingCycleFactory( $container->get( 'api.shop.currency' ) );
|
||||
},
|
||||
'api.factory.payment-preferences' => static function( ContainerInterface $container ):PaymentPreferencesFactory {
|
||||
return new PaymentPreferencesFactory( $container->get( 'api.shop.currency' ) );
|
||||
},
|
||||
'api.factory.plan' => static function( ContainerInterface $container ): PlanFactory {
|
||||
return new PlanFactory(
|
||||
$container->get( 'api.factory.billing-cycle' ),
|
||||
$container->get( 'api.factory.payment-preferences' )
|
||||
);
|
||||
},
|
||||
'api.helpers.dccapplies' => static function ( ContainerInterface $container ) : DccApplies {
|
||||
return new DccApplies(
|
||||
$container->get( 'api.dcc-supported-country-currency-matrix' ),
|
||||
|
@ -631,6 +685,27 @@ return array(
|
|||
'SGD',
|
||||
'USD',
|
||||
),
|
||||
'MX' => array(
|
||||
'MXN',
|
||||
),
|
||||
'JP' => array(
|
||||
'AUD',
|
||||
'CAD',
|
||||
'CHF',
|
||||
'CZK',
|
||||
'DKK',
|
||||
'EUR',
|
||||
'GBP',
|
||||
'HKD',
|
||||
'HUF',
|
||||
'JPY',
|
||||
'NOK',
|
||||
'NZD',
|
||||
'PLN',
|
||||
'SEK',
|
||||
'SGD',
|
||||
'USD',
|
||||
),
|
||||
)
|
||||
);
|
||||
},
|
||||
|
@ -687,6 +762,17 @@ return array(
|
|||
'amex' => array( 'CAD' ),
|
||||
'jcb' => array( 'CAD' ),
|
||||
),
|
||||
'MX' => array(
|
||||
'mastercard' => array(),
|
||||
'visa' => array(),
|
||||
'amex' => array(),
|
||||
),
|
||||
'JP' => array(
|
||||
'mastercard' => array(),
|
||||
'visa' => array(),
|
||||
'amex' => array( 'JPY' ),
|
||||
'jcb' => array( 'JPY' ),
|
||||
),
|
||||
)
|
||||
);
|
||||
},
|
||||
|
|
|
@ -9,6 +9,7 @@ declare(strict_types=1);
|
|||
|
||||
namespace WooCommerce\PayPalCommerce\ApiClient\Endpoint;
|
||||
|
||||
use Exception;
|
||||
use stdClass;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Authentication\Bearer;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
|
||||
|
@ -120,6 +121,10 @@ class BillingAgreementsEndpoint {
|
|||
*/
|
||||
public function reference_transaction_enabled(): bool {
|
||||
try {
|
||||
if ( get_transient( 'ppcp_reference_transaction_enabled' ) === true ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$this->is_request_logging_enabled = false;
|
||||
|
||||
try {
|
||||
|
@ -130,10 +135,12 @@ class BillingAgreementsEndpoint {
|
|||
);
|
||||
} finally {
|
||||
$this->is_request_logging_enabled = true;
|
||||
set_transient( 'ppcp_reference_transaction_enabled', true, 3 * MONTH_IN_SECONDS );
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch ( PayPalApiException $exception ) {
|
||||
} catch ( Exception $exception ) {
|
||||
delete_transient( 'ppcp_reference_transaction_enabled' );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
229
modules/ppcp-api-client/src/Endpoint/BillingPlans.php
Normal file
229
modules/ppcp-api-client/src/Endpoint/BillingPlans.php
Normal file
|
@ -0,0 +1,229 @@
|
|||
<?php
|
||||
/**
|
||||
* The Billing Plans endpoint.
|
||||
*
|
||||
* @package WooCommerce\PayPalCommerce\ApiClient\Endpoint
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\ApiClient\Endpoint;
|
||||
|
||||
use Psr\Log\LoggerInterface;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Authentication\Bearer;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\BillingCycle;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Plan;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Factory\BillingCycleFactory;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Factory\PlanFactory;
|
||||
|
||||
/**
|
||||
* Class BillingPlans
|
||||
*/
|
||||
class BillingPlans {
|
||||
|
||||
use RequestTrait;
|
||||
|
||||
/**
|
||||
* The host.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $host;
|
||||
|
||||
/**
|
||||
* The bearer.
|
||||
*
|
||||
* @var Bearer
|
||||
*/
|
||||
private $bearer;
|
||||
|
||||
/**
|
||||
* Billing cycle factory
|
||||
*
|
||||
* @var BillingCycleFactory
|
||||
*/
|
||||
private $billing_cycle_factory;
|
||||
|
||||
/**
|
||||
* Plan factory
|
||||
*
|
||||
* @var PlanFactory
|
||||
*/
|
||||
private $plan_factory;
|
||||
|
||||
/**
|
||||
* The logger.
|
||||
*
|
||||
* The logger.
|
||||
*
|
||||
* @var LoggerInterface
|
||||
*/
|
||||
private $logger;
|
||||
|
||||
/**
|
||||
* BillingPlans constructor.
|
||||
*
|
||||
* @param string $host The host.
|
||||
* @param Bearer $bearer The bearer.
|
||||
* @param BillingCycleFactory $billing_cycle_factory Billing cycle factory.
|
||||
* @param PlanFactory $plan_factory Plan factory.
|
||||
* @param LoggerInterface $logger The logger.
|
||||
*/
|
||||
public function __construct(
|
||||
string $host,
|
||||
Bearer $bearer,
|
||||
BillingCycleFactory $billing_cycle_factory,
|
||||
PlanFactory $plan_factory,
|
||||
LoggerInterface $logger
|
||||
) {
|
||||
$this->host = $host;
|
||||
$this->bearer = $bearer;
|
||||
$this->billing_cycle_factory = $billing_cycle_factory;
|
||||
$this->plan_factory = $plan_factory;
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a subscription plan.
|
||||
*
|
||||
* @param string $name Product name.
|
||||
* @param string $product_id Product ID.
|
||||
* @param array $billing_cycles Billing cycles.
|
||||
* @param array $payment_preferences Payment preferences.
|
||||
*
|
||||
* @return Plan
|
||||
*
|
||||
* @throws RuntimeException If the request fails.
|
||||
* @throws PayPalApiException If the request fails.
|
||||
*/
|
||||
public function create(
|
||||
string $name,
|
||||
string $product_id,
|
||||
array $billing_cycles,
|
||||
array $payment_preferences
|
||||
): Plan {
|
||||
|
||||
$data = array(
|
||||
'name' => $name,
|
||||
'product_id' => $product_id,
|
||||
'billing_cycles' => $billing_cycles,
|
||||
'payment_preferences' => $payment_preferences,
|
||||
);
|
||||
|
||||
$bearer = $this->bearer->bearer();
|
||||
$url = trailingslashit( $this->host ) . 'v1/billing/plans';
|
||||
$args = array(
|
||||
'method' => 'POST',
|
||||
'headers' => array(
|
||||
'Authorization' => 'Bearer ' . $bearer->token(),
|
||||
'Content-Type' => 'application/json',
|
||||
'Prefer' => 'return=representation',
|
||||
),
|
||||
'body' => wp_json_encode( $data ),
|
||||
);
|
||||
|
||||
$response = $this->request( $url, $args );
|
||||
|
||||
if ( is_wp_error( $response ) || ! is_array( $response ) ) {
|
||||
throw new RuntimeException( 'Not able to create plan.' );
|
||||
}
|
||||
|
||||
$json = json_decode( $response['body'] );
|
||||
$status_code = (int) wp_remote_retrieve_response_code( $response );
|
||||
if ( 201 !== $status_code ) {
|
||||
throw new PayPalApiException(
|
||||
$json,
|
||||
$status_code
|
||||
);
|
||||
}
|
||||
|
||||
return $this->plan_factory->from_paypal_response( $json );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a plan,
|
||||
*
|
||||
* @param string $id Plan ID.
|
||||
*
|
||||
* @return Plan
|
||||
*
|
||||
* @throws RuntimeException If the request fails.
|
||||
* @throws PayPalApiException If the request fails.
|
||||
*/
|
||||
public function plan( string $id ): Plan {
|
||||
$bearer = $this->bearer->bearer();
|
||||
$url = trailingslashit( $this->host ) . 'v1/billing/plans/' . $id;
|
||||
$args = array(
|
||||
'headers' => array(
|
||||
'Authorization' => 'Bearer ' . $bearer->token(),
|
||||
'Content-Type' => 'application/json',
|
||||
'Prefer' => 'return=representation',
|
||||
),
|
||||
);
|
||||
|
||||
$response = $this->request( $url, $args );
|
||||
if ( is_wp_error( $response ) || ! is_array( $response ) ) {
|
||||
throw new RuntimeException( 'Not able to get plan.' );
|
||||
}
|
||||
|
||||
$json = json_decode( $response['body'] );
|
||||
$status_code = (int) wp_remote_retrieve_response_code( $response );
|
||||
if ( 200 !== $status_code ) {
|
||||
throw new PayPalApiException(
|
||||
$json,
|
||||
$status_code
|
||||
);
|
||||
}
|
||||
|
||||
return $this->plan_factory->from_paypal_response( $json );
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates pricing.
|
||||
*
|
||||
* @param string $id Plan ID.
|
||||
* @param BillingCycle $billing_cycle Billing cycle.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws RuntimeException If the request fails.
|
||||
* @throws PayPalApiException If the request fails.
|
||||
*/
|
||||
public function update_pricing( string $id, BillingCycle $billing_cycle ): void {
|
||||
$data = array(
|
||||
'pricing_schemes' => array(
|
||||
(object) array(
|
||||
'billing_cycle_sequence' => 1,
|
||||
'pricing_scheme' => $billing_cycle->pricing_scheme(),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
$bearer = $this->bearer->bearer();
|
||||
$url = trailingslashit( $this->host ) . 'v1/billing/plans/' . $id . '/update-pricing-schemes';
|
||||
$args = array(
|
||||
'method' => 'POST',
|
||||
'headers' => array(
|
||||
'Authorization' => 'Bearer ' . $bearer->token(),
|
||||
'Content-Type' => 'application/json',
|
||||
),
|
||||
'body' => wp_json_encode( $data ),
|
||||
);
|
||||
|
||||
$response = $this->request( $url, $args );
|
||||
if ( is_wp_error( $response ) || ! is_array( $response ) ) {
|
||||
throw new RuntimeException( 'Could not update pricing.' );
|
||||
}
|
||||
|
||||
$json = json_decode( $response['body'] );
|
||||
$status_code = (int) wp_remote_retrieve_response_code( $response );
|
||||
if ( 204 !== $status_code ) {
|
||||
throw new PayPalApiException(
|
||||
$json,
|
||||
$status_code
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
217
modules/ppcp-api-client/src/Endpoint/BillingSubscriptions.php
Normal file
217
modules/ppcp-api-client/src/Endpoint/BillingSubscriptions.php
Normal file
|
@ -0,0 +1,217 @@
|
|||
<?php
|
||||
/**
|
||||
* The Billing Subscriptions endpoint.
|
||||
*
|
||||
* @package WooCommerce\PayPalCommerce\ApiClient\Endpoint
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\ApiClient\Endpoint;
|
||||
|
||||
use Psr\Log\LoggerInterface;
|
||||
use stdClass;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Authentication\Bearer;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
|
||||
/**
|
||||
* Class BillingSubscriptions
|
||||
*/
|
||||
class BillingSubscriptions {
|
||||
|
||||
use RequestTrait;
|
||||
|
||||
/**
|
||||
* The host.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $host;
|
||||
|
||||
/**
|
||||
* The bearer.
|
||||
*
|
||||
* @var Bearer
|
||||
*/
|
||||
private $bearer;
|
||||
|
||||
/**
|
||||
* The logger.
|
||||
*
|
||||
* @var LoggerInterface
|
||||
*/
|
||||
private $logger;
|
||||
|
||||
/**
|
||||
* BillingSubscriptions constructor.
|
||||
*
|
||||
* @param string $host The host.
|
||||
* @param Bearer $bearer The bearer.
|
||||
* @param LoggerInterface $logger The logger.
|
||||
*/
|
||||
public function __construct( string $host, Bearer $bearer, LoggerInterface $logger ) {
|
||||
$this->host = $host;
|
||||
$this->bearer = $bearer;
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Suspends a subscription.
|
||||
*
|
||||
* @param string $id Subscription ID.
|
||||
* @return void
|
||||
*
|
||||
* @throws RuntimeException If the request fails.
|
||||
* @throws PayPalApiException If the request fails.
|
||||
*/
|
||||
public function suspend( string $id ):void {
|
||||
$data = array(
|
||||
'reason' => 'Suspended by customer',
|
||||
);
|
||||
|
||||
$bearer = $this->bearer->bearer();
|
||||
$url = trailingslashit( $this->host ) . 'v1/billing/subscriptions/' . $id . '/suspend';
|
||||
$args = array(
|
||||
'method' => 'POST',
|
||||
'headers' => array(
|
||||
'Authorization' => 'Bearer ' . $bearer->token(),
|
||||
'Content-Type' => 'application/json',
|
||||
),
|
||||
'body' => wp_json_encode( $data ),
|
||||
);
|
||||
|
||||
$response = $this->request( $url, $args );
|
||||
if ( is_wp_error( $response ) || ! is_array( $response ) ) {
|
||||
throw new RuntimeException( 'Not able to suspend subscription.' );
|
||||
}
|
||||
|
||||
$json = json_decode( $response['body'] );
|
||||
$status_code = (int) wp_remote_retrieve_response_code( $response );
|
||||
if ( 204 !== $status_code ) {
|
||||
throw new PayPalApiException(
|
||||
$json,
|
||||
$status_code
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Activates a subscription.
|
||||
*
|
||||
* @param string $id Subscription ID.
|
||||
* @return void
|
||||
*
|
||||
* @throws RuntimeException If the request fails.
|
||||
* @throws PayPalApiException If the request fails.
|
||||
*/
|
||||
public function activate( string $id ): void {
|
||||
$data = array(
|
||||
'reason' => 'Reactivated by customer',
|
||||
);
|
||||
|
||||
$bearer = $this->bearer->bearer();
|
||||
$url = trailingslashit( $this->host ) . 'v1/billing/subscriptions/' . $id . '/activate';
|
||||
$args = array(
|
||||
'method' => 'POST',
|
||||
'headers' => array(
|
||||
'Authorization' => 'Bearer ' . $bearer->token(),
|
||||
'Content-Type' => 'application/json',
|
||||
),
|
||||
'body' => wp_json_encode( $data ),
|
||||
);
|
||||
|
||||
$response = $this->request( $url, $args );
|
||||
if ( is_wp_error( $response ) || ! is_array( $response ) ) {
|
||||
throw new RuntimeException( 'Not able to reactivate subscription.' );
|
||||
}
|
||||
|
||||
$json = json_decode( $response['body'] );
|
||||
$status_code = (int) wp_remote_retrieve_response_code( $response );
|
||||
if ( 204 !== $status_code ) {
|
||||
throw new PayPalApiException(
|
||||
$json,
|
||||
$status_code
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancels a Subscription.
|
||||
*
|
||||
* @param string $id Subscription ID.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws RuntimeException If the request fails.
|
||||
* @throws PayPalApiException If the request fails.
|
||||
*/
|
||||
public function cancel( string $id ): void {
|
||||
$data = array(
|
||||
'reason' => 'Cancelled by customer',
|
||||
);
|
||||
|
||||
$bearer = $this->bearer->bearer();
|
||||
$url = trailingslashit( $this->host ) . 'v1/billing/subscriptions/' . $id . '/cancel';
|
||||
$args = array(
|
||||
'method' => 'POST',
|
||||
'headers' => array(
|
||||
'Authorization' => 'Bearer ' . $bearer->token(),
|
||||
'Content-Type' => 'application/json',
|
||||
),
|
||||
'body' => wp_json_encode( $data ),
|
||||
);
|
||||
|
||||
$response = $this->request( $url, $args );
|
||||
if ( is_wp_error( $response ) || ! is_array( $response ) ) {
|
||||
throw new RuntimeException( 'Not able to cancel subscription.' );
|
||||
}
|
||||
|
||||
$json = json_decode( $response['body'] );
|
||||
$status_code = (int) wp_remote_retrieve_response_code( $response );
|
||||
if ( 204 !== $status_code ) {
|
||||
throw new PayPalApiException(
|
||||
$json,
|
||||
$status_code
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a Subscription object from the given ID.
|
||||
*
|
||||
* @param string $id Subscription ID.
|
||||
*
|
||||
* @return stdClass
|
||||
*
|
||||
* @throws RuntimeException If the request fails.
|
||||
* @throws PayPalApiException If the request fails.
|
||||
*/
|
||||
public function subscription( string $id ): stdClass {
|
||||
$bearer = $this->bearer->bearer();
|
||||
$url = trailingslashit( $this->host ) . 'v1/billing/subscriptions/' . $id;
|
||||
$args = array(
|
||||
'headers' => array(
|
||||
'Authorization' => 'Bearer ' . $bearer->token(),
|
||||
'Content-Type' => 'application/json',
|
||||
'Prefer' => 'return=representation',
|
||||
),
|
||||
);
|
||||
|
||||
$response = $this->request( $url, $args );
|
||||
if ( is_wp_error( $response ) || ! is_array( $response ) ) {
|
||||
throw new RuntimeException( 'Not able to get subscription.' );
|
||||
}
|
||||
|
||||
$json = json_decode( $response['body'] );
|
||||
$status_code = (int) wp_remote_retrieve_response_code( $response );
|
||||
if ( 200 !== $status_code ) {
|
||||
throw new PayPalApiException(
|
||||
$json,
|
||||
$status_code
|
||||
);
|
||||
}
|
||||
|
||||
return $json;
|
||||
}
|
||||
}
|
199
modules/ppcp-api-client/src/Endpoint/CatalogProducts.php
Normal file
199
modules/ppcp-api-client/src/Endpoint/CatalogProducts.php
Normal file
|
@ -0,0 +1,199 @@
|
|||
<?php
|
||||
/**
|
||||
* The Catalog Products endpoint.
|
||||
*
|
||||
* @package WooCommerce\PayPalCommerce\ApiClient\Endpoint
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\ApiClient\Endpoint;
|
||||
|
||||
use Psr\Log\LoggerInterface;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Authentication\Bearer;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Product;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Factory\ProductFactory;
|
||||
|
||||
/**
|
||||
* Class CatalogProduct
|
||||
*/
|
||||
class CatalogProducts {
|
||||
use RequestTrait;
|
||||
|
||||
/**
|
||||
* The host.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $host;
|
||||
|
||||
/**
|
||||
* The bearer.
|
||||
*
|
||||
* @var Bearer
|
||||
*/
|
||||
private $bearer;
|
||||
|
||||
/**
|
||||
* The logger.
|
||||
*
|
||||
* @var LoggerInterface
|
||||
*/
|
||||
private $logger;
|
||||
|
||||
/**
|
||||
* Product factory.
|
||||
*
|
||||
* @var ProductFactory
|
||||
*/
|
||||
private $product_factory;
|
||||
|
||||
/**
|
||||
* CatalogProducts constructor.
|
||||
*
|
||||
* @param string $host The host.
|
||||
* @param Bearer $bearer The bearer.
|
||||
* @param ProductFactory $product_factory Product factory.
|
||||
* @param LoggerInterface $logger The logger.
|
||||
*/
|
||||
public function __construct(
|
||||
string $host,
|
||||
Bearer $bearer,
|
||||
ProductFactory $product_factory,
|
||||
LoggerInterface $logger
|
||||
) {
|
||||
$this->host = $host;
|
||||
$this->bearer = $bearer;
|
||||
$this->product_factory = $product_factory;
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a product.
|
||||
*
|
||||
* @param string $name Product name.
|
||||
* @param string $description Product description.
|
||||
*
|
||||
* @return Product
|
||||
*
|
||||
* @throws RuntimeException If the request fails.
|
||||
* @throws PayPalApiException If the request fails.
|
||||
*/
|
||||
public function create( string $name, string $description ): Product {
|
||||
$data = array(
|
||||
'name' => $name,
|
||||
);
|
||||
|
||||
if ( $description ) {
|
||||
$data['description'] = $description;
|
||||
}
|
||||
|
||||
$bearer = $this->bearer->bearer();
|
||||
$url = trailingslashit( $this->host ) . 'v1/catalogs/products';
|
||||
$args = array(
|
||||
'method' => 'POST',
|
||||
'headers' => array(
|
||||
'Authorization' => 'Bearer ' . $bearer->token(),
|
||||
'Content-Type' => 'application/json',
|
||||
'Prefer' => 'return=representation',
|
||||
),
|
||||
'body' => wp_json_encode( $data ),
|
||||
);
|
||||
|
||||
$response = $this->request( $url, $args );
|
||||
|
||||
if ( is_wp_error( $response ) || ! is_array( $response ) ) {
|
||||
throw new RuntimeException( 'Not able to create product.' );
|
||||
}
|
||||
|
||||
$json = json_decode( $response['body'] );
|
||||
$status_code = (int) wp_remote_retrieve_response_code( $response );
|
||||
if ( 201 !== $status_code ) {
|
||||
throw new PayPalApiException(
|
||||
$json,
|
||||
$status_code
|
||||
);
|
||||
}
|
||||
|
||||
return $this->product_factory->from_paypal_response( $json );
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a Product.
|
||||
*
|
||||
* @param string $id Product ID.
|
||||
* @param array $data Data to update.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws RuntimeException If the request fails.
|
||||
* @throws PayPalApiException If the request fails.
|
||||
*/
|
||||
public function update( string $id, array $data ): void {
|
||||
$bearer = $this->bearer->bearer();
|
||||
$url = trailingslashit( $this->host ) . 'v1/catalogs/products/' . $id;
|
||||
$args = array(
|
||||
'method' => 'PATCH',
|
||||
'headers' => array(
|
||||
'Authorization' => 'Bearer ' . $bearer->token(),
|
||||
'Content-Type' => 'application/json',
|
||||
'Prefer' => 'return=representation',
|
||||
),
|
||||
'body' => wp_json_encode( $data ),
|
||||
);
|
||||
|
||||
$response = $this->request( $url, $args );
|
||||
if ( is_wp_error( $response ) || ! is_array( $response ) ) {
|
||||
throw new RuntimeException( 'Not able to update product.' );
|
||||
}
|
||||
|
||||
$json = json_decode( $response['body'] );
|
||||
$status_code = (int) wp_remote_retrieve_response_code( $response );
|
||||
if ( 204 !== $status_code ) {
|
||||
throw new PayPalApiException(
|
||||
$json,
|
||||
$status_code
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a Product from the given ID.
|
||||
*
|
||||
* @param string $id Product ID.
|
||||
*
|
||||
* @return Product
|
||||
*
|
||||
* @throws RuntimeException If the request fails.
|
||||
* @throws PayPalApiException If the request fails.
|
||||
*/
|
||||
public function product( string $id ): Product {
|
||||
$bearer = $this->bearer->bearer();
|
||||
$url = trailingslashit( $this->host ) . 'v1/catalogs/products/' . $id;
|
||||
$args = array(
|
||||
'headers' => array(
|
||||
'Authorization' => 'Bearer ' . $bearer->token(),
|
||||
'Content-Type' => 'application/json',
|
||||
'Prefer' => 'return=representation',
|
||||
),
|
||||
);
|
||||
|
||||
$response = $this->request( $url, $args );
|
||||
if ( is_wp_error( $response ) || ! is_array( $response ) ) {
|
||||
throw new RuntimeException( 'Not able to get product.' );
|
||||
}
|
||||
|
||||
$json = json_decode( $response['body'] );
|
||||
$status_code = (int) wp_remote_retrieve_response_code( $response );
|
||||
if ( 200 !== $status_code ) {
|
||||
throw new PayPalApiException(
|
||||
$json,
|
||||
$status_code
|
||||
);
|
||||
}
|
||||
|
||||
return $this->product_factory->from_paypal_response( $json );
|
||||
}
|
||||
}
|
|
@ -103,7 +103,8 @@ class IdentityToken {
|
|||
);
|
||||
if (
|
||||
( $this->settings->has( 'vault_enabled' ) && $this->settings->get( 'vault_enabled' ) )
|
||||
&& defined( 'PPCP_FLAG_SUBSCRIPTION' ) && PPCP_FLAG_SUBSCRIPTION
|
||||
|| ( $this->settings->has( 'vault_enabled_dcc' ) && $this->settings->get( 'vault_enabled_dcc' ) )
|
||||
|| ( $this->settings->has( 'subscriptions_mode' ) && $this->settings->get( 'subscriptions_mode' ) === 'vaulting_api' )
|
||||
) {
|
||||
$customer_id = $this->customer_repository->customer_id_for_user( ( $user_id ) );
|
||||
update_user_meta( $user_id, 'ppcp_customer_id', $customer_id );
|
||||
|
|
|
@ -16,6 +16,7 @@ use WooCommerce\PayPalCommerce\ApiClient\Entity\AuthorizationStatus;
|
|||
use WooCommerce\PayPalCommerce\ApiClient\Entity\CaptureStatus;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Order;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\OrderStatus;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\PatchCollection;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Payer;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentMethod;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentToken;
|
||||
|
@ -180,6 +181,8 @@ class OrderEndpoint {
|
|||
* @param Payer|null $payer The payer off the order.
|
||||
* @param PaymentToken|null $payment_token The payment token.
|
||||
* @param PaymentMethod|null $payment_method The payment method.
|
||||
* @param string $paypal_request_id The paypal request id.
|
||||
* @param string $user_action The user action.
|
||||
*
|
||||
* @return Order
|
||||
* @throws RuntimeException If the request fails.
|
||||
|
@ -189,19 +192,28 @@ class OrderEndpoint {
|
|||
string $shipping_preference,
|
||||
Payer $payer = null,
|
||||
PaymentToken $payment_token = null,
|
||||
PaymentMethod $payment_method = null
|
||||
PaymentMethod $payment_method = null,
|
||||
string $paypal_request_id = '',
|
||||
string $user_action = ApplicationContext::USER_ACTION_CONTINUE
|
||||
): Order {
|
||||
$bearer = $this->bearer->bearer();
|
||||
$data = array(
|
||||
'intent' => ( $this->subscription_helper->cart_contains_subscription() || $this->subscription_helper->current_product_is_subscription() ) ? 'AUTHORIZE' : $this->intent,
|
||||
'purchase_units' => array_map(
|
||||
static function ( PurchaseUnit $item ): array {
|
||||
return $item->to_array();
|
||||
static function ( PurchaseUnit $item ) use ( $shipping_preference ): array {
|
||||
$data = $item->to_array();
|
||||
|
||||
if ( $shipping_preference !== ApplicationContext::SHIPPING_PREFERENCE_GET_FROM_FILE ) {
|
||||
// Shipping options are not allowed to be sent when not getting the address from PayPal.
|
||||
unset( $data['shipping']['options'] );
|
||||
}
|
||||
|
||||
return $data;
|
||||
},
|
||||
$items
|
||||
),
|
||||
'application_context' => $this->application_context_repository
|
||||
->current_context( $shipping_preference )->to_array(),
|
||||
->current_context( $shipping_preference, $user_action )->to_array(),
|
||||
);
|
||||
if ( $payer && ! empty( $payer->email_address() ) ) {
|
||||
$data['payer'] = $payer->to_array();
|
||||
|
@ -512,13 +524,22 @@ class OrderEndpoint {
|
|||
return $order_to_update;
|
||||
}
|
||||
|
||||
$this->patch( $order_to_update->id(), $patches );
|
||||
|
||||
$new_order = $this->order( $order_to_update->id() );
|
||||
return $new_order;
|
||||
}
|
||||
|
||||
/**
|
||||
* Patches an order.
|
||||
*
|
||||
* @param string $order_id The PayPal order ID.
|
||||
* @param PatchCollection $patches The patches.
|
||||
*
|
||||
* @throws RuntimeException If the request fails.
|
||||
*/
|
||||
public function patch( string $order_id, PatchCollection $patches ): void {
|
||||
$patches_array = $patches->to_array();
|
||||
if ( ! isset( $patches_array[0]['value']['shipping'] ) ) {
|
||||
$shipping = isset( $order_to_update->purchase_units()[0] ) && null !== $order_to_update->purchase_units()[0]->shipping() ? $order_to_update->purchase_units()[0]->shipping() : null;
|
||||
if ( $shipping ) {
|
||||
$patches_array[0]['value']['shipping'] = $shipping->to_array();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The filter can be used to modify the order patching request body data (the final prices, items).
|
||||
|
@ -526,7 +547,7 @@ class OrderEndpoint {
|
|||
$patches_array = apply_filters( 'ppcp_patch_order_request_body_data', $patches_array );
|
||||
|
||||
$bearer = $this->bearer->bearer();
|
||||
$url = trailingslashit( $this->host ) . 'v2/checkout/orders/' . $order_to_update->id();
|
||||
$url = trailingslashit( $this->host ) . 'v2/checkout/orders/' . $order_id;
|
||||
$args = array(
|
||||
'method' => 'PATCH',
|
||||
'headers' => array(
|
||||
|
@ -542,11 +563,8 @@ class OrderEndpoint {
|
|||
$response = $this->request( $url, $args );
|
||||
|
||||
if ( is_wp_error( $response ) ) {
|
||||
$error = new RuntimeException(
|
||||
__( 'Could not retrieve order.', 'woocommerce-paypal-payments' )
|
||||
);
|
||||
$this->logger->log(
|
||||
'warning',
|
||||
$error = new RuntimeException( 'Could not patch order.' );
|
||||
$this->logger->warning(
|
||||
$error->getMessage(),
|
||||
array(
|
||||
'args' => $args,
|
||||
|
@ -562,8 +580,7 @@ class OrderEndpoint {
|
|||
$json,
|
||||
$status_code
|
||||
);
|
||||
$this->logger->log(
|
||||
'warning',
|
||||
$this->logger->warning(
|
||||
$error->getMessage(),
|
||||
array(
|
||||
'args' => $args,
|
||||
|
@ -572,9 +589,6 @@ class OrderEndpoint {
|
|||
);
|
||||
throw $error;
|
||||
}
|
||||
|
||||
$new_order = $this->order( $order_to_update->id() );
|
||||
return $new_order;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
134
modules/ppcp-api-client/src/Entity/BillingCycle.php
Normal file
134
modules/ppcp-api-client/src/Entity/BillingCycle.php
Normal file
|
@ -0,0 +1,134 @@
|
|||
<?php
|
||||
/**
|
||||
* The Billing Cycle object.
|
||||
*
|
||||
* @package WooCommerce\PayPalCommerce\ApiClient\Entity
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\ApiClient\Entity;
|
||||
|
||||
/**
|
||||
* Class BillingCycle
|
||||
*/
|
||||
class BillingCycle {
|
||||
|
||||
/**
|
||||
* Frequency.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $frequency;
|
||||
|
||||
/**
|
||||
* Sequence.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $sequence;
|
||||
|
||||
/**
|
||||
* Tenure Type.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $tenure_type;
|
||||
|
||||
/**
|
||||
* Pricing scheme.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $pricing_scheme;
|
||||
|
||||
/**
|
||||
* Total cycles.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $total_cycles;
|
||||
|
||||
/**
|
||||
* BillingCycle constructor.
|
||||
*
|
||||
* @param array $frequency Frequency.
|
||||
* @param int $sequence Sequence.
|
||||
* @param string $tenure_type Tenure type.
|
||||
* @param array $pricing_scheme Pricing scheme.
|
||||
* @param int $total_cycles Total cycles.
|
||||
*/
|
||||
public function __construct(
|
||||
array $frequency,
|
||||
int $sequence,
|
||||
string $tenure_type,
|
||||
array $pricing_scheme = array(),
|
||||
int $total_cycles = 1
|
||||
) {
|
||||
$this->frequency = $frequency;
|
||||
$this->sequence = $sequence;
|
||||
$this->tenure_type = $tenure_type;
|
||||
$this->pricing_scheme = $pricing_scheme;
|
||||
$this->total_cycles = $total_cycles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns frequency.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function frequency(): array {
|
||||
return $this->frequency;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns sequence.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function sequence(): int {
|
||||
return $this->sequence;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns tenure type.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function tenure_type(): string {
|
||||
return $this->tenure_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns pricing scheme.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function pricing_scheme(): array {
|
||||
return $this->pricing_scheme;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return total cycles.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function total_cycles(): int {
|
||||
return $this->total_cycles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Billing Cycle as array.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function to_array(): array {
|
||||
return array(
|
||||
'frequency' => $this->frequency(),
|
||||
'sequence' => $this->sequence(),
|
||||
'tenure_type' => $this->tenure_type(),
|
||||
'pricing_scheme' => $this->pricing_scheme(),
|
||||
'total_cycles' => $this->total_cycles(),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -83,8 +83,8 @@ class Patch {
|
|||
public function to_array(): array {
|
||||
return array(
|
||||
'op' => $this->op(),
|
||||
'value' => $this->value(),
|
||||
'path' => $this->path(),
|
||||
'value' => $this->value(),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
115
modules/ppcp-api-client/src/Entity/PaymentPreferences.php
Normal file
115
modules/ppcp-api-client/src/Entity/PaymentPreferences.php
Normal file
|
@ -0,0 +1,115 @@
|
|||
<?php
|
||||
/**
|
||||
* The Payment Preferences object.
|
||||
*
|
||||
* @package WooCommerce\PayPalCommerce\ApiClient\Entity
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\ApiClient\Entity;
|
||||
|
||||
/**
|
||||
* Class PaymentPreferences
|
||||
*/
|
||||
class PaymentPreferences {
|
||||
|
||||
/**
|
||||
* Setup fee.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $setup_fee;
|
||||
|
||||
/**
|
||||
* Auto bill outstanding.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $auto_bill_outstanding;
|
||||
|
||||
/**
|
||||
* Setup fee failure action.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $setup_fee_failure_action;
|
||||
|
||||
/**
|
||||
* Payment failure threshold.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $payment_failure_threshold;
|
||||
|
||||
/**
|
||||
* PaymentPreferences constructor.
|
||||
*
|
||||
* @param array $setup_fee Setup fee.
|
||||
* @param bool $auto_bill_outstanding Auto bill outstanding.
|
||||
* @param string $setup_fee_failure_action Setup fee failure action.
|
||||
* @param int $payment_failure_threshold payment failure threshold.
|
||||
*/
|
||||
public function __construct(
|
||||
array $setup_fee,
|
||||
bool $auto_bill_outstanding = true,
|
||||
string $setup_fee_failure_action = 'CONTINUE',
|
||||
int $payment_failure_threshold = 3
|
||||
) {
|
||||
|
||||
$this->setup_fee = $setup_fee;
|
||||
$this->auto_bill_outstanding = $auto_bill_outstanding;
|
||||
$this->setup_fee_failure_action = $setup_fee_failure_action;
|
||||
$this->payment_failure_threshold = $payment_failure_threshold;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup fee.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function setup_fee(): array {
|
||||
return $this->setup_fee;
|
||||
}
|
||||
|
||||
/**
|
||||
* Auto bill outstanding.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function auto_bill_outstanding(): bool {
|
||||
return $this->auto_bill_outstanding;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup fee failure action.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function setup_fee_failure_action(): string {
|
||||
return $this->setup_fee_failure_action;
|
||||
}
|
||||
|
||||
/**
|
||||
* Payment failure threshold.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function payment_failure_threshold(): int {
|
||||
return $this->payment_failure_threshold;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Payment Preferences as array.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function to_array():array {
|
||||
return array(
|
||||
'setup_fee' => $this->setup_fee(),
|
||||
'auto_bill_outstanding' => $this->auto_bill_outstanding(),
|
||||
'setup_fee_failure_action' => $this->setup_fee_failure_action(),
|
||||
'payment_failure_threshold' => $this->payment_failure_threshold(),
|
||||
);
|
||||
}
|
||||
}
|
154
modules/ppcp-api-client/src/Entity/Plan.php
Normal file
154
modules/ppcp-api-client/src/Entity/Plan.php
Normal file
|
@ -0,0 +1,154 @@
|
|||
<?php
|
||||
/**
|
||||
* The Plan object.
|
||||
*
|
||||
* @package WooCommerce\PayPalCommerce\ApiClient\Entity
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\ApiClient\Entity;
|
||||
|
||||
/**
|
||||
* Class Plan
|
||||
*/
|
||||
class Plan {
|
||||
|
||||
/**
|
||||
* Plan ID.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* Plan name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $name;
|
||||
|
||||
/**
|
||||
* Product ID.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $product_id;
|
||||
|
||||
/**
|
||||
* Billing cycles.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $billing_cycles;
|
||||
|
||||
/**
|
||||
* Payment preferences.
|
||||
*
|
||||
* @var PaymentPreferences
|
||||
*/
|
||||
private $payment_preferences;
|
||||
|
||||
/**
|
||||
* Plan status.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $status;
|
||||
|
||||
/**
|
||||
* Plan constructor.
|
||||
*
|
||||
* @param string $id Plan ID.
|
||||
* @param string $name Plan name.
|
||||
* @param string $product_id Product ID.
|
||||
* @param array $billing_cycles Billing cycles.
|
||||
* @param PaymentPreferences $payment_preferences Payment preferences.
|
||||
* @param string $status Plan status.
|
||||
*/
|
||||
public function __construct(
|
||||
string $id,
|
||||
string $name,
|
||||
string $product_id,
|
||||
array $billing_cycles,
|
||||
PaymentPreferences $payment_preferences,
|
||||
string $status = ''
|
||||
) {
|
||||
$this->id = $id;
|
||||
$this->name = $name;
|
||||
$this->product_id = $product_id;
|
||||
$this->billing_cycles = $billing_cycles;
|
||||
$this->payment_preferences = $payment_preferences;
|
||||
$this->status = $status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Plan ID.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function id(): string {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Plan name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function name(): string {
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Product ID.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function product_id(): string {
|
||||
return $this->product_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Billing cycles.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function billing_cycles(): array {
|
||||
return $this->billing_cycles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Payment preferences.
|
||||
*
|
||||
* @return PaymentPreferences
|
||||
*/
|
||||
public function payment_preferences(): PaymentPreferences {
|
||||
return $this->payment_preferences;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Plan status.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function status(): string {
|
||||
return $this->status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Plan as array.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function to_array():array {
|
||||
return array(
|
||||
'id' => $this->id(),
|
||||
'name' => $this->name(),
|
||||
'product_id' => $this->product_id(),
|
||||
'billing_cycles' => $this->billing_cycles(),
|
||||
'payment_preferences' => $this->payment_preferences(),
|
||||
'status' => $this->status(),
|
||||
);
|
||||
}
|
||||
}
|
90
modules/ppcp-api-client/src/Entity/Product.php
Normal file
90
modules/ppcp-api-client/src/Entity/Product.php
Normal file
|
@ -0,0 +1,90 @@
|
|||
<?php
|
||||
/**
|
||||
* The Product object.
|
||||
*
|
||||
* @package WooCommerce\PayPalCommerce\ApiClient\Entity
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\ApiClient\Entity;
|
||||
|
||||
/**
|
||||
* Class Product
|
||||
*/
|
||||
class Product {
|
||||
|
||||
/**
|
||||
* Product ID.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* Product name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $name;
|
||||
|
||||
/**
|
||||
* Product description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $description;
|
||||
|
||||
/**
|
||||
* Product constructor.
|
||||
*
|
||||
* @param string $id Product ID.
|
||||
* @param string $name Product name.
|
||||
* @param string $description Product description.
|
||||
*/
|
||||
public function __construct( string $id, string $name, string $description = '' ) {
|
||||
$this->id = $id;
|
||||
$this->name = $name;
|
||||
$this->description = $description;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the product ID.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function id(): string {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the product name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function name(): string {
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the product description.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function description(): string {
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the object as array.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function to_array() {
|
||||
return array(
|
||||
'id' => $this->id(),
|
||||
'name' => $this->name(),
|
||||
'description' => $this->description(),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -28,15 +28,24 @@ class Shipping {
|
|||
*/
|
||||
private $address;
|
||||
|
||||
/**
|
||||
* Shipping methods.
|
||||
*
|
||||
* @var ShippingOption[]
|
||||
*/
|
||||
private $options;
|
||||
|
||||
/**
|
||||
* Shipping constructor.
|
||||
*
|
||||
* @param string $name The name.
|
||||
* @param Address $address The address.
|
||||
* @param string $name The name.
|
||||
* @param Address $address The address.
|
||||
* @param ShippingOption[] $options Shipping methods.
|
||||
*/
|
||||
public function __construct( string $name, Address $address ) {
|
||||
public function __construct( string $name, Address $address, array $options = array() ) {
|
||||
$this->name = $name;
|
||||
$this->address = $address;
|
||||
$this->options = $options;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -57,17 +66,35 @@ class Shipping {
|
|||
return $this->address;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the shipping methods.
|
||||
*
|
||||
* @return ShippingOption[]
|
||||
*/
|
||||
public function options(): array {
|
||||
return $this->options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the object as array.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function to_array(): array {
|
||||
return array(
|
||||
$result = array(
|
||||
'name' => array(
|
||||
'full_name' => $this->name(),
|
||||
),
|
||||
'address' => $this->address()->to_array(),
|
||||
);
|
||||
if ( $this->options ) {
|
||||
$result['options'] = array_map(
|
||||
function ( ShippingOption $opt ): array {
|
||||
return $opt->to_array();
|
||||
},
|
||||
$this->options
|
||||
);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
|
139
modules/ppcp-api-client/src/Entity/ShippingOption.php
Normal file
139
modules/ppcp-api-client/src/Entity/ShippingOption.php
Normal file
|
@ -0,0 +1,139 @@
|
|||
<?php
|
||||
/**
|
||||
* The ShippingOption object.
|
||||
*
|
||||
* @package WooCommerce\PayPalCommerce\ApiClient\Entity
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\ApiClient\Entity;
|
||||
|
||||
/**
|
||||
* Class ShippingOption
|
||||
*/
|
||||
class ShippingOption {
|
||||
const TYPE_SHIPPING = 'SHIPPING';
|
||||
const TYPE_PICKUP = 'PICKUP';
|
||||
|
||||
/**
|
||||
* The name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* The label.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $label;
|
||||
|
||||
/**
|
||||
* Whether the method is selected by default.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $selected;
|
||||
|
||||
/**
|
||||
* The price.
|
||||
*
|
||||
* @var Money
|
||||
*/
|
||||
private $amount;
|
||||
|
||||
/**
|
||||
* SHIPPING or PICKUP.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $type;
|
||||
|
||||
/**
|
||||
* ShippingOption constructor.
|
||||
*
|
||||
* @param string $id The name.
|
||||
* @param string $label The label.
|
||||
* @param bool $selected Whether the method is selected by default.
|
||||
* @param Money $amount The price.
|
||||
* @param string $type SHIPPING or PICKUP.
|
||||
*/
|
||||
public function __construct( string $id, string $label, bool $selected, Money $amount, string $type ) {
|
||||
$this->id = $id;
|
||||
$this->label = $label;
|
||||
$this->selected = $selected;
|
||||
$this->amount = $amount;
|
||||
$this->type = $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* The name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function id(): string {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* The label.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function label(): string {
|
||||
return $this->label;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the method is selected by default.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function selected(): bool {
|
||||
return $this->selected;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether the method is selected by default.
|
||||
*
|
||||
* @param bool $selected The value to be set.
|
||||
*/
|
||||
public function set_selected( bool $selected ): void {
|
||||
$this->selected = $selected;
|
||||
}
|
||||
|
||||
/**
|
||||
* The price.
|
||||
*
|
||||
* @return Money
|
||||
*/
|
||||
public function amount(): Money {
|
||||
return $this->amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* SHIPPING or PICKUP.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function type(): string {
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the object as array.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function to_array(): array {
|
||||
return array(
|
||||
'id' => $this->id,
|
||||
'label' => $this->label,
|
||||
'selected' => $this->selected,
|
||||
'amount' => $this->amount->to_array(),
|
||||
'type' => $this->type,
|
||||
);
|
||||
}
|
||||
}
|
84
modules/ppcp-api-client/src/Factory/BillingCycleFactory.php
Normal file
84
modules/ppcp-api-client/src/Factory/BillingCycleFactory.php
Normal file
|
@ -0,0 +1,84 @@
|
|||
<?php
|
||||
/**
|
||||
* The Billing Cycle factory.
|
||||
*
|
||||
* @package WooCommerce\PayPalCommerce\ApiClient\Factory
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\ApiClient\Factory;
|
||||
|
||||
use stdClass;
|
||||
use WC_Product;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\BillingCycle;
|
||||
|
||||
/**
|
||||
* Class BillingCycleFactory
|
||||
*/
|
||||
class BillingCycleFactory {
|
||||
|
||||
/**
|
||||
* The currency.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $currency;
|
||||
|
||||
/**
|
||||
* BillingCycleFactory constructor.
|
||||
*
|
||||
* @param string $currency The currency.
|
||||
*/
|
||||
public function __construct( string $currency ) {
|
||||
$this->currency = $currency;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a BillingCycle object from the given WC product.
|
||||
*
|
||||
* @param WC_Product $product WC product.
|
||||
* @return BillingCycle
|
||||
*/
|
||||
public function from_wc_product( WC_Product $product ): BillingCycle {
|
||||
return new BillingCycle(
|
||||
array(
|
||||
'interval_unit' => $product->get_meta( '_subscription_period' ),
|
||||
'interval_count' => $product->get_meta( '_subscription_period_interval' ),
|
||||
),
|
||||
1,
|
||||
'REGULAR',
|
||||
array(
|
||||
'fixed_price' => array(
|
||||
'value' => $product->get_meta( '_subscription_price' ),
|
||||
'currency_code' => $this->currency,
|
||||
),
|
||||
),
|
||||
(int) $product->get_meta( '_subscription_length' )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a BillingCycle object based off a PayPal response.
|
||||
*
|
||||
* @param stdClass $data the data.
|
||||
* @return BillingCycle
|
||||
*/
|
||||
public function from_paypal_response( stdClass $data ): BillingCycle {
|
||||
return new BillingCycle(
|
||||
array(
|
||||
'interval_unit' => $data->frequency->interval_unit,
|
||||
'interval_count' => $data->frequency->interval_count,
|
||||
),
|
||||
$data->sequence,
|
||||
$data->tenure_type,
|
||||
array(
|
||||
'fixed_price' => array(
|
||||
'value' => $data->pricing_scheme->fixed_price->value,
|
||||
'currency_code' => $data->pricing_scheme->fixed_price->currency_code,
|
||||
),
|
||||
),
|
||||
$data->total_cycles
|
||||
);
|
||||
}
|
||||
}
|
|
@ -71,7 +71,15 @@ class PatchCollectionFactory {
|
|||
);
|
||||
$operation = $purchase_unit_from ? 'replace' : 'add';
|
||||
$value = $purchase_unit_to->to_array();
|
||||
$patches[] = new Patch(
|
||||
|
||||
if ( ! isset( $value['shipping'] ) ) {
|
||||
$shipping = $purchase_unit_from && null !== $purchase_unit_from->shipping() ? $purchase_unit_from->shipping() : null;
|
||||
if ( $shipping ) {
|
||||
$value['shipping'] = $shipping->to_array();
|
||||
}
|
||||
}
|
||||
|
||||
$patches[] = new Patch(
|
||||
$operation,
|
||||
$path . "/@reference_id=='" . $purchase_unit_to->reference_id() . "'",
|
||||
$value
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
<?php
|
||||
/**
|
||||
* The Payment Preferences factory.
|
||||
*
|
||||
* @package WooCommerce\PayPalCommerce\ApiClient\Factory
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\ApiClient\Factory;
|
||||
|
||||
use stdClass;
|
||||
use WC_Product;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentPreferences;
|
||||
|
||||
/**
|
||||
* Class PaymentPreferencesFactory
|
||||
*/
|
||||
class PaymentPreferencesFactory {
|
||||
|
||||
/**
|
||||
* The currency.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $currency;
|
||||
|
||||
/**
|
||||
* PaymentPreferencesFactory constructor.
|
||||
*
|
||||
* @param string $currency The currency.
|
||||
*/
|
||||
public function __construct( string $currency ) {
|
||||
$this->currency = $currency;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a PaymentPreferences object from the given WC product.
|
||||
*
|
||||
* @param WC_Product $product WC product.
|
||||
* @return PaymentPreferences
|
||||
*/
|
||||
public function from_wc_product( WC_Product $product ):PaymentPreferences {
|
||||
return new PaymentPreferences(
|
||||
array(
|
||||
'value' => $product->get_meta( '_subscription_sign_up_fee' ) ?: '0',
|
||||
'currency_code' => $this->currency,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a PaymentPreferences object based off a PayPal response.
|
||||
*
|
||||
* @param stdClass $data The data.
|
||||
* @return PaymentPreferences
|
||||
*/
|
||||
public function from_paypal_response( stdClass $data ) {
|
||||
return new PaymentPreferences(
|
||||
array(
|
||||
'value' => $data->setup_fee->value,
|
||||
'currency_code' => $data->setup_fee->currency_code,
|
||||
),
|
||||
$data->auto_bill_outstanding,
|
||||
$data->setup_fee_failure_action,
|
||||
$data->payment_failure_threshold
|
||||
);
|
||||
}
|
||||
}
|
96
modules/ppcp-api-client/src/Factory/PlanFactory.php
Normal file
96
modules/ppcp-api-client/src/Factory/PlanFactory.php
Normal file
|
@ -0,0 +1,96 @@
|
|||
<?php
|
||||
/**
|
||||
* Plan Factory.
|
||||
*
|
||||
* @package WooCommerce\PayPalCommerce\Webhooks\Handler
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\ApiClient\Factory;
|
||||
|
||||
use stdClass;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Plan;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
|
||||
/**
|
||||
* Class PlanFactory
|
||||
*/
|
||||
class PlanFactory {
|
||||
|
||||
/**
|
||||
* Billing cycle factory.
|
||||
*
|
||||
* @var BillingCycleFactory
|
||||
*/
|
||||
private $billing_cycle_factory;
|
||||
|
||||
/**
|
||||
* Payment preferences factory.
|
||||
*
|
||||
* @var PaymentPreferencesFactory
|
||||
*/
|
||||
private $payment_preferences_factory;
|
||||
|
||||
/**
|
||||
* PlanFactory constructor.
|
||||
*
|
||||
* @param BillingCycleFactory $billing_cycle_factory Billing cycle factory.
|
||||
* @param PaymentPreferencesFactory $payment_preferences_factory Payment preferences factory.
|
||||
*/
|
||||
public function __construct(
|
||||
BillingCycleFactory $billing_cycle_factory,
|
||||
PaymentPreferencesFactory $payment_preferences_factory
|
||||
) {
|
||||
$this->billing_cycle_factory = $billing_cycle_factory;
|
||||
$this->payment_preferences_factory = $payment_preferences_factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a Plan from PayPal response.
|
||||
*
|
||||
* @param stdClass $data The data.
|
||||
*
|
||||
* @return Plan
|
||||
*
|
||||
* @throws RuntimeException If it could not create Plan.
|
||||
*/
|
||||
public function from_paypal_response( stdClass $data ): Plan {
|
||||
if ( ! isset( $data->id ) ) {
|
||||
throw new RuntimeException(
|
||||
__( 'No id for given plan', 'woocommerce-paypal-payments' )
|
||||
);
|
||||
}
|
||||
if ( ! isset( $data->name ) ) {
|
||||
throw new RuntimeException(
|
||||
__( 'No name for plan given', 'woocommerce-paypal-payments' )
|
||||
);
|
||||
}
|
||||
if ( ! isset( $data->product_id ) ) {
|
||||
throw new RuntimeException(
|
||||
__( 'No product id for given plan', 'woocommerce-paypal-payments' )
|
||||
);
|
||||
}
|
||||
if ( ! isset( $data->billing_cycles ) ) {
|
||||
throw new RuntimeException(
|
||||
__( 'No billing cycles for given plan', 'woocommerce-paypal-payments' )
|
||||
);
|
||||
}
|
||||
|
||||
$billing_cycles = array();
|
||||
foreach ( $data->billing_cycles as $billing_cycle ) {
|
||||
$billing_cycles[] = $this->billing_cycle_factory->from_paypal_response( $billing_cycle );
|
||||
}
|
||||
|
||||
$payment_preferences = $this->payment_preferences_factory->from_paypal_response( $data->payment_preferences );
|
||||
|
||||
return new Plan(
|
||||
$data->id,
|
||||
$data->name,
|
||||
$data->product_id,
|
||||
$billing_cycles,
|
||||
$payment_preferences,
|
||||
$data->status ?? ''
|
||||
);
|
||||
}
|
||||
}
|
47
modules/ppcp-api-client/src/Factory/ProductFactory.php
Normal file
47
modules/ppcp-api-client/src/Factory/ProductFactory.php
Normal file
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
/**
|
||||
* The Product factory.
|
||||
*
|
||||
* @package WooCommerce\PayPalCommerce\ApiClient\Factory
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\ApiClient\Factory;
|
||||
|
||||
use stdClass;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Product;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
|
||||
/**
|
||||
* Class ProductFactory
|
||||
*/
|
||||
class ProductFactory {
|
||||
|
||||
/**
|
||||
* Creates a Product based off a PayPal response.
|
||||
*
|
||||
* @param stdClass $data The JSON object.
|
||||
*
|
||||
* @return Product
|
||||
* @throws RuntimeException When JSON object is malformed.
|
||||
*/
|
||||
public function from_paypal_response( stdClass $data ): Product {
|
||||
if ( ! isset( $data->id ) ) {
|
||||
throw new RuntimeException(
|
||||
__( 'No id for product given', 'woocommerce-paypal-payments' )
|
||||
);
|
||||
}
|
||||
if ( ! isset( $data->name ) ) {
|
||||
throw new RuntimeException(
|
||||
__( 'No name for product given', 'woocommerce-paypal-payments' )
|
||||
);
|
||||
}
|
||||
|
||||
return new Product(
|
||||
$data->id,
|
||||
$data->name,
|
||||
$data->description ?? ''
|
||||
);
|
||||
}
|
||||
}
|
|
@ -153,10 +153,11 @@ class PurchaseUnitFactory {
|
|||
* Creates a PurchaseUnit based off a WooCommerce cart.
|
||||
*
|
||||
* @param \WC_Cart|null $cart The cart.
|
||||
* @param bool $with_shipping_options Include WC shipping methods.
|
||||
*
|
||||
* @return PurchaseUnit
|
||||
*/
|
||||
public function from_wc_cart( ?\WC_Cart $cart = null ): PurchaseUnit {
|
||||
public function from_wc_cart( ?\WC_Cart $cart = null, bool $with_shipping_options = false ): PurchaseUnit {
|
||||
if ( ! $cart ) {
|
||||
$cart = WC()->cart ?? new \WC_Cart();
|
||||
}
|
||||
|
@ -172,7 +173,7 @@ class PurchaseUnitFactory {
|
|||
$shipping = null;
|
||||
$customer = \WC()->customer;
|
||||
if ( $this->shipping_needed( ... array_values( $items ) ) && is_a( $customer, \WC_Customer::class ) ) {
|
||||
$shipping = $this->shipping_factory->from_wc_customer( \WC()->customer );
|
||||
$shipping = $this->shipping_factory->from_wc_customer( \WC()->customer, $with_shipping_options );
|
||||
if (
|
||||
2 !== strlen( $shipping->address()->country_code() ) ||
|
||||
( ! $shipping->address()->postal_code() && ! $this->country_without_postal_code( $shipping->address()->country_code() ) )
|
||||
|
|
|
@ -10,6 +10,7 @@ declare(strict_types=1);
|
|||
namespace WooCommerce\PayPalCommerce\ApiClient\Factory;
|
||||
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Shipping;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\ShippingOption;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
|
||||
/**
|
||||
|
@ -24,23 +25,33 @@ class ShippingFactory {
|
|||
*/
|
||||
private $address_factory;
|
||||
|
||||
/**
|
||||
* The shipping option factory.
|
||||
*
|
||||
* @var ShippingOptionFactory
|
||||
*/
|
||||
private $shipping_option_factory;
|
||||
|
||||
/**
|
||||
* ShippingFactory constructor.
|
||||
*
|
||||
* @param AddressFactory $address_factory The address factory.
|
||||
* @param AddressFactory $address_factory The address factory.
|
||||
* @param ShippingOptionFactory $shipping_option_factory The shipping option factory.
|
||||
*/
|
||||
public function __construct( AddressFactory $address_factory ) {
|
||||
$this->address_factory = $address_factory;
|
||||
public function __construct( AddressFactory $address_factory, ShippingOptionFactory $shipping_option_factory ) {
|
||||
$this->address_factory = $address_factory;
|
||||
$this->shipping_option_factory = $shipping_option_factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a shipping object based off a WooCommerce customer.
|
||||
*
|
||||
* @param \WC_Customer $customer The WooCommerce customer.
|
||||
* @param bool $with_shipping_options Include WC shipping methods.
|
||||
*
|
||||
* @return Shipping
|
||||
*/
|
||||
public function from_wc_customer( \WC_Customer $customer ): Shipping {
|
||||
public function from_wc_customer( \WC_Customer $customer, bool $with_shipping_options = false ): Shipping {
|
||||
// Replicates the Behavior of \WC_Order::get_formatted_shipping_full_name().
|
||||
$full_name = sprintf(
|
||||
// translators: %1$s is the first name and %2$s is the second name. wc translation.
|
||||
|
@ -51,7 +62,8 @@ class ShippingFactory {
|
|||
$address = $this->address_factory->from_wc_customer( $customer );
|
||||
return new Shipping(
|
||||
$full_name,
|
||||
$address
|
||||
$address,
|
||||
$with_shipping_options ? $this->shipping_option_factory->from_wc_cart() : array()
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -91,9 +103,14 @@ class ShippingFactory {
|
|||
);
|
||||
}
|
||||
$address = $this->address_factory->from_paypal_response( $data->address );
|
||||
$options = array_map(
|
||||
array( $this->shipping_option_factory, 'from_paypal_response' ),
|
||||
$data->options ?? array()
|
||||
);
|
||||
return new Shipping(
|
||||
$data->name->full_name,
|
||||
$address
|
||||
$address,
|
||||
$options
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
111
modules/ppcp-api-client/src/Factory/ShippingOptionFactory.php
Normal file
111
modules/ppcp-api-client/src/Factory/ShippingOptionFactory.php
Normal file
|
@ -0,0 +1,111 @@
|
|||
<?php
|
||||
/**
|
||||
* The shipping options factory.
|
||||
*
|
||||
* @package WooCommerce\PayPalCommerce\ApiClient\Factory
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\ApiClient\Factory;
|
||||
|
||||
use stdClass;
|
||||
use WC_Cart;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Money;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\ShippingOption;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
|
||||
/**
|
||||
* Class ShippingOptionFactory
|
||||
*/
|
||||
class ShippingOptionFactory {
|
||||
|
||||
/**
|
||||
* The Money factory.
|
||||
*
|
||||
* @var MoneyFactory
|
||||
*/
|
||||
private $money_factory;
|
||||
|
||||
/**
|
||||
* ShippingOptionFactory constructor.
|
||||
*
|
||||
* @param MoneyFactory $money_factory The Money factory.
|
||||
*/
|
||||
public function __construct( MoneyFactory $money_factory ) {
|
||||
$this->money_factory = $money_factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an array of ShippingOption objects for the shipping methods available in the cart.
|
||||
*
|
||||
* @param WC_Cart|null $cart The cart.
|
||||
* @return ShippingOption[]
|
||||
*/
|
||||
public function from_wc_cart( ?WC_Cart $cart = null ): array {
|
||||
if ( ! $cart ) {
|
||||
$cart = WC()->cart ?? new WC_Cart();
|
||||
}
|
||||
|
||||
$cart->calculate_shipping();
|
||||
|
||||
$chosen_shipping_methods = WC()->session->get( 'chosen_shipping_methods', array() );
|
||||
if ( ! is_array( $chosen_shipping_methods ) ) {
|
||||
$chosen_shipping_methods = array();
|
||||
}
|
||||
|
||||
$packages = WC()->shipping()->get_packages();
|
||||
$options = array();
|
||||
foreach ( $packages as $package ) {
|
||||
$rates = $package['rates'] ?? array();
|
||||
foreach ( $rates as $rate ) {
|
||||
if ( ! $rate instanceof \WC_Shipping_Rate ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$options[] = new ShippingOption(
|
||||
$rate->get_id(),
|
||||
$rate->get_label(),
|
||||
in_array( $rate->get_id(), $chosen_shipping_methods, true ),
|
||||
new Money(
|
||||
(float) $rate->get_cost(),
|
||||
get_woocommerce_currency()
|
||||
),
|
||||
ShippingOption::TYPE_SHIPPING
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! $chosen_shipping_methods && $options ) {
|
||||
$options[0]->set_selected( true );
|
||||
}
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a ShippingOption object from the PayPal JSON object.
|
||||
*
|
||||
* @param stdClass $data The JSON object.
|
||||
*
|
||||
* @return ShippingOption
|
||||
* @throws RuntimeException When JSON object is malformed.
|
||||
*/
|
||||
public function from_paypal_response( stdClass $data ): ShippingOption {
|
||||
if ( ! isset( $data->id ) ) {
|
||||
throw new RuntimeException( 'No id was given for shipping option.' );
|
||||
}
|
||||
if ( ! isset( $data->amount ) ) {
|
||||
throw new RuntimeException( 'Shipping option amount not found' );
|
||||
}
|
||||
|
||||
$amount = $this->money_factory->from_paypal_response( $data->amount );
|
||||
return new ShippingOption(
|
||||
$data->id,
|
||||
$data->label ?? '',
|
||||
isset( $data->selected ) ? (bool) $data->selected : false,
|
||||
$amount,
|
||||
$data->type ?? ShippingOption::TYPE_SHIPPING
|
||||
);
|
||||
}
|
||||
}
|
|
@ -38,11 +38,13 @@ class ApplicationContextRepository {
|
|||
* Returns the current application context.
|
||||
*
|
||||
* @param string $shipping_preferences The shipping preferences.
|
||||
* @param string $user_action The user action.
|
||||
*
|
||||
* @return ApplicationContext
|
||||
*/
|
||||
public function current_context(
|
||||
string $shipping_preferences = ApplicationContext::SHIPPING_PREFERENCE_NO_SHIPPING
|
||||
string $shipping_preferences = ApplicationContext::SHIPPING_PREFERENCE_NO_SHIPPING,
|
||||
string $user_action = ApplicationContext::USER_ACTION_CONTINUE
|
||||
): ApplicationContext {
|
||||
|
||||
$brand_name = $this->settings->has( 'brand_name' ) ? $this->settings->get( 'brand_name' ) : '';
|
||||
|
@ -55,7 +57,8 @@ class ApplicationContextRepository {
|
|||
(string) $brand_name,
|
||||
$locale,
|
||||
(string) $landingpage,
|
||||
$shipping_preferences
|
||||
$shipping_preferences,
|
||||
$user_action
|
||||
);
|
||||
return $context;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue