Add SellerReceivableBreakdown

This commit is contained in:
Alex P 2022-02-11 17:49:44 +02:00
parent 5cbd84a050
commit 2ab75368b4
8 changed files with 788 additions and 0 deletions

View file

@ -26,6 +26,7 @@ use WooCommerce\PayPalCommerce\ApiClient\Factory\AmountFactory;
use WooCommerce\PayPalCommerce\ApiClient\Factory\ApplicationContextFactory; use WooCommerce\PayPalCommerce\ApiClient\Factory\ApplicationContextFactory;
use WooCommerce\PayPalCommerce\ApiClient\Factory\AuthorizationFactory; use WooCommerce\PayPalCommerce\ApiClient\Factory\AuthorizationFactory;
use WooCommerce\PayPalCommerce\ApiClient\Factory\CaptureFactory; use WooCommerce\PayPalCommerce\ApiClient\Factory\CaptureFactory;
use WooCommerce\PayPalCommerce\ApiClient\Factory\ExchangeRateFactory;
use WooCommerce\PayPalCommerce\ApiClient\Factory\ItemFactory; use WooCommerce\PayPalCommerce\ApiClient\Factory\ItemFactory;
use WooCommerce\PayPalCommerce\ApiClient\Factory\MoneyFactory; use WooCommerce\PayPalCommerce\ApiClient\Factory\MoneyFactory;
use WooCommerce\PayPalCommerce\ApiClient\Factory\OrderFactory; use WooCommerce\PayPalCommerce\ApiClient\Factory\OrderFactory;
@ -35,7 +36,9 @@ use WooCommerce\PayPalCommerce\ApiClient\Factory\PayerFactory;
use WooCommerce\PayPalCommerce\ApiClient\Factory\PaymentsFactory; use WooCommerce\PayPalCommerce\ApiClient\Factory\PaymentsFactory;
use WooCommerce\PayPalCommerce\ApiClient\Factory\PaymentSourceFactory; use WooCommerce\PayPalCommerce\ApiClient\Factory\PaymentSourceFactory;
use WooCommerce\PayPalCommerce\ApiClient\Factory\PaymentTokenFactory; use WooCommerce\PayPalCommerce\ApiClient\Factory\PaymentTokenFactory;
use WooCommerce\PayPalCommerce\ApiClient\Factory\PlatformFeeFactory;
use WooCommerce\PayPalCommerce\ApiClient\Factory\PurchaseUnitFactory; use WooCommerce\PayPalCommerce\ApiClient\Factory\PurchaseUnitFactory;
use WooCommerce\PayPalCommerce\ApiClient\Factory\SellerReceivableBreakdownFactory;
use WooCommerce\PayPalCommerce\ApiClient\Factory\SellerStatusFactory; use WooCommerce\PayPalCommerce\ApiClient\Factory\SellerStatusFactory;
use WooCommerce\PayPalCommerce\ApiClient\Factory\ShippingFactory; use WooCommerce\PayPalCommerce\ApiClient\Factory\ShippingFactory;
use WooCommerce\PayPalCommerce\ApiClient\Factory\WebhookEventFactory; use WooCommerce\PayPalCommerce\ApiClient\Factory\WebhookEventFactory;
@ -320,6 +323,22 @@ return array(
'api.factory.authorization' => static function ( ContainerInterface $container ): AuthorizationFactory { 'api.factory.authorization' => static function ( ContainerInterface $container ): AuthorizationFactory {
return new AuthorizationFactory(); return new AuthorizationFactory();
}, },
'api.factory.exchange-rate' => static function ( ContainerInterface $container ): ExchangeRateFactory {
return new ExchangeRateFactory();
},
'api.factory.platform-fee' => static function ( ContainerInterface $container ): PlatformFeeFactory {
return new PlatformFeeFactory(
$container->get( 'api.factory.money' ),
$container->get( 'api.factory.payee' )
);
},
'api.factory.seller-receivable-breakdown' => static function ( ContainerInterface $container ): SellerReceivableBreakdownFactory {
return new SellerReceivableBreakdownFactory(
$container->get( 'api.factory.money' ),
$container->get( 'api.factory.exchange-rate' ),
$container->get( 'api.factory.platform-fee' )
);
},
'api.helpers.dccapplies' => static function ( ContainerInterface $container ) : DccApplies { 'api.helpers.dccapplies' => static function ( ContainerInterface $container ) : DccApplies {
return new DccApplies( return new DccApplies(
$container->get( 'api.dcc-supported-country-currency-matrix' ), $container->get( 'api.dcc-supported-country-currency-matrix' ),

View file

@ -0,0 +1,90 @@
<?php
/**
* The exchange rate object.
*
* @package WooCommerce\PayPalCommerce\ApiClient\Entity
*/
declare(strict_types=1);
namespace WooCommerce\PayPalCommerce\ApiClient\Entity;
/**
* Class ExchangeRate.
*/
class ExchangeRate {
/**
* The source currency from which to convert an amount.
*
* @var string
*/
private $source_currency;
/**
* The target currency to which to convert an amount.
*
* @var string
*/
private $target_currency;
/**
* The target currency amount. Equivalent to one unit of the source currency.
*
* @var string
*/
private $value;
/**
* ExchangeRate constructor.
*
* @param string $source_currency The source currency from which to convert an amount.
* @param string $target_currency The target currency to which to convert an amount.
* @param string $value The target currency amount. Equivalent to one unit of the source currency.
*/
public function __construct( string $source_currency, string $target_currency, string $value ) {
$this->source_currency = $source_currency;
$this->target_currency = $target_currency;
$this->value = $value;
}
/**
* The source currency from which to convert an amount.
*
* @return string
*/
public function source_currency(): string {
return $this->source_currency;
}
/**
* The target currency to which to convert an amount.
*
* @return string
*/
public function target_currency(): string {
return $this->target_currency;
}
/**
* The target currency amount. Equivalent to one unit of the source currency.
*
* @return string
*/
public function value(): string {
return $this->value;
}
/**
* Returns the object as array.
*
* @return array
*/
public function to_array(): array {
return array(
'source_currency' => $this->source_currency,
'target_currency' => $this->target_currency,
'value' => $this->value,
);
}
}

View file

@ -0,0 +1,74 @@
<?php
/**
* The platform fee object.
*
* @package WooCommerce\PayPalCommerce\ApiClient\Entity
*/
declare(strict_types=1);
namespace WooCommerce\PayPalCommerce\ApiClient\Entity;
/**
* Class PlatformFee.
*/
class PlatformFee {
/**
* The fee.
*
* @var Money
*/
private $amount;
/**
* The recipient of the fee.
*
* @var Payee|null
*/
private $payee;
/**
* PlatformFee constructor.
*
* @param Money $amount The fee.
* @param Payee|null $payee The recipient of the fee.
*/
public function __construct( Money $amount, ?Payee $payee ) {
$this->amount = $amount;
$this->payee = $payee;
}
/**
* The fee.
*
* @return Money
*/
public function amount(): Money {
return $this->amount;
}
/**
* The recipient of the fee.
*
* @return Payee|null
*/
public function payee(): ?Payee {
return $this->payee;
}
/**
* Returns the object as array.
*
* @return array
*/
public function to_array(): array {
$data = array(
'amount' => $this->amount->to_array(),
);
if ( $this->payee ) {
$data['payee'] = $this->payee->to_array();
}
return $data;
}
}

View file

@ -0,0 +1,211 @@
<?php
/**
* The info about fees and amount that will be received by the seller.
*
* @package WooCommerce\PayPalCommerce\ApiClient\Entity
*/
declare(strict_types=1);
namespace WooCommerce\PayPalCommerce\ApiClient\Entity;
/**
* Class SellerReceivableBreakdown
*/
class SellerReceivableBreakdown {
/**
* The amount for this captured payment in the currency of the transaction.
*
* @var Money
*/
private $gross_amount;
/**
* The applicable fee for this captured payment in the currency of the transaction.
*
* @var Money|null
*/
private $paypal_fee;
/**
* The applicable fee for this captured payment in the receivable currency.
*
* Present only in cases the fee is charged in the receivable currency.
*
* @var Money|null
*/
private $paypal_fee_in_receivable_currency;
/**
* The net amount that the payee receives for this captured payment in their PayPal account.
*
* Computed as gross_amount minus the paypal_fee minus the platform_fees.
*
* @var Money|null
*/
private $net_amount;
/**
* The net amount that is credited to the payee's PayPal account.
*
* Present only when the currency of the captured payment is different from the currency
* of the PayPal account where the payee wants to credit the funds. Computed as net_amount times exchange_rate.
*
* @var Money|null
*/
private $receivable_amount;
/**
* The exchange rate that determines the amount that is credited to the payee's PayPal account.
*
* Present when the currency of the captured payment is different from the currency of the PayPal account where the payee wants to credit the funds.
*
* @var ExchangeRate|null
*/
private $exchange_rate;
/**
* An array of platform or partner fees, commissions, or brokerage fees that associated with the captured payment.
*
* @var PlatformFee[]
*/
private $platform_fees;
/**
* SellerReceivableBreakdown constructor.
*
* @param Money $gross_amount The amount for this captured payment in the currency of the transaction.
* @param Money|null $paypal_fee The applicable fee for this captured payment in the currency of the transaction.
* @param Money|null $paypal_fee_in_receivable_currency The applicable fee for this captured payment in the receivable currency.
* @param Money|null $net_amount The net amount that the payee receives for this captured payment in their PayPal account.
* @param Money|null $receivable_amount The net amount that is credited to the payee's PayPal account.
* @param ExchangeRate|null $exchange_rate The exchange rate that determines the amount that is credited to the payee's PayPal account.
* @param PlatformFee[] $platform_fees An array of platform or partner fees, commissions, or brokerage fees that associated with the captured payment.
*/
public function __construct(
Money $gross_amount,
?Money $paypal_fee,
?Money $paypal_fee_in_receivable_currency,
?Money $net_amount,
?Money $receivable_amount,
?ExchangeRate $exchange_rate,
array $platform_fees
) {
$this->gross_amount = $gross_amount;
$this->paypal_fee = $paypal_fee;
$this->paypal_fee_in_receivable_currency = $paypal_fee_in_receivable_currency;
$this->net_amount = $net_amount;
$this->receivable_amount = $receivable_amount;
$this->exchange_rate = $exchange_rate;
$this->platform_fees = $platform_fees;
}
/**
* The amount for this captured payment in the currency of the transaction.
*
* @return Money
*/
public function gross_amount(): ?Money {
return $this->gross_amount;
}
/**
* The applicable fee for this captured payment in the currency of the transaction.
*
* @return Money|null
*/
public function paypal_fee(): ?Money {
return $this->paypal_fee;
}
/**
* The applicable fee for this captured payment in the receivable currency.
*
* Present only in cases the fee is charged in the receivable currency.
*
* @return Money|null
*/
public function paypal_fee_in_receivable_currency(): ?Money {
return $this->paypal_fee_in_receivable_currency;
}
/**
* The net amount that the payee receives for this captured payment in their PayPal account.
*
* Computed as gross_amount minus the paypal_fee minus the platform_fees.
*
* @return Money|null
*/
public function net_amount(): ?Money {
return $this->net_amount;
}
/**
* The net amount that is credited to the payee's PayPal account.
*
* Present only when the currency of the captured payment is different from the currency
* of the PayPal account where the payee wants to credit the funds. Computed as net_amount times exchange_rate.
*
* @return Money|null
*/
public function receivable_amount(): ?Money {
return $this->receivable_amount;
}
/**
* The exchange rate that determines the amount that is credited to the payee's PayPal account.
*
* Present when the currency of the captured payment is different from the currency of the PayPal account where the payee wants to credit the funds.
*
* @return ExchangeRate|null
*/
public function exchange_rate(): ?ExchangeRate {
return $this->exchange_rate;
}
/**
* An array of platform or partner fees, commissions, or brokerage fees that associated with the captured payment.
*
* @return PlatformFee[]
*/
public function platform_fees(): array {
return $this->platform_fees;
}
/**
* Returns the object as array.
*
* @return array
*/
public function to_array(): array {
$data = array(
'gross_amount' => $this->gross_amount->to_array(),
);
if ( $this->paypal_fee ) {
$data['paypal_fee'] = $this->paypal_fee->to_array();
}
if ( $this->paypal_fee_in_receivable_currency ) {
$data['paypal_fee_in_receivable_currency'] = $this->paypal_fee_in_receivable_currency->to_array();
}
if ( $this->net_amount ) {
$data['net_amount'] = $this->net_amount->to_array();
}
if ( $this->receivable_amount ) {
$data['receivable_amount'] = $this->receivable_amount->to_array();
}
if ( $this->exchange_rate ) {
$data['exchange_rate'] = $this->exchange_rate->to_array();
}
if ( $this->platform_fees ) {
$data['platform_fees'] = array_map(
function ( PlatformFee $fee ) {
return $fee->to_array();
},
$this->platform_fees
);
}
return $data;
}
}

View file

@ -0,0 +1,41 @@
<?php
/**
* The ExchangeRateFactory Factory.
*
* @package WooCommerce\PayPalCommerce\ApiClient\Factory
*/
declare(strict_types=1);
namespace WooCommerce\PayPalCommerce\ApiClient\Factory;
use stdClass;
use WooCommerce\PayPalCommerce\ApiClient\Entity\ExchangeRate;
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
/**
* Class ExchangeRateFactory
*/
class ExchangeRateFactory {
/**
* Returns an ExchangeRate object based off a PayPal Response.
*
* @param stdClass $data The JSON object.
*
* @return ExchangeRate
* @throws RuntimeException When JSON object is malformed.
*/
public function from_paypal_response( stdClass $data ): ExchangeRate {
if ( ! isset( $data->source_currency ) ) {
throw new RuntimeException( 'Exchange rate source currency not found' );
}
if ( ! isset( $data->target_currency ) ) {
throw new RuntimeException( 'Exchange rate target currency not found' );
}
if ( ! isset( $data->value ) ) {
throw new RuntimeException( 'Exchange rate value not found' );
}
return new ExchangeRate( $data->source_currency, $data->target_currency, $data->value );
}
}

View file

@ -0,0 +1,64 @@
<?php
/**
* The PlatformFee Factory.
*
* @package WooCommerce\PayPalCommerce\ApiClient\Factory
*/
declare(strict_types=1);
namespace WooCommerce\PayPalCommerce\ApiClient\Factory;
use stdClass;
use WooCommerce\PayPalCommerce\ApiClient\Entity\PlatformFee;
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
/**
* Class PayeeFactory
*/
class PlatformFeeFactory {
/**
* The Money factory.
*
* @var MoneyFactory
*/
private $money_factory;
/**
* The Payee factory.
*
* @var PayeeFactory
*/
private $payee_factory;
/**
* PlatformFeeFactory constructor.
*
* @param MoneyFactory $money_factory The Money factory.
* @param PayeeFactory $payee_factory The Payee factory.
*/
public function __construct( MoneyFactory $money_factory, PayeeFactory $payee_factory ) {
$this->money_factory = $money_factory;
$this->payee_factory = $payee_factory;
}
/**
* Returns a Payee object based off a PayPal Response.
*
* @param stdClass $data The JSON object.
*
* @return PlatformFee
* @throws RuntimeException When JSON object is malformed.
*/
public function from_paypal_response( stdClass $data ): PlatformFee {
if ( ! isset( $data->amount ) ) {
throw new RuntimeException( 'Platform fee amount not found' );
}
$amount = $this->money_factory->from_paypal_response( $data->amount );
$payee = ( isset( $data->payee ) ) ? $this->payee_factory->from_paypal_response( $data->payee ) : null;
return new PlatformFee( $amount, $payee );
}
}

View file

@ -0,0 +1,97 @@
<?php
/**
* The SellerReceivableBreakdown Factory.
*
* @package WooCommerce\PayPalCommerce\ApiClient\Factory
*/
declare(strict_types=1);
namespace WooCommerce\PayPalCommerce\ApiClient\Factory;
use stdClass;
use WooCommerce\PayPalCommerce\ApiClient\Entity\PlatformFee;
use WooCommerce\PayPalCommerce\ApiClient\Entity\SellerReceivableBreakdown;
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
/**
* Class SellerReceivableBreakdownFactory
*/
class SellerReceivableBreakdownFactory {
/**
* The Money factory.
*
* @var MoneyFactory
*/
private $money_factory;
/**
* The ExchangeRate factory.
*
* @var ExchangeRateFactory
*/
private $exchange_rate_factory;
/**
* The PlatformFee factory.
*
* @var PlatformFeeFactory
*/
private $platform_fee_factory;
/**
* SellerReceivableBreakdownFactory constructor.
*
* @param MoneyFactory $money_factory The Money factory.
* @param ExchangeRateFactory $exchange_rate_factory The ExchangeRate factory.
* @param PlatformFeeFactory $platform_fee_factory The PlatformFee factory.
*/
public function __construct(
MoneyFactory $money_factory,
ExchangeRateFactory $exchange_rate_factory,
PlatformFeeFactory $platform_fee_factory
) {
$this->money_factory = $money_factory;
$this->exchange_rate_factory = $exchange_rate_factory;
$this->platform_fee_factory = $platform_fee_factory;
}
/**
* Returns a SellerReceivableBreakdown object based off a PayPal Response.
*
* @param stdClass $data The JSON object.
*
* @return SellerReceivableBreakdown
* @throws RuntimeException When JSON object is malformed.
*/
public function from_paypal_response( stdClass $data ): SellerReceivableBreakdown {
if ( ! isset( $data->gross_amount ) ) {
throw new RuntimeException( 'Seller breakdown gross amount not found' );
}
$gross_amount = $this->money_factory->from_paypal_response( $data->gross_amount );
$paypal_fee = ( isset( $data->paypal_fee ) ) ? $this->money_factory->from_paypal_response( $data->paypal_fee ) : null;
$paypal_fee_in_receivable_currency = ( isset( $data->paypal_fee_in_receivable_currency ) ) ? $this->money_factory->from_paypal_response( $data->paypal_fee_in_receivable_currency ) : null;
$net_amount = ( isset( $data->net_amount ) ) ? $this->money_factory->from_paypal_response( $data->net_amount ) : null;
$receivable_amount = ( isset( $data->receivable_amount ) ) ? $this->money_factory->from_paypal_response( $data->receivable_amount ) : null;
$exchange_rate = ( isset( $data->exchange_rate ) ) ? $this->exchange_rate_factory->from_paypal_response( $data->exchange_rate ) : null;
$platform_fees = ( isset( $data->platform_fees ) ) ? array_map(
function ( stdClass $fee_data ): PlatformFee {
return $this->platform_fee_factory->from_paypal_response( $fee_data );
},
$data->platform_fees
) : array();
return new SellerReceivableBreakdown(
$gross_amount,
$paypal_fee,
$paypal_fee_in_receivable_currency,
$net_amount,
$receivable_amount,
$exchange_rate,
$platform_fees
);
}
}

View file

@ -0,0 +1,192 @@
<?php
declare(strict_types=1);
namespace WooCommerce\PayPalCommerce\ApiClient\Factory;
use WooCommerce\PayPalCommerce\ApiClient\TestCase;
class SellerReceivableBreakdownFactoryFactoryTest extends TestCase
{
private $testee;
public function setUp(): void
{
parent::setUp();
$this->testee = new SellerReceivableBreakdownFactory(
new MoneyFactory(),
new ExchangeRateFactory(),
new PlatformFeeFactory(new MoneyFactory(), new PayeeFactory())
);
}
/**
* @dataProvider dataForTestFromPayPalResponse
*/
public function testFromPayPalResponse(string $json, array $expected_result)
{
$obj = json_decode($json);
$result = $this->testee->from_paypal_response($obj);
self::assertEquals($expected_result, $result->to_array());
}
public function dataForTestFromPayPalResponse() : array
{
return [
'fee' => [
'
{
"gross_amount": {
"currency_code": "USD",
"value": "10.42"
},
"paypal_fee": {
"currency_code": "USD",
"value": "0.41"
},
"net_amount": {
"currency_code": "USD",
"value": "10.01"
}
}',
[
'gross_amount' => [
'currency_code' => 'USD',
'value' => '10.42',
],
'paypal_fee' => [
'currency_code' => 'USD',
'value' => '0.41',
],
'net_amount' => [
'currency_code' => 'USD',
'value' => '10.01',
],
],
],
'min' => [
'
{
"gross_amount": {
"currency_code": "USD",
"value": "10.42"
}
}',
[
'gross_amount' => [
'currency_code' => 'USD',
'value' => '10.42',
],
],
],
'exchange' => [
'
{
"gross_amount": {
"value": "10.99",
"currency_code": "USD"
},
"paypal_fee": {
"value": "0.33",
"currency_code": "USD"
},
"net_amount": {
"value": "10.66",
"currency_code": "USD"
},
"receivable_amount": {
"currency_code": "CNY",
"value": "59.26"
},
"paypal_fee_in_receivable_currency": {
"currency_code": "CNY",
"value": "1.13"
},
"exchange_rate": {
"source_currency": "USD",
"target_currency": "CNY",
"value": "5.9483297432325"
}
}',
[
'gross_amount' => [
'currency_code' => 'USD',
'value' => '10.99',
],
'paypal_fee' => [
'currency_code' => 'USD',
'value' => '0.33',
],
'net_amount' => [
'currency_code' => 'USD',
'value' => '10.66',
],
'receivable_amount' => [
'currency_code' => 'CNY',
'value' => '59.26',
],
'paypal_fee_in_receivable_currency' => [
'currency_code' => 'CNY',
'value' => '1.13',
],
'exchange_rate' => [
'source_currency' => 'USD',
'target_currency' => 'CNY',
'value' => '5.9483297432325',
],
],
],
'platform_fees' => [
'
{
"gross_amount": {
"currency_code": "USD",
"value": "10.42"
},
"platform_fees": [
{
"amount": {
"currency_code": "USD",
"value": "0.06"
}
},
{
"amount": {
"currency_code": "USD",
"value": "0.08"
},
"payee": {
"email_address": "example@gmail.com"
}
}
]
}',
[
'gross_amount' => [
'currency_code' => 'USD',
'value' => '10.42',
],
'platform_fees' => [
[
'amount' => [
'currency_code' => 'USD',
'value' => '0.06',
],
],
[
'amount' => [
'currency_code' => 'USD',
'value' => '0.08',
],
'payee' => [
'email_address' => 'example@gmail.com',
],
],
],
],
],
];
}
}